--- title: "Sprint 6 — Server Briefing" description: "Stance system, tile occupancy, two-phase verb computation, smuggler inventory" type: sprint status: archived sprint: 6 team: "server" --- # Sprint 6: Touch — Server Tasks **Goal:** Movement stances, fog rebuild, multi-verb interactions, and smuggler inventory **Branch:** `server` **Agents:** Dudley (simulation), Tyre (architecture), Hoshe (QA) ## New Tickets | # | Title | Blocked by | |---|-------|------------| | #449 | ObserverSnapshot v6 — add player_stance, player_inventory wire fields | — | | #417 | Stance system — Sprint/Walk/Careful/Crouch with tick-based movement | #444 (done) | | #418 | MovementProfile component per archetype | #417 | | #419 | Sprint interaction buffer suppression | #417 | | #420 | Same-tile occupancy — TilePresence with posture layers | #444 (done) | | #421 | ObjectType component + verb sets per type | — | | #422 | Two-phase verb computation — KG-gated Phase 2 observer filter | #421 | | #424 | Smuggler inventory — CarriedBy component, Take/Place verbs, info boundary | #445 (done) | | #428 | Sprint anomaly monologue — double-take survival | — | Use `db/connectors/ticket show ` for full details. ## Key Decisions - `decisions/scope.md` — D-053 (Movement as stance toggle system), D-065 (Smuggler inventory) - `decisions/architecture.md` — D-054 (Tile-based movement with same-tile occupancy), D-055 (Sprint explicitly suppresses interaction buffer) - `decisions/perception.md` — D-057 (Entity interaction — vertical list, two-phase verb computation) ## Open Questions Resolved - **OQ-01: Tile size** — Resolved to 0.5m x 0.5m sim tiles (ticket #444, done). Amended by D-066: dual-scale grid with 1m visual tiles (2x retina factor). All world geometry 2x2 sim tile minimum. - **OQ-24: Inventory capacity** — Resolved to 3x3 grid = 9 slots universal (ticket #445, done) ## Notes ### #449: ObserverSnapshot v6 — player_stance, player_inventory - **What exists:** `server/src/bridge/types.rs` defines ObserverSnapshot v5 (current version: 4, see line 30-48) - **Needs:** Add two new fields to ObserverSnapshot struct: - `player_stance: MovementStance` (enum: Sprint/Walk/Careful/Crouch) - `player_inventory: Vec` (items carried by player, visible to player only per D-010 info boundary) - **Integration:** #417 provides MovementStance enum, #424 provides CarriedBy component query - **Critical path:** This ticket unblocks client #439 (stance UI) and #438 (inventory UI) ### #417: Stance system — tick-based movement - **What exists:** `server/src/simulation/movement.rs` has basic movement at 1 tile/2 ticks (Walk default) - **Needs:** Add MovementStance component (enum: Sprint/Walk/Careful/Crouch/Prone), implement stance ladder toggling via PlayerAction::ToggleStance, apply tick multipliers per stance (Sprint=1/1, Walk=1/2, Careful=1/3, Crouch=TBD), wire monologue rate modifiers (Sprint=40%, Walk=100%, Careful=150%) - **D-053 spec:** Sprint suppresses monologue to 40%, Careful enhances it to 150%. Perception coupling is multiplicative. No vision cone changes (cognitive, not sensory). - **Gotcha:** Prone is toggle-out only in normal play (must stand up explicitly). Future combat allows "hit the deck" quick-entry. v0.1 scope: Sprint/Walk/Careful/Crouch only. - **Integration:** Blocks #418 (MovementProfile), #419 (sprint suppression), #426 (ListeningFocus deferred), #439 (client stance UI) ### #418: MovementProfile component per archetype - **Needs:** Add MovementProfile component storing default stance per archetype (smuggler=Walk, detective=Walk). Apply on spawn. - **Rationale:** Future archetypes may have different defaults (e.g., maintenance worker defaults to Careful). Smuggler and detective both start Walk for v0.1. - **Integration:** Blocked by #417 (stance system must exist first) ### #419: Sprint interaction buffer suppression - **What exists:** `server/src/simulation/interaction.rs` computes nearby_interactions for ObserverSnapshot - **Needs:** When player stance == Sprint, explicitly clear interaction buffer (nearby_interactions = empty vec). Anomaly monologue survives sprint (D-055: sprint suppresses interpretation, not sensory data). - **D-055 spec:** Interaction verbs not computed during sprint. Sprint double-take: if character passes anomaly while sprinting, delayed monologue fires retroactively ("Wait — was that Kael? At this hour?"). - **Integration:** Blocked by #417 (stance system), works with #428 (anomaly monologue) ### #420: Same-tile occupancy — TilePresence layers - **What exists:** Movement system uses discrete tile positions (Position component) - **Needs:** Add TilePresence component (enum: Standing/Prone/Seated/Fixture), allow multiple entities per tile if different posture layers, update collision detection to check layer conflicts - **D-054 spec:** Tile-based movement enables determinism (D-010 principle 4). Occupancy adds positioning depth (doorway blocking, eavesdrop positioning, sitting at furniture) within tile constraints. ~150 lines. - **Integration:** Crouch stance (#417) uses Prone/Seated layer. Enables future eavesdrop mechanics (#426, deferred). ### #421: ObjectType component + verb sets per type - **Needs:** Add ObjectType component (enum: Readable, Container, Terminal, Door, Pickup, Furniture), define verb sets per type (e.g., Readable → {Read, Observe}, Container → {Open, Search, Observe}), spawn objects with ObjectType in map loader - **D-057 context:** ObjectType drives Phase 1 verb computation (max possible verb set, no KG). Phase 2 filters by observer's KG. - **Integration:** Blocks #422 (two-phase verb computation) ### #422: Two-phase verb computation — KG observer filter - **What exists:** `server/src/simulation/interaction.rs` computes verbs, `server/src/knowledge/` has KG query infrastructure - **Needs:** Refactor verb computation into two phases: - **Phase 1 (simulation, no KG):** Query ObjectType component → return max verb set for that type - **Phase 2 (observer, reads KG):** Filter Phase 1 verbs by player's knowledge (e.g., Confront requires KnowsDetails+ per D-041), apply POI priority flips, add contradiction markers, character-archetype verb variation (smuggler sees "Move/Stash", detective sees "Scan/Flag" for same crate) - **D-057 spec:** Vertical list handles 2-4 options max. New verbs unlocked by KG changes highlighted with glow (client-side). Character differentiation via Phase 2 observer filter, not separate verb systems. - **Integration:** Blocked by #421 (ObjectType). Enables rich interactions without hardcoding character logic into simulation. ### #424: Smuggler inventory — CarriedBy, Take/Place verbs - **What exists:** Entities are world entities in ECS, KG tracks knowledge (not items) - **Needs:** Add CarriedBy(StableId) component referencing carrier entity, implement Take/Place verbs (add/remove CarriedBy component), respect info boundary (carried items private, not visible to other entities unless revealed via search/scan/confrontation), query system: all items WHERE CarriedBy == player - **D-065 spec:** Knowledge is primary inventory (you SAW the manifest). Physical inventory is secondary (3 specific items for smuggler in v0.1: manifest copy, access token, comm log). Smuggler 9 slots, detective 2 slots (D-065 updated after OQ-24 resolution: 3x3 grid = 9 slots universal). - **Gotcha:** Contraband detection (#425, deferred) will scan carried items via KG + CarriedBy query. Items behind info boundary until revealed. - **Integration:** Blocks #425 (contraband, deferred), #438 (client inventory UI) ### #428: Sprint anomaly monologue — double-take - **Needs:** When player in Sprint stance passes an anomaly (e.g., THE FRIEND in wrong location/wrong time), suppress immediate monologue but fire delayed retroactive monologue after ~1-2s: "Wait — was that Kael? At this hour?" - **D-055 context:** Sprint suppresses interpretation (monologue at 40%), not sensory data. Anomaly survival creates the "sprint double-take" feel — character's brain catches up after the fact. - **Integration:** Works with #419 (sprint suppression), uses existing monologue pipeline (#414, done in Sprint 5) ## Dependency Chain ``` Critical path: #449 (ObserverSnapshot v6) → standalone, unblocks client #438, #439 #417 (Stance system) ├─→ #418 (MovementProfile) ├─→ #419 (Sprint suppression) └─→ #420 (TilePresence, parallel but both use tick system) #421 (ObjectType) → #422 (Two-phase verb computation) #424 (Smuggler inventory) → standalone, unblocks client #438 #428 (Sprint anomaly monologue) → standalone, parallel work ``` ## 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): movement stances, tile occupancy, two-phase verbs, smuggler inventory" \ --description "Sprint 6 server deliverables per D-053, D-054, D-055, D-057, D-065" \ --base main \ --head server ```