wren/val Public Public: anyone can read this; nobody can change it.
forked from benjivers/val
workbenchthis machine
The walking measurement starts from a seat that can walk
The preview's test run failed once in the bundled-client test, about nine hundred milliseconds in — where it stops the arena and measures how far the drawn body leads the server with a key held. That measurement assumed the seat could walk. By then the arena has been run through whole rounds with this seat standing still, so it may be dead, mid-plant, slowed, stood inside a barrier a bot put up, or in the seconds after a round is decided — and in every one of those the guess rightly stands still, and the lead is nothing. The end-phase rule added in this pull (nobody moves once a round is decided, so the guess does not either) widened that window. The test now puts the seat on its feet in a live round, clears what abilities left, lets one snapshot carry that to the client, and only then stops the clock — trying again if a round ends or a bot lands a kill in that moment. Ten runs alone and six under three-way contention, all clean. Co-Authored-By: Claude Fable 5.1 <[email protected]>
1 file
changed +20
−4
src/client.test.ts +20 −4
| @@ -336,10 +336,26 @@ test("the bundled client connects, paints the HUD and draws a frame", async () = | ||
| 336 | 336 | // arrive at all — the drawn body still carries the keys you are holding |
| 337 | 337 | // forward, as far as the cap and no further, and stops there. |
| 338 | 338 | press("KeyV"); // the top-down view, where your own body is an arrow |
| 339 | for (let i = 0; i < 60 && arena.match().phase !== "live"; i++) arena.advance(1); | |
| 340 | await Bun.sleep(60); | |
| 341 | runFrame(); | |
| 342 | arena.stopArena(); | |
| 339 | // The measurement needs a live round and a seat that can walk. The arena | |
| 340 | // has been run through whole rounds above with this seat standing still, | |
| 341 | // so by now it may be dead, mid-plant, slowed, or stood inside a barrier a | |
| 342 | // bot put up — and a guess about a body that cannot move is rightly nothing. | |
| 343 | // Put it on its feet, clear what abilities left, and let a snapshot carry | |
| 344 | // that to the client before the clock is stopped; try again if a round | |
| 345 | // ends or a bot lands a kill in that moment. | |
| 346 | for (let tries = 0; tries < 10; tries++) { | |
| 347 | for (let i = 0; i < 60 && arena.match().phase !== "live"; i++) arena.advance(1); | |
| 348 | Object.assign(seat, { alive: true, hp: 100, planting: 0, defusing: 0, haste: 0, slow: 0 }); | |
| 349 | arena.match().zones.length = 0; | |
| 350 | arena.advance(1 / 30); | |
| 351 | await Bun.sleep(80); | |
| 352 | runFrame(); | |
| 353 | arena.stopArena(); | |
| 354 | if (arena.match().phase === "live" && seat.alive && arena.match().zones.length === 0) break; | |
| 355 | arena.startArena(); | |
| 356 | } | |
| 357 | expect(arena.match().phase).toBe("live"); | |
| 358 | expect(seat.alive).toBe(true); | |
| 343 | 359 | // Walk whichever way is open from where the server last put us. |
| 344 | 360 | for (const code of ["KeyW", "KeyA", "KeyS", "KeyD"]) release(code); |
| 345 | 361 | const { blockedCircle } = await import("./map.ts"); |