src/noise/cliffs/cliffCatalog.ts exports its own sliderToLinear, computed
entirely in f64 and rounded once at the end. src/noise/eval/math.ts exports a
second one that rounds every operation to f32. cliffFields.ts is the only
consumer of the f64 copy; every other caller (moisture.ts, fulgoraScrap.ts,
fulgoraShared.ts) uses the f32 one.
The f32-per-operation form is the one that was measured against the game.
fulgora_grid is 175 - slider_to_linear(freq, -50, 50), sampled at five
slider positions on a real 2.1.14 surface: an f64 chain rounded once at the end
misses s = 3 by exactly one f32 ULP, and rounding every operation matches all
five. So the cliff copy is very likely wrong, and the port had to reproduce it.
Measured
The two forms compared after Math.fround, over the two ranges the cliff gate
reads. 11 of 22 slider positions differ.
| range |
slider |
f64 form (cliffCatalog) |
f32 form (eval/math) |
| (-1, 1) |
1/3 |
-0.61314719276545848 |
-0.61314713954925537 |
| (-1, 1) |
2/3 |
-0.22629438553091685 |
-0.22629439830780029 |
| (-1, 1) |
1.5 |
0.22629438553091674 |
0.22629439830780029 |
| (-1, 1) |
2 |
0.38685280723454163 |
0.38685274124145508 |
| (-1, 1) |
3 |
0.61314719276545837 |
0.61314713954925537 |
| (-1.7, 1.7) |
0.5 |
-0.65764977229872068 |
-0.65764969587326050 |
| (-1.7, 1.7) |
2/3 |
-0.38470045540255859 |
-0.38470047712326050 |
| (-1.7, 1.7) |
1 |
0 |
4.7683716530855236e-8 |
| (-1.7, 1.7) |
1.5 |
0.38470045540255859 |
0.38470059633255005 |
| (-1.7, 1.7) |
2 |
0.65764977229872090 |
0.65764981508255005 |
| (-1.7, 1.7) |
3 |
1.0423502277012793 |
1.0423500537872314 |
Largest gap 1.409e-7, at s = 1.5 on (-1.7, 1.7).
Why nothing has ever caught it
All three cliff fixtures (oracle-cliff-elevation, oracle-cliffiness,
oracle-rock-density) were captured at default settings. At s = 1 the two
forms agree exactly on (-1, 1) - both return 0.
They do not agree on (-1.7, 1.7), where the f32 form returns 4.768e-8
rather than 0. But the gate reads that range only inside
low_freq_lever = min(slider_to_linear(cliff_frequency, -1.7, 1.7),
slider_to_linear(cliff_richness, -1, 1))
and at the defaults the min picks the (-1, 1) zero. So the one place the two
forms differ at the default is masked by an argument the min never chooses.
test/cliffCatalog.spec.ts asserts sliderToLinear(1, -1.7, 1.7) is 0 to 12
decimal places, which pins the f64 form - the game-validated f32 form would
fail that line.
What the Rust port did
crates/fmw-noise/src/cliffs/catalog.rs::cliff_slider_to_linear reproduces the
f64 form, deliberately, with a doc comment saying not to "fix" it there. A
unilateral change on the Rust side would read as a port bug in tier 2, which is
the whole point of having tier 2.
Settling it
Neither form is known to be the game's here. fulgora_grid is evidence about
slider_to_linear as an operation, which is a good prior but not a capture of
the cliff gate away from its defaults. A capture of cliffiness_nauvis at a
non-default nauvis_cliff frequency or richness would decide it directly.
Note the gate is discrete and forgiving: the closest of 2,048 fixture positions
sits 2.344e-4 from the cutoff, so a 1.4e-7 lever difference will not flip it.
cliff_elevation_nauvis does not read the lever at all. So a capture would need
to sample main_cliffiness or a sub-term rather than the gate.
src/noise/cliffs/cliffCatalog.tsexports its ownsliderToLinear, computedentirely in f64 and rounded once at the end.
src/noise/eval/math.tsexports asecond one that rounds every operation to f32.
cliffFields.tsis the onlyconsumer of the f64 copy; every other caller (
moisture.ts,fulgoraScrap.ts,fulgoraShared.ts) uses the f32 one.The f32-per-operation form is the one that was measured against the game.
fulgora_gridis175 - slider_to_linear(freq, -50, 50), sampled at fiveslider positions on a real 2.1.14 surface: an f64 chain rounded once at the end
misses
s = 3by exactly one f32 ULP, and rounding every operation matches allfive. So the cliff copy is very likely wrong, and the port had to reproduce it.
Measured
The two forms compared after
Math.fround, over the two ranges the cliff gatereads. 11 of 22 slider positions differ.
Largest gap 1.409e-7, at
s = 1.5on(-1.7, 1.7).Why nothing has ever caught it
All three cliff fixtures (
oracle-cliff-elevation,oracle-cliffiness,oracle-rock-density) were captured at default settings. Ats = 1the twoforms agree exactly on
(-1, 1)- both return 0.They do not agree on
(-1.7, 1.7), where the f32 form returns 4.768e-8rather than 0. But the gate reads that range only inside
and at the defaults the
minpicks the(-1, 1)zero. So the one place the twoforms differ at the default is masked by an argument the
minnever chooses.test/cliffCatalog.spec.tsassertssliderToLinear(1, -1.7, 1.7)is 0 to 12decimal places, which pins the f64 form - the game-validated f32 form would
fail that line.
What the Rust port did
crates/fmw-noise/src/cliffs/catalog.rs::cliff_slider_to_linearreproduces thef64 form, deliberately, with a doc comment saying not to "fix" it there. A
unilateral change on the Rust side would read as a port bug in tier 2, which is
the whole point of having tier 2.
Settling it
Neither form is known to be the game's here.
fulgora_gridis evidence aboutslider_to_linearas an operation, which is a good prior but not a capture ofthe cliff gate away from its defaults. A capture of
cliffiness_nauvisat anon-default
nauvis_clifffrequency or richness would decide it directly.Note the gate is discrete and forgiving: the closest of 2,048 fixture positions
sits 2.344e-4 from the cutoff, so a 1.4e-7 lever difference will not flip it.
cliff_elevation_nauvisdoes not read the lever at all. So a capture would needto sample
main_cliffinessor a sub-term rather than the gate.