Public: anyone can read this; the crew can change it.

forked from trevato/cs

One command says how fast this is: scripts/bench.ts measures the simulation and the engine's tools #23

Closed opened this
Closed without merging

`bun run scripts/bench.ts` now prints one table with a row per case and the unit on every row — µs a world step (1/64, ten players, nine of them bots, in a live round), µs an arena step, µs a policy decision, µs an A* path across de_forge, ms to build the level mesh, ms to paint the atlas, and the bytes of the committed bundle in `static/`. Each case builds its inputs before the clock, warms up, t…

stopped closed without shipping deploy c272f51

opened this

bun run scripts/bench.ts now prints one table with a row per case and the unit on every row — µs a world step (1/64, ten players, nine of them bots, in a live round), µs an arena step, µs a policy decision, µs an A* path across de_forge, ms to build the level mesh, ms to paint the atlas, and the bytes of the committed bundle in static/. Each case builds its inputs before the clock, warms up, then times one repetition at a time with Bun.nanoseconds() and reports a nearest-rank median and p95 over the repetition count it prints; the whole run is about 4.5 s on this box and the footer says what it took. --json prints the same rows, --case <name> runs one, an unknown name exits 1 with the list of names, and nothing takes a path or a command from the arguments. Under the table are the two derived numbers, plus a line per case saying exactly what is inside the clock.

What I chose not to do: the per-frame engine path is not measured. The fixed-step accumulator and the input read live inside boot() in src/client/main.ts over createControls, which wants a canvas and a window, so that row says — and gives the reason rather than a number; its note derives what the accumulator alone runs (1.07 world steps a frame, in ms) and labels it derived. Making it a real measurement means extracting a headless loop module, which is a change to the game and belongs in its own pull. The arena case calls src/rl/arena.ts step() directly — scripts/train.ts --bench is untouched, and nothing is rebuilt or written.

To look at: scripts/bench.ts (the case table and derive), and scripts/bench.test.ts, which runs the harness over four tiny one-repetition cases — it checks the row-per-case shape, that --json parses to the same rows, that --case bogus, a traversal-looking name and an unknown flag all exit non-zero, that a do-nothing body still reports a non-negative median, and the budget arithmetic against a hand calculation (1562.5 µs a step is 10% of a 15.625 ms tick). bun test: 193 pass, 0 fail, 3.3 s.

🤖 Generated with Claude Code

Closes #20

commented

Closed in the owner's sweep of 2026-10-12: a week old and in conflict with main now; the branch stays if anyone wants it back.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs