The latch is stale-proof by construction, the cup divisor honest, the trail visible

Oliver's tournament freeze was the stale latch by a THIRD route:
matchFallWillPlay kept the deathmatch /4 while cup matchPoint divides by
4*need, so it promised a fall on a no-crossing point — whose synchronous
matchReady left the after-set latch scoping a dead rally. No more ordering
arguments: the latch is set BEFORE the resolve, the swallow exempts the
in-progress resolution via G.matchEarly, and every path that arms a rally
clears it in matchReady. willFall now mirrors the cup divisor exactly and
knows a mid-round game keeps its body. Regression test drives the full QF
sequence (no-crossing points, the fall, the mid-round game, game two).

And the two 'not really' reports: the trail's 0.26 alpha was tuned on the
gore palette and vanished on the bright lawn — 0.38 now, gate at 13 m/s;
oppBright 1.18 -> 1.3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-08-13 22:36:44 +02:00
1 parent f9b26e5380
commit 129a001109
6 files changed
+67 -21

No files matched your search

+38
View File
@@ -836,6 +836,44 @@ test('THE TOURNAMENT: bands draw, bodies deepen, rounds hold their body, the cha
assert.equal(G.match.felled, CUP_ROUNDS.length, 'four bodies felled, banked as a match run');
});
test('cup rallies never strand the latch: no-crossing points, the fall, and the mid-round game', () => {
// Oliver's second lock: in the quarter-final, matchFallWillPlay still divided by 4 while
// matchPoint divided by 4*need — it promised a fall on a point that crossed nothing, the
// no-fall path re-armed synchronously, and the after-set latch went stale ("basically like
// freeze from before"). The latch is set BEFORE the resolve now (the swallow exempts the
// resolution in progress via G.matchEarly), and willFall mirrors the cup divisor exactly.
const { CUP_ROUNDS } = cfg;
_startMatch(true); G.modal = null; G.modalQ.length = 0;
G.mode = 'splatter';
const d = G.match;
G.interlude.introT = 0;
for (let k = 0; k < 4; k++) resolveInterlude('P'); // round one falls to the ordinary path
G.modal = null; G.modalQ.length = 0;
passMopBeat();
assert.equal(d.cup.round, 1, 'on the quarter-final');
const zb = oppOf();
const launch = () => {
zb.x = -4; zb.z = 2;
ball.active = true; ball.lastHit = 'P'; ball.bounces = 0; ball.wid = 'ball'; ball.collected = false;
ball.x = 3.4; ball.z = 7; ball.y = 0.5; ball.vx = 0.5; ball.vy = -2; ball.vz = -6; ball.g = TUNE.gravity;
G.phase = 'rally'; G.wasServe = false;
const before = score.pts[0] + score.games[0] * 10;
for (let i = 0; i < 8 * 60 && score.pts[0] + score.games[0] * 10 === before && !G.matchFall; i++) update(DT);
for (let i = 0; i < 6 * 60 && (G.matchFall || G.modal); i++) { G.modal = null; G.modalQ.length = 0; update(DT); }
};
launch(); // 8 -> 7: crosses nothing (the old mispredict)
assert.equal(zb.hp, 7, 'point one chipped the pool');
assert.ok(!d.decided, 'no stale latch after a no-crossing point');
launch(); // 7 -> 6: still nothing
launch(); // 6 -> 5: the arm comes off, mid-flight
assert.ok(!d.decided, 'the fall beat ended and released its latch');
launch(); // the game point, mid-round: same body plays on
assert.ok(zombies.includes(zb), 'game one banked, the quarter-final body stands');
assert.equal(score.games[0], 2, 'the game went up');
launch(); // game two opens: the match is ALIVE
assert.equal(score.pts[0], 1, 'the next rally resolved — no freeze');
});
test('service alternates by game, and the opponent actually serves', () => {
// Until now the corpse only ever returned: score.server was pinned to 'P' because the match calls
// advancePoint directly and the flip lives in tennis's pointTo, which the match bypasses. Return