feat(ui): step-canvas map component — RTT terrain + stepped zoom (D-255, T-1182) #203

Closed
jpmschweitzer wants to merge 0 commits from t1182-client-map into main
Owner

Summary

The two-layer client rebuild per D-255(a)(b)(e), replacing the _canvas.scale continuous-zoom model with one viewer, one path, all six rungs. Net -9,400 lines.

  • step_canvas_protocol.gd: the T-1181 wire codec — incl. a discovered wire subtlety (rmp_serde without serde_bytes emits png_bytes as a msgpack int-array, not bin; verified against rmp_serde dispatch, repacked before Image.load_png_from_buffer) and the extent-echo rule (read the server-clamped extent, never assume the requested one).
  • step_canvas/ component: six-rung transport (cursor-anchored scroll steps, edge-scroll/WASD pan with edge-crossing re-request, hard reset-to-Global), RTT terrain layer (Image.set_pixel colorize per the c1 measured ruling, texture.update reuse, NEAREST coarse / LINEAR fine), unscaled screen-space annotation sibling (courses + markers at literal px), in-memory LRU (Tier 1; T-1183 layers disk beneath), request lifecycle with pending-hold (no blank frames).
  • Full _canvas.scale retirement in the same change: 10 source files + 14 dead test suites deleted (T-1157 dead-goldens rule; replacement visual-capture coverage owed under re-scoped T-1157).
  • Surviving surfaces kept per ticket — with one documented correction: the real LRU shape lives in atlas_window_cache.gd (kept, cited), not the retiring orchestrator atlas_window_tile_set.gd the ticket text named.

Verification

  • 7 new gdUnit suites (164 cases) — including a real extent-echo bug caught by its own test during implementation. Full client suite green through the gate (3,452 passed / 0 failed) with the SR_LIVE-gated suites RUNNING (worktree server built — a fresh-worktree pitfall diagnosed this session: no server binary -> live suites skip -> gdUnit orphan exit 101).
  • tooling/godot-cold-parse --run-menu: clean (autoload parse-order rule honored in the sim_bridge.gd edits).
  • Paired-set screenshot eyeball (cold server, main vs branch, incl. the lake window) queued next — merge waits on its verdict.

What you will SEE

Opening a body lands on the whole-body Global view; the wheel walks six discrete cursor-anchored steps down to 64 m Chunk; terrain is texel-exact, annotations constant-px; the previous step holds with a pending wash while the next loads. Not yet: disk cache (T-1183), step-cross tween (optional cosmetic), footprint-true settlement markers (server approximation inherited).

🤖 Generated with Claude Code

## Summary The two-layer client rebuild per D-255(a)(b)(e), replacing the _canvas.scale continuous-zoom model with one viewer, one path, all six rungs. Net -9,400 lines. - step_canvas_protocol.gd: the T-1181 wire codec — incl. a discovered wire subtlety (rmp_serde without serde_bytes emits png_bytes as a msgpack int-array, not bin; verified against rmp_serde dispatch, repacked before Image.load_png_from_buffer) and the extent-echo rule (read the server-clamped extent, never assume the requested one). - step_canvas/ component: six-rung transport (cursor-anchored scroll steps, edge-scroll/WASD pan with edge-crossing re-request, hard reset-to-Global), RTT terrain layer (Image.set_pixel colorize per the c1 measured ruling, texture.update reuse, NEAREST coarse / LINEAR fine), unscaled screen-space annotation sibling (courses + markers at literal px), in-memory LRU (Tier 1; T-1183 layers disk beneath), request lifecycle with pending-hold (no blank frames). - Full _canvas.scale retirement in the same change: 10 source files + 14 dead test suites deleted (T-1157 dead-goldens rule; replacement visual-capture coverage owed under re-scoped T-1157). - Surviving surfaces kept per ticket — with one documented correction: the real LRU shape lives in atlas_window_cache.gd (kept, cited), not the retiring orchestrator atlas_window_tile_set.gd the ticket text named. ## Verification - 7 new gdUnit suites (164 cases) — including a real extent-echo bug caught by its own test during implementation. Full client suite green through the gate (3,452 passed / 0 failed) with the SR_LIVE-gated suites RUNNING (worktree server built — a fresh-worktree pitfall diagnosed this session: no server binary -> live suites skip -> gdUnit orphan exit 101). - tooling/godot-cold-parse --run-menu: clean (autoload parse-order rule honored in the sim_bridge.gd edits). - Paired-set screenshot eyeball (cold server, main vs branch, incl. the lake window) queued next — merge waits on its verdict. ## What you will SEE Opening a body lands on the whole-body Global view; the wheel walks six discrete cursor-anchored steps down to 64 m Chunk; terrain is texel-exact, annotations constant-px; the previous step holds with a pending wash while the next loads. Not yet: disk cache (T-1183), step-cross tween (optional cosmetic), footprint-true settlement markers (server approximation inherited). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer added 2 commits 2026-07-25 08:57:14 +02:00
The two-layer client rebuild per D-255(a)(b)(e), replacing the
_canvas.scale continuous-zoom model with one viewer, one path, all six
rungs:

- step_canvas_protocol.gd: StepCanvasRequest/Response codec against
  the T-1181 wire contract — incl. the discovered png_bytes subtlety
  (rmp_serde without serde_bytes emits a msgpack int-array, not bin;
  decode repacks via PackedByteArray before load_png_from_buffer) and
  the extent-echo rule (read the server-clamped extent, never assume
  the requested one).
- step_canvas/ component: transport (six-rung ladder, cursor-anchored
  scroll steps, edge-scroll/WASD pan with re-request on edge crossing,
  hard reset-to-Global), RTT terrain layer (Image.set_pixel colorize
  per the c1 measured ruling, texture.update reuse on step-cross,
  NEAREST coarse / LINEAR fine per rung), unscaled screen-space
  annotation sibling (courses + settlement markers at literal px),
  in-memory LRU cache (Tier 1; T-1183 layers the disk tiers beneath),
  request lifecycle (pending retry, staleness gate, extent echo).
- Full _canvas.scale retirement in the same change: the zoom-scaled
  canvas model, the _zs compensation family, select_rung /
  MAX_COVERAGE_M / compute_tile_grid, the orbital-mosaic-vs-window
  two-path split, _view_zoom/_canonical_fit_zoom — 10 source files
  deleted; their 14 test suites deleted with them (T-1157 dead-goldens
  rule; replacement visual-capture coverage is re-scoped T-1157).
- Surviving surfaces kept per the ticket: atlas_window_cache.gd's LRU
  shape (the ticket's named file atlas_window_tile_set.gd was the
  retiring orchestrator; the real LRU shape lives in
  atlas_window_cache.gd — cited in step_canvas_cache.gd), overlay
  colors, legend/overlay-bar chrome, AtlasViewer descend geometry.

Determinism boundary per D-255(e): the client interpolates only within
the closed server-supplied input set. 7 new gdUnit suites (164 cases)
incl. a real extent-echo bug caught by its own test during
implementation. Full client suite green (exit 0) with the live-gated
suites running against a worktree server build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jpmschweitzer added 1 commit 2026-07-25 09:35:06 +02:00
Tyre finding: the orphaned AtlasViewer cluster is now actually deleted
(atlas_viewer, atlas_marker_overlay, atlas_descend_geometry,
atlas_legend_panel — a sixth orphan found beyond the review list —
atlas_generation_proxy, atlas_generation_state; ~2,497 lines), with
reachability re-verified across preload/class_name/res:// strings,
every .tscn, and the standalone companion app. Test suites triaged,
not blanket-deleted: 5 pure AtlasOverlayColors tests relocated into
test_atlas_window_colors, the live type-identity regression guard
relocated into test_step_canvas_viewer, dead coverage deleted. A real
harness gap surfaced during diligence and RULED, not patched:
visual_scenarios/visual_capture golden shots call retired
continuous-zoom API — no shim (would resurrect what D-255 kills);
inventory recorded on re-scoped T-1157 (gate-invisible, manual
targets only).

Hoshe finding 1: decode_png_field now detects the [Error,
PackedByteArray] bin-shape from messagepack.gd explicitly — a genuine
msgpack bin payload decodes correctly instead of silently collapsing
to [0,0]; test built from a real round-tripped bin decode.

Hoshe finding 2: the hard zoom-out reset is wired — ascend at rung 0
with a drifted view triggers _reset_to_global (the restored HARD
condition), behavioral tests through the real input path.

Notes folded: refloat + edge-scroll test coverage, legend smoke suite,
Vector2i narrowing-safety comment with computed headroom.

gdlint clean on touched files; full client suite 3364/3364.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

Review: t1182-client-map -> main (type: code, client)

Tyre (Architecture): REQUEST_CHANGES (1 finding — fixed)

D-255(e) verified clean — the component is a genuinely pure map-art function (server-sourced RTT colorize, unscaled annotations, no per-pixel invention; LINEAR filter correctly scoped as sanctioned texture-to-viewport resize) and the five-item retirement executed correctly inside the reachable path, with load-bearing doc comments throughout. Finding: ~3,600 lines of the AtlasViewer/_canvas.scale/_view_zoom cluster survived fully ORPHANED (zero production entry points — the orbital view is system_screen's own drawing), contradicting the one-viewer-one-path claim, plus ~1,300 lines of tests exercising the orphaned surface (the T-1157 dead-goldens anti-pattern).

Hoshe (Code Quality): REQUEST_CHANGES (2 findings — fixed)

Verified solid: D-243 spacing table matches scale.rs exactly, demux ordering provably safe, extent-echo + cache-key discipline mirror the server, deletion of the original 10 files clean, sim_bridge autoload edit follows the parse-order rule.

# File Issue
1 step_canvas_protocol.gd (decode_png_field) Silent byte-loss on genuine msgpack bin payloads: messagepack.gd's bin path returns [Error, PackedByteArray], which passes the Array guard and collapses to [0,0] — latent until a future serde_bytes annotation, then corrupts every texture silently.
2 step_canvas_viewer.gd (_reset_to_global) The documented hard zoom-out reset is dead code — zero production callers; regresses the explicit HARD condition the retired viewer honored.

Notes: refloat/edge-scroll/legend coverage gaps; Vector2i narrowing comment.

Author response — all fixed in 76d82a6a5

Tyre: reachability independently re-verified (incl. .tscn/string paths and the standalone app — surfaces the original grep could not see), then the cluster deleted TOTALLY: six files (~2,497 lines — a sixth orphan, atlas_legend_panel.gd, found beyond the review list). Test suites triaged, not blanket-deleted: 5 pure AtlasOverlayColors tests relocated into test_atlas_window_colors, the live type-identity regression guard relocated into test_step_canvas_viewer, dead coverage deleted. One REAL gap surfaced during diligence and RULED rather than patched: visual_scenarios/visual_capture golden shots (6 of 12, gate-invisible manual targets) call retired continuous-zoom API — no shim (would resurrect exactly what D-255 kills); full inventory recorded on re-scoped T-1157, which owns the (body, rung)-keyed harness redesign.

Hoshe 1: the [Error, PackedByteArray] bin-shape is now detected explicitly; test built from a REAL round-tripped bin decode (would have caught the original bug).

Hoshe 2: wired — ascend at rung 0 with a drifted view triggers _reset_to_global (new _is_global_view_drifted guard); behavioral tests through the real input path, plus the no-op case.

Notes: 4 refloat tests, 5 edge-scroll tests, a 10-test legend smoke suite, and the narrowing-safety comment with computed headroom — all folded, no parking lot.

Cold-parse clean post-deletion; full client suite 3,364/3,364 through the gate on re-push.

Screenshot eyeball: PASS (all four gates)

Cold start clean (Global fully drawn before 2s); the six-rung ladder walkthrough lands coherently with constant-px annotations and visible pending-hold; world-content agreement with the old viewer confirmed at the Arbour lake; untouched orbital screens byte-identical (AE=0). Rung-ladder capture set: .cache/screenshots/t1182-eyeball/rung-ladder/. Two non-blocking findings ticketed: T-1188 (blocky lake shorelines — server-side tone/refinement question, not viewer plumbing), T-1189 (Region-rung longitude wrap on small bodies).

Verdict: CHANGES REQUESTED -> resolved; merging (after PR #202, which holds the queue's outlet-stub check)

## Review: t1182-client-map -> main (type: code, client) ### Tyre (Architecture): REQUEST_CHANGES (1 finding — fixed) D-255(e) verified clean — the component is a genuinely pure map-art function (server-sourced RTT colorize, unscaled annotations, no per-pixel invention; LINEAR filter correctly scoped as sanctioned texture-to-viewport resize) and the five-item retirement executed correctly inside the reachable path, with load-bearing doc comments throughout. Finding: ~3,600 lines of the AtlasViewer/_canvas.scale/_view_zoom cluster survived fully ORPHANED (zero production entry points — the orbital view is system_screen's own drawing), contradicting the one-viewer-one-path claim, plus ~1,300 lines of tests exercising the orphaned surface (the T-1157 dead-goldens anti-pattern). ### Hoshe (Code Quality): REQUEST_CHANGES (2 findings — fixed) Verified solid: D-243 spacing table matches scale.rs exactly, demux ordering provably safe, extent-echo + cache-key discipline mirror the server, deletion of the original 10 files clean, sim_bridge autoload edit follows the parse-order rule. | # | File | Issue | |---|------|-------| | 1 | step_canvas_protocol.gd (decode_png_field) | Silent byte-loss on genuine msgpack bin payloads: messagepack.gd's bin path returns [Error, PackedByteArray], which passes the Array guard and collapses to [0,0] — latent until a future serde_bytes annotation, then corrupts every texture silently. | | 2 | step_canvas_viewer.gd (_reset_to_global) | The documented hard zoom-out reset is dead code — zero production callers; regresses the explicit HARD condition the retired viewer honored. | Notes: refloat/edge-scroll/legend coverage gaps; Vector2i narrowing comment. ## Author response — all fixed in 76d82a6a5 **Tyre**: reachability independently re-verified (incl. .tscn/string paths and the standalone app — surfaces the original grep could not see), then the cluster deleted TOTALLY: six files (~2,497 lines — a sixth orphan, atlas_legend_panel.gd, found beyond the review list). Test suites triaged, not blanket-deleted: 5 pure AtlasOverlayColors tests relocated into test_atlas_window_colors, the live type-identity regression guard relocated into test_step_canvas_viewer, dead coverage deleted. One REAL gap surfaced during diligence and RULED rather than patched: visual_scenarios/visual_capture golden shots (6 of 12, gate-invisible manual targets) call retired continuous-zoom API — no shim (would resurrect exactly what D-255 kills); full inventory recorded on re-scoped T-1157, which owns the (body, rung)-keyed harness redesign. **Hoshe 1**: the [Error, PackedByteArray] bin-shape is now detected explicitly; test built from a REAL round-tripped bin decode (would have caught the original bug). **Hoshe 2**: wired — ascend at rung 0 with a drifted view triggers _reset_to_global (new _is_global_view_drifted guard); behavioral tests through the real input path, plus the no-op case. **Notes**: 4 refloat tests, 5 edge-scroll tests, a 10-test legend smoke suite, and the narrowing-safety comment with computed headroom — all folded, no parking lot. Cold-parse clean post-deletion; full client suite 3,364/3,364 through the gate on re-push. ## Screenshot eyeball: PASS (all four gates) Cold start clean (Global fully drawn before 2s); the six-rung ladder walkthrough lands coherently with constant-px annotations and visible pending-hold; world-content agreement with the old viewer confirmed at the Arbour lake; untouched orbital screens byte-identical (AE=0). Rung-ladder capture set: .cache/screenshots/t1182-eyeball/rung-ladder/. Two non-blocking findings ticketed: T-1188 (blocky lake shorelines — server-side tone/refinement question, not viewer plumbing), T-1189 (Region-rung longitude wrap on small bodies). ### Verdict: CHANGES REQUESTED -> resolved; merging (after PR #202, which holds the queue's outlet-stub check)
jpmschweitzer closed this pull request 2026-07-25 10:39:14 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jpmschweitzer/settled-reach#203