docs(sprints): add Sprint 10 Prove briefings

Server (7), client (7), CI (3), audio (1) — 18 tickets total.
Gauntlet expansion, audio wiring, client UX polish, CI pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 12:12:45 +01:00
co-authored by Claude Opus 4.6
parent 407018ecdf
commit b4a3784218
5 changed files with 530 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
# Sprint 10: Prove — Audio Tasks
**Goal:** Expand the Gauntlet test suite with new rooms and cross-room scenarios, wire the audio architecture end-to-end, and complete client UX polish from Sprint 9 carry-overs — proving the full system holds together.
**Branch:** `audio`
**Agents:** Inigo (sound design)
---
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #327 | Audio asset set — 8 minimum viable files via Stable Audio Open | — |
Use `db/connectors/ticket show <id>` for full details.
---
## Key Decisions
- `decisions/scope.md` — D-038 (audio in v0.1 — 8 files spec, hybrid generation approach)
- `decisions/perception.md` — D-067 (recognition chime fires at onset of cognitive delay), D-069 (audio dip profiles), D-071 (ListeningFocus boost), D-072 (universal event-driven conversation murmur)
- `decisions/architecture.md` — D-068 (5-bus audio architecture), D-073 (zone crossfade)
- `decisions/content.md` — D-074 (audio aesthetic identity — insert-tech vs organic)
---
## Notes
**#327 — Audio asset set — 8 minimum viable files**
- Existing: `AudioManager` autoload at `client/scripts/autoloads/audio_manager.gd` is fully implemented (D-068). The directory-scan registry pattern is in place — drop OGG files into `res://audio/` and they register automatically. Sprint 9 delivered 6 interaction SFX and 2 revised monologue chimes (#440, #453).
- What this ticket adds: The 8 ambient and world-SFX assets specified in D-038. These are distinct from the Sprint 9 interaction sounds — they cover the continuous soundscape and footstep system.
**The 8 files (D-038):**
| Key | File | Duration | Bus | Method |
|-----|------|----------|-----|--------|
| `amb_station_base` | `amb_station_base.ogg` | 60-90s | Ambient | SAO — station hum + span gate vibration |
| `amb_workplace_layer` | `amb_workplace_layer.ogg` | 45-60s | Ambient | SAO — cargo machinery |
| `amb_bar_layer` | `amb_bar_layer.ogg` | 45-60s | Ambient | SAO — conversation murmur baked in |
| `amb_corridor_layer` | `amb_corridor_layer.ogg` | 45-60s | Ambient | SAO — ventilation/subtle hum |
| `sfx_footstep_metal_walk` | `sfx_footstep_metal_walk.ogg` | 0.2-0.3s | WorldSFX | SAO or manual — one footstep, walk cadence |
| `sfx_footstep_metal_run` | `sfx_footstep_metal_run.ogg` | 0.2-0.3s | WorldSFX | SAO or manual — one footstep, run cadence |
| `sfx_monologue_chime` | `sfx_monologue_chime.ogg` | 0.5-1.0s | UISounds | Manual synthesis — crystalline, neural-lattice feel |
| `sfx_monologue_chime_urgent` | `sfx_monologue_chime_urgent.ogg` | 0.5-1.0s | UISounds | Manual synthesis — sharper, contradiction/anomaly variant |
**D-074 aesthetic split — critical:**
- Ambient layers and footsteps = **organic**: warm, breathy, environmental reverb, natural decay. Use SAO for these.
- Monologue chimes = **insert-tech**: synthetic, precise, clinical, no reverb. Manually synthesize — SAO will produce too organic a character for chimes.
- The Sprint 9 chimes (#453) are acknowledged placeholders. Sprint 10 chimes are the production-quality replacements.
**D-038 amendment (hybrid approach):**
- SAO ceiling is ~47s. Accept 45s loops with crossfade for ambient layers (the `play_loop` method in AudioManager handles this).
- Sounds <200ms with precise/digital character: manual synthesis only.
**Zone crossfade integration:**
- `AudioManager.set_zone()` is currently a stub (D-073). This sprint's audio assets enable testing the stub's behavior. Inigo should verify that `amb_station_base`, `amb_workplace_layer`, `amb_bar_layer`, and `amb_corridor_layer` all loop cleanly with no audible seam — AudioManager's `_enable_loop` will set `loop = true` on OGG streams automatically.
- Full zone crossfade logic (the tween between ambient layers on zone change) is NOT in scope for this sprint — it remains a stub. The assets just need to be present and looping.
**Delivery:**
- Commit all 8 OGG files to `audio` branch under `client/audio/` (which maps to `res://audio/` in Godot).
- AudioManager registers them at startup via directory scan. No code changes to client branch.
- Effort: 3-4d (generation + iteration + mastering).
---
## Dependency Chain
```
#327 (8 audio assets) — standalone; AudioManager stub (D-068) already in client branch
```
---
## 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(audio): sprint 10 prove — ambient + world sfx assets" --description "body" --base main --head audio
```
+68
View File
@@ -0,0 +1,68 @@
# Sprint 10: Prove — CI Tasks
**Goal:** Expand the Gauntlet test suite with new rooms and cross-room scenarios, wire the audio architecture end-to-end, and complete client UX polish from Sprint 9 carry-overs — proving the full system holds together.
**Branch:** `ci`
**Agents:** Justine (build/deploy), Hoshe (QA review)
---
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #499 | Performance baseline tooling (make perf-baseline) | #487 (done) |
| #510 | CI pipeline (Gitea Actions YAML, 3-tier) | — |
| #515 | Bidirectional relationship consistency warning (content validation check 9) | #464 (done) |
Use `db/connectors/ticket show <id>` for full details.
---
## Key Decisions
- `decisions/architecture.md` — D-030 (testing architecture phases), D-026 (100ms tick budget)
- `decisions/scope.md` — D-038 (audio in v0.1 — audio asset presence/absence affects `make ci` behavior)
---
## Notes
**#499 — Performance baseline tooling**
- Existing: `Makefile` has `make pre-pr`, `make test-server`, `make test-client` targets. The test infrastructure (Sprint 9) is complete. No `perf-baseline` target exists yet.
- Deliver: `make perf-baseline` target. Runs the server benchmark suite, captures tick timing, memory usage, and entity count scaling metrics, outputs results to `tests/perf/`. The baseline file should be committed and tracked in git so future runs can detect regressions.
- Integration: Server #500 (content scaling test) feeds into this — coordinate timing so #499 can include the content scaling numbers in the baseline output. If #500 isn't merged, the perf baseline can run with existing content and be updated when #500 lands.
**#510 — CI pipeline (Gitea Actions YAML, 3-tier)**
- Existing: `make pre-pr` exists and is the manual gate. Gitea Actions self-hosted runner is available.
- Deliver: A Gitea Actions workflow YAML (`/.gitea/workflows/ci.yaml` or `.gitea/workflows/`) implementing three tiers:
- Commit tier: `<2min` — lint only (`make lint-server`, `make lint-client`)
- PR merge gate: `<15min` — wraps `make pre-pr`
- Nightly: `<30min` — full build + all tests + content validation
- **Deferred condition**: This ticket is backlog-tagged "deferred until lead greenlights." Confirm with Team Leader before starting. If greenlit, coordinate with Tyre on self-hosted runner configuration.
- Integration: Wraps existing `make` targets — should require zero changes to those targets.
**#515 — Bidirectional relationship consistency warning**
- Existing: Content validation runs via `tooling/validate-content`. Phase 1-2 checks are complete (#464 done). Check 9 is advisory.
- Deliver: Advisory warning (non-blocking, not an error) when NPC A has a relationship to NPC B but no reciprocal entry exists in NPC B's relationships. Output format: `WARN: NPC 'kael' has relationship to 'sera' but 'sera' has no reciprocal entry.` Effort: 0.25d.
- Non-obvious: One-sided relationships are sometimes intentional (faction member knows of faction leader, not vice versa). The warning is advisory, never a hard failure.
---
## Dependency Chain
```
#499 (perf baseline) — standalone (server #487 done); benefits from server #500 merging first
#510 (CI pipeline) — standalone; greenlight from lead required before start
#515 (bidirectional warning) — standalone (#464 done)
```
---
## 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(ci): sprint 10 prove — ci" --description "body" --base main --head ci
```
+109
View File
@@ -0,0 +1,109 @@
# Sprint 10: Prove — Client Tasks
**Goal:** Expand the Gauntlet test suite with new rooms and cross-room scenarios, wire the audio architecture end-to-end, and complete client UX polish from Sprint 9 carry-overs — proving the full system holds together.
**Branch:** `client`
**Agents:** Stig (UI/client dev), Tyre (arch review), Hoshe (QA)
---
## Carry-over from Sprint 9
| # | Title | Status | Notes |
|---|-------|--------|-------|
| #501 | Hub teleport client UX (Home key, fade transition) | backlog | Targeted Sprint 9, slipped — blocked by #491 server work which also slipped. Unblocks immediately once server #491 ships. |
| #502 | Room reset client UX (reset plate tile, interaction verb, amber flash) | backlog | Targeted Sprint 9, slipped. Unblocked (#490 done). |
| #503 | Auto-checklist progress tracking (client-side snapshot evaluation) | backlog | Targeted Sprint 9, slipped. Unblocked (#497 done). |
---
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #501 | Hub teleport client UX (Home key, fade transition) | #491 server (Sprint 10) |
| #502 | Room reset client UX (reset plate tile, interaction verb, amber flash) | #490 (done) |
| #503 | Auto-checklist progress tracking (client-side snapshot evaluation) | #497 (done) |
| #517 | Introduce Michroma as game font | — |
| #526 | Client: mouse-relative facing and movement (D-054) | — |
| #518 | Client: wire insert open/close to PauseSimulation command | — |
| #521 | Confrontation D-033 color shift — client-side entity tint | #520 server (Sprint 10) |
Use `db/connectors/ticket show <id>` for full details.
---
## Key Decisions
- `decisions/architecture.md` — D-020 (Godot/Rust IPC), D-054 (mouse-relative facing), D-058 (auto-pause on insert open), D-066 (dual-scale grid)
- `decisions/perception.md` — D-033 (entity color = relationship to player), D-056 (insert diegetic visibility), D-057 (interaction verbs), D-060 (cognitive delay), D-063 (confrontation same box)
- `decisions/scope.md` — D-053 (movement stance toggle)
---
## Open Questions to Resolve Early
- **Q-019 (partial): Client-side entity lifecycle / StableId mapping** — #521 reads relationship state from `ObserverSnapshot` and adjusts entity tint. Confirm with server team that relationship state is included in the snapshot before #521 starts. Resolve before #521 begins.
---
## Notes
**#501 — Hub teleport client UX**
- Existing: `client/scripts/protocol/protocol.gd` handles PlayerAction serialization. `client/scripts/rendering/world_renderer.gd` handles camera.
- Deliver: Home key sends `PlayerAction::TeleportToHub`. On receipt: instant camera snap to hub spawn position + 0.3s fade-to-black-and-back tween. Effort: 0.5d. Gauntlet-mode only guard matches server behavior.
- Dependency: Wait for server #491 to merge before testing end-to-end. Can develop and unit-test client logic in isolation using local bridge stub.
**#502 — Room reset client UX**
- Existing: `client/scripts/rendering/tile_renderer.gd` handles tile visual overrides. Interaction verbs rendered by UI layer.
- Deliver: (1) `reset_plate` tile type renders with amber color override. (2) 'Reset Room' verb appears when player faces reset plate. (3) On reset confirmation: 0.15s amber flash + monologue "Systems recalibrated." fires via monologue event. Effort: 0.5d.
- Integration: Server #490 (done) already emits the reset event. Client just needs to consume it.
**#503 — Auto-checklist progress tracking**
- Existing: Checklist YAML schema defined by CI #497 (done). The test client handles its own evaluation separately.
- Deliver: Client evaluates `ObserverSnapshot` against loaded checklist YAML conditions, auto-tracks verification items with a Gauntlet-mode HUD overlay. Full tracking in test-client-only mode; lightweight overlay in Godot per R2-OQ-06. Effort: 1.5d.
- Integration: Test-client-only overlay — does not affect production game HUD. Coordinate with Hoshe on checklist condition format.
**#517 — Michroma font**
- Existing: Default Godot font throughout client UI. No font assets committed yet.
- Deliver: Download Michroma from Google Fonts (OFL license), commit to `client/assets/fonts/`. Update all Label, RichTextLabel, and LineEdit nodes to use Michroma. Acceptance: font renders legibly in HUD, dialogue box, and debug overlay at game resolution. Effort: 0.5d. Purely cosmetic — no logic changes.
- Non-obvious: Michroma is geometric sans-serif at display weights — confirm legibility at small sizes (sub-16px tooltip text) before committing globally. Consider a size floor.
**#526 — Mouse-relative facing and movement**
- Existing: `client/scripts/main.gd` handles input. WASD currently uses fixed cardinal directions. `client/scripts/protocol/protocol.gd` sends facing octant to server.
- Deliver: Mouse position determines facing direction (client-side float computed from player screen position to cursor). WASD movement becomes mouse-relative (forward = toward cursor). Server receives facing octant only, unchanged interface. Effort: 1d.
- Key decision: D-054 — mouse facing is purely client-side. Server only ever sees the octant. The full float stays in the client for rendering purposes.
**#518 — Wire insert open/close to PauseSimulation**
- Existing: Server pause system at 50%/0% tick rate exists (#406, done). `client/scripts/autoloads/sim_bridge.gd` handles server commands. Insert UI open/close events are in `client/scripts/main.gd`.
- Deliver: When insert UI opens, client sends `PauseSimulation` command. When it closes, client sends `ResumeSimulation`. D-058 confirms auto-pause in SP mode. Ticket #448 was cancelled before client wiring was completed. Effort: 0.5d.
- Non-obvious: The pause/resume must be idempotent — if the server is already paused (e.g. Gauntlet room interlude), opening the insert should not double-pause.
**#521 — Confrontation D-033 color shift**
- Existing: `client/scripts/rendering/entity_renderer.gd` applies D-033 relationship colors. `ObserverSnapshot` carries entity relationship state.
- Deliver: On confrontation delivery (server #520 decrements relationship state), entity renderer fades the entity's D-033 tint toward the new relationship color using a 0.5-1s tween. Not an instant flip — a fade that the player perceives as "something changed."
- Dependency: Blocked by server #520. Start after #520 merges.
---
## Dependency Chain
```
#502 (room reset UX) — standalone (server #490 done)
#503 (auto-checklist) — standalone (CI #497 done)
#517 (Michroma font) — standalone, parallel
#518 (insert pause wire) — standalone, parallel
#526 (mouse-relative facing) — standalone, parallel
Server #491 (hub teleport) → #501 (hub teleport UX)
Server #520 (confrontation response) → #521 (D-033 color shift)
```
---
## 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(client): sprint 10 prove — client" --description "body" --base main --head client
```
+167
View File
@@ -0,0 +1,167 @@
# Sprint 10: Prove — Joint / Integration
**Goal:** Expand the Gauntlet test suite with new rooms and cross-room scenarios, wire the audio architecture end-to-end, and complete client UX polish from Sprint 9 carry-overs — proving the full system holds together.
**Agents:** All implementation agents (Dudley, Stig, Hoshe, Tyre, Justine, Inigo)
---
## Pre-Sprint Decisions
No new decisions are required before Sprint 10 begins. All sprint tickets operate within confirmed decisions. Items to monitor:
| Item | Status | Needed by |
|------|--------|-----------|
| Relationship state in ObserverSnapshot | Confirm with server team that relationship state is carried per entity in the snapshot (Q-019 partial resolution) | #521 (D-033 color shift, client) |
| CI pipeline greenlight | Team Leader must confirm before #510 starts | #510 (Gitea Actions YAML, CI) |
| Server #491 merge timing | Client #501 is blocked on it — server should prioritize #491 in the first half of sprint | #501 (hub teleport UX, client) |
| Server #520 merge timing | Client #521 is blocked on it — server should ship #520 before sprint midpoint | #521 (confrontation color shift, client) |
---
## Cross-Team Dependencies
```
Server #491 (hub teleport action)
→ Client #501 (hub teleport UX — Home key + fade)
Server #520 (confrontation world response)
→ Client #521 (D-033 color shift on confrontation)
Server #500 (content scaling test)
→ CI #499 (perf baseline — benefits from #500 data)
Server #498 (Gauntlet rooms 4-7)
→ #506 (cross-room transitions, deferred to Sprint 11)
Server #483 (replay loading)
→ Scripted Gauntlet testing (unblocks Sprint 11 automation)
Audio #327 (8 ambient + SFX assets)
→ Client AudioManager (automatic registration via directory scan — no client code change)
→ D-073 zone crossfade stub can be tested with real assets for the first time
```
**Critical path:** `Server #491 → Client #501` and `Server #520 → Client #521`. Both server tickets need to merge before sprint midpoint to give client time to complete their dependent work.
---
## Sprint Completion Proof
Sprint 10 is complete when all of the following are observable:
**Hub teleport**
- Pressing Home key in Gauntlet mode sends `TeleportToHub`, player entity moves to hub spawn tile
- 0.3s fade-to-black-and-back plays on teleport
- Dialogue/monologue/interaction buffer is cleared on teleport
- Non-Gauntlet maps: action is rejected server-side with log warning; client shows no effect
**Room reset UX**
- `reset_plate` tile type renders with amber color
- 'Reset Room' verb appears in interaction menu when player faces reset plate
- On reset: 0.15s amber flash + "Systems recalibrated." monologue line plays
**Auto-checklist tracking**
- In test-client mode: checklist YAML loads, client evaluates ObserverSnapshot against conditions, verified items tick off automatically in HUD overlay
- Checklist HUD is absent in non-test-client Godot mode
**Gauntlet expansion**
- Server boots with Gauntlet content and all 7 rooms (existing 3 + new 4) load without panic
- Room constants for all 4 new rooms in `server/src/test_world/constants.rs`
- Room reset works correctly in new rooms (entity positions and fog reset to tick-0 state)
**Content scaling**
- `make test-server` includes the content scaling test: baseline run passes, extra-NPC comparative run stays within D-026 tick budget
**Performance baseline**
- `make perf-baseline` runs without error and produces `tests/perf/baseline.json` (or equivalent)
- Baseline file committed to repo
**Replay loading**
- `tooling/test-client --replay <file.jsonl>` loads the file and sends PlayerInput at correct tick timing against a live server
**Client UX polish**
- Michroma font renders in all Labels/RichTextLabels in HUD and dialogue box
- WASD movement is mouse-relative (forward = toward cursor direction)
- Insert open sends `PauseSimulation`, insert close sends `ResumeSimulation`
**Confrontation system**
- Confrontation delivery: target NPC shifts to Tier 2 animation, relationship state decrements, monologue spike fires (server)
- Client: entity D-033 tint fades to new relationship color over 0.5-1s on confrontation delivery
**Audio**
- 8 OGG files present in `audio` branch under `client/audio/`
- `AudioManager` registers all 8 at startup (log output confirms count)
- Ambient loops play without audible seam
- Monologue chimes have no reverb (insert-tech aesthetic per D-074)
**CI (if greenlit)**
- Gitea Actions YAML committed to `.gitea/workflows/`
- Commit tier runs in <2min on push
- PR merge gate wraps `make pre-pr` in <15min
---
## Test Plan Alignment (D-030)
| D-030 Phase | Coverage | Sprint 10 Status |
|-------------|----------|-----------------|
| Phase 1 (infra) | Done Sprints 1-2 | — |
| Phase 2 (integration) | Done Sprints 3-5 | — |
| Phase 3 (CauseChain, divergent snapshots) | Gauntlet golden suite (#485, Sprint 9) | Expanding with rooms 4-7 |
| Replay / scripted testing | #483 (test client replay loading) | In scope |
| Performance regression baseline | #499 (make perf-baseline) | In scope |
| Content scaling | #500 (baseline + NPC pack comparative) | In scope |
| Pre-PR gate | `make pre-pr` (Sprint 9, done) | Stable |
---
## Open Questions to Resolve Early
- **Q-019 (partial): Client-side entity StableId / relationship state in snapshot** — Client #521 needs relationship state per entity in ObserverSnapshot. Server team should confirm scope before #521 starts. No formal Q-NNN resolution required — just a server team confirmation.
- **CI pipeline greenlight (no Q-NNN)** — #510 has an explicit "deferred until lead greenlights" note. Team Leader to confirm before CI team starts that ticket.
---
## Sequence Recommendation
**Days 1-3 (all teams in parallel):**
- Server: start #491 immediately (no blockers). Priority — unblocks client #501.
- Server: start #483 (no blockers). `replay.rs` stub exists in `tooling/test-client/src/`.
- Server: start #498 (no blockers). 4 new Gauntlet rooms; follow existing room pattern.
- Server: start #514 (small, standalone).
- Server: start #519 (standalone, #427 done).
- Client: start #502 (no blockers, #490 done).
- Client: start #503 (no blockers, #497 done).
- Client: start #517 (standalone).
- Client: start #526 (standalone).
- Client: start #518 (standalone).
- CI: start #499 (no blockers, #487 done).
- CI: start #515 (standalone, #464 done).
- Audio: start #327.
**Days 4-6:**
- Server: start #520 (no blockers). Priority — unblocks client #521.
- Server: start #500 (no blockers, #489 done).
- Client: #501 unblocks once server #491 merges.
**Days 7-10:**
- Client: #521 unblocks once server #520 merges.
- CI: #510 starts only after lead greenlight (may be later in sprint or deferred).
- All teams: verification against Sprint Completion Proof criteria.
---
## PR Workflow
Each team submits their own PR from their branch. Integration is via merge to `main`. No joint branch — all tickets are single-team. The `joint.md` tracks integration readiness but does not produce a separate branch.
```bash
# Verify sprint assignment before PR
db/connectors/sprint status --team <team>
# Standard PR (all flags required — see CLAUDE.md)
tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
--title "feat(<scope>): sprint 10 prove — <team summary>" \
--description "body" --base main --head <branch>
```
+103
View File
@@ -0,0 +1,103 @@
# Sprint 10: Prove — Server Tasks
**Goal:** Expand the Gauntlet test suite with new rooms and cross-room scenarios, wire the audio architecture end-to-end, and complete client UX polish from Sprint 9 carry-overs — proving the full system holds together.
**Branch:** `server`
**Agents:** Dudley (simulation), Tyre (arch review), Hoshe (QA)
---
## Carry-over from Sprint 9
| # | Title | Status | Notes |
|---|-------|--------|-------|
| #491 | Hub teleport action (PlayerAction::TeleportToHub) | backlog | Targeted for Sprint 9, slipped due to #487 dependency completing late. Unblocked as of sprint close. |
| #483 | Test client replay loading + tick-scheduled sending | backlog | Critical for scripted Gauntlet testing. Targeted Sprint 9, slipped. Unblocked (#480 done). |
| #500 | Content scaling test (baseline + extra NPC comparative) | backlog | Targeted Sprint 9, deferred. Unblocked (#489 done). |
---
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #491 | Hub teleport action (PlayerAction::TeleportToHub) | #487 (done) |
| #483 | Test client replay loading + tick-scheduled sending | #480 (done) |
| #498 | Gauntlet rooms 4-7 (Interaction Gallery, Fog Theater, Crowd Plaza, Dialogue Room) | #487 (done) |
| #500 | Content scaling test (baseline + extra NPC comparative) | #489 (done) |
| #514 | blocked_entities debug field on ObserverSnapshot | — |
| #519 | Walk-away NPC reaction — server-side Phase 2 (animation shift, routine change) | #427 (done) |
| #520 | Confrontation world response — server-side trigger | — |
Use `db/connectors/ticket show <id>` for full details.
---
## Key Decisions
- `decisions/architecture.md` — D-010 (deterministic simulation), D-026 (100ms tick budget), D-041 (knowledge graph data model)
- `decisions/perception.md` — D-059 (fog/shader five layers), D-060 (cognitive delay), D-063 (confrontation world response), D-064 (walk-away three phases)
- `decisions/scope.md` — D-038 (audio in v0.1 scope)
---
## Notes
**#491 — Hub teleport action**
- Existing: `server/src/test_world/rooms/hub.rs` for the hub spawn location. `PlayerAction` enum lives in `server/src/bridge/`.
- Deliver: `PlayerAction::TeleportToHub` variant. On receipt: move player entity to hub spawn tile, clear dialogue/monologue/interaction buffer. Does NOT affect room state, inventory, game time, or knowledge graph. Reject the action with a log warning on non-Gauntlet maps.
- Integration: Client #501 depends on this — ship it first half of sprint.
**#483 — Test client replay loading**
- Existing: `tooling/test-client/src/` has `main.rs`, `golden.rs`, `replay.rs` (stub). The `replay.rs` module exists but the loading logic was deferred.
- Deliver: Load a JSONL replay file (one JSON array per tick), send `PlayerInput` at correct tick timing. Target: `tooling/test-client/src/replay.rs`.
- Integration: Enables scripted Gauntlet testing end-to-end — unblocks the cross-room test scenarios in later sprints.
**#498 — Gauntlet rooms 4-7**
- Existing: `server/src/test_world/rooms/` has `hub.rs`, `inventory_warehouse.rs`, `occlusion_corridor.rs`, `pause_chamber.rs`. The `mod.rs` wires them together.
- Deliver: Four new rooms — Interaction Gallery (24x20, 5 entities, D-057), Fog Theater (44x32, 4 entities, D-059), Crowd Plaza (32x32, 15 entities), Dialogue Room (28x20, 4 entities, D-041). Follow the pattern of existing room modules. Each room must have constants in `server/src/test_world/constants.rs`.
- Integration: Unblocks #506 (cross-room transition tests) in a future sprint.
**#500 — Content scaling test**
- Existing: The baseline test infrastructure is in place post-#489. Content packs are in `server/src/content/`.
- Deliver: A test that runs the baseline NPC pack then the same scenario with additional NPCs, asserts tick timing stays within D-026 budget and behavior is unchanged for original NPCs.
- Integration: Feeds into CI perf baseline (#499) which CI team handles.
**#514 — blocked_entities debug field**
- Existing: `ObserverSnapshot` in `server/src/bridge/`. LOS computation is in `server/src/perception/`.
- Deliver: Add `blocked_entities: Vec<StableId>` (or `Option<Vec<StableId>>`) to `ObserverSnapshot`. Feasibility confirmed at ~300 tile lookups/tick (R2-OQ-05). Debug-only field; `#[serde(default)]` so client gracefully ignores on older snapshots.
- Integration: Improves test client debug output. Standalone, no cross-team dependency.
**#519 — Walk-away NPC reaction Phase 2**
- Existing: Phase 1 (client fade, #437) and Phase 3 (KG recording, #427) are done. Phase 2 is the missing server-side piece.
- Deliver: On `PlayerAction::WalkAway` (or dialogue exit event), server triggers: (1) target NPC shifts animation tier to Tier 2 (D-047), (2) NPC routine deviation is recorded in their state machine. D-064 Phase 2 scope.
- Integration: Standalone server-side work. No client changes required.
**#520 — Confrontation world response**
- Existing: Confrontation delivery is wired through dialogue system. D-063 specifies the world response.
- Deliver: On confrontation delivery: (1) target NPC shifts to Tier 2 animation (D-047 animated tier), (2) NPC relationship state decremented (affects D-033 color which client #521 renders), (3) monologue spike event emitted. Three separate effects, all server-authoritative.
- Integration: Client #521 blocked by this — complete #520 first half of sprint.
---
## Dependency Chain
```
#483 (replay loading) — standalone, parallel
#491 (hub teleport server) → #501 (hub teleport client UX, cross-team)
#498 (Gauntlet rooms 4-7) → #506 (cross-room transitions, future sprint)
#500 (content scaling) → #499 (perf baseline, CI team)
#514 (blocked_entities) — standalone, parallel
#519 (walk-away phase 2) — standalone, parallel
#520 (confrontation world response) → #521 (D-033 color shift, client team)
```
---
## 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 10 prove — server" --description "body" --base main --head server
```