test(cliffs): collapse the rule term by term - #18 is in the FIELD, not the placement - #81
Merged
Merged
Conversation
Answers "will messing with the other cliff prototypes help": the cliff ENTITY
prototype will not - the crossing pass reads only grid_size/grid_offset off it
and the fixture already proves those (all 1569 cliffs land exactly on
(cx*4+2, cy*4+2.5), zero off-lattice). But `cliff_settings` holds every
constant the rule uses, all settable on the surface, so a term can be switched
OFF in the game instead of modelled:
cliff_smoothing = 0 leaves the RAW elevation
cliff_elevation_interval = 1e6 a SINGLE contour at cliff_elevation_0
richness = 4 0.5*log2(4)=1, so cliffiness_basic
saturates at 1.5 and its >0.5 gate is open
Together the rule reduces to "an edge crosses iff elevation crosses 70", making
the game's cliffs a direct readout of sign(elevation - 70) at the generator's
own sample points.
Vulcanus arm game ours matched wrong
smoothing off only 352 432 289 83 = 28.7%
+ single contour 271 349 208 79 = 38.0%
+ gate held open 335 463 265 99 = 37.4%
bands, gate open 431 559 360 105 = 29.2%
NAUVIS, through the same code and lattice, is EXACT - and not only at the
default. cliff_elevation_interval = 80 had never been captured before; the port
reproduces it 281/281 in both directions, so the rule tracks the game when a
setting MOVES. It also agrees on the degenerate arm where a single contour at
50 yields zero cliffs from both, because cliffiness_nauvis's cutoff derives
from the interval while cliffiness_basic's does not.
That control is what gives the Vulcanus numbers meaning. The rule, lattice,
code packing, repair sweep and settings plumbing are now all confirmed against
the game under a changed setting. What is left is the field - and the
informative half is the over-placement, not the error rate: we place 463 where
the game places 335, so our 70-contour is ~38% longer. Our elevation is
ROUGHER at the 4-tile scale than the one the generator reads.
The open lead is that our field may be right in the wrong CHANNEL. It
reproduces the corner-fields fixture to 4.8e-2, but that fixture came from
calculate_tile_properties. `multisample` sits in vulcanus_elevation's chain via
vulcanus_basalt_lakes_multisample and is absent from cliff_elevation_nauvis -
the asymmetry the residual needs - and its own docs call it "a separate noise
program with a larger grid" whose "sub-grids are copied to the main program",
i.e. explicitly grid-dependent. The cliff generator walks a 4-tile lattice;
calculate_tile_properties does not. vulcanus-multisample-NOTES established
multisample(e,dx,dy) == e(x+dx,y+dy) at 150/150 - but measured it through
calculate_tile_properties, the same channel as the fixture. A min() of four
samples is an erosion operator, so a coarser effective grid would smooth the
field exactly the way the over-placement implies.
Oracle changes: the `cliffSmoothing` option generalises to a `cliffSettings`
record keyed by the game's own field names (one call site updated); the Nauvis
path gets the same map_gen_settings round-trip, safe because the sampled
regions are far from spawn and ungenerated at on_init; and parseCliffDumpFull
normalises `cliffs` to an array, because table_to_json serialises an EMPTY Lua
table as {} and a legitimately-zero result was reading as undefined.
DOES NOT FIX #18.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GRx1CU29RKLsRuUAErEDRB
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.
Answers "will messing with the other cliff prototypes help?"
The cliff entity prototype: no. The crossing pass reads only
grid_size/grid_offsetoff it, and the fixture already proves both - all 1569 cliffs land exactly on(cx*4+2, cy*4+2.5), zero off-lattice.cliff_settings: yes, decisively. It holds every constant the rule uses, all settable on the surface, so a term can be switched off in the game rather than modelled:cliff_smoothing = 0cliff_elevation_interval = 1e6cliff_elevation_0; no band arithmeticrichness = 40.5*log2(4) = 1, socliffiness_basicsaturates at 1.5 and its> 0.5gate is always openTogether the rule reduces to "an edge crosses iff elevation crosses 70" - making the game's own cliffs a direct readout of
sign(elevation - 70)at the generator's sample points.The control is what makes this mean something
Nauvis, through the same code and the same lattice, is exact - and not only at the default.
cliff_elevation_interval = 80had never been captured before; the port reproduces it 281/281 in both directions, so the rule tracks the game when a setting moves. It also agrees on the degenerate arm, where a single contour at 50 yields zero cliffs from both (cliffiness_nauvis's cutoff derives from the interval;cliffiness_basic's does not).So the rule, lattice, code packing, repair sweep and settings plumbing are all now confirmed against the game under a changed setting. What is left is the field.
The informative half is the over-placement, not the error rate: we place 463 where the game places 335, so our 70-contour is ~38% longer. Our elevation is rougher at the 4-tile scale than the one the generator reads.
The open lead: right field, wrong channel
Our field is not wrong against the channel it was checked in - it reproduces the corner-fields fixture to a max of 4.8e-2, and that fixture came from
calculate_tile_properties. The question is whether the map generator reads the same values that channel reports.multisamplesits invulcanus_elevation's chain viavulcanus_basalt_lakes_multisample, and is absent fromcliff_elevation_nauvis- the asymmetry the residual needs. Its own docs call it "a separate noise program with a larger grid" whose "sub-grids are copied to the main program" - explicitly grid-dependent. The cliff generator walks a 4-tile lattice;calculate_tile_propertiesdoes not.vulcanus-multisample-NOTES.mdestablishedmultisample(e,dx,dy) == e(x+dx,y+dy)at 150/150 - but measured it throughcalculate_tile_properties, the same channel as the fixture. Amin()of four samples is an erosion operator, so a coarser effective grid would smooth the field exactly the way the over-placement implies.Not a fixture captured at the wrong site this time - one captured through the wrong channel.
Oracle changes
cliffSmoothinggeneralises to acliffSettingsrecord keyed by the game's own field names (one call site updated).map_gen_settingsround-trip - safe because the sampled regions are far from spawn and ungenerated aton_init.parseCliffDumpFullnormalisescliffsto an array:table_to_jsonserialises an empty Lua table as{}, so a legitimately-zero result was reading asundefined. That is a real configuration - raisingrichnesson Nauvis liftscliffiness_nauvis's cutoff until nothing qualifies.Does not fix #18.
pnpm run verify: 308 files clean, 1298 passed / 3 skipped, preview 12 passed.🤖 Generated with Claude Code
https://claude.ai/code/session_01GRx1CU29RKLsRuUAErEDRB