Performance on main
Each game records its performance in test/profile-history.jsonl, beside its count baseline. Each line is one head measured on one machine, so cat shows the record and git log -p shows it over time. The history file is the record. The Main Performance dashboard that charted the same numbers was paused on 2026-09-25 and is retired.
The number of record is the platform’s frame budget: a game holds 144 fps when no more than 1% of its frames take longer than 6.94 ms. Not every game holds it yet. In each game’s latest row on a Ryzen 9 3900X with an RTX 3070, from 2026-09-29 and 2026-09-30 with vsync off, the arena, the example, the mmorpg and Sled, with a p99 of 2.0 to 5.1 ms, hold it. Holdfast, with a p99 of 11.8 ms and 44% of its frames over 6.94 ms, does not. The engine’s own frame, the stock scene with one character and no game systems, costs at most half of the 6.94 ms budget, 3.47 ms, and the bench page measures it. A row holds the following:
- The head’s SHA and commit date.
- The machine’s CPU, the renderer string that names its GPU, Chromium’s version and the page’s viewport.
- The spins before and after the runs, in milliseconds, and how many other node and chrome processes were running.
- The steps and frames the loop took over the vsync-off run.
- Each run’s timings: the p50 and p99 frame, the share of frames over its budget, and the main-thread and GPU p50.
- The counts the check compares with the baseline.
spawnite play profile --check appends the row, so a row lands whenever a session runs a game’s perf target, such as after a merge to main. A check whose spin reads the machine as loaded appends no row, as the frame page describes. Compare rows only on the same machine: another CPU or GPU reads different timings for the same head. One row is one sample, and load moves a timing by about 20%, so read a change across several rows rather than from one.
spawnite play profile --check in a game’s folder checks that game. A check holds a lock while it profiles, so a second check, from this session or another, waits for it rather than sharing the machine. When a count rose, the check names the merges since this machine’s previous row that touch the game, packages/engine or packages/assets. --update-baseline=<count>,<count> rewrites only the counts it names. The frame page says how each works.
Check what a game looks like
Section titled “Check what a game looks like”To check that a change to a material, a shader, a look or an asset kept a game’s colour and quality, run spawnite play compare in a running playtest. It shoots each shot the game’s test/shots.json names and compares it with the accepted image in test/shots. Like the perf check, it gates nothing: run it on request, and file a difference as a follow-up.
Each entry of test/shots.json names a shot:
name: the accepted image’s file name,test/shots/<name>.webp.scene: the registered scene to shoot, which the command opens before it steps; the game’s start scene without it. A room game’s shots take none.steps: the step to shoot on, counted from the page’s load, or from the scene’s opening where the shot names one. In a room game, the room runs before its page joins, so the steps count from where the room stands, and a second run needs a freshplay start --replace.size: the page’s size, such as960x540;1280x720without it.- The camera, as the screenshot command’s flags name it:
view,camera,eyewithtarget, orframingwitharound. Without one, the shot is one render of the player’s camera. hud:trueto shoot the page as it shows, with its HUD.share: the share of pixels that may differ,0.01without it.
For each shot, the command prints the share of pixels whose any channel differs by more than 8 of 255, and pass or fail. It writes a difference image, with the changed pixels red, to the temp folder, and exits 1 when a shot fails. --accept writes the shots as the accepted set.
The accepted images are the GPU’s. Two runs of one build on one GPU differed in at most 0.09% of pixels in the five games measured, and 2.9% to 4.8% in arena, whose spawn pads animate on the room’s clock, so its shot allows 6%. Software rendering differs from the GPU in about 3% of pixels, close to the 5.7% a faint tint changes, so the 1% share that catches the tint also fails software rendering. On a machine with another GPU or none, run --accept on your branch’s base first and compare your change against that set, as you compare perf rows only on the same machine.