Files
station-master-startos/startos/versions/current.ts
T
JesseandClaude Opus 5 8f2f733a66 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
2026-09-08 03:56:40 -04:00

139 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk'
export const current = VersionInfo.of({
// `<upstream>:<downstream>` — 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.7.9.8:0',
releaseNotes: {
en_US:
'Bundles Station Master v0.7.9.8 — eight releases of fixes since v0.7.9, aimed at multiplayer. ' +
'GAMES IN PROGRESS ON THIS SERVER ARE UNAFFECTED and will resume normally. Two things a table ' +
'could see that only one seat should have: the random seed was announced in the shared history, ' +
'and a blind Home Office draw named the card it drew. The history panel came back EMPTY after a ' +
'browser reload mid-game — the server had the whole log and was sending it in a field nothing ' +
'read. During the end-of-game "play another Day?" vote the turn chart named one arbitrary ' +
'player, next to a tally correctly showing everyone still to vote; the vote is open to every ' +
'seat at once, so it now says nobody is being waited on. A train stopped at your Limits by an ' +
'Interlocking VANISHED off the board until an A/D track freed up — it is drawn at the Limits ' +
'now, marked as held. Trains queued for a Crew Tray say so instead of waiting invisibly, with ' +
'the number of free trays beside them. A Red Flag standing at an Office is drawn on the map. A ' +
'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:
'Incluye Station Master v0.7.9.8 — ocho versiones de correcciones desde la v0.7.9, centradas en ' +
'el multijugador. LAS PARTIDAS EN CURSO EN ESTE SERVIDOR NO SE VEN AFECTADAS y se reanudarán con ' +
'normalidad. Dos cosas que toda la mesa podía ver y solo un jugador debía: la semilla aleatoria ' +
'se anunciaba en el historial compartido, y un robo a ciegas de la Oficina Central nombraba la ' +
'carta robada. El panel de historial volvía VACÍO tras recargar el navegador a mitad de partida: ' +
'el servidor tenía el registro completo y lo enviaba en un campo que nadie leía. Durante la ' +
'votación final de "¿jugar otro Día?" el turno nombraba a un jugador cualquiera, junto a un ' +
'recuento que sí mostraba a todos los pendientes; la votación está abierta a todos a la vez, así ' +
'que ahora dice que no se espera a nadie. Un tren detenido en tus Límites por un Enclavamiento ' +
'DESAPARECÍA del tablero hasta que se liberaba una vía: ahora se dibuja en los Límites, marcado ' +
'como retenido. Los trenes en cola por una Bandeja de Personal lo indican, con el número de ' +
'bandejas libres al lado. Una Bandera Roja plantada en una Oficina se dibuja en el mapa. Un ' +
'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:
'Enthält Station Master v0.7.9.8 — acht Fehlerkorrektur-Versionen seit v0.7.9, mit Blick auf den ' +
'Mehrspielermodus. LAUFENDE PARTIEN AUF DIESEM SERVER SIND NICHT BETROFFEN und werden normal ' +
'fortgesetzt. Zwei Dinge, die der ganze Tisch sehen konnte und nur ein Platz sollte: der ' +
'Zufallsstartwert stand im gemeinsamen Verlauf, und ein Blindzug aus dem Hauptbüro nannte die ' +
'gezogene Karte. Der Verlauf kam nach einem Neuladen des Browsers mitten im Spiel LEER zurück — ' +
'der Server hatte das ganze Protokoll und schickte es in einem Feld, das niemand las. Bei der ' +
'Abstimmung "noch einen Tag spielen?" nannte die Zuganzeige einen beliebigen Spieler, neben ' +
'einer Zählung, die alle Ausstehenden korrekt zeigte; die Abstimmung steht allen zugleich offen, ' +
'also heißt es jetzt, dass auf niemanden gewartet wird. Ein von einem Stellwerk an deinen ' +
'Grenzen angehaltener Zug VERSCHWAND vom Brett, bis ein Gleis frei wurde — er wird jetzt an den ' +
'Grenzen gezeichnet und als angehalten markiert. Züge, die auf ein Besatzungstablett warten, ' +
'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:
'Zawiera Station Master v0.7.9.8 — osiem wydań poprawek od v0.7.9, pod kątem gry wieloosobowej. ' +
'TRWAJĄCE PARTIE NA TYM SERWERZE NIE SĄ DOTKNIĘTE i wznowią się normalnie. Dwie rzeczy, które ' +
'widział cały stół, a powinien tylko jeden gracz: losowe ziarno ogłaszano we wspólnej historii, a ' +
'zakryte dobranie z Biura Głównego podawało nazwę dobranej karty. Panel historii wracał PUSTY po ' +
'przeładowaniu przeglądarki w trakcie gry — serwer miał cały dziennik i wysyłał go w polu, ' +
'którego nikt nie czytał. Podczas głosowania "zagrać jeszcze jeden Dzień?" wykres tury wskazywał ' +
'przypadkowego gracza, obok licznika poprawnie pokazującego wszystkich pozostałych; głosowanie ' +
'jest otwarte dla wszystkich naraz, więc teraz mówi, że nie czeka się na nikogo. Pociąg ' +
'zatrzymany na twoich Granicach przez Nastawnię ZNIKAŁ z planszy do czasu zwolnienia toru — teraz ' +
'jest rysowany na Granicach i oznaczony jako wstrzymany. Pociągi czekające na Tackę Załogi mówią ' +
'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:
'Inclut Station Master v0.7.9.8 — huit versions de corrections depuis la v0.7.9, orientées ' +
'multijoueur. LES PARTIES EN COURS SUR CE SERVEUR NE SONT PAS AFFECTÉES et reprendront ' +
'normalement. Deux choses que toute la table pouvait voir et qu’un seul joueur aurait dû : la ' +
'graine aléatoire était annoncée dans l’historique partagé, et une pioche à l’aveugle au Bureau ' +
'Central nommait la carte piochée. L’historique revenait VIDE après un rechargement du ' +
'navigateur en pleine partie : le serveur avait tout le journal et l’envoyait dans un champ que ' +
'personne ne lisait. Pendant le vote « jouer un Jour de plus ? », le tableau des tours nommait un ' +
'joueur arbitraire, à côté d’un décompte affichant correctement tous ceux qui restaient à voter ; ' +
'le vote est ouvert à tous à la fois, il indique donc maintenant qu’on n’attend personne. Un ' +
'train arrêté à vos Limites par un Enclenchement DISPARAISSAIT du plateau jusqu’à ce qu’une voie ' +
'se libère — il est désormais dessiné aux Limites, marqué comme retenu. Les trains en attente ' +
'd’un Plateau d’Équipe le disent, avec le nombre de plateaux libres à côté. Un Drapeau Rouge ' +
'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: {
/**
* 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 changed a RULE (§3.4's collision caps became live in solitaire), so a saved game that
* had crossed one stopped replaying. The general rule that fell out of it is written down in the
* game's README: 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.
*
* SO THE QUESTION FOR THIS BUMP IS NARROW: did anything become illegal between v0.7.9 and
* v0.7.9.8? Measured with `git diff v0.7.9..HEAD -- src/engine/` and reading every non-comment
* line of it. The whole diff is: `isExpedited` exported and widened to a structural parameter
* 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.
*
* MULTIPLAYER SAVES LIVE ON THIS SERVER and are the ones this package can strand, so that
* matters here in a way it did not for v0.7.9 — whose breakage was solitaire, in the player's own
* browser, where nothing in this package could have acted on it either way. Games in progress
* resume; the release notes say so in all five locales rather than leaving it to be discovered.
*
* WHAT IS NOT COVERED BY THAT ARGUMENT: `Frame` gained fields (`crewTrays`, `queued`,
* `heldAtLimits`, `enhancementsSpent`) and lost the narration log it was carrying for nobody.
* 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.
*/
up: async ({ effects }) => {},
down: IMPOSSIBLE,
},
})