From b4a3784218fb395b04e6227a47a423e9e1827d0c Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Wed, 18 Feb 2026 12:12:45 +0100 Subject: [PATCH] docs(sprints): add Sprint 10 Prove briefings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- docs/sprints/sprint-10/audio.md | 83 +++++++++++++++ docs/sprints/sprint-10/ci.md | 68 +++++++++++++ docs/sprints/sprint-10/client.md | 109 ++++++++++++++++++++ docs/sprints/sprint-10/joint.md | 167 +++++++++++++++++++++++++++++++ docs/sprints/sprint-10/server.md | 103 +++++++++++++++++++ 5 files changed, 530 insertions(+) create mode 100644 docs/sprints/sprint-10/audio.md create mode 100644 docs/sprints/sprint-10/ci.md create mode 100644 docs/sprints/sprint-10/client.md create mode 100644 docs/sprints/sprint-10/joint.md create mode 100644 docs/sprints/sprint-10/server.md diff --git a/docs/sprints/sprint-10/audio.md b/docs/sprints/sprint-10/audio.md new file mode 100644 index 000000000..15549deef --- /dev/null +++ b/docs/sprints/sprint-10/audio.md @@ -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 ` 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 +``` diff --git a/docs/sprints/sprint-10/ci.md b/docs/sprints/sprint-10/ci.md new file mode 100644 index 000000000..4a39c7514 --- /dev/null +++ b/docs/sprints/sprint-10/ci.md @@ -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 ` 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 +``` diff --git a/docs/sprints/sprint-10/client.md b/docs/sprints/sprint-10/client.md new file mode 100644 index 000000000..a0d6cc465 --- /dev/null +++ b/docs/sprints/sprint-10/client.md @@ -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 ` 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 +``` diff --git a/docs/sprints/sprint-10/joint.md b/docs/sprints/sprint-10/joint.md new file mode 100644 index 000000000..829d95b47 --- /dev/null +++ b/docs/sprints/sprint-10/joint.md @@ -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 ` 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 + +# Standard PR (all flags required — see CLAUDE.md) +tea pr create --repo jpmschweitzer/settled-reach --login schweitz \ + --title "feat(): sprint 10 prove — " \ + --description "body" --base main --head +``` diff --git a/docs/sprints/sprint-10/server.md b/docs/sprints/sprint-10/server.md new file mode 100644 index 000000000..1d2a42e00 --- /dev/null +++ b/docs/sprints/sprint-10/server.md @@ -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 ` 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` (or `Option>`) 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 +```