0.8.0.12:0 — bundle Station Master v0.8.0.12, and a Restore a Seat action
A player who has lost their browser storage can be put back in their seat (Gitea#33 in the game repo). The session token is the only identity the game has and it lives in one browser's localStorage, scoped to the origin joined at, so a cleared profile, a private window or a different browser locks a player out of a game that is still running with their session still on disk. Seen at a real table: of two humans in one game, the host reloaded straight back in and the joiner met an empty lobby. New action, restore-seat: pick a seat from a dropdown of the players actually holding a session — bots never appear, since seatedPlayers is read from the server's session map rather than guessed from display names — and get back a link built from this interface's own address. serverApi gained mintClaim; the dictionary gained 57-64 in all five locales. THE LINK CARRIES A CODE, NOT THE TOKEN. lobby-and-sessions.md §1 says to keep the token out of URLs so it is not shoulder-surfed or pasted into a chat, and a recovery link is exactly what gets pasted into a chat. The code is single-use, expires in 30 minutes, and the page trades it for the real token over a POST. Minting is admin-gated because deciding that somebody has lost a seat is a judgement no route can make safely; spending needs no secret, because the player following the link holds none. GAMES IN PROGRESS RESUME NORMALLY, measured rather than assumed: `git diff v0.8.0.11..v0.8.0.12 -- src/engine/` is EMPTY. The release is the server's HTTP surface, the client and the docs. The codes live in memory and are deliberately not persisted, so nothing new reaches the volume and there is nothing to migrate. README, instructions.md and the release notes in all five locales say so. NOT YET EXERCISED END TO END: the two routes and the action are typechecked and the claim store is unit-tested, but nothing has run them against a live server. This build is what makes that possible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017nnuCv8UodHucFfx3LWEoX
This commit is contained in:
@@ -13,19 +13,18 @@ Station Master is a railroad operations board game with an authoritative multipl
|
||||
solitaire needs no server and is not what this package is for. This package runs that server —
|
||||
the browser client, the lobby, and the intent/SSE API — as a single StartOS service.
|
||||
|
||||
**Bundled version: 0.8.0.11.** Sixteen fixes from the second multiplayer playtest. Making up a train
|
||||
now says what the consist STILL needs, that a player adds one car before the round passes on, marks the
|
||||
train being loaded on the Division map, and gives an addable car in the yard the page's action colour. A
|
||||
train's arrival names whose Office it reached. A player watching the board catch up can pause it, look at
|
||||
another player's Office Area, and sees one consistent Day/Stage/phase rather than a chart running ahead of
|
||||
the board. Saves download named after the game. v0.8.0.10 before it corrected when the Superintendent is
|
||||
asked to rule; v0.8.0.9 rebuilt the bot and made the engine about three times faster.
|
||||
**Bundled version: 0.8.0.12.** A player who has lost their browser storage can be put back in their
|
||||
seat, through the new **Restore a Seat** action — see Actions below. The session token is the only
|
||||
identity the game has and it lives in one browser's `localStorage`, so a cleared profile, a private
|
||||
window or a different browser locks a player out of a game that is still running with their session
|
||||
still on disk. v0.8.0.11 before it was sixteen playtest fixes, including the New Train panel saying what
|
||||
a consist still needs; v0.8.0.10 corrected when the Superintendent is asked to rule.
|
||||
|
||||
**Games in progress resume normally on this one**, and it was checked the narrow way rather than assumed:
|
||||
`git diff v0.8.0.10..v0.8.0.11 -- src/engine/` is three files, nineteen insertions — an `owner` field on
|
||||
the `trainArrived` event, the one line that fills it, and a reworded card description. No predicate
|
||||
changed its answer, so no once-legal move became illegal. (0.8.0.10 was the exception: it corrected a
|
||||
ruling and deliberately stranded games holding one. That warning does not apply here.)
|
||||
**Games in progress resume normally on this one**, and it was checked the narrow way rather than
|
||||
assumed: `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 — no predicate was edited, so no once-legal move became
|
||||
illegal. (0.8.0.10 was the exception: it corrected a ruling and deliberately stranded games holding
|
||||
one. That warning does not apply here.)
|
||||
|
||||
The paragraphs below were written for the 0.7.9.8 bump and still describe how a bump is checked.
|
||||
|
||||
@@ -285,8 +284,8 @@ progress on every update, including updates that changed only how the board is d
|
||||
|
||||
## Actions
|
||||
|
||||
Two of the three read or change the games on the server, and both are `only-running`: what they
|
||||
report exists only inside the live server process. A save is a seed plus a list of moves, so
|
||||
Three of the four read or change the games on the server, and all three are `only-running`: what
|
||||
they report exists only inside the live server process. A save is a seed plus a list of moves, so
|
||||
"whose turn is it" is answerable only by replaying the game through the engine — which lives in
|
||||
the game repo, not in this package. The server has already done that work and is asked for the
|
||||
answer.
|
||||
@@ -313,6 +312,19 @@ answer.
|
||||
worth replaying. This is the only way a game ends other than being played to a finish: an
|
||||
abandoned game otherwise stays active and is resumed on every restart indefinitely.
|
||||
|
||||
- **Restore a Seat** (`restore-seat`) — pick a seat from a dropdown of the players actually holding
|
||||
a session, and get back a one-time link that puts that player into it. **This is the answer to a
|
||||
lost seat token** (Gitea#33 in the game repo): the token is the only identity the game has and it
|
||||
lives in one browser's `localStorage`, so a cleared profile, a private window or a different
|
||||
browser leaves a player locked out of a game that is still running with their session still on
|
||||
disk. The link carries a **code, never the token** — single-use, expires in 30 minutes — which the
|
||||
page trades for the real token over a POST as it loads (`lobby-and-sessions.md` §1: keep the token
|
||||
out of URLs). Anyone who opens the link takes that seat, so it is sent to one person and not to a
|
||||
public channel. Minting is administrative because deciding that somebody has lost a seat is a
|
||||
judgement; spending needs no secret, because the player following the link holds none. The
|
||||
dropdown lists only seats a human holds a token for — bots never appear, read from the server's
|
||||
session map rather than guessed from player names.
|
||||
|
||||
## Tasks
|
||||
|
||||
- **Get the join secret to share with players** — raised on install, severity `critical`. Points
|
||||
|
||||
Reference in New Issue
Block a user