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
235 lines
16 KiB
Markdown
235 lines
16 KiB
Markdown
# Station Master
|
|
|
|
## Documentation
|
|
|
|
- [Rules and design docs](https://draco.local:53871/Jesse.Markowitz/station-master/src/branch/main/docs)
|
|
— the rulebook implications, the multiplayer design, and the game's architecture.
|
|
|
|
## What you get on StartOS
|
|
|
|
This service runs the multiplayer server: a lobby, and a table for 2 to 4 players to play a
|
|
competitive or cooperative game together from their own browsers. Everything a player needs — the
|
|
game itself, the lobby, and the connection back to this server — is served from the single web
|
|
interface below; there is nothing else to install or configure on a player's side.
|
|
|
|
## Getting set up
|
|
|
|
1. Run the **Get Join Secret** action from this service's Actions menu, and copy the value it
|
|
returns.
|
|
2. Share that secret, and this service's address, with everyone you want to play with. Anyone
|
|
holding the secret can create a new game or join one that hasn't started yet.
|
|
3. Open this service's **Multiplayer Table** interface. You'll land on the front page, which
|
|
offers three ways in: solitaire, the replay viewer, and multiplayer.
|
|
4. Click **Play multiplayer**, then **Create Game** (or **Join Game** with a game code someone
|
|
else created), and enter the join secret when asked.
|
|
|
|
## Using Station Master
|
|
|
|
### Multiplayer Table
|
|
|
|
The front page offers solitaire, the replay viewer, and multiplayer. **Play multiplayer** takes you
|
|
to the lobby: create or join a game, seat players (including filling empty seats with a bot), and
|
|
start. Once a game is underway, this same interface is where every player plays their turns and
|
|
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
|
|
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
|
|
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.
|
|
They are now. A saved solitaire game in which trains have collided will therefore refuse to reopen,
|
|
because the moves it recorded are no longer all legal. **Nothing is destroyed:** the save is left
|
|
exactly as it was and the game simply declines to load it, rather than opening something the rules
|
|
could not have produced. If you have a solitaire game you care about, finish it before updating.
|
|
**Multiplayer games on this server are not affected.**
|
|
|
|
The rest of 0.7.9 is things you can see. **The end-of-game screen now asks whether to play one more
|
|
Day** — the question was being drawn underneath the results dialog, so a solitaire player reaching
|
|
the end of the timetable was never offered it. **"Waiting on" now names the person and what they are
|
|
being asked**, instead of saying nobody was holding the game up while it waited on the
|
|
Superintendent. **The game's settings have moved off the top line into a This Game card** at the foot
|
|
of the right-hand column, where all of them are listed rather than the four that fitted; the running
|
|
collision counts take their place at the top, since those change as you play. **The Office Area's
|
|
show/hide button is now three buttons** — auto-hide, always show, always hide — because as a single
|
|
cycling button it could not reach every setting. **The history now reads newest first.** And **a
|
|
Heavy Grade card shows which way it climbs**, instead of only saying so in its tooltip.
|
|
|
|
**What changed in 0.7.8.** The solitaire setup screen now appears for everyone. It was being skipped
|
|
whenever your browser held a saved solitaire game — and any browser that has ever played holds one —
|
|
so most players never saw it at all. Clicking **Play solitaire** now always asks how you want the
|
|
game set up. **Your game in progress is safe:** the screen offers **Continue saved game**, and says
|
|
plainly that dealing a new one replaces it. Simply reopening the page still picks up where you left
|
|
off, exactly as before. The homepage footer now names both ways to play, too.
|
|
|
|
**What changed in 0.7.7.** Updates to this service now actually reach your browser. Until now every
|
|
release published its files under the same cache name and the server never told browsers when to
|
|
look again, so returning players kept running whatever version their browser had already stored —
|
|
the 0.7.5 solitaire setup screen and its 0.7.6 fix were both installed correctly here and neither
|
|
was ever seen. If a past update seemed to do nothing, this is why, and opening the page in a private
|
|
window was the only way to see it. That should not be necessary again.
|
|
|
|
**What changed in 0.7.6.** The **Play solitaire** door on the front page now reliably reaches
|
|
solitaire. If this browser had ever taken a seat at a multiplayer table, the door used to lose to
|
|
that game or lobby instead — a plain page load couldn't tell "I clicked Play solitaire" apart from
|
|
"I reloaded mid multiplayer game". Fixed; nothing else changed.
|
|
|
|
**What changed in 0.7.5.** Solitaire now asks before it deals. A genuinely fresh visit to the
|
|
solitaire page opens a setup screen with the full set of options — game type, starting hand, where
|
|
an Extra may start, the revenue rates, victory conditions, and the optional rules — the same
|
|
question the multiplayer lobby has asked before a game starts since 0.7.0, below. Press **Deal**
|
|
when you're ready. A saved game, a shared link that already carries a seed, or a link the setup
|
|
screen itself just produced all skip straight past it — those already answer the question rather
|
|
than needing to ask it again. Nothing about the rules changed, so **every game in progress carries
|
|
over**, both here and on the multiplayer server, without exception.
|
|
|
|
**Setting a game up (new in 0.7.0).** The lobby opens on **Join a game**: type the code you were
|
|
given and you will see the whole rule set — the opening hand, what the work pays, every way the game
|
|
can end — _before_ you take a seat. Creating a game instead starts from a **game type**: Co-op,
|
|
Competitive or Cutthroat. A type just fills in the rules; every one of them is yours to change, and
|
|
changing any of them marks the game **Custom**, which keeps the scoring of the type you started
|
|
from. The seed, the number of players and the number of Days sit above the type and do not make a
|
|
game Custom — the targets re-derive from them.
|
|
|
|
**What changed in 0.7.4.** Before anything else: **a game already in progress may not carry over.**
|
|
These are rules changes, and three of them alter what a saved game is allowed to contain, so an
|
|
old game may stop replaying. The server declines to resume one rather than breaking it — it says
|
|
which move it stopped at and leaves the save alone — so if you are mid-game and it matters, finish
|
|
it before updating or put 0.7.3 back on afterwards. A game that never runs into one of the three
|
|
carries on as normal.
|
|
|
|
**The Yard Office asks you now.** A freight train arriving in your district used to be sent into the
|
|
yard automatically, whether you wanted it there or not. Now you are asked. Three things it never
|
|
checked before it does now: it has to be able to **reach the yard in one move** — if it cannot, you
|
|
are not offered the choice, and the history tells you why rather than staying silent — and if there
|
|
are **cars standing on the way in, the train hits them**, exactly as it would anywhere else. Taking
|
|
the yard still keeps your Train Order Office free, which is the whole point of the card.
|
|
|
|
**Circus, Campaign and Military trains run loaded.** They take loaded cars from the Division Yard
|
|
while there are any, empties once there are not, and will run short rather than wait. A Circus or
|
|
Campaign train earns its point for setting up **once in each player's district** rather than once in
|
|
the whole game — so a train that tours the Division is worth more than one that parks — and only
|
|
when every car is full. Not much of a circus if the cars are empty. The Campaign train earns that
|
|
point for the first time; it never scored at all before, and it needs its candidate aboard.
|
|
|
|
**Red Flags does something else entirely.** It used to protect one stopped train out on the line.
|
|
Now you plant it on the **east or west side of your own district**, and it holds the next train
|
|
coming from that way — which is how you buy yourself a Stage to finish switching. It comes down with
|
|
the train it stops: one card, one train. You can also play it at the moment it matters. If a train
|
|
is arriving into a certain collision and you are holding the card, the game stops and asks whether
|
|
you want to flag it; say no and the collision happens.
|
|
|
|
**What changed in 0.7.3.** **Your games in progress survive this one** — unlike the last update,
|
|
nothing about the deck or the way a game is saved has changed, so a game saved under 0.7.2 picks up
|
|
where it left off.
|
|
|
|
**The game asks before it ends.** When the last Day on the timetable runs out, you are no longer
|
|
simply told the game is over: you are asked whether to play one more Day. Say yes and you get one
|
|
Day — not two, not the rest of the evening — and at the end of it you are asked again. In a
|
|
multiplayer game **everybody has to agree**, and one "no" ends it there and then, so nobody is kept
|
|
playing a game they have finished with.
|
|
|
|
**Playing on cannot change who won.** The result is decided at the length you dealt the game for. If
|
|
you set up five Days and carry on to eight, the winner is still whoever was ahead at the end of Day
|
|
5, and the results screen says so — everything after that is recorded as what it is, an exhibition.
|
|
One exception: a game that ends because of **too many collisions** is over for good and is not
|
|
offered another Day, whether that happens on a scheduled Day or an extra one. A railroad that has
|
|
been declared unsafe does not carry on regardless.
|
|
|
|
**The end of a game now tells you what happened.** In place of one line and a number there is a full
|
|
results screen: why the game ended, in plain English rather than a code; who won and by how much;
|
|
every player's Revenue side by side; the rules the game was actually dealt under, including the pay
|
|
rates and any optional rules; who did what; and what the railroad managed — trains that ran the
|
|
length of the Division and how many of them did any switching on the way, loads made up and broken,
|
|
passengers boarded and set down, cars coupled and set out, and any trains lost to a collision along
|
|
with the cars that went with them. It comes up by itself when the game ends and there is a button to
|
|
open it again, so playing on never costs you the results.
|
|
|
|
**What changed in 0.7.2.** Before you read on: that update was the one where **a game already in
|
|
progress did not carry over**, because the card deck changed size. If you are updating from 0.7.1 or
|
|
earlier, that still applies to you.
|
|
|
|
At the table, three things looked different. **Crossing a Mainline card is quicker, and counted
|
|
differently**: the speed sign printed on the card was always just scenery, and what decides the time
|
|
is the number of regions drawn on it — Plains and Double Track one, Curves and Tunnel two, Heavy
|
|
Grade three unless you have Helpers or Brakeman on it. A train's **Fast/Slow rating only matters on
|
|
the Hilly card** now, instead of adding a Stage to every card, so slow trains in particular get
|
|
across the Division far quicker than they used to. **The deck is smaller and holds less track**,
|
|
matching the published card counts, so building a district is a slower business and the cards you
|
|
draw are worth more. And **the Division map is one row you read left to right**, west on the left and
|
|
east on the right, instead of wrapping around the screen — it no longer shows the inside of anyone's
|
|
district, which is what your own Office map is for, but every train in a district still appears on
|
|
it, with the ones holding an arrival track drawn on the rail and any crew switching drawn below it.
|
|
|
|
**Leaving, and coming back.** Anyone may leave a lobby, and the host can clear a chair, so a
|
|
mis-join or somebody who wanders off no longer blocks a table that cannot start until every seat is
|
|
taken. A **Leave game** button appears once a game is running: it keeps your seat and the table
|
|
waits for you, and the lobby lists every game this browser is in so you can rejoin it — or join a
|
|
different one without losing the first. **Forget** on that list is the one thing that cannot be
|
|
undone: the token kept in your browser is the only proof of who you are, so a forgotten game cannot
|
|
be rejoined from that browser.
|
|
|
|
### Get Join Secret
|
|
|
|
Run this whenever you need the current join secret again, or want to shut out anyone still
|
|
holding an old one. Every run replaces the secret and immediately puts the new one into effect —
|
|
players already seated in a game are unaffected, but the old secret stops working for creating or
|
|
joining games from that point on.
|
|
|
|
### Games in Progress
|
|
|
|
Shows every game on the server: who is playing, which Day and Stage they have reached, and whose
|
|
turn it is. It changes nothing, so run it whenever you are curious. It is also how you spot a game
|
|
nobody is coming back to — one whose last move was days ago, still waiting on a particular player.
|
|
|
|
### Manage Game
|
|
|
|
Pick a game, then either save a copy of it or end it.
|
|
|
|
**Export** hands you the whole game as text and leaves it running. Save that text as a `.json`
|
|
file and you can open it in the replay viewer later to watch the game back.
|
|
|
|
**End the game** deletes it and disconnects anyone still watching. This is the only way to clear
|
|
a game that will never be finished — otherwise it sits there, and comes back every time the
|
|
service restarts. It cannot be undone, so the game's save is handed back to you when it happens:
|
|
that text is the only copy left, so keep it if the game was worth watching.
|
|
|
|
> **Games in progress normally survive an update of this service.** When the update changes the
|
|
> rules of the game itself, a half-played game cannot be resumed under rules it was not played by,
|
|
> and that game is set aside rather than continued — you would see it disappear from the lobby.
|
|
> Nothing is ever deleted, so going back to the previous version makes it playable again.
|