Skip to content

test(noise): channel audit - cliffs ARE the only coarse-grid consumer (#84) - #87

Merged
wormeyman merged 1 commit into
mainfrom
audit/multisample-channel-consumers
Aug 2, 2026
Merged

test(noise): channel audit - cliffs ARE the only coarse-grid consumer (#84)#87
wormeyman merged 1 commit into
mainfrom
audit/multisample-channel-consumers

Conversation

@wormeyman

Copy link
Copy Markdown
Owner

Closes item 4 of #84.

#83 left an assumption behind: that cliffs are the only consumer reading a multisample-bearing field on a grid other than 1 tile. That was never measured - which is exactly the status the cliff case itself had before #83.

The audit surface is much smaller than it looks

multisample appears in ~/GitHub/factorio-data @ 2.1.12 in exactly one place - vulcanus_basalt_lakes_multisample (planet-vulcanus-map-gen.lua:547), used only by vulcanus_elev. No other planet uses the primitive at all. So "audit every consumer of a multisample-bearing field" reduces to "audit every consumer of Vulcanus elevation":

consumer reads elevation? grid how established
cliff generator yes, via cliff_elevation_from_elevation 4 measured, #83
tile generator (19 *_range expressions) yes, via vulcanus_elev 1 measured, here
vulcanus_temperature yes, min(elev, elev/100) 1 same program as tiles
resources: tungsten, coal, calcite, sulfuric acid no n/a read the Lua
rocks, geyser no n/a read the Lua

The resource row had to be checked rather than assumed, because the generic path does couple to elevation: starting_resources_lake_mask = clamp((elevation - 1) / 10, 0, 1) feeds starting_patches' spot_favorability_expression (core/prototypes/noise-programs.lua:270), and CLAUDE.md flags that coupling as exactly what changed at 2.1.9. Vulcanus does not take that path - each of its four resources is placed by its own vulcanus_*_region expression, and those four definitions contain 0 references to elevation.

The tile generator reads grid 1, measured against the game

Substituting the cliff generator's 4-tile elevation into the tile resolver, compared against the game's own get_tile output over the 381 oracle positions:

grid 1 (ships) grid 4
tile-name agreement 0.9816 0.8609
lava misclassifications 0 / 381 27 / 381

46 tiles would be named wrongly, and the binary lava call - the only thing the cliff collision rejection reads - goes from exact to 27 wrong.

The sensitivity is the part worth insisting on. PR #57's field substitution failed precisely because "nothing changed" could not be distinguished from "the substitution never ran". Both arms here carry that guard explicitly, and the spec also asserts the max(-500, ...) clamp never bites at these positions, so the swap really is "the same field at grid 4" rather than something subtly different.

Side result

This clears the lava perimeter that costs 13 real cliffs their placement (#86): reading the other elevation channel makes lava dramatically worse, not better. So the perimeter error is not a channel mistake - it is somewhere else in vulcanusCatalog.

pnpm run verify green: 1310 passed / 3 skipped, 0 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WRKSNgkidxc6daeHGJHqpt

…#84)

#83 left an assumption behind: that cliffs are the only consumer reading a
multisample-bearing field on a grid other than 1 tile. That was never measured,
which is exactly the status the cliff case itself had before #83. Closes #84
item 4.

The surface is much smaller than "audit every consumer", and that is the first
finding. multisample appears in factorio-data @ 2.1.12 in exactly ONE place -
vulcanus_basalt_lakes_multisample, used only by vulcanus_elev. No other planet
uses the primitive. So the audit reduces to "who consumes Vulcanus elevation":

| consumer                  | reads elevation? | grid | how              |
| ------------------------- | ---------------- | ---- | ---------------- |
| cliff generator           | yes              | 4    | measured, #83    |
| tile generator (19 range) | yes, via elev    | 1    | measured, here   |
| vulcanus_temperature      | yes              | 1    | same program     |
| tungsten/coal/calcite/SA  | no               | n/a  | read the Lua     |
| rocks, geyser             | no               | n/a  | read the Lua     |

The resource row had to be checked rather than assumed, because the generic path
DOES couple to elevation: starting_resources_lake_mask = clamp((elevation-1)/10,
0, 1) feeds starting_patches' spot_favorability_expression, and CLAUDE.md flags
that coupling as exactly what changed at 2.1.9. Vulcanus does not take that
path - each of its four resources uses its own vulcanus_*_region expression, and
those four definitions contain 0 references to elevation.

The tile generator reads grid 1, measured against the game. Substituting the
cliff generator's 4-tile elevation into the tile resolver, over the 381 oracle
positions:

|                          | grid 1 (ships) | grid 4  |
| ------------------------ | -------------- | ------- |
| tile-name agreement      | 0.9816         | 0.8609  |
| lava misclassifications  | 0 / 381        | 27 / 381 |

46 tiles named wrongly, and the binary lava call - the only thing the cliff
collision rejection reads - goes from exact to 27 wrong. The metric is
demonstrably sensitive to the swap, which is the part worth insisting on: PR
#57's substitution failed precisely because "nothing changed" could not be
distinguished from "the substitution never ran". Both arms carry that guard
explicitly.

Side result: this clears the lava perimeter that costs 13 real cliffs their
placement (#86). Reading the other elevation channel makes lava dramatically
worse, not better, so the perimeter error is not a channel mistake - it is
somewhere else in vulcanusCatalog.

Also asserts the max(-500, ...) clamp never bites at these positions, so the
swap is exactly "the same field at grid 4" rather than something subtly else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WRKSNgkidxc6daeHGJHqpt
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