feat(ui): the Atlas ladder bottoms out at Quarter (D-255, T-1213)
Quarter becomes the deepest navigable rung. Block and Chunk leave the ladder. The rule, from the amendment: the deepest Atlas rung is the one at which a screen pixel shows one subtile. At the uniform 2x2 px display ratio a 3440x1440 window gives 540 gridunits on the short axis, so Quarter's 512 m extent draws 0.948 m per gridunit -- about one voxel per gridunit and one 0.5 m subtile per pixel. Block (0.237) and Chunk (0.119) magnify beneath the finest datum that can exist, and measured as exactly that on Ferrath: one morphology zone, one vegetation class, an unbroken colour field. They were not missing a feature; there was nothing left to show them. CHUNK ITSELF IS UNTOUCHED. It remains D-243's 64 m stream/derive unit and is where Phase 5 derives first-person walkable content -- D-012's load-around-the-player is expressed in chunks. Block remains the 128 m generator planning unit. Both keep their enum variants, their extent_m answers and their wire vocabulary. What was retired is the claim that a MAP of one is worth looking at. DEEP_RUNGS moved with the floor, and this is the part worth reading twice. It is a mandatory D-255(d) hardening: a per-body retention cap bounding how much ground an exhaustive pan can hold resident at fine spacing. Left as [Block, Chunk] it would have guarded rungs no client can request -- dead code -- while the accumulation gap silently re-opened under Quarter, now the finest navigable rung at ~0.95 m per gridunit. It is now [District, Quarter]. A control that names its targets by rung has to follow the ladder when the ladder moves. Six tests pinned the old floor and were updated rather than deleted, since each was protecting a real property: the clamp tests now clamp at Quarter, and the disk-cache tests use Region for "shallow" (District is capped now) and Quarter for "deep". One new test pins the distinction the change turns on -- the retired rungs are absent from RUNG_LADDER but still present in RUNG_EXTENT_M, because viewability was retired, not vocabulary. Also removes the four capture scenarios for the retired rungs, including the two blank goldens that had been passing against blank captures. 1838 client tests, 0 failed. Server clippy clean, step_canvas suite green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 110 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 70 KiB |
@@ -254,13 +254,18 @@ func test_capacity_sweep_never_touches_an_entry_under_budget() -> void:
|
||||
|
||||
func test_deep_rung_cap_evicts_oldest_deep_rung_entry_when_exceeded() -> void:
|
||||
var cache := StepCanvasDiskCache.new(_test_root)
|
||||
# Fill past the cap: MAX_DEEP_RUNG_ENTRIES_PER_BODY + 2 distinct Chunk
|
||||
# Fill past the cap: MAX_DEEP_RUNG_ENTRIES_PER_BODY + 2 distinct Quarter
|
||||
# windows for one body, backdating each so eviction order is
|
||||
# deterministic (oldest last_read_at goes first).
|
||||
#
|
||||
# Quarter, not Chunk: DEEP_RUNGS became [District, Quarter] when the ladder
|
||||
# floor moved (D-255 amendment 2026-08-07). Quarter is now the finest
|
||||
# navigable rung and therefore the exhaustive-pan accumulation case this
|
||||
# cap exists to bound.
|
||||
var cap: int = StepCanvasDiskCache.MAX_DEEP_RUNG_ENTRIES_PER_BODY
|
||||
for i in range(cap + 2):
|
||||
cache.put("GJ1c", "Chunk", Vector2i(i, 0), Vector2i(64, 64), _stub_canvas({"i": i}))
|
||||
var key := StepCanvasDiskCache.make_key("GJ1c", "Chunk", Vector2i(i, 0), Vector2i(64, 64))
|
||||
cache.put("GJ1c", "Quarter", Vector2i(i, 0), Vector2i(64, 64), _stub_canvas({"i": i}))
|
||||
var key := StepCanvasDiskCache.make_key("GJ1c", "Quarter", Vector2i(i, 0), Vector2i(64, 64))
|
||||
cache._debug_backdate_entry("GJ1c", key, i, i) # strictly increasing "recency"
|
||||
|
||||
assert_int(cache.entry_count("GJ1c")).override_failure_message(
|
||||
@@ -268,20 +273,24 @@ func test_deep_rung_cap_evicts_oldest_deep_rung_entry_when_exceeded() -> void:
|
||||
).is_equal(cap)
|
||||
|
||||
# The two OLDEST (i=0, i=1) must have been evicted; the newest must survive.
|
||||
assert_bool(cache.has("GJ1c", "Chunk", Vector2i(0, 0), Vector2i(64, 64))).is_false()
|
||||
assert_bool(cache.has("GJ1c", "Chunk", Vector2i(1, 0), Vector2i(64, 64))).is_false()
|
||||
assert_bool(cache.has("GJ1c", "Quarter", Vector2i(0, 0), Vector2i(64, 64))).is_false()
|
||||
assert_bool(cache.has("GJ1c", "Quarter", Vector2i(1, 0), Vector2i(64, 64))).is_false()
|
||||
assert_bool(
|
||||
cache.has("GJ1c", "Chunk", Vector2i(cap + 1, 0), Vector2i(64, 64))
|
||||
cache.has("GJ1c", "Quarter", Vector2i(cap + 1, 0), Vector2i(64, 64))
|
||||
).override_failure_message("the most-recently-written deep-rung entry must survive").is_true()
|
||||
|
||||
|
||||
## Region, not District: the ladder floor moved on 2026-08-07 and DEEP_RUNGS
|
||||
## moved with it, from [Block, Chunk] to [District, Quarter]. District is now a
|
||||
## capped rung, so it can no longer stand for "shallow" — Region is the finest
|
||||
## rung the cap does not apply to.
|
||||
func test_deep_rung_cap_does_not_apply_to_shallow_rungs() -> void:
|
||||
var cache := StepCanvasDiskCache.new(_test_root)
|
||||
var cap: int = StepCanvasDiskCache.MAX_DEEP_RUNG_ENTRIES_PER_BODY
|
||||
for i in range(cap + 5):
|
||||
cache.put("GJ1c", "District", Vector2i(i, 0), Vector2i(64, 64), _stub_canvas({"i": i}))
|
||||
cache.put("GJ1c", "Region", Vector2i(i, 0), Vector2i(64, 64), _stub_canvas({"i": i}))
|
||||
assert_int(cache.entry_count("GJ1c")).override_failure_message(
|
||||
"District is not a DEEP_RUNGS member — the deep-rung cap must not evict it"
|
||||
"Region is not a DEEP_RUNGS member — the deep-rung cap must not evict it"
|
||||
).is_equal(cap + 5)
|
||||
|
||||
|
||||
@@ -290,7 +299,7 @@ func test_deep_rung_cap_never_evicts_the_global_floor_entry() -> void:
|
||||
cache.put("GJ1c", "Global", Vector2i.ZERO, Vector2i.ZERO, _stub_canvas())
|
||||
var cap: int = StepCanvasDiskCache.MAX_DEEP_RUNG_ENTRIES_PER_BODY
|
||||
for i in range(cap + 3):
|
||||
cache.put("GJ1c", "Chunk", Vector2i(i, 0), Vector2i(64, 64), _stub_canvas({"i": i}))
|
||||
cache.put("GJ1c", "Quarter", Vector2i(i, 0), Vector2i(64, 64), _stub_canvas({"i": i}))
|
||||
assert_bool(cache.has("GJ1c", "Global", Vector2i.ZERO, Vector2i.ZERO)).override_failure_message(
|
||||
"the Global floor entry must survive deep-rung cap eviction regardless of fill order"
|
||||
).is_true()
|
||||
|
||||
@@ -20,13 +20,30 @@ func test_rung_at_index_zero_is_global() -> void:
|
||||
assert_str(StepCanvasTransport.rung_at_index(0)).is_equal(StepCanvasTransport.RUNG_GLOBAL)
|
||||
|
||||
|
||||
func test_rung_at_index_five_is_chunk_the_deepest() -> void:
|
||||
assert_str(StepCanvasTransport.rung_at_index(5)).is_equal(StepCanvasTransport.RUNG_CHUNK)
|
||||
## The ladder bottoms out at Quarter (D-255 amendment 2026-08-07): the deepest
|
||||
## rung is the one where a screen pixel shows one subtile, and Quarter's 512 m
|
||||
## extent draws ~0.948 m per gridunit — about one voxel per gridunit at the 2x2
|
||||
## display ratio. Block and Chunk drew 0.237 and 0.119 m per gridunit, below
|
||||
## the finest datum that exists, so they magnified rather than informed.
|
||||
func test_rung_at_index_three_is_quarter_the_deepest() -> void:
|
||||
assert_str(StepCanvasTransport.rung_at_index(3)).is_equal(StepCanvasTransport.RUNG_QUARTER)
|
||||
|
||||
|
||||
## Block and Chunk remain legal WIRE vocabulary (RUNG_EXTENT_M still carries
|
||||
## them, and the server enum still has the variants) — they are simply not
|
||||
## reachable by scrolling. This pins that distinction: the ladder does not
|
||||
## offer them, whatever the index.
|
||||
func test_retired_rungs_are_not_reachable_on_the_ladder() -> void:
|
||||
assert_int(StepCanvasTransport.RUNG_LADDER.size()).is_equal(4)
|
||||
assert_bool(StepCanvasTransport.RUNG_LADDER.has(StepCanvasTransport.RUNG_BLOCK)).is_false()
|
||||
assert_bool(StepCanvasTransport.RUNG_LADDER.has(StepCanvasTransport.RUNG_CHUNK)).is_false()
|
||||
# Still nameable — the retirement is of viewability, not of the vocabulary.
|
||||
assert_bool(StepCanvasTransport.RUNG_EXTENT_M.has(StepCanvasTransport.RUNG_CHUNK)).is_true()
|
||||
|
||||
|
||||
func test_rung_at_index_clamps_out_of_range_indices() -> void:
|
||||
assert_str(StepCanvasTransport.rung_at_index(-3)).is_equal(StepCanvasTransport.RUNG_GLOBAL)
|
||||
assert_str(StepCanvasTransport.rung_at_index(99)).is_equal(StepCanvasTransport.RUNG_CHUNK)
|
||||
assert_str(StepCanvasTransport.rung_at_index(99)).is_equal(StepCanvasTransport.RUNG_QUARTER)
|
||||
|
||||
|
||||
func test_index_for_rung_round_trips_every_ladder_entry() -> void:
|
||||
@@ -49,7 +66,8 @@ func test_scroll_step_ascends_one_notch_at_a_time() -> void:
|
||||
|
||||
|
||||
func test_scroll_step_clamps_at_the_deepest_rung() -> void:
|
||||
assert_int(StepCanvasTransport.scroll_step(5, 1)).is_equal(5)
|
||||
# Index 3 = Quarter, the floor since the 2026-08-07 ladder amendment.
|
||||
assert_int(StepCanvasTransport.scroll_step(3, 1)).is_equal(3)
|
||||
|
||||
|
||||
func test_scroll_step_clamps_at_the_global_opener() -> void:
|
||||
|
||||
@@ -66,7 +66,9 @@ func test_scroll_rung_clamps_at_the_deepest_rung() -> void:
|
||||
v.enter({"body_id": "GJ380c", "body_radius_km": 6238.4}, {})
|
||||
for _i in range(10):
|
||||
v._scroll_rung(1, Vector2(400.0, 300.0))
|
||||
assert_str(v.get_held_rung()).is_equal(StepCanvasTransport.RUNG_CHUNK)
|
||||
# Quarter is the floor (D-255 amendment 2026-08-07) — scrolling past it
|
||||
# would magnify below one subtile per pixel rather than show more.
|
||||
assert_str(v.get_held_rung()).is_equal(StepCanvasTransport.RUNG_QUARTER)
|
||||
|
||||
|
||||
func test_reset_to_global_returns_from_a_deep_rung() -> void:
|
||||
|
||||
@@ -179,20 +179,6 @@ func apply_setup(scenario_name: String, tree_root: Node) -> bool:
|
||||
["gen_dw_moisture"]
|
||||
)
|
||||
|
||||
"atlas_GJ338Bd_Block":
|
||||
_setup_atlas_golden_shot(
|
||||
tree_root,
|
||||
{
|
||||
"body_id": "GJ338Bd",
|
||||
"body_radius_km": 6711.0,
|
||||
"proper_name": "Arbour",
|
||||
"terrain_reference": "wiki/star-systems/GJ-338B/bodies/GJ338Bd/heightmap.png",
|
||||
},
|
||||
{"system_id": "GJ 338B", "proper_name": "Arbour"},
|
||||
"Block",
|
||||
[]
|
||||
)
|
||||
|
||||
"atlas_GJ820Bc_Global":
|
||||
_setup_atlas_golden_shot(
|
||||
tree_root,
|
||||
@@ -247,15 +233,6 @@ func apply_setup(scenario_name: String, tree_root: Node) -> bool:
|
||||
tree_root, _FERRATH, _CYGNI_B, "Quarter", [], _FERRATH_LAND
|
||||
)
|
||||
|
||||
"atlas_GJ820Bc_land_Block":
|
||||
_setup_atlas_golden_shot(
|
||||
tree_root, _FERRATH, _CYGNI_B, "Block", [], _FERRATH_LAND
|
||||
)
|
||||
|
||||
"atlas_GJ820Bc_land_Chunk":
|
||||
_setup_atlas_golden_shot(
|
||||
tree_root, _FERRATH, _CYGNI_B, "Chunk", [], _FERRATH_LAND
|
||||
)
|
||||
|
||||
"atlas_GJ251c_Global":
|
||||
_setup_atlas_golden_shot(
|
||||
@@ -296,19 +273,6 @@ func apply_setup(scenario_name: String, tree_root: Node) -> bool:
|
||||
["gen_dw_temp"]
|
||||
)
|
||||
|
||||
"atlas_GJ445c-m1_Chunk":
|
||||
_setup_atlas_golden_shot(
|
||||
tree_root,
|
||||
{
|
||||
"body_id": "GJ445c-m1",
|
||||
"proper_name": "Jinghu",
|
||||
"terrain_reference": "wiki/star-systems/GJ-445/bodies/GJ445c-m1/heightmap.png",
|
||||
},
|
||||
{"system_id": "GJ 445", "proper_name": "Jinghu"},
|
||||
"Chunk",
|
||||
[]
|
||||
)
|
||||
|
||||
_:
|
||||
push_warning("VisualScenarios: unknown scenario '%s'" % scenario_name)
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user