0.7.9.8:0 — bundle Station Master v0.7.9.8

Eight releases of fixes since v0.7.9, most of them multiplayer, which is
what this package is for. Submodule pin and `startos/versions/current.ts`
only — no Dockerfile, main.ts or manifest change, as an ordinary bump
should be.

Bumped in place rather than spun off: v0.7.9's migration body is empty,
which is `versions.md`'s common case, and git history keeps its release
notes.

FOUR-COMPONENT VERSION, CHECKED. Every example in `versions.md` has
three, so `0.7.9.8:0` was parsed with the SDK's own ExVer parser before
being written down: upstream `[0,7,9,8]`, which sorts above `[0,7,9]`, so
a box on 0.7.9:0 takes this as an update rather than refusing it as a
downgrade.

GAMES IN PROGRESS ON THE BOX RESUME, and that was established rather than
hoped for. v0.7.9 broke solitaire saves because it changed a RULE, and
the rule behind that is that a save is a seed plus the moves played,
replayed through the CURRENT rules — so the question for any bump is
whether something became illegal. `git diff v0.7.9..HEAD -- src/engine/`
is, in full: `isExpedited` exported and widened to a structural parameter
type, `isFreight` exported, one new read-only helper
(`freightRuleSpentHere`, which only the blocked panel asks), and
`check('draw.end')`'s inline hand-limit test replaced by a call to
`overHandLimit(state, player)` holding the identical expression. No
predicate changed its answer. The release notes say so in all five
locales rather than leaving it to be discovered.

UPDATING.md CORRECTED: it said a running server's saves "are stamped with
`engineVersion` and refuse to resume under a mismatched one". They are
stamped with it and it is reported, but `src/server/index.ts` decides by
attempting the replay and names the versions only inside the failure
message — its own comment says why, that "some version differs" was never
enough to act on. A doc that sends the next person to schedule downtime
for a bump that needs none costs about as much as the reverse. It now
carries the diff command to ask the question of the code instead.

What players get, briefly: two multiplayer information leaks closed (the
seed in the shared log, and a blind Home Office draw naming its card); a
history panel that came back EMPTY after a mid-game browser reload; the
extended-play vote no longer naming an arbitrary player when the vote is
open to everyone at once; a train held at your Limits by an Interlocking
no longer vanishing off the board until a track frees; trains queued for
a Crew Tray saying so with the free count; a Red Flag drawn on the map; a
spent Telegraph/Telephone/Radio struck through; the Campaign Train saying
whether its speeches are made; and two bugs from the last playtest — the
Express's one-freight-car-per-location rule explained where it refuses
you, and westbound trains drawn in the correct half of a card.

README.md and instructions.md updated in the same change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5boPxP6JHRYMm8adXaF5R
This commit is contained in:
Jesse
2026-09-08 03:56:40 -04:00
co-authored by Claude Opus 5
parent bd802cb512
commit 8f2f733a66
5 changed files with 232 additions and 92 deletions
+53
View File
@@ -13,6 +13,59 @@ Station Master is a railroad operations board game with an authoritative multipl
solitaire needs no server and is not what this package is for. This package runs that server — solitaire needs no server and is not what this package is for. This package runs that server —
the browser client, the lobby, and the intent/SSE API — as a single StartOS service. the browser client, the lobby, and the intent/SSE API — as a single StartOS service.
**Bundled version: 0.7.9.8.** Eight releases of fixes since 0.7.9, most of them multiplayer, and
**games in progress on this server resume normally** — which was checked rather than assumed.
**Why saves are safe this time, and how that was established.** 0.7.9's breakage came from a rules
change, and the general rule behind it is that a save is a seed plus the moves played, replayed
through the *current* rules — so any change that makes a once-legal move illegal stops an older save.
The question for this bump is therefore narrow: did anything become illegal? `git diff v0.7.9..HEAD
-- src/engine/` is, in its entirety, four things — `isExpedited` exported and widened to a structural
parameter type, `isFreight` exported, one new read-only helper (`freightRuleSpentHere`, which only
the blocked panel asks), and `check('draw.end')`'s inline hand-limit test replaced by a call to
`overHandLimit(state, player)` holding the identical expression. **No predicate changed its answer.**
Eight releases, none of them in the rules.
Note that `engineVersion` is *not* a gate. `src/server/index.ts` attempts the replay and reports the
stored and running versions only in the failure message; a game is refused because a move no longer
replays, never because the version string differs.
**Two multiplayer information leaks.** The random seed was announced in the shared narration log at
game creation, and a blind Home Office draw resolved the drawn card to its real name for every seat.
Both were found by reading a plan rather than by a test, which is why 0.7.9.4 added a systematic
redaction net: a seat's Frame, the spectator projection and the narration are serialised and searched
for every opponent card id, every card name unique to one hand, the seed, and any private decision
data — with an allow-list of every public property that fails the suite when a field is added.
**The history panel came back empty after a mid-game reload.** `Frame.lines` carried the whole
narration log on every push to every seat and nothing read it — `RemoteSession` accumulates from
`Push.lines` alone. The waste was masking the fault: `connect()` cleared the frame cache but not the
narration watermark, so a reconnecting seat was told "nothing new since your last push" while the
browser it was answering had just reloaded from an empty accumulator.
**Whose turn it is, during the extended-play vote.** The §3.3 vote is parallel — every un-voted seat
may vote at once — so there is no actor to be, and the engine says so. The turn chart named the last
seat to move anyway, beside a tally correctly showing three seats outstanding. Cause: two functions
answering one question, one carrying a status guard and one not; there is one now, and it is the same
function that *refuses* an intent, so the screen can no longer name somebody the server would turn
away.
**A train held at the Limits was drawn nowhere.** An Interlocking stops an inbound train on the Limit
Track instead of colliding with a full Office. `arriveAtOffice` removes the tray from the Mainline
node's `transits` and the Interlocking branch never assigns `tray.position`, so with the map drawing
mainline nodes from `transits` and squares from `position.at === 'grid'`, the train was in neither —
it vanished off the board until an A/D track freed. Fixed in the view; the engine state was right.
**Also in this range.** Trains queued for a Crew Tray (a Timetabled departure, a played Extra, an
ordered second section) now report themselves with the free-tray count, where two of the three had
been waiting invisibly behind an exhausted pool. A Red Flag standing at an Office's Limits is drawn
on the map. A spent Telegraph/Telephone/Radio is struck through and says when another district holds
the Fedora — it is the Superintendent's own devices that get spent, and the Fedora moves every three
Stages. The Campaign Train says whether its speeches are made, which is what decides whether leaving
it off the Office square is a fault. Two bugs from the last playtest session: the Express's one
freight car per location rule is explained where it refuses you (the panel had been describing the
industry instead), and westbound trains are drawn in the correct half of a Mainline card.
**Bundled version: 0.7.9.** Enforces solitaire's collision limits, which had been offered as **Bundled version: 0.7.9.** Enforces solitaire's collision limits, which had been offered as
settings and never checked — and that is a rules change, so **a solitaire game in progress will not settings and never checked — and that is a rules change, so **a solitaire game in progress will not
resume if it has had collisions**. resume if it has had collisions**.
+31 -5
View File
@@ -77,8 +77,34 @@ from a dirty tree. Never publish one of those.
--- ---
If the jump carries a multiplayer protocol or persistence-format change (check the game repo's ## Will the games already on the box survive the bump?
`CHANGELOG.md` and `docs/architecture/multiplayer.md`), read it before bumping: a running
server's saved games are stamped with `engineVersion` and refuse to resume under a mismatched **`engineVersion` is NOT a gate, and this section used to say it was.** It claimed a running server's
one (`src/server/index.ts` in the game repo) — nothing in this package works around that, so an saves "are stamped with `engineVersion` and refuse to resume under a mismatched one". They are
in-progress game must finish (or be accepted as lost) before an incompatible bump. stamped with it, and it is *reported* — but `src/server/index.ts` decides by attempting the replay,
and names the stored and running versions only inside the failure message. Its own comment says why:
"some version differs" was never enough to act on. A game is refused because a move no longer
replays, never because a string changed.
**So the real question is whether anything became ILLEGAL.** A save is a seed plus the moves played,
replayed through the *current* rules, so a change that makes a once-legal move illegal truncates an
older save; everything else — new fields, renderer work, exports, refactors — cannot. Ask it directly
of the code rather than of the changelog:
```bash
cd station-master
git diff v<old>..v<new> -- src/engine/ | grep -E '^[+-]' | grep -vE '^[+-]{3}' \
| grep -vE '^[+-]\s*(\*|//|/\*)' | grep -vE '^[+-]\s*$'
```
Read every surviving line. For v0.7.9 → v0.7.9.8 that was four things — two exports, one new
read-only helper, and one inline expression moved into a shared function — so no predicate changed
its answer and every game resumed. **If a predicate in `apply.ts`, `legal.ts` or `advance.ts` did
change, say so in the release notes in all five locales**, the way v0.7.9 did: an in-progress game
must then finish, or be accepted as lost, before the bump.
Multiplayer saves live on the SERVER, which is the half this package can actually strand — a
solitaire save lives in the player's own browser, where nothing here can reach it either way.
The `Frame` sent to a browser is not part of this question. It gains and loses fields freely; a
browser reloads onto the new client as part of the update, so there is no version skew to migrate.
+34
View File
@@ -35,6 +35,40 @@ watches the table — there is nothing else to open.
Solitaire runs entirely in your own browser and needs nothing from the server, so it works here Solitaire runs entirely in your own browser and needs nothing from the server, so it works here
exactly as it does on the public Station Master site. exactly as it does on the public Station Master site.
**What changed in 0.7.9.8. Games already running on this server are not affected** — they resume
normally, and nothing in this update changes a rule, so no saved game stops being playable. (That is
the opposite of 0.7.9 below, which did change one. It was checked, not assumed.)
Most of this update is multiplayer, and two of it are things the table could see that only one player
should have. **The random number that deals the game was announced in the shared history**, and **a
blind draw from the Home Office named the card it drew** to everybody, not just the player who drew
it. Both are gone.
**Your history panel came back empty if you reloaded the page mid-game.** The server had the whole
log the entire time and was sending it in a field the page never read, while the field the page does
read was told there was nothing new. Reload now and your history comes back with you.
**During the "play one more Day?" vote, the turn chart named a player at random.** That vote is open
to everyone at once — anybody who has not voted may vote, in any order — so there is nobody whose
turn it is, and the chart said so wrongly while the tally beside it correctly listed everyone still
to vote. It now says nobody is being waited on.
**A train your Interlocking stopped at your Limits used to disappear from the board.** It was still
there in the rules — first in line for the next free A/D track — but nothing drew it, so it looked
like the train had gone until it reappeared in your Office some Stages later. It now stands at the
Limits, marked as held.
Things that are easier to see: **trains waiting for a Crew Tray say so**, with how many trays are
free — a played Extra or an ordered second section used to wait with nothing on screen about it.
**A Red Flag standing at an Office is drawn on the map**, at the end it guards. **A Telegraph,
Telephone or Radio you have already used today is struck through** instead of still advertising its
bonus, and tells you when another district is dispatching, since it is the Superintendent's devices
that get used. **The Campaign Train says whether its speeches are made** — before them it stops
normally, after them it must be kept at the station. And two from the last playtest session: **the
Express's "one freight car per location" rule is now explained where it stops you** (the panel used
to talk about the industry instead, sending you to fix the wrong thing), and **westbound trains are
drawn in the correct half of a Mainline card**.
**What changed in 0.7.9. Read this part first: your saved solitaire game may not reopen.** Solitaire **What changed in 0.7.9. Read this part first: your saved solitaire game may not reopen.** Solitaire
has always had two collision limits — 3 in a Day and 5 in a game — and the setup screen has always has always had two collision limits — 3 in a Day and 5 in a game — and the setup screen has always
offered them and said that reaching one ends the game in a loss. They were never actually checked. offered them and said that reaching one ends the game in a loss. They were never actually checked.
+113 -86
View File
@@ -5,105 +5,132 @@ export const current = VersionInfo.of({
// (`versions.md`'s consistency checklist), so bumping the submodule pin and bumping this are one // (`versions.md`'s consistency checklist), so bumping the submodule pin and bumping this are one
// action. The downstream half moves only for packaging-only changes, and RESETS to `:0` when the // action. The downstream half moves only for packaging-only changes, and RESETS to `:0` when the
// upstream half moves. // upstream half moves.
version: '0.7.9:0', //
// FOUR COMPONENTS IS FINE. ExVer's upstream half is an arbitrary-length dotted number, not semver
// — checked against the SDK's own parser rather than assumed, since every example in `versions.md`
// has three: `0.7.9.8:0` parses to upstream `[0,7,9,8]`, which sorts above `[0,7,9]`, so a box on
// 0.7.9:0 sees this as an update rather than refusing it as a downgrade.
version: '0.7.9.8:0',
releaseNotes: { releaseNotes: {
en_US: en_US:
'Bundles Station Master v0.7.9. — READ FIRST: SOLITAIRE GAMES IN PROGRESS DO NOT CARRY OVER. ' + 'Bundles Station Master v0.7.9.8 — eight releases of fixes since v0.7.9, aimed at multiplayer. ' +
"Solitaire's two collision limits (3 in a Day, 5 in a game) were offered as settings, said the " + 'GAMES IN PROGRESS ON THIS SERVER ARE UNAFFECTED and will resume normally. Two things a table ' +
'game would end in a loss, and were never actually checked. They now do what they say — so a ' + 'could see that only one seat should have: the random seed was announced in the shared history, ' +
'saved solitaire game that has had collisions will refuse to reopen. It fails safe: the save is ' + 'and a blind Home Office draw named the card it drew. The history panel came back EMPTY after a ' +
'left untouched and the game simply declines rather than corrupting anything. Finish what you ' + 'browser reload mid-game — the server had the whole log and was sending it in a field nothing ' +
'care about before updating. Multiplayer games on this server are unaffected. Also in this ' + 'read. During the end-of-game "play another Day?" vote the turn chart named one arbitrary ' +
'release: the end-of-game screen now asks whether to play one more Day, a question that was ' + 'player, next to a tally correctly showing everyone still to vote; the vote is open to every ' +
'being drawn underneath it and could not be reached; "waiting on" names the person and what ' + 'seat at once, so it now says nobody is being waited on. A train stopped at your Limits by an ' +
'they are being asked, instead of saying nobody; the game settings moved off the top line into ' + 'Interlocking VANISHED off the board until an A/D track freed up — it is drawn at the Limits ' +
'a This Game card, with the running collision counts taking their place; the Office Area ' + 'now, marked as held. Trains queued for a Crew Tray say so instead of waiting invisibly, with ' +
'show/hide control offers all three modes instead of cycling past one; the history reads newest ' + 'the number of free trays beside them. A Red Flag standing at an Office is drawn on the map. A ' +
'first; and a Heavy Grade card now shows which way it climbs.', 'Telegraph, Telephone or Radio already used today is struck through instead of still ' +
'advertising its bonus, and says so when another district holds the Fedora. The Campaign Train ' +
'says whether its speeches are made, which is what decides whether it must be kept at the ' +
'station. Plus two bugs from the last playtest: the Express’s one-freight-car-per-location ' +
'rule is now explained where it refuses you, and westbound trains are drawn in the correct half ' +
'of a Mainline card.',
es_ES: es_ES:
'Incluye Station Master v0.7.9. — LEE ESTO PRIMERO: LAS PARTIDAS DE SOLITARIO EN CURSO NO SE ' + 'Incluye Station Master v0.7.9.8 — ocho versiones de correcciones desde la v0.7.9, centradas en ' +
'CONSERVAN. Los dos límites de colisiones del solitario (3 por Día, 5 por partida) se ofrecían ' + 'el multijugador. LAS PARTIDAS EN CURSO EN ESTE SERVIDOR NO SE VEN AFECTADAS y se reanudarán con ' +
'como ajustes, decían que la partida terminaría en derrota y nunca se comprobaban. Ahora hacen ' + 'normalidad. Dos cosas que toda la mesa podía ver y solo un jugador debía: la semilla aleatoria ' +
'lo que dicen, así que una partida de solitario guardada que haya tenido colisiones se negará a ' + 'se anunciaba en el historial compartido, y un robo a ciegas de la Oficina Central nombraba la ' +
'abrirse. Falla de forma segura: el archivo guardado queda intacto y la partida simplemente se ' + 'carta robada. El panel de historial volvía VACÍO tras recargar el navegador a mitad de partida: ' +
'niega, sin corromper nada. Termina lo que te importe antes de actualizar. Las partidas ' + 'el servidor tenía el registro completo y lo enviaba en un campo que nadie leía. Durante la ' +
'multijugador de este servidor no se ven afectadas. Además: la pantalla de fin de partida ya ' + 'votación final de "¿jugar otro Día?" el turno nombraba a un jugador cualquiera, junto a un ' +
'pregunta si quieres jugar un Día más, una pregunta que se dibujaba debajo y era inalcanzable; ' + 'recuento que sí mostraba a todos los pendientes; la votación está abierta a todos a la vez, así ' +
'"esperando a" nombra a la persona y lo que se le pregunta, en vez de decir que a nadie; los ' + 'que ahora dice que no se espera a nadie. Un tren detenido en tus Límites por un Enclavamiento ' +
'ajustes de la partida salen de la línea superior a una tarjeta Esta Partida, y en su lugar ' + 'DESAPARECÍA del tablero hasta que se liberaba una vía: ahora se dibuja en los Límites, marcado ' +
'aparecen los recuentos de colisiones; el control de mostrar/ocultar del Área de Oficina ofrece ' + 'como retenido. Los trenes en cola por una Bandeja de Personal lo indican, con el número de ' +
'los tres modos en vez de saltarse uno; el historial se lee de lo más reciente a lo más ' + 'bandejas libres al lado. Una Bandera Roja plantada en una Oficina se dibuja en el mapa. Un ' +
'antiguo; y una carta de Pendiente Fuerte muestra hacia dónde sube.', 'Telégrafo, Teléfono o Radio ya usado hoy aparece tachado en vez de seguir anunciando su bono, e ' +
'indica cuándo el Sombrero lo tiene otro distrito. El Tren de Campaña dice si ya ha dado sus ' +
'discursos, que es lo que decide si debe permanecer en la estación. Además, dos fallos del ' +
'último playtest: la regla de un vagón de carga por ubicación del Expreso se explica donde te ' +
'rechaza, y los trenes en dirección oeste se dibujan en la mitad correcta de la carta.',
de_DE: de_DE:
'Enthält Station Master v0.7.9. — ZUERST LESEN: LAUFENDE SOLOSPIELE BLEIBEN NICHT ERHALTEN. Die ' + 'Enthält Station Master v0.7.9.8 — acht Fehlerkorrektur-Versionen seit v0.7.9, mit Blick auf den ' +
'beiden Kollisionsgrenzen des Solospiels (3 pro Tag, 5 pro Partie) wurden als Einstellungen ' + 'Mehrspielermodus. LAUFENDE PARTIEN AUF DIESEM SERVER SIND NICHT BETROFFEN und werden normal ' +
'angeboten, sagten eine Niederlage an und wurden nie geprüft. Jetzt tun sie, was sie sagen — ' + 'fortgesetzt. Zwei Dinge, die der ganze Tisch sehen konnte und nur ein Platz sollte: der ' +
'ein gespeichertes Solospiel mit Kollisionen lässt sich also nicht mehr öffnen. Es scheitert ' + 'Zufallsstartwert stand im gemeinsamen Verlauf, und ein Blindzug aus dem Hauptbüro nannte die ' +
'sicher: der Spielstand bleibt unangetastet und das Spiel verweigert schlicht, statt etwas zu ' + 'gezogene Karte. Der Verlauf kam nach einem Neuladen des Browsers mitten im Spiel LEER zurück — ' +
'beschädigen. Beende vor dem Update, was dir wichtig ist. Mehrspielerpartien auf diesem Server ' + 'der Server hatte das ganze Protokoll und schickte es in einem Feld, das niemand las. Bei der ' +
'sind nicht betroffen. Außerdem: der Endbildschirm fragt jetzt, ob ein weiterer Tag gespielt ' + 'Abstimmung "noch einen Tag spielen?" nannte die Zuganzeige einen beliebigen Spieler, neben ' +
'werden soll — diese Frage wurde bisher darunter gezeichnet und war unerreichbar; "wartet auf" ' + 'einer Zählung, die alle Ausstehenden korrekt zeigte; die Abstimmung steht allen zugleich offen, ' +
'nennt die Person und ihre Frage, statt niemanden zu nennen; die Spieleinstellungen wandern aus ' + 'also heißt es jetzt, dass auf niemanden gewartet wird. Ein von einem Stellwerk an deinen ' +
'der Kopfzeile in eine Karte Dieses Spiel, an ihre Stelle treten die laufenden Kollisionszähler; ' + 'Grenzen angehaltener Zug VERSCHWAND vom Brett, bis ein Gleis frei wurde — er wird jetzt an den ' +
'die Anzeigesteuerung des Amtsbereichs bietet alle drei Modi, statt an einem vorbeizuschalten; ' + 'Grenzen gezeichnet und als angehalten markiert. Züge, die auf ein Besatzungstablett warten, ' +
'der Verlauf liest sich neueste zuerst; und eine Steigungskarte zeigt jetzt ihre Richtung.', 'sagen das nun, mit der Zahl der freien Tabletts daneben. Eine an einem Büro stehende Rote Fahne ' +
'erscheint auf der Karte. Ein heute schon genutzter Telegraf, ein Telefon oder Radio wird ' +
'durchgestrichen, statt weiter seinen Bonus anzupreisen, und sagt, wenn ein anderer Bezirk den ' +
'Hut hat. Der Wahlkampfzug sagt, ob seine Reden gehalten sind — das entscheidet, ob er am ' +
'Bahnhof bleiben muss. Dazu zwei Fehler aus dem letzten Playtest: die Ein-Güterwagen-pro-Ort- ' +
'Regel des Express wird dort erklärt, wo sie dich abweist, und Züge nach Westen werden in der ' +
'richtigen Kartenhälfte gezeichnet.',
pl_PL: pl_PL:
'Zawiera Station Master v0.7.9. — PRZECZYTAJ NAJPIERW: TRWAJĄCE GRY SOLO NIE ZOSTANĄ ZACHOWANE. ' + 'Zawiera Station Master v0.7.9.8 — osiem wydań poprawek od v0.7.9, pod kątem gry wieloosobowej. ' +
'Dwa limity kolizji w grze solo (3 na Dzień, 5 na partię) były oferowane jako ustawienia, ' + 'TRWAJĄCE PARTIE NA TYM SERWERZE NIE SĄ DOTKNIĘTE i wznowią się normalnie. Dwie rzeczy, które ' +
'zapowiadały przegraną i nigdy nie były sprawdzane. Teraz robią to, co mówią — więc zapisana ' + 'widział cały stół, a powinien tylko jeden gracz: losowe ziarno ogłaszano we wspólnej historii, a ' +
'gra solo, w której doszło do kolizji, odmówi otwarcia. Zawodzi bezpiecznie: zapis pozostaje ' + 'zakryte dobranie z Biura Głównego podawało nazwę dobranej karty. Panel historii wracał PUSTY po ' +
'nietknięty, a gra po prostu odmawia, niczego nie uszkadzając. Dokończ to, na czym ci zależy, ' + 'przeładowaniu przeglądarki w trakcie gry — serwer miał cały dziennik i wysyłał go w polu, ' +
'przed aktualizacją. Gry wieloosobowe na tym serwerze nie są dotknięte. Ponadto: ekran końca ' + 'którego nikt nie czytał. Podczas głosowania "zagrać jeszcze jeden Dzień?" wykres tury wskazywał ' +
'gry pyta teraz, czy zagrać jeszcze jeden Dzień — to pytanie było rysowane pod nim i ' + 'przypadkowego gracza, obok licznika poprawnie pokazującego wszystkich pozostałych; głosowanie ' +
'nieosiągalne; "czeka na" podaje osobę i pytanie, zamiast mówić, że nikogo; ustawienia gry ' + 'jest otwarte dla wszystkich naraz, więc teraz mówi, że nie czeka się na nikogo. Pociąg ' +
'przeniosły się z górnego wiersza do karty Ta Gra, a ich miejsce zajęły bieżące liczniki ' + 'zatrzymany na twoich Granicach przez Nastawnię ZNIKAŁ z planszy do czasu zwolnienia toru — teraz ' +
'kolizji; przełącznik Biura oferuje wszystkie trzy tryby zamiast omijać jeden; historia czyta ' + 'jest rysowany na Granicach i oznaczony jako wstrzymany. Pociągi czekające na Tackę Załogi mówią ' +
'się od najnowszych; a karta Stromego Podjazdu pokazuje, w którą stronę się wznosi.', 'o tym, z liczbą wolnych tacek obok. Czerwona Flaga stojąca przy Biurze jest widoczna na mapie. ' +
'Telegraf, Telefon lub Radio użyte już dzisiaj są przekreślone, zamiast wciąż reklamować swoją ' +
'premię, i informują, gdy Kapelusz ma inny okręg. Pociąg Kampanijny mówi, czy przemówienia już ' +
'wygłoszono — to decyduje, czy musi stać na stacji. Do tego dwa błędy z ostatniego playtestu: ' +
'zasada jednego wagonu towarowego na lokalizację w Ekspresie jest wyjaśniana tam, gdzie cię ' +
'blokuje, a pociągi na zachód są rysowane we właściwej połowie karty.',
fr_FR: fr_FR:
"Inclut Station Master v0.7.9. — À LIRE D'ABORD : LES PARTIES SOLO EN COURS NE SONT PAS " + 'Inclut Station Master v0.7.9.8 — huit versions de corrections depuis la v0.7.9, orientées ' +
'CONSERVÉES. Les deux limites de collisions du solo (3 par Jour, 5 par partie) étaient proposées ' + 'multijoueur. LES PARTIES EN COURS SUR CE SERVEUR NE SONT PAS AFFECTÉES et reprendront ' +
'comme réglages, annonçaient une défaite et n’étaient jamais vérifiées. Elles font désormais ce ' + 'normalement. Deux choses que toute la table pouvait voir et qu’un seul joueur aurait dû : la ' +
'qu’elles disent : une partie solo sauvegardée ayant connu des collisions refusera de ' + 'graine aléatoire était annoncée dans l’historique partagé, et une pioche à l’aveugle au Bureau ' +
's’ouvrir. L’échec est sûr — la sauvegarde reste intacte et la partie refuse simplement, sans ' + 'Central nommait la carte piochée. L’historique revenait VIDE après un rechargement du ' +
'rien corrompre. Terminez ce qui compte avant de mettre à jour. Les parties multijoueurs de ce ' + 'navigateur en pleine partie : le serveur avait tout le journal et l’envoyait dans un champ que ' +
'serveur ne sont pas affectées. Par ailleurs : l’écran de fin demande maintenant s’il faut ' + 'personne ne lisait. Pendant le vote « jouer un Jour de plus ? », le tableau des tours nommait un ' +
'jouer un Jour de plus, question qui était dessinée en dessous et restait inaccessible ; ' + 'joueur arbitraire, à côté d’un décompte affichant correctement tous ceux qui restaient à voter ; ' +
'« en attente de » nomme la personne et ce qu’on lui demande, au lieu de ne nommer personne ; ' + 'le vote est ouvert à tous à la fois, il indique donc maintenant qu’on n’attend personne. Un ' +
'les réglages quittent la ligne du haut pour une carte Cette Partie, remplaçés là par les ' + 'train arrêté à vos Limites par un Enclenchement DISPARAISSAIT du plateau jusqu’à ce qu’une voie ' +
'compteurs de collisions ; le contrôle d’affichage du Bureau propose les trois modes au lieu ' + 'se libère — il est désormais dessiné aux Limites, marqué comme retenu. Les trains en attente ' +
'd’en sauter un ; l’historique se lit du plus récent au plus ancien ; et une carte de Forte ' + 'd’un Plateau d’Équipe le disent, avec le nombre de plateaux libres à côté. Un Drapeau Rouge ' +
'Rampe montre desormais dans quel sens elle monte.', 'planté à un Bureau apparaît sur la carte. Un Télégraphe, Téléphone ou Radio déjà utilisé ' +
'aujourd’hui est barré au lieu de continuer à annoncer son bonus, et signale quand un autre ' +
'district porte le Chapeau. Le Train de Campagne dit si ses discours sont faits, ce qui décide ' +
's’il doit rester en gare. Plus deux bugs du dernier playtest : la règle un wagon de fret par ' +
'emplacement de l’Express est expliquée là où elle vous refuse, et les trains vers l’ouest sont ' +
'dessinés dans la bonne moitié de la carte.',
}, },
migrations: { migrations: {
/** /**
* NOTHING TO CARRY, AND THIS TIME THAT IS NOT THE SAME AS "NOTHING BREAKS". * NOTHING TO CARRY, AND THIS TIME THAT REALLY IS "NOTHING BREAKS" — which is the opposite of
* v0.7.9, and was checked rather than hoped for.
* *
* v0.7.9 changes a RULE. `advance.ts` gated §3.4's collision check on * v0.7.9 changed a RULE (§3.4's collision caps became live in solitaire), so a saved game that
* `mode === 'competitive' || mode === 'coop'`, so a solitaire game carried both limits * had crossed one stopped replaying. The general rule that fell out of it is written down in the
* (`SOLO_CONFIG`: 3 a Day, 5 total), offered them on the New Game screen as live settings, told * game's README: a save is a seed plus the moves played, replayed through the CURRENT rules, so
* the player the game would end in a loss — and never checked them. Jesse's ruling was that the * any change that makes a once-legal move illegal stops an older save.
* settings should do what they say, so the gate is gone.
* *
* A SOLITAIRE SAVE IS A SEED PLUS THE MOVES PLAYED, and it does NOT carry the collision caps — * SO THE QUESTION FOR THIS BUMP IS NARROW: did anything become illegal between v0.7.9 and
* `Save` is `{ seed, history, rules? }`, where `rules` is the house rules only. The caps come * v0.7.9.8? Measured with `git diff v0.7.9..HEAD -- src/engine/` and reading every non-comment
* from today's defaults on restore. So a save recorded under 0.7.8 replays under 0.7.9 with the * line of it. The whole diff is: `isExpedited` exported and widened to a structural parameter
* caps now live, and a game that crossed one stops replaying at that point. * type, `isFreight` exported, one new read-only helper (`freightRuleSpentHere`, which the
* blocked panel asks and nothing else), and `check('draw.end')`'s inline hand-limit test replaced
* by a call to `overHandLimit(state, player)` holding the identical expression. No predicate
* changed its answer. Eight releases of work, and none of it in the rules.
* *
* MEASURED RATHER THAN ASSUMED, because the first two attempts at measuring it were wrong. With * MULTIPLAYER SAVES LIVE ON THIS SERVER and are the ones this package can strand, so that
* the caps disabled, 1200 of 1200 generated solitaire saves replay every intent — that is the * matters here in a way it did not for v0.7.9 — whose breakage was solitaire, in the player's own
* control, and without it the experiment says nothing (an earlier run reported "no saves break" * browser, where nothing in this package could have acted on it either way. Games in progress
* when in fact every replay was failing at intent 2 for an unrelated house-rules mismatch). Of * resume; the release notes say so in all five locales rather than leaving it to be discovered.
* those, 74 games crossed the 5-collision total, and 70 of the 74 truncate once the caps are
* enforced: one replays 141 of its 532 intents and stops. So this is "will break for anyone who
* crashed", not "may break".
* *
* IT FAILS SAFE. The save file is left untouched and the game declines to open rather than * WHAT IS NOT COVERED BY THAT ARGUMENT: `Frame` gained fields (`crewTrays`, `queued`,
* loading a position the rules could not have produced, so a player who cares can put 0.7.8 back * `heldAtLimits`, `enhancementsSpent`) and lost the narration log it was carrying for nobody.
* and finish. The release notes lead with it in all five locales. * That is the wire between this server and a browser, not anything on disk — a browser reloads
* * onto the new page as part of the update, so there is no version skew to migrate.
* NOTHING HERE CAN ACT ON IT EITHER WAY: a solitaire save lives in the player's own browser, not
* on this server. A MULTIPLAYER game in progress is unaffected — competitive and coop have been
* inside that gate all along, so their rules did not move.
*/ */
up: async ({ effects }) => {}, up: async ({ effects }) => {},
down: IMPOSSIBLE, down: IMPOSSIBLE,