# The demo games: conventions

Each game lives in `demo/<game>/` with exactly these files:

- `index.html`: the page. `<meta name="author" content="Lars Rocha">`, a `<title>… · sitoolz demo</title>`, `<link rel="stylesheet" href="../demo.css">`, a `<nav>` with links to `../` (the demo), `../../maps.html` (the showcase) and `HOWTO.md`. Loads sitoolz's JavaScript with plain script tags from `../../../sitoolz/js/` (globals: `RulerLand`, `SITerrain`, `CityLaw`, `SIStamps`, `SIRails`, `SIQrand`, `SIGamerng`, `SIIndexrng`, `SIPrimes`, `SIClocks`, `SIPuzzles`, `SISpn` (+ `spn.data.js` first), `SIForests`, `SILogic`; `rangeblends.js` before `rulerland.js` before `terrain.js`; `blake2b.js` before `indexrng.js`). Fixtures by `fetch("../../../sitoolz/fixtures/<name>.json")`.
- `game.js`: the game. Exposes `window.Demo = {ready: true, state: () => ({...}), act: (name, ...args) => ...}` so a smoke can drive it.
- `HOWTO.md`: the guide, in this order: **What it imports** (the script tags and the functions used), **The twenty lines that make it** (the core of the game as a snippet), **How to change the law** (which knob changes what, with one example), **How to verify it** (the fixture and test that prove the arithmetic the game stands on), **What was missing** (anything the game needed that sitoolz did not have; leave the section with "Nothing." if so), and the screenshot `![](shot.png)`.
- `smoke.cjs`: `const {browser} = require("../../cdp.cjs")`; opens `http://127.0.0.1:8025/sitoolz-showcase/demo/<game>/`, waits for `window.Demo && Demo.ready`, plays a few actions through `Demo.act`, asserts on `Demo.state()`, saves `shot.png` beside the page, prints `PASS <game>: …`. Chrome is headless on 9223; `~/mywork` is served on 8025.

Rules: the game is built from sitoolz alone (no code copied from range-arcade-editions; read it for the feel, then rebuild from the kit); the arithmetic comes from the library, the page only draws and listens; phone-first (44px targets, no horizontal scroll at 390px wide, canvas scales with `width:100%`); keyboard and touch both work; nothing personal on the page; Lars Rocha is the author shown; the game reads well with no explanation (a lede of two sentences at most). Keep `game.js` under about 300 lines.
