Commit Graph
4 Commits
Author SHA1 Message Date
jpmschweitzerandClaude ae03ea2de7 perf(ui): Atlas deep rungs draw one gridunit per 2x2 px block
DISPLAY_RATIO_DEEP 1.0 -> 2.0, so a viewport-fit request at District/
Quarter/Block/Chunk asks for ~4x fewer gridunits (1920x1080: ~2.07M
cells -> ~518K) and the server-side derive cost falls with it. Texel-
exactness is preserved — the ratio stays a whole number of screen px
per gridunit, so every source texel still lands on whole pixels; only
the block size changes. Non-integer ratios are not an option here:
they reintroduce exactly the sub-pixel blur D-255's texel-exactness
exists to prevent.

Judged live by Jeroen against the 1x1 build (pair session): the deep
rungs read as crisp larger pixels rather than blur, and the speedup is
substantial. Looks were the gate.

Both transport tests that pinned the old literal now assert the
RELATIONSHIP instead — deep rungs share the constant, viewport-fit
divides by it — plus a new guard that the ratio stays whole, so the
value remains tunable without editing tests that are not about it.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-26 17:11:44 +02:00
jpmschweitzerandClaude Fable 5 374b195594 fix(ui): PR #205 review round — integer px-per-gridunit fit replaces fractional (T-1189, T-1192)
The fractional fit branch is deleted, resolving both review findings at
the root: tyre showed its comments cited D-255 for an exception the
record does not contain (the language came from the lead's ticket text,
not governance), and hoshe showed it returned sub-1x for a canvas
exceeding the viewport on one axis. Replacement: fit_scale_ratio()
chooses the largest integer pixels-per-gridunit R fitting both
legend-reserved axes, floored at 1 (over-viewport draws native and
crops like every fixed rung) — the fine-grained integer lattice (GJ1c
1080p -> 9px/gu = 1593x792, ~98% width; 4K -> 20) that makes the
fractional hatch unnecessary. center_offset() floors to whole pixels
(half-pixel centering would blur the texel grid). Doc comments cite the
real sanction (D-255 amendment 2026-07-25, this branch). Legend column
constant is now canonical in transport, read directly by the legend
(was an independently-typed literal); its test asserts real geometry.
New regression test proves _global_body_extent clears on body switch
and never caps another body's requests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:14:12 +02:00
jpmschweitzerandClaude Fable 5 c1a97166c5 feat(ui): cap rung extents to the body + fit/center the Global canvas (T-1189, T-1192)
The two client fixes for the Atlas frames Jeroen flagged. Region rung no
longer requests more planet than exists: cap_extent_to_body() caps the
viewport-fit extent at the body's own region grid (the Global canvas
extent echo — cols=regions_per_equator, rows=cols/2), matched by gridunit
SPACING not rung name, applied before the request/cache key is built;
cold-start scroll-before-Global-echo requests uncapped and lets the
server clamp (documented). Kills both the side-by-side continent repeat
and the past-the-pole stripe smear.

Global opener now fit-scales and centers through one shared letterbox
mechanism (center_offset/integer_fit_scale/fit_scale, 75%-coverage
integer-vs-fractional decision, NEAREST already forced on orbital rungs
per D-255's escape hatch) also used for the Region cap's letterbox
remainder. Legend column reserved before fitting — pinned to the legend's
own width by a cross-constant test, never overlapping the canvas.

Also fixes a latent crash: NOTIFICATION_RESIZED fires mid-_ready() before
children exist; null guard in the resize path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 12:52:06 +02:00
jpmschweitzerandClaude Fable 5 d28d24fd26 feat(ui): step-canvas map component — RTT terrain + stepped zoom (D-255, T-1182)
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>
2026-07-25 08:53:48 +02:00