v0.7.1 — a caboose is not a load, a Day that says it ended, and a train you may throw away
Four issues off the Gitea tracker, all of them things a player saw at the board. Reasoning for every item, and what was verified how: CHANGELOG.md. - Gitea#8: X22 Pee-Dee refused every caboose, including the one it was made up with, so setting it out stranded the train. All six cabooses are minted loaded because §2.2's "coloured is loaded, white is empty" doubles as a piece count in the supply table; one read of the flag took that literally. A caboose carries the crew, not freight, so it is never a load. - Gitea#10: a Day turns over inside the phases that run themselves, so it passes between one click and the next — and both transient signals fade before a player reading the board notices. A modal stops and waits, carrying the standings, the Days left and the combined target. Suppressed on the first frame, on Undo stepping back across a rollover, and on the Day the game ends. - Gitea#9, which SUPERSEDES Gitea#6 from three days ago: a Timetabled train may be tossed face-up to a Department slot, where a rival may pick it up — the second half of the ruling needed no code, since that is where every discard already goes. An Extra still may not. A New Game setting on this line (discardTimetabled, on by default), the plain rule on the 0.4.9 line. - Gitea#2 is not an engine bug: the rules are implemented exactly, and running the coach pool dry is Jesse's ruling to keep — "part of the strategy". What was wrong is that the game said nothing. A blocked platform now gives its reason, from the engine's own predicate, including how many coaches are stranded in Classification and what brings them back. The same four ship as v0.4.9g on the playtest line. Closes #2 Closes #8 Closes #9 Closes #10 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FLnYR4XtXQNamYJXGYT8oC
This commit is contained in:
co-authored by
Claude Opus 5
parent
603d38602c
commit
441447648d
+47
-16
@@ -888,34 +888,65 @@ any setting** — being a place an Extra can start is part of what upgrading buy
|
||||
|
||||
---
|
||||
|
||||
## §6.2 — a train card is never discarded
|
||||
## §6.2 — which train cards may be discarded
|
||||
|
||||
**Jesse's ruling, v0.4.9e playtest** (Gitea#6): "Players are not allowed to discard Train cards. They
|
||||
may keep the card in their hand for multiple stages and even multiple days, but they may not discard
|
||||
it. If a player has three train cards in their hand, and they draw a fourth, then they must play one
|
||||
of those cards."
|
||||
**SUPERSEDED ONCE. Read both rulings; the second narrows the first.**
|
||||
|
||||
**Extras count.** An Extra is a train, even though it runs once and ends in the Salvage Yard where a
|
||||
Timetabled card joins the timetable for the rest of the game.
|
||||
**Gitea#6, v0.4.9e playtest:** "Players are not allowed to discard Train cards. They may keep the
|
||||
card in their hand for multiple stages and even multiple days, but they may not discard it. If a
|
||||
player has three train cards in their hand, and they draw a fourth, then they must play one of those
|
||||
cards." Extras counted: an Extra is a train.
|
||||
|
||||
**Gitea#9, 2026-08-24 — the ruling in force:** "Timetabled trains are at the choice of the player:
|
||||
they can either play or discard. If someone else wants to pick it up, they are more than able to.
|
||||
The reason: I don't want, if you decide to play a game longer than five days, to decide that maybe
|
||||
there are too many trains, the stations are jammed, and the railroad doesn't need any more. You can
|
||||
toss it. Someone else might disagree and pick it up."
|
||||
|
||||
So the rule is now:
|
||||
|
||||
- a **Timetabled** train may be discarded;
|
||||
- an **Extra** may not. It never joins the timetable, so it can never be what jams it, and the only
|
||||
rule it would dodge by being thrown away is the hand limit;
|
||||
- **on `main` the Timetabled half is a New Game setting** (`discardTimetabled`, on by default),
|
||||
because Jesse's reasoning is explicitly about LONG games and a five-Day game may well want
|
||||
Gitea#6's pressure. The 0.4.9 playtest line has no scaffolding for a setting and takes the plain
|
||||
rule. Both lines behave identically at their defaults.
|
||||
|
||||
**"Someone else might disagree and pick it up" needed no machinery.** A discard already goes face-up
|
||||
onto a Department pile, and a Department pile is exactly what a rival draws from. The second half of
|
||||
the ruling was already built; only the first half was a change.
|
||||
|
||||
§6.2 as transcribed says only "the player must reduce his hand to no more than three cards" with no
|
||||
exception for any card type, so this is a ruling rather than a gap — the prototype rules do not
|
||||
address it either way.
|
||||
exception for any card type, so both of these are rulings rather than gaps — the prototype rules do
|
||||
not address it either way.
|
||||
|
||||
### It needs no forcing mechanism, and that is the point
|
||||
|
||||
The interesting property of this rule is that the forced play falls out of two rules that already
|
||||
The interesting property of the rule is that the forced play falls out of two rules that already
|
||||
exist rather than needing a third:
|
||||
|
||||
1. a train card cannot be discarded, so it is not among the ways to shed a card; and
|
||||
1. an undiscardable card is not among the ways to shed a card; and
|
||||
2. `draw.end` already refuses while the hand is over the limit (§6.2).
|
||||
|
||||
A player holding four trains therefore has exactly one legal way to conclude the turn — play one —
|
||||
without anything in the engine ever computing "you must play a train". The corner cannot lock a
|
||||
player in, because **playing a train card is unconditionally legal**: `card.play`'s train case
|
||||
A player holding four undiscardable trains therefore has exactly one legal way to conclude the turn —
|
||||
play one — without anything in the engine ever computing "you must play a train". The corner cannot
|
||||
lock a player in, because **playing a train card is unconditionally legal**: `card.play`'s train case
|
||||
refuses only a board placement, and a train card played when the timetable is full still leaves the
|
||||
hand (it simply schedules nothing). Confirmed by playing it: a hand of four trains offers zero
|
||||
discards, no `draw.end`, and four plays.
|
||||
hand (it simply schedules nothing). Confirmed by playing it: such a hand offers zero discards, no
|
||||
`draw.end`, and four plays.
|
||||
|
||||
**Gitea#9 does not retire that corner, it narrows the way in.** With the setting on, the only hand
|
||||
that reaches it is four Extras; with the setting off it is any four trains, exactly as before.
|
||||
|
||||
### One place decides, and the card says which rule refused
|
||||
|
||||
`keepReason` (`src/engine/apply.ts`) returns the sentence a player should read, or `null` if the card
|
||||
may be discarded. `check`, the hand panel and the blocked "End Local Operations" button all ask it,
|
||||
so none of them can drift from the rule. It returns a SENTENCE rather than a boolean because there
|
||||
are now two distinct reasons — "an Extra is never discarded" and "not in this game" — and a panel
|
||||
that hard-codes one of them tells half the players the wrong thing. It reaches the page as the
|
||||
Frame's `handKeepWhy`.
|
||||
|
||||
The bot needed no rule of its own either. `legal.ts` enumerates candidates and filters them through
|
||||
`check`, so the option stops being offered; and the developer bot already reaches for `card.play`
|
||||
|
||||
Reference in New Issue
Block a user