# Conflicts: # CHANGELOG.md # content/_meta/README.md # content/_meta/npc-authoring-style-guide.md # wiki/_templates/cultural-group.md # wiki/_templates/institution.md # wiki/_templates/star-system.md # wiki/characters/devra.md # wiki/characters/drin.md # wiki/characters/harek.md # wiki/characters/lera-sessik.md # wiki/characters/maret-korr.md # wiki/characters/naia-tamm.md # wiki/characters/nils-davan.md # wiki/characters/pell.md # wiki/characters/renn.md # wiki/characters/resha.md # wiki/characters/sabel.md # wiki/characters/sera-venn.md # wiki/characters/torek-lintar.md # wiki/characters/voss.md # wiki/star-systems/krenn/index.md
9.9 KiB
title, description, type, status, sprint, team
| title | description | type | status | sprint | team |
|---|---|---|---|---|---|
| Sprint 22 — Server Briefing | Signed z-level fix, NPC pool generation, triangle instantiation, contamination activation | sprint | archived | 22 | server |
Sprint 22: Wire — Server Tasks
Goal: Fix the fog regression, wire the authored Sova content into a production population and triangle set, and activate the contamination pacing layer that gives the vertical slice its 30-minute shape.
Branch: server
Agents: Dudley (simulation dev), Tyre (arch), Hoshe (QA)
New Tickets
| # | Title | Blocked by |
|---|---|---|
| #565 | Fix signed z-level addressing: base_z u8 → i8 | — |
| #567 | Add modifications: Vec stub on chunk and MobileChunk | — |
| #176 | NPC pool generation | — |
| #188 | Triangle instantiation from authored content | #176 |
| #254 | Contamination activation mechanic | #188, Q-017 |
| #509 | Fuzzy tests for dynamic/procedural maps | — |
| #512 | Zone Gate room implementation | — |
Use tooling/db/ticket show <id> for full details on any ticket.
Key Decisions
decisions/architecture.md— D-010 (deterministic simulation, BTreeMap over HashMap), D-026 (simulation tiers), D-041 (knowledge graph data model)decisions/content.md— D-023 (three-tier content model), D-024 (10-axis NPC model), D-025 (social site as atomic template unit), D-028 (dialogue tagged pools), D-029 (population entanglement ratio 30/50/20), D-034 (THE FRIEND pattern), D-036 (Sova Transit District setting)decisions/scope.md— D-027 (vertical slice success criteria), D-087 (3 active forks, 2 passive tensions), D-089 (self-contained triangle forks, no cross-triangle cascade)
Open Questions to Resolve Early
- Q-017: Triangle pressure threshold — What events increase pressure? What numeric threshold triggers
confrontationsituation? Assigned to Gestalt and Paula. Resolve before #254 starts — the contamination mechanic needs a pressure model. If Q-017 is unresolved by the time #188 lands, implement #254 with a timer-based fallback (tick count, e.g., 1800 ticks = 30 game-minutes) and leave the pressure threshold as a named constant for Q-017 to fill in.
Notes
#565 — Fix signed z-level addressing: base_z u8 → i8
- Decision D-110 (pending formal filing): change
base_zfromu8toi8inMultiBlockReservation,FloorZone.z_level, and all structs that reference a z-level position (not a count).z_levelscounts remainu8. - Mechanically a cascading type change — no logic changes, only type propagation through ~20 structs.
- Grep starting points:
server/src/simulation/spatial.rs,server/src/simulation/zone.rs, and any struct with a field namedz_levelorbase_z. - Add a doc comment on
DistrictSkeleton(if present) clarifying the distinction:base_z: i8(lowest floor, can be negative for sub-basement) vsz_levels: u8(count, always positive). - Acceptance:
cargo test -p servergreen,clippyclean.
#567 — Add modifications: Vec stub on chunk and MobileChunk
- Decision D-111/D-112 (pending formal filing): DLC scope stub. Entry point for future player construction system.
- Add
modifications: Vec<Modification>(initially an emptyVec) to both static chunk entities andMobileChunkentities. - Define
Modificationenum/struct in a newserver/src/simulation/modification.rswith at minimum:position: TilePosition,modification_type: ModificationType(enum stub),placed_at_tick: u64. - Wire into
SaveStateV1(server/src/simulation/save_state.rs) so player-modified spaces round-trip through save/load. The field can beVec<Modification>with#[serde(default)]— empty for now, but the save slot exists. - No construction logic ships. This is a data model stub only.
- Acceptance: a round-trip save/load test asserts the
modificationsfield serializes and deserializes without data loss (even when empty).
#176 — NPC pool generation
- This is the key production startup ticket. The Gauntlet uses hand-crafted
setup_gauntlet(). The production path needs an equivalent that loads fromcontent/and spawns the Sova NPC pool. - The authored content already exists: 23 NPC YAML files at
content/campaigns/main/systems/van-maanens-star/stations/sova/districts/transit/npcs/. The content loader (server/src/content/loader.rs) already loadsDistrictContent. The spawn module (server/src/content/spawn.rs) already hasspawn_district_npcs()andresolve_cross_references(). - The gap: there is no production startup path that calls these. The server boots into Gauntlet (
setup_gauntlet) or does nothing (without thegauntletfeature). Add a production startup system that: (1) loadscontent/campaigns/main/campaign.yaml, (2) resolves the Sova district, (3) callsspawn_district_npcs()+resolve_cross_references(), (4) applies the 30/50/20 entanglement ratio from D-029 to mark NPCs as flat/mundane/intrigue-entangled via a newEntanglementTagcomponent. - Entanglement ratio: seed the assignment via
SimRng(D-010 determinism). The 17 authored Sova NPCs are pre-assigned by content (YAML fieldtriangle_membership). The entanglement ratio applies to any procedurally generated padding NPCs. - Acceptance: integration test (non-gauntlet boot) asserts 17+ NPCs spawn with correct
StableIdassignments and at least oneEntanglementTag::Intrigueentity.
#188 — Triangle instantiation from authored content
- Depends on #176. The 5 triangle YAML files exist at
content/campaigns/main/systems/van-maanens-star/stations/sova/districts/transit/triangles/(hub-power, bar-tensions, informant-question, worried-knowledge, worried-partner). - The instantiation engine (
server/src/content/instantiation.rs) already handlesFullTemplateDef→TriangleState. This ticket wires the authored Sova triangles (loaded from YAML) into that engine, rather than template-generated triangles. - Per D-087: 3 active forks (T1, T2, T4 = hub-power, bar-tensions, informant-question) and 2 passive tensions (T3, T5 = worried-knowledge, worried-partner). The
TriangleStatecomponent must reflect this classification. - Per D-089: self-contained forks. No cross-triangle cascade. Each
TriangleStateescalates independently. - Cross-template triangle (D-024): bar-tensions links NPCs across the logistics-hub and bar templates. Ensure
TemplateReferenceMapentries are populated for cross-template role assignments. - Acceptance: after production startup,
query<TriangleState>()returns 5 triangle entities: 3 taggedActive(forks), 2 taggedPassive(tensions). All 5 have valid role assignments to existing NPC entities.
#254 — Contamination activation mechanic
- Blocked by #188. Blocked by Q-017 resolution (or timer fallback — see Open Questions above).
- The
StorytellerPlugininserver/src/storyteller/mod.rsis currently a stub. This ticket adds the v0.1 contamination system. - Minimum viable: a Bevy system that fires after a configurable tick threshold (
CONTAMINATION_DELAY_TICKS, default 1800 = 30 game-minutes at 10 tps). On firing: (1) set aContaminationActiveresource to true, (2) push pressure on all Active triangles (incrementTriangleState::pressureby a configured delta), (3) emit aContaminationEventthat the monologue system can hook for "the air feels different" NPC behavioural shifts. - This gives the session its shape: 30 minutes of daily life, then escalation begins. The contamination is not an event the player sees directly — it's the upstream cause of NPC deviations, tell escalation, and eventually confrontation-threshold crossings.
- If Q-017 resolves before this ticket ships: wire the actual pressure threshold from that resolution. If not: the
CONFRONTATION_THRESHOLDconstant is the hook point, set to a reasonable default (e.g., 75 on a 0-100 scale). - Acceptance: integration test runs 1801 ticks, asserts
ContaminationActiveresource is set and all ActiveTriangleStateentities havepressure > 0.
#509 — Fuzzy tests for dynamic/procedural maps
- Part of QA epic #455. Randomized testing of procedurally generated maps against structural invariants.
- Invariants to assert: (1) all walkable tiles are reachable from the player start position (connectivity), (2) no entity spawns outside the map bounds, (3) every door entity has at least one adjacent walkable tile on each side, (4) tile count within expected range (±20% of configured density).
- Use
SimRngwith varying seeds (e.g., 50 seeds, 1ms timeout each).proptestor a manual seed loop both acceptable. - Acceptance:
cargo test -p server -- fuzzy_mappasses with at least 50 seed variations, each asserting all 4 invariants.
#512 — Zone Gate room implementation
- Part of QA epic #455. Gauntlet room for testing zone transitions.
- Add to
server/src/test_world/rooms/following the existing room pattern (seeshift_change.rsfor reference). - The room needs: two distinct zones (e.g.,
ZoneId::TerminalandZoneId::Corridor), a walkable path crossing the zone boundary, a door entity on the boundary, and a reset plate. - Next available StableId range starts at 75 (see
test_world/mod.rsfor the allocation table). Update the table comment. - Acceptance: golden file test for this room passes; zone-crossing event fires when player entity crosses the boundary tile.
Dependency Chain
#565 (z-level type fix) — standalone
#567 (modifications stub) — standalone
#509 (fuzzy map tests) — standalone
#512 (zone gate room) — standalone
#176 (NPC pool generation)
→ #188 (triangle instantiation from authored content)
→ #254 (contamination activation) [also blocked by Q-017 / timer fallback]
Parallel tracks: #565, #567, #509, #512 can all start immediately. #176 is the chain head — start it first after those are underway.
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 22 — NPC pool, triangles, contamination" --description "body" --base main --head server