test(cliffs): four of the ten ore remainders are the onDestroy CASCADE (#84) - #125
Merged
Merged
Conversation
#84) `vulcanusOreRejection.ts` records box overlap as explaining 21 of the 31 cells the ore suppresses, the other ten as "run remainders", and the cascade half of that question as REFUTED. That refutation is about a DIFFERENT cascade. It tested #108's crossing-stage mechanism - a rejection zeroes the cell's edge registers, a neighbour's code changes, re-test to a fixpoint - and its conclusion ("rejected cells do not turn neighbours rejectable") still stands. The `applyCliffs` cascade is `Cliff::onDestroy` taking the facing end of every connected neighbour and destroying a neighbour left with no end at all. It was read out of the binary in #113, AFTER #110 ran, and nothing had re-run the remainder question against it. Replayed entirely on the game's own data - its ore-off cliff set (892 with the game's orientations), its resource entity positions, the prototype boxes the fixture itself carries - so none of the port's field, ore model or geyser roll appears in the measurement: | arm | matched | wrong | surplus | | --- | --- | --- | --- | | control - destroy the lever's own 31 | 861 | 0 | 0 | | direct overlap only, no cascade | 856 | 5 | 10 | | direct overlap + onDestroy CASCADE | 859 | 2 | 6 | - Direct overlap fires on 21 and every one is in the lever's 31 - precision 1.000 re-derived with no data of ours. - The cascade closes 4 of the 10 remainders and 3 of the 5 orientation errors. Recall 21/31 = 0.677 -> 25/31 = 0.806, no new parameter, no wider box. - `missing` is 0 in both arms, so no cell the game kept is ever removed. That is what separates a mechanism from a bigger rectangle - and #124 established the box is not the engine's collision test to begin with. The control validates the harness, and getting it exact needs `noUpdateConnections: true`: the game's dumped set is POST-pipeline, so running `updateConnections` over it again double-applies the pass and scores wrong=13, which reads like a defect in the cascade model and is an artifact of the harness. Any experiment starting from a dumped set has the same hazard. Six remain: 1546,1550.5 1546,1554.5 1606,1590.5 1606,1594.5 1622,1614.5 1626,1614.5. Two are the geyser pair, and the first is the one cell in this whole residual whose destruction the game's own orientations directly witness (#124's n=1) - so the best-evidenced destruction is still unexplained. Measurement only - the renderer rejects at the crossing stage and does not run `applyCliffConnections` at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015jeznBmWiZywUc7cBw9xFU
wormeyman
added a commit
that referenced
this pull request
Aug 4, 2026
…count is 14 (#84) (#126) Everything the last three PRs established about the ore rule was measured on [1500,1500], because that is the only region `oracle-vulcanus-cliff-ore-direction` re-runs with the resources off. A rule characterised on one region and never tested on another is fitted until proven otherwise, so the lever was captured for the two regions the entities fixture covers and it never did. | region | resources | ON | OFF | suppressed | | --- | --- | --- | --- | --- | | [0,0] | 945 tungsten-ore | 283 | 283 | 0 | | [-1200,800] | 1047 coal | 387 | 387 | 0 | - PRECISION 1.000 SURVIVES. Our predicate fires on zero cells in both regions, so 1992 resource entities across two fresh regions produce no false positive. This is the arm that would have caught a rule fitted to [1500,1500]. - THE UNEXPLAINED POPULATION IS 14, NOT 11. #123 could only park `106,26.5`, `90,38.5` and `-1050,1022.5` as undetermined because the lever's region did not cover them. It does now, and the ore suppresses nothing there. - Re-confirms #110's attribution - 27 calcite, 4 geyser, 0 tungsten and coal - at far larger scale than the arm that produced it. The non-vacuity check is in the fixture rather than argued: "0 suppressed" is also what a lever that never reached the generator prints, and the OFF arms read back 0 resources against 945 and 1047. What this does NOT establish: neither region contains calcite or a geyser, the only two controls that suppress anything. So this is a PRECISION test, not a recall test - the rule's positive evidence is still one region, and #125's cascade result is still measured on [1500,1500] alone. Breaking the rule would need a region with calcite in it, and the oracle set has none. New fixture is deliberately separate from `oracle-vulcanus-cliff-ore-direction` so regenerating it cannot rewrite ground truth four merged PRs depend on. PROVENANCE entry added. Claude-Session: https://claude.ai/code/session_015jeznBmWiZywUc7cBw9xFU Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
wormeyman
added a commit
that referenced
this pull request
Aug 4, 2026
…for cliffs (#84) (#128) Every ore result in #84 uses one instrument: switch a resource off through `map_gen_settings.autoplace_controls` and see which cliffs come back, treated throughout as removing entities and nothing else. It does more, and the game's data files say so: vulcanus_calcite_size = slider_rescale(control:calcite:size, 2) vulcanus_calcite_region = ... vulcanus_calcite_size ..., control:calcite:frequency ... volcanic_jagged_ground_range = 5 * min(10, max(vulcanus_calcite_region + 0.2, ...)) That last one is a TILE range, so `calcite size = 0` changes which tile the argmax picks - a live route from the lever to `Surface::wouldCollide`'s tile half, exactly the kind #124 was left looking for after closing the entity half. Measured against the GAME, three arms over [1500,1500] on a uniform stride-2 grid of 16384 points: | arm | tiles changed | blocking gained | blocking lost | | --- | --- | --- | --- | | calcite OFF | 841 (5.1%) | 0 | 0 | | ALL resources OFF | 1066 | 0 | 0 | Every change is ground-to-ground - jagged-ground losing the argmax to folds, folds-warm, soil-dark, soil-light, folds-flat. Nothing crosses the lava/lava-hot boundary, so `constCollideWithTile` cannot see any of it and EVERY ORE RESULT IN #84 STANDS. But the instrument was mischaracterised, and anyone using `autoplace_controls` for a new question needs to know it moves tiles. Non-vacuity: 1682 of the 16384 sampled tiles ARE blocking, so there was a boundary to cross, and each arm records the controls the SURFACE read back. Our port reproduces it - 3335 of 65536 changed, 0 blocking, a rate of 5.09% against the game's 5.13%. That corroborates the port on a lever nobody had pointed at it, and is what lets its "no blocking flip anywhere" cover the 75% of tiles the grid skipped. Control: tungsten OFF moves zero tiles here, because there is no tungsten in this region. WHERE THIS LEAVES THE MECHANISM - a three-way contradiction, recorded rather than smoothed over. Both halves of `Surface::wouldCollide` are now closed against the ore (entity by #124, tile here), yet #124 also found the ore acting at the destroy stage, where `wouldCollide` is the only thing that destroys. All three cannot be right. Ranked by corroboration, the destroy-stage result is weakest at n=1 - and its one cell, `1546,1550.5`, is also one of the six #125's cascade does not explain, so it has been anomalous twice. Harness: `sampleTileNames` gains an `autoplaceControls` override and a `sampleTileNamesFull` sibling returning the controls the surface read back. New fixture + PROVENANCE entry; capture takes ~7s. Claude-Session: https://claude.ai/code/session_015jeznBmWiZywUc7cBw9xFU 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.
vulcanusOreRejection.tsrecords box overlap as explaining 21 of the 31 cells the ore suppresses, the other ten as "run remainders", and the cascade half of that question as REFUTED.That refutation is about a different cascade. It tested #108's crossing-stage mechanism - a rejection zeroes the cell's edge registers, a neighbour's code changes, re-test to a fixpoint - and its conclusion ("rejected cells do not turn neighbours rejectable") still stands.
The
applyCliffscascade is a different thing:Cliff::onDestroytakes the facing end of every connected neighbour, and a neighbour left with no end at all is destroyed outright. It was read out of the binary in #113, after #110 ran, and nothing had re-run the remainder question against it.Replayed entirely on the game's own data
Nothing of the port's field, ore model or geyser roll appears in this measurement:
ALL resources OFFcliff set - 892 cells with the game's own orientationsresources ONset - 861 cellsonDestroycascademissingis 0 in both arms, so no cell the game kept is ever removed. That is what separates a mechanism from a bigger rectangle - a box wide enough to reach those four would also reach cells the game kept, and test(cliffs): the ore rule is NOT entity collision, and it acts at the destroy stage (#84) #124 established the box is not the engine's collision test to begin with.The control is load-bearing, and so is one flag
The control says the ore-off world minus those 31 cells is the ore-on world, orientations included. Without it none of the other rows mean anything.
Getting it exact needs
noUpdateConnections: true: the game's dumped set is POST-pipeline, so runningupdateConnectionsover it again double-applies the pass and trims ends that legitimately survived. Forget it and the control scoreswrong = 13- which reads like a defect in the cascade model and is an artifact of the harness. Any future experiment that starts from a dumped set rather than from our own queue has the same hazard, so it is written down.The six that remain
Two are the pair #123 attributed to the geyser, and
1546,1550.5is the one cell in this entire residual whose destruction the game's own orientations directly witness (#124's n=1). So the best-evidenced destruction in the whole investigation is still unexplained by any rule.What this does NOT change
Nothing shipping. The renderer rejects at the crossing stage and does not run
applyCliffConnectionsat all - see## The queue has a CONSUMERfor why that is deliberate. This is a statement about the RULE and about which of its remainders now have a mechanism. The stale "cascade REFUTED" line invulcanusOreRejection.tsis corrected in place rather than left to mislead.Verification
pnpm run verifygreen - 1465 app (up 4) + 13 worker + 3 container tests, 0 warnings, exit 0.🤖 Generated with Claude Code
https://claude.ai/code/session_015jeznBmWiZywUc7cBw9xFU