# Sprint 20: Shape — Joint Coordination **Goal:** The social site template system gains its foundational schema; triangles become generatable and observable as escalating tensions; the client gains save/load UI and code quality improvements. ## Pre-Sprint Decisions No blocking pre-sprint decisions are required. All selected tickets have their upstream decisions confirmed. | Decision | Status | Impact | |----------|--------|--------| | D-087 (v0.1 triangle configuration) | Confirmed | Server #106/#107/#250 must produce T1-T5 triangle types | | D-089 (self-contained forks, no cascade) | Confirmed | No cross-triangle state in `TriangleDef` or `TriangleState` | | D-025 (social site as atomic template unit) | Confirmed | Server #163/#164/#165 schema shapes | | D-020 (Godot = pure renderer) | Confirmed | Client refactors #557-#560 are motivated by this | **One open question to monitor:** - **Q-028 (line ID collision)** — resolved by D-084 (dual-namespace scheme), but the `RoleCounter` implementation is referenced in D-084 as a requirement for `server/src/content/npc_slug.rs`. Ticket #163 (role definition schema) should create the `server/data/templates/` directory structure; confirm with server team whether the slug counter module belongs in this sprint or the next. ## Sprint Completion Proof The sprint is done when all of the following are observable: 1. **Template schema compiles and round-trips**: `cargo test -p server -- template` passes. A YAML file at `server/data/templates/sample_role.yaml` deserializes cleanly into a `RoleSchema` struct and re-serializes with identical content. 2. **Triangle generation produces valid state**: `cargo test -p server -- triangle` passes. A 4-NPC test world with 2 `TriangleDef` entries produces 2 `TriangleState` components with valid role assignments and tension values within the configured range. 3. **Triangle escalation fires events**: A unit test simulates 60 ticks on a triangle configured to escalate at tick 50, asserts `TriangleCrisisEvent` was emitted at the correct tick. 4. **Single-ownership model serializes**: A world with 2 templates and a cross-reference survives a save/load round-trip: `TemplateOwnership` components and `TemplateReferenceMap` entries are identical before and after. 5. **Refactors don't regress tests**: `make ci-client` passes with #557-#560 merged. `game_state.apply_snapshot()` contains no conditional accumulation logic. `dialogue_box.gd` has zero direct references to `GameState` or `AudioManager`. `main.gd` is under 350 lines. 6. **District layout design decided**: #153 produces a confirmed D-record specifying: complete district topology (how terminal, bar, smuggling corridors, and gate connect), tile dimensions per zone, access topology, and sightline constraints. Unblocks #155 (hand-crafted location authoring) and #188 (triangle instantiation). ## Test Plan Alignment (D-030) Sprint 20 is Phase 3+ territory (D-030 sub-decision #8: Phase 3 = sprint 5+: CauseChain verification + divergent snapshots). The new template/triangle system introduces the first simulation structures that will eventually require CauseChain verification. | Ticket | Test scope | Priority | |--------|------------|----------| | #163 | Unit: YAML round-trip, constraint validation | High | | #164 | Unit: spec validation, tile count range | High | | #165 | Unit: ownership component, reference map | High | | #106 | Unit: triangle YAML round-trip, conflict validation | High | | #107 | Unit: constraint satisfaction, minimum 2 triangles | High | | #250 | Unit: escalation timing, crisis event emission, resolve command | High | | #557-#560 | Regression: existing test suite must remain green | Medium | | #153 | Design discussion: district layout confirmed as D-record | High | The triangle system's `TriangleCrisisEvent` is the first event candidate for CauseChain integration. Do not wire CauseChain this sprint — but structure the event type so it can carry a `CauseChain` field in a future sprint without breaking callsites. ## Cross-Team Integration Points | Server ticket | Client dependency | Notes | |---------------|-------------------|-------| | #165 (`TemplateOwnership` serialization) | None this sprint | Adds fields to `SaveStateV1` — no client protocol change needed until template data is rendered | | #250 (`TriangleCrisisEvent` in `ObserverSnapshot`) | None this sprint | Event added to snapshot schema as stub — client rendering of triangle state is Sprint 21+ | | Planning ticket | Downstream impact | Notes | |-----------------|-------------------|-------| | #153 (district layout design) | Unblocks #155, #188 | Layout decisions feed into Sprint 21 hand-crafted location authoring and triangle instantiation | No live cross-team protocol dependencies this sprint. Server and client work in parallel. ## Deferred to Sprint 21 The following tickets are natural Sprint 21 candidates once this sprint's foundation lands: - **#166** (Template-to-instance mapping) — instantiate templates into the world; requires #163+#164+#165 - **#161** (Template instantiation engine) — full NPC spawn from template; requires #163+#164+#165+#166 - **#159** (Tier 2 template definition format) — YAML schema for the full template document; blocked by #163 - **#108** (Cross-template triangle generation) — requires #106+#107 - **#109** (Triangle validation) — quality checks on generated triangles; requires #107 - **#155** (Hand-crafted location authoring) — requires #153 (station district layout design), which is being resolved this sprint on the planning branch