The last pass, judged against somebody sitting down for two minutes: four things were worth doing, and the rest is left alone on purpose.
What changed
The moment a round turns now says something. The view used to freeze with "Round over" in the prompt and nothing else. The match now keeps the outcome as data (last: round, winner, why), the snapshot carries it, and a banner on the view reads "Round won — spike defused · next round in 4s" (or "lost"). The prompt, the watching view and the server-rendered first paint say the same. The first three seconds of every buy phase carry a round card — "Round 5 · you attack — plant the spike on A or B" — that fades out over half a second rather than blinking off. New module static/banner.js, tests in src/banner.test.ts.
The buy panel reads as a panel, not a price list. Rows are labelled agent · gun · armour · abilities, the "refused server-side" header is replaced with a sentence for a first-time reader, and the gun you hold is outlined.
The scoreboard goes out only when it changes. It was 1673 of 3817 bytes in every snapshot for a table that changes a few times a round. Measured over two minutes of match: mean snapshot 3633 → 1973 bytes (46% less), 106 → 58 KB/s a seat, the board sent on 72 of 3600 ticks. The page and the terminal keep the one they have; the full snapshot on socket open and in every test is untouched.
The deploy gate's coin flip is found and closed. Captured on run 8: the plant test in server.test.ts left every other player's spike, planting and held F as the live arena had them, so a bot mid-plant on A finished first and the spike landed on A, not B — and because the bots were never restored after that failure, seven seat tests after it failed as a cascade. The test now clears exactly what it measures and restores the bots in a finally. Fifteen straight runs after the fix, none before it could manage six. One other test was wrong and is fixed: the prompt test fed result: "Spike defused" in an end phase, a snapshot the server never sends, since result is only set when the match is over.
What to press in the first ten seconds: open the preview and wait for a round to end, or press B during a buy phase. The banner and the round card are the difference; ` still prints the frame numbers if the extra fillRect is doubted (it is one rectangle and two texts).
Decided, not done: overtime at 12–12 is a choice, now said so in the README: a match is twenty-five rounds the bots play both halves of, and 13–12 reads as a result. Bots committing to a site is a forty-round-player thing and outside this pass. Agents still read as different mostly through their kit and a trim colour; making them read differently at a glance in the world means new silhouettes, which is a drawing pass of its own.
If there were another pass: give each agent a silhouette (a hat, a pack, a stance) so "who is that" is answered by shape before the name tag is readable; and let the terminal show the banner words too. Leave exactly as it is: the interpolation and prediction path, the vision rules, the spectator view, and the flash. They are measured, and nothing in this read found a number to improve.
The last pass, judged against somebody sitting down for two minutes: four things were worth doing, and the rest is left alone on purpose.
What changed
last: round, winner, why), the snapshot carries it, and a banner on the view reads "Round won — spike defused · next round in 4s" (or "lost"). The prompt, the watching view and the server-rendered first paint say the same. The first three seconds of every buy phase carry a round card — "Round 5 · you attack — plant the spike on A or B" — that fades out over half a second rather than blinking off. New modulestatic/banner.js, tests insrc/banner.test.ts.server.test.tsleft every other player'sspike,plantingand held F as the live arena had them, so a bot mid-plant on A finished first and the spike landed on A, not B — and because the bots were never restored after that failure, seven seat tests after it failed as a cascade. The test now clears exactly what it measures and restores the bots in afinally. Fifteen straight runs after the fix, none before it could manage six. One other test was wrong and is fixed: the prompt test fedresult: "Spike defused"in anendphase, a snapshot the server never sends, sinceresultis only set when the match is over.What to press in the first ten seconds: open the preview and wait for a round to end, or press B during a buy phase. The banner and the round card are the difference; ` still prints the frame numbers if the extra fillRect is doubted (it is one rectangle and two texts).
Decided, not done: overtime at 12–12 is a choice, now said so in the README: a match is twenty-five rounds the bots play both halves of, and 13–12 reads as a result. Bots committing to a site is a forty-round-player thing and outside this pass. Agents still read as different mostly through their kit and a trim colour; making them read differently at a glance in the world means new silhouettes, which is a drawing pass of its own.
If there were another pass: give each agent a silhouette (a hat, a pack, a stance) so "who is that" is answered by shape before the name tag is readable; and let the terminal show the banner words too. Leave exactly as it is: the interpolation and prediction path, the vision rules, the spectator view, and the flash. They are measured, and nothing in this read found a number to improve.
🤖 Generated with Claude Code
Closes #20