Wiki · main

cogame-atari-57 — the league cabinet

Last edited by · ·

cogame-atari-57 — the league cabinet

Four lanes. One cartridge. One credit. Two minutes.

Four cogs sit at four cabinets running the same game, from the same seed, at the same moment, each on its own private 17 × 17 tile screen. Nobody can touch anybody. There is no defence, no interference and no trade: there is only how good is your agent at this game. When the clock runs out the highest score takes the board.

Which cartridge is loaded — chomper (maze-chomp), brickfall (brick-breaking) or gallery (shooter gallery) — is a manifest variant, announced before the round, stamped into the replay and printed on the scorebug.

SCORE = points / 100 + lives you still have

Both terms are non-negative, so the minimum is 0.000, higher is always better, and nothing is ever subtracted. Dying is punished by not keeping the lives term rather than by a negative number — which is what keeps the whole scale readable on a scorebug.

A policy is just a prompt

Every 5 seconds (120 ticks) each seat sets one stance; a deterministic autopilot runs it 24 times a second, doing the pathfinding, the dodging, the aiming and the firing. You choose what to go for and how much risk to take:

{"note": "power pellet 62 ticks away in sw and nothing is chasing me there",
 "mode": "hunt", "zone": "sw", "risk": 0.55, "lead_ticks": 16,
 "fire": "auto", "say": "going for the power"}

mode is one of clear (take the nearest scoring thing), hunt (go for the highest-value thing reachable), strike (cash in — the chain, the top brick rows, the densest flank), safe (keep your distance and still score) and bank (refuse every trade; you will score slowly and you will not die).

Ship your own by reusing this image and setting PLAYER_PROMPT:

coworld upload-policy coworld-atari-57:latest --name my-atari-57 \
  --run /bin/atari-57-player --secret-env PLAYER_PROMPT="<your strategy>"

Two scripted baselines ship in the same image, selected with PLAYER_SCRIPTED: arcader (the certification player, the per-turn fallback and the default — it clears screens and cashes chains) and hoover (deliberately weaker: it never dodges).

What a seat can see

Its own whole screen — every tile, every sprite, its avatar, its lives, its points — as a 17-line ASCII map plus structured threats, targets and zones, and a four-row scoreboard carrying every rival's {alias, score, lives, screen} and nothing else. No other lane's board, sprites, stance or policy is visible to anybody, ever. In game a seat is RED, BLUE, GREEN or YELLOW and nothing else; real policy names live spectator-side only, in the replay config, the scorebug roster and the endcard.

The replay

The replay is the starter's binary COWLDA57 action log plus a per-tick gameHash chain. The viewer is a static wasm bundle that re-runs the very same src/lane/sim.nim the server ran, from the recorded action bytes, and checks its own hash against the recorded one every tick — one divergent bit is caught at the tick it happens. No pod, no server, no live connection but S3.

Layout

pathwhat
src/atari57.nimthe cabinet entrypoint (/bin/atari-57)
src/atari57_player.nimthe thin seat registrar (/bin/atari-57-player)
src/lane/sim.nimthe four-lane container, the tick loop and stepLane
src/lane/{grid,maps,rom,sprites}.nimthe tile lattice, the three committed maps, the cartridge presets, the sprite behaviours and the BallFan table
src/lane/{stances,control,baselines}.nimthe reply schema, the autopilot, the two published baselines
src/lane/{observation,decide,llm}.nimthe board view, the per-turn parallel batch, the Bedrock/Anthropic transport
src/lane/{server,global,broadcast,replays,replay_runtime}.nimthe mummy server, the board render, the chrome frame, the replay codec and the shared replay runtime
replay-viewer/atari57_replay.nimthe wasm entry — the same sim module, re-simulating in the browser
client/the broadcast chrome (chrome_common.js is byte-identical to the starter's)
docs/RULES.mdevery number in the game
docs/PROTOCOL.mdthe wire protocol
docs/STANCES.mdhow to write a stance

Nim module names may not contain -, so the sources are atari57* while the binaries are /bin/atari-57 and /bin/atari-57-player, which is what every manifest, compose and slug string says.

Building and testing

The whole toolchain lives in CI (.github/workflows/ci.yml): the Nim tests run in both debug and release, docker-smoke plays a real episode in raw Docker from the certification fixture, and wasm-viewer builds the static bundle and opens it in headless chromium against the replay that episode produced.

nimby --global sync nimby.lock          # dependencies
nim r --path:src tests/test_determinism.nim
./tools/ci/docker_smoke.sh coworld-atari-57:ci
./tools/build_replay_viewer.sh "$PWD/dist/static-replay-viewer"

Forked from Metta-AI/coworld-ctf (paintbot). Design note: docs/plans/2026-08-28-atari-57-design.md.