The extension question was hidden behind the results screen (Gitea#11)

Jesse, playing v0.7.8: "Solitaire game ended. I did not have an option
to extend the game by a day."

The engine and the Frame were right — checked before changing anything.
A solitaire game at the end of its timetable reaches awaitingExtension
with extensionVotes [null], and renderEnding writes "play one more Day"
into #actions. It then opens #resultsdlg, which is MODAL, so those
buttons were directly underneath a dialog whose only control was Close.

The results dialog now carries the question itself, hidden unless a vote
is pending: Play One More Day / End the Game Here, casting the same
game.extend intent. The #actions buttons stay as the fallback once it is
closed.

TODO.md #35 recorded extended play as verified on phoenix.local — over
the HTTP API, which renders no dialog. What was proven was that the
server supports it, not that a player can reach it. Noted there.

Rides along in the unshipped v0.7.9. 870 tests pass, one 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 01:26:03 -04:00
co-authored by Claude Sonnet 5
parent f2c87b6871
commit e035dda5a3
5 changed files with 101 additions and 2 deletions
+26 -2
View File
@@ -52,6 +52,30 @@ when `start.seat !== seatOf(s, player)`, which cannot happen — so this is a la
gameplay effect and nothing to re-measure. The permissive label described a permission a lone player
was never being granted, and named an "any player" they have no contrast with.
### The extension question was hidden behind the results screen
Jesse, 2026-08-30: "Solitaire game ended. I did not have an option to extend the game by a day."
**The engine and the Frame were right the whole time** — checked before changing anything: a
solitaire game at the end of its timetable reaches `awaitingExtension` with `extensionVotes: [null]`,
and `isExtendable` covers both `revenueFloor` and `daysElapsed`. `renderActions` reaches
`renderEnding` for any non-active status, and `renderEnding` writes "play one more Day" and "end the
game here" into `#actions`.
Then it opens `#resultsdlg`, **which is modal**. So the two buttons were rendered directly underneath
a dialog whose only control was Close, and the player read a results screen that offered nothing but
Close and concluded the game was over — which is precisely what it looked like.
The results dialog now carries the question itself, hidden unless a vote is actually pending:
**Play One More Day** and **End the Game Here**, casting the same `game.extend` intent. The
`#actions` buttons stay, because they are what remains once the dialog is closed and what a player
who reopens it with "see the full results" comes back to.
**Why this survived being "verified".** `TODO.md` #35 recorded extended play as checked on
`phoenix.local` — over the HTTP API, which renders no dialog. The browser path had never been run to
the end of a timetable. Same shape as the three attempts before it: the thing that was verified was
not the thing the player uses.
### Three wording and layout fixes
- **The collision entries** on all three screens now read "The game ends immediately and results in
@@ -66,8 +90,8 @@ was never being granted, and named an "any player" they have no contrast with.
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".
869 tests pass, two of them new; one existing test asserted the opposite of the ruling above and
says so where it was reversed.
870 tests pass, three of them new; one existing test asserted the opposite of the collision ruling
above and says so where it was reversed.
---