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.8 KiB
title, description, type, status, sprint, team
| title | description | type | status | sprint | team |
|---|---|---|---|---|---|
| Sprint 16 — Server Briefing | Dialogue response handler, trust-gated gossip, line variety tracker | sprint | archived | 16 | server |
Sprint 16: Converse — Server Tasks
Goal: Dialogue becomes a two-way exchange — players pick options and the server responds; NPC information-giving deepens through trust and trait-shaped delivery; the sprite pipeline gets its correct art-direction angle; and housekeeping fixes land across all three active teams.
Branch: server
Agents: Dudley (simulation), Tyre (arch), Hoshe (QA)
Carry-over from Sprint 15
None. Sprint 15 was 100% complete (16/16 done).
New Tickets
| # | Title | Blocked by |
|---|---|---|
| #538 | Arch: Move dialogue systems from BridgePlugin to NpcPlugin | — |
| #539 | Server: implement DialogueResponse verb handler | #538 |
| #171 | Layer 3: Trust-gated gossip | — |
| #338 | Line variety tracker — prevent repeat dialogue | — (unblocked: #305 done) |
Use db/connectors/ticket show <id> for full details.
Key Decisions
decisions/content.md— D-028 (dialogue architecture, four relational layers), D-035 (tag taxonomy, trust/access tiers), D-075 (layered confidence gate on trust tier)decisions/architecture.md— D-041 (knowledge graph data model, KnowledgeConfidence hierarchy), D-010 (no baking player identity into game loop)
Notes
#538 — Arch: Move dialogue systems from BridgePlugin to NpcPlugin
What exists: server/src/bridge/mod.rs (lines 181-187) registers process_talk_interaction, process_walk_away, and process_confrontation_response inside BridgePlugin::build(). These systems depend on NPC-layer resources (TrustEventQueue, KnowledgeGraph, KnowledgeEventQueue) but live in the bridge module, which is supposed to own only wire protocol concerns.
What to deliver: Move the three .add_systems() calls from BridgePlugin::build() to NpcPlugin::build() in server/src/npc/mod.rs. The function implementations in server/src/simulation/dialogue.rs do not move — only their registration site changes. The scheduling constraints (.after(process_player_input), .before(compute_observer_snapshot)) must be preserved exactly. NpcPlugin already has access to TrustEventQueue and other NPC resources (it init_resources them), so no new resource registration is needed.
Gotcha: The game_loop integration tests in dialogue.rs that manually set up TrustEventQueue were the signal that this was misplaced. After the move, those tests should no longer need the manual init. Verify no test breaks.
Integration point for #539: This must merge before #539 starts, since #539 adds a new dialogue system that should register in NpcPlugin from the start.
#539 — Server: implement DialogueResponse verb handler
What exists: process_talk_interaction in server/src/simulation/dialogue.rs handles the initial Talk verb. It selects a line via the 4-layer pipeline and writes to DialogueResponseBuffer. The client sends DialogueResponse { response_id } when the player picks an option, but no server system consumes it. PlayerAction::DialogueResponse is already defined in the bridge types.
What to deliver: A new system process_dialogue_response in server/src/simulation/dialogue.rs that:
- Reads
DialogueResponseactions from the player input queue - Looks up the NPC's
DialogueProfile(location, role) and activeKnowledgeGraphstate - Runs the same 4-layer filtering pipeline (
query_dialogueonLinePoolIndexResource) to select a follow-up line based on the response_id context - Writes the result to
DialogueResponseBufferfor snapshot inclusion - For conversations that have ended (no follow-up lines), clears
ActiveDialogue
Key design constraints from D-028 + D-062: Dialogue options the player hasn't unlocked are invisible — so response_id will only arrive for options that were legitimately sent. No validation needed beyond confirming the response_id maps to a known dialogue context. The server does not need to validate "was this a valid choice?" — if the client sent it, it was shown.
Integration with #171: If trust-gated gossip (#171) is complete in the same sprint, this system should also route Real/Secret tier responses through the trust-gated pipeline. If #171 lands after, stub with Surface-only for now.
Register in NpcPlugin (after #538 lands).
#171 — Layer 3: Trust-gated gossip
What exists: The trust tier gate is already fully implemented. relationship_to_trust() in server/src/simulation/dialogue.rs (lines 199-216) takes RelationshipState and KnowledgeConfidence and returns TrustTier per D-075. The LinePoolIndexResource query pipeline in content/mod.rs accepts a TrustTier and filters lines accordingly. The content YAML files already carry trust: real and trust: secret tags on authored lines.
What to deliver: Three disclosure tiers per NPC role (surface / real / secret). The engine is ready — the gap is that process_talk_interaction may not be passing the correct KnowledgeConfidence from the observer's KnowledgeGraph to relationship_to_trust(). Verify in process_talk_interaction that:
- The observer's
KnowledgeGraphis queried for the NPC'sStableId confidence_of(&target_sid)is passed as the second arg torelationship_to_trust()- The resulting
TrustTierfilters lines inquery_dialogue
If this path is already wired (check near line 345 in dialogue.rs), the ticket may be a content validation: confirm that authored lines with trust: real and trust: secret actually surface for a player with KnowsOf+ / KnowsDetails+ knowledge. Write a test that initializes a player KG with KnowsDetails on a target NPC, runs process_talk_interaction, and asserts a Secret-tier line was selected.
Progressive revelation: The same NPC gives different answers on first meeting (Surface only) vs. after investigation (Real/Secret unlocked). This is not a UI change — it is already handled by D-062's invisible locks. The engine must simply populate DialogueResponseBuffer with the tier-appropriate line.
#338 — Line variety tracker — prevent repeat dialogue
What exists: DialogueCooldownTracker is already implemented as a Component in server/src/simulation/dialogue.rs (lines 78-105). It tracks line_id → tick_used in a BTreeMap<String, u64> with a 600-tick (1 game-hour) cooldown. record(), is_on_cooldown(), and prune() methods exist.
What to deliver: Wire the tracker into process_talk_interaction:
- Query
DialogueCooldownTrackeron the player entity (it may already be queried — check the system signature near line 345) - After the 4-layer pipeline returns candidates, filter out lines where
tracker.is_on_cooldown(line_id, current_tick)returns true - Call
tracker.record(selected_line_id, current_tick)after selection - Call
tracker.prune(current_tick)each time to prevent unbounded growth
If the tracker is already being queried but not used to filter, this is a 10-line change. If it is not queried at all, add it to the system signature and wire it in. Write a test that sends Talk repeatedly to the same NPC and asserts no line_id appears twice within LINE_COOLDOWN_TICKS.
Dependency Chain
#538 (BridgePlugin → NpcPlugin refactor)
→ #539 (DialogueResponse verb handler)
#171 (Layer 3: Trust-gated gossip) → standalone, parallel track
[may inform #539 if both land same sprint]
#338 (Line variety tracker wiring) → standalone, parallel track
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(simulation): sprint 16 dialogue server" --description "body" --base main --head server