Files
settled-reach/docs/sprints/sprint-18/client.md
T
jpmschweitzerandClaude Opus 4.6 86aab2d14e docs(sprints): add Sprint 18: Touch briefings
14 tickets across server (9), client (3), copy (2). Examine mechanic,
NPC awareness, social propagation, minimap, dialogue UI, save state
data model, and blocker-clearing work for Sprint 19.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:42:52 +01:00

100 lines
7.0 KiB
Markdown

# Sprint 18: Touch — Client Tasks
**Goal:** The player can examine entities and objects to generate character-filtered observations; NPCs detect and react when watched; social actions propagate through the relationship graph; minimap renders POIs on the client.
**Branch:** `client`
**Agents:** Stig (UI/rendering), Tyre (architecture), Hoshe (QA)
## Carry-over from Sprint 17
None. Sprint 17 closed 19/19.
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #151 | Minimap rendering | #148/#149 (both done in Sprint 17) |
| #174 | Dialogue UI — client (D-061 spec) | #434 (done) |
| #264 | Knowledge/journal display | — |
Use `db/connectors/ticket show <id>` for full details.
## Key Decisions
- `decisions/architecture.md` — D-020 (client is pure renderer, no game logic in GDScript), D-041 (knowledge graph — client displays KG data from snapshot), D-042 (UI microcopy format — YAML via UIStrings autoload)
- `decisions/perception.md` — D-013 (diegetic insert/POI system — minimap is insert-layer UI), D-061 (dialogue box spec — 20% max height, no portraits)
- `decisions/content.md` — D-028 (dialogue architecture — client renders options, server selects), D-062 (invisible locked options), D-064 (walk-away — WASD during dialogue)
- `decisions/scope.md` — D-027 (vertical slice — dual-character POI and knowledge display)
## Notes
### #151 — Minimap rendering
POI data infrastructure (`PointOfInterest` component, discovery events) landed on the server in Sprint 17 (#148, #149). The `ObserverSnapshot` will carry POI data for discovered points. This ticket wires that data into a rendered minimap overlay.
What this ticket must deliver:
- A `MinimapRenderer` scene or node attached to the insert HUD layer (z-layer 6, diegetic insert per D-049)
- Nearby POIs rendered as colored dots at their relative compass position from player origin
- Distant POIs (beyond minimap radius) rendered as directional arrows at the minimap border
- POI dot color and shape vary by category (the server sends `poi_category` in snapshot — use it)
- Player is always centered; minimap does not scroll or rotate (fixed-north, D-015)
- Minimap must be diegetically framed — it reads as a neural insert overlay, not a traditional game HUD
- If no POIs discovered: minimap is empty but the insert frame still renders (the frame is diegetic, always present)
Existing infrastructure to build on:
- `client/scripts/autoloads/game_state.gd` — holds `current_snapshot` which will include POI array from server
- `client/scripts/autoloads/ui_strings.gd` — minimap label strings (add to `client/data/ui-strings.yaml` per D-042)
- `client/scripts/rendering/world_renderer.gd` — reference for how snapshot data drives rendered output
Gotcha: POI positions are in simulation tile coordinates. The minimap renders relative compass direction and distance, not absolute tile positions. Convert server tile positions to player-relative vectors in GDScript.
### #174 — Dialogue UI — client (implement to D-061 spec)
The dialogue box spec (#434, D-061) was delivered in Sprint 7 and is done. This ticket (#174) is the older "Dialogue UI" story whose description has been updated to reference the D-061 spec. Given that the dialogue box, response selection, and walk-away mechanic are already implemented (#434, #435, #437), this ticket now covers the remaining dialogue UI surface not yet wired.
What this ticket must deliver — audit first, then implement gaps:
- Verify the existing dialogue box correctly uses `game_state.current_dialogue` field (set in Sprint 14+)
- **Examine result display**: the examine verb (#242 server) returns a character-filtered text description. The client needs a display path for this — it should appear as a non-interactive overlay (not a dialogue box, no options), floating above the examined entity or in a dedicated "observation" panel. Design to spec: brief, diegetic, auto-dismisses after 4-6 seconds
- **Dialogue UI hardening**: confirm invisible locked options (D-062) — no grayed-out elements, no lock icons anywhere in the dialogue tree
- **Confrontation styling** (#436, D-063): verify italic first-person voice for confrontation options is rendering correctly; confirm the 1-2 second pre-delivery monologue beat fires before the option triggers
Integration point: `client/scripts/autoloads/game_state.gd` holds `current_dialogue`. The rendering layer reads this each frame. Examine result will come through a new `current_examine_result` field (coordinate field name with server team).
### #264 — Knowledge/journal display
Client UI for reviewing accumulated KG facts. The player character's `KnowledgeGraph` is populated server-side and sent down in snapshot as a structured object. This ticket creates the review panel.
What this ticket must deliver:
- A journal/insert panel — toggle key (TBD, coordinate with server team for any keybind — likely `J` or dedicated insert shortcut)
- Displays accumulated facts grouped by entity: "What I know about Kael Davan", then fact entries with confidence level and source
- Fact entries show: fact text, `KnowledgeConfidence` level (Suspects / KnowsOf / KnowsDetails / Direct), source (`DirectObservation` / `ToldBy` / `Heard`), and `last_observed_tick` timestamp converted to game-time string
- `Contradicted` facts rendered with a visual distinction (strikethrough or amber tint) — these are the moments where THE FRIEND arc surfaces in the UI
- `Stale` facts rendered more dimly than `Active` facts
- The display is read-only — no player interaction with entries beyond scrolling
- Diegetic frame: the panel reads as neural insert memory recall. Use `UIStrings` (D-042) for all labels (`client/data/ui-strings.yaml`)
Integration with `game_state.gd`: the snapshot does not currently carry a full KG dump — coordinate with server team. The server team will need to add a `player_knowledge` field to `ObserverSnapshot` (or a separate periodic message). Define the wire format jointly before implementation.
Key gotcha: the journal panel must close when dialogue opens and vice versa — they cannot be open simultaneously. Both compete for insert-layer attention.
## Dependency Chain
```
#151 (minimap) → POI data in snapshot (#148/#149 done) — start immediately
#174 (dialogue UI hardening + examine result display) → examine field from server #242
→ coordinate wire format week 1, implement week 2
#264 (knowledge/journal display) → player_knowledge field in snapshot (coordinate with server)
→ start design week 1, implement after wire format agreed
```
Parallel tracks: #151 can start immediately. #174 and #264 both need a brief coordination with server team on wire format additions — block 30 minutes in week 1 to agree those field names, then implement in parallel.
## PR Workflow
When ready to submit, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts (see CLAUDE.md "Gitea access" section):
```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(client): description" --description "body" --base main --head client
```