Skip to content

test(cliffs): the direction is ORE -> CLIFF, and it is worth 31 cells (#84) - #99

Merged
wormeyman merged 1 commit into
mainfrom
feat/cliff-ore-exclusion
Aug 2, 2026
Merged

test(cliffs): the direction is ORE -> CLIFF, and it is worth 31 cells (#84)#99
wormeyman merged 1 commit into
mainfrom
feat/cliff-ore-exclusion

Conversation

@wormeyman

Copy link
Copy Markdown
Owner

Closes the question #94 handed over. That PR ruled out lava, every other tile, the cliffiness gate and entity collision, then stopped: the cliff/ore correlation fits two stories demanding opposite fixes, and its note closed with "settle the direction, not add a rejection."

Settled with a lever rather than an argument. map_gen_settings.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

Turning the ore off puts a cliff in all ten blob cells - 0/10 -> 10/10. The converse arm is what makes this a direction rather than a correlation: the collapsed settings force 335 cliffs through that 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

  • One-way. Removing a resource only ever ADDS cliffs - nothing the game placed with them on disappears, across all four paired arms. A perturbed field would move cells both ways; a rejection cannot.
  • Additive. 27 calcite + 4 geyser = exactly the 31 of all-off, with no overlap. Each resource acts independently.
  • Local, and the geometry is a BOX OVERLAP against the resource entity's rectangle, not "is a resource tile inside the 4x4 cell". That is measurable only because sulfuric-acid-geyser's collision half-extent is 1.398 against the ores' 0.098 - a point-at-tile-centre test explains the calcite cells and cannot explain the geyser ones, which is exactly the residual that made every candidate geometry score 20-27 of 31.

Scored as a box overlap: 21 of 31 explained, zero false alarms across the 885 the game kept. The other 10 are not scattered - the suppressed set has six 4-connected components and every one contains a directly-overlapped cell. Adjacency is not a free pass: only 8 of the 885 kept cliffs touch a suppressed cell.

What it is worth

Every one of the 31 is a cell the port currently places, and none is a cliff the game kept. The rule is pure precision - it can only remove surplus, and it removes 31 of the 42 cells the port over-places at [1500,1500].

Still not a collision, now doubly established

The mask argument stands, and the fixture now 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 - so no collision test in the cliff path can see one, and #94's "maybe ore avoids cliffs" alternative is refuted by the converse arm.

crater-cliff is suppressed by calcite the same way (0 with it on, 8 with it off) and craters are placed on a completely different path (CliffCraterPlacer::tryToPlaceCliffAsCrater, 0x10160bcac, from applyEntities), so whatever this is, it is common to both cliff kinds.

Harness

sampleCliffEntitiesFull gains autoplaceControls, alsoResources and protoNames. Every arm dumps cliffs, resources, prototype collision geometry and the controls the surface read back, all from one generated surface - so an override that silently failed cannot be mistaken for a term that does not matter, and "the ore moved" and "the cliffs moved" are never compared across two different worlds.

Deliberately NOT done

Porting the rejection. The 31/0 score uses the game's resource entities as input, which isolates the rule from the accuracy of the resource port; driving it from renderVulcanusResources is a second question and has not been measured. The notes say so at the point of use.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LT6oy76sLRqoC1QzLocQ1h

…#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
wormeyman force-pushed the feat/cliff-ore-exclusion branch from 6187d70 to b540470 Compare August 2, 2026 18:18
@wormeyman
wormeyman merged commit 97420aa into main Aug 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant