import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk' export const current = VersionInfo.of({ // `:` — the upstream half tracks the bundled Station Master tag exactly // (`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 // upstream half moves. // // 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.8.2:0', releaseNotes: { en_US: 'Bundles Station Master v0.8.2 — a playtest read back against its own save file. **The change you ' + 'notice first: every district now opens on a DEPOT rather than a Whistle Post.** A Depot has two ' + 'arrival/departure tracks and works passengers from the first Stage; a Whistle Post has one track ' + 'and is not a passenger facility at all, so the opening of every game used to be spent unable to ' + 'earn from a passenger and one arrival away from a wreck. A table that wants the harder game can ' + 'tick "Players start with Whistle Posts, not Depots" when the game is created. **GAMES ALREADY ' + 'RUNNING ON THIS SERVER: MOST WILL NOT RESUME.** Measured before release rather than discovered ' + 'after: of the thirteen saved games on the test server, three resume and ten stop. Six of those ' + 'ten are one new rule — a Waiting Area, Restaurant or Hotel may no longer be played at a Whistle ' + 'Post, because a Whistle Post is not a passenger facility and the card did nothing there. A game ' + 'that stops says which move it stopped on and its file is left untouched, so anything worth ' + 'finishing can be finished by putting 0.8.1.0 back. **An Office could hold two trains on one ' + 'track.** The train an Interlocking had been holding at the Limits took the track that freed, and ' + 'the train arriving at that moment was let in after it without anyone checking there was still ' + 'room — so the collision the rules call for simply did not happen. **Your history could freeze ' + 'part-way through a game** and never gain another line, at a different moment for each player. ' + '**Trains were released when they should have been held**, twice over: a card that says "trains ' + 'may pass" was clearing the whole line ahead rather than just itself, and a train standing at a ' + 'full Office was invisible to the check although it was about to pull out again. **Things that ' + 'happened silently now say so** — a train held against one coming the other way, a train released ' + 'from the Limits, and the train an Interlocking is holding, which now draws differently on the ' + 'board instead of only explaining itself in a tooltip. **When a move is refused, the board says ' + 'which rule refused it.** **The documentation is a set of proper pages now**, served by this ' + 'package and reachable from inside a game under This Game, instead of five files of plain text ' + 'where every table came out as rows of pipes. **Smaller:** a Modifier must sit square against ' + 'what it serves rather than on a diagonal; ordering a Second Section costs the card, which was ' + 'declared in the rules and never actually dealt; a train may always recover its own caboose; and ' + 'an industry may be built over a straight already laid.', es_ES: 'Incluye Station Master v0.8.2 — una partida de prueba revisada contra su propio archivo ' + 'guardado. **El cambio que más se nota: cada distrito empieza ahora con un DEPÓSITO en vez de un ' + 'Apeadero.** Un Depósito tiene dos vías de llegada/salida y trabaja viajeros desde la primera ' + 'Etapa; un Apeadero tiene una vía y no es una instalación de viajeros, así que el comienzo de ' + 'cada partida se pasaba sin poder ganar con un viajero y a una llegada de un choque. Una mesa que ' + 'quiera el juego más difícil puede marcar "Los jugadores empiezan con Apeaderos, no Depósitos" al ' + 'crear la partida. **LAS PARTIDAS EN CURSO EN ESTE SERVIDOR: LA MAYORÍA NO SE REANUDARÁN.** ' + 'Medido antes de publicar, no descubierto después: de las trece partidas guardadas en el servidor ' + 'de pruebas, tres se reanudan y diez se detienen. Seis de esas diez se deben a una regla nueva: ' + 'una Sala de Espera, un Restaurante o un Hotel ya no pueden jugarse en un Apeadero, porque no es ' + 'una instalación de viajeros y la carta no hacía nada allí. Una partida que se detiene indica en ' + 'qué movimiento lo hizo y su archivo queda intacto, así que lo que merezca la pena terminar puede ' + 'terminarse reinstalando 0.8.1.0. **Una Oficina podía albergar dos trenes en una sola vía.** El ' + 'tren que el Enclavamiento retenía en los Límites ocupaba la vía que quedaba libre, y el que ' + 'llegaba en ese momento entraba detrás sin que nadie comprobara que aún hubiera sitio, así que el ' + 'choque que exigen las reglas simplemente no ocurría. **El historial podía congelarse a mitad de ' + 'partida** y no añadir ni una línea más, en un momento distinto para cada jugador. **Se soltaban ' + 'trenes que debían retenerse**, por dos motivos: una carta que dice "los trenes pueden cruzarse" ' + 'despejaba toda la línea por delante en vez de solo a sí misma, y un tren parado en una Oficina ' + 'llena era invisible para la comprobación aunque estuviera a punto de salir otra vez. **Lo que ' + 'antes ocurría en silencio ahora se dice** — un tren retenido ante otro de frente, un tren ' + 'liberado de los Límites, y el tren que retiene un Enclavamiento, que ahora se dibuja distinto en ' + 'el tablero en lugar de explicarse solo al pasar el ratón. **Cuando se rechaza un movimiento, el ' + 'tablero dice qué regla lo rechazó.** **La documentación son páginas de verdad**, servidas por ' + 'este paquete y accesibles desde dentro de la partida en Esta Partida, en lugar de cinco archivos ' + 'de texto plano donde cada tabla salía como filas de barras. **Menor:** un Modificador debe ir ' + 'pegado en ortogonal a lo que sirve, no en diagonal; ordenar una Segunda Sección cuesta su carta, ' + 'que estaba en las reglas y nunca se repartía; un tren siempre puede recuperar su propio furgón ' + 'de cola; y una industria puede construirse sobre una vía recta ya colocada.', de_DE: 'Enthält Station Master v0.8.2 — ein Testspiel, gegen seine eigene Speicherdatei nachgelesen. ' + '**Die auffälligste Änderung: jeder Bezirk beginnt jetzt mit einem DEPOT statt einem ' + 'Haltepunkt.** Ein Depot hat zwei Ankunfts-/Abfahrtsgleise und arbeitet Fahrgäste ab der ersten ' + 'Etappe ab; ein Haltepunkt hat ein Gleis und ist gar keine Personenanlage, sodass der Anfang ' + 'jeder Partie ohne Einnahmen aus Fahrgästen verging und eine Ankunft von einem Unfall entfernt ' + 'war. Wer das härtere Spiel will, hakt beim Erstellen "Spieler starten mit Haltepunkten statt ' + 'Depots" an. **LAUFENDE PARTIEN AUF DIESEM SERVER: DIE MEISTEN WERDEN NICHT FORTGESETZT.** Vor ' + 'der Freigabe gemessen, nicht hinterher entdeckt: von dreizehn Spielständen auf dem Testserver ' + 'werden drei fortgesetzt und zehn brechen ab. Sechs davon wegen einer neuen Regel — ein ' + 'Wartesaal, ein Restaurant oder ein Hotel darf nicht mehr an einem Haltepunkt gespielt werden, ' + 'der keine Personenanlage ist und an dem die Karte nichts bewirkte. Eine abgebrochene Partie ' + 'nennt den Zug, an dem sie stehen blieb, und ihre Datei bleibt unangetastet — was sich zu Ende ' + 'spielen lohnt, lässt sich mit 0.8.1.0 zu Ende spielen. **Ein Büro konnte zwei Züge auf einem ' + 'Gleis halten.** Der vom Stellwerk an der Grenze gehaltene Zug nahm das frei gewordene Gleis, und ' + 'der gerade ankommende wurde dahinter eingelassen, ohne dass noch einmal nach Platz gefragt wurde ' + '— der von den Regeln geforderte Zusammenstoß blieb also aus. **Der Verlauf konnte mitten im ' + 'Spiel einfrieren** und keine Zeile mehr bekommen, bei jedem Spieler zu einem anderen Zeitpunkt. ' + '**Züge fuhren los, die hätten warten müssen**, gleich zweifach: eine Karte mit "Züge können sich ' + 'begegnen" gab die ganze Strecke frei statt nur sich selbst, und ein an einem vollen Büro ' + 'stehender Zug war für die Prüfung unsichtbar, obwohl er gleich wieder ausfahren würde. **Was ' + 'vorher stumm geschah, wird jetzt gesagt** — ein gegen einen entgegenkommenden Zug gehaltener ' + 'Zug, ein von der Grenze freigegebener Zug, und der vom Stellwerk gehaltene Zug, der nun auf dem ' + 'Plan anders gezeichnet wird, statt sich nur im Tooltip zu erklären. **Wird ein Zug abgelehnt, ' + 'nennt der Plan die Regel.** **Die Dokumentation besteht jetzt aus richtigen Seiten**, von diesem ' + 'Paket ausgeliefert und aus der Partie heraus unter Diese Partie erreichbar, statt aus fünf ' + 'Textdateien, in denen jede Tabelle als Reihen von Strichen erschien. **Kleineres:** ein ' + 'Modifikator muss rechtwinklig an dem liegen, was er bedient, nicht diagonal; eine Zweite Sektion ' + 'kostet ihre Karte, die in den Regeln stand und nie ausgeteilt wurde; ein Zug darf seinen eigenen ' + 'Zugschlusswagen immer zurückholen; und eine Industrie darf über ein bereits verlegtes gerades ' + 'Gleis gebaut werden.', pl_PL: 'Zawiera Station Master v0.8.2 — rozgrywkę testową odczytaną z jej własnego zapisu. **Zmiana, ' + 'którą widać najpierw: każdy okręg zaczyna teraz od DWORCA, a nie od przystanku.** Dworzec ma dwa ' + 'tory przyjazdowo-odjazdowe i obsługuje pasażerów od pierwszego etapu; przystanek ma jeden tor i ' + 'wcale nie jest obiektem pasażerskim, więc początek każdej partii mijał bez możliwości zarobku na ' + 'pasażerze i o jeden przyjazd od katastrofy. Stół, który chce trudniejszej gry, zaznacza przy ' + 'tworzeniu "Gracze zaczynają od przystanków, nie dworców". **PARTIE TRWAJĄCE NA TYM SERWERZE: ' + 'WIĘKSZOŚĆ SIĘ NIE WZNOWI.** Zmierzone przed wydaniem, a nie odkryte później: z trzynastu zapisów ' + 'na serwerze testowym trzy się wznawiają, a dziesięć zatrzymuje. Sześć z nich przez jedną nową ' + 'zasadę — poczekalni, restauracji ani hotelu nie można już zagrać na przystanku, bo nie jest on ' + 'obiektem pasażerskim i karta nic tam nie robiła. Zatrzymana partia podaje ruch, na którym ' + 'stanęła, a jej plik pozostaje nietknięty, więc to, co warto dokończyć, można dokończyć ' + 'przywracając 0.8.1.0. **Biuro mogło pomieścić dwa pociągi na jednym torze.** Pociąg trzymany ' + 'przez blokadę na granicy zajmował zwolniony tor, a przyjeżdżający w tej chwili wjeżdżał za nim, ' + 'choć nikt nie sprawdzał, czy jest jeszcze miejsce — więc wymagana zasadami kolizja po prostu nie ' + 'następowała. **Historia mogła zamarznąć w połowie partii** i nie dostać już ani jednej linii, u ' + 'każdego gracza w innym momencie. **Pociągi ruszały, choć powinny czekać**, z dwóch powodów: ' + 'karta mówiąca "pociągi mogą się mijać" zwalniała całą drogę przed sobą zamiast tylko siebie, a ' + 'pociąg stojący na pełnym biurze był niewidoczny dla sprawdzenia, choć za chwilę miał znowu ' + 'wyjechać. **To, co działo się po cichu, teraz jest mówione** — pociąg wstrzymany przed ' + 'nadjeżdżającym z naprzeciwka, pociąg zwolniony z granicy, oraz pociąg trzymany przez blokadę, ' + 'który rysuje się teraz inaczej zamiast tłumaczyć się tylko w dymku. **Gdy ruch zostaje ' + 'odrzucony, plansza podaje zasadę.** **Dokumentacja to teraz prawdziwe strony**, serwowane przez ' + 'ten pakiet i dostępne z wnętrza gry w karcie Ta Partia, zamiast pięciu plików zwykłego tekstu, w ' + 'których każda tabela wychodziła jako rzędy kresek. **Drobne:** modyfikator musi przylegać ' + 'prostopadle do tego, czemu służy, nie po skosie; zamówienie drugiej sekcji kosztuje kartę, która ' + 'była w zasadach i nigdy nie trafiała do talii; pociąg zawsze może odzyskać własny wagon ' + 'służbowy; a przemysł można zbudować na już położonym torze prostym.', fr_FR: 'Contient Station Master v0.8.2 — une partie de test relue contre sa propre sauvegarde. **Le ' + 'changement que l\'on voit d\'abord : chaque district commence désormais avec un DÉPÔT et non un ' + 'arrêt.** Un dépôt a deux voies d\'arrivée et de départ et traite les voyageurs dès la première ' + 'étape ; un arrêt n\'a qu\'une voie et n\'est pas une installation voyageurs, si bien que le début ' + 'de chaque partie se passait sans pouvoir gagner sur un voyageur et à une arrivée d\'un accident. ' + 'Une table qui veut le jeu plus difficile coche « Les joueurs commencent avec des arrêts, pas des ' + 'dépôts » à la création. **PARTIES EN COURS SUR CE SERVEUR : LA PLUPART NE REPRENDRONT PAS.** ' + 'Mesuré avant la publication, et non découvert après : sur les treize sauvegardes du serveur de ' + 'test, trois reprennent et dix s\'arrêtent. Six de ces dix tiennent à une règle nouvelle — une ' + 'salle d\'attente, un restaurant ou un hôtel ne peut plus être joué sur un arrêt, qui n\'est pas ' + 'une installation voyageurs et où la carte ne faisait rien. Une partie qui s\'arrête indique à ' + 'quel coup, et son fichier reste intact : ce qui mérite d\'être terminé peut l\'être en ' + 'réinstallant 0.8.1.0. **Un bureau pouvait accueillir deux trains sur une seule voie.** Le train ' + 'que l\'enclenchement retenait aux limites prenait la voie libérée, et celui qui arrivait à cet ' + 'instant entrait derrière lui sans que personne ne revérifie la place — la collision exigée par ' + 'les règles n\'avait donc pas lieu. **L\'historique pouvait se figer en pleine partie** et ne plus ' + 'recevoir une seule ligne, à un moment différent pour chaque joueur. **Des trains partaient alors ' + 'qu\'ils auraient dû attendre**, pour deux raisons : une carte disant « les trains peuvent se ' + 'croiser » dégageait toute la voie devant elle au lieu d\'elle seule, et un train à l\'arrêt dans ' + 'un bureau plein était invisible au contrôle bien qu\'il fût sur le point de repartir. **Ce qui se ' + 'passait en silence se dit maintenant** — un train retenu face à un autre, un train libéré des ' + 'limites, et le train que retient un enclenchement, désormais dessiné différemment sur le plan au ' + 'lieu de ne s\'expliquer qu\'en infobulle. **Quand un mouvement est refusé, le plateau dit quelle ' + 'règle l\'a refusé.** **La documentation est faite de vraies pages**, servies par ce paquet et ' + 'accessibles depuis la partie sous Cette Partie, au lieu de cinq fichiers de texte brut où chaque ' + 'tableau sortait en rangées de barres. **Mineur :** un modificateur doit être accolé ' + 'orthogonalement à ce qu\'il dessert, jamais en diagonale ; commander une deuxième section coûte ' + 'sa carte, prévue par les règles et jamais distribuée ; un train peut toujours récupérer son ' + 'propre fourgon de queue ; et une industrie peut être bâtie sur une voie droite déjà posée.', }, migrations: { /** * NOTHING TO CARRY, AND CHECKED THE SAME NARROW WAY v0.7.9.8's ENTRY WAS. * * The rule this package lives by is in the game's README: a save is a seed plus the moves * played, replayed through the CURRENT rules, so the only thing that strands an older save is a * change that makes a once-legal move illegal. So the question is never "how big was the * release" — v0.8.0 is a large one — but "did any predicate change its answer". * * Measured with `git diff v0.7.9.8..v0.8.0.1 -- src/engine/`. The WHOLE engine diff is eight * lines: * four `GameEvent` types (`trayMoved`, `carsCoupled`, `carsDropped`, `consistSorted`) gained a * `player` field, and the four places that build them pass it. `check()` is untouched, `legal.ts` * and `advance.ts` are untouched, and no predicate anywhere was edited. Games in progress resume, * and the release notes say so in all five locales rather than leaving it to be discovered. * * EVENTS ARE NOT PERSISTED, so widening four of them cannot invalidate anything on disk: a * `SavedGame` is `{ seed, config, history: Intent[], … }` and the events are derived by replaying * it. The narration TEXT of two lines changed with them ("Moved Train 3 …" where it used to read * "CREW moved …"), which a resumed game simply regenerates — the log is not stored either. * * WHAT IS NOT COVERED BY THAT ARGUMENT, and why it still does not need a migration: the wire * between this server and a browser gained a lot. `Push` now carries ordered presentation steps * and a public-board baseline, and the board deltas changed shape. None of it is on disk, and a * browser reloads onto the new page as part of the update, so there is no version skew to * migrate — the same reasoning v0.7.9.8 used for its own `Frame` changes. * * v0.8.0.1 ADDED NOTHING TO THIS ARGUMENT: `git diff v0.8.0..v0.8.0.1 -- src/engine/` is empty. * It changed `sim/pacing.ts`, `web/step-queue.ts` and `web/main.ts` — how long a step is shown * and when the queue calls itself idle — which is presentation and touches neither the rules nor * anything on disk. * * v0.8.0.2 DOES TOUCH THE ENGINE, and it is worth being exact about why that is still nothing to * migrate. `git diff v0.8.0.1..v0.8.0.2 -- src/engine/` is three added lines: `collisionsPrevDay` * declared on `GameState`, initialised to 0 in `setup.ts`, and assigned at the Day rollover in * `advance.ts`. It is a counter that nothing checks — no predicate reads it, so no once-legal move * became illegal. * * v0.8.0.3 THROUGH v0.8.0.7 ADDED NOTHING: `git diff v0.8.0.2..v0.8.0.7 -- src/engine/` is empty. * One moved the Skip button, changed what the waiting row says, and stopped the speed control * stretching the clock; one took a hostname out of comments; the last drew the Home Office deck * and lit the pile a watched move touched, which is a diff of two frames the client already * holds. None of it is a rule, and none of it is on disk. * * v0.8.0.8 IS DIFFERENT AND IS THE ONE TO READ CAREFULLY: it changes a RULE (Gitea#23). When the * Home Office deck is reshuffled, a timetabled train sitting in the SALVAGE YARD is no longer * recovered — it was played, its number is on the timetable, and it cannot be run twice. The same * card in a DEPARTMENT was discarded rather than played and still comes back, as does any Extra. * A duplicate went with it: `trainScheduled` had been pushing a synthetic `train-` beside the * real card, so four scheduled trains left eight entries in a pile of four. * * GAMES IN PROGRESS STILL RESUME, and the reason is the narrow one this package always asks * (README § Design notes): a save is a seed plus the moves played, replayed through the CURRENT * rules, so what strands one is a change that makes a once-legal move ILLEGAL. Nothing here does. * `check()` is untouched; a draw is a draw whatever lies on top of the deck. What differs is the * Salvage Yard's depth, which was double-counting, and which cards a reshuffle returns — and a * reshuffle is effectively unreachable in ordinary play: eight games driven to 4000 moves across * eight seeds produced ZERO. A game that had somehow reshuffled would replay to a different deck * order rather than refusing to replay, which is worth knowing and is not the same as breaking. * * v0.8.0.9 TOUCHES THE ENGINE FOR SPEED, AND PROVED IT CHANGED NOTHING. `git diff v0.8.0.8..v0.8.0.9 * -- src/engine/` adds a route cache scoped to one unchanged position (`withRouteCache`), splits * `applyIntent` into `prepareIntent` + `commitEvents`, trims allocation in `exploreMoves`, adds * `legalSwitchingActions`, and exports `badlyMadeUp`, `protoCard` and `extendLimitsIfNeeded` for the * bot. No predicate's answer changed: every event and intent of 32 seeded games hashed identical before * and after each step, and the game's `test/route-cache.test.ts` pins the split. Everything else is the * developer bot, whose past moves are already intents in a save. Games in progress resume. * * v0.8.0.10 IS THE FIRST BUMP THAT BREAKS RESUMES, AND IT DOES SO DELIBERATELY. It corrects WHEN §8.1 * asks the Superintendent to rule (Gitea#26): a train on a card BEHIND the one departing is nobody's * concern, and was being counted. A save is the seed and the moves replayed through the CURRENT rules, * so a game holding a `mainline.clearance` the rules no longer ask for is refused at that move with * NO_PENDING_DECISION — `tryResumeSession` reports which move, and `index.ts` logs the refusal and * leaves the file alone. Measured before shipping: 40 four-seat co-op games recorded by bots under * v0.8.0.9 and replayed under this release — 28 stop, usually 5-40% of the way in. Jesse's call * (2026-09-15): no games in progress need keeping, so this ships without a per-game switch for the old * rule, and the release notes say so in all five locales. A game worth finishing can be finished by * putting v0.8.0.9 back — the save file is untouched. * * The rest of the release is the screen and the log — who the board says it is waiting on, what the * history says and when it says it, a flash on a realigned Mainline card — plus one new read-only * route (`GET /api/save?token=…`) that hands a seated player their own save. None of it is on disk. * * A NEW STATE FIELD CANNOT STRAND A SAVE HERE, which is the property worth naming rather than * re-deriving: a `SavedGame` holds `{ seed, config, history }` and NOT a serialised `GameState`. * Resuming calls `createGame` — which fills the new field from `setup.ts` — and then replays the * intents through the current rules, so the field is populated on the way past. There is no old * shape on disk for a new field to be missing from. * * THE ONE THING THAT WOULD HAVE NEEDED CARE, had it been built the way the plan first described: * the display-step collector runs inside `submit()`, and the resume path (`fromMultiplayerSave`) * deliberately does not go through `submit()`. So replaying a saved game emits no steps and burns * no sequence numbers. A test in the game pins that, because it is a property rather than an * accident. * * v0.8.0.11 RESUMES, AND IT WAS MEASURED THE SAME NARROW WAY — which matters more than usual * here, because the release immediately before it is the one that did NOT. * `git diff v0.8.0.10..v0.8.0.11 -- src/engine/` is three files and nineteen insertions: * `trainArrived` gains an `owner` field (`events.ts`), the one line in `advance.ts` that fills * it from `playerAtSeat`, and a Mainline card's printed description losing a sentence about a * speed that is not drawn on the card (`content.ts`). `check()` and `legal.ts` are untouched and * no predicate was edited, so nothing once legal became illegal. Events are not persisted — a * `SavedGame` is `{ seed, config, history }` and the events are derived by replaying it — so * widening one of them cannot invalidate anything on disk, exactly as the v0.8.0.1 entry above * argues for four of them. * * THE REST OF THE RELEASE IS THE SCREEN: a Pause control for the catch-up queue, a one-render * look at another player's Office Area, the turn chart following the step being replayed rather * than the live game, "still needs" on the make-up panel, the amber on an addable yard chip, and * save filenames carrying the join code. None of it is a rule and none of it is on disk. * * v0.8.0.12 TOUCHES THE ENGINE NOT AT ALL, which is the shortest entry this comment has ever * had a right to: `git diff v0.8.0.11..v0.8.0.12 -- src/engine/` is EMPTY. The release is the * server's HTTP surface, the browser client and the docs — a seat recovery flow (Gitea#33) for * a player whose browser has lost the token that is their only identity. * * WHAT IT ADDS, AND WHY NONE OF IT IS A MIGRATION: two routes (`POST /api/games//claim` * behind the admin secret, `POST /api/claim` for the player following the link), a `?claim=` * entry path in the client, and `seatedPlayers` on the administrative game listing. The codes * themselves live in memory and are deliberately NOT persisted — minted on demand and spent * within minutes, so a restart dropping them is the right failure rather than a loss. Nothing * new is written to the volume, no predicate was edited, and `check()` and `legal.ts` are * untouched, so no once-legal move became illegal. Games in progress resume, and the release * notes say so in all five locales. * * v0.8.0.13 TOUCHES THE ENGINE AGAIN, AND THE WHOLE DIFF IS TWO LINES. * `git diff v0.8.0.12..v0.8.0.13 -- src/engine/` adds a `superintendentChanged` variant to the * `GameEvent` union (`events.ts`) and the one `events.push` in `advance.ts` that emits it beside * the `actorChanged` that was already there — §5's handover of the Fedora, which the log had been * dropping as turn bookkeeping. Nothing was removed and nothing was edited: `check()`, `legal.ts` * and every predicate are untouched, so no once-legal move became illegal, and a widened event * cannot invalidate anything on disk because events are DERIVED by replaying a `SavedGame` rather * than stored in one — the same argument the v0.8.0.1 and v0.8.0.11 entries above make for * theirs. Games in progress resume, and the release notes say so in all five locales. * * THE REST IS THE SCREEN AND THE LOG, none of it on disk: the Division Yard chips now obey the * catch-up queue (they did not, and a click during it submitted a real intent against a stale * board), the yard counts are read from the shown board rather than the live game, the district * picker gained your own seat and is ordered by seat rather than by player index, collisions name * the district's owner and the 5 Revenue they lose, a Depot that cannot stock an outbound * passenger explains which car it is short of, and the history panel keeps 90 lines. The * passenger case is a RULING rather than a fix — §6.3 wants a loaded coach in the Division Yard, * and Jesse kept the shortage (Gitea#2's ruling) while ending the silence about it. * * v0.8.0.14 IS THE SECOND BUMP THAT BREAKS RESUMES, AND LIKE v0.8.0.10 IT DOES SO DELIBERATELY. * A Modifier card may no longer be placed outside a player's Limits (§2.1). That REVERSES an * earlier ruling of Jesse's — Modifiers were exempt because a Facility standing at the limit has * three of its nine spots beyond the sign — and it is exactly the shape of change this package's * `UPDATING.md` says to look for: a predicate in `apply.ts` changed its answer, so a move that * was legal when it was played is refused on replay. * * MEASURED, NOT ESTIMATED. The Day 3 playtest save stops at intent 528 of 539 — * `card.play c55 → (-2,4)` with the sign at column 3 — eleven moves short of where the table had * got to. `tryResumeSession` names the move, `index.ts` logs the refusal, and the file is left * untouched, so re-installing v0.8.0.13 finishes any game worth finishing. Jesse's call, knowing * it strands the game that was on the box. * * THE REST OF THE ENGINE DIFF STRANDS NOTHING, and is worth separating from the part that does. * `makeUpShort` is a new event reporting that the make-up round could give a train nothing; * `switchingEnded` closes a switching turn; `trayMoved` carries the Stage's Move allowance and * `consistSorted` carries where the engine ended up; `switch.sortConsist` gained an OPTIONAL * `engineAt` (absent means the nose, which is what every sort did before, so an older save * replays to the same train). Events are derived by replaying a save rather than stored in one, * and an optional intent field defaulting to the old behaviour changes no past move. * * THE SMALL YARD RULE CHANGED IN THE PERMISSIVE DIRECTION, which cannot strand a save either: a * train there may now be sorted with cars ahead of its engine (`implications.md` against the * v0.4.5 card text, Jesse's ruling). Nothing once legal became illegal; §8.2's departure check is * untouched and still holds a broken-backed train at the Office. * * v0.8.0.15 AND v0.8.0.16 CHANGE NO RULE AND STRAND NOTHING. * `git diff v0.8.0.14..v0.8.0.16 -- src/engine/` is one sentence of card TEXT and one doc * comment. The Interchange stopped telling players "Cars may be sorted into any new order here" * — a printed capability that has never been implemented, reaching the board through * `mainlineDescription`, which `view.ts` renders as a Mainline card's `what`. Nothing reads * `sortsCars` to permit a sort; its only live use is marking the card an Extra may be made up * on. No predicate was touched, so no once-legal move became illegal. * * The rest of those two releases is documentation inside the repository — a Quickstart for a new * player, and the four hand-written references brought up to the game as it runs. None of it is * served by the site or read by the service; it rides along in the image because the Dockerfile * copies the game's tree in. * * SO THE RESUME WARNING IN THESE RELEASE NOTES IS ENTIRELY v0.8.0.14's, and it still applies: * a box on 0.8.0.13:0 takes this update in one hop and meets the Modifier rule on the way. */ up: async ({ effects }) => {}, down: IMPOSSIBLE, }, })