Initial commit
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# Station Master
|
||||
|
||||
A railroad operations game set in the era of timetable-and-train-order railroading (1840–1950),
|
||||
being built as a multiplayer browser game with an authoritative server.
|
||||
|
||||
You are the Station Master of a lineside Office on a shared east–west 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.
|
||||
Reference in New Issue
Block a user