A browser kart racer for up to eight friends: one link, a four-letter room code, no install, no account. Rust simulation shared between the browser and the server; Three.js for the picture.
Play it at https://formulanone.sushimafia.com: Solo race against seven bots, or Create room and send the code to friends.
- One sim, two hosts. The rules of the game live in one Rust crate,
crates/sim, with a deterministicstep(state, inputs, dt). The server runs it natively as the authority; the browser runs the same code as WebAssembly to predict its own kart, then reconciles with the server's snapshots. CI replays recorded races natively and in wasm and fails if the two disagree by a single bit. - A decision per file. The PRD is issue 1, and each decision in it is a
record in
docs/adr: what was chosen, what it rejected and what it costs. A changed decision gets a new record, never an edit. - A style guide that is checked.
docs/style-guide.htmlshows every graphic the game draws, with the palette, the type and the rules for the next one;tools/repo-checksholds its palette and liveries to the code.docs/GLOSSARY.mdfixes the words. - Built with an agent. The project is built with Claude Code, one
issue at a time: test first, a review pass,
pnpm check, then a pull request the author reviews and merges.CLAUDE.mdis the brief it works from, and the quickest map of the repo for a person too.
Requirements: Rust stable (via rustup; rust-toolchain.toml adds clippy,
rustfmt and the wasm target), cargo-nextest, wasm-pack, Node 22 and
pnpm 11.
cargo install cargo-nextest wasm-pack --locked
pnpm install
pnpm build:bridgepnpm build:bridge compiles the bridge crate to WebAssembly into
apps/web/src/generated/bridge (ignored by git). The web app, its typecheck
and its tests need it; rerun it after changing crates/sim or
crates/bridge.
| Side | Build | Lint | Test |
|---|---|---|---|
| Rust | cargo build --workspace |
cargo clippy --all-targets -- -D warnings |
cargo nextest run |
| Web | pnpm build |
pnpm lint |
pnpm test |
pnpm test:e2e runs the Playwright smoke test against the Vite dev server
(run pnpm --filter web exec playwright install chromium once).
Two terminals from the repo root:
cargo run -p server # HTTP and the WebSocket fallback on 0.0.0.0:8080
pnpm --filter web dev # Vite on http://localhost:5173, proxying /api to 8080Open http://localhost:5173. WebTransport is off without TLS_CERT and
TLS_KEY, so the client uses the WebSocket; deploy/README.md has the full
stack with Caddy, Prometheus and Grafana. The server's metrics are at
http://127.0.0.1:8080/metrics once a room has a player in it (ADR 0018).
infra/ describes the author's own deployment on AWS, not a template; to
host the game yourself, use the Compose stack under deploy/, as
Hosting your own sets out.
Keyboard only. Arrows and WASD do the same thing.
| Action | Keys | Notes |
|---|---|---|
| Steer | Left/Right, A/D | |
| Throttle | Up, W | |
| Brake | Down, S, Q | Reverses from a standstill. Q leaves W free to stay held through a brake drift. |
| Hop | Space | Land while steering to start a drift; keep it held, let go for the mini-turbo. |
| Item | Shift | Fires the held item. Keep it held to trail a hazard behind you until released. |
| Look behind | E | While held. |
Rocket start: hold the throttle from the first half of the 2 through GO for the full boost, from the second half for a weaker one; hold it from before the 2 and the kart stalls. The beeps count 3, 2, 1 and GO.
Slipstream: follow a kart closely for a second and its wake tows you past the tuned top speed, for as long as you hold it and a second after you pull out; wind lines build as the tow charges.
CLAUDE.mdfor the layout, the dependency rule and the commands.docs/GLOSSARY.mdfor the vocabulary.docs/adr/for the decisions, numbered in the PRD's order.
The code is MIT. The art and sound are CC0 1.0, made in this repo
apart from one Kenney font; assets/LICENSES.md
records where each came from (ADR 0066). Contributions follow
CONTRIBUTING.md.
Formula None is a parody and is not affiliated with Formula One or any circuit.
