Browser co-op kitchen game: FastAPI + native WebSockets, server-authoritative 20 Hz simulation, in-memory anonymous lobbies, data-driven YAML levels, Canvas 2D vanilla ES-module client with locally authored SVG art and no external CDNs. .agents/PLAN.md records the LOCKED decisions; .agents/user_stories/ holds the 12 flow contracts; .agents/phases/todo/ breaks them into 14 sequential, test-gated phases (71 task files), each leaving the app launchable and the suite green. LLM-Generated: true
1.6 KiB
1.6 KiB
US-09 — Drop out and come back mid-round
As a player on flaky Wi-Fi (or a locked laptop), I want to reconnect and land back in the same kitchen mid-round, so that one dropped socket does not ruin the group's game.
Acceptance criteria
- Losing the socket keeps the player's seat for
GUEST_IDLE_TIMEOUT_S(default 45 s); the cook stays in the kitchen and, after 3 s idle, parks and drops what they carried. - The other players see a "Cookie disconnected" label, not a vanished cook.
- Reconnecting with the same token + code mid-round restores the seat and resumes snapshots; time-to-playable ≤ 3 s after page load.
- The client shows a "reconnecting…" overlay with exponential backoff (0.5 s → 8 s cap, jittered) and never spams the server.
- Reconnecting after the grace window releases the seat and the player re-enters as a spectator (or joins the lobby if one exists).
- The server never leaves a ghost connection: a second socket for a token evicts the first, and closed rooms reject stale tokens with a clean error.
- A room whose last seat is gone is closed and its resources freed within one GC cycle.
- A mid-round server-side room exception aborts only that room and tells its players.
E2E suite
tests/e2e/test_us09_disconnect_rejoin.py — kill the socket (context.close of page B /
server-side kill_connection test hook), assert ghost label, reload and rejoin mid-round,
assert playable ≤ 3 s and identical score. Integration: seat grace, GC, stale-token paths.
Phases
06_realtime_websocket_protocol, 08_client_prediction_and_touch,
12_reconnect_resilience_and_scale