# game-kit The shared infrastructure of Wiz-War and Waving Hands, extracted so the next game starts with all of it in place: the hall, room codes and tables, the Peanut Gallery (and the host's leave for it to talk), table talk, rematches, seats that travel between devices by phrase, the keeper's bell, append-only ledgers replayed through a deterministic engine, the rules revision, the reports desk, the deploy script with its determinism gate, nightly rollup and backup, Sentry with Slack alerts, and the visitors, pulse and reports skills for Claude. The game itself is one file. `src/lib/game/index.ts` implements `GameSpec` (see `src/lib/game/spec.ts`); the server, the client store, the hall and the ops tools never look past it. The template ships with a demo game, High Card, so everything runs before you have written a line. ## Start a game ./new-game.sh "" [port] [domain] That copies `template/` to `~/projects/`, fills the name, port and domain in, initialises git, installs dependencies, and prints the steps that remain: write the game, fill in the hall and rules and guide, create the droplet and the Sentry project, deploy. `CONVENTIONS.md` is copied to the new project as `docs/conventions.md`; it is the house style. Run the demo locally from a new project: npm run server # the game server on its port npm run dev -- --host ## What is where template/ src/lib/game/spec.ts the contract a game implements src/lib/game/index.ts the demo game; replace it src/lib/net/ client.ts (calls, held seats, socket), room.svelte.ts (the room store), talk.ts, view.ts src/lib/components/ Hall, Lobby, TableTalk, ReportSlip, Board (demo; replace it) src/routes/ the hall, /join/[code], /rules, /guide server/src/ index (routes), rooms (game-agnostic), store (ledger), reports (the desk), ratelimit deploy/ deploy, setup, Caddy, systemd, cron, gate + replay, backup, rollup, pulse, visitors, Slack alert, reports tools .claude/skills/ -visitors, -pulse, -reports Placeholders: `__SLUG__`, `__NAME__`, `__PORT__`, `__DOMAIN__` are filled by `new-game.sh`; `__IP__`, `__SENTRY_DSN__`, `__SENTRY_PROJECT_ID__`, `__SENTRY_SLACK_INTEGRATION__` and `__SLACK_CHANNEL_ID__` wait until those things exist. ## What the kit is, and is not The model is copy and diverge. A new game starts as a copy of the template and then goes its own way; the two games that came before it are not instances of the template and were not rewritten to be. The kit holds the reference copy of the shared parts and the conventions they follow, so a third game starts from the best current version of everything. Drift is meant to be visible, not prevented: ./drift.sh ../waving-hands # how far each shared file has wandered `drift-map/.txt` pairs files when a game's layout differs from the template's. When a game grows something every game should have (the gallery and the reports desk were both born in one game and ported to the other), bring it back here, with placeholders, so the next game inherits it, and read the drift before assuming the kit has it. The contract is simultaneous rounds: every seat that needs input submits, then the round resolves; turn-at-a-time games fit as the case where one seat needs input at a time. A game of single commands with out-of-turn interruptions, Wiz-War's shape, does not fit and keeps its own server.