The short ball gets chased, intercept gets legs, the vignette gets corners
Second recorded session: 5 wins and a deuce war to 5-6 — the mode is a contest — but all seven losses shared one signature: the ball died in court 1.4-2m short of him while he ran 0.2-0.5m. Three defects: The pace cut created dying rollers. Slow returns bounce and die at z 18-20, outside intercept's near zone, so nothing chased them, and the rolled-dead rule hands the point to the zombie. They also arrive at his feet below legal contact height — the "ball arrives right at the player" feel. intercept keeps an anyHit candidate now: the earliest reachable point on his half where the ball is still at hitting height, so the assist runs forward onto the short ball. Verified: he sprints z 23 -> 16.4 and meets it at gap ~0. intercept computed reachability with autoAssist — 0 on any fine pointer — so a desktop match's planner answered "home" every time. He had legs, his destination was always the baseline. assistK() is shared by mover and planner now. And the vignette was a radial gradient in a portrait canvas: the circle reaches the corners but hits the side edges at fraction zero — "red pulsing from below" was the bottom edge being the only place it got close. Four linear edge fades now, hugging the rectangle on any aspect. 48 tests, 12 seeds clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3a789eb2e9
commit
f37fb93875
5 files changed
+93
-16
No files matched your search
@@ -588,6 +588,33 @@ test('the match brings its own legs: auto-run works even where autoAssist is 0',
|
||||
} finally { TUNE.autoAssist = assist; }
|
||||
});
|
||||
|
||||
test('THE SHORT BALL: the assist runs FORWARD onto a dying return, desktop conditions included', () => {
|
||||
// Seven of seven recorded losses: a slow return bounced and died at z 18-20 — outside the
|
||||
// intercept zone, so nothing chased it and it rolled dead at his feet (below legal contact
|
||||
// height). Doubly broken on desktop: intercept computed reachability with autoAssist (0 there),
|
||||
// so its answer was always "run home". Both fixed via assistK() + the anyHit candidate.
|
||||
const assist = TUNE.autoAssist; TUNE.autoAssist = 0; // the desktop pane condition
|
||||
try {
|
||||
startMatch();
|
||||
for (let i = 0; i < 2.2 * 60; i++) update(DT);
|
||||
G.phase = 'rally';
|
||||
P.x = 0; P.z = 23;
|
||||
// a slow short return: incoming, will bounce and die around z ~19
|
||||
ball.active = true; ball.lastHit = 'O'; ball.x = 1.5; ball.z = 10; ball.y = 1.6;
|
||||
ball.vx = 0.4; ball.vy = 2.2; ball.vz = 5.5; ball.bounces = 0; ball.g = TUNE.gravity;
|
||||
const z0 = P.z;
|
||||
let minGap = 99, minPz = P.z; // deepest he RAN, read during the chase — the point reset
|
||||
// teleports him home after, so the final position proves nothing
|
||||
for (let i = 0; i < 2.5 * 60 && ball.active && ball.lastHit === 'O'; i++) {
|
||||
update(DT);
|
||||
minPz = Math.min(minPz, P.z);
|
||||
minGap = Math.min(minGap, Math.hypot(ball.x - P.x, (ball.z - P.z) * 0.8));
|
||||
}
|
||||
assert.ok(minPz < z0 - 3.0, 'he ran FORWARD to meet it: z ' + z0 + ' -> ' + minPz.toFixed(1));
|
||||
assert.ok(minGap < 1.6, 'and got the ball into reach (closest ' + minGap.toFixed(1) + ' m)');
|
||||
} finally { TUNE.autoAssist = assist; }
|
||||
});
|
||||
|
||||
test('the match recovers to CENTRE between shots — a wide return must not strand you', () => {
|
||||
// The match inherited gore-splatter's depth-only recovery (a sidestep-protection rule) by being
|
||||
// G.mode 'splatter' — so one wide return pulled you off centre and you STAYED there, and the next
|
||||
|
||||
Reference in new issue
Block a user