Files
settled-reach/client/tests/test_atlas_window_nature_overlay_draw_smoke.gd
T
jpmschweitzerandClaude Fable 5 60faf667a5 fix(ui): T-1156 live rounds — zoom-compensated marker sizes; toggle-redraw regression pin
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>
2026-07-23 08:55:29 +02:00

282 lines
12 KiB
GDScript

## T-1156 wave 1: a REAL draw smoke test for AtlasWindowNatureOverlay,
## matching test_atlas_window_overlay_draw_smoke.gd's established pattern —
## `draw_circle()`/`draw_rect()`/`draw_arc()`/`draw_colored_polygon()` calls
## require a live render pass under this engine version (confirmed directly:
## a plain unit test calling `_draw()` outside one throws "Drawing is only
## allowed inside this node's `_draw()`..."). Render into a REAL SubViewport,
## force a settle wait, and assert visible non-background pixels — proving
## the river-dot/mouth-ring/basin-polygon/attractor-glyph draw calls actually
## paint, not just that the state feeding them is correct (that half is
## test_atlas_window_nature_overlay.gd's job).
##
## **REQUIRES A REAL RENDERING DRIVER — SKIPS (not fails) under
## `tests/run-godot`'s hardcoded `--headless`**, same posture/rationale as
## test_atlas_window_overlay_draw_smoke.gd's own header doc (dummy driver,
## no GPU texture output — SubViewport.get_texture().get_image() returns an
## all-zero/unusable image under it).
##
## To actually exercise this file's assertions, run it with a real driver:
## godot4 --display-driver x11 --rendering-driver opengl3 \
## -s addons/gdUnit4/bin/GdUnitCmdTool.gd --ignoreHeadlessMode -c \
## -a res://tests/test_atlas_window_nature_overlay_draw_smoke.gd
##
## **Known limitation, verified directly (2026-07-23 zoom-compensation fix
## verification):** the shared _BackgroundRect/_render_to_image() harness
## (copied from test_atlas_window_overlay_draw_smoke.gd) occasionally fails
## to composite the COLOR_BG fill at all under a real X11/opengl3 run in this
## environment (sampled pixels read (0,0,0,0), not COLOR_BG — an unrelated,
## intermittent X11/SubViewport timing issue, confirmed via an XServer
## "BadMatch" warning in that same run's log). When that happens EVERY pixel
## reads as "non-background" regardless of what this overlay actually draws,
## making a low MIN_NON_BACKGROUND_FRACTION threshold pass VACUOUSLY (it
## would pass even with zoom-compensation deliberately broken — confirmed by
## direct revert-test). The terrain sibling suite is accidentally immune to
## this (its checkerboard composite covers most of the frame regardless of
## background correctness); this suite's SPARSE markers are not. **The
## reliable, environment-independent regression gate for the zoom-
## compensation fix is therefore the pure-function suite in
## test_atlas_window_geometry_nature.gd** (zoom_compensated_size()'s own
## tests) — this smoke suite is a supplementary "does it actually paint"
## check when the harness cooperates, not the primary gate.
class_name TestAtlasWindowNatureOverlayDrawSmoke
extends GdUnitTestSuite
const AtlasWindowNatureOverlay := preload("res://ui/implant/apps/atlas/atlas_window_nature_overlay.gd")
const COLOR_BG: Color = Color("#0d1117") # AtlasWindowViewer.COLOR_BG, mirrored (private const)
const VIEWPORT_SIZE: Vector2i = Vector2i(512, 512)
const MIN_NON_BACKGROUND_FRACTION: float = 0.0005 # river dots are sparse — a low bar is honest here
const SKIP_REASON: String = (
"no real rendering driver (dummy/headless) — run with e.g."
+ " `godot4 --display-driver x11 --rendering-driver opengl3"
+ " -s addons/gdUnit4/bin/GdUnitCmdTool.gd --ignoreHeadlessMode -c"
+ " -a res://tests/test_atlas_window_nature_overlay_draw_smoke.gd` to exercise this file"
)
## Matches test_atlas_window_overlay_draw_smoke.gd's own detection exactly.
static func _dummy_renderer_active() -> bool:
return DisplayServer.get_name() == "headless"
## Same duck-typed viewer contract as test_atlas_window_nature_overlay.gd's
## _ViewerStub, minus the SimBridge-signal machinery this smoke test doesn't
## need (layer1 is injected directly via _layer1, not through a response).
## view_zoom MUST be kept in sync with whatever zoom _render_to_image() is
## called with — the whole point of this smoke suite (post-live-eyeball,
## coordinator finding 2026-07-23) is proving markers stay visible at the
## REAL orbital fit zoom, not an artificially large test zoom that would
## mask the zoom-compensation bug the fix addresses.
class _ViewerStub:
var held_granularity_v2: String = "Region"
var body_radius_km: float = 6371.0
var held_center: Vector2i = Vector2i.ZERO
var held_n: int = 64
var view_zoom: float = 1.0
var overlay_visibility: Dictionary = {"gen_rivers": true, "gen_basins": true, "gen_attractors": true}
func get_held_granularity_v2() -> String:
return held_granularity_v2
func get_body_radius_km() -> float:
return body_radius_km
func get_held_center() -> Vector2i:
return held_center
func get_held_n() -> int:
return held_n
func get_cell_pixel_size() -> float:
return 16.0
func get_view_zoom() -> float:
return view_zoom
func is_overlay_visible(overlay_id: String) -> bool:
return bool(overlay_visibility.get(overlay_id, false))
## A dense scatter of river cells spanning the whole held window's canvas
## footprint (not clustered in one corner) — a genuine "does the composite
## draw something visible across the frame" check, same intent as the
## terrain smoke test's checkerboard morphology spread.
static func _mock_layer1_dense() -> Dictionary:
var river_cells: Array = []
var river_class: PackedByteArray = PackedByteArray()
for i in range(40):
river_cells.append([i * 3, i * 3])
river_class.append(2) # trunk — visible at every rung this suite exercises
return {
"river_network": {
"river_cells": river_cells,
"river_class": river_class,
"confluences": [[60, 60]],
"mouths": [[120, 120]],
},
"drainage_basins": [
{"basin_id": 1, "boundary": [[0, 0], [0, 40], [40, 40], [40, 0]]},
],
"attractors": [
{"position": [80, 80], "strength": 0.9, "attractor_type": "Oasis", "sub_biome": ""},
],
"grid_w": 256,
"grid_h": 128,
}
## Same _BackgroundRect/_render_to_image/_non_background_fraction shared
## rendering infrastructure as test_atlas_window_overlay_draw_smoke.gd —
## duplicated rather than imported since gdUnit4 test suites are not
## typically composed via inheritance in this codebase (no precedent for a
## shared test-infra base class in client/tests/), and the block is small.
class _BackgroundRect extends Node2D:
var fill_color: Color = Color.BLACK
var fill_size: Vector2 = Vector2.ZERO
func _draw() -> void:
draw_rect(Rect2(Vector2.ZERO, fill_size), fill_color)
func _render_to_image(overlay: Node2D, zoom: float = 1.0) -> Image:
var sub_viewport := SubViewport.new()
sub_viewport.size = VIEWPORT_SIZE
sub_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
sub_viewport.transparent_bg = false
add_child(sub_viewport)
auto_free(sub_viewport)
var bg := _BackgroundRect.new()
bg.fill_color = COLOR_BG
bg.fill_size = Vector2(VIEWPORT_SIZE)
sub_viewport.add_child(bg)
bg.queue_redraw()
var canvas := Node2D.new()
canvas.position = Vector2(VIEWPORT_SIZE) * 0.5
canvas.scale = Vector2(zoom, zoom)
sub_viewport.add_child(canvas)
canvas.add_child(overlay)
overlay.queue_redraw()
for _i in range(6):
await get_tree().process_frame
return sub_viewport.get_texture().get_image()
static func _non_background_fraction(image: Image) -> float:
var w: int = image.get_width()
var h: int = image.get_height()
if w <= 0 or h <= 0:
return 0.0
var total: int = w * h
var differing: int = 0
var bg_rgb: Color = Color(COLOR_BG.r, COLOR_BG.g, COLOR_BG.b, 1.0)
for y in range(h):
for x in range(w):
var px: Color = image.get_pixel(x, y)
var px_rgb: Color = Color(px.r, px.g, px.b, 1.0)
if not px_rgb.is_equal_approx(bg_rgb):
differing += 1
return float(differing) / float(total)
## Region rung, every toggle on: rivers + confluence + mouth + basin fill +
## attractor glyph must all draw SOMETHING — the "does the composite actually
## paint" proof the state-only unit suite cannot provide.
func test_region_rung_draws_visible_pixels() -> void:
if _dummy_renderer_active():
print(SKIP_REASON)
return
var overlay := AtlasWindowNatureOverlay.new()
var stub := _ViewerStub.new()
overlay.viewer = stub
overlay._layer1 = _mock_layer1_dense()
overlay._requested_body_id = "SmokeBody"
# Zoom chosen so the held window's canvas footprint (held_n * cell_px =
# 64 * 16 = 1024 units) comfortably fills the 512px viewport.
var zoom: float = float(VIEWPORT_SIZE.x) / (float(stub.held_n) * stub.get_cell_pixel_size())
stub.view_zoom = zoom
var image: Image = await _render_to_image(overlay, zoom)
var fraction: float = _non_background_fraction(image)
assert_float(fraction).override_failure_message(
(
"the Region-rung nature composite (rivers + confluence + mouth + basin +"
+ " attractor, every toggle on) must render VISIBLE non-background pixels —"
+ " got only %.4f%% of the frame differing from COLOR_BG"
)
% (fraction * 100.0)
).is_greater(MIN_NON_BACKGROUND_FRACTION)
## District rung: only trunk rivers (class 2, all cells in the dense fixture
## are trunk) + the mouth carve-out draw; basins/attractors/confluences are
## rung-gated off. Still must produce visible pixels — proving the "fade
## down, don't vanish" posture actually leaves SOMETHING on screen.
func test_district_rung_still_draws_visible_pixels() -> void:
if _dummy_renderer_active():
print(SKIP_REASON)
return
var overlay := AtlasWindowNatureOverlay.new()
var stub := _ViewerStub.new()
stub.held_granularity_v2 = "District"
overlay.viewer = stub
overlay._layer1 = _mock_layer1_dense()
overlay._requested_body_id = "SmokeBody"
var zoom: float = float(VIEWPORT_SIZE.x) / (float(stub.held_n) * stub.get_cell_pixel_size())
stub.view_zoom = zoom
var image: Image = await _render_to_image(overlay, zoom)
var fraction: float = _non_background_fraction(image)
assert_float(fraction).override_failure_message(
(
"the District-rung composite (trunk rivers + mouth carve-out only) must"
+ " still render VISIBLE non-background pixels — got only %.4f%% of the"
+ " frame differing from COLOR_BG"
)
% (fraction * 100.0)
).is_greater(MIN_NON_BACKGROUND_FRACTION)
## Coordinator live-eyeball regression (2026-07-23): the ORBITAL TILE MOSAIC
## rest state's REAL fit zoom on a Lendel-scale body (~0.0063, confirmed
## directly via a live drive script — held_n=19139 districts,
## cell_px=16, a ~1600px viewport) — NOT the comfortable ~0.5 zoom the
## sibling test above uses. Before the zoom-compensation fix, this exact
## zoom magnitude produced ZERO visible river/mouth pixels (a 2.2px trunk
## dot rasterized at ~0.014 screen px) despite RVR being on and the policy
## table correctly returning full Region visibility — the captures showed
## terrain-only with literally nothing drawn. Pins the regression at
## production scale, not a toy zoom that could accidentally still pass.
func test_orbital_scale_zoom_still_draws_visible_pixels() -> void:
if _dummy_renderer_active():
print(SKIP_REASON)
return
var overlay := AtlasWindowNatureOverlay.new()
var stub := _ViewerStub.new()
stub.held_n = 19139 # Lendel's own raw circumference, live drive script
stub.view_zoom = 0.0063 # Lendel's own live orbital fit zoom
overlay.viewer = stub
overlay._layer1 = _mock_layer1_dense()
overlay._requested_body_id = "SmokeBody"
var image: Image = await _render_to_image(overlay, stub.view_zoom)
var fraction: float = _non_background_fraction(image)
assert_float(fraction).override_failure_message(
(
"at Lendel's REAL orbital fit zoom (~0.0063), the Region-rung nature"
+ " composite must still render VISIBLE non-background pixels — got only"
+ " %.4f%% of the frame differing from COLOR_BG. This is exactly the"
+ " coordinator's live-eyeball finding: uncompensated screen-space marker"
+ " sizes get multiplied by the canvas's own zoom transform, vanishing"
+ " sub-pixel at the orbital rest state's tiny fit zoom."
)
% (fraction * 100.0)
).is_greater(MIN_NON_BACKGROUND_FRACTION)