Files
settled-reach/docs/sprints/sprint-23/client.md
T
jpmschweitzerandClaude Opus 4.6 bccdcfcdcb docs(docs): add frontmatter to all sprint briefings
Standardized YAML frontmatter on all 115 sprint briefing files across
sprints 1-26 with title, description, type, status, sprint number, and
team fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 00:15:45 +01:00

7.8 KiB

title, description, type, status, sprint, team
title description type status sprint team
Sprint 23 — Client Briefing Dialogue speaker colors fix, test failures fix, debug console UI, wall LOS rendering sprint archived 23 client

Sprint 23: Terrain — Client Tasks

Goal: Build the walkable Sova world under the authored content, complete the storyteller engagement layer, and add the debug console — clearing the path to v0.1 integration in Sprint 24.

Branch: client Agents: Stig (UI/rendering), Hoshe (QA)


New Tickets

# Title Blocked by
#573 Dialogue speaker colors are position-based instead of speaker-bound
#574 Pre-existing test failures in test_entity_renderer (test_rendering.gd)
#581 Debug console client: tilde console UI, settings toggle, command dispatch #580 (server)
#585 Walls at LOS boundary: client — render margin tiles correctly through fog #584 (server)

Use tooling/db/ticket show <id> for full descriptions.


Key Decisions

  • decisions/architecture.md — D-020 (ObserverSnapshot is the only data crossing IPC boundary), D-088 (3-state pause — Normal/Overlay/Paused)
  • decisions/content.md — D-033 (entity color = relationship to player; player color set at character creation), D-076 (dialogue box max-width 1200px)
  • decisions/perception.md — D-059 (fog system — 3-state: visible, explored, never-seen)

Notes

#573 — Dialogue speaker colors

What exists: client/ui/dialogue_box.gd renders the dialogue box (D-028, D-076). Speaker colors are currently assigned by position (left speaker = color A, right speaker = color B), which means all left-side speakers share one color and all right-side speakers share another regardless of identity.

What to deliver: Bind speaker color to entity identity, not screen position. The ObserverSnapshot carries entity IDs on dialogue lines (check client/scripts/protocol/protocol.gd _decode_nearby_interaction for the entity_id field on dialogue events). Maintain a Dict[entity_id -> Color] in dialogue_box.gd. On first encounter with an entity ID, assign a color from a palette and store it. Subsequent lines from the same entity reuse the stored color. The palette should be distinct from D-033 relationship colors (those are world-layer entity colors; dialogue colors are UI-layer only).

Non-obvious gotcha: The player character is always one speaker. Assign the player a fixed color (e.g. the character's D-033 color, or a designated white/near-white). NPCs get assigned from the palette on first appearance in the conversation.

#574 — Entity renderer test failures

What exists: client/tests/test_rendering.gd contains test_entity_renderer_* tests that fail on clean main (5aea6e2). Affected: positions_centered, player_color_differs_from_npc, player_uses_d033_color, npc_uses_unknown_teal, object_uses_grey, facing_indicator_rotation_accuracy, regression_345_entity_position_set_from_entity_id_entity.

What to deliver: Fix the failing tests. client/scripts/rendering/entity_renderer.gd likely changed without the tests being updated. Read the renderer to understand the current implementation, then update tests to match (or fix the renderer if it regressed from D-033 spec). Do not change the passing visual golden tests — only fix the unit tests in test_rendering.gd. Run make test-client to verify.

Gotcha: D-033 specifies entity color = relationship to player. If entity_renderer.gd was updated correctly but tests use stale expected values, update the test assertions. If entity_renderer.gd was updated incorrectly and broke D-033 compliance, fix the renderer.

#581 — Debug console client

What exists: client/ui/settings_dialog.gd — existing settings panel with 5-bus audio volume sliders. client/ui/debug_overlay.gd — existing debug overlay tied to OS.is_debug_build() and a debug_overlay input action. client/scripts/main.gd — input routing. client/scripts/protocol/protocol.gdencode_player_input(tick, action_name, action_data) and decode_snapshot().

What to deliver:

  1. client/ui/debug_console.gd + debug_console.tscn — semi-transparent panel (40% screen height, anchored bottom). Input line at bottom, scrollable output log above (50-line buffer). Tilde key (KEY_QUOTELEFT) toggles open/closed. When open, swallows all keyboard input except tilde (no movement commands leak).

  2. Settings integration — add a "Debug Console" checkbox to settings_dialog.gd. Persisted in user://settings.cfg alongside audio volumes. Default: enabled. When disabled, tilde key is inert.

  3. Command parsing and dispatch — parse input as <command> [args...]. Map to DebugCommandKind variants. Serialize via Protocol.encode_player_input('debug_command', { kind: ..., args: ... }). Commands: ticks <n>, contaminate, tp <x> <y> [z], tp <name>, activate, triangle <id>, npc <id>, triangles, pop, status, help.

  4. Response display — read debug_response from the decoded snapshot dict (new optional field from server #580). Format and append to output log. Complex payloads (NPC state, triangle list) displayed as formatted key-value blocks.

  5. Protocol extension — update protocol.gd to encode debug_command action and decode debug_response from snapshot. Bump Protocol.PROTOCOL_VERSION to 18 to match server.

Coordination required: Stig must coordinate with Dudley on the PROTOCOL_VERSION bump (#580 server) before either PR is merged. Client and server PRs must land together or within the same merge window — a version mismatch will crash the connection.

Blocked by: #580 (server must define DebugCommandKind wire format before client serialization is finalized).

#585 — LOS boundary wall rendering

What exists: client/scripts/rendering/tile_renderer.gdupdate_tiles() processes VisibleTile entries from the snapshot. The tile accumulation fix (removed clear() from update_tiles()) means explored tiles stay rendered. client/scripts/autoloads/fog_state.gd — manages exploration state per tile.

What to deliver: Handle the new VisibilitySector::BoundaryWall tiles from server #584. In update_tiles(), detect boundary wall sector tiles and:

  • Render them to the TileMapLayer as wall tiles (so fog has content to composite over)
  • Do NOT record them as explored in fog_state.gd — they are "seen right now" only, not explored
  • Do NOT update the fog exploration texture for these tiles

The visual result: walls at the LOS edge are distinct from fog (they render as wall tiles) but disappear from the map when not in the current LOS cone (they don't leave a memory trace).

Blocked by: #584 (server must send the boundary tiles before client can render them).


Dependency Chain

#573  (speaker color fix)  — standalone
#574  (renderer test fix)  — standalone

#580 (server debug) → #581 (debug console)

#584 (server wall margin) → #585 (client wall margin)

#573 and #574 are fully independent — start immediately. #581 is blocked on server work landing first. #585 is blocked on server #584 landing first.


PR Workflow

tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
  --title "fix(client): bind dialogue speaker colors to entity identity" \
  --description "body" --base main --head client

Sprint Completion (Client Criteria)

  1. Dialogue conversations show consistent per-speaker colors regardless of screen position.
  2. All test_entity_renderer_* tests pass in test_rendering.gd.
  3. Tilde key opens debug console in-game; status command returns contamination state; triangles lists all active triangles.
  4. Debug console toggle visible in Settings menu; persists across restarts.
  5. Walls at LOS edge render as distinct tile content rather than blending into fog.
  6. make test-client green on client branch.