Say who the game is waiting on, and move the Fedora; replay in words

Three items folded into the unshipped v0.7.9.

WAITING ON (reported by Jesse from play). The status line said "nobody —
the Division is running itself" while the game was stopped on the
Superintendent. Frame.actor carried clock.currentActor, which is null
for the whole Mainline Phase, so all three interruptions — §8.1's
clearance ruling, Gitea#5's Yard Office offer, Gitea#19's Red Flag
prompt — reported that nobody was holding it up. actingPlayer had the
answer since the Gitea#5 refactor; the Frame threw it away. It carries
actingPlayer now, plus a new `awaiting` field naming the question and
the train: "waiting on Bob · a clearance ruling · Train 4". Naming the
person alone is not enough when three different things can be pending.

THE FEDORA (TODO #29) rides at the right-hand end of the phase row
instead of a line of its own, and wraps under rather than squeezing the
chips.

THE DEVELOPER REPLAY (TODO #34) printed "loss — revenueFloor", the same
defect Gitea#16 was filed about, still alive because nothing
player-facing pointed at it. panels.ts's reasonSentence is exported and
shared rather than reimplemented, fed the last recorded frame and
stripped of markup. The drift test maps win/loss to won/lost so it still
checks the two AGREE rather than that they are spelled alike.

Also carries the previous, unsigned commit's work: the two setup screens
worded the same section by section.

877 tests pass, ten new.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdG46Ja2PEDBkpqiDazMoX
This commit is contained in:
Jesse.Markowitz
2026-08-30 09:01:19 -04:00
co-authored by Claude Sonnet 5
parent 131538dc7c
commit a70b7f88f3
11 changed files with 304 additions and 81 deletions
+65 -1
View File
@@ -154,6 +154,70 @@ missing one just made it a different form that happened to share a rules block.
The drift guard that had been checking three prefixes now checks two, and a new assertion fails if
any `ng-` id ever reappears.
### The two screens are worded the same, section by section
Jesse, 2026-08-30: "let's get the text between the Multiplayer and solitaire as close as possible to
the same." Walked section by section; where the two said the same thing differently, the lobby's
wording won, because it was written for the harder case.
- **The chair note is one paragraph on both**, replacing two that each described only their own
case: "Every chair must be filled before the game can start. For solitaire, there's only one
player. For multiplayer, that must be filled by a person or a bot. The number of players cannot be
changed once the game is created."
- **The Game type heading names which game the screen deals** — "Game type (multi-player)" and
"Game type (solitaire)". That heading is now the whole explanation for the dimmed rows.
- **No reason is printed beside a dimmed type any more.** The lobby appended "— dealt with the New
game button, not here" to Solitaire, and the solitaire screen appended "— use the Multiplayer
button; a table needs a server" to each of three. Jesse: "grayed out with no additional
explanation. The explanation above… is sufficient." One heading says it once; three rows were
saying it three times. `markUnavailable` is down to dimming, and `.lb-why` is gone with them.
- **The sentence under the radios is deleted on both.** It restated the type just chosen to the
person who had just chosen it. Its one non-obvious case — how many settings a Custom game differs
by — is not lost: `form.mark` already puts "Co-op default: …" on each row that differs, which is
where a reader can act on it rather than a count they would have to go and find. The tests that
read that sentence now read the row hints instead.
- **The Game settings, Starting hand and Victory conditions notes are the lobby's on both**, with
one edit Jesse asked for: "clicking a type again resets" → "changing the game type resets", which
names the control that does it rather than a gesture. Victory conditions was not on his list —
applied under the same rule, and the lobby's wording fits now that solitaire also shows the table
size.
What is deliberately still different: each screen's own opening paragraph, and the heading above.
### The status line said nobody was holding the game up
Jesse, 2026-08-30: "waiting on shows 'nobody — the Division is running itself' BUT the system is
actually waiting on the Superintendent."
`Frame.actor` carried `clock.currentActor`, which is null for the whole Mainline Phase — so the three
interruptions that stop the game and put a question to a named person (§8.1's clearance ruling,
Gitea#5's Yard Office offer, Gitea#19's Red Flag prompt) all reported that the Division was running
itself. `actingPlayer` has had the answer since the Gitea#5 refactor; the Frame threw it away.
It carries `actingPlayer` now, **and what the question is**: "waiting on **Bob** · a clearance ruling
· Train 4". Naming the person is not enough on its own — three different things can be pending, and
"waiting on Bob" with nothing after it is a game that looks stuck to everyone except Bob.
### The Fedora moved to the end of the phase row
`TODO.md` #29. It sat on a line of its own between the phase chips and everything above them, which
put a thing that moves every third Stage in among the things that move every Stage. It rides at the
right-hand end of the phase row now — the row whose last chip is Supervisor Shift, the phase that
passes it — and wraps underneath rather than squeezing the chips on a narrow screen.
### The developer replay stopped printing a raw enum
`TODO.md` #34. Its heading read `loss — revenueFloor`: the exact defect Gitea#16 was filed about on
the playable page, still alive here a release after that was fixed, because nothing player-facing
pointed at it. It reads "lost — The Division closed short: 3 Revenue between everyone, against a
floor of 15…" now.
`panels.ts`'s `reasonSentence` is exported and shared rather than reimplemented, so the replay and
the results screen cannot explain one ending two different ways. It is fed the last recorded frame —
the state the outcome was decided in — and stripped of markup, since it lands in an `<h1>` and a
console line. The drift test that compared this string against the engine now maps `win`/`loss` to
`won`/`lost`, so it still checks the two agree rather than that they are spelled alike.
### Three wording and layout fixes
- **The collision entries** on all three screens now read "The game ends immediately and results in
@@ -168,7 +232,7 @@ any `ng-` id ever reappears.
cost, not a danger, and red would outrank the actual rules above it. The buttons say **Continue
Existing Saved Game** and **Deal New Game** rather than "Continue saved game" and "Deal".
874 tests pass, seven of them new; one existing test asserted the opposite of the collision ruling
877 tests pass, ten of them new; one existing test asserted the opposite of the collision ruling
above and says so where it was reversed.
---