--- title: "Sprint 21 — Client Briefing" description: "Save/load game flow, debug overlay housekeeping" type: sprint status: archived sprint: 21 team: "client" --- # Sprint 21: Instantiate — Client Tasks **Goal:** The template system becomes executable — templates spawn NPCs, assign triangles, and place them in world space; cross-template triangles link social sites; the client gains save/load game flow; and the generator pipeline gets its architectural design. **Branch:** `client` **Agents:** Stig (dev), Hoshe (QA) ## New Tickets | # | Title | Blocked by | |---|-------|------------| | #257 | Save/load game flow | — (#256 done) | | #561 | Housekeeping: move debug_overlay.gd to ui/ directory | — | Use `tooling/db/ticket show ` for full details on any ticket. ## Key Decisions - `decisions/architecture.md` — D-020 (Godot = pure renderer, no game logic in GDScript), D-085 (per-game save directories under `user://saves//`), D-088 (3-state pause: Normal/Overlay/Paused, server-authoritative) - `decisions/scope.md` — D-027 (vertical slice: smuggler + detective, two-character proof) ## Notes **#257 — Save/load game flow** - Server-side serialization (`SaveStateV1`, `SaveLoadCommand`) landed in Sprint 19 (#553, #553). The client `SessionManager` autoload (`client/scripts/autoloads/session_manager.gd`) already creates per-game directories and tracks `current_game_id`. The `input.rs` server-side hook for `SaveLoadCommand::Save` and `SaveLoadCommand::Load` is in place. - What's missing: the client UI flow — save-to-file and load-from-file screens, and F5/F6 quicksave/quickload keybinds wired to `PlayerInput`. - `client/ui/main_menu.gd` exists. Add a "Load Game" screen that calls `SessionManager.list_game_dirs()` and lets the player select a save. - F5 quicksave flow: send `PlayerInput { action: QuickSave }` → server responds with serialised save data → client writes to `user://saves//quicksave.sav`. F6 quickload: reverse. - Loading screen: a minimal full-screen overlay ("Resuming...") during the round-trip to prevent input during load. No elaborate animation needed for v0.1. - D-020 constraint: no game logic in client. The client never constructs save data — it only sends the command and receives the file bytes from the server. - Existing stub in `session_manager.gd` line 71 notes: "The actual F5 save will be wired here once server supports SaveCommand." Server supports it now — wire it. - Acceptance: (1) F5 in-game triggers quicksave, file appears at correct path. (2) F6 reloads it, player position and NPC state match save. (3) Main menu "Load Game" lists existing saves sorted by date. **#561 — Housekeeping: move debug_overlay.gd to ui/ directory** - `client/scripts/ui/debug_overlay.gd` is the odd one out — all 17 other UI components live in `client/ui/`. This was flagged in a code review. - Steps: move `client/scripts/ui/debug_overlay.gd` (and its `.uid` file) to `client/ui/debug_overlay.gd`. Update any `preload()` or `load()` references. Update the `.tscn` that instances it if one exists. - Check `client/scripts/rendering/` and `client/scripts/autoloads/` for any imports of the old path. - If moving would break more than 3 references and the distinction is intentional (debug overlay is a script, not a scene-based UI), document the distinction in a comment at the top of the file instead, and close the ticket as "documented not moved." - Acceptance: `make ci-client` passes with the file at its new location, or the distinction is documented in-file. ## Dependency Chain ``` #257 (save/load game flow) — standalone #561 (debug_overlay housekeeping) — standalone, parallel ``` Both tickets are independent and can be developed in parallel. ## PR Workflow When ready to submit, create a PR with `tea` CLI: ```bash tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(client): Sprint 21 save/load game flow" --description "body" --base main --head client ```