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

8.8 KiB

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):

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