The rush picks a lane and commits to it, and stops on a strike line

"They just overrun you without a chance" — two reasons, and the second one only
existed because of the first.

IT FOLLOWED YOU. The rush tracked your x every frame it was running, so the
sidestep was decoration: it simply came across and took you anyway. The lane is
LOCKED when the rush starts now. You get the whole 2.2 s run-up to leave it, and
what it runs down is that line, not you.

AND IT LANDED ON YOU. A rush that stopped at your feet left the boss standing
there afterwards, and nothing gets you out from under that — dodgeCool is 0.5 s
against a 0.28 s i-frame, so the second contact kills you while the first is
still fading. It stops on a STRIKE LINE 0.4 m short instead, reached on the same
frame the rush timer expires, so it turns and withdraws the instant it arrives.

The version of this that ran the rush THROUGH you and out the far side is why
bossStrike is a short stop and not an overrun: a body past the baseline is
deleted and scores a point, so the boss quietly despawned itself mid-fight and
left the fight running with nothing in it.

Measured, 45 s against the seller, the champion's third phase and the physio:
stand still and the first rush kills you (4.1 s); step out of the lane and you
survive all of it — seven or eight rushes, one sidestep each, the boss on court
the whole time and out at its line between them where you can hit it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-09 17:11:21 +02:00
1 parent d57433ed2b
commit 482c7cdce4
2 files changed
+25 -10

No files matched your search

+17 -10
View File
@@ -174,10 +174,16 @@ function bossAI(zb, dt) {
zb.moveT -= dt;
const v = TUNE.bossChargeV * (A.speedMul ?? 1);
if (zb.charging) {
const dx = P.x - zb.x;
zb.x += Math.sign(dx) * Math.min(Math.abs(dx), TUNE.bossStrafe * dt); // it tracks your lane SLOWLY: a sidestep beats it
zb.z = Math.min(P.z, zb.z + zb.chargeV * dt); // AT you and NO FURTHER: unclamped it ran
if (zb.moveT <= 0) { zb.charging = false; zb.moveT = TUNE.bossChargeRest; } // off the back of the court
// IT COMMITTED TO A LANE AND IT IS RUNNING DOWN THAT LANE, whatever you do next. Tracking your
// x for the whole rush made the sidestep meaningless — it just followed you across and ran you
// over ("they overrun you without a chance"), and stopping the rush ON you left it standing
// there afterwards, where the 0.5 s dodge cooldown cannot outrun a 0.28 s i-frame. So: the
// lane is locked when the rush begins, you get the entire run-up to leave it, and the rush
// ends on a STRIKE LINE just in front of you, on the same frame the rush timer expires, so it
// turns and withdraws the instant it arrives. A rush that misses is over.
zb.x += Math.sign(zb.lane - zb.x) * Math.min(Math.abs(zb.lane - zb.x), TUNE.bossStrafe * 2 * dt);
zb.z += zb.chargeV * dt;
if (zb.moveT <= 0) { zb.charging = false; zb.moveT = TUNE.bossChargeRest; } // spent: it turns and walks back
} else {
// AND IT FALLS BACK. A rush that ended where it landed left the boss parked on top of you for
// the rest of the fight: dodge or die every two seconds, with no window to hit it and nothing
@@ -187,13 +193,14 @@ function bossAI(zb, dt) {
// PASSES: you dodge it, and the ground it gives up again is your turn to hit it.
const home = TUNE.bossZMax, sp = v * (A.retreat ?? 1.3) * dt; // toward its LINE, from either side:
zb.z += Math.sign(home - zb.z) * Math.min(Math.abs(home - zb.z), sp); // backward off a rush, forward on the way in
// THE RUSH IS TIMED, NOT PACED. Whatever ground the retreat left between you, it covers it in
// bossChargeT — so every charge arrives, and every charge takes the same readable run-up to do
// it. Paced at a flat speed instead, the same fix that stopped it camping on you also stopped
// it ever reaching you: it started each rush from the band and ran out of clock 8 m short.
if (zb.moveT <= 0) {
// THE RUSH IS TIMED, NOT PACED, and it always begins FROM THE LINE — never from wherever a
// half-finished retreat happened to leave it, which is how a rush could start on your toes
// with no run-up to read. It covers the whole distance in bossChargeT, so the approach looks
// the same every time whatever the design's speed.
if (zb.moveT <= 0 && Math.abs(zb.z - home) < 0.1) {
zb.charging = true; zb.moveT = TUNE.bossChargeT;
zb.chargeV = Math.max(v, (P.z - zb.z) / TUNE.bossChargeT);
zb.lane = P.x; // the lane, locked. You have the run-up to leave it.
zb.chargeV = (P.z - TUNE.bossStrike - zb.z) / TUNE.bossChargeT;
}
}
} else if (style === 'shadow') {