--- title: "Sprint 12 — Server Briefing" description: "Tier marker components, active tier simulation, information tag schema, access control" type: sprint status: archived sprint: 12 team: "server" --- # Sprint 12: Build — Server Tasks **Goal:** Lay the production-layer foundations — simulation tier system, sound event pipeline, visual grammar, and knowledge boundary enforcement — and complete all v0.1 copy authoring so content packs, opening hooks, and world-building docs are done. **Branch:** `server` **Agents:** Dudley (simulation dev), Tyre (architect), Hoshe (QA) ## Carry-over from Sprint 11 None. Sprint 11 was 7/7 done. ## New Tickets | # | Title | Blocked by | |---|-------|------------| | #93 | Tier marker components | — | | #94 | Active tier simulation | #93 | | #99 | Tier transition logic | #93 | | #138 | Information tag schema | — | | #139 | Component-level access control | #138 | | #124 | Sound event system — server | — | | #193 | Line previewer CLI | — | Use `db/connectors/ticket show ` for full details. ## Key Decisions - `decisions/architecture.md` — D-020 (Godot + Rust IPC), D-041 (Knowledge Graph data model), D-066 (dual-scale grid: 0.5m sim, 1m visual) - `decisions/perception.md` — D-017 (perception modes), D-018 (three-range sound model) - `decisions/scope.md` — D-027 (vertical slice), D-053 (movement stance system) ## Notes **#93 — Tier marker components** - Epic #40 (Simulation Tier System) is entirely unstarted — this is the entry point. - Deliver three zero-sized marker components: `ActiveSim`, `BackgroundSim`, `StateSaved`. - Add a `TierPlugin` that registers them. Tag-based: systems query `With` to scope work to nearby NPCs only. - Lives in `server/src/simulation/tier.rs` (file exists; currently stubs the stance system — check before overwriting). - Integration point: all NPC behavior systems in `server/src/simulation/` should gain `With` query filters once this exists. **#94 — Active tier simulation** - Full behavior systems (movement, perception, dialogue, monologue) run at 10–20 ticks/sec for `ActiveSim` NPCs only. - Practically: add `With` filter to the movement, pathfinding, observation, and monologue systems in `server/src/simulation/`. - No new systems needed yet — this is scope-gating existing ones. - Blocked by #93 (marker components must exist first). **#99 — Tier transition logic** - Promote `StateSaved → BackgroundSim → ActiveSim` when player approaches; demote on departure. - Budget: 2–5ms reactivation. Use `SpatialIndex` trait (see `server/src/simulation/` — check if `SpatialIndex` already exists from earlier sprints; if not, #340 defines it but is still backlog — implement the naive Vec version inline for now). - Tier transitions fire on position-change events. Wire to the existing movement system in `server/src/simulation/movement.rs`. - Blocked by #93. **#138 — Information tag schema** - Completes the knowledge graph work from Sprints 2–3 (#361–367 all done). - Define `ObserverAccess` enum: `Public`, `OwnerOnly`, `FactionOnly(faction_id)`, `RelationshipGated(threshold)`, `KnowledgeGated(flag)`. - Add as component metadata attribute — each ECS component that carries sensitive data gets an `#[access = ...]` annotation (or a companion `AccessRule` component). - Lives in `server/src/knowledge/types.rs` (already exists — add to the existing types file). - This schema is what #139 enforces. **#139 — Component-level access control** - Query filter layer: observer queries (the `observer/` module under `server/src/perception/`) must respect `ObserverAccess` tags before returning data. - Implement as a filter function on the observer snapshot builder: `filter_by_access(observer_entity, component_access_rule, kg: &KnowledgeGraph) -> bool`. - The `KnowledgeGraph` component (done, `server/src/knowledge/graph.rs`) provides the knowledge state needed for `KnowledgeGated` checks. - Blocked by #138. **#124 — Sound event system — server** - `SoundEventEmitter` component: emits typed events (`Footstep`, `Voice`, `Machinery`, `Alert`, `Ambient`) with position, intensity, `RangeCategory` (Close/Medium/Long per D-018). - `SoundEventQueue` resource: collects events each tick, fans out to subscribers (client bridge + NPC awareness). - Wire into the bridge: sound events within player LOS range → included in `ObserverSnapshot` as a `sound_events` vec. - Existing audio manager on client (`client/scripts/autoloads/audio_manager.gd`) expects a `sound_events` array in the snapshot — confirm field name matches. - Unblocked (standalone). #125 on client is blocked on this. **#193 — Line previewer CLI** - Rust binary (`tooling/line-previewer` or `server/src/bin/line_preview.rs`) sharing code with the dialogue pipeline. - MVP: (1) load YAML content pack, (2) set filter context via CLI flags (`--character smuggler --knows smuggling_operation`), (3) print matching lines, (4) `--explain` mode shows why each line matched/filtered, (5) sequence preview for ordered monologue. - Shares `server/src/content/` types (`LinePool`, `ContentLoader`). - This tool is what Mellanie needs before authoring content packs — unblocks #190, #191, #192. ## Dependency Chain ``` #93 (tier markers) → #94 (active sim) → #99 (tier transitions) #138 (access schema) → #139 (access control) #124 (sound events) — standalone, unblocks client #125 #193 (line previewer) — standalone, unblocks copy #190, #191, #192 ``` ## 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(simulation): Sprint 12 server — tier system, sound events, KG access control" --description "body" --base main --head server ```