Files
settled-reach/docs/sprints/sprint-11/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

6.6 KiB

title, description, type, status, sprint, team
title description type status sprint team
Sprint 11 — Client Briefing WRONG button full captures, OQ-07 no-insert interaction resolution sprint archived 11 client

Sprint 11: Combine — Client Tasks

Goal: Complete the Gauntlet test matrix with final interaction-combination rooms and cross-room scenarios, deliver the WRONG-button bug-capture system, resolve open implementation questions OQ-07 and OQ-18, and add contraband detection — hardening the system as a fully covered, testable unit.

Branch: client Agents: Stig (UI/client dev), Tyre (arch review), Hoshe (QA)


New Tickets

# Title Blocked by
#507 WRONG button full captures (input history ring buffer, snapshot history, replay seed) #495 (done)
#522 Resolve OQ-07: no-insert interaction behavior (diegetic test)

Use db/connectors/ticket show <id> for full details.


Key Decisions

  • decisions/architecture.md — D-020 (Godot/Rust IPC, ObserverSnapshot as the only data crossing the boundary), D-030 (testability architecture — JSON output format for bug reports)
  • decisions/perception.md — D-056 (cursor states — insert-styled geometric, diegetic test: labels render on z-layer 6, disappear if insert is off), D-057 (entity interaction — vertical list, diegetic test referenced), D-048 (neural insert overlay — visual design)

Open Questions to Resolve Early

  • OQ-07 (#522): No-insert interaction behavior — Resolve early (day 1-2) because the answer determines whether #507's WRONG button output includes cursor-state data in the capture, and whether the entity interaction system (#432) needs a code path for insert-off mode. Three candidate resolutions: (a) cursor reverts to default shape only, no verb labels; (b) cursor does not change at all; (c) non-insert fallback renders prompts via alternative channel. Resolve, document as a decision amendment to D-056 or D-057, then implement.

Notes

#507 — WRONG button full captures (input history ring buffer, snapshot history, replay seed)

  • Existing: The WRONG button MVP (#495, done Sprint 9) is in place as a bug_report.gd autoload. F12 pauses, captures a single ObserverSnapshot (JSON), runs the text renderer, saves tick/room/seed and a tester description to tests/bug-reports/gauntlet-t{tick}-{timestamp}/. The MVP is a single-tick point-in-time capture.
  • Deliver: Upgrade the bug capture system to a rolling 60-tick history:
    • Input history ring buffer: Maintain a 60-entry circular buffer of PlayerInput arrays in bug_report.gd. Every tick, push the current tick's input(s) onto the buffer (oldest entry evicted when full). On F12 capture, flush the last 60 ticks of inputs to inputs.jsonl (one JSON array per line — matches the replay format from tooling/test-client/src/replay.rs).
    • Snapshot history: Maintain a parallel 60-entry circular buffer of ObserverSnapshot JSON strings. Flush to snapshots.jsonl on capture (one snapshot per line). Allows replay of the exact 60-tick window leading to the bug.
    • Replay seed: Include the server's current RNG seed in the capture output (requires the server to send the seed in the ObserverSnapshot or via a metadata message). Output as seed.txt in the bug report directory.
    • Room metadata: Already present in MVP — confirm it includes the room name and map identifier.
    • Output directory format is unchanged: tests/bug-reports/gauntlet-t{tick}-{timestamp}/.
  • Integration: The inputs.jsonl output must be valid input for tooling/test-client --replay <file> (Sprint 10 #483). Test this by replaying a captured session against a fresh server — it should reproduce the same snapshot sequence.
  • The ring buffer must add negligible per-tick cost — pre-allocate the 60-slot arrays at startup. Do not allocate on every tick.
  • Non-obvious: The server RNG seed may need a new field in ObserverSnapshot or a dedicated handshake message. Coordinate with the server team if a protocol change is needed. If the seed is already present in an existing field, document which field.

#522 — Resolve OQ-07: no-insert interaction behavior (diegetic test)

  • Existing: D-056 cursor states and D-057 entity interaction both reference the diegetic test: interaction labels render on z-layer 6 (insert overlay) and disappear if the insert is off. client/scripts/rendering/cursor_renderer.gd handles cursor state transitions. The entity interaction vertical list is in client/scripts/rendering/ (likely entity_renderer.gd or a dedicated interaction UI file, per #432).
  • Deliver: Resolve OQ-07 with one of three options, implement, and document:
    • (a) Cursor reverts to default shape only, no verb labels — cursor state machine still fires (shape changes: default → entity hover bracket or X-shape on object hover), but the tooltip/verb label layer is suppressed because z-layer 6 (insert overlay) has no data to render. This is the most diegetically consistent option: the character still physically orients to the target, but receives no information from their insert.
    • (b) Cursor does not change at all — insert-off mode means the cursor_renderer.gd stays in Default state regardless of what the cursor is over. Full suppression.
    • (c) Non-insert fallback — prompts appear via a non-insert visual channel (e.g., world-space text at z-layer 2 or 3). Least diegetically consistent; least likely to be the right answer given D-056's "diegetic test" framing.
    • After resolution: amend the relevant decision (D-056 or D-057) with the OQ-07 resolution note, and update client/scripts/rendering/cursor_renderer.gd and the interaction list renderer to enforce the chosen behavior when insert_active == false.
  • This is primarily a design resolution + small implementation task. Effort: 0.5d for decision, up to 0.5d for code.

Dependency Chain

#507 (WRONG button full captures) — standalone (#495 done), parallel
#522 (OQ-07 resolution) — standalone, resolve day 1-2

Both tickets are independent. No cross-team blockers. Client can run both tracks in parallel from day 1.

Watch: If #507 requires a new field on ObserverSnapshot for the RNG seed, that is a server protocol change. Raise with the server team immediately — do not wait until the ticket is otherwise complete.


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(client): sprint 11 combine — client" \
  --description "body" --base main --head client