Two separable findings from the live A/B (real driver): (1) the original zero-ring report was a viewport-framing crop — the ring fired all along at screen (1755,-191), above the frame under the COVER fit; recentering via set_view proved the path live. (2) The real bug once in-frame: at Quarter fit zoom the compensated ring radius (5.0/7.5=0.667 canvas) fell below the floored stroke (1.0 canvas) and draw_arc's stroke filled its own hole — a solid blob, not a ring. Bracket: 1x stroke=blob, 1.5x=hollow recovers, 2x=clean. Fix: zoom_compensated_ring_radius() floors the radius at 2x the paired stroke, wired through _zs_ring_radius() for both ring and halo arcs; verified live producing a clean hollow double-ring. The third member of the Godot sub-canvas-unit rasterizer family (width floor, stroke-vs-width sites, now radius-vs-stroke) — all recorded for the T-1176 render-mechanism discussion. 10 pin tests in the stroke-width suite; revert-verified (floor drop -> named failures); full client suite 3956/3956; gdlint clean. Tickets: T-1170 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
253 lines
14 KiB
GDScript
253 lines
14 KiB
GDScript
## T-1170 live round (2026-07-23): tests for
|
|
## AtlasWindowGeometryNature.zoom_compensated_stroke_width() — the
|
|
## STROKE-WIDTH-specific sibling of zoom_compensated_size(), added after the
|
|
## course-polyline hairline finding (Araminta's pixel scan of
|
|
## D-district-courses.png/Q-quarter-courses.png: a UNIFORM 1px hairline for
|
|
## the ENTIRE visible course, no width/opacity variation at all, in BOTH
|
|
## District and Quarter captures). Split into its own file rather than
|
|
## folded into test_atlas_window_geometry_nature.gd, which was already at the
|
|
## gdlint max-file-lines cap — same file-per-concern precedent as every other
|
|
## split in this cluster.
|
|
##
|
|
## Live A/B evidence (temporary instrumentation, since reverted — the
|
|
## dossier discipline): draw_line()/draw_polyline() called with a
|
|
## canvas-local width in [0.6, 1.0) renders as a flat 1px hairline
|
|
## regardless of the input value, confirmed identically on BOTH APIs (ruling
|
|
## out a draw_polyline()-specific quirk) — Godot's line rasterizer has a
|
|
## ~1.0-canvas-local-unit floor that draw_circle()'s radius parameter does
|
|
## NOT share (confirmed: mouth ring radii at the same District/Quarter zoom
|
|
## render correctly-sized via the unchanged zoom_compensated_size()/_zs()
|
|
## path — only the STROKE WIDTH argument was affected). The compensation
|
|
## MATH itself was never wrong (0.373 * 3.75 round-trips to 1.4 exactly) —
|
|
## the bug was that nothing floored the intermediate value against Godot's
|
|
## own rasterizer minimum before handing it to draw_line()/draw_polyline().
|
|
class_name TestAtlasWindowGeometryStrokeWidth
|
|
extends GdUnitTestSuite
|
|
|
|
const AtlasWindowGeometryNature := preload(
|
|
"res://ui/implant/apps/atlas/atlas_window_geometry_nature.gd"
|
|
)
|
|
|
|
|
|
## At zoom=1.0, unchanged from zoom_compensated_size() — no floor engages
|
|
## when the input is already >= 1.0.
|
|
func test_zoom_compensated_stroke_width_at_zoom_one_is_unchanged() -> void:
|
|
assert_float(
|
|
AtlasWindowGeometryNature.zoom_compensated_stroke_width(2.2, 1.0)
|
|
).is_equal_approx(2.2, 0.0001)
|
|
|
|
|
|
## The EXACT regression shape this round closes: at District's real fit zoom
|
|
## (3.75, live capture), the tributary class's raw table width (1.4px)
|
|
## divides to 0.3733 canvas-local — BELOW the 1.0 floor under the OLD
|
|
## zoom_compensated_size() path (pinned directly, not just asserted) — and
|
|
## zoom_compensated_stroke_width() must instead return exactly 1.0 (the
|
|
## floor), never the sub-floor raw division result.
|
|
func test_zoom_compensated_stroke_width_district_tributary_hits_the_floor() -> void:
|
|
var view_zoom := 3.75 # LENDEL's live District fit zoom, capture-confirmed
|
|
var raw_width_px := 1.4 # COURSE_CLASS_WIDTH_PX[RIVER_CLASS_TRIBUTARY]
|
|
var unfloored: float = AtlasWindowGeometryNature.zoom_compensated_size(raw_width_px, view_zoom)
|
|
assert_float(unfloored).override_failure_message(
|
|
"regression pin: the OLD unfloored division must be BELOW 1.0 at this"
|
|
+ " zoom — this is the exact numeric shape of the hairline bug"
|
|
).is_less(1.0)
|
|
var floored: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(raw_width_px, view_zoom)
|
|
assert_float(floored).override_failure_message(
|
|
"zoom_compensated_stroke_width() must clamp to the 1.0 floor, not the"
|
|
+ " sub-pixel unfloored value that collapses to Godot's hairline"
|
|
).is_equal_approx(1.0, 0.0001)
|
|
|
|
|
|
## Same shape at Quarter's real fit zoom (7.5, live capture) — the floor
|
|
## engages even harder there (raw width divides to 0.1867).
|
|
func test_zoom_compensated_stroke_width_quarter_tributary_hits_the_floor() -> void:
|
|
var view_zoom := 7.5 # LENDEL's live Quarter fit zoom, capture-confirmed
|
|
var raw_width_px := 1.4
|
|
var floored: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(raw_width_px, view_zoom)
|
|
assert_float(floored).is_equal_approx(1.0, 0.0001)
|
|
|
|
|
|
## Regression pin (PR #195 stroke-width-class shape, per the coordinator's
|
|
## explicit ask): for EACH course class, at District's real fit zoom, the
|
|
## EFFECTIVE on-screen width the render plan feeds (canvas-local width times
|
|
## view_zoom, exactly what the canvas transform multiplies at render time)
|
|
## must equal AT LEAST the table value — never less, since the floor can only
|
|
## push the effective width UP from what an unfloored divide would produce,
|
|
## never down. This is the "does the value actually reaching the screen
|
|
## match the table" pin the coordinator asked for, computed both ways
|
|
## (floored vs table) rather than eyeballed.
|
|
func test_effective_stroke_width_at_district_zoom_meets_table_value_per_class() -> void:
|
|
var view_zoom := 3.75
|
|
for cls in [
|
|
AtlasWindowGeometryNature.RIVER_CLASS_STREAM,
|
|
AtlasWindowGeometryNature.RIVER_CLASS_TRIBUTARY,
|
|
AtlasWindowGeometryNature.RIVER_CLASS_TRUNK,
|
|
]:
|
|
var table_width: float = AtlasWindowGeometryNature.course_class_width_px(cls)
|
|
var canvas_local: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(
|
|
table_width, view_zoom
|
|
)
|
|
var effective_screen_px: float = canvas_local * view_zoom
|
|
assert_float(effective_screen_px).override_failure_message(
|
|
(
|
|
"class %d's effective on-screen stroke width (%.3fpx) must be AT"
|
|
+ " LEAST its table value (%.3fpx) — the floor must never make a"
|
|
+ " course THINNER than the ruling specifies, only ever thicker"
|
|
+ " when the literal value would otherwise be sub-pixel"
|
|
)
|
|
% [cls, effective_screen_px, table_width]
|
|
).is_greater_equal(table_width - 0.001)
|
|
|
|
|
|
## Same pin at Quarter's fit zoom (7.5) — the floor engages harder there
|
|
## (streams' 0.9px table value divides to 0.12 canvas-local, furthest below
|
|
## the floor of any class/rung combination this batch draws).
|
|
func test_effective_stroke_width_at_quarter_zoom_meets_table_value_per_class() -> void:
|
|
var view_zoom := 7.5
|
|
for cls in [
|
|
AtlasWindowGeometryNature.RIVER_CLASS_STREAM,
|
|
AtlasWindowGeometryNature.RIVER_CLASS_TRIBUTARY,
|
|
AtlasWindowGeometryNature.RIVER_CLASS_TRUNK,
|
|
]:
|
|
var table_width: float = AtlasWindowGeometryNature.course_class_width_px(cls)
|
|
var canvas_local: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(
|
|
table_width, view_zoom
|
|
)
|
|
var effective_screen_px: float = canvas_local * view_zoom
|
|
assert_float(effective_screen_px).is_greater_equal(table_width - 0.001)
|
|
|
|
|
|
## At a LOW zoom (well under 1.0, e.g. an extreme zoom-out within a rung —
|
|
## not just Region's orbital case), the floor must NOT engage: the ordinary
|
|
## divide-then-scale math must still produce the literal table value exactly,
|
|
## matching zoom_compensated_size()'s own unfloored behavior. Pins that the
|
|
## floor is a ONE-DIRECTION safety net, not a blanket override.
|
|
func test_zoom_compensated_stroke_width_does_not_engage_at_low_zoom() -> void:
|
|
var view_zoom := 0.1
|
|
var raw_width_px := 2.2
|
|
var floored: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(raw_width_px, view_zoom)
|
|
var unfloored: float = AtlasWindowGeometryNature.zoom_compensated_size(raw_width_px, view_zoom)
|
|
assert_float(floored).override_failure_message(
|
|
"at a zoom where the unfloored value is already well above 1.0, the"
|
|
+ " floor must be a no-op — identical to zoom_compensated_size()"
|
|
).is_equal_approx(unfloored, 0.0001)
|
|
|
|
|
|
## A degenerate zero (or negative) view_zoom must not divide-by-zero/produce
|
|
## infinity/NaN — same total-function guarantee as zoom_compensated_size().
|
|
func test_zoom_compensated_stroke_width_zero_zoom_does_not_blow_up() -> void:
|
|
var result: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(2.2, 0.0)
|
|
assert_bool(is_finite(result)).override_failure_message(
|
|
"a degenerate zero view_zoom must not produce inf/NaN"
|
|
).is_true()
|
|
|
|
|
|
# =============================================================================
|
|
# T-1170 live round (2026-07-23, coordinator's mouth-ring finding):
|
|
# zoom_compensated_ring_radius() — the RADIUS-SMALLER-THAN-STROKE regime.
|
|
# Same A/B-bracket discipline as the stroke-width suite above, applied to
|
|
# draw_arc() RING markers (mouth rings), whose radius AND stroke are both
|
|
# small zoom-compensated values that can cross each other.
|
|
##
|
|
## Live A/B evidence (temporary instrumentation, since reverted): at the
|
|
## PRODUCTION Quarter-rung radius/stroke pair (radius=0.667, stroke=1.0
|
|
## canvas-local units, Quarter fit zoom 7.5), draw_arc() rendered a SOLID
|
|
## BLOB, not a hollow ring — confirmed via a re-centered live capture (the
|
|
## ORIGINAL "zero ring pixels" symptom was a separate viewport-framing crop,
|
|
## not this bug — see zoom_compensated_ring_radius()'s own doc). Bracket
|
|
## (stroke fixed at 1.0 canvas-local, radius varied): 0.51 (~stroke/2) ->
|
|
## blob; 1.0 (=stroke, the production case) -> blob; 1.5 (1.5x stroke) ->
|
|
## hollow ring recovers; 2.0 (2x stroke) -> hollow ring, cleaner. Floor set
|
|
## at 2x with margin over the observed 1.0x-blob/1.5x-hollow transition.
|
|
# =============================================================================
|
|
|
|
|
|
## At zoom=1.0 with a radius comfortably above stroke*2 already, the floor
|
|
## must be a no-op — identical to zoom_compensated_size() directly.
|
|
func test_zoom_compensated_ring_radius_no_op_when_radius_already_clears_the_floor() -> void:
|
|
var radius: float = AtlasWindowGeometryNature.zoom_compensated_ring_radius(5.0, 1.5, 1.0)
|
|
assert_float(radius).is_equal_approx(5.0, 0.0001)
|
|
|
|
|
|
## The EXACT regression shape this round closes: at Quarter's real fit zoom
|
|
## (7.5, live capture), MOUTH_RING_RADIUS (5.0) divides to 0.667
|
|
## canvas-local — BELOW its own paired stroke (1.5/7.5 floored to 1.0 via
|
|
## zoom_compensated_stroke_width) — pinned directly, not just asserted.
|
|
## zoom_compensated_ring_radius() must instead return stroke * 2.0 (the
|
|
## floor), never the sub-floor raw division result that produced the blob.
|
|
func test_zoom_compensated_ring_radius_quarter_mouth_ring_hits_the_floor() -> void:
|
|
var view_zoom := 7.5 # LENDEL's live Quarter fit zoom, capture-confirmed
|
|
var raw_radius := 5.0 # MOUTH_RING_RADIUS
|
|
var stroke: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(1.5, view_zoom)
|
|
var unfloored: float = AtlasWindowGeometryNature.zoom_compensated_size(raw_radius, view_zoom)
|
|
assert_float(unfloored).override_failure_message(
|
|
"regression pin: the OLD unfloored radius must be AT/BELOW the paired"
|
|
+ " stroke at this zoom — this is the exact numeric shape of the blob bug"
|
|
).is_less_equal(stroke)
|
|
var floored: float = AtlasWindowGeometryNature.zoom_compensated_ring_radius(
|
|
raw_radius, stroke, view_zoom
|
|
)
|
|
assert_float(floored).override_failure_message(
|
|
"zoom_compensated_ring_radius() must clamp to stroke * 2.0 (the floor),"
|
|
+ " not the sub-floor unfloored value that renders as a solid blob"
|
|
).is_equal_approx(stroke * AtlasWindowGeometryNature.RING_RADIUS_STROKE_MULTIPLIER, 0.0001)
|
|
|
|
|
|
## Regression pin (the stroke-width suite's own "effective on-screen value"
|
|
## shape, applied to the radius/stroke RATIO instead of an absolute value):
|
|
## for the mouth ring AND halo (the two draw_arc() ring markers in this
|
|
## cluster), at Quarter's real fit zoom, the floored radius must be AT LEAST
|
|
## RING_RADIUS_STROKE_MULTIPLIER times its own paired stroke — the actual
|
|
## geometric property that keeps the ring hollow, verified directly rather
|
|
## than just re-checking the numeric floor value in isolation.
|
|
func test_ring_radius_stays_at_least_the_multiplier_above_its_stroke_at_quarter_zoom() -> void:
|
|
var view_zoom := 7.5
|
|
# (raw_radius_px, raw_stroke_px) pairs — the mouth ring and halo's own
|
|
# literal call-site arguments in _draw_mouth().
|
|
for pair in [[5.0, 1.5], [8.0, 1.0]]:
|
|
var raw_radius: float = pair[0]
|
|
var raw_stroke: float = pair[1]
|
|
var stroke: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(
|
|
raw_stroke, view_zoom
|
|
)
|
|
var radius: float = AtlasWindowGeometryNature.zoom_compensated_ring_radius(
|
|
raw_radius, stroke, view_zoom
|
|
)
|
|
assert_float(radius).override_failure_message(
|
|
(
|
|
"radius %.3f must be at least %.1fx its paired stroke %.3f — a ratio"
|
|
+ " below this rendered as a SOLID BLOB in the live A/B bracket,"
|
|
+ " never a hollow ring"
|
|
)
|
|
% [radius, AtlasWindowGeometryNature.RING_RADIUS_STROKE_MULTIPLIER, stroke]
|
|
).is_greater_equal(stroke * AtlasWindowGeometryNature.RING_RADIUS_STROKE_MULTIPLIER - 0.0001)
|
|
|
|
|
|
## At a LOW zoom (e.g. Region's tiny orbital fit, or any zoom where the
|
|
## naive radius is already well clear of the floor), the floor must NOT
|
|
## engage — matching zoom_compensated_stroke_width()'s own
|
|
## does-not-engage-at-low-zoom guarantee. Pins that this is a one-direction
|
|
## safety net, not a blanket override.
|
|
func test_zoom_compensated_ring_radius_does_not_engage_at_low_zoom() -> void:
|
|
var view_zoom := 0.0063 # Lendel's real orbital fit zoom
|
|
var raw_radius := 5.0 # MOUTH_RING_RADIUS
|
|
var stroke: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(1.5, view_zoom)
|
|
var floored: float = AtlasWindowGeometryNature.zoom_compensated_ring_radius(
|
|
raw_radius, stroke, view_zoom
|
|
)
|
|
var unfloored: float = AtlasWindowGeometryNature.zoom_compensated_size(raw_radius, view_zoom)
|
|
assert_float(floored).override_failure_message(
|
|
"at a zoom where the naive radius is already far above the floor, the"
|
|
+ " floor must be a no-op — identical to zoom_compensated_size()"
|
|
).is_equal_approx(unfloored, 0.0001)
|
|
|
|
|
|
## A degenerate zero (or negative) view_zoom must not divide-by-zero/produce
|
|
## infinity/NaN — same total-function guarantee as the stroke-width sibling.
|
|
func test_zoom_compensated_ring_radius_zero_zoom_does_not_blow_up() -> void:
|
|
var stroke: float = AtlasWindowGeometryNature.zoom_compensated_stroke_width(1.5, 0.0)
|
|
var result: float = AtlasWindowGeometryNature.zoom_compensated_ring_radius(5.0, stroke, 0.0)
|
|
assert_bool(is_finite(result)).override_failure_message(
|
|
"a degenerate zero view_zoom must not produce inf/NaN"
|
|
).is_true()
|