Flatten the ladder: cap how wide an opponent paints

Oliver: from the Runner on the zombie game is very hard. Measured with
the ring bot: the win rate fell off a cliff wherever an opponent's
width crossed ~3.3 m, the auto-run's reach from the centre (at the
Steward, and again at the Seller), and from there every line could be
painted. Legs and flub decay moved nothing.

Every match opponent's spread is now capped at 3.0 m (matchWideMax),
and the put-away chance runs 0.15 to 0.8 instead of 0.2 to 0.85.
Level 10: the Runner goes from 44% to 68% of points, the Champion from
24% to 33%, with a steady slope between them. New test pins the cap.
v387.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5.5 committed 2026-10-15 22:02:30 +02:00
1 parent c8d43fbe15
commit 0576f24614
5 files changed
+63 -4

No files matched your search

+25
View File
@@ -3662,6 +3662,31 @@ function winStoryCup() {
G.modal = null; G.modalQ.length = 0;
}
test('THE LADDER IS FLATTER: no opponent paints wider than matchWideMax (the cliff at ~3.3 m)', () => {
// Oliver, 2026-10-15: "ab Runner ist das Zombie-Game schon sehr schwer". The win rate fell off a cliff
// wherever the rung's width crossed the auto-run's reach from the centre; the width is capped now.
startMatch(); G.interlude.introT = 0;
const zb = oppOf();
for (const n of [8, 12, 18]) {
G.match.opp = n; zb.foe = cfg.matchFoe(n);
let widest = 0;
for (let i = 0; i < 600; i++) {
G.phase = 'rally'; G.wasServe = false; G.match.surprised = G.match.expected = false;
P.x = i % 2 ? 3 : -3; P.z = 23; P.swingT = -1;
zb.x = 0; zb.z = 2; zb.swingT = -1; zb.swingCool = 0; zb.serveHold = 0;
Object.assign(ball, { active: true, lastHit: 'P', pow: 1, bounces: 1, rx: null, spin: 1, soft: false,
x: 0, z: 2.4, y: 1.2, vx: 0, vy: 0, vz: -1 });
update(DT);
if (ball.lastHit !== 'O' || ball.soft) { ball.active = false; continue; }
const t = (ball.vy + Math.sqrt(ball.vy * ball.vy + 2 * ball.g * ball.y)) / ball.g;
widest = Math.max(widest, Math.abs(ball.x + ball.vx * t));
ball.active = false;
}
assert.ok(widest > 2.2 && widest <= 3.0 + 0.35, `rung ${n}: widest landing ${widest.toFixed(2)} m (the flattening set 3.0)`);
}
endMatch();
});
test('THE STORY: every act\'s cup final is the body that becomes its boss, and the stock grows act by act', () => {
const famOf = n => cfg.matchFoe(n).fam;
const bossFam = { 0: 'gk', 5: 'ma', 2: 'cu', 3: 'hc', 9: 'ch' }; // design -> the ladder body it grew from