18 tickets across 3 teams. Movement stances, fog shader rebuild, multi-verb interactions, smuggler inventory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
112 lines
8.9 KiB
Markdown
112 lines
8.9 KiB
Markdown
# Sprint 6: Touch — Client Tasks
|
|
|
|
**Goal:** Movement stances, fog rebuild, multi-verb interactions, and smuggler inventory
|
|
|
|
**Branch:** `client`
|
|
**Agents:** Stig (UI/rendering), Tyre (architecture), Hoshe (QA)
|
|
|
|
## New Tickets
|
|
|
|
| # | Title | Blocked by |
|
|
|---|-------|------------|
|
|
| #429 | Cursor state machine — 4 states, Araminta spec, 150ms transitions | — |
|
|
| #430 | Fog shader rebuild — 5-layer, CanvasGroup Layer 5, animated noise | — |
|
|
| #432 | Entity interaction vertical list — insert-styled, z-layer 6 | #429 |
|
|
| #433 | World radial menu — 2 spokes v0.1 (Observe + Insert) | — |
|
|
| #438 | Inventory UI — 3x3 grid, 1-9 hotkeys | #449 (server) |
|
|
| #439 | Stance toggle UI — keybind + HUD indicator | #449 (server) |
|
|
|
|
Use `db/connectors/ticket show <id>` for full details.
|
|
|
|
## Key Decisions
|
|
|
|
- `decisions/perception.md` — D-056 (Cursor states), D-057 (Entity interaction vertical list), D-058 (World radial menu), D-059 (Fog shader rebuild), D-061 (Dialogue box)
|
|
- `decisions/scope.md` — D-053 (Movement stances), D-065 (Smuggler inventory)
|
|
- `decisions/architecture.md` — D-049 (Z-level rendering stack)
|
|
|
|
## Open Questions Resolved
|
|
|
|
- **OQ-24: Inventory capacity** — Resolved to 3x3 grid = 9 slots (ticket #445, done)
|
|
|
|
## Notes
|
|
|
|
### #429: Cursor state machine — 4 states
|
|
- **What exists:** Basic cursor rendering in Godot (default arrow)
|
|
- **Needs:** Implement 4-state cursor using D-048 insert geometric aesthetic (thin ticks, bloom shader):
|
|
- **Default:** Four thin inward-pointing ticks with bloom. White-blue #c8d0e0. Barely visible.
|
|
- **Entity hover:** Ticks expand outward (150ms), corner brackets frame entity, color shifts to D-033 relationship color, verb tooltip in insert styling, bloom pulse ~10% brighter on entity outline
|
|
- **Object hover:** Ticks rotate 45° to X-shape, muted grey #8b8ba0 (amber #e8c547 if flagged), simpler frame than entity
|
|
- **Weapon aim:** Hard transition. Ticks extend, center gap widens, lines thicken 1→2px, warm white #f0e8d8, NO bloom. Entity in sights tints to D-033 color (aiming at friend = green tint should feel wrong).
|
|
- **D-056 spec:** All transitions 150ms linear. z-layer 7. Never changes by zone/narrative state (D-045). Cursor changes on LOS, not just proximity. Click interaction range: ~2 tiles. Weapon-selected mode suppresses interaction prompts unless Shift held.
|
|
- **Diegetic test (Stig):** Interaction labels render on z-layer 6 (insert overlay). If insert is off, labels disappear.
|
|
- **Integration:** Blocks #432 (entity interaction list — cursor states trigger list display)
|
|
|
|
### #430: Fog shader rebuild — 5-layer from scratch
|
|
- **What exists:** `client/scripts/rendering/fog_renderer.gd` extends TileMapLayer with 2-state fog (opaque black, semi-transparent edge). Lines 1-50 show current implementation.
|
|
- **Needs:** **REBUILD from scratch.** Replace TileMapLayer-based fog with CanvasGroup + fragment shader. Five distinct layers:
|
|
1. **Clear (vision cone):** Soft gradient edge 3-4 tiles (Darkwood approach), no hard line
|
|
2. **Light fog (peripheral):** Desaturated 40-50%, brightness -30%, animated Perlin noise overlay (8-10s cycle), entity D-033 colors visible but reduced
|
|
3. **Deep fog (previously explored):** Near-monochrome with ~10% "zone temperature" tint (bar=warm dark, hub=cool dark, corridor=neutral dark), more pronounced noise (15-20s cycle), fog breathes
|
|
4. **Unexplored + maps app:** Geometric wireframe outlines #333340 (insert data aesthetic)
|
|
5. **Unexplored, no maps:** Solid near-black #12141a (information zero)
|
|
- **Fog entities (sprites on Layer 5):**
|
|
- **Sound pings:** 2-3 thin concentric expanding rings (sonar-style) from source direction, insert white-blue. Loud = 3 rings bright fast. Quiet = 1 ring faint slow. Fade over 1.5s.
|
|
- **Recognized entity:** D-033 color glow + faint identifying silhouette feature (e.g., "Kael's vest") + 0.8s breathing pulse + ±0.5 tile position drift (approximate, not exact). Recognition transition governed by D-060 cognitive delay.
|
|
- **Unrecognized entity:** Neutral grey #555566 blob. No silhouette, no identifying features.
|
|
- **D-059 spec:** Knowledge-graph-driven — same fog shows different information per character based on their KG. Smuggler recognizes dock workers = green icons. Detective sees same entities = grey blobs. "Fog is not darkness — it's the absence of your attention."
|
|
- **Performance target:** <1ms/frame total. Vision cone = PointLight2D. Fog = natural darkness + noise shader on CanvasGroup (Layer 5). Sound pings = 0-5 sprites. Entity ghosts = 0-10 sprites typical.
|
|
- **Gotcha:** This is a complete rewrite, not an enhancement. Delete `fog_renderer.gd` and start fresh with shader-based approach. Araminta's spec in D-059 is the source of truth.
|
|
- **Integration:** Blocks #431 (fog entity visualization, deferred to Sprint 7+)
|
|
|
|
### #432: Entity interaction vertical list — insert-styled
|
|
- **What exists:** Interaction prompt system (#405, done in Sprint 5) shows "E: <verb>" on nearest entity
|
|
- **Needs:** Replace single-verb prompt with compact vertical list (2-4 options max), anchored to entity position, insert-styled with Araminta's geometric aesthetic (thin lines, bloom, z-layer 6). New options unlocked by KG changes highlighted with gradient glow background. Max 3 visible response options in dialogue context.
|
|
- **D-057 spec:** Variable-length text options (confrontation lines in character voice) break radial spatial memory. List handles 1-4 options cleanly. Radial reserved for world menu only (#433).
|
|
- **Server integration:** Reads `nearby_interactions` from ObserverSnapshot (Phase 2 filtered verbs per D-057). Server provides 2-4 verbs, client renders list. Clicking a verb sends PlayerAction::Interact with target + verb.
|
|
- **Diegetic test:** Labels render on z-layer 6. If insert is off, labels disappear (passes "is this information from character's implant?" test).
|
|
- **Integration:** Blocked by #429 (cursor states — entity hover triggers list display). Works with server #422 (two-phase verb computation).
|
|
|
|
### #433: World radial menu — 2 spokes v0.1
|
|
- **Needs:** Right-click opens radial world menu. v0.1: 2 spokes only (Observe + Insert). Insert-styled: geometric lines, thin spokes with icons (eye icon for Observe, phone icon for Insert), nearly transparent. Renders on z-layer 6. Drag-release for power users (high-speed drag-to-select), click-click for newcomers. Future: scale to 4 spokes (add Comms, Wait).
|
|
- **D-058 spec:** Radial works for world menu because items are fixed categories that don't vary by knowledge state (unlike entity verbs which use vertical list #432). Spatial memory builds quickly (~10 minutes).
|
|
- **Integration:** Standalone. Complements #432 (entity list vs world radial — different UX for different contexts).
|
|
|
|
### #438: Inventory UI — 3x3 grid, 1-9 hotkeys
|
|
- **Needs:** Bottom-right HUD area, 3x3 grid (40x40px icons), mapped to 1-9 keys. No empty slots displayed — icons appear only when items are carried. Reads `player_inventory` from ObserverSnapshot v6 (server #449).
|
|
- **D-065 spec:** OQ-24 resolved to 9 slots universal (3x3 grid). Smuggler gets 3 items in v0.1 (manifest copy, access token, comm log). Detective gets 2 slots used. Items are world entities with CarriedBy component (server-side).
|
|
- **UI positioning:** Bottom-right, does not overlap dialogue box (max 20% height per D-061). Icons render at z-layer 7 (HUD elements).
|
|
- **Integration:** Blocked by server #449 (ObserverSnapshot v6 adds player_inventory field). Works with server #424 (CarriedBy component + Take/Place verbs).
|
|
|
|
### #439: Stance toggle UI — keybind + HUD indicator
|
|
- **Needs:** Keybind for stance toggle (suggest C key, or Ctrl as ladder climb), HUD indicator showing current stance (icon + text: "Sprint" / "Walk" / "Careful" / "Crouch"). Reads `player_stance` from ObserverSnapshot v6 (server #449). Visual feedback on stance change (brief highlight or fade).
|
|
- **D-053 spec:** Toggle-based ladder: Sprint → Walk → Careful → Crouch → (Prone future). Each stance affects movement speed and monologue rate. v0.1: 4 stances (Sprint/Walk/Careful/Crouch).
|
|
- **UI positioning:** Top-left or top-right HUD area (not overlapping dialogue box or inventory). z-layer 7.
|
|
- **Integration:** Blocked by server #449 (ObserverSnapshot v6 adds player_stance field). Works with server #417 (stance system).
|
|
|
|
## Dependency Chain
|
|
|
|
```
|
|
Critical path:
|
|
#429 (Cursor states) → #432 (Entity interaction list)
|
|
|
|
Parallel tracks:
|
|
#430 (Fog shader rebuild) → standalone, large rewrite
|
|
#433 (World radial menu) → standalone
|
|
#438 (Inventory UI) → blocked by server #449
|
|
#439 (Stance UI) → blocked by server #449
|
|
```
|
|
|
|
## 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): cursor states, fog shader rebuild, interaction list, inventory + stance UI" \
|
|
--description "Sprint 6 client deliverables per D-056, D-057, D-058, D-059, D-061, D-065" \
|
|
--base main \
|
|
--head client
|
|
```
|