Skip to content

Commit 1769779

Browse files
wormeymanclaude
andauthored
docs(cliffs): correct the notes that #83 falsified (#85)
An audit after the multisample grid fix. Several documents still asserted the opposite of what is now measured, and three of them were TITLES - the lines a reader trusts fastest. - `cliffs-NOTES.md` gains a STATUS banner at the top. The root cause sat at line 636 under 635 lines of superseded investigation, so a cold reader met the wrong conclusions first. The banner carries the current recall and orientation numbers, points at the ROOT CAUSE section, and names the specific stale figures below it (the ~90%, the 12.5%/29.8%/8.1%/11.7% tables, the 0.806/0.938/0.853 recalls) as pre-fix. - Two headings there were plainly wrong: "validated ~90% tile-for-tile", and "Validation result: EXACT since 2026-07-30 (the residual is resolved)" - which was only ever true of Nauvis. - `vulcanus-cliffs-NOTES.md` gains the same banner, and its "## The residual is in the RULE, not the fields" section is marked FALSIFIED. Its experiment and numbers are sound; the verdict is not. The fixture it substitutes came through calculate_tile_properties (1-tile grid) while the cliff generator reads a 4-tile grid, so the fixture and the port shared the mistake and could never disagree. - `client-preview-ROADMAP.md` said the residual "is now believed to be a RULE error rather than a field error (PR #57)". It was a field error. Corrected with why PR #57's substitution missed it. - `vulcanusCliffCornerFields.spec.ts`'s doc header and `vulcanusOreCliffSeparation.spec.ts`'s describe name both still claimed the fields are exact and the residual is in the rule. Both now say the fields are exact IN THE TILE CHANNEL, which is the accurate and more useful statement. - CLAUDE.md's spec-file count was 143; it is 152. No behaviour change. `pnpm run verify`: 310 files clean, 1306 passed / 3 skipped, preview 12 passed - the suite is green on an unloaded machine, which also confirms the earlier local timeouts were load and not a regression. Claude-Session: https://claude.ai/code/session_01GRx1CU29RKLsRuUAErEDRB Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 0f0eee6 commit 1769779

6 files changed

Lines changed: 88 additions & 15 deletions

File tree

CLAUDE.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,9 @@ matters, set it explicitly.
175175
one gate. **~65-90s on a dev machine, ~4 minutes on a CI runner**, of which
176176
the app test suite is ~57s and `check:vue` ~2.5s. The `~9.5s` this line
177177
claimed for a long time was simply wrong - already wrong by a factor of six
178-
before `check:vue` existed, because the suite grew to 143 files through the
179-
Vulcanus and cliff work - and the gap mattered: ~63s is exactly the duration
178+
before `check:vue` existed, because the suite grew through the Vulcanus and
179+
cliff work (143 files then; **152 as of 2026-08-01**, which is what the
180+
`test/**/*.spec.ts` include actually matches) - and the gap mattered: ~63s is exactly the duration
180181
at which people start skipping a manual gate, which is half the argument for
181182
the CI workflow below. Don't budget 10 seconds for this.
182183
- `pnpm refs:sync` - pin `factorioLuaAPI/` + `~/GitHub/factorio-data` to the

docs/noise/client-preview-ROADMAP.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,14 @@ Done = ore patches overlaid on land, responding to the frequency/size/richness s
329329
**zero** predictions on Nauvis; the exact `wouldCollide` rejection is moot
330330
because **no Nauvis cliff touches water at all**; and the ore-on-cliff
331331
exclusion was withdrawn outright (see the M3a follow-up above - there is no
332-
such rule in the game). The residual is still open and is now believed to be
333-
a **rule** error rather than a field error (PR #57). `VoronoiNoise` (layer-1 primitive table below) is
332+
such rule in the game). **The residual is CLOSED as of 2026-08-01 (PR #83).**
333+
It was a FIELD error after all, not the rule error PR #57 concluded:
334+
`multisample`'s offsets are in the calling noise program's GRID UNITS, so
335+
the cliff generator (4-tile lattice) and the tile generator (1 tile) read
336+
different `vulcanus_elevation`. PR #57's substitution missed it because its
337+
fixture came through the same 1-tile channel the port used. Vulcanus recall
338+
is now 1.000/0.973/0.965 with 2.4% wrong orientations; see the ROOT CAUSE
339+
section of `cliffs-NOTES.md` and issue #84 for the remainder. `VoronoiNoise` (layer-1 primitive table below) is
334340
confirmed **unneeded for Nauvis** - it appears nowhere in the cliff tree or
335341
any other Nauvis expression traced so far, only on Space-Age planets - so it
336342
remains un-ported with no open TODO against it.

docs/noise/cliffs-NOTES.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# Cliffs (M4) - reverse-engineering notes
22

3+
> ## STATUS, 2026-08-01: both planets validated; issue #18 is CLOSED
4+
>
5+
> | | recall | precision | wrong orientation |
6+
> | --- | --- | --- | --- |
7+
> | **Nauvis** | 1.0000 | 1.0000 | **0 / 334** |
8+
> | **Vulcanus** | 1.000 / 0.973 / 0.965 | 0.872 | **37 / 1531 = 2.4%** |
9+
>
10+
> Vulcanus's precision is measured **without** the lava-collision rejection, which
11+
> the shipping renderer does apply; the remainder is tracked in **issue #84**.
12+
>
13+
> **Read `## ROOT CAUSE, 2026-08-01` (further down) before anything else in this
14+
> file.** It is the resolution of issue #18: `multisample`'s offsets are in the
15+
> calling noise program's GRID UNITS, not tiles, so the cliff generator and the
16+
> tile generator read genuinely different elevation fields.
17+
>
18+
> **Everything between here and that section is the investigation record.** Its
19+
> measurements stand and are worth reading for method; its *conclusions* are
20+
> superseded, several of them within hours of being written. Do not act on a
21+
> number from those sections without checking it against this banner - in
22+
> particular the `~90%` in the next heading, the 12.5% / 29.8% / 8.1% / 11.7%
23+
> orientation-error tables, and the 0.806 / 0.938 / 0.853 recalls all describe the
24+
> port BEFORE the fix.
25+
326
Factorio 2.1.11 (build 86962, mac-arm64). Measured 2026-07-20 against the headless
427
oracle (`test/oracle/oracle.ts` `sampleExpression` for the noise fields; a
528
`find_entities_filtered{type="cliff"}` chunk-forced dump for placement) and the
@@ -89,7 +112,7 @@ refactor), the offset/ringbreak chain (string seeds `'nauvis_offset_x/y'`), the
89112
86883 `basis_noise`, and `slider_to_linear`. **No `VoronoiNoise`** anywhere in the
90113
Nauvis cliff tree (it appears only on Space-Age planets).
91114

92-
## Placement rule (disasm-confirmed + validated ~90% tile-for-tile)
115+
## Placement rule (disasm-confirmed; see the STATUS banner for current accuracy)
93116

94117
Reverse-engineered from the non-stripped binary and validated against a real
95118
`find_entities_filtered{type="cliff"}` dump (chunk-forced generation, default preset).
@@ -963,7 +986,7 @@ presets, but all 9 strings in `builtin-presets.json` decode to `u8 = 0` and
963986
either way; what is unknown is whether the wire carries smoothing at all. Worth an
964987
issue if the Nauvis render is ever driven by a Lakes/Island preset.
965988

966-
## Validation result: EXACT since 2026-07-30 (the residual is resolved)
989+
## Validation result: NAUVIS exact since 2026-07-30 (historical - Nauvis only)
967990

968991
> **The ~6% Nauvis residual documented throughout this section is GONE, and the
969992
> cause was none of the six things named for it.** The port sampled the two

docs/noise/vulcanus-cliffs-NOTES.md

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Vulcanus cliffs - port notes
22

3+
> ## STATUS, 2026-08-01: issue #18 is CLOSED; remainder tracked in #84
4+
>
5+
> Recall **1.000 / 0.973 / 0.965** across the three regions, **37 / 1531 = 2.4%**
6+
> wrong orientations (was 0.806 / 0.938 / 0.853 and 12.5%). Precision 0.872,
7+
> measured **without** the lava-collision rejection the shipping renderer applies.
8+
>
9+
> **Root cause: `multisample`'s offsets are in the calling noise program's GRID
10+
> UNITS, not tiles**, so `vulcanus_basalt_lakes_multisample`'s `min` is a 4-tile
11+
> min-filter for the cliff generator and a 1-tile one for every per-tile consumer.
12+
> The port used the 1-tile field for both, making cliff elevation too rough. Full
13+
> write-up at `## ROOT CAUSE, 2026-08-01` in `cliffs-NOTES.md`; the measurement is
14+
> `test/multisampleGrid.spec.ts`.
15+
>
16+
> **Every accuracy table below this banner is the PRE-FIX state**, kept because the
17+
> reasoning is the useful part. Do not quote one as current.
18+
319
Factorio 2.1.12 (build 87038, mac-arm64). Ported 2026-07-26. Companion to
420
`cliffs-NOTES.md`, which holds the reverse-engineering of the placement rule
521
itself - none of that had to be redone, because the placement geometry is engine
@@ -523,10 +539,14 @@ the `all` path the Vulcanus DAG is evaluated four times per pixel region.
523539
> because the reasoning that got from one to the other is the useful part. The
524540
> current figures are in "ROOT CAUSE: `cliff_smoothing`".
525541
>
526-
> **And read "The residual is in the RULE, not the fields" at the end of this
527-
> file before spending any time on field accuracy.** Substituting the game's own
528-
> `elevation` and `cliffiness` for ours does not move a single placed cell, so
529-
> the residual this section chases is not in the fields.
542+
> ~~**And read "The residual is in the RULE, not the fields"...**~~ **FALSIFIED
543+
> 2026-08-01.** The residual WAS in the field. The substitution test that
544+
> "does not move a single placed cell" was comparing against a fixture sampled
545+
> through `calculate_tile_properties` - a 1-tile-grid noise program - while the
546+
> cliff generator reads the same expression on a 4-tile grid, where `multisample`
547+
> returns different values. The fixture and the port shared the same mistake and
548+
> so agreed with each other. That substitution now correctly MOVES cells; see
549+
> `test/vulcanusCliffCornerFields.spec.ts`.
530550
531551
**Superseded the "Not validated" section below.** `test/vulcanusCliffEntities.spec.ts`
532552
now compares the port against every real `cliff-vulcanus` the game places, captured
@@ -710,12 +730,24 @@ That capture is the obvious next step and is the same shape as
710730
`captureCliffEntities` in `test/oracle/capture.ts`, pointed at a Vulcanus
711731
surface.
712732

713-
## The residual is in the RULE, not the fields - measured 2026-07-29
733+
## ~~The residual is in the RULE, not the fields~~ - FALSIFIED 2026-08-01
734+
735+
> **This section's conclusion is wrong, and the way it was wrong is the most
736+
> useful thing in this file.** The residual WAS in the field. The substitution
737+
> below is sound as an experiment and its numbers are real - but the fixture it
738+
> substitutes was captured through `LuaSurface.calculate_tile_properties`, whose
739+
> noise program has a **1-tile grid**, while the cliff generator reads the same
740+
> expression on a **4-tile** grid. `multisample`'s offsets are in grid units, so
741+
> the two channels return different values for `vulcanus_elevation`. The fixture
742+
> and the port were making the same mistake, so substituting one into the other
743+
> could never move a cell. See `## ROOT CAUSE, 2026-08-01` in `cliffs-NOTES.md`.
744+
>
745+
> Read on for the method, not the verdict.
714746
715747
Everything above, and all of #18, treats the Vulcanus cliff gap as a **field
716748
accuracy** problem: the noise field matches to 5e-6, the constants are read from
717749
the game, so the ~1.15-1.19x over-placement must be residual field error
718-
somewhere. **That is wrong, and it is now measured rather than argued.**
750+
somewhere. **That was believed to be wrong; it was in fact right.**
719751

720752
`test/oracle/capture.ts vulcanus-cliff-corner-fields` dumps the game's own
721753
`vulcanus_elevation` and `cliffiness_basic` at every corner of the placement

test/vulcanusCliffCornerFields.spec.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,19 @@ import { withCtxDefaults } from "../src/noise/eval/ctx";
1717
const key = (x: number, y: number): string => `${String(x)},${String(y)}`;
1818

1919
/**
20-
* **The Vulcanus cliff FIELDS are exact at the regions the port is scored on -
21-
* including `[0,0]`, where it is worst** (issue #18).
20+
* **The Vulcanus cliff fields are exact IN THE TILE CHANNEL - which turned out
21+
* not to be the channel the cliff generator reads** (issue #18).
22+
*
23+
* This fixture samples `vulcanus_elevation` and `cliffiness_basic` through
24+
* `LuaSurface.calculate_tile_properties`, whose noise program has a 1-tile grid.
25+
* The cliff generator walks the 4-tile corner lattice, and `multisample`'s
26+
* offsets are in GRID UNITS, so `vulcanus_basalt_lakes_multisample` returns
27+
* different values in the two channels. The port now reads the cliff-channel
28+
* field, so these values no longer reproduce our placement - and must not.
29+
* See `test/multisampleGrid.spec.ts`.
30+
*
31+
* The history below is kept because it is how the wrong channel stayed hidden:
32+
* every check agreed, because the fixture and the port shared the mistake.
2233
*
2334
* PR #57 established this by substituting the game's own `vulcanus_elevation`
2435
* and `cliffiness_basic` into our placement and finding it moved not one cell.

test/vulcanusOreCliffSeparation.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ function gameCornerFields(): { elevation: Map<string, number>; cliffiness: Map<s
399399
const cornerIndex = (x: number, y: number): string =>
400400
key(x / cornerFix.grid, Math.round((y - cornerFix.cornerOffsetY) / cornerFix.grid));
401401

402-
describe("Vulcanus cliffs: the port's FIELDS are exact; the residual is in the RULE", () => {
402+
describe("Vulcanus cliffs: the game's TILE-CHANNEL fields are not the cliff channel", () => {
403403
/**
404404
* The measurement `#18` never had, and the one that resolves `#24`.
405405
*

0 commit comments

Comments
 (0)