The third release from the audit; nothing a player sees changes. CHANGELOG has the detail. The 0.4.9 playtest line is no longer maintained (Jesse, 2026-09-29): the deploy rule that existed for it is gone and #85 is moot. The table test (#39 #35 #42a #40) is closed — every line of the checklist was met at a table. #46 is done and cannot regrow: the 36 unused declarations are removed and `noUnusedLocals`/`noUnusedParameters` are on; two of them were dead bot functions from rejected candidates the round said it had deleted. The documents no longer teach `trainCapSlack` (a knob that throws), point at `as-built.md` (deleted in 0.8.2), model `officeType` (the engine says `tier`) or describe `collisionOccurred` (never emitted); the README's account of bot flags now matches the bot's. Five playtest saves committed in `docs/` against the repository's own rule are in the ignored `playtests/`. What the audit found and did not fix is written down as TODO #112-#117, each with its reason. #112 is `docs/plans/structure.md`, the proposal for `http.ts`, `main.ts` and `check`. #117 — `/api/save` hands a seat the seed mid-game — waits on a conversation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FrCWubm9GAftYCm2hWdKwK
123 lines
8.4 KiB
Markdown
123 lines
8.4 KiB
Markdown
# 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.
|
||
|
||
## For players and testers
|
||
|
||
Written to be handed to somebody who is about to play, rather than to somebody building the game.
|
||
|
||
| Document | What it is |
|
||
| --- | --- |
|
||
| [`quickstart.md`](quickstart.md) | **Start here if you have never played.** The point of the game, how a Stage runs, what is on screen, how you win, a first twenty minutes, and what to report. |
|
||
| [`rules.md`](rules.md) | **The rules in full**, as the engine actually runs them, with a FAQ. |
|
||
| [`home-deck.md`](home-deck.md) | How the Home Office deck is dealt, drawn and played out. |
|
||
| [`mainline-deck.md`](mainline-deck.md) | The Mainline cards, how the deck is dealt, and what a card does to a train crossing it. |
|
||
| [`components.md`](components.md) | Rolling stock, the two yards, Crew Trays, the Fedora, the D12. |
|
||
|
||
**None of these carry a version in the filename**, and that is deliberate (Jesse, 2026-09-21): they
|
||
are kept current with every release rather than published as editions, so the name is always the
|
||
latest and each says at the top which build it describes. Four of them were stamped `v0.4.5` until
|
||
v0.8.0.17 — the prototype rules edition they were first written against, never the version they
|
||
described — which read as though they documented a build five minor versions old.
|
||
|
||
## 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) | **⚠ SUPERSEDED** — an invented 52-card placeholder, kept for its economy summary and its history. For what is printed on every card, read the generated tables in [`home-deck.md`](home-deck.md) and [`mainline-deck.md`](mainline-deck.md). |
|
||
| [`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.8.2.** Rules formalized, card faces specified, architecture documented, and the game
|
||
playable **solitaire and multiplayer** in a browser against an authoritative server. 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, the
|
||
playable page — and the server: lobby, game codes, seating, bots, per-seat reconnection, persistence
|
||
by replaying the intent history, and an ordered replay of other players' turns on each player's own
|
||
screen. It ships as a StartOS package. **999 fast tests and 35 simulation tests.**
|
||
|
||
**What is not.** The 22 opponent-directed cards — the Action and Space-use categories — are held out
|
||
of every dealt deck until they have an implementation, along with the two defensive cards whose only
|
||
purpose is to answer them. Real audio: everything the game plays is synthesised from oscillators.
|
||
|
||
**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.
|
||
|
||
**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.**
|
||
The generated tables in [`home-deck.md`](home-deck.md) and [`mainline-deck.md`](mainline-deck.md)
|
||
carry every card face as the game actually deals it, 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.
|
||
|