Server (7), client (5), copy (2) tickets. Goal: player acts and world reacts — follow/examine, dialogue access layers, server-side monologue events, personality and tell system. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.0 KiB
Sprint 15: React — Client Tasks
Goal: The player acts and the world reacts — follow and examine mechanics connect the player to the living NPC simulation; the dialogue system's first two access layers open up information gating; server-side monologue events fire in context; and the personality/tell system completes the NPC data model.
Branch: client
Agents: Stig (UI/rendering dev), Tyre (architect), Hoshe (QA)
New Tickets
| # | Title | Blocked by |
|---|---|---|
| #71 | Tilemap rendering system | — |
| #72 | Entity sprite system | — |
| #73 | Input capture system | — |
| #74 | Basic UI framework | — |
| #117 | Smooth camera movement | #116 (done) |
Use db/connectors/ticket show <id> for full details.
Key Decisions
decisions/perception.md— D-015 (camera locked to character, fixed-north for v0.1), D-019 (top-down confirmed, ~15-20° from vertical "the angle", sprite art convention not camera setting), D-033 (entity color = relationship to player), D-049 (8-layer z-stack), D-059 (fog shader five layers)decisions/architecture.md— D-020 (Godot client = pure renderer, no game logic in GDScript), D-066 (dual-scale grid: 0.5m simulation, 1m visual, 64x64px visual tile), D-010 (deterministic simulation — client renders what server sends)decisions/perception.md— D-043 (functional warmth art style), D-044 (entity > object > structure visual hierarchy), D-046 (three-reference lighting: Darkwood/BR2049/Hopper), D-056 (insert-styled cursor states)
Notes
-
#71 Tilemap rendering system:
client/scripts/rendering/tile_renderer.gdexists and is referenced inworld_renderer.gdas$FogGroup/FloorTiles(a TileMapLayer node). The current implementation may be a stub — this ticket must deliver: TileMap node with atlas management, multi-layer support for floor/walls/objects matching D-049 z-stack layers 0 (FloorTiles), 1 (FloorObjects), 2 (furniture in YSortGroup). Tile size isConstants.TILE_SIZE(32px visual, per D-066 dual-scale grid where 1 visual tile = 1m = 64x64 source, scaled to 32px runtime). Wall rendering follows D-019 amendment: Option B for structural walls (visible top + face), Option A (boundary lines) for interior partitions. Atlas must accept tiles fromObserverSnapshot.visible_tiles(format:[{x, y, z, type}]).world_renderer.gdalready callstile_renderer.update_tiles(GameState.visible_tiles)— ensureupdate_tiles()is the correct entry point. -
#72 Entity sprite system:
client/scripts/rendering/entity_renderer.gdis substantially implemented — it handles D-033 color derivation (Phase 1 defaults by kind, Phase 2 from RelationshipState), position lerp withLERP_SPEED = 12.0, and 0.5s color fade for relationship transitions (#521). This ticket must validate and complete: ensure all entity kinds fromObserverSnapshot.entitiesrender correctly, including thekind.variantfield dispatching to correct sprite/shape, the 24x32 entity footprint within 64x64 visual tiles (D-044), and y-sort ordering withinYSortGroup. If placeholder shapes (ColorRect) are used, that is correct for v0.1 per D-014. Integration check:world_renderer.gddrives entity updates through the sameupdate_from_state()path — confirm entity renderer is wired there. Follow-mode UI state (#241, server) will need a new field onGameState— stub afollow_target_id: int = -1for when the server ticket lands. -
#73 Input capture system:
client/scripts/autoloads/input_mapper.gdis implemented with WASD movement (D-054 mouse-relative), stance toggles, Interact, and semantic action dispatch.InputMapper.Actionenum covers:MOVE_*(8 directions),INTERACT,USE_PERCEPTION_MODE,OPEN_MENU,PAUSE/UNPAUSE,TOGGLE_STANCE_*,SET_FACING. This ticket must validate the full pipeline: physical key →Actionenum →input_queue→ message serialized and sent to server. Verify: movement throttle per stance (Sprint=5/s, Walk=2.5/s, Careful=1.7/s, Crouch=1.25/s) is active, facing angle updates every frame,InputMappercorrectly suppresses movement whenGameState.dialogue_active == true(D-061 walk-away via WASD). If any semantic actions are stubbed out or missing from the protocol send path, complete them. TheFollowverb (#241 server) will arrive vianearby_interactions— confirm the client can dispatch anInteractaction with a specificresponse_idcorresponding to Follow. -
#74 Basic UI framework:
main.gdreveals the current HUD structure —$UILayer/HUD,$UILayer/MonologueDisplay,$InsertOverlay/InteractionList,$InsertOverlay/DialogueBox,$UILayer/StanceIndicator, and more are already wired. This ticket must ensure the HUD structural layout is complete and stable: monologue display area (top of screen or floating, z-layer 7 per D-049), placeholder area for insert/minimap (D-013, not yet implemented), stance indicator visible, and the overall scene hierarchy matches D-049's 8-layer z-stack. The$InsertOverlayis z-layer 6 (insert overlay),$UILayeris z-layer 7 (UI/monologue). ConfirmGameState.insert_activecontrols visibility of z-layer 6 elements per D-056/D-057 OQ-07 resolution. This is a completion + validation ticket — identify gaps in the existing HUD structure rather than building from scratch. -
#117 Smooth camera movement: Camera lock to character is done (#116) —
camerainmain.gdis aCamera2D._camera_anchoredand_teleport_in_progressflags exist for init sequencing. This ticket adds interpolated camera tracking: instead of snappingcamera.positiontoGameState.player_positioneach frame, use exponential smoothing (same pattern asentity_renderer.gd'sLERP_SPEED). Configurable smoothing: expose a constant or project setting for the smoothing factor. Edge cases to handle — camera must snap immediately on teleport (the_teleport_in_progressflag already exists for exactly this), and must not smooth during initial camera anchor (_camera_anchoredflag). Camera is always fixed-north per D-015 v0.1 scope — no rotation logic.
Dependency Chain
#71 (Tilemap rendering) ─────────────────────────────────────────────┐
#72 (Entity sprite system) ──────────────────────────────────────────┤→ integrated in world_renderer.gd
#73 (Input capture system) → feeds server #241 (Follow), #242 (Examine)│
#74 (Basic UI framework) ────────────────────────────────────────────┘
#117 (Smooth camera) → standalone, parallel track
PR Workflow
When ready to submit, create a PR with the 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(client): sprint 15 react — client deliverables" --description "body" --base main --head client