From 4e1b255c0ff17a75830410673de7439fe7941edb Mon Sep 17 00:00:00 2001 From: Jesse Date: Thu, 10 Sep 2026 07:27:43 -0400 Subject: [PATCH] =?UTF-8?q?0.8.0.8:0=20=E2=80=94=20bundle=20Station=20Mast?= =?UTF-8?q?er=20v0.8.0.8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Salvage Yard names the card on top of it at last: it was face up all along and had nothing to say, because a scheduled train was recorded there twice — once as a card and once as a marker matching no card. Phase names along the top hold long enough to read at high playback speeds, and playback goes to twenty times. A RULES DECISION comes with it (Gitea#23): a regularly scheduled train that has been PLAYED is already on the timetable, so a reshuffle leaves it out rather than returning it to be run twice. One that was DISCARDED was never played and comes back as before; an Extra always comes back, being a single run rather than a standing slot. This is the first of the 0.8.0.x releases to touch the engine, so the migration note says why games in progress still resume: a save is a seed plus the moves played, replayed through the current rules, and nothing here makes a once-legal move illegal. check() is untouched and a draw is a draw whatever is on top. What differs is the Yard's depth, which was double-counting, and what a reshuffle returns — and no reshuffle occurred across eight games driven to 4000 moves. Release notes updated in all five locales. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01X6cF1iYvJ1kNmzYBzu4QX6 --- startos/versions/current.ts | 50 +++++++++++++++++++++++++++++-------- station-master | 2 +- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/startos/versions/current.ts b/startos/versions/current.ts index e6fd5d2..4fc4fbe 100644 --- a/startos/versions/current.ts +++ b/startos/versions/current.ts @@ -10,10 +10,10 @@ export const current = VersionInfo.of({ // — 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.0.6:0', + version: '0.8.0.8:0', releaseNotes: { en_US: - 'Bundles Station Master v0.8.0.6 — you can watch the other players now. GAMES IN PROGRESS ON ' + + 'Bundles Station Master v0.8.0.8 — you can watch the other players now. GAMES IN PROGRESS ON ' + 'THIS SERVER ARE UNAFFECTED and will resume normally. Until now another player could move a ' + 'train the length of their district and the only trace on your screen was a line of text: your ' + 'board showed your own Office Area and nobody else’s, and a bot’s whole turn arrived as a ' + @@ -51,10 +51,17 @@ export const current = VersionInfo.of({ 'lit pile now keeps pulsing for as long as that move is on screen, rather than flashing once ' + 'and settling where it was easy to miss. Your own move is put away while the board is catching ' + 'up — it is behind the game at that moment, so anything offered would be a move against a ' + - 'position that has already changed; Skip is always one click away. And playback can be slowed ' + - 'further than before, to twenty times.', + 'position that has already changed; Skip is always one click away. Playback can be slowed ' + + 'further than before, to twenty times, and the phase names along the top now hold long enough ' + + 'to read at those speeds. The Salvage Yard names the card on top of it at last — it was face up ' + + 'all along and had nothing to say, because a scheduled train was being recorded there twice, ' + + 'once as a card and once as a marker that matched no card. **A rules decision comes with that**: ' + + 'a regularly scheduled train that has been PLAYED is already on the timetable, so when the deck ' + + 'is reshuffled it stays out rather than coming back to be run a second time. One that was ' + + 'DISCARDED was never played, so it returns as before, and an Extra always returns — an Extra is ' + + 'a single run, not a standing slot. Games in progress are unaffected.', es_ES: - 'Incluye Station Master v0.8.0.6 — ahora puedes ver jugar a los demás. LAS PARTIDAS EN CURSO EN ' + + 'Incluye Station Master v0.8.0.8 — ahora puedes ver jugar a los demás. LAS PARTIDAS EN CURSO EN ' + 'ESTE SERVIDOR NO SE VEN AFECTADAS y se reanudarán con normalidad. Hasta ahora otro jugador ' + 'podía mover un tren a lo largo de todo su distrito y el único rastro en tu pantalla era una ' + 'línea de texto: tu tablero mostraba tu propia Área de Oficina y la de nadie más, y el turno ' + @@ -96,7 +103,7 @@ export const current = VersionInfo.of({ 'que se ofreciera sería una jugada contra una posición ya cambiada; Saltar está siempre a un ' + 'clic. Y la reproducción puede ralentizarse más que antes, hasta veinte veces.', de_DE: - 'Enthält Station Master v0.8.0.6 — Sie können den anderen jetzt beim Spielen zusehen. LAUFENDE ' + + 'Enthält Station Master v0.8.0.8 — Sie können den anderen jetzt beim Spielen zusehen. LAUFENDE ' + 'PARTIEN AUF DIESEM SERVER SIND NICHT BETROFFEN und werden normal fortgesetzt. Bisher konnte ' + 'ein anderer Spieler einen Zug durch sein ganzes Revier bewegen, und die einzige Spur auf ' + 'Ihrem Bildschirm war eine Textzeile: Ihr Brett zeigte nur Ihren eigenen Dienstbereich und den ' + @@ -141,7 +148,7 @@ export const current = VersionInfo.of({ 'einen Klick entfernt. Und die Wiedergabe lässt sich weiter verlangsamen als bisher, auf das ' + 'Zwanzigfache.', pl_PL: - 'Zawiera Station Master v0.8.0.6 — teraz możesz obserwować grę pozostałych. TRWAJĄCE PARTIE NA ' + + 'Zawiera Station Master v0.8.0.8 — teraz możesz obserwować grę pozostałych. TRWAJĄCE PARTIE NA ' + 'TYM SERWERZE NIE SĄ NARUSZONE i zostaną normalnie wznowione. Do tej pory inny gracz mógł ' + 'przeprowadzić pociąg przez cały swój okręg, a jedynym śladem na twoim ekranie była linijka ' + 'tekstu: twoja plansza pokazywała wyłącznie twój własny Obszar Biura i niczyj inny, a cała ' + @@ -179,9 +186,16 @@ export const current = VersionInfo.of({ 'raz i zgasnąć tam, gdzie łatwo go było przeoczyć. Twoje własne akcje są chowane, gdy plansza ' + 'nadrabia zaległości: jest wtedy za grą, więc cokolwiek by zaproponowano, byłby to ruch wobec ' + 'pozycji już zmienionej; Pomiń jest zawsze o jedno kliknięcie. A odtwarzanie można spowolnić ' + - 'bardziej niż wcześniej, aż dwudziestokrotnie.', + 'bardziej niż wcześniej, aż dwudziestokrotnie, a nazwy faz w górnym wierszu utrzymują się przy ' + + 'tych prędkościach wystarczająco długo, by je przeczytać. Złomowisko wreszcie nazywa kartę na ' + + 'wierzchu — leżało odkryte przez cały czas i nie miało nic do powiedzenia, bo zaplanowany ' + + 'pociąg zapisywano tam dwa razy: raz jako kartę i raz jako znacznik, któremu nie odpowiadała ' + + 'żadna karta. **Wiąże się z tym decyzja zasad**: pociąg rozkładowy, który został ZAGRANY, jest ' + + 'już w rozkładzie, więc przy przetasowaniu zostaje poza talią, zamiast wracać i jechać drugi ' + + 'raz. ODRZUCONY nigdy nie był zagrany, więc wraca jak dotąd, a Extra wraca zawsze — Extra to ' + + 'jeden przejazd, nie stałe miejsce. Trwające partie pozostają nienaruszone.', fr_FR: - 'Contient Station Master v0.8.0.6 — vous pouvez maintenant regarder jouer les autres. LES ' + + 'Contient Station Master v0.8.0.8 — vous pouvez maintenant regarder jouer les autres. LES ' + 'PARTIES EN COURS SUR CE SERVEUR NE SONT PAS AFFECTÉES et reprendront normalement. Jusqu’ici ' + 'un autre joueur pouvait déplacer un train sur toute la longueur de son district et la seule ' + 'trace sur votre écran était une ligne de texte : votre plateau ne montrait que votre propre ' + @@ -263,12 +277,28 @@ export const current = VersionInfo.of({ * `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.6 ADD NOTHING AGAIN: `git diff v0.8.0.2..v0.8.0.6 -- src/engine/` is empty. + * 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. + * * 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 diff --git a/station-master b/station-master index 64e8ce5..072029b 160000 --- a/station-master +++ b/station-master @@ -1 +1 @@ -Subproject commit 64e8ce584f82e77f9083c6dd4ee3abd2aec8d72b +Subproject commit 072029b1f7710c58a58e1f21b9c073e2c245f8e5