test(cliffs): the blob is ORE - item 2 of #84 is #24 - #94
Merged
Conversation
The handoff named "the blob" the sharpest open lead in #84: a contiguous patch in region [0,0] where the game places no cliff whatever cliff_elevation is routed onto it, on the reasoning that a bounded, field-independent hole cannot be a field error and must be a rule the port does not implement. That reasoning holds and the rule is ore exclusion - the patch is a tungsten-ore field. Measured over the three oracle regions: - the game puts a cliff on ore 3 times in 1,569; the port, 29 - 26 of the port's 45 surplus cells sit on ore, all at [1500,1500] - the collapsed arms' blob is 10 cells, ALL on ore, and the SAME ten in all four arms - gate open and gate real, single contour and real bands - so it cannot be a field or cliffiness effect Ruled out first, each by measurement rather than reading: - not lava: 2,597 surface.get_tile samples from the game over the blob (0 lookup misses) are volcanic-cracks-* with no lava at all. The standing "not lava" claim had used OUR resolver, the component it needed to exonerate. - not any other tile: cliff-vulcanus's mask, read off a running game, is cliff/is_lower_object/is_object/item/meltable/object/player/ water_tile, and only lava + lava-hot of the 18 Vulcanus tiles share a layer. VULCANUS_CLIFF_BLOCKING_TILES is now measured, not deduced. - not the cliffiness gate: 0 flips over all 24,960 captured edges, scored as the BINARY crossesCliff reads (avg of the two corners > 0.5) rather than as a value. Two thirds of those corners sit on a clamp, which made the old value comparison vacuous - but a clamped corner is not vacuous for a THRESHOLD, it is where a small error flips it. - not entity collision, though ruling it out found a real unported rule: applyCliffs re-tests every cliff through Surface::wouldCollide (0x10160c088), which calls collideWithEntity as well as constCollideWithTile. Ore carries only the `resource` layer so it cannot be what that rejects - but big/huge-volcanic-rock and crater-cliff do collide, and none of it is ported. The mechanism of the exclusion is still open: it is not a collision, so it is either an ordering effect in EntityMapGenerationTask or something in resource_autoplace. Settling the direction comes before adding any rejection. Also corrects the issue's headline. "37 of 1531 = 2.4%" is the arm with NO lava rejection; with the rejection renderVulcanusCliffs actually applies it is 33 wrong of 1,525 matched, 45 over-placed, 6 missed. Both arms are pinned so they cannot be confused again. No src change - this is evidence, not a fix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T4Q2ep3HJSjkyWddMSYj4Y
This was referenced Aug 2, 2026
wormeyman
added a commit
that referenced
this pull request
Aug 2, 2026
…#84) #94 ruled out lava, every other tile, the cliffiness gate and entity collision, then handed the mechanism over open: the cliff/ore correlation fits two stories demanding opposite fixes, and the note closed "settle the direction, not add a rejection." Settled with a lever rather than an argument. `autoplace_controls` is settable on the surface exactly like `cliff_settings`, so the resources can be switched off (`size = 0`) and the same regions regenerated - #82's collapse trick pointed one subsystem over. | arm | cliff-vulcanus | resources | | --- | --- | --- | | `[1500,1500]` resources ON | 885 | 3,933 | | `[1500,1500]` calcite OFF | 912 | 19 | | `[1500,1500]` geyser OFF | 889 | 3,914 | | `[1500,1500]` ALL OFF | 916 | 0 | | `[0,0]` collapsed, ON | 335 | 945 | | `[0,0]` collapsed, ALL OFF | **345** | 0 | **Both arms, not one.** Ore off puts a cliff in all ten blob cells, 0/10 -> 10/10. The converse arm is what makes it a direction: the collapsed settings force 335 cliffs through the region against the default's 283, straight through the tungsten field, and the ore does not move - the same 945 entities. Three properties, each constraining the mechanism: it is ONE-WAY (removing a resource only ever adds cliffs, in all four paired arms), ADDITIVE (27 calcite + 4 geyser = exactly the 31 of all-off, disjoint), and LOCAL with a geometry that is a BOX OVERLAP against the resource ENTITY's rectangle - measurable only because the geyser's collision half-extent is 1.398 against the ores' 0.098, which is why every point-at-tile-centre geometry scored 20-27 of 31. Scored as box overlap: 21 of 31 explained, ZERO false alarms in 885, and all six connected components of the suppressed set contain a directly-overlapped cell (adjacency is not a free pass - only 8 of 885 kept cliffs touch one). Worth 31 of the 42 cells the port over-places at `[1500,1500]`: every one of the 31 is a cell the port places and none is a cliff the game kept, so the rule is pure precision. Still not a collision, now doubly established. The mask argument stands and the fixture carries the layers rather than a claim about them. The disassembly says it more strongly: `computeInternal` (0x101622860) calls `generateCliffs` at +44 and `generateEntities` at +148; `apply` (0x101623b48) calls `applyCliffs` at +124 and `applyEntities` at +164 - the cliffs are computed AND placed before any resource exists, which also refutes #94's "maybe ore avoids cliffs" guess. Harness: `sampleCliffEntitiesFull` gains `autoplaceControls`, `alsoResources` and `protoNames`, dumping cliffs, resources, prototype collision geometry and the controls the SURFACE read back from ONE generated surface - so an override that failed to apply cannot be mistaken for a term that does not matter, and "the ore moved" and "the cliffs moved" are never compared across two worlds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LT6oy76sLRqoC1QzLocQ1h
wormeyman
added a commit
that referenced
this pull request
Aug 2, 2026
…#84) (#99) #94 ruled out lava, every other tile, the cliffiness gate and entity collision, then handed the mechanism over open: the cliff/ore correlation fits two stories demanding opposite fixes, and the note closed "settle the direction, not add a rejection." Settled with a lever rather than an argument. `autoplace_controls` is settable on the surface exactly like `cliff_settings`, so the resources can be switched off (`size = 0`) and the same regions regenerated - #82's collapse trick pointed one subsystem over. | arm | cliff-vulcanus | resources | | --- | --- | --- | | `[1500,1500]` resources ON | 885 | 3,933 | | `[1500,1500]` calcite OFF | 912 | 19 | | `[1500,1500]` geyser OFF | 889 | 3,914 | | `[1500,1500]` ALL OFF | 916 | 0 | | `[0,0]` collapsed, ON | 335 | 945 | | `[0,0]` collapsed, ALL OFF | **345** | 0 | **Both arms, not one.** Ore off puts a cliff in all ten blob cells, 0/10 -> 10/10. The converse arm is what makes it a direction: the collapsed settings force 335 cliffs through the region against the default's 283, straight through the tungsten field, and the ore does not move - the same 945 entities. Three properties, each constraining the mechanism: it is ONE-WAY (removing a resource only ever adds cliffs, in all four paired arms), ADDITIVE (27 calcite + 4 geyser = exactly the 31 of all-off, disjoint), and LOCAL with a geometry that is a BOX OVERLAP against the resource ENTITY's rectangle - measurable only because the geyser's collision half-extent is 1.398 against the ores' 0.098, which is why every point-at-tile-centre geometry scored 20-27 of 31. Scored as box overlap: 21 of 31 explained, ZERO false alarms in 885, and all six connected components of the suppressed set contain a directly-overlapped cell (adjacency is not a free pass - only 8 of 885 kept cliffs touch one). Worth 31 of the 42 cells the port over-places at `[1500,1500]`: every one of the 31 is a cell the port places and none is a cliff the game kept, so the rule is pure precision. Still not a collision, now doubly established. The mask argument stands and the fixture carries the layers rather than a claim about them. The disassembly says it more strongly: `computeInternal` (0x101622860) calls `generateCliffs` at +44 and `generateEntities` at +148; `apply` (0x101623b48) calls `applyCliffs` at +124 and `applyEntities` at +164 - the cliffs are computed AND placed before any resource exists, which also refutes #94's "maybe ore avoids cliffs" guess. Harness: `sampleCliffEntitiesFull` gains `autoplaceControls`, `alsoResources` and `protoNames`, dumping cliffs, resources, prototype collision geometry and the controls the SURFACE read back from ONE generated surface - so an override that failed to apply cannot be mistaken for a term that does not matter, and "the ore moved" and "the cliffs moved" are never compared across two worlds. Claude-Session: https://claude.ai/code/session_01LT6oy76sLRqoC1QzLocQ1h Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The handoff into this session named "the blob" the sharpest open lead in #84: a contiguous patch in region
[0,0]where the game places no cliff whatevercliff_elevationis routed onto it, on the reasoning that a bounded, field-independent hole cannot be a field error and must be a rule the port does not implement at all.That reasoning holds. The rule is ore exclusion - the patch is a tungsten-ore field.
The measurement
[1500,1500]The blob is the same ten cells in all four collapsed arms - gate forced open and gate real, single contour and real bands. A set invariant to both the band structure and the gate cannot be a field or a cliffiness effect.
Scope note: at real settings the port places nothing in the blob (
[0,0]scores 283/283, 2 surplus, 2 missed, neither in it). The blob is only reachable when a sweep forces a contour through the ore field; the ore rule costs accuracy only at[1500,1500].What it is not - each measured, not read
surface.get_tilesamples from the game overx 160..208, y 124..176, 0 lookup misses: the blob's interior isvolcanic-cracks-*with no lava at all. The standing "not lava" claim had been made with our resolver - the component it needed to exonerate, and one known to miss lava the game has.cliff-vulcanus's collision mask, read off a running game:cliff, is_lower_object, is_object, item, meltable, object, player, water_tile. Of the 18 Vulcanus tiles onlylava/lava-hotshare a layer.VULCANUS_CLIFF_BLOCKING_TILESis now measured, not deduced fromtile_collision_masks.lava().crossesCliffreads (avg(corners) > 0.5) rather than as a value. Two thirds of those corners sit on a clamp, which is what made the old value comparison vacuous - but a clamped corner is not vacuous for a threshold, it is exactly where a small error flips it.applyCliffs(0x101623c98) re-tests every accepted cliff throughSurface::wouldCollide(0x10160c088), which callscollideWithEntityas well asconstCollideWithTile; the port implements only the task-level, tile-onlywouldCollide. Ore carries the bareresourcelayer so it cannot be what that rejects - butbig-volcanic-rock,huge-volcanic-rockandcrater-cliffdo collide, and none of it is ported.The mechanism of the exclusion is still open: it is not a collision, so it is either an ordering effect in
EntityMapGenerationTask(generateCliffsruns beforegenerateEntities, so the direction may be that ore avoids cliffs) or something inresource_autoplace. Settling the direction comes before adding any rejection.Correction to the issue's headline
37 / 1531 = 2.4%is the arm with no lava rejection. With the rejectionrenderVulcanusCliffsactually applies it is 33 wrong of 1,525 matched, 45 over-placed, 6 missed. Both arms are now pinned so they cannot be confused again.No
srcchange - this is evidence, not a fix.pnpm run verifygreen (1,336 tests).🤖 Generated with Claude Code
https://claude.ai/code/session_01T4Q2ep3HJSjkyWddMSYj4Y