# Station Master — design index Station Master is a tabletop railroad-operations game set in the era of timetable-and-train-order railroading (1840–1950), being developed into a multiplayer digital game: players connect from a web browser and an authoritative server manages lobbies and game state. ## Source of record - `StationMasterPrototypeRules.pdf` — the original prototype rules - `StationMaster-PrototypeTurnChart.pdf` — the 12-Stage turn chart - `Deck cards2.xlsx` — the complete card list (115-card deck, 104 track pieces, 12 start cards) - `Mainline Cards.pdf` — the ten Mainline card types with their speeds and entry points - `Trains3.pdf` — all 22 train cards with names, speed class, consist and operating rules - `tracks.png` — card art for track and industry cards These stay as-is. Everything below is derived from them. > **The last four arrived after the engine was built** and expand the game roughly threefold. See > [`rules/implications.md`](rules/implications.md): much of what is recorded below as decided was a > placeholder for exactly this material, and the balance measurements in Gap 12 were taken against a > ruleset that does not match the design. ## Rules | Document | What it is | | --- | --- | | [`rules/rules-v0.1.md`](rules/rules-v0.1.md) | Faithful markdown transcription of the PDFs. No corrections. The baseline everything diffs against. | | [`rules/rules-v0.2.md`](rules/rules-v0.2.md) | **The working ruleset.** v0.1 with all ten gaps resolved, each change marked with its gap number. | | [`rules/card-reference.md`](rules/card-reference.md) | What is printed on every card, plus the economy summary. The spec an engine or a print-and-play layout consumes. | | [`rules/glossary.md`](rules/glossary.md) | Every defined term, alphabetized. | | [`rules/open-questions.md`](rules/open-questions.md) | All thirteen gaps, each with the options considered, the decision, and the rationale. | | [`rules/implications.md`](rules/implications.md) | **Read this first.** What the four recovered design files (`Deck cards2.xlsx`, `Mainline Cards.pdf`, `Trains3.pdf`, `tracks.png`) change — and which decisions they supersede. | ## Architecture Target is **small self-hosted** scale: a handful of concurrent games, hosted on a website or as a StartOS service. Stack is deliberately undecided; these documents describe what any implementation must do. | Document | What it is | | --- | --- | | [`architecture/components.md`](architecture/components.md) | **The project plan.** All 20 buildable pieces — where each runs, when, MVP vs finished size — plus dependency graph and build order. | | [`architecture/overview.md`](architecture/overview.md) | Why the server is authoritative; state/intent/event split; transport; the rules-engine boundary. | | [`architecture/game-state.md`](architecture/game-state.md) | The entity model, and the constraints that are easy to lose. | | [`architecture/protocol.md`](architecture/protocol.md) | Intents, events, and per-player view redaction. | | [`architecture/lobby-and-sessions.md`](architecture/lobby-and-sessions.md) | Create/join, seating, reconnection, persistence. | | [`architecture/deployment.md`](architecture/deployment.md) | Plain web host vs StartOS service — and the one constraint that differs. | | [`architecture/multiplayer.md`](architecture/multiplayer.md) | **The multiplayer build plan.** The authoritative server as a layer added on top, with solitaire unchanged and server-free — plus every decision taken, listed for review. | ## Current status **v0.4.3.** Rules formalized, card faces specified, architecture documented, and the game playable solitaire in a browser. See [`../CHANGELOG.md`](../CHANGELOG.md) for what each version changed and [`../TODO.md`](../TODO.md) for what is open; this section is the shape of the project, not a running tally, because a hand-maintained tally is what drifted last time. **What is built.** The rules engine, the developer bot, the balance harness, the replay viewer and the playable page — components 1–7, 17 and 18 of [`architecture/components.md`](architecture/components.md). A game can be saved, shared, replayed and stepped back through. **493 tests.** **What is not.** The server. Phases 0 and 1 of [`architecture/multiplayer.md`](architecture/multiplayer.md) landed in v0.4.0 — seat and player are separate, turn state is per player, and the page talks to a `Session` rather than to the engine, so a `RemoteSession` drops in without the page changing. Phase 2 onward is **deliberately held** until the two provisional rules introduced in v0.3.0 have been played at a table: changing a rule after the wire format is live costs far more than changing it before. Also unbuilt: the 22 opponent-directed cards and real audio. **Balance is not where it should be, and no conclusion should be read from the revenue numbers yet.** The rebalance pass is deliberately deferred until the rules stop moving — card counts, industry counts and the track mix all need moving together. `TODO.md` carries the standing distortions and the measurements behind them. **Three rules are genuinely open**, and they are the reason the README does not claim the rules are finished: where the Local's coach stands while its engine works (a §A.4 question, not a train-card question); Poling, the one card in the deck with no defined behaviour; and whether a Heavy Grade's orientation is rolled or chosen at setup. Thirteen gaps in the prototype rules were found and closed; these three came after. **The event log narrates; the intents reconstruct.** Settled in v0.4.0 after the documentation had claimed `state = fold(events)` for months. It is not true — the phase driver mutates state and then describes it — so the canonical record is `{ seed, history: Intent[] }` and persistence will be built on that. [`architecture/protocol.md`](architecture/protocol.md) §3 has the reasoning; `test/events.test.ts` pins it. **The economy, in one line:** Local Operations actions are the main currency — one per Stage, twelve per Day — but **inbound work bypasses them**, which is where the game's variance comes from. See `card-reference.md` §7. **Stack: TypeScript**, chosen so the engine runs in both the server and the browser — one implementation of the movement rules, and instant affordances without a round-trip. Node 22 runs TypeScript natively, so there is no build step during development, which also means **erasable syntax only**: no `enum`, no parameter properties, no namespaces. Running alongside, and independent of all of it: **print-and-play components.** `card-reference.md` specifies every card face, so layout and art are the only remaining work before a table playtest — which answers the one question simulation cannot, whether it is fun. Run the harness with `node src/sim/harness.ts [games] [length]`. **Watch a game:** `node src/sim/replay.ts --seed 1234 [--length standard] [--out replay.html]` writes a self-contained HTML file — open it in any browser and step through the game. It shows the Division, the Office Area grid, every facility's boxes and `MEN|AT|WORK` track, plain-English narration of each event, and a **Blocked** panel explaining why nothing is moving. Running alongside, and independent of all of it: **print-and-play components.** `card-reference.md` specifies every card face, so layout and art are the only remaining work before a table playtest — which answers the one question simulation cannot, whether it is fun.