Files
settled-reach/docs/sprints/sprint-6/server.md
T
jpmschweitzerandClaude Opus 4.6 f1bd361816 feat(docs): add D-066 dual-scale grid decision and propagate to all docs
0.5m sim tiles for movement/LOS granularity, 1m visual tiles for
proportional art and readable spaces (2x retina factor). All world
geometry constrained to 2x2 sim tile minimum so cover/LOS maps 1:1
with visuals. Entities occupy 1x1 sim tiles for fine positioning.

Updates: D-043, D-044, D-051, D-056, D-059 annotations, workshop
outcomes (art direction + control/interaction), sprint 6 briefings,
decision index, and CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 11:01:05 +01:00

125 lines
8.8 KiB
Markdown

# 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 <id>` 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<VisibleItem>` (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
```