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>
7.7 KiB
title, description, type, status, sprint, team
| title | description | type | status | sprint | team |
|---|---|---|---|---|---|
| Sprint 14 — Client Briefing | Monologue display, passive dialogue panel, F3 debug overlay | sprint | archived | 14 | client |
Sprint 14: Live — Client Tasks
Goal: Bring NPCs to life — mood, trust, routine execution, and NPC-to-NPC conversation drive the first emergent social observables; the simulation produces a world that breathes independently of the player.
Branch: client
Agents: Stig (UI/rendering dev), Tyre (architect), Hoshe (QA)
Carry-over from Sprint 13
None. All Sprint 13 client tickets done.
New Tickets
| # | Title | Blocked by |
|---|---|---|
| #122 | Monologue display — client | — |
| #535 | Passive dialogue panel — overheard NPC conversation display | #247 (server) |
| #511 | F3 debug overlay (deferred — WRONG button covers same data) | #495 done |
Use db/connectors/ticket show <id> for full details.
Key Decisions
decisions/architecture.md— D-020 (ObserverSnapshot —current_monologuefield), D-042 (UI microcopy format — YAML autoload for HUD labels)decisions/perception.md— D-016 (internal monologue — text display, atmosphere function), D-018 (three-range sound model — NPC-to-NPC conversations are Voice events), D-055 (sprint suppresses monologue at 40% rate — client renders what server sends; no client-side suppression needed)decisions/content.md— D-032 (separate monologue pools per character — client only needs to render; no character branching in display layer), D-035 (tag taxonomy — monologue hascharacter,trigger,prerequisitetags; client ignores, server filters)- D-078 (overheard NPC conversation — passive dialogue panel, server-authoritative occlusion, pre-occluded text rendering, speaker attribution)
Notes
-
#122 — Monologue display — client: The server-side monologue trigger system is complete —
MonologueEventarrives inObserverSnapshot.current_monologue(field added Sprint 5,server/src/bridge/types.rs). The visual spec for monologue display was authored in Sprint 13 (#315,docs/design/monologue-display-spec.md). Sprint 14 work: implement the client-side display using that spec. Key requirements from the spec:- Position: Bottom-left of viewport, above the interaction verb list, below the minimap. Not in the dialogue box area (max 20% height, D-061).
- Typography: Italic, smaller than dialogue (spec has exact px/pt — read
docs/design/monologue-display-spec.md§Typography). - Stacking: Queue — if a new monologue arrives while one is displaying, queue it (max depth from spec). Do not overwrite mid-display. Sprint 13 note: "monologue not lost on overwrite" is a P0 test (#477, done).
- Fade: Auto-fade after display duration. Duration is embedded in
MonologueEvent.display_duration(float, seconds). Standard GodotTween. - Character differentiation: Smuggler and detective lines use different text colours — hex values in spec. Client reads the active character from
game_state.gd(autoload atclient/scripts/autoloads/game_state.gd) or derives it from the snapshot. The server already partitions monologue pools per character (D-032) so the client receives only the correct character's lines — no client-side branching needed. - Existing
world_renderer.gd(client/scripts/rendering/world_renderer.gd) is the root scene; monologue display is a newCanvasLayerchild node or aControlnode in the HUD layer (z-layer 6 per D-049 rendering stack). Do not put it in the dialogue box scene. - Integration with audio: Monologue display does NOT trigger audio (monologue chime fires at cognitive delay onset from the server's recognition pipeline, not from text display). No client-side audio calls needed here.
- Delivery:
client/scripts/rendering/monologue_display.gd(or similar), integrated into the HUD scene, readingObserverSnapshot.current_monologue. Tests via Hoshe's gdUnit4 harness: queue management, fade-out timing, character colour, no-overwrite on active display.
-
#535 — Passive dialogue panel — overheard NPC conversation display: Consumes
ConversationEventfromObserverSnapshot(added by server #247). Render overheard NPC-to-NPC conversations in the existing dialogue box in passive (read-only) mode. Per D-078 amendment — occlusion is server-authoritative; this ticket is a pure renderer of pre-occluded text. Key requirements:- Speaker attribution: Display header as "Speaker → Target" (e.g. "Kael → Mira") using
speaker_nameandtarget_namefrom the event. Use the same attribution label slot as player conversation NPC-name display — no new layout region needed. - Pre-occluded text renderer: Render
occluded_lineas-is. The server has already performed per-word Bernoulli drops and replaced dropped words with.... The client performs no stochastic logic — noclarity_score, norandf(), no per-word processing. Display the received string directly in the passive panel. - Read-only mode: The dialogue box must suppress response options and player input when displaying a passive conversation. No response list, no input capture. Player can still move freely.
- Dismissal: On
conversation_endevent (or if player moves far enough that noConversationEventarrives for the NPC pair), dismiss via the standard 300ms fade (sameTweenas walk-away fade, #437 done). - Monologue isolation: Monologue display (#122, z-layer 6) is unaffected. Do not route conversation text through the monologue display. The server triggers
witness_interactionwhich may produce a monologue — that arrives separately viacurrent_monologueand is rendered by #122 normally. - Blocked by #247 —
ConversationEventstruct must exist onObserverSnapshotbefore this can be wired. Start with a stub event type and placeholder renderer if #247 is not yet landed. - Delivery: passive mode in
client/scripts/ui/dialogue_box.gd(or a newpassive_dialogue.gdsibling), verbatimoccluded_linerender, speaker attribution header,conversation_enddismissal. Tests via Hoshe's gdUnit4 harness: attribution renders correctly,occluded_linewith...tokens renders verbatim, panel does not show response options in passive mode, dismisses onconversation_end.
- Speaker attribution: Display header as "Speaker → Target" (e.g. "Kael → Mira") using
-
#511 — F3 debug overlay (deferred): This ticket is low priority. The WRONG button (F12, #507 done) already captures snapshot state, text render, and description on demand without per-frame cost. The F3 overlay would duplicate that information as a persistent overlay. Stig recommended deferral in Sprint 12. Only implement this sprint if server tickets finish early and QA explicitly needs real-time overlay data that WRONG button cannot provide. Default: skip.
Dependency Chain
#122 (monologue display) — standalone, no server dependency this sprint
#535 (passive dialogue panel) — blocked by #247 (server, NPC-to-NPC conversation system)
#511 (F3 overlay) — standalone, low priority, implement only if capacity allows
#122 has no blockers — current_monologue in the snapshot has been live since Sprint 5. The spec (#315) is done. This is a pure client rendering task.
#535 is blocked on #247 landing the ConversationEvent struct with occluded_line: String on ObserverSnapshot. Stig can stub the event type locally and build the renderer against it in parallel; wire-up follows when #247 merges. No stochastic logic needed on the client — render occluded_line verbatim.
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):
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(client): description" --description "body" --base main --head client