Files
settled-reach/docs/sprints/sprint-21/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.0 KiB

title, description, type, status, sprint, team
title description type status sprint team
Sprint 21 — Server Briefing Template definition format, template-to-instance mapping, cross-template triangle generation sprint archived 21 server

Sprint 21: Instantiate — Server Tasks

Goal: The template system becomes executable — templates spawn NPCs, assign triangles, and place them in world space; cross-template triangles link social sites; the client gains save/load game flow; and the generator pipeline gets its architectural design.

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

New Tickets

# Title Blocked by
#159 Tier 2 template definition format — (#158 done)
#166 Template-to-instance mapping — (#163, #164, #165 done)
#161 Template instantiation engine #166
#108 Cross-template triangle generation — (#106, #107 done)
#109 Triangle validation — (#107 done)
#85 Error handling & recovery
#246 Basic environmental interaction

Use tooling/db/ticket show <id> for full details on any ticket.

Key Decisions

  • decisions/content.md — D-023 (three-tier content model), D-024 (NPC generation model, 10 axes), D-025 (social site as atomic template unit), D-028 (dialogue tagged pools), D-029 (population entanglement ratio)
  • decisions/architecture.md — D-020 (Godot + Rust IPC, ObserverSnapshot), D-010 (deterministic simulation), D-087 (v0.1 triangle configuration), D-088 (3-state pause, server-authoritative), D-089 (self-contained forks, no cascade)

Notes

#159 — Tier 2 template definition format

  • server/src/content/template.rs already defines RoleSchema, SpaceSpec, TriangleDef (Sprint 20). #158 (Tier 1 drama module schema) is done — use it as a reference for YAML conventions.
  • This ticket extends that to the full Tier 2 document: roles, spaces, triangles, dialogue pool references, NPC routines, and spatial spec in one YAML document.
  • server/data/templates/ directory exists (created by #385). Place the canonical Tier 2 schema definition and at least one authored example template here.
  • Acceptance: a complete Tier 2 template YAML round-trips cleanly through RoleSchema / SpaceSpec deserialization.

#166 — Template-to-instance mapping

  • Depends on the schema from #159, but #159 is partially stubbed already — Dudley can start here in parallel if schema is stabilising.
  • Core task: given a loaded TemplateOwnership + SpaceSpec, spawn NPC entities for each role slot, assign relationships, and record the mapping in TemplateReferenceMap.
  • Existing hook: server/src/content/spawn.rs. The TemplateOwnership component (Sprint 20) already tracks which template owns an entity. This ticket wires spawning to that system.
  • Instance lifecycle: entities spawned from a template must be tagged such that they can be despawned/reset cleanly (gauntlet room reset pattern in server/src/test_world/ is a reference).
  • Acceptance: unit test spawns a 4-NPC template, asserts all role slots filled, TemplateOwnership set correctly on each entity, TemplateReferenceMap entries present.

#161 — Template instantiation engine

  • Blocked by #166. Once mapping works, this ticket wires the full pipeline: load YAML → deserialize → call spawn → generate triangles via server/src/content/template.rs:assign_triangle_roles() → register ownership.
  • Instance lifecycle management: track active instances, support unloading (for zone transitions and save/load).
  • Integration point with #166: the instantiation engine calls the mapping layer, not the raw spawn functions.
  • Acceptance: end-to-end test — load server/data/templates/ logistics_hub YAML, instantiate it, assert NPCs exist with correct roles and 2+ TriangleState components generated.

#108 — Cross-template triangle generation

  • Sprint 20 landed intra-template triangles (#107). This ticket adds the 1 cross-template triangle required by D-024 ("2 per template minimum, 1 cross-template").
  • The existing assign_triangle_roles() in server/src/content/template.rs takes &[TriangleDef] — extend to accept role slots from two different TemplateOwnership sources.
  • D-025 ownership model: NPCs are owned by one template but can hold reference roles in another. The cross-template triangle uses TemplateReferenceMap reference links (carrying relationship metadata) not direct ownership links.
  • Acceptance: test world with two instantiated templates (logistics hub + bar) produces 1 cross-template TriangleState with role assignments spanning both templates.

#109 — Triangle validation

  • Quality checks on generated triangles. Three checks minimum: (1) conflict viability — the three role slots have at least one opposing Want axis, (2) relationship coherence — at least one Relationships entry links the three roles, (3) interest divergence — no two roles share identical Want+Secret combination.
  • Validation runs at instantiation time (not a separate pass). Return Result<Vec<TriangleState>, ValidationError> from assign_triangle_roles().
  • Hoshe: unit tests for each failure mode — triangle that fails conflict viability, triangle that fails coherence, triangle that fails divergence.
  • Acceptance: cargo test -p server -- triangle_validation passes, covering all three failure modes plus a valid triangle that passes all checks.

#85 — Error handling & recovery

  • Handle three categories: (1) simulation panics / process crashes, (2) protocol deserialization errors, (3) desync detection between client state and server state.
  • Server side: server/src/bridge/local.rs is the IPC entry point. Add a supervision layer that catches panics from the tick loop and sends a structured SimError message to the client before dying, rather than an abrupt disconnect.
  • Protocol errors: server/src/bridge/types.rs — ensure malformed input returns a typed error response, not a panic. The existing malformed_input_in_batch_rejects_entire_batch test (#479, done) is the baseline.
  • Desync: add a state_hash field to ObserverSnapshot (a fast hash of key mutable state — player position, NPC count, tick number). Client logs hash mismatches for debugging. No automatic recovery in v0.1 — detect and report only.
  • Acceptance: integration test sends a deliberately malformed message mid-session, asserts the server emits a SimError message and continues running (does not exit).

#246 — Basic environmental interaction

  • ObjectType enum is already in server/src/bridge/types.rs (extended by #421, #422). Interactable component is in server/src/simulation/interaction.rs.
  • Currently ObjectType::Door, ObjectType::Terminal, ObjectType::Readable, ObjectType::Container, ObjectType::Furniture exist with verb sets.
  • This ticket: implement the behaviour behind Door (toggle walkable on the blocking tile(s), emit a zone-crossable notification), Examinable objects (return examine text from content), and usable Terminals (trigger a TerminalInteracted event for future dialogue hook).
  • Door state must be tracked in SaveStateV1 (currently a field gap — add open_doors: Vec<StableId> to the save struct in server/src/simulation/save_state.rs).
  • Acceptance: unit test — player interacts with a Door entity, asserts walkability flips; interacts again, asserts it flips back. Examine on a Readable entity returns non-empty text.

Dependency Chain

#159 (Tier 2 template format) → #166 (template-to-instance mapping) → #161 (instantiation engine)
#107 (done: intra-template triangles) → #108 (cross-template triangles) → #109 (triangle validation)
#85 (error handling) — standalone
#246 (environmental interaction) — standalone

Parallel tracks: #159→#166→#161 and #108→#109 can run concurrently. #85 and #246 are independent.

PR Workflow

When ready to submit, create a PR with tea CLI:

tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(simulation): Sprint 21 template instantiation" --description "body" --base main --head server