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

+4 -2
View File
@@ -2145,9 +2145,11 @@ export function render() {
for (let i = 0; i < 3; i++) {
const h = ballHist[ballHist.length - 2 - i * 2]; if (!h) break;
const p = proj(h.x, h.y, h.z);
ctx.globalAlpha = 0.26 - i * 0.08;
// 0.26 was tuned against the gore mode's dark rot palette; on the bright tennis lawn it
// vanished entirely — "i see no ball trails" (Oliver, in the tournament)
ctx.globalAlpha = 0.38 - i * 0.11;
ctx.fillStyle = UI.ball;
ctx.beginPath(); ctx.arc(p.x, p.y, Math.max(1, p.s * 0.09 * (0.8 - i * 0.18)), 0, 7); ctx.fill();
ctx.beginPath(); ctx.arc(p.x, p.y, Math.max(1.5, p.s * 0.09 * (0.9 - i * 0.18)), 0, 7); ctx.fill();
}
ctx.globalAlpha = 1;
}