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
139 lines
12 KiB
TypeScript
139 lines
12 KiB
TypeScript
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,
|
||
},
|
||
})
|