Files
settled-reach/docs/sprints/sprint-15/server.md
T
jpmschweitzerandClaude Opus 4.6 bccdcfcdcb docs(docs): add frontmatter to all sprint briefings
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>
2026-03-14 00:15:45 +01:00

8.5 KiB

title, description, type, status, sprint, team
title description type status sprint team
Sprint 15 — Server Briefing Monologue event generation, NPC generation pipeline, follow mechanic sprint archived 15 server

Sprint 15: React — Server Tasks

Goal: The player acts and the world reacts — follow and examine mechanics connect the player to the living NPC simulation; the dialogue system's first two access layers open up information gating; server-side monologue events fire in context; and the personality/tell system completes the NPC data model.

Branch: server Agents: Dudley (simulation dev), Tyre (architect), Hoshe (QA)

New Tickets

# Title Blocked by
#119 Monologue event generation — server #239 (done)
#92 NPC generation pipeline #86 (done)
#90 Personality & tell system #89 (cancelled — blocker resolved)
#241 Follow mechanic #240 (done)
#243 Routine deviation detection #88 (done)
#105 Tolerance threshold triggers
#340 Define SpatialIndex trait with naive Vec implementation

Use db/connectors/ticket show <id> for full details.

Key Decisions

  • decisions/perception.md — D-011 (fog of perception universal to all entities), D-016 (internal monologue as perception bridge), D-060 (cognitive delay), D-067 (recognition chime onset)
  • decisions/content.md — D-024 (10-axis NPC generation model + tell system), D-028 (dialogue 4-layer architecture), D-035 (converged tag taxonomy, 9 mood states), D-075 (dialogue filtering: confidence gates trust tier, not access tier)
  • decisions/architecture.md — D-010 (information boundaries first-class), D-026 (simulation tiers), D-041 (knowledge graph: KnowsOf / KnowsDetails confidence levels)

Notes

  • #119 Monologue event generation — server: server/src/simulation/monologue.rs already handles enter_location and time_idle triggers. This ticket extends the system to fire on observe_npc, hear_sound, observe_anomaly, witness_interaction, and post_conversation triggers — all enumerated in D-035 tag taxonomy. The ObservationEvent struct from server/src/simulation/interaction.rs (completed in #239) is the input source. Each trigger must emit a MonologueEvent into MonologueBuffer with context tags (location, situation, character_state) so the content pool selector can match against D-035 structural tags. Respect the COOLDOWN_TICKS = 300 anti-spam guard already in the file. The witness_interaction trigger (D-078) fires after overheard NPC-to-NPC conversation is displayed — coordinate with the passive dialogue system in server/src/simulation/conversation.rs and server/src/simulation/listening.rs.

  • #92 NPC generation pipeline: Core NPC ECS components (Want, Secret, Relationships, Tolerance, Routine, Contentment) are done in server/src/npc/mod.rs (#86). This ticket wires procedural generation: takes a role definition as input, seeds all 10 axes using the sim RNG (server/src/simulation/rng.rs), applies constraint validation, and spawns a fully-populated NPC entity. Use the SimRng resource for all randomness — determinism is non-negotiable (D-010 principle 4). Constraint validation must catch: relationship graph cycles, tolerance values that would immediately trigger, routines that conflict spatially. Output: a function generate_npc(role: &RoleDefinition, world: &mut World, rng: &mut SimRng) or equivalent ECS command. Personality traits (2-3 per NPC) must be populated — they feed #90.

  • #90 Personality & tell system: The blocker (#89, Information inventory) was cancelled; the knowledge graph (D-041, completed in Sprint 12) supersedes it. PersonalityTraits component holds 2-3 traits drawn from a trait set. TellSystem covers 5 categories: nervous, angry, friendly, guarded, routine_deviation. Tell state is derived each tick from NPC axis values — not authored per NPC. Derivation rules: Secret + low Tolerance → nervous, low Contentment + Hostile mood → angry, high Contentment + Friendly relationship → friendly, high Secret weight → guarded, deviation from routine → routine_deviation. NpcMood is already available from server/src/npc/mood.rs (#323). The mood.rs header comment explicitly flags Tell system (#337, deferred to Sprint 15) → reads MoodState. The v0.1 renderer for tells is monologue text, not visual animation — emit tell state into ObserverSnapshot as a field on the entity's tell status; the client reads it for future use. server/src/npc/ is the correct home for new components.

  • #241 Follow mechanic: Player uses Interact verb on an NPC to designate a follow target. The interaction dispatcher in server/src/simulation/interaction.rs (#240, done) must be extended with a Follow verb. Server tracks: target NPC entity ID, current distance (tile-based), LOS state (from the existing shadowcasting system in server/src/perception/). Observation events (observe_npc trigger) fire at double frequency while following. NPC suspicion increases via ToleranceThreshold stress if the player maintains close proximity + LOS for sustained ticks. Define "too close too long" as a configurable threshold (start: within 2 tiles for 60+ ticks). Follow ends when: target enters deep fog (LOS lost for N ticks), target detects player (suspicion threshold crossed, feeds NpcPlayerAwareness), or player issues a different action. Emit follow-state events into ObserverSnapshot so the client can show follow-mode UI state.

  • #243 Routine deviation detection: server/src/npc/routine.rs tracks ActivityState (set when NPC arrives at routine destination) and DailyRoutine (schedule of phase → location). Compare the NPC's current TilePosition and ActivityState against what DailyRoutine specifies for the current DayPhase. Emit RoutineDeviationEvent when: NPC is in wrong location for phase, NPC is absent from expected location (has been out of expected zone for N ticks), NPC is performing wrong activity. Absence detection covers the case where the player expects an NPC at a known location and they are not there. RoutineDeviationEvent feeds the observation event generator (#239, done), which will route it to observe_anomaly monologue triggers (#119, this sprint). This is the primary detective mechanic per D-027 criterion 4.

  • #105 Tolerance threshold triggers: ToleranceThreshold component exists (part of NPC data model). This ticket adds the monitoring system: each tick, check all Active-tier NPCs' tolerance against accumulated stress. When stress exceeds threshold, emit a ToleranceBreachEvent and apply behavioral state changes (mood shift, potential confrontation-initiation, avoidance behavior). Threshold value varies per NPC seed — do not hardcode. This unblocks #250 (Triangle escalation system) in a later sprint, which needs tolerance breach events as input. Integrate with server/src/npc/mood.rs — a tolerance breach should push mood toward Hostile or Anxious per the FSM.

  • #340 SpatialIndex trait: XS effort task. Define a trait in server/src/ (suggest server/src/simulation/spatial.rs) with three methods: entities_in_range(position, radius), entities_at(position), update(entity_id, position). Implement a naive Vec-backed backend (NaiveSpatialIndex). This is called from the follow mechanic (#241) for proximity queries and from the NPC vision system (#115, deferred). The trait abstraction means a grid/quadtree can replace the naive impl later without touching callers. Register as a Bevy resource.

Dependency Chain

#340 (SpatialIndex) ─────────────────────────────────┐
                                                       ↓
#92 (NPC generation pipeline) → #90 (Personality & tell) → future: #337 (tell state derivation)

#243 (Routine deviation detection) ──────────────────┐
                                                       ↓
#119 (Monologue event generation) ← also feeds from #241 (Follow mechanic)
         ↑
    #241 (Follow mechanic) → feeds NPC suspicion → future: #115 (NPC vision)

#105 (Tolerance threshold triggers) → future: #250 (Triangle escalation)

PR Workflow

When ready to submit, create a PR with the 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 15 react — server deliverables" --description "body" --base main --head server