Commit da0a888
* Port Vulcanus resources and the 19-tile catalog (#225)
Phase 5's expression chain stopped at elevation. This adds the two layers
above it - `vulcanus_resources` and `tiles/vulcanus_catalog` - plus the
`vulcanus_stack` that binds the whole Vulcanus graph, and `range_select_base`
in `eval/math`, which the rock port will read from there rather than restate.
**Every count agrees with the TypeScript, measured rather than assumed.** All
15 resource fields were scored on both sides against the same fixture with the
same 1/256 capture-grid snap, and they match on the count AND on the worst
residual to every printed digit. So the frozen numbers describe the distance
both ports sit from the game, not a gap between them.
The four starting spots are the load-bearing agreement: 1082, 974, 969 and
1049 of 1085 are the only counts `test/vulcanusResources.spec.ts` freezes
rather than bounds, landed with #279, and this port reproduces all four
without having seen them.
Tile placement lands the same way - 374 of 381 at the forced surface seed and
368 of 381 at a real save's, both matching the TypeScript exactly, with the
raw map seed scoring 37 as the control. That contrast is the point of the
second test: without it, 368 of 381 would look like a strong result for a port
that ignored the seed derivation entirely.
The TypeScript asserts `agreement > 0.978` on the first of those. A bound that
wide cannot see a change worth six tiles, so this side freezes the count -
#162's pathology is exactly what the port exists to stop inheriting.
Two things the anti-vacuity work caught rather than confirmed:
- The all-zero field state has **no tie**, so the tie-break test built on it
would have proven nothing. Its own assertion said so, and the state was
rebuilt from expressions that genuinely collapse onto each other.
- A numeric hook cannot reach the argmax, so `resolve_tile` carries
`poison::index_result` rather than `f64_result` - the same hook Fulgora's
argmax needed for the same reason. All four new tile tests were watched
going red under `--features poison`.
`engine.wasm` is byte-identical: nothing exported reaches these layers yet, so
they are dead code in the wasm build. The render wiring is the next step.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A6kcDigVgZYxzCa5GNZeP9
* Render Vulcanus terrain through the engine, on a per-planet ABI (#225)
The v1 request header was one fixed 104-byte struct with Fulgora's island
sliders and four trig values baked into it. Vulcanus needs 31 more `f64` -
three volcanism and temperature levers, eight resource-control values, and
twenty trig values for its ten per-render bearings.
v2 splits it instead of growing it: a 56-byte common prefix, then a block whose
length the prefix declares. v1's `reserved` word becomes `params_bytes`, which
is what its own comment said it was for, and its `ReservedNotZero` status
becomes `BadParamsLength` - same slot, same code, same job of refusing a writer
that disagrees with its own version word. **A Fulgora request is still exactly
104 bytes**, and Nauvis gets a third block in phase 6 with no further bump.
Tier 3 holds both ways:
- WASM against the TypeScript is byte-identical across four windows that vary
width, height, origin and tiles-per-pixel independently.
- WASM against the game's 1024x1024 PNG differs on **12,423 of 929,686**
compared pixels - 98.664%, which is the TypeScript's own number to four
decimal places, arrived at through a separate path. That is asserted as an
EXACT count rather than the 2% bound `previewAgreement.spec.ts` uses, because
byte-identity means it can be.
The seed trap has its own arm: rendering at the raw map seed instead of
`mapSeed + crc32("vulcanus")` scores an order of magnitude worse, so the
derivation is load-bearing rather than incidental.
**The round-trip fixture's independent checker was measured missing a real
defect, and that is why it grew a third check.** `verify-wasm-request.py` is a
third implementation - not the TypeScript writer, not the Rust reader - and it
cannot reproduce the trig VALUES, because those are V8's `Math.sin` and a
second libm is exactly the disagreement #270 measured. Checking each pair for
unit norm caught a shifted block but **passed a planted swap of two bearings** -
the failure that renders a plausible planet with its biomes rotated. It now
also recovers each angle with `atan2` and checks it against the offset the
game's Lua gives it. Seven planted breaks are caught, up from four.
**The size tripwire fired at 138,642 bytes and was measured before it moved**,
which is what its own comment asks for. Stubbing the Vulcanus dispatch arm
dead-code-eliminates the whole chain: the ABI change alone is +2,072 bytes and
the ported math is +52,399. Nothing unaccounted for got linked in, so the
ceiling goes to 256 KB - the same 1.8x headroom 128 KB kept over phase 3.
Only the bare `terrain` view routes to the module. Vulcanus's rock, cliff and
resource overlays are still TypeScript, so the composite views keep the
TypeScript path, and a test asserts that rather than assuming it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A6kcDigVgZYxzCa5GNZeP9
* Record phase 5's state and the ABI v2 split in CLAUDE.md
Vulcanus now renders through the engine, so the paragraph saying its chain
stops at elevation is out of date. Also records what the round-trip fixture's
independent checker was measured missing - a property check is not a structural
check, and a planted bearing swap is the cheap way to find out which one you
wrote.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A6kcDigVgZYxzCa5GNZeP9
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent ba8fbd8 commit da0a888
21 files changed
Lines changed: 4016 additions & 283 deletions
File tree
- crates
- fmw-noise/src
- eval
- expressions
- tiles
- fmw-wasm/src
- scripts
- src/noise
- preview
- wasm
- test
- fixtures
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1327 | 1327 | | |
1328 | 1328 | | |
1329 | 1329 | | |
1330 | | - | |
1331 | | - | |
1332 | | - | |
1333 | | - | |
1334 | | - | |
1335 | | - | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
1336 | 1345 | | |
1337 | | - | |
1338 | | - | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
1339 | 1361 | | |
1340 | 1362 | | |
1341 | 1363 | | |
| |||
1380 | 1402 | | |
1381 | 1403 | | |
1382 | 1404 | | |
1383 | | - | |
1384 | | - | |
| 1405 | + | |
| 1406 | + | |
1385 | 1407 | | |
1386 | | - | |
1387 | | - | |
1388 | | - | |
1389 | | - | |
| 1408 | + | |
| 1409 | + | |
| 1410 | + | |
| 1411 | + | |
| 1412 | + | |
| 1413 | + | |
| 1414 | + | |
| 1415 | + | |
| 1416 | + | |
| 1417 | + | |
| 1418 | + | |
| 1419 | + | |
| 1420 | + | |
| 1421 | + | |
| 1422 | + | |
| 1423 | + | |
| 1424 | + | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
| 1435 | + | |
| 1436 | + | |
| 1437 | + | |
| 1438 | + | |
1390 | 1439 | | |
1391 | 1440 | | |
1392 | 1441 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
169 | 169 | | |
170 | 170 | | |
171 | 171 | | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
172 | 192 | | |
173 | 193 | | |
174 | 194 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
| 26 | + | |
0 commit comments