Files
VoxelForge/Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md
T
Fr0zkaandClaude Opus 5.5 976d012a86 wip(assembler): round L13 -- one density field for every route (multiplayer determinism fix)
Region pages fell back to the legacy GetDensityAt evaluator while the base shape used the Core
manifest field, so a tile's density (and sometimes mesh) depended on streaming history. Pages
are now bound to their world's base FStandaloneShapeWorld evaluator before publication; density,
lattice, detail, classification and solid queries all delegate to it. WorldAssemblyEvaluatorVersion
5 -> 6. Route-parity audit: fails on L12 (5/5); after the fix 0 mismatches over 87 tile pairs
(base/page, base/native-only, edited, two histories), 56 exact-query pairs, 2.3M page samples,
4 seeds/recipes. Page-tile proof audit: 1,274 blocks, 0 violations. The spawn and island worlds
are unchanged; crossing output changed as intended. Reviewer interleaved spawn: +1.1% (noise).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 01:54:54 +02:00

9.3 KiB
Raw Blame History

VoxelForge M3 Linux13 — route-invariant density

Field decision and fix

The approved reference is the Core base shape built from the reviewed owner manifest: Heightfield2D for SurfaceWorld and FloatingIslandFieldV1 for FloatingIslands. L12's base route sampled that field. Its analytic pages instead fell through to the copied legacy owner GetDensityAt evaluator, so the same key could sample different values after the player crossed into a page. In the L12 SurfaceWorld audit, all 48 base-covered LOD1 candidates had different density; 10 also differed in mesh, payload, and topology. A 214,375-sample L12 negative-control run measured max/mean density delta 0.076171875 / 0.0133467594, 29 sign changes, 170 edge-crossing changes, and up to 1.7778 voxels of surface displacement. The manifest field is the approved Core world and is the reference kept here.

Changing the page manifest flag alone did not fix FloatingIslands: 8/8 page pairs still failed, with max density delta 433.925781, 262,676 sign changes, and 17,188 edge-crossing changes across 343,000 samples. The source fix binds each compiled page to its world's base FStandaloneShapeWorld before publication. Page density, lattice, detail, classification, and solid queries now delegate to that one evaluator; the legacy page-local evaluator is no longer an independent output route. WorldAssemblyEvaluatorVersion is bumped from 5 to 6.

Route parity

The L12 evaluator-v5 negative control fails as required: 5/5 selected base/page pairs mismatch. After the fix, four audits passed: SurfaceWorld seeds 0, 1, and 17, plus FloatingIslands seed 0.

Compared routes Pairs Mismatches
Base vs page (28 clipmap-requested pages; 26 base-covered page controls) 54 0
Base vs native-only shape-free route (SurfaceWorld LOD0) 27 0
Edited base vs edited page 4 0
Same key built in initial and moved-world history 2 0
Tile samples vs exact Core queries at LOD2–8 56 0

All 87 tile-generation pairs match density, mesh, payload, and topology hashes. The 56 higher-LOD pairs compare the sampled tile lattice to direct densityAt / densityAtLattice queries; these also match all sampled densities and solid/air signs. The owner fixture has full_res_clip_levels=2, so analytic page routes exist only at LOD0–1. In total, page comparisons covered 2,315,250 density samples with zero delta, sign, edge-crossing, or surface-root differences; 6,172,229 exact-query samples had zero mismatches. The audit exits nonzero on any output-hash, sample, route-verification, exact-query, or proof-violation mismatch.

The history probe builds the same LOD0 key in a second Core world after a 96 m camera move. Both SurfaceWorld and FloatingIslands match all four hashes across those two build histories. The edit probe applies a sequence-1 density offset centered on a sampled sign crossing; it changes the field, and edited base/page results still match.

Page proof audit

The fill-and-check audit generated page tiles with full density capture and uniform-block proof verification, so it checked the field those pages actually sample. Across the four audits it checked 1,274 blocks / 1,695,694 samples: 518 blocks used the exact fallback, 6 were unknown, and there were zero false proofs or violations. SurfaceWorld walkability passed 5,642/5,642, 6,080/6,080, and 4,785/4,785 samples for seeds 0, 1, and 17; FloatingIslands passed 4,000/4,000. Shape readiness passed 27/27 near-ring tiles where eligible. FloatingIslands has no eligible native-only tiles.

Cost, hashing off

W12, seed 0, --force-generate, camera 0,-35,-487.94, with the same crossing setup as L12:

Move Entering tiles L12 crossing L13 crossing L13 peak RSS
8 m 144 0.0347 s 0.0399 s 468 MiB
16 m 288 0.1249 s 0.0856 s 513 MiB
24 m 432 0.1635 s 0.1242 s 512 MiB
32 m 576 0.1717 s 0.1692 s 511 MiB
1 km 2,260 1.2474 s 0.7696 s 673 MiB

Three W12 spawn runs had medians of 157 ms first tile, 180 ms near ring, and 1.499 s whole view; L12 medians were 146 ms, 161 ms, and 1.361 s. Each spawn run generated the same 2,553-tile benchmark view. The final timings are in Saved/Linux/l13-crossing-final-*.log and Saved/Linux/l13-spawn-final-*.log.

Determinism and invariants

All 28 required configurations passed: SurfaceWorld and FloatingIslands seed 0; Clang -ffp-contract=off and GCC default; W1/W8/W12, with five W12 repeats per compiler and recipe. Each run matched all 12 rows (full detail, whole view, LOD0–8, exact queries) against L12/L11.

Recipe Full detail D/M/P/T Whole view D/M/P/T Exact density / unclamped / detail / collision
SurfaceWorld 0x0ee0579bd15cbbe4 / 0x32e5d4964d610fee / 0x1932b96ee4b1d910 / 0x69743c6bad3447dc 0xc10697a8f48380c7 / 0xe75c9119a1498cd5 / 0x49a9a8d1835a6c8c / 0xedcb23288b5e8724 0xe4d4a8eb95b35933 / 0xe4d4a8eb95b35933 / 0xefcba20c0c70c415 / 0xe604823a249029bf
FloatingIslands 0x6d842d2878b08ef6 / 0x4b868a3184f08035 / 0x2cedf2236788752d / 0xeac17d5e0cb5044a 0x5be4d8cde79b2a76 / 0x96f75041f6861b3a / 0x3700a516cc89d50c / 0x6b99948d6eab4f21 0x61daded9c303becb / 0x61daded9c303becb / 0xefcba20c0c70c415 / 0x84d37463be9b0573

The crossing output changes as intended. The 24 m W1 and W12 moved-tile hashes match each other: 0x337ca62131576728 / 0x7612f48e2ddbbaab / 0x69a67ed4add83b87 / 0xf11ac1ebd0f7ddb8 (D/M/P/T), replacing L12's 0x174588abdc8c0d2c / 0x4c401e27d9d05dea / 0xeb10d9801c5ef125 / 0xf59d12304d0dcb4a.

The L3 FP-contract preamble and runtime self-test, L4 FLazy, L7 shared column cache, L9/L12 proofs, and L11 native-only readiness/crash fixes were preserved. The L6 screen-space controls still pass their six same-LOD checks and reject the missing/floating-surface, global-octave, and stride-2 negative controls as required. Its whole gate still rejects the known far-field error over the 1 px bound (exit 6); the route binding does not affect those LOD3–8 base-field comparisons. The asynchronous MPSC/Epoch path and ARCHITECTURE.md §8.10 invariants are unchanged. No Unreal adapter files were touched; the Core exact-query and collision-sign routes were checked, but Unreal collision cooking was not built here. ARCHITECTURE.md §8.36 and CODEMAP.md §3.22 document the new route law.

Builds and runs used CPUs 0–11, at most 12 workers, a 6 GiB address-space cap, and a 6,000,000,000 byte RSS monitor. The governor remained powersave. Peak sampled RSS was 904 MiB across runs (673 MiB in the no-hash cost table); the GCC build process group peaked at 4.27 GiB. Clang and GCC builds passed. No system changes or Unreal builds were made.

Failed and retried runs

  • l13-route-baseline-s0-w12.log exited 2 because the inferred binary-relative owner JSON path did not exist; reruns used the explicit repository JSON. The first baseline capture used the wrong camera, then an audit pass had empty proof-skipped density captures; the final L12 negative control is l13-route-baseline-s0-w12-r4.log.
  • l13-route-fi-diagnostic.log and l13-route-fi-diagnostic-r2.log intentionally exposed the remaining FloatingIslands split before the shared-source binding; both exit 9 on 8/8 mismatches.
  • l13-route-edit-s0.log exited 9 because its brush did not change the selected tile. Centering the brush on a sampled sign crossing fixed the audit in l13-route-edit-s0-r2.log.
  • l13-route-history-sw-s0.log exited 9 because the second-world probe exceeded the 4,096-node region compiler envelope. The retry compiles one matching LOD0 anchor tile and passes.
  • The first l13-cost-* measurements omitted --force-generate and used the owner JSON start; those are not used above. The final crossing and spawn runs use L12's camera and force-generation setting. The screen-space run's exit 6 is its expected far-field rejection, not a retried run.
  • All final builds, the 28 hash runs, eight no-hash cost runs, and two crossing-hash runs completed within their limits. No commit, push, or stash was made.

Multiplayer note for the owner

Peers with the same manifest, seed, evaluator version 6, and tile key now reconstruct the same Core density and tile output through each available base, page, or native-only route, regardless of arrival history; terrain geometry still does not need to cross the network. Player edits remain an explicit versioned diff that must be ordered and synchronized between peers.

Orchestrator review (Claude)

  • Spawn cost re-run by me, 5 interleaved W12 pairs, no hashing: whole view L12 1.385/1.405/1.419/1.443/1.460 s vs L13 1.401/1.448/1.430/1.435/1.451 s (median 1.419 → 1.435 s, +1.1%, within noise); near ring 0.168 → 0.171 s. The +10% in the cost table above compares L13 runs with L12 numbers from another session; interleaved, there is no measurable spawn regression.
  • The fix is structural: pages are bound to their world's single base FStandaloneShapeWorld evaluator before publication, so routes can't diverge by construction. The negative control fails on L12 (5/5), and the 87 tile pairs, 56 exact-query pairs and 2.3M page samples show 0 mismatches after. The page lifetime is safe because the base shape is owned by the World and outlives its pages.
  • Crossing output changed, as intended (evaluator version 5 → 6); the spawn and island worlds are unchanged.