Standardized YAML frontmatter on all 115 sprint briefing files across sprints 1-26 with title, description, type, status, sprint number, and team fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
155 lines
10 KiB
Markdown
155 lines
10 KiB
Markdown
---
|
|
title: "Sprint 8 — Client Briefing"
|
|
description: "Dialogue response selection, walk-away mechanic, confrontation text styling"
|
|
type: sprint
|
|
status: archived
|
|
sprint: 8
|
|
team: "client"
|
|
---
|
|
|
|
# Sprint 8: React — Client Tasks
|
|
|
|
**Goal:** Activate the dialogue pipeline end-to-end — player talks to NPCs, NPCs respond, the world reacts.
|
|
|
|
**Branch:** `client`
|
|
**Agents:** Stig (dev), Tyre (arch), Hoshe (QA)
|
|
|
|
## Carry-over from Sprint 7
|
|
|
|
| # | Title | Status | Notes |
|
|
|---|-------|--------|-------|
|
|
| #431 | Fog entity visualization — sound pings, cognitive delay anim | in_progress | Protocol v7 bump + visualization implementation |
|
|
|
|
## New Tickets
|
|
|
|
| # | Title | Blocked by |
|
|
|---|-------|------------|
|
|
| #435 | Dialogue response selection — max 3 visible, invisible locks | #434 (done) |
|
|
| #437 | Walk-away mechanic — WASD detect during dialogue, 300ms fade | — |
|
|
| #436 | Confrontation text styling — italic voice, monologue beat | #435 |
|
|
|
|
Use `db/connectors/ticket show <id>` for full details.
|
|
|
|
## Key Decisions
|
|
|
|
- `decisions/content.md` — D-062 (invisible locked dialogue options), D-063 (confrontation same box different weight), D-064 (walk-away 3-phase consequences)
|
|
- `decisions/perception.md` — D-059 (fog shader 5 layers), D-060 (cognitive delay), D-061 (dialogue box max 20% height)
|
|
- `decisions/architecture.md` — D-066 (dual-scale grid 0.5m sim / 1m visual)
|
|
|
|
## Open Questions to Resolve Early
|
|
|
|
None.
|
|
|
|
## Notes
|
|
|
|
### #431: Fog entity visualization — sound pings, cognitive delay anim (HIGH, carry-over)
|
|
**What exists:**
|
|
- `client/scripts/rendering/fog_shader.gd` — FogShader node with 5-layer shader (D-059), noise animation
|
|
- `client/scripts/protocol/protocol.gd` — MessagePack decoder for ObserverSnapshot (protocol v6)
|
|
- Fog layers 1-3 (clear, light fog, deep fog) render via shader, no entity visualization yet
|
|
|
|
**What the ticket needs to deliver:**
|
|
- **Protocol v7 bump:** Add `pending_recognitions` and `sound_events` fields to ObserverSnapshot in protocol.gd decode logic
|
|
- **Sound ping rendering:** On FogState layer 6 (insert overlay, NOT affected by fog shader), render 2-3 thin concentric expanding rings from sound source direction. Sonar-style. Insert white-blue color. Loud = 3 rings bright fast. Quiet = 1 ring faint slow. Fade over 1.5s. Use simple Sprite2D or Line2D, not particles.
|
|
- **Recognized entity in fog:** Entity with `pending: false` renders on layer 6 as: D-033 color glow (via PointLight2D ~40% blend) + faint silhouette feature (cached sprite at ~20% opacity) + 0.8s breathing pulse (shader uniform or tween) + ±0.5 tile position drift (approx position, not exact). Silhouette feature: Kael's vest, Lera's apron (sprite metadata from entity.silhouette_feature field).
|
|
- **Unrecognized entity in fog:** Entity with `pending: true` renders as neutral grey #555566 blob (simple circle sprite, no identifying features). No silhouette. No D-033 color.
|
|
- **Recognition transition:** When `pending` flips from true → false, tween grey blob → color+silhouette over 0.3s (within the 0.6s cognitive delay window per D-060). Monologue fires during this tween.
|
|
|
|
**Integration points:**
|
|
- Pairs with server #423 (cognitive delay system, done Sprint 7)
|
|
- Protocol v7 wire format must match server ObserverSnapshot struct additions
|
|
- Builds on fog shader from Sprint 6
|
|
|
|
**Non-obvious gotchas:**
|
|
- Sound pings and fog entities render on layer 6 (insert overlay), NOT layer 5 (fog shader). Insert data is computational, not perceptual — not affected by vision cone.
|
|
- ±0.5 tile drift is VISUAL only (client-side randomness for "approximate" feel). Server sends exact position; client adds noise.
|
|
- Silhouette feature sprite is entity metadata, not a full sprite. Think "identifying accessory" not "full character render."
|
|
- Tween recognition over 0.3s to align with monologue timing (D-060: monologue fires DURING delay, not after)
|
|
|
|
---
|
|
|
|
### #435: Dialogue response selection — max 3 visible, invisible locks (HIGH)
|
|
**What exists:**
|
|
- `client/ui/interaction_list.gd` — Vertical list for entity interaction verbs (Talk, Observe, etc.)
|
|
- `client/scripts/protocol/protocol.gd` — Decodes NearbyInteraction from snapshot
|
|
- D-061 dialogue box spec: bottom screen, max 20% height, max-width, no portraits
|
|
|
|
**What the ticket needs to deliver:**
|
|
- **New scene:** `dialogue_box.tscn` — Bottom-screen container with two sections: NPC speech (Label, top), player response options (VBoxContainer, bottom). Max 20% viewport height, max-width (exact value: viewport width minus 40px margin). Left-aligned text. Insert-styled per D-057/D-061.
|
|
- **Response option rendering:** Each response is a Button (or custom Control with hover state). Show max 3 visible options. Sort by priority (server provides sorted list). D-062: locked options are invisible (not rendered at all). No grayed-out options. No lock icons. Player doesn't know what they don't know.
|
|
- **New protocol field:** `dialogue_response` in ObserverSnapshot — array of {text: String, response_id: String, priority: int}. Decode in protocol.gd.
|
|
- **Integration:** When player selects Talk verb from interaction_list, server sends snapshot with dialogue_response populated. Client shows dialogue_box, hides interaction_list. Player clicks response → send PlayerInput::DialogueResponse{response_id}.
|
|
- **Monologue interaction:** Monologue floats ABOVE dialogue box on z-layer 7 (spatial separation, D-061). Both can be visible simultaneously — character thinks one thing while NPC says another.
|
|
|
|
**Integration points:**
|
|
- Blocked by #434 (interaction verb execution, done Sprint 7)
|
|
- Pairs with server #305 (dialogue selection pipeline)
|
|
- Blocks #436 (confrontation styling)
|
|
|
|
**Non-obvious gotchas:**
|
|
- Max 3 VISIBLE means if server sends 5 options, show top 3 by priority. But D-062 invisible locks mean server should never send locked options at all (server filters before protocol). Client just renders what it receives.
|
|
- Player response text can be variable length (confrontation lines are longer than casual small talk). Use word wrap, auto-expand button height.
|
|
- No close button per D-064 — walk-away is the exit. Dialogue box stays until player walks away or server sends empty dialogue_response (conversation ended).
|
|
|
|
---
|
|
|
|
### #437: Walk-away mechanic — WASD detect during dialogue, 300ms fade (MEDIUM)
|
|
**What exists:**
|
|
- Input handling in `client/scripts/main.gd` captures WASD for movement, sends PlayerInput::Move
|
|
- Dialogue box (#435) renders dialogue but doesn't handle walk-away yet
|
|
|
|
**What the ticket needs to deliver:**
|
|
- **Input override:** When dialogue_box is visible, WASD input triggers walk-away instead of movement. Send PlayerInput::WalkAway{npc_id} to server.
|
|
- **Visual fade:** Dialogue box fades out over 300ms (Tween modulate alpha 1.0 → 0.0). No sound. Silence. D-064 phase 1.
|
|
- **NPC may react:** Server may send updated NPC animation or monologue after walk-away (D-064 phase 2). Client renders these as normal snapshot updates — no special walk-away animation on client.
|
|
- **KG recording:** Server handles D-064 phase 3 (#427). Client just sends WalkAway input.
|
|
|
|
**Integration points:**
|
|
- Pairs with server #427 (walk-away KG recording)
|
|
- Depends on #435 (dialogue box exists)
|
|
|
|
**Non-obvious gotchas:**
|
|
- Walk-away is ANY WASD press during dialogue, not just "walk away from NPC." Even pressing W (toward NPC) triggers walk-away. The direction doesn't matter — the intent to move ends the conversation.
|
|
- After WalkAway input sent, dialogue box fades but player can't move until fade completes (300ms input block). Prevents "walk through NPC" edge case.
|
|
- If server sends new dialogue_response during fade (NPC talks again), cancel fade and re-show dialogue. Rare edge case but possible (NPC calls after player).
|
|
|
|
---
|
|
|
|
### #436: Confrontation text styling — italic voice, monologue beat (MEDIUM)
|
|
**What exists:**
|
|
- Dialogue box (#435) renders NPC speech + player responses
|
|
- D-063 spec: confrontation uses same UI, different weight via styling + monologue beat
|
|
|
|
**What the ticket needs to deliver:**
|
|
- **Confrontation option styling:** Response options marked as `confrontation: true` (new protocol field) render in italic + first-person voice. Example: regular = "Shift schedule", confrontation = *"I saw you in corridor B-7"* (italic BBCode tag).
|
|
- **Pre-delivery monologue beat:** When player clicks confrontation option, 1-2 second pause before sending DialogueResponse input. During pause, show monologue: *"This changes things. No taking it back."* (hardcoded v0.1 line, future from content pools). Monologue displays on layer 7, dialogue box dims slightly (reduce opacity to 70%).
|
|
- **Audio dip:** Ambient audio volume drops to 50% during confrontation selection (via AudioServer bus manipulation). Restore after response sent.
|
|
- **No camera change:** D-063 defers camera tighten to post-v0.1. Same camera position throughout.
|
|
|
|
**Integration points:**
|
|
- Blocked by #435 (dialogue box)
|
|
- Pairs with server #305 (dialogue pipeline marks confrontation lines)
|
|
|
|
**Non-obvious gotchas:**
|
|
- Monologue beat is client-side delay (pause before sending input). Server doesn't know about the pause — from server's view, DialogueResponse arrives 1-2s after Talk verb.
|
|
- Italic rendering: use BBCode `[i]...[/i]` in RichTextLabel. Standard Label doesn't support italics.
|
|
- Don't apply italic to NPC speech — only to player confrontation responses. Regular dialogue responses stay non-italic.
|
|
- Audio dip is temporary (duration of monologue beat only). Restore ambient volume after response sent, not after NPC replies.
|
|
|
|
## Dependency Chain
|
|
|
|
```
|
|
#431 (fog visualization) → standalone, protocol v7 prerequisite for other features
|
|
#435 (dialogue box) → #437 (walk-away) depends on this, #436 (confrontation styling) depends on this
|
|
#437 (walk-away) → standalone once #435 exists
|
|
#436 (confrontation styling) → depends on #435
|
|
```
|
|
|
|
## 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(ui): dialogue pipeline client (Sprint 8 client)" --description "Implements #431 #435 #437 #436 — fog entity viz, dialogue response selection, walk-away, confrontation styling" --base main --head client
|
|
```
|