Yard Office not implemented #5

Closed
opened 2026-08-22 16:37:22 +00:00 by Jesse.Markowitz · 3 comments
Owner

Yard Office: trains that are only freight (cabooses ok, no coaches allowed) that arrive in a players area who has the yard office card get an extra ability. On the turn (mainline phase) that the train arrives the game will offer that player the option to have that train go directly to the yard office card instead of the standard office. They can of course still choose to have the train go to the standard office.

However, just like other trains (that are not working either) finding cars on the tracks you use to get into either result in a crash. Also, if the Yard Office is not accessible in one move, you should not get the option. It's got to have a direct route in

Yard Office: trains that are only freight (cabooses ok, no coaches allowed) that arrive in a players area who has the yard office card get an extra ability. On the turn (mainline phase) that the train arrives the game will offer that player the option to have that train go directly to the yard office card instead of the standard office. They can of course still choose to have the train go to the standard office. However, just like other trains (that are not working either) finding cars on the tracks you use to get into either result in a crash. Also, if the Yard Office is not accessible in one move, you should not get the option. It's got to have a direct route in
Author
Owner

Half right — the Yard Office is implemented, but in a stripped form that is missing all three of the conditions you describe. Leaving this open, retitled in effect to "Yard Office is implemented incorrectly".

What exists today (arriveAtOffice in src/engine/advance.ts): on arrival, if the train carries no coaches and a Yard Office card is anywhere in the player's Office Area, the train is sent to the Yard Office card and sidesteps the A/D track entirely.

What your description asks for, and what is missing:

  1. It is automatic, not offered. The player is never asked. A qualifying train always goes to the Yard Office and can never choose the standard Office. Your rule makes it an option on the Mainline-phase turn the train arrives.
  2. There is no reachability check. The train is simply relocated onto the Yard Office card — no route is computed, so "it's got to have a direct route in" and "if it is not accessible in one move you should not get the option" are both unenforced. The card's own printed effect already says "…that can reach the yard office in one move", so the text and the code disagree, and the code is the one that is wrong.
  3. Cars in the way do not cause a crash. Because no route is walked, nothing is ever met on the way in. Trains not working that find cars on the track should crash the same as anywhere else.

Cabooses being allowed and coaches banned is implemented correctly.

So the fix is to route the arrival through the normal movement walk instead of teleporting, offer the choice when the walk succeeds, and let the walk's own collision handling do the rest. That is a real piece of work rather than a one-liner, which is why it has not been picked up with the others.

**Half right — the Yard Office is implemented, but in a stripped form that is missing all three of the conditions you describe.** Leaving this open, retitled in effect to "Yard Office is implemented incorrectly". What exists today (`arriveAtOffice` in `src/engine/advance.ts`): on arrival, if the train carries **no coaches** and a Yard Office card is anywhere in the player's Office Area, the train is sent to the Yard Office card and sidesteps the A/D track entirely. What your description asks for, and what is missing: 1. **It is automatic, not offered.** The player is never asked. A qualifying train always goes to the Yard Office and can never choose the standard Office. Your rule makes it an option on the Mainline-phase turn the train arrives. 2. **There is no reachability check.** The train is simply relocated onto the Yard Office card — no route is computed, so "it's got to have a direct route in" and "if it is not accessible in one move you should not get the option" are both unenforced. The card's own printed effect already says *"…that can reach the yard office in one move"*, so the text and the code disagree, and the code is the one that is wrong. 3. **Cars in the way do not cause a crash.** Because no route is walked, nothing is ever met on the way in. Trains not working that find cars on the track should crash the same as anywhere else. Cabooses being allowed and coaches banned is implemented correctly. So the fix is to route the arrival through the normal movement walk instead of teleporting, offer the choice when the walk succeeds, and let the walk's own collision handling do the rest. That is a real piece of work rather than a one-liner, which is why it has not been picked up with the others.
Author
Owner

For the yard office, it only accepts non-coach trains. And you have to ask if non-coach trains wish to go in there, rather than to the office.

For the yard office, it only accepts non-coach trains. And you have to ask if non-coach trains wish to go in there, rather than to the office.
Author
Owner

Done in v0.7.4, commit 2280276. Shipped to phoenix.local as 0.7.4:0.

All three of the conditions the earlier comment listed as missing now hold:

  1. Offered, not imposed. The arrival interrupts the Mainline Phase and asks whoever sits in the
    district. Declining is an ordinary arrival onto an A/D track — "they can of course still choose to
    have the train go to the standard office".
  2. Reachability is checked, using the engine's own move walk rather than a bespoke test.
    exploreMoves already means exactly what the card's "in one move" means — any distance without
    changing direction, finishing on Operational Rail — so the code and the card now agree, which was
    the complaint. Reversing is a separate Move, so a yard reachable only by backing up is correctly
    out of reach.
  3. Cars on the lead collide. The walk does not treat standing cars as obstacles — it COUPLES
    them, because that is what a switching move does. An arriving train is not switching, so what it
    would have coupled is what it is about to hit, which is the reading §8.3 already applies to the
    Running Track. destination.couples turned out to be the fouling signal with no new machinery.

Your ruling of 2026-08-29 kept the two failures apart: no route means no offer, and the history
says why
("make sure this is logged in history — why can't move so user knows why they can't get to
yard"); a route that exists but is fouled is still offered, and taking it crashes.

What it cost structurally, and what it bought

pendingDecision was one question asked of one player — §8.1's clearance, always the Superintendent
— and currentActor hardcoded that. It is a discriminated union now, with decisionActor as the one
place mapping a question to whoever answers it. Six copies of
pendingDecision !== null ? superintendent : currentActor across the engine, the sim, the web client
and the tests collapsed into one helper; they had already stopped being correct the moment a second
kind of question existed. #19 then needed only to add a case.

A trap worth recording for the next interruption: the offer must be put BEFORE the train is taken
off its Mainline card. Returning needsClearance unwinds the whole phase and the driver re-enters
from the top, so my first cut asked after the transit was removed and the train simply vanished —
the question was asked and the answer had nowhere to land. §8.1 gets this right by asking before it
commits.

The developer bot declines: the Yard Office frees an A/D track, but the lead may be fouled and the
bot cannot read its own yard well enough to tell. Declining is always safe.

Done in **v0.7.4**, commit `2280276`. Shipped to `phoenix.local` as `0.7.4:0`. All three of the conditions the earlier comment listed as missing now hold: 1. **Offered, not imposed.** The arrival interrupts the Mainline Phase and asks whoever sits in the district. Declining is an ordinary arrival onto an A/D track — "they can of course still choose to have the train go to the standard office". 2. **Reachability is checked**, using the engine's own move walk rather than a bespoke test. `exploreMoves` already means exactly what the card's "in one move" means — any distance without changing direction, finishing on Operational Rail — so the code and the card now agree, which was the complaint. Reversing is a separate Move, so a yard reachable only by backing up is correctly out of reach. 3. **Cars on the lead collide.** The walk does not treat standing cars as obstacles — it COUPLES them, because that is what a switching move does. An arriving train is not switching, so what it would have coupled is what it is about to hit, which is the reading §8.3 already applies to the Running Track. `destination.couples` turned out to be the fouling signal with no new machinery. Your ruling of 2026-08-29 kept the two failures apart: **no route means no offer, and the history says why** ("make sure this is logged in history — why can't move so user knows why they can't get to yard"); **a route that exists but is fouled is still offered**, and taking it crashes. ### What it cost structurally, and what it bought `pendingDecision` was one question asked of one player — §8.1's clearance, always the Superintendent — and `currentActor` hardcoded that. It is a discriminated union now, with `decisionActor` as the one place mapping a question to whoever answers it. Six copies of `pendingDecision !== null ? superintendent : currentActor` across the engine, the sim, the web client and the tests collapsed into one helper; they had already stopped being correct the moment a second kind of question existed. #19 then needed only to add a case. **A trap worth recording for the next interruption:** the offer must be put BEFORE the train is taken off its Mainline card. Returning `needsClearance` unwinds the whole phase and the driver re-enters from the top, so my first cut asked after the transit was removed and the train simply vanished — the question was asked and the answer had nowhere to land. §8.1 gets this right by asking before it commits. The developer bot declines: the Yard Office frees an A/D track, but the lead may be fouled and the bot cannot read its own yard well enough to tell. Declining is always safe.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Jesse.Markowitz/station-master#5