v0.8.2 — every district opens on a Depot, and the docs are pages now

A second-digit bump for a playtest read back against the save file. Nine questions
were asked of one three-Day game; three were bugs, three were the rules working
and undocumented, three were decisions. Every save on the test server was replayed
against this build BEFORE release, which is how the cost of each rule was known
before it was chosen rather than discovered after.

EVERY DISTRICT OPENS ON A DEPOT. A Whistle Post has one A/D track and is not a
Passenger Facility, so the opening of every game was spent unable to work a
passenger and one arrival away from a collision. Two A/D tracks and passengers
from Stage 1 now; "Players start with Whistle Posts, not Depots" is the harder
game, set when the game is created. The deck follows the choice — starting on
Depots the four Depot upgrade cards are left out, because an upgrade must be to
the next tier and a Depot card at a table of Depots is a dead draw. How much
easier it is showed up as a test failure rather than an argument: the cue-coverage
pool needed widening from 24 seeded games to 60 before it held one collision.

NO SAVE WAS STRANDED BY IT, which took care. This is the one house rule that
changes how a game is DEALT rather than how it plays, so replaying a save under
the wrong opening is a different railroad from intent one — silently, with no
error. `withSavedOpening` fills it on the replay paths ONLY. Putting it in the
resolver instead made a fresh Cutthroat game deal Whistle Posts and read as
Custom, which is how the distinction was found.

THREE BUGS, ALL REPORTED FROM ONE GAME AND ALL CONFIRMED ON ITS SAVE.

An Office held TWO TRAINS ON ONE A/D TRACK. The capacity test passed with nothing
standing, the train the Interlocking had been holding at the Limits was moved into
the free slot, and the arriving train was pushed in after it without anyone asking
again whether there was room — so the collision §8.3 calls for never happened. The
held train keeps priority; the newcomer now takes the consequence it would have
met had the held train arrived first.

THE HISTORY FROZE, permanently, and the log cap was not really the cause. Each
seat's "what have I sent you" bookmark was an INDEX into an array the game trims,
so once a seat's bookmark reached the limit the slice returned nothing for the
rest of the game — at a different moment per seat, because each holds its own.
That game's log ended at exactly the cap. Lines carry a sequence number now, which
survives trimming; proven by pushing twice the cap through a simulated seat.

§8.1 ASKED THE WRONG QUESTION TWICE. "Trains may pass" returned `clear` before the
Subdivision was looked at, so a train entering a Double Track was released however
busy the rest of it was — that, not anything about Control Points, is what let
Train 8 out with no ruling. And a train standing at an Office was invisible to the
scan, so one about to re-enter the very Subdivision being entered counted for
nothing. Capacity is the test, not presence: a Depot with a track free is not in
the way; a Whistle Post with its one track taken is.

THINGS THAT HAPPENED SILENTLY NOW SAY SO — a train held against a facing one, a
train released from the Limits (a side effect of somebody else's arrival, so it
simply appeared at the Office), and the train an Interlocking is holding, whose
explanatory tooltip has existed since #99 with NO renderer ever reading the flag.

WHERE A MOVE IS REFUSED, AND WHY. `exploreMoves` decides where the rails go and the
pick-up restrictions are enforced afterwards in `check`, so a square the rails
reached and the card forbade was reachable, un-offered, and absent from the block
list with nothing said. Those squares are blocked with the rule that blocks them
now, and the reasons are got by ASKING `check` rather than re-deriving: a second
implementation of the rules is exactly the failure the block list exists to avoid.
A train may also always recover its own caboose — X13 prints "may drop but not
pick up anything", and a train needs its caboose to be made up, so one that parted
with it could never legally leave again.

RULES DECIDED IN SEPTEMBER AND APPLIED HERE. A Modifier must sit square against its
host, no diagonals. A passenger Modifier may not be played at a Whistle Post. Both
were built, measured, held back for a fortnight so a playtest could finish, and
applied now. A Second Section costs its card: `SECOND_SECTION` was declared in
content.ts and never dealt, so the action was free and the bot ordered 26
accidental ones in a measured round. The card is dealt and spent — gating on a card
the deck never holds would have deleted the mechanic rather than fixed it.

THE DOCUMENTATION IS A SET OF PAGES, not five text files served as text/plain — a
card reference is mostly tables, and as plain text a table is rows of pipes.
Markdown is still the one copy; the build renders it, and publishes the .md beside
each page. No Markdown library: this project has no runtime dependencies and one
would be a poor first. The pages add what Markdown cannot carry without drifting —
a nav across the set, a contents list built from the headings actually rendered,
an anchor on every heading, a 70-character measure, and tables that are tables.
They print as ink on paper.

The references caught up with the rules, checked rather than assumed: two
statements had gone from stale to misleading (the Quickstart told a new player to
"get a Depot down as soon as one appears"), and four rules nobody could look up
are written down — the Office tier table, §8.1 in practice, what the Circus Train
pays for, and that a Realignment can be a card with no legal target.

Adding one card to the deck reshuffles every seeded deal, which broke five
fixtures. Each was a seed meaning "a game like this" — TODO #84, exactly — so
seeds moved and pools widened rather than assertions weakening, and the clearance
fixture pins its terrain the way `enhancements.test.ts` already does. The three
published replays were re-recorded.

Closes TODO #40, #42a, #108, #109 and #110.

1046 fast tests and 35 sim tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MUizFYCMHRWhbWwXhp7WPR
This commit is contained in:
Jesse.Markowitz
2026-09-23 07:07:21 -04:00
co-authored by Claude Opus 5
parent 517238a727
commit 3befc420da
66 changed files with 6828 additions and 3324 deletions
+60 -48
View File
@@ -1,6 +1,8 @@
# Station Master — Quickstart
**For a tester who has never played. Describes the game as built at v0.8.1.0** (2026-09-22).
**Version 0.8.2** · 2026-09-23
For a player who has never played.
Read this once before you sit down. It is about twenty minutes of reading and will save you an hour
of confusion. The deeper references are listed at the end.
@@ -32,21 +34,26 @@ and do not wait.**
## 2. How you win
The game runs a set number of **Days** — five by default. Each Day is **12 Stages**, which you can
think of as two-hour clock periods from midnight.
A game runs for a set number of **Days**, chosen when the game is created. Each Day is **12
Stages**, which you can think of as two-hour clock periods from midnight.
At the end of the last Day:
At the end of the last Day, the table's **combined Revenue** is checked against a floor. **Miss it
and everybody loses**, however well you personally did — this is the number to watch. The floor is
worked out from the number of players and Days when the game is dealt, and whoever sets the game up
can raise or lower it.
1. **The table's combined Revenue is checked first**, against a floor of **3 × players × Days**. At
three players over five Days that is 45. **Miss it and everybody loses**, however well you
personally did. This is the number to watch.
2. **Co-op:** meeting the floor is the win, together.
3. **Competitive:** meeting the floor puts the game on, and the **highest individual Revenue** wins.
4. **Solitaire:** meet the floor by yourself.
Clear the floor, and how you win depends on the game type:
- **Co-op** — clearing the floor is the win, together.
- **Competitive** — clearing the floor puts the game on, and the **highest individual Revenue**
wins. Everyone is still working towards the same floor first.
- **Cutthroat** — competitive, with the opponent-directed cards in play, so players can act against
each other directly. Those cards are not implemented yet, so this plays as Competitive today.
- **Solitaire** — clear the floor by yourself.
**Collisions can end it early and badly.** Breaching the collision limit stops play at once in a
collective loss — the railroad has been declared unsafe. Default limits are 3 in one Day and 5 in
the game.
collective loss: the railroad has been declared unsafe. The limits are configurable, and can be
switched off entirely.
**Falling short offers another Day** rather than just ending, so a game that misses the floor can be
played on. A game stopped by collisions cannot.
@@ -59,11 +66,11 @@ played on. A game stopped by collisions cannot.
| A passenger getting off at your platform | 1 |
| Completing an outbound freight load | 1 |
| Completing an inbound freight unload | 1 |
| A train completing its run across the whole Division | 0 by default, to every player |
| A train completing its run across the whole Division | paid to every player; usually set to 0 |
Those rates are set when the game is dealt and can be changed. The default means **your score comes
almost entirely from working cars in your own district** — trains passing through pay nothing by
themselves.
Every rate is set when the game is dealt and can be changed. As they usually stand, **your score
comes almost entirely from working cars in your own district** — trains passing through pay nothing
by themselves.
---
@@ -100,7 +107,13 @@ Stage not spent switching.
## 4. The screen
Left column, top to bottom:
**Across the top:** your Revenue, the target, the Day and Stage, collisions, and the game code.
**When other players are acting**, their turns are replayed on your board a step at a time rather
than arriving already rearranged, with a `[N behind]` counter, **Pause** and **Skip**. Your own moves
are not replayed at you — they are already on your screen.
**The main display, on the left**, top to bottom:
- **The Division — west to east.** The shared main line: every Office and the Mainline cards between
them, with trains drawn where they are. **West is always on the left**, and a train's engine is
@@ -109,7 +122,7 @@ Left column, top to bottom:
outside the phases that change it, unless you pin it open.
- **History.** What has happened, most recent first.
Right column:
**The right-hand column:**
- **Your Move** — the buttons. If it is not your turn this is empty, and the board tells you who is
acting.
@@ -121,23 +134,20 @@ Right column:
- **Blocked — why nothing is moving.** *Read this panel.* When something will not work, this is
where the game explains why, in rules terms.
- **Facilities** — the load pipelines at each industry.
Across the top: your Revenue, the target, the Day and Stage, collisions, and the game code.
**When other players are acting**, their turns are replayed on your board a step at a time rather
than arriving already rearranged, with a `[N behind]` counter, **Pause** and **Skip**. Your own moves
are not replayed at you — they are already on your screen.
- **This Game** — the seed or your seat, the game code, the rules this game was dealt under, and
links to this guide and the other references.
---
## 5. Your first twenty minutes
## 5. Start with solitaire
Play a **solitaire** game first. It needs no server and nobody else, and it is the same rules.
1. Open the site, choose **Play solitaire**, accept the defaults, **Deal**.
2. **Stage 1 — Draw.** You start on a **Whistle Post** with almost nothing. Play a track card or two
to extend your Running Track, and get a **Depot** down as soon as one appears: it is the upgrade
that makes you a passenger facility and gives you a second A/D track.
2. **Stage 1 — Draw.** You start on a **Depot** with almost nothing else. Play a track card or two to
extend your Running Track. A Depot already works passengers and has two A/D tracks, so a second
train can stand at your Office without wrecking; a **Station** upgrade, when one appears, buys a
third track and another Porter.
3. **Build one industry** on a stub off the main — not on the Running Track itself, which the game
will not allow.
4. **Play a train card** when you get one. It rolls onto the timetable and then runs at that Stage
@@ -147,8 +157,6 @@ Play a **solitaire** game first. It needs no server and nobody else, and it is t
6. Watch the **Blocked** panel whenever you are stuck. It is usually one missing thing: no empty car
spotted, no loaded car in the yard, a full box, a locked industry track.
Then play a Day or two of multiplayer with bots filling the other seats, to see the table take turns.
---
## 6. Things that surprise new players
@@ -167,33 +175,37 @@ Then play a Day or two of multiplayer with bots filling the other seats, to see
- **Passengers may dry up completely.** Coaches move one way — boarding sends the emptied coach to
the Classification Yard, and it only comes back when the Division Yard is bare, which may never
happen. When it does, the yard panel warns you and passenger trains are made up empty. **This is
the rules working as designed**, not a bug; report how it felt, not that it happened.
the rules working as designed.**
- **Expedited trains leave the same Stage they arrived**, after the Cargo phase. Ordinary ones wait.
---
## 7. What to report
Most useful, in order:
1. **What you expected versus what happened**, with the Day and Stage. "Day 2 Stage 9, train 5 had
no coaches" is worth more than "passengers seem broken".
2. **Save the game** (the **Save replay** button) and send the file. A save is the seed and the moves
made, so it replays exactly and the bug can be looked at directly.
3. **Anything the screen did not explain.** If you had to guess a rule, that is a finding even when
the game was right.
4. **Anything you went looking for and could not find.**
Bugs go to the tracker; anything unclear in this guide is also worth saying.
After playing some solitaire, play a day or two of multiplayer with bots or friends to get a feel
for how players interact. Then you are ready to run a real division.
---
## 8. Where to read more
## 7. Issues / Suggestions
Please do report anything that looks like a bug or an area to be improved.
- **What you expected versus what happened**, with the Day and Stage. "Day 2 Stage 9, train 5 had
no coaches" is worth more than "passengers seem broken".
- **Save the game** (the **Save replay** button) and send the file. A save is the seed and the moves
made, so it replays exactly and the problem can be looked at directly.
- **Anything the screen did not explain.** If you had to guess a rule, that is worth saying even
when the game was right.
- **Anything you went looking for and could not find.**
**A save replays under the rules of the build that opens it.** When a rule changes, a save made
before it may stop part-way — the game says which move it stopped on and leaves your file untouched,
so the build you played on will still finish it.
---
## 8. Documentation / References
| For | Read |
| --- | --- |
| The rules in full, with the FAQ | [Rules](rules.md) |
| Every card, generated from the code | [`rules/as-built.md`](rules/as-built.md) |
| How the Home Office deck is dealt and played | [Home deck](home-deck.md) |
| The Mainline cards and what they do to a train | [Mainline deck](mainline-deck.md) |
| Rolling stock, yards, trays, the Fedora | [Components](components.md) |