Stop calling "passed you" while the ball is still on its way to him

Oliver's v366 log: a LOST "passed you" with no swing. The match gave the
CPU the point the moment its ball crossed 0.3 m behind the baseline — a
line from when the player stood inside it. Since step 1 he waits up to
2.2 m behind the line for deep balls, and a ball going by ~1.5 m beside
him only enters his reach just in front of him, so the point was called
before it was ever playable. In the match "past you" now means past his
reach. The swing log's hits also say whether the timing was early or
late. v367.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5.5 committed 2026-10-14 13:03:30 +02:00
1 parent 5bbde720ad
commit dfdb699f9d
4 files changed
+73 -4

No files matched your search

+11 -3
View File
@@ -1705,7 +1705,10 @@ function trySwing(ch, isAI, qCap = TUNE.aiQualityMax) {
const sway = swayOf(aim), lane = Math.abs(sway) > 0.15 ? (sway < 0 ? ' left' : ' right') : '';
const cap = q >= q0 ? '' : ball.rx && ball.rx.lob ? ' · capped: lobbed, on your heels'
: ball.bounces === 0 ? ' · capped: volley below the tape' : ' · capped: dug out a drop';
logSwing({ result: 'HIT', reason: `q=${r2(q)}${kind}${lane}${volley ? ' volley' : ''} · ${P.flick ? 'flick' : 'tap'} ${P.tap || 0}ms${cap}`,
// ...and WHICH WAY the timing missed: contact before the window's centre means the ball was
// already there — the swing came LATE; after it, the swing came EARLY
const off = Math.round((t - center) * 1000), timing = q0 >= 0.95 ? '' : off < 0 ? ` · late ${-off}ms` : ` · early ${off}ms`;
logSwing({ result: 'HIT', reason: `q=${r2(q)}${kind}${lane}${volley ? ' volley' : ''}${timing} · ${P.flick ? 'flick' : 'tap'} ${P.tap || 0}ms${cap}`,
d: r2(Math.hypot(dx, dz * 0.8)), y: r2(ball.y) });
}
doHit(ch, q, aim);
@@ -2496,8 +2499,13 @@ export function update(dt) {
} else if (ball.bounces === 1) pointTo(ball.lastHit, null);
}
}
// a racket zombie's return that gets past you (crosses your baseline) is a point for THEM
if (G.mode === 'splatter' && ball.active && !ball.scored && ball.lastHit === 'O' && ball.z > COURT.L + 0.3) {
// a racket zombie's return that gets past you (crosses your baseline) is a point for THEM.
// IN THE MATCH "past you" means past your REACH (2026-10-14, Oliver's v366 log): since step 1 a
// baseliner waits up to rallyBehind BEHIND his line, so the old line — 0.3 m behind the baseline —
// called the point while the ball was still on its way to his racket. Every deep topspin ball the
// auto-run met deep was a "passed you" with no swing. The duel keeps the old line.
const passZ = G.match ? Math.max(COURT.L + 0.3, P.z + TUNE.reach * TUNE.matchReach + 0.3) : COURT.L + 0.3;
if (G.mode === 'splatter' && ball.active && !ball.scored && ball.lastHit === 'O' && ball.z > passZ) {
ball.active = false;
if (G.interlude) resolveInterlude('O', 'passed_player'); // sudden death: its passing shot ends the duel
else { if (!G.horde && !G.clearing) splatPoint('O'); spentBall(); } // clearing = mop-up, no scoring either way