Files
station-master/README.md
T
2026-07-31 07:19:57 -04:00

61 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Station Master
A railroad operations game set in the era of timetable-and-train-order railroading (18401950),
being built as a multiplayer browser game with an authoritative server.
You are the Station Master of a lineside Office on a shared eastwest Division. Trains run to a
timetable with no radios — just pocket watches and written orders. You switch cars, work freight and
passengers, and take your turn as Superintendent deciding whether it is safe to clear a following
train into an occupied Subdivision. Get that wrong and two trains meet at speed.
## Status
Design complete, implementation just begun.
- **Rules** — fully specified. Ten gaps in the original prototype rules found and resolved.
- **Card faces** — every card's printed values specified.
- **Architecture** — six documents, including a 20-component build plan.
- **Code** — build step 1 of 12 complete: card catalogue, state model, seeded RNG.
The MVP target is **solitaire, one Office, a fixed number of Days**, with a server talking to a
single browser.
## Layout
```
station-master/
├── docs/
│ ├── rules/ ← the ruleset, card reference, glossary, decision record
│ └── architecture/ ← how it is built, and what the pieces are
├── src/
│ └── engine/ ← pure rules engine: no I/O, no clock, deterministic from a seed
└── test/
```
Start with [`docs/design.md`](docs/design.md) — it indexes everything.
## Development
Requires **Node 22.18+**, which runs TypeScript directly by type stripping. There is no build step.
```sh
npm install
npm test # node --test
npm run typecheck # tsc --noEmit
```
Because Node strips types rather than compiling them, the codebase is restricted to **erasable
syntax**: no `enum`, no parameter properties, no namespaces. `tsconfig.json` enforces this.
## Design notes worth knowing
- **The rules engine is pure.** No I/O, no clock, no sockets, and all randomness derives from one
stored seed — so any game is exactly replayable, and a full game can be driven in a unit test with
no server at all.
- **It has two entry points, not one.** `apply(state, intent)` for player actions, and
`advance(state)` for everything the game does on its own — Mainline movement, collisions, the Stage
clock, Superintendent rotation.
- **State is `fold(events)`.** The event log is the source of truth, which is what gives reconnection,
restart recovery and post-game replay from a single decision.
- **Never call `Math.random()`.** One ambient random call silently breaks replay.