Live round 2 (the real bug): every nature-overlay marker size was a raw screen-space constant drawn inside _canvas, whose scale IS view_zoom — at Lendel's orbital fit zoom (0.0063) a 2.2px trunk dot rendered at ~0.014px, invisible; the same code at District's 3.75 zoom produced the correctly-visible mouth ring, which is why one capture worked and the headline rung didn't. Fixed via AtlasWindowGeometry.zoom_compensated_ size() (pure, floor-guarded) wired through every radius/line-width; basin FILL points are positions and correctly stay unscaled. Suspect tile-mode-rung-detection was ruled out live (granularity_v2=Region confirmed in tile mode) but pinned with a named regression test anyway. +8 pure-function tests incl. a numeric pin of the pre-fix magnitude (<0.02px at orbital zoom); revert-verified by name. Draw-smoke suite documented as supplementary (the shared SubViewport background harness can pass vacuously under X11 BadMatch — the pure suite is the gate). Live round 3 (drive-script bug, no product change): the lead's scratch drive passed the button LABEL to set_overlay_visible() and the unknown- id guard silently no-op'd — but the chase banked a real pin: test_set_overlay_visible_gen_basins_flips_gate_and_redraws_nature_ overlay (draw-counting spy per the cold-start precedent; is_queued_for_ redraw does not exist in this build). Revert-verified. Basins verified live: 7 Lendel watershed boundaries render at the ruling's alphas. Suites: viewer 76/76, geometry-nature 42/42, nature- overlay 22/22, zoom-ladder 50/50, no regressions across the cluster. Tickets: T-1156 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
284 lines
13 KiB
GDScript
284 lines
13 KiB
GDScript
## T-1156 wave 1: pure-function tests for AtlasWindowGeometry's Layer-1
|
|
## nature-overlay pixel mapping (layer1_pixel_to_world_m/world_m_to_district/
|
|
## layer1_pixel_to_canvas_local) and per-rung visibility/filter policy
|
|
## (river_class_visible_at_rung/confluences_visible_at_rung/
|
|
## mouths_visible_at_rung/basins_visible_at_rung/attractors_visible_at_rung).
|
|
## Split from test_atlas_window_geometry.gd (already close to the gdlint
|
|
## max-file-lines cap) — same file-per-concern precedent as
|
|
## test_atlas_window_colors.gd being separate from test_atlas_window_overlay.gd.
|
|
class_name TestAtlasWindowGeometryNature
|
|
extends GdUnitTestSuite
|
|
|
|
const AtlasWindowGeometry := preload("res://ui/implant/apps/atlas/atlas_window_geometry.gd")
|
|
|
|
const CELL_PIXEL_SIZE: float = 16.0
|
|
const DISTRICT_M: float = 2048.0
|
|
|
|
|
|
# =============================================================================
|
|
# layer1_pixel_to_world_m — the forward mirror of
|
|
# server/src/atlas/district_profile.rs's pixel_to_world_m(), verified against
|
|
# that function's source directly (not assumed).
|
|
# =============================================================================
|
|
|
|
|
|
## Column 0 is world/longitude 0 on every body — no -0.5 centering, unlike
|
|
## rows (longitude wraps and has no "half" concept the way latitude does).
|
|
func test_layer1_pixel_to_world_m_col_zero_is_world_x_zero() -> void:
|
|
var w: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(0.0, 0.0, 256.0, 128.0, 6371.0)
|
|
assert_float(w.x).is_equal_approx(0.0, 0.001)
|
|
|
|
|
|
## Row 0 is the NORTH POLE — server's own comment: `lat_frac = -0.5 = N pole`
|
|
## — which the forward map resolves to the MOST NEGATIVE wy (world Y
|
|
## increases southward, matching AtlasDescendGeometry.district_pos_at()'s own
|
|
## row-increases-southward convention on the inverse side of this mapping).
|
|
func test_layer1_pixel_to_world_m_row_zero_is_north_pole_negative_wy() -> void:
|
|
var radius_km := 6371.0
|
|
var grid_h := 128.0
|
|
var w: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(0.0, 0.0, 256.0, grid_h, radius_km)
|
|
var meridian_m: float = PI * radius_km * 1000.0
|
|
assert_float(w.y).is_equal_approx(-0.5 * meridian_m, 1.0)
|
|
|
|
|
|
## Row (grid_h - 1) is the SOUTH POLE — `lat_frac = +0.5 = S` — the most
|
|
## POSITIVE wy, the opposite extreme from row 0.
|
|
func test_layer1_pixel_to_world_m_last_row_is_south_pole_positive_wy() -> void:
|
|
var radius_km := 6371.0
|
|
var grid_h := 128.0
|
|
var w: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(
|
|
grid_h - 1.0, 0.0, 256.0, grid_h, radius_km
|
|
)
|
|
var meridian_m: float = PI * radius_km * 1000.0
|
|
assert_float(w.y).is_equal_approx(0.5 * meridian_m, 1.0)
|
|
|
|
|
|
## The equator row (grid_h / 2, approximately — the exact half-height pixel)
|
|
## is world Y ~0 — halfway between the two poles. Not EXACT (the denominator
|
|
## is grid_h - 1 = 127, not 128), so the tolerance is loose (200km).
|
|
func test_layer1_pixel_to_world_m_mid_row_is_near_equator() -> void:
|
|
var w: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(64.0, 0.0, 256.0, 128.0, 6371.0)
|
|
assert_float(w.y).is_equal_approx(0.0, 200_000.0)
|
|
|
|
|
|
## Column at grid_w (a full wrap) must equal the FULL circumference — the
|
|
## wrap point, matching longitude's periodic (not clamped) treatment.
|
|
func test_layer1_pixel_to_world_m_full_width_col_is_full_circumference() -> void:
|
|
var radius_km := 6371.0
|
|
var grid_w := 256.0
|
|
var w: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(0.0, grid_w, grid_w, 128.0, radius_km)
|
|
var circumference_m: float = TAU * radius_km * 1000.0
|
|
assert_float(w.x).is_equal_approx(circumference_m, 5.0)
|
|
|
|
|
|
## No-radius (tiny test body): 1 heightmap pixel = 1 DISTRICT_M metre exactly
|
|
## — matching pixel_to_world_m()'s own no-radius fallback and
|
|
## AtlasDescendGeometry.district_pos_at()'s no-radius branch on the inverse side.
|
|
func test_layer1_pixel_to_world_m_no_radius_is_one_pixel_one_district_m() -> void:
|
|
var w: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(3.0, 5.0, 64.0, 64.0, 0.0)
|
|
assert_that(w).is_equal(Vector2(5.0 * DISTRICT_M, 3.0 * DISTRICT_M))
|
|
|
|
|
|
## Degenerate grid dims (grid_w/grid_h <= 0) must not divide-by-zero or crash.
|
|
func test_layer1_pixel_to_world_m_zero_grid_dims_returns_zero() -> void:
|
|
var w: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(1.0, 1.0, 0.0, 0.0, 6371.0)
|
|
assert_that(w).is_equal(Vector2.ZERO)
|
|
|
|
|
|
# =============================================================================
|
|
# world_m_to_district — one division by DISTRICT_M, sub-district precision
|
|
# preserved (not rounded).
|
|
# =============================================================================
|
|
|
|
|
|
func test_world_m_to_district_divides_by_district_m() -> void:
|
|
var d: Vector2 = AtlasWindowGeometry.world_m_to_district(Vector2(DISTRICT_M * 3.5, DISTRICT_M * -2.25))
|
|
assert_that(d).is_equal_approx(Vector2(3.5, -2.25), Vector2.ONE * 0.001)
|
|
|
|
|
|
# =============================================================================
|
|
# layer1_pixel_to_canvas_local — the full composition, cross-checked against
|
|
# district_to_canvas_local() called manually with the same intermediate value.
|
|
# =============================================================================
|
|
|
|
|
|
## A river pixel at the held window's own center district must land at
|
|
## canvas-local half-extent — same invariant
|
|
## test_district_to_canvas_local_center_district_lands_at_half_extent()
|
|
## pins for the district-space function this one wraps.
|
|
func test_layer1_pixel_to_canvas_local_matches_manual_composition() -> void:
|
|
var radius_km := 6371.0
|
|
var grid_w := 256.0
|
|
var grid_h := 128.0
|
|
var held_center := Vector2i(10, 20)
|
|
var held_n := 64
|
|
var row := 40.0
|
|
var col := 80.0
|
|
|
|
var result: Vector2 = AtlasWindowGeometry.layer1_pixel_to_canvas_local(
|
|
row, col, grid_w, grid_h, radius_km, held_center, held_n, CELL_PIXEL_SIZE
|
|
)
|
|
|
|
var world_m: Vector2 = AtlasWindowGeometry.layer1_pixel_to_world_m(
|
|
row, col, grid_w, grid_h, radius_km
|
|
)
|
|
var district: Vector2 = AtlasWindowGeometry.world_m_to_district(world_m)
|
|
var expected: Vector2 = AtlasWindowGeometry.district_to_canvas_local(
|
|
district, held_center, held_n, CELL_PIXEL_SIZE
|
|
)
|
|
assert_that(result).is_equal_approx(expected, Vector2.ONE * 0.001)
|
|
|
|
|
|
# =============================================================================
|
|
# Per-rung river-class visibility (Araminta's ruling, 2026-07-23) —
|
|
# river_class_visible_at_rung()
|
|
# =============================================================================
|
|
|
|
|
|
func test_river_class_visible_at_rung_region_shows_every_class() -> void:
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(AtlasWindowGeometry.RIVER_CLASS_STREAM, "Region")
|
|
).is_true()
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(
|
|
AtlasWindowGeometry.RIVER_CLASS_TRIBUTARY, "Region"
|
|
)
|
|
).is_true()
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(AtlasWindowGeometry.RIVER_CLASS_TRUNK, "Region")
|
|
).is_true()
|
|
|
|
|
|
func test_river_class_visible_at_rung_district_shows_trunk_only() -> void:
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(
|
|
AtlasWindowGeometry.RIVER_CLASS_STREAM, "District"
|
|
)
|
|
).is_false()
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(
|
|
AtlasWindowGeometry.RIVER_CLASS_TRIBUTARY, "District"
|
|
)
|
|
).is_false()
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(AtlasWindowGeometry.RIVER_CLASS_TRUNK, "District")
|
|
).is_true()
|
|
|
|
|
|
func test_river_class_visible_at_rung_quarter_shows_nothing() -> void:
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(AtlasWindowGeometry.RIVER_CLASS_STREAM, "Quarter")
|
|
).is_false()
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(
|
|
AtlasWindowGeometry.RIVER_CLASS_TRIBUTARY, "Quarter"
|
|
)
|
|
).is_false()
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(AtlasWindowGeometry.RIVER_CLASS_TRUNK, "Quarter")
|
|
).is_false()
|
|
|
|
|
|
## An unrecognized rung tag falls back to Region's fullest visibility set —
|
|
## the cluster's existing "unrecognized -> safest/most permissive already-
|
|
## shipped behavior" posture.
|
|
func test_river_class_visible_at_rung_unknown_tag_falls_back_to_region() -> void:
|
|
assert_bool(
|
|
AtlasWindowGeometry.river_class_visible_at_rung(AtlasWindowGeometry.RIVER_CLASS_STREAM, "Bogus")
|
|
).is_true()
|
|
|
|
|
|
# =============================================================================
|
|
# Feature-group per-rung gates — confluences/mouths/basins/attractors.
|
|
# =============================================================================
|
|
|
|
|
|
func test_confluences_visible_at_rung_region_true_others_false() -> void:
|
|
assert_bool(AtlasWindowGeometry.confluences_visible_at_rung("Region")).is_true()
|
|
assert_bool(AtlasWindowGeometry.confluences_visible_at_rung("District")).is_false()
|
|
assert_bool(AtlasWindowGeometry.confluences_visible_at_rung("Quarter")).is_false()
|
|
|
|
|
|
## Mouths get the one rung-based EXCEPTION in the whole table: District keeps
|
|
## them visible (a mouth is always a landmark, per the ruling) — the only
|
|
## feature group where District differs from Region's disposition.
|
|
func test_mouths_visible_at_rung_region_and_district_true_quarter_false() -> void:
|
|
assert_bool(AtlasWindowGeometry.mouths_visible_at_rung("Region")).is_true()
|
|
assert_bool(AtlasWindowGeometry.mouths_visible_at_rung("District")).is_true()
|
|
assert_bool(AtlasWindowGeometry.mouths_visible_at_rung("Quarter")).is_false()
|
|
|
|
|
|
func test_basins_visible_at_rung_region_only() -> void:
|
|
assert_bool(AtlasWindowGeometry.basins_visible_at_rung("Region")).is_true()
|
|
assert_bool(AtlasWindowGeometry.basins_visible_at_rung("District")).is_false()
|
|
assert_bool(AtlasWindowGeometry.basins_visible_at_rung("Quarter")).is_false()
|
|
|
|
|
|
func test_attractors_visible_at_rung_region_only() -> void:
|
|
assert_bool(AtlasWindowGeometry.attractors_visible_at_rung("Region")).is_true()
|
|
assert_bool(AtlasWindowGeometry.attractors_visible_at_rung("District")).is_false()
|
|
assert_bool(AtlasWindowGeometry.attractors_visible_at_rung("Quarter")).is_false()
|
|
|
|
|
|
# =============================================================================
|
|
# Coordinator live-eyeball finding (2026-07-23): zoom_compensated_size() —
|
|
# marker sizes must stay CONSTANT on screen regardless of _view_zoom
|
|
# (Araminta's ruling), but draw calls execute inside a Node2D whose .scale IS
|
|
# _view_zoom — a raw constant gets multiplied by that transform at render
|
|
# time. This function pre-divides so the transform's multiply cancels back
|
|
# out to the literal screen-space value.
|
|
# =============================================================================
|
|
|
|
|
|
## At zoom=1.0 (the canvas transform's identity scale) the compensated size
|
|
## must equal the input unchanged — no over/under-correction at the one zoom
|
|
## level where compensation is a no-op by construction.
|
|
func test_zoom_compensated_size_at_zoom_one_is_unchanged() -> void:
|
|
assert_float(AtlasWindowGeometry.zoom_compensated_size(2.2, 1.0)).is_equal_approx(2.2, 0.0001)
|
|
|
|
|
|
## The exact regression shape: at Lendel's real orbital fit zoom (~0.0063,
|
|
## live drive script), the compensated size must be much LARGER than the
|
|
## raw screen-space constant — inversely proportional to zoom — so that once
|
|
## the canvas transform re-multiplies it by view_zoom at render time, the
|
|
## EFFECTIVE on-screen size lands back at the literal ruling value, not a
|
|
## sub-pixel sliver.
|
|
func test_zoom_compensated_size_at_orbital_zoom_scales_up_inversely() -> void:
|
|
var view_zoom := 0.0063
|
|
var screen_space_size := 2.2
|
|
var compensated: float = AtlasWindowGeometry.zoom_compensated_size(screen_space_size, view_zoom)
|
|
# Round-trip: compensated * view_zoom must reconstruct the original
|
|
# screen-space size — this IS the property that makes the on-screen
|
|
# result zoom-invariant (the canvas transform performs exactly this
|
|
# multiply at render time).
|
|
assert_float(compensated * view_zoom).is_equal_approx(screen_space_size, 0.001)
|
|
assert_float(compensated).override_failure_message(
|
|
"at a tiny orbital zoom, the compensated size must be dramatically LARGER"
|
|
+ " than the raw screen-space constant — that's the whole point of the fix"
|
|
).is_greater(screen_space_size * 10.0)
|
|
|
|
|
|
## The exact BUG this fix closes, pinned as a regression: an UNCOMPENSATED
|
|
## radius (screen_space_size used directly, the pre-fix behavior) multiplied
|
|
## by Lendel's real orbital zoom produces a sub-pixel effective size — this
|
|
## is the "the ruling's px value, at orbital fit zoom, is invisible" claim
|
|
## from the coordinator's diagnosis, verified numerically rather than just
|
|
## asserted.
|
|
func test_uncompensated_radius_at_orbital_zoom_would_be_sub_pixel() -> void:
|
|
var view_zoom := 0.0063
|
|
var raw_screen_space_radius := 2.2 # RIVER_DOT_RADIUS_BY_CLASS_REGION[TRUNK]
|
|
var effective_size_if_uncompensated: float = raw_screen_space_radius * view_zoom
|
|
assert_float(effective_size_if_uncompensated).override_failure_message(
|
|
"an uncompensated radius at orbital zoom must be sub-pixel — pinning the"
|
|
+ " numeric magnitude of the bug this fix closes, not just its existence"
|
|
).is_less(0.02)
|
|
|
|
|
|
## A degenerate zero (or negative) view_zoom must not divide-by-zero/produce
|
|
## infinity/NaN — the floor guard keeps this function total.
|
|
func test_zoom_compensated_size_zero_zoom_does_not_blow_up() -> void:
|
|
var result: float = AtlasWindowGeometry.zoom_compensated_size(2.2, 0.0)
|
|
assert_bool(is_finite(result)).override_failure_message(
|
|
"a degenerate zero view_zoom must not produce inf/NaN"
|
|
).is_true()
|