fix(session): reset lobby when player leaves finished match

This commit is contained in:
2026-09-13 23:14:09 +03:00
parent b6d484dbc9
commit 8ad856b931
10 changed files with 146 additions and 38 deletions
+58 -28
View File
@@ -3443,8 +3443,9 @@ resources.
Let an authenticated player or observer deliberately leave through the
top-right settings menu, revoke only that browser's session, immediately free
its slot, and return it to the name-entry screen with its previous display name
prefilled. A player leaving an unfinished match must authoritatively cancel
that match and return every remaining participant to the lobby, while an
prefilled. A player leaving any non-waiting match phase, including a finished
result, must authoritatively cancel that match and return every remaining
participant to the lobby, while an
observer departure or a lobby departure must not reset gameplay.
### Scope
@@ -3457,10 +3458,10 @@ observer departure or a lobby departure must not reset gameplay.
authenticated player or observer session; do not show it on the unauthenticated
welcome and name-entry screen.
- Require a modal confirmation before sending an exit command. For a player in
countdown, active, finish-pending, or paused state, clearly warn that the
current match will end for everyone and the player's slot will be freed. For
a player in the lobby or an observer in any phase, explain that only this
browser's place will be released.
countdown, active, finish-pending, paused, or finished state, clearly warn
that the current match will return everyone to the waiting lobby and the
player's slot will be freed. For a player in the lobby or an observer in any
phase, explain that only this browser's place will be released.
- Treat opening or cancelling the confirmation as browser-local UI only. While
it is open, suppress input from that browser without pausing or otherwise
mutating authoritative state; cancelling must restore the previous screen,
@@ -3469,15 +3470,14 @@ observer departure or a lobby departure must not reset gameplay.
correlated success response. It must be distinct from an unexpected socket
disconnect, page reload, or transient connection loss, which retain the
existing 60-second player reconnection contract.
- On an accepted player leave during countdown, active, finish-pending, or
paused state, stop all match timers, clear the current authoritative match,
return the lobby to its waiting state, retain every other connected session
and role, revoke the leaving session, free its player slot immediately, and
broadcast the cancellation and fresh lobby state to the remaining players
and observers.
- On an accepted player leave while already in the waiting lobby or after a
completed result, revoke only that player's session and free its slot. Do not
reset an unfinished match because none is active in those phases.
- On an accepted player leave during countdown, active, finish-pending, paused,
or finished state, stop all match timers, clear the current authoritative
match, return the lobby to its waiting state, retain every other connected
session and role, revoke the leaving session, free its player slot
immediately, and broadcast the cancellation and fresh lobby state to the
remaining players and observers.
- On an accepted player leave while already in the waiting lobby, revoke only
that player's session and free its slot.
- On an accepted observer leave in any phase, revoke only that observer's
session and free its observer slot. Never pause, reset, finish, restart, or
otherwise mutate the match because an observer leaves.
@@ -3536,18 +3536,20 @@ observer departure or a lobby departure must not reset gameplay.
modal and sends no protocol command until explicit confirmation. Cancelling,
pressing Escape, or activating the modal's cancel action leaves the session
and authoritative state unchanged and safely restores focus.
3. A player confirmation during countdown, active, finish-pending, or paused
state explicitly says that the match will end for everyone and the slot will
be freed. Confirmation produces exactly one authoritative cancellation,
stops every relevant timer, clears the current match, and returns all
remaining connected participants to a fresh waiting lobby.
3. A player confirmation during countdown, active, finish-pending, paused, or
finished state explicitly says that the match will return everyone to the
waiting lobby and the slot will be freed. Confirmation produces exactly one
authoritative cancellation, stops every relevant timer, clears the current
match, and returns all remaining connected participants to a fresh waiting
lobby.
4. The leaving player's session is removed and its slot becomes available in
the same accepted server transition. Every other player's and observer's
session, role, and connection remain valid, and the resulting lobby snapshot
consistently shows the newly free slot.
5. A player leaving the waiting lobby or a completed result releases only that
player's session and slot. It does not disconnect other participants or
perform an additional match reset.
5. A player leaving the waiting lobby releases only that player's session and
slot. A player leaving a completed result performs the same authoritative
return-to-lobby transition as another non-waiting player exit, without
disconnecting any remaining participant.
6. An observer leaving during any phase releases only that observer session and
observer slot. Match phase, players, timers, maze, objects, inventory, and
results remain byte-for-byte unchanged except for the expected lobby
@@ -3586,11 +3588,12 @@ observer departure or a lobby departure must not reset gameplay.
15. All host and browser tests pass; compressed-web-asset validation passes;
the payload remains within the 1.5 MiB web budget and LittleFS partition;
and firmware remains within the factory partition.
16. Physical-device testing confirms that a player can cancel an unfinished
match and immediately release its slot, an observer can leave without
affecting play, the remaining browsers receive the correct lobby state,
and the departing browser returns to a prefilled name-entry screen without
stale controls, delayed input, or reconnect side effects.
16. Physical-device testing confirms that a player can cancel a non-waiting
match, including a finished result, and immediately release its slot, an
observer can leave without affecting play, the remaining browsers receive
the correct lobby state, and the departing browser returns to a prefilled
name-entry screen without stale controls, delayed input, or reconnect side
effects.
17. The project owner confirms on representative mobile and desktop browsers
that the exit action is easy to find but difficult to trigger accidentally,
its consequences are clear, and all role-specific outcomes match the
@@ -3614,3 +3617,30 @@ observer departure or a lobby departure must not reset gameplay.
immediate server-side session revocation, player-match cancellation, and a
browser confirmation flow that clears the temporary token only after the
correlated acknowledgement.
- On 2026-09-13, a corrective lifecycle inspection found that the explicit
player-leave handler excluded `MAZE32_GAME_PHASE_FINISHED` from its match
reset condition. It therefore revoked the departing result-screen session
but did not broadcast `reset`, which could leave remaining clients behind an
unusable result modal. The handler now resets for a player leaving every
non-waiting lobby phase, including a completed result; it keeps waiting-lobby
player exits and observer exits session-scoped. The reset is broadcast before
the fresh lobby snapshot, and browser reset handling hides the modal and
renders the waiting lobby.
- On 2026-09-13, `node --test test/web/test_player_app.js` passed 31 tests,
including the result-phase leave regression that verifies the confirmation
warning, server reset condition, correlated token cleanup, modal dismissal,
and lobby rendering. `bash scripts/run_host_tests.sh` passed all suites;
its lobby/protocol suite reported explicit leave session revocation and slot
reuse as passing, including invalid-token restoration after either Player 1
or Player 2 leaves, retained player and observer sessions, observer-only
leave, duplicate leave idempotence, and immediate replacement of both player
slots. `python3
scripts/verify_web_assets.py` passed with deterministic payload
`3fb28e1ae55deba0ac592bcd99d81b7e95271604a5b35d7f293c4b8bffef6143` at
33,183 / 1,572,864 bytes. `/home/sasa/.platformio/penv/bin/pio run` passed
at 1,030,256 / 2,097,152 factory bytes, and `/home/sasa/.platformio/penv/bin/pio
run --target buildfs` passed at 2,031,616 / 2,031,616 LittleFS bytes.
- On 2026-09-13, the project owner checked the corrected result-screen exit
flow in the browser and confirmed that the issue was fixed: a remaining
participant is returned from the result modal to a usable waiting lobby when
the other player explicitly leaves.