29 Commits
Author SHA1 Message Date
Fr0zkaandClaude Opus 5.5 f23ab7b9fa wip(L28): passage columns/routes culled per tile (BVH); cost back near L24, bit-identical to L27
GenerateMesh scopes passage queries to the tile's sample bounds with a feature AABB BVH plus
per-passage segment BVHs; L9 proof boxes use a passage-bound BVH. Whole view vs L24: FI ~0%, SW
+3.7% (reviewer interleaved). All hashes equal L27; all passage/route/proof audits pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-21 07:42:16 +02:00
Fr0zkaandClaude Opus 5.5 07b3fe2852 wip(L27, side branch): passages cross open voids inside shared natural rock columns
Unsupported passage runs > 12.5 m become a solid relief-bearing column (ceiling/island to
ground, flared base) with the helix inside, for every recipe; FI anchor uses the same path.
All 4 styles x both recipes: 0/0/0, 0 open-air, naturalness pass; no-long-bridge audit (L26
fails it). Deterministic, Clang = GCC. Look approved; cost +35% SW / +19% FI blocks merge (L28).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-21 04:14:14 +02:00
Fr0zkaandClaude Opus 5.5 37a223046c wip(L26, side branch): every passage style walkable in both recipes (0/0/0); SW bridges look wrong
All 4 styles x both recipes pass capsule, open-air and naturalness audits, and full-view hashes are
deterministic. But the SW passage crosses 355 m of open SurfaceWorld sky as a ~2 km fragmented rock
ramp, which is not natural. L27 replaces long bridges with a shared ceiling-to-ground rock column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-21 02:39:44 +02:00
Fr0zkaandClaude Opus 5.5 ef789aaa00 wip(L25, side branch): FI helix enclosed in a 13 m rock root; support never created in open air
Fixes the L24 ribbon (owner request). NOT merged: the open-air support gate leaves ~4,000 unsupported
samples on every SurfaceWorld-recipe passage style (TN -> SW), a walkability regression. L26 fixes that
on this branch. See Linux25/REPORT.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-21 00:38:57 +02:00
Fr0zkaandClaude Opus 5.5 cb9236c265 wip(assembler): round L24 -- per-strate passage styles; natural Worm default; FI anchor island
Core plans inter-strate passages from each upper strate's FStratePassageConfig for every
generator: Straight / Worm (the new natural default: meander, variable radius, rough walls) /
Spiral / Cascading. A naturalness audit (no >8 m flat runs, >=0.20 m wall relief) fails on L23's
smooth tube. FloatingIslands selects Spiral, with a deterministic unique anchor island (ordinal 2)
joined to the bedrock floor by a rock root. The SW arrival no longer stamps flat shelves.
Capsule audits 0 blocked / 0 unsupported / 0 grade failures, all styles. Full-view hashes
deterministic W1/W8/W12, Clang = GCC (reviewer re-run). Evaluator 10, FI geometry 5.
KNOWN: the FI helix renders as a spiral ribbon in open air around the pillar instead of a tunnel
enclosed in rock; fix next round. Unreal edits uncompiled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 21:42:21 +02:00
Fr0zkaandClaude Opus 5.5 71d09a8c52 wip(assembler): round L23 -- inter-strate passages planned from the resolved layout and carved
After L22 the FI -> SW passage no longer connected the strates (legacy owner-voxel coordinates,
lower end 23 m above SW), and Core never carved passages through the bands. Now the director
plans passages from the resolved layout (PlanResolvedLayoutPassagesV1; deterministic hash of
seed/strates/connection; placement disk from PassageConfig, 8-24 m around (0,0)); shared
composition applies generator field -> bands -> bounded passage carve and support shelf, opening
the bands only along the tunnel. Mouths bind to the strate routes. Capsule audit: 0 blocked /
0 unsupported (325,962 samples FI, 284,319 TunnelNetwork), negative controls detected; all 8
generator kinds exercised. SW away from the passage is bit-identical. Layout V3, evaluator 9.
Open: look not yet natural (stepped tube in FI void, terraced SW arrival); SW-as-upper route
planning fails; Unreal adapter uncompiled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 18:22:12 +02:00
Fr0zkaandClaude Opus 5.5 55c26a05a7 wip(assembler): round L22 -- one 8 m layout chunk for every strate; real ceiling -> content -> bedrock
StrateLayoutChunkSizeMeters (world setting, default 8 m; owner decision) is resolved once in
the director/adapter and standalone loader; every generator reads the resolved width (no
CHUNK_SIZE / Core-tile inference). Every strate gets solid ceiling and bedrock bands from its
BoundarySealThickness in the shared composition path (diggable by default); faces come from the
shared boundary path. Owner world: FloatingIslands +8..-120 m (128 m, now with a bedrock floor),
SurfaceWorld -120..-632 m (unchanged; full-detail and exact-query hashes equal L21); the 60 m gap is
gone. The strict layout validator passes on the real world, with 0 endpoint dispatch
disagreements. Spawn/benchmark camera derived from route.front. Ledges under the islands gone
(reviewer capture). Evaluator 7, recipe schema 2, layout snapshot 2, FI geometry 4.
Open: SW cap profiles exceed the ceiling band (owner call); transitions still Hard; Unreal
setting/manager/adapter edits uncompiled here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 12:03:14 +02:00
Fr0zkaandClaude Opus 5.5 8753f6dbe4 wip(assembler): round L21 -- resolved strate layout snapshot + validator (no world change)
Core ResolvedLayoutSnapshotV1 (canonical JSON, stable identity): per strate stable ID, generator,
recipe, interior bounds in metres, ceiling/bedrock bands as Core really applies them, transition
mode/width, dispatch provenance. Validator: compat mode reports today's deviations; strict mode
enforces ceiling -> content -> bedrock -> next ceiling (owner rule), two separate bands, nominal
contiguity, interpenetration only within the declared EVoxelStrateTransition width; 7 negative
controls rejected. Findings: SW built at -120..-632 m although the params say -60 m; a 60 m unowned
gap filled by analytic FI fallback; no active bedrock bands; transitions ignored by Core.
All L19 hashes unchanged (28 + 14 crossing runs). The Unreal adapter exports resolved_layout
(uncompiled here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 10:22:00 +02:00
Fr0zkaandClaude Opus 5.5 5d5447dc32 docs(assembler): Sol 6.1 review of the L20 strate/units design
Verdict: direction right; preserve today's bounds as compatibility data but reject overlaps in new
layouts; approve the LOD2 boundary fix with a precise affected region; one director-owned vertical
partition (strate interior / shared bedrock band / explicit void); bedrock = solid volume + explicit
LOD-stable surface; first step = versioned resolved-layout snapshot + validator, no output change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 09:20:33 +02:00
Fr0zkaandClaude Opus 5.5 6f9c7bd652 docs(assembler): round L20 -- design for director / generators / mesher, layout in metres
Standalone/DESIGN_STRATA_UNITS_AND_LAYERS.md: maps today's code to the three layers, ranks 9
violations (top: no single physical stratum-bounds/interface record; SurfaceWorld 8 m vs
FloatingIslands 4 m per chunk), defines the director-resolved generator request/result contract,
moves seals/caps/voids/interfaces into shared composition, and proposes an explicit LOD-stable
interface surface for the L19 ledges. 6-step migration plan with "worlds don't move" checks;
owner decisions listed. No code or world change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 08:53:03 +02:00
Fr0zkaandClaude Opus 5.5 811c4b7b17 wip(assembler): round L19 -- strate ceilings closed at every LOD; ledges diagnosed
The shared boundary-cap path now emits a cap wherever the field is solid just below a strate's
configured top (it previously required a solid-to-air crossing there) and checks a 5x5 perimeter
grid before suppressing a fallback cap. Strict audit: 0 misses / 0 edge gaps, LOD0-8.
farHorizonVersion 3 -> 4. SurfaceWorld LOD0-2, full detail and exact queries unchanged; 28/28
matrix plus 14/14 crossing; route parity and proofs pass.
Ledges: the lower stratum's terrain at the FI/SW interface, seen through the FI void, sampled at
0.5/1/2 m at LOD1-3 (up to 1.5 m / 7.7 m ring steps). Fix deferred to the units/layers round.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 08:46:29 +02:00
Fr0zkaandClaude Opus 5.5 dcf0763ec5 wip(assembler): round L18 -- FloatingIslands false floors removed; shared strate ceiling
FI geometry v3 drops the all-XY lower boundary seal that created false floors (3.5/8 m); the
ceiling comes from the shared VF_ApplyUpperBoundarySeal and AppendStratumBoundaryCeilings path
for every generator, at each strate's own configured upper boundary (owner: every strate has a
ceiling). Far-LOD ceiling continuity: 0 gaps at LOD4-8. SurfaceWorld bit-identical to L14
(14 configs + 24 m crossing); FI deterministic (28-row matrix); route parity and proofs pass.
Unreal: FI geometryVersion 2->3 and the shared upper-seal helper extracted (UBT compile needed on
the owner PC). Open: small ceiling holes; lower-stratum LOD ring steps seen through the FI void.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 07:55:53 +02:00
Fr0zkaandClaude Opus 5.5 87041290dd docs+tool(assembler): round L17 report; readable shading in the Linux capture tool
The capture tool gains --shade=readable (directional light, soft ambient, height tint) and an
optional --tile-edges overlay; display only. The L17 Core fix is NOT merged: its owner/Core chunk
scale change (8 m -> 4 m) moves every stratum and leaves the SurfaceWorld spawn camera over a void
(reviewer before/after renders). Kept on wip/l17-fi-scale. The FloatingIslands full-XY
boundarySeal cap is the likely real cause of the false floors and needs a separate minimal fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 05:53:17 +02:00
Fr0zkaandClaude Opus 5.5 9a7c87e47b docs(assembler): round L16 report -- disk terrain cache design + prototype (code on side branch)
Lossless zlib halves the size; loaded tiles are exact; corrupt/stale files are rejected and
regenerated; zero cost when off. Code is on wip/l16-tile-cache until it is made Windows-safe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 04:19:56 +02:00
Fr0zkaandClaude Opus 5.5 a6cd7cf339 docs(assembler): round L15 report -- no far-mesh saving fits the owner's pixel budget
Refine x2 at LOD4-8 would save 13.6% of whole view but smooths far crests and opens holes
(gate and captures agree); connector shortcuts open gaps. Default far output is unchanged; the
code is on side branch wip/l15-far-budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 03:29:14 +02:00
Fr0zkaandClaude Opus 5.5 a176d0743a wip(assembler): round L14 -- far-LOD cost counted; no exact-output lever above 3% (opt-in counters)
Plain W12 far work: LOD6 2.59, LOD8 2.05, LOD4 1.57, LOD5 1.41, LOD7 1.16 worker-s. Ground/cap
refinement ~3.95 worker-s and LOD6 connector repair 1.40 worker-s (82% uncached formula calls)
build visible geometry; no bit-identical reduction proved. Adds opt-in far-shell column counters
(reviewed: no cost when off, interleaved 1.429 vs 1.419 s). All hashes, the crossing hash and route
parity are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 02:33:48 +02:00
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
Fr0zkaandClaude Opus 5.5 32b8670833 wip(assembler): round L12 -- region pages keep LOD1 block proofs: 24 m crossing 5x faster
Analytic region pages now retain the immutable shared manifest, so LOD1 page tiles get the L9
uniform-block proofs (71.7 -> 5.6 ms per tile). Reviewer W12 no-hash: 24 m crossing 0.898 ->
0.166 s; Luna: 1 km 5.89 -> 1.25 s. Spawn unchanged; all L1/FloatingIslands hashes and the 24 m
crossing hash unchanged (W1/W12).
KNOWN BUG (pre-existing, measured here): the same tile key yields different density from the base
shape (manifest field) than from a region page (legacy field), sometimes different mesh too, so
output depends on streaming history. To be fixed in L13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 01:07:47 +02:00
Fr0zkaandClaude Opus 5.5 b1cfaf53b8 wip(assembler): round L11 -- fix 24 m+ crossing crash; near ring ready 2x sooner at spawn
Crash: crossing tiles were coalesced into one huge rectangle, and BuildSpatialBins tried to
resize to ~4.3e17 bytes (std::bad_alloc; the L7 32 m failure had the same cause). Analytic
regions now skip unread dense bins and compile in world-aligned 128-voxel pages, published
together; out-of-range keys error before allocation. 24 m, 32 m and 1 km crossings pass
(1 km: 72 pages, peak RSS 700 MiB).
Spawn: World::isTileShapeFree proves LOD0 SurfaceWorld tiles that never read the cave shape;
those start before shape compile, and all others wait. Reviewer W12 no-hash: near ring 0.337 ->
0.159 s, whole view +2.1%. All SurfaceWorld/FloatingIslands hashes unchanged (W1/W8/W12, both
compilers, forced-overlap run). Unreal VoxelWorld.cpp adapter changed but NOT built here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 00:28:58 +02:00
Fr0zkaandClaude Opus 5.5 b370908174 docs(assembler): round L10 report -- spawn waits on the full shape; 24 m crossing hits bad_alloc
First tile starts ~300 ms after cold start: plan 51 ms (serial), shape compile 223 ms (caves,
signs, detail band, far parents). The first SurfaceWorld tiles use the native heightfield and do
not read that shape, but generateTile requires the full base shape. 8/16 m crossings repeat no
compile (61 ms for 288 tiles); a 24 m crossing died with std::bad_alloc under the 6 GiB
address-space cap (cause unknown). Telemetry not committed (+1% when off).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-19 23:44:52 +02:00
Fr0zkaandClaude Opus 5.5 7650abb755 wip(assembler): round L9 -- LOD1 skips proven-uniform blocks: 95% fewer samples, view ~2% faster
Step-2 (LOD1) tiles of native SurfaceWorld now prove 8-cell blocks uniform from exact heightfield
column extrema over the padded block (cells + normal halo) and skip their density fill; features,
edits, mixed strata and Unknown verdicts still fill. LOD1 samples 42,875 -> 2,063 per tile.
Audit: 80,502 skipped blocks (3 seeds) + 9,216 island blocks force-filled, 0 violations. All
SurfaceWorld and FloatingIslands hashes unchanged at W1/W8/W12, Clang off and GCC default.
Reviewer interleaved W12, no hashing: whole view 1.439 -> 1.409 s. L8 phase probes removed;
--profile-lod-work and --audit-uniform-block-proofs are opt-in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-19 23:14:16 +02:00
Fr0zkaandClaude Opus 5.5 82813fb13b docs(assembler): round L8 report -- where the time goes after the shared cache
W12 L1 view: tile work 17.3 worker-s finishes 4 ms from ideal 12-way scaling; the remaining
~0.28 s is startup (shape compile 215 ms). Largest lever: LOD1 density-grid fill (3.35 worker-s;
proof blocks are gated to steps 1 and 8). LOD6's 4x columns = far connector-shell repair (1.38
worker-s). No code committed: the diagnostic instrumentation stays uncommitted for L9.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-19 22:10:05 +02:00
Fr0zkaandClaude Opus 5.5 4b1108bf86 wip(assembler): round L7 -- shared column cache across workers: whole view 16-19% faster, world unchanged
SharedColumnCache.h: a world-owned, bounded 4-way second-tier cache of exact column values
(heightfield and floating islands), keyed by recipe/plan identity plus content hash, XY and island
id. Lock-free seqlock reads; set-local spin lock on misses. The FLazy thread-local tier stays
first. 83.6% of repeated column work was cross-worker; formula evaluations -60.9%.
W12 L1 view: Luna 2.165 -> 1.754 s; reviewer interleaved 2.059 -> 1.722 s. 8 m crossing new tiles
82 -> 52 ms. +66 MiB peak RSS. All hashes (whole view, per-LOD, exact queries, islands seed 0)
identical at W1/W8/W12, Clang off and GCC default. MSVC/UBT not compiled here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-19 21:46:15 +02:00
Fr0zkaandClaude Opus 5.5 9898e057fd wip(assembler): rounds L5+L6 -- Linux far-terrain captures and screen-space gate (world unchanged)
Linux offscreen capture (EGL/GLES pbuffer; llvmpipe in the sandbox) and an opt-in screen-space gate
for LOD>=3 (normal distance projected at each LOD's closest display distance, 1 px at 1440p =
0.61 mrad). The gate rejects the S13 octave-drop and stride-2 controls, fault injections, and a
vertical-vs-screen control. Finding: today's far meshes differ from the field by up to 92 px, and
LOD swaps snap mesa rims by tens of px (p50 0 px), a silhouette effect of plain LOD switching. The
octave cutoff was dropped: nothing qualified, and octaves are a small share of far time. Off-path
cost: reviewer interleaved W12 within noise vs L4 (+0.6% median). Hashes = L4.
Largest far lever measured: column work outside noise, 34% of far worker time (duplicate XY across tiles).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ED33VnqepD4YY6gDAAA832
2026-10-19 21:10:08 +02:00
Fr0zkaandClaude Opus 5.5 7770074503 wip(assembler): round L4 -- lazy per-thread caches: 17.3 MiB -> 43 KiB per thread, view 7% faster
VoxelForgeCoreThreadLocal::FLazy<T> (new public header ThreadLocalStorage.h) makes every large
thread_local cache a pointer that heap-allocates on that thread's first use (still worker-private,
lock-free). Static TLS 17.33 MiB -> 43 KiB (initialised image 5.8 MiB -> 21 KiB); worker start
5.2 -> 0.12 ms; idle worker RSS 17.7 MiB -> 52 KiB. Linux workers back to 8 MiB stacks.
World unchanged (L1 hashes Clang off/GCC default, W1/W12; FloatingIslands seed 0).
Reviewer interleaved W12: 2.256 -> 2.091 s. MSVC/UBT not compiled here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ED33VnqepD4YY6gDAAA832
2026-10-19 19:16:14 +02:00
Fr0zkaandClaude Opus 5.5 046f2af495 wip(assembler): round L3 -- Core forces FP contraction off and refuses to generate if it can't
CoreNamespacePreamble.h applies per-compiler contraction-off pragmas (Clang, MSVC, GCC; unknown
compiler = #error) and a fused-multiply-add self-test that World::compile runs before building.
Clang -ffp-contract=on and GCC's default (fast) now reproduce the L1/Windows hashes (they diverged
in L2); Clang -ffp-contract=fast ignores the pragma and is refused at startup (negative control).
Seed sweep with every cube on real terrain: 48 seeds x 2 recipes x 3 builds x W1/W12, 576 runs,
0 mismatches, 0 empty meshes. Cost +0.5% (2.326 -> 2.337 s, interleaved). World unchanged.
MSVC/UBT not compiled here: Windows to-do list in Linux3/REPORT.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:51:07 +02:00
Fr0zkaandClaude Opus 5.5 303b7b9f24 wip(assembler): round L2 -- the cross-platform hash check can fail; FP contraction changes the world
Clang -ffp-contract=on/fast and GCC's default (fast) all change the density hash on the L1 view;
contraction off reproduces L1 (= Windows S13) at W1/W12. Seed sweep: 48 FloatingIslands seeds and
14 effective SurfaceWorld seeds (34 of 48 fell on a seed-independent cube) match across Clang/GCC
and W1/W12. Standalone gains --seed/--recipe/--render-distance-chunks (viewer + headless) and a
Windows replay script. Linux standalone workers get 32 MiB pthread stacks (TLS is 17.3 MiB/thread),
so no external stack limit is needed. No Core or world-output change; MSVC compile unverified.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:18:34 +02:00
Fr0zkaandClaude Opus 5.5 1276fd11e3 wip(assembler): round L1 -- Linux baseline on abyss: Linux world identical to Windows
Headless Linux benchmark/hash tool (Clang 19 / GCC 14) sharing the viewer's plan builder and
streaming pipeline (moved verbatim into StreamBenchmarkPipeline.h / WorldAssemblyPrototype.h).
Owner Round17 view: density/mesh/payload/topology hashes equal the Windows S13 reference at
W1/W8/W12 (Clang, 3 runs each) and W8 (GCC), with -ffp-contract=off. No output change.
Baseline (i9-12900H, CPUs 0-11, powersave/balance_performance): whole view W8 3.562 s median,
W12 3.512 s, W1 16.555 s; peak RSS < 605 MiB.
Review: the default-stack crash is 17.3 MiB of static TLS per thread (glibc puts it in the
thread stack; HeightfieldColumnCache 6.8 MB), not recursion -- open, after S14.
MSVC compile of the viewer refactor not verified (no MSVC here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:18:34 +02:00
Fr0zkaandClaude Opus 5.5 ec2afe9c93 wip(assembler): round S14 -- 4-way column cache + memoized MC gradients (output unchanged)
Worker-local XY column cache uses deterministic 4-way sets at LOD3-8: LOD4
misses 8,224 -> 1,437, conflicts 7,407 -> 0 (direct-map control: 6.62 s /
43.5 worker-s vs 4.24 s / 21.7). Exact LOD0 lattice gradients memoized per
tile: MC-exclusive 242 -> 201 ns/sample, two-pass loop unchanged. Hashes
identical, no recipe bump. Primary cold trace 4.24 s full set, ring 0.45 s,
75/75 at 40 m/s; a repeat ran uniformly ~40% slower on every LOD (machine
contention suspected); tick p95 to re-check on an idle machine. CVars
voxel.CoreColumnCacheDirectMapped / voxel.CoreMCGradientMemoization.
Report: Standalone/Research/WorldAssemblerM3/Round18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
2026-10-19 17:58:54 +02:00
194 changed files with 21339 additions and 1356 deletions

No files matched your search

+278 -5
View File
@@ -73,7 +73,7 @@ is the only density path; a degenerate (zero-height) strate has none and is open
| Maze | `FMazeGenerationParams` | `BuildMazeStack` | origin-directed spanning-tree corridors on a 3D lattice, with capped loop edges and a thread-local per-cell capsule cache | | Maze | `FMazeGenerationParams` | `BuildMazeStack` | origin-directed spanning-tree corridors on a 3D lattice, with capped loop edges and a thread-local per-cell capsule cache |
| SurfaceWorld | `FSurfaceGenerationParams` | `BuildSurfaceStack` | heightfield terrain: domain-warped continents+ridged mtns+detail, a low-freq **relief map** (`M`) that scales mountains/elevation for plains↔highland variety, **F20 heightfield terrain ops** (`Surface|Ops` — all default off ⇒ byte-identical): **Cliff** (slope-gated steepening — where the analytic structural slope > `CliffSlopeThreshold`, push the height away from the local mean by `CliffSharpness` ⇒ gentle slopes become sheer walls/canyon faces that hug real steep ground, gentle areas untouched; 4 structural resamples only when enabled), **Terrace** (relief-gated plateau quantize + `TerraceHardness` soft-round↔crisp-mesa), **LayerLines** (sedimentary sine shelves, slope-expressed) — pure per-column height remaps in the single oracle `ComputeSurfaceTerrainZ` (`SampleSurfaceStructuralZ` = pre-op raw height, re-sampled at an XY offset for Cliff's slope), biome-selected + border-blended for free via each biome's `SurfaceParams` + the height output-lerp; plus **phase-2 Overhang** (the first VOLUMETRIC op — real jutting shelves like a cliff lip): in `FOverhangShelfMod`, for AIR voxels in the window `(TerrainZ, TerrainZ+OverhangHeight]` above a steep slope, the heightfield is re-sampled UPHILL (toward the cliff) by a reach that GROWS with height and unioned in. Low in the window the shift is ~0 (borrows nearby low rock ⇒ stays air over the void); high up it reaches the far cliff (solid) ⇒ a shelf attached to the cliff, tapering out over the void with air underneath. Per-column `OverhangAmp`(=strength·slope-gate) + unit uphill dir `(DirX,DirY)` are resolved once in `ComputeSurfaceColumn` — the gradient sampled at the REACH scale (`OverhangReach`) so a point out over the void can "see" the cliff to know which way is uphill — and cached on `FSurfaceColumn`. It's genuine 3D (per-voxel structural re-eval), so it's gated hard to steep overhang columns; the union only ADDS rock (never removes), capped at `TerrainZ+OverhangHeight`, so `ClassifyTile` forces Mixed only in `(TerrainZ, TerrainZ+OverhangMargin]` (upward-only; margin = max `OverhangHeight`) — a shelf never holes a trivially-skipped tile, and only the thin cliff-edge band of air tiles is woken (NOT far-field like phase-3 spikes/holes). Overhang undersides classify as ground rock by the F17 rule (down-facing but below `TerrainZ`). Known v1 limit: applies at all LODs (Step-agnostic) — may alias far; gate to fine tiles later. Beaches at water line, high sky-cap ceiling. The cap is shapeable terrain in its own right (`ComputeSurfaceCeiling`, `Surface|Sky` params: `CeilingUndulation` broad inverted hills/valleys, `CeilingRidgeStrength` hanging ridgelines, `CeilingRoughness`+freq fine bumps, `CeilingWarp*`) — defaults (strengths 0, freq 0.04) = old flat-ish cap. (`Surface|Macro` params = the cheap precursor to biomes; `ReliefStrength=0` ⇒ old uniform terrain.) **Sky-cap vs ground is a PER-TRIANGLE surface class (F17), not a per-tile verdict**: the mesher classifies each unique vertex on the **worker** — only down-facing verts (`N.Z<-0.1`) pay a memoized `GetSurfaceHeightAt` column query; nearer `CeilSurf` ⇒ sky-cap, nearer `TerrainZ` ⇒ terrain overhang stays ground (a future SurfaceWorld cave roof — down-facing but below `TerrainZ` — also lands ground by the same rule; non-surface strates always ground). Triangles take the majority class of their 3 verts and are packed as **two contiguous index runs** (ground then cap, `FVoxelMeshData::NumCeilingTriangles`; skirts inherit their source triangle's run) → RMC **polygroups 0/1** → one **section per non-empty group** (`ApplyMeshToTile`, material slot = group index): slot 0 = strate `OverrideMaterial`/default (min-corner chunk), slot 1 = `CeilingMaterial` resolved at the tile's **TOP chunk** (mid as gap fallback, then min; fallback: ground material) — a coarse tile is 2^level chunks tall, so its min corner can sit in a lower strate/gap while the cap belongs to the strate above (this was the "far cap = ground material" residue), so the shadowless overhead rock is tinted separately instead of reading flat/bright. Shadow is **per section** via `FRealtimeMeshSectionConfig::bCastsShadow` (NOT the component `SetCastShadow` — RMC's proxy ignores the component flag; this is also why level≥2 far tiles only stopped casting once the section flag was wired): ground casts at level≤1, the cap section never casts, so the rock ceiling never shadows the terrain below it. History: v1 was a game-thread centre height-oracle (misclassified coarse far tiles → terrain material on the cap underside); v2 a whole-tile worker normal VOTE — which painted **mixed coarse tiles** (one far tile spanning terrain AND cap) entirely with the winner's material, and put sky material under terrain overhangs. The per-triangle class fixes both and is the identity channel caves/F8 will reuse. | | SurfaceWorld | `FSurfaceGenerationParams` | `BuildSurfaceStack` | heightfield terrain: domain-warped continents+ridged mtns+detail, a low-freq **relief map** (`M`) that scales mountains/elevation for plains↔highland variety, **F20 heightfield terrain ops** (`Surface|Ops` — all default off ⇒ byte-identical): **Cliff** (slope-gated steepening — where the analytic structural slope > `CliffSlopeThreshold`, push the height away from the local mean by `CliffSharpness` ⇒ gentle slopes become sheer walls/canyon faces that hug real steep ground, gentle areas untouched; 4 structural resamples only when enabled), **Terrace** (relief-gated plateau quantize + `TerraceHardness` soft-round↔crisp-mesa), **LayerLines** (sedimentary sine shelves, slope-expressed) — pure per-column height remaps in the single oracle `ComputeSurfaceTerrainZ` (`SampleSurfaceStructuralZ` = pre-op raw height, re-sampled at an XY offset for Cliff's slope), biome-selected + border-blended for free via each biome's `SurfaceParams` + the height output-lerp; plus **phase-2 Overhang** (the first VOLUMETRIC op — real jutting shelves like a cliff lip): in `FOverhangShelfMod`, for AIR voxels in the window `(TerrainZ, TerrainZ+OverhangHeight]` above a steep slope, the heightfield is re-sampled UPHILL (toward the cliff) by a reach that GROWS with height and unioned in. Low in the window the shift is ~0 (borrows nearby low rock ⇒ stays air over the void); high up it reaches the far cliff (solid) ⇒ a shelf attached to the cliff, tapering out over the void with air underneath. Per-column `OverhangAmp`(=strength·slope-gate) + unit uphill dir `(DirX,DirY)` are resolved once in `ComputeSurfaceColumn` — the gradient sampled at the REACH scale (`OverhangReach`) so a point out over the void can "see" the cliff to know which way is uphill — and cached on `FSurfaceColumn`. It's genuine 3D (per-voxel structural re-eval), so it's gated hard to steep overhang columns; the union only ADDS rock (never removes), capped at `TerrainZ+OverhangHeight`, so `ClassifyTile` forces Mixed only in `(TerrainZ, TerrainZ+OverhangMargin]` (upward-only; margin = max `OverhangHeight`) — a shelf never holes a trivially-skipped tile, and only the thin cliff-edge band of air tiles is woken (NOT far-field like phase-3 spikes/holes). Overhang undersides classify as ground rock by the F17 rule (down-facing but below `TerrainZ`). Known v1 limit: applies at all LODs (Step-agnostic) — may alias far; gate to fine tiles later. Beaches at water line, high sky-cap ceiling. The cap is shapeable terrain in its own right (`ComputeSurfaceCeiling`, `Surface|Sky` params: `CeilingUndulation` broad inverted hills/valleys, `CeilingRidgeStrength` hanging ridgelines, `CeilingRoughness`+freq fine bumps, `CeilingWarp*`) — defaults (strengths 0, freq 0.04) = old flat-ish cap. (`Surface|Macro` params = the cheap precursor to biomes; `ReliefStrength=0` ⇒ old uniform terrain.) **Sky-cap vs ground is a PER-TRIANGLE surface class (F17), not a per-tile verdict**: the mesher classifies each unique vertex on the **worker** — only down-facing verts (`N.Z<-0.1`) pay a memoized `GetSurfaceHeightAt` column query; nearer `CeilSurf` ⇒ sky-cap, nearer `TerrainZ` ⇒ terrain overhang stays ground (a future SurfaceWorld cave roof — down-facing but below `TerrainZ` — also lands ground by the same rule; non-surface strates always ground). Triangles take the majority class of their 3 verts and are packed as **two contiguous index runs** (ground then cap, `FVoxelMeshData::NumCeilingTriangles`; skirts inherit their source triangle's run) → RMC **polygroups 0/1** → one **section per non-empty group** (`ApplyMeshToTile`, material slot = group index): slot 0 = strate `OverrideMaterial`/default (min-corner chunk), slot 1 = `CeilingMaterial` resolved at the tile's **TOP chunk** (mid as gap fallback, then min; fallback: ground material) — a coarse tile is 2^level chunks tall, so its min corner can sit in a lower strate/gap while the cap belongs to the strate above (this was the "far cap = ground material" residue), so the shadowless overhead rock is tinted separately instead of reading flat/bright. Shadow is **per section** via `FRealtimeMeshSectionConfig::bCastsShadow` (NOT the component `SetCastShadow` — RMC's proxy ignores the component flag; this is also why level≥2 far tiles only stopped casting once the section flag was wired): ground casts at level≤1, the cap section never casts, so the rock ceiling never shadows the terrain below it. History: v1 was a game-thread centre height-oracle (misclassified coarse far tiles → terrain material on the cap underside); v2 a whole-tile worker normal VOTE — which painted **mixed coarse tiles** (one far tile spanning terrain AND cap) entirely with the winner's material, and put sky material under terrain overhangs. The per-triangle class fixes both and is the identity channel caves/F8 will reuse. |
| VerticalShafts | `FVerticalShaftParams` | `BuildVerticalShaftStack` | full-height shafts + horizontal connectors + partial ledges | | VerticalShafts | `FVerticalShaftParams` | `BuildVerticalShaftStack` | full-height shafts + horizontal connectors + partial ledges |
| FloatingIslands | `FFloatingIslandParams` | `BuildFloatingIslandStack` | asymmetric islands: flat land top + underside tapering to a point, lobed (domain-warped) outline, in an open void | | FloatingIslands | `FFloatingIslandParams` | `BuildFloatingIslandStack` | asymmetric islands: flat land top + underside tapering to a point, lobed (domain-warped) outline, beneath the shared ceiling at its configured strate upper boundary |
| Underwater | `FStrateGenerationParams` + water | (reuses `BuildTunnelNetworkStack`) | tunnel rock + high water table | | Underwater | `FStrateGenerationParams` + water | (reuses `BuildTunnelNetworkStack`) | tunnel rock + high water table |
All stacks share the convention: internal **positive=solid**, and `AppendStructuralPost` ends every All stacks share the convention: internal **positive=solid**, and `AppendStructuralPost` ends every
@@ -648,6 +648,7 @@ driven by `EditorBrush*` props.
two global settings through `FVoxelOpContext` once per chunk, while `ClassifyBox`/`ClassifyTile` two global settings through `FVoxelOpContext` once per chunk, while `ClassifyBox`/`ClassifyTile`
share the radial proof. This adds no cache, state, RNG, or clipmap stream, and does not touch the share the radial proof. This adds no cache, state, RNG, or clipmap stream, and does not touch the
density grid's two-pass MC loop or any existing `thread_local` cache. density grid's two-pass MC loop or any existing `thread_local` cache.
- **Large `thread_local` caches are lazy** (`VoxelForgeCoreThreadLocal::FLazy<T>`, `Standalone/Core/include/VoxelForgeCore/ThreadLocalStorage.h`, round Linux4): the per-thread handle is a pointer; the table is heap-allocated on that thread's first use and freed at thread exit. Still worker-private and lock-free. It keeps the static TLS block at ~43 KiB instead of 17.3 MiB (glibc carves static TLS out of each thread's stack, and a Linux server pays it on every thread). New cache tables over a few KiB go through `FLazy`, never a bare `thread_local` array.
- **Biome cache** (`ResolveBiomeSampleAt`/`FChunkBiomeCache`, §8.14): validity is a world-XY BOX + - **Biome cache** (`ResolveBiomeSampleAt`/`FChunkBiomeCache`, §8.14): validity is a world-XY BOX +
ChunkZ + Seed, NOT a chunk key — same reason as the SDF cache. The cell classification is ChunkZ + Seed, NOT a chunk key — same reason as the SDF cache. The cell classification is
noise-heavy; a chunk-key would thrash it on gradient-normal / +X/+Y boundary samples. Keep noise-heavy; a chunk-key would thrash it on gradient-normal / +X/+Y boundary samples. Keep
@@ -694,6 +695,10 @@ driven by `EditorBrush*` props.
position → seamless across chunk borders (both sides use identical pure samples). NO per-vertex position → seamless across chunk borders (both sides use identical pure samples). NO per-vertex
`GetDensityAt` (was ~6/vertex, often as costly as the whole grid). `ComputeGradientNormal` is now `GetDensityAt` (was ~6/vertex, often as costly as the whole grid). `ComputeGradientNormal` is now
unused. Only NORMALS changed vs the old path; geometry is identical. unused. Only NORMALS changed vs the old path; geometry is identical.
Round 18 memoizes these exact central-difference `FVector`s in per-worker scratch arrays for the
step-1 ShapeWorld path. Validity is reset for each tile; cache hits return the same vector and do
not bypass the density grid, halo, or two-pass cell loop. Keep the cache worker-local and exact;
do not move gradient probes above the surface-cell test.
- **Core hybrid sharp mesher (M2)** (`CoreMesherRecipe` / `MesherRecipe`): the property remains - **Core hybrid sharp mesher (M2)** (`CoreMesherRecipe` / `MesherRecipe`): the property remains
opt-in and defaults to `MarchingCubesV1`; `bUseVoxelForgeCore` remains separately default-off. opt-in and defaults to `MarchingCubesV1`; `bUseVoxelForgeCore` remains separately default-off.
V1 preserves the round-3 feature-aware dual-contouring path for repeatability. V2 reuses the V1 preserves the round-3 feature-aware dual-contouring path for repeatability. V2 reuses the
@@ -727,6 +732,15 @@ driven by `EditorBrush*` props.
its default member initialization was never observable; removing that generated TLS leaf avoids its default member initialization was never observable; removing that generated TLS leaf avoids
constructor work without changing a height or density. Integer queries still read the cached constructor work without changing a height or density. Integer queries still read the cached
payload, and fractional queries still use the same direct locals. payload, and fractional queries still use the same direct locals.
- **Core shared column cache (L7)**: `Heightfield2D` and FloatingIslands keep their `FLazy`
worker-local caches as the first tier. A world-owned, fixed-size four-way table is the second
tier, keyed by recipe and plan identity plus content hash, exact XY, and an optional exact
sub-domain identity (FloatingIslands uses the island stable ID). Hits read versioned atomic
entries without taking a lock; misses take only their set's spin lock, recheck, compute once, and
publish. The tables are bounded and die with the world after its tile work has drained. This
deliberately adds shared reads on column-cache hits while preserving the no-lock hot-path rule;
S14's purely worker-local cache remains the first lookup. Keep large worker-local storage behind
`FLazy`, and do not make cache values or keys depend on engine objects.
- **Sampler unknown-source audit**: the earlier plugin-side `FSurfaceColumn` constructor PCs no longer - **Sampler unknown-source audit**: the earlier plugin-side `FSurfaceColumn` constructor PCs no longer
occur after the trivial-payload change. The largest remaining LOD0 unknown cluster in the final occur after the trivial-payload change. The largest remaining LOD0 unknown cluster in the final
sampler raw CSV is `UnrealEditor-Core.dll + RVA 0xC080` (runtime PCs around sampler raw CSV is `UnrealEditor-Core.dll + RVA 0xC080` (runtime PCs around
@@ -1417,8 +1431,9 @@ density roots, including a 100 cm datum-offset negative control. See
evaluators keep their recorded cap behavior. The clip joins the exact near density root at the owning evaluators keep their recorded cap behavior. The clip joins the exact near density root at the owning
boundary without changing LOD0–3 density hashes. Future families with planar roofs must declare their boundary without changing LOD0–3 density hashes. Future families with planar roofs must declare their
cap height and bounds through the family plan/provider contract; the shared tile generator consumes cap height and bounds through the family plan/provider contract; the shared tile generator consumes
that declaration. FloatingIslands declares no planar roof, so open sky above a surface island is the that declaration. FloatingIslands uses the same resolved strate-boundary data flow: its upper seal
expected view. follows its plan's chunk range and the shared boundary-seal primitive, while SurfaceWorld keeps its
existing heightfield cap.
For each requested far SurfaceWorld XY column at LOD4–8, desired-tile selection adds cap-height For each requested far SurfaceWorld XY column at LOD4–8, desired-tile selection adds cap-height
bands only when they do not overlap an existing or already accepted 3D clipmap tile. The original bands only when they do not overlap an existing or already accepted 3D clipmap tile. The original
@@ -1457,8 +1472,9 @@ neighborhood have installed collision (or are explicitly collision-not-required)
now** — the active view has ground, horizon and the family-appropriate ceiling, with no exposed now** — the active view has ground, horizon and the family-appropriate ceiling, with no exposed
coverage hole or unexpected sky; (3) **refined soon** — each target LOD resolves within its stated coverage hole or unexpected sky; (3) **refined soon** — each target LOD resolves within its stated
time or travel distance after entering range. While moving, report the largest frame/time gap in time or travel distance after entering range. While moving, report the largest frame/time gap in
enclosure and maximum distance that unresolved work trails the pawn. FloatingIslands has open sky by enclosure and maximum distance that unresolved work trails the pawn. FloatingIslands is enclosed by a
design, so its enclosure check excludes a planar roof. planar roof at the upper boundary of its configured strate range; a taller strate places that roof
farther above its islands.
The shared `AVoxelWorld::UpdateChunksAroundPosition` scheduler serves both the Core snapshot path and The shared `AVoxelWorld::UpdateChunksAroundPosition` scheduler serves both the Core snapshot path and
Core-off legacy path. It admits the collision-critical 3×3 ring first. The measured S5 order remains Core-off legacy path. It admits the collision-critical 3×3 ring first. The measured S5 order remains
@@ -1778,6 +1794,263 @@ shared-page A/B test, not proof that a shared cache will pay after synchronizati
costs. Round 17 changed no density, mesh, collision, or recipe output; recipe versions remain costs. Round 17 changed no density, mesh, collision, or recipe output; recipe versions remain
unchanged. See [`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md). unchanged. See [`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md).
**Round 18 / S14:** the 65,536-entry worker-local XY column cache keeps the legacy direct-map
lookup for LOD0–2 (at most 33/28/4 conflict misses in the cold audit) and uses four-way sets for
LOD3–8. The deterministic coordinate/hash mixer and round-robin replacement cut LOD4 from 8,224
misses / 7,407 conflict misses to 1,437 / 0, and LOD3 from 1,634 / 1,119 to 574 / 0. Exact key
validation keeps fill order from affecting samples. `voxel.CoreColumnCacheDirectMapped=1` restores
the S13 route as a recorded negative control.
The step-1 ShapeWorld gradient memo reduced LOD0 fallback density probes from 11,474 to 3,018 at
the sampled p95 and gradient-normal cost from 65.10 to 24.16 ns/sample; the two-pass MC invariant
is unchanged. `voxel.CoreMCGradientMemoization=0` is its recorded negative control. No shared XY
page was added: cross-worker repeats alone do not establish a net page-cache win, and the S8
immutable-page lifetime rules would add ownership and memory cost. Round 18 changed no output or
recipe version. See [`Standalone/Research/WorldAssemblerM3/Round18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round18/REPORT.md).
### 8.35 Shared Core column cache — World Assembler L7
L7 measured 1.34 million repeated formula evaluations on the W12 L1 view before sharing: 83.6%
were another worker's XY, 4.0% were same-worker repeats after eviction, and 12.0% were halo/normal
repeats. The world-owned shared second tier cut measured formula executions by 60.9% and improved
median whole-view-ready time by 19.0%; moving 8 m and generating 144 entering tiles improved median
wall time by 36.1%. Peak RSS rose by about 66 MiB. The cache is a bounded exact-value table rather
than published pages; no scheduling affinity or page prefetch was needed to clear the measured
whole-view threshold.
The thread-local first tier remains because it avoids shared atomics for local hits. The shared
table has no lock on hits; only a miss takes a set-local spin lock. FloatingIslands' cache identity
includes its island stable ID because distinct anchors can request the same XY with different
column metrics. All W1/W12 L1 hashes, exact queries, and the seed-0 FloatingIslands fixture match
the pre-L7 binary with Clang FP contraction off and GCC defaults. See
[`Standalone/Research/WorldAssemblerM3/Linux7/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux7/REPORT.md).
### 8.36 Route-invariant Core density — World Assembler M3 L13
For an unedited Core world, tile density, mesh, payload, and topology are a function of the world
manifest/recipe, seed, and tile key. The reviewed manifest field is authoritative: SurfaceWorld uses
its `Heightfield2D`, while FloatingIslands uses its `FloatingIslandFieldV1`. `World::densityAt` and
tile generation read the same `FStandaloneShapeWorld` instance. A compiled analytic region page
retains bounded spatial bins for page ownership and routing, but `SetSharedDensitySource` binds it to
that base shape before publication; density, lattice, detail, classification, and solid queries
delegate to the shared evaluator. This keeps exact queries, collision occupancy signs, page tiles,
and base tiles on one field. Player edits remain explicit versioned overlays on that world state.
The route-binding change increments `WorldAssemblyEvaluatorVersion` from 5 to 6. Do not restore a
page-local legacy evaluator: it disagrees with the reviewed field. Uniform-block proof audits must
fill and check page tiles against the evaluator they actually sample. This is the shared Core path;
the Unreal adapter and its asynchronous MPSC/Epoch flow are unchanged. See
[`Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md).
### 8.37 Shared strate boundaries and FloatingIslands lower seal — World Assembler L18
`FStandaloneShapeWorld::GetResolvedStratumBounds` supplies one physical lower/upper-bound descriptor
to layer ranges, far-field sample protection, and far-shell continuity for every strate. SurfaceWorld
retains its exact `topChunkZ * 32` Core-voxel mapping and native heightfield cap. Native FloatingIslands
takes its resolved bounds from its plan, whose chunk range is converted through the serialized
owner/Core voxel ratio. Its version-3 field removes only the lower all-XY seal and calls the same
`VF_ApplyUpperBoundarySeal` primitive used by the shared two-sided `VF_ApplyBoundarySeal` for its upper
boundary. The ceiling therefore sits at that strate's own upper boundary, with the common
`boundarySealSubvoxels` thickness; there is no FloatingIslands-specific height. The recipe range is
un-inset to match the Unreal adapter. Versions 1 and 2 retain their serialized two-sided seals.
SurfaceWorld's field and output hashes remain unchanged. See
[`Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md).
### 8.38 Closed shared boundary ceilings and LOD sampling audit — World Assembler L19
`AppendStratumBoundaryCeilings` fills a candidate cell when the authoritative field is solid just
inside that strate's configured upper boundary. It does not require the raw field to cross back to
air above the boundary: the ceiling itself closes the strate even when the field continues solid
through that plane. This avoids isolated holes where a coarse lattice node has no zero crossing.
`FFarMeshColumnIndex::HasDownwardCellCoverage` still suppresses a fallback quad only after its
interior and perimeter probes all hit the existing downward face. The L19 `farHorizonVersion` is 4
for this shared boundary-cap change; hashes remain direct at LOD0–3 and salted at LOD4–8. No density
query, stratum position, scale, or asynchronous route changes. The strict LOD0–8 roof and paired-edge
audit and the matched before/after captures are in
[`Standalone/Research/WorldAssemblerM3/Linux19/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux19/REPORT.md).
### 8.39 Resolved layout snapshots and nominal strate bands — World Assembler L21 (historical)
`ResolvedLayoutSnapshotV1` is a separate Core-owned record built from the resolved manager slots and
the native SurfaceWorld/FloatingIslands plans. It has a canonical JSON representation, schema version,
and stable FNV-1a identity. Its physical intervals use half-open micrometre coordinates; recipe anchors
retain their serialized fixed-point units. The Unreal adapter exports it beside `world_assembly`, so the
layout digest never salts a recipe, manifest, density, or mesh hash. The standalone exporter follows
the same builder after plan resolution. It runs once per plan request and is not read from density or
tile-worker loops.
Each record separates the nominal ceiling, content, and bedrock bands. A strict layout requires that
sequence for every strate and requires bedrock(N) to touch the next strate's ceiling(N+1). The two
bands remain separately owned. Gradient and Interleaved interfaces may declare interpenetration only
inside their explicit transition zone; Hard has zero effective width. The manager's `TransitionBlendChunks`
is expressed in owner-chunk metres. Interleaved's existing two-chunk domain warp extends its possible
fingers beyond the blend width and is recorded separately. Compatibility validation reports current
gaps, overlaps, ambiguities, inactive/missing bands, and unhonoured transitions while accepting them;
strict validation rejects them. Core dispatches per-strate recipe fields without applying that
parameter blend, even though the legacy manager helper implements it. Both band types default diggable,
with protection represented explicitly.
Compatibility facts from L21: native SurfaceWorld plan/query bounds use 32 Core voxels (8 m) per
dispatch chunk, while FloatingIslands converts the 32-voxel owner chunk through its 12.5/25 cm scale
(16 Core voxels, 4 m). In the prototype where the top slot is FloatingIslands, this leaves a nominal
60 m interval between the FI bottom (−60 m) and SurfaceWorld top (−120 m); the Core selectors fall
through to the compiled analytic FloatingIslands fallback there. Core does not apply the manager's
parameter blend at either recipe boundary. The FI v3 upper seal remains a ceiling inside its current
content range, and its missing lower bedrock is recorded without changing evaluation. See
[`Standalone/Research/WorldAssemblerM3/Linux21/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux21/REPORT.md).
### 8.40 Fixed-metre strate layout units and shared boundary volumes — World Assembler L22
`StrateLayoutChunkSizeMeters` is one world-level setting, defaulting to **8 m**, independent of the
legacy 32-voxel chunk and Core's 32³ storage tile. The director resolves the setting once to physical
micrometres and Core subvoxels; every generator plan and dispatch reads that snapshot. At a 25 cm Core
voxel, an 8 m layout chunk is 32 Core voxels (8192 1/256-voxel units); at 20 cm it is 40 Core voxels
(10240 units). The Core tile remains 32³ voxels and is not a layout chunk.
The owner's FI/SW intervals are contiguous: FloatingIslands occupies [−120,+8) m and SurfaceWorld
occupies [−632,−120) m. Each strate is ceiling → content → bedrock. Both solid, diggable boundary
bands use its generator's existing `BoundarySealThickness` and `BaseDensity`; `InterStrateGapChunks`
controls only spacing, and `EdgeSealThickness` remains horizontal. No new thickness parameter or hidden
band height was added. The shared composition layer emits both volumes for every generator and the
shared mesh path closes their visible ceiling and floor faces.
The snapshot is schema V2 and is consumed by bounds planning, native and legacy dispatch, solid-band
composition, and validation. Strict validation accepts the real owner layouts, and the boundary probe
audit agrees at all 27 sampled endpoints in both recipe modes. The owner authored Gradient transition
is recorded as an explicit Hard fallback with zero interpenetration; Gradient and Interleaved mixing
remain unimplemented and must not be inferred from the declared blend width. Seven validator negative
controls continue to reject malformed bands.
Evidence and owner caveats are in
[`Standalone/Research/WorldAssemblerM3/Linux22/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux22/REPORT.md).
### 8.41 Director-resolved inter-strate passages and walkable landings — World Assembler L23
Core passage geometry is derived after the director has resolved physical strate bands and native
route anchors. `PlanResolvedLayoutPassagesV1` joins every adjacent resolved pair. Its placement hash
uses `(seed, upper strate, lower strate, connection, salt)`; `PassageConfig.DistanceMax` is the
outer radius around world `(0,0)` (24 m for the owner's first interface), while `DistanceMin` is
the inner radius used when a mouth has no route anchor. A route-bound mouth reuses the upper
strate's departure or lower strate's arrival anchor, after checking it lies within `DistanceMax`.
The legacy `UVoxelStrateManager::GeneratePassages` and its owner-voxel control points remain the
legacy generator path; Core does not import the exported legacy `passages` array. The season
manifest carries recipes and plans, and the adapter rebuilds the resolved layout and its passages
from the current manager slots and route anchors each time it attaches the Core world.
`ApplyResolvedStrateComposition` composes the current generator field, applies the resolved ceiling
and bedrock bands, then unions the passage carve and floor support. Only the hashed capsule path
opens a band; the support strip stays below the player capsule. The lower mouth index splits the
monotone descent from the short route-bound landing tail, whose height may vary with the route.
Both route and passage audits sample the 0.34 m by 1.76 m capsule, support probes, and grade; the
negative control compiles the same world without passage carving and must detect a blocked capsule.
The L23 shared-field change is `WorldAssemblyEvaluatorVersion=9`. It does not change the L22 bands
or any generator's field away from a passage. The L23 report includes exact-query/hash comparisons,
the blocked control, captures, and the Windows adapter checklist. §8.10's cache, proof, streaming,
and async rules remain unchanged.
[`Standalone/Research/WorldAssemblerM3/Linux23/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux23/REPORT.md)
records the audit and captures.
### 8.42 Per-strate natural passages and the FloatingIslands anchor helix — World Assembler L24
`FStratePassageConfig.Style` now drives the shared Core planner for every generator. The default is
`Worm`; Straight, Spiral and Cascading remain selectable per upper strate. Passage radius, reach,
distance and style stay in the resolved-layout input, so equal seeds and route anchors produce equal
paths on every peer. The passage carver adds bounded, deterministic wall relief (`0.24 m` before the
gravity-facing attenuation) while its support tread follows the same route profile below the capsule.
FloatingIslands' owner config selects Spiral. A seed-derived anchor island near `(0,0)` is joined to
bedrock by a 6 m radius rock root. The 3 m helix descends from the island mouth to the `-119.5 m`
bedrock top inside that root, leaving at least the authored clearance around its 1.5 m bore, then
widens into the Worm route toward the SurfaceWorld arrival. The selected anchor is ordinal 2; the
other island ordinals and their placement hashes are unchanged. FloatingIslands recipe geometry is
version 5 and the shared passage evaluator is version 10; the resolved-layout snapshot stays V3.
The passage naturalness audit rejects a horizontal run above 8 m (segments flatter than 0.5 degrees)
or wall relief below 0.20 m peak-to-peak across at least 8 valid samples. The smooth-wall control
has zero relief and fails; the anchored Spiral has 0 m flat run and 0.793 m measured relief. Strict
layout controls, route binding, capsule clearance, support, grade, and the no-carve negative control
remain required. Passage-centered interval proofs remain unknown/fallback rather than falsely
certified. At the lower mouth, the shared layer now relies on native terrain plus the passage tread;
it does not stamp additional flat route-anchor shelves over the cave opening. The L24 report records
compiler/worker parity, unchanged SurfaceWorld hashes away from the route, captures and the Windows
adapter checklist.
The Linux offscreen capture tool accepts `--headlamp=on` to aim brighter readable shading from the
camera for interior views and `--clip-plane=NX,NY,NZ,D` to discard the plane's negative half-space for
cutaway views. Both affect captures only, not generated geometry.
[`Standalone/Research/WorldAssemblerM3/Linux24/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux24/REPORT.md)
records the evidence and owner-facing caveats.
### 8.43 Enclosed FloatingIslands helix and native-solid passage support — World Assembler L25
L24's support tread was composited into the passage field without requiring native solid terrain at
the support sample. A 6 m root could not contain the resolved helix either: the centreline reaches
5.562 m from the anchor axis and the mouth bore is 4.5 m. With the old root radius, the tread could
therefore read as a free-floating spiral outside the rock. This was not a unit conversion error.
The shared passage composer now emits route-mouth support, tread, and fallback support only where
the pre-passage native density is solid. The open-air audit samples each support footprint at 0.25 m
spacing and two depths, including route-mouth shelves; its L24 ungated-support control must report a
violation. The FI anchor root is now a relief-bearing 13.25 m nominal rock column. Across five
heights its measured radius is 12.0–13.375 m. Taking the maximum 5.562 m centreline radius and the
full 4.5 m mouth bore at every height gives a conservative minimum wall of 1.938 m, exceeding the
previous 1.5 m reserve. The authored mid-bore remains 3 m. The helix is selected from its route-bound
root point and joins the lower route before the tunnel hands off through the shared SW ceiling.
The configured FI Spiral passes the capsule/support/grade audit with zero blocked, unsupported, or
grade-failure samples; the L23 smooth-wall control fails naturalness and the L24 ungated-support
control fails the open-air audit. The other style overrides also pass the open-air audit, but their
capsule results are recorded individually in the L25 report because some overrides are not
walkable after floating support is suppressed. Evaluator version is 12, FI geometry version is 7,
and resolved-layout schema V3 remains unchanged. The L25 report records measurements, hashes,
captures, style results, and the single Unreal adapter version edit.
[`Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md)
records the evidence and caveats.
### 8.44 Walkable passages as tunnels in rock — World Assembler L26
L25 correctly stopped support from appearing in native air, but its SurfaceWorld-recipe passages
still crossed a long open volume in the SurfaceWorld arrival strata. The segment map places that gap
inside SurfaceWorld (about `-146` to `-497 m`), after the TunnelNetwork transition; it is not TunnelNetwork
cave air. Both ends meet native rock. The shared Core planner now finds contiguous unsupported ranges
from the native field sign and caches them by resolved-layout identity. It adds a deterministic,
relief-bearing rock span only across those ranges. The span is at least 5 m wide, several metres thick,
and joins native rock at both ends. The passage carve then opens the bore through the added density,
leaving a grounded floor and rock walls/ceiling. SurfaceWorld away from the passage remains unchanged.
Native route support remains gated on pre-passage solid density. Before adding any support density, the
composer also checks the resolved player capsule, so neighboring floor segments cannot restore rock
inside the avatar path. This keeps all four style overrides walkable in both recipes. The bridge audit
measures its authored density field at 256 route sections, checks the 5 m width and connected ends, and
records a relief-bearing thickness range; the open-air audit still runs the L24 negative control.
The shared evaluator is version 13; FloatingIslands geometry remains version 7 and resolved-layout
schema V3 is unchanged. These changes are in Core and the standalone audit/capture path; no Unreal
adapter edit is required. The L26 report contains the eight-style table, hashes, captures and run history.
[`Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md)
records the final evidence.
### 8.45 Tile-bounded passage evaluation — World Assembler M3 Linux L28
Each mesh tile scopes passage composition to the inclusive density-sample AABB, including the
mesher's normal halo. A conservative feature AABB BVH selects route segments, columns and mouth
support for that tile. A per-passage nearest-segment BVH bounds the long helix search; a separate
passage-bound BVH rejects far L9 proof boxes. An unindexed native-only proof object uses a conservative
linear fallback. No field, union order, serialized layout or recipe version changes.
The column's exact complex SDF is evaluated only in XY/Z feature candidates. A cheap density-aware
radial guard remains for samples sharing the column's Z slab: a positive column distance can still
lower positive base density, so skipping that guard needs an exact bound on the base field. This is
the remaining SurfaceWorld cost noted in the Linux L28 report. The passage candidate lists and
proof bounds preserve the L27 output.
[Linux28 report](Standalone/Research/WorldAssemblerM3/Linux28/REPORT.md)
records counts, parity, costs and audit caveats.
## 9. Multiplayer model (listen-server first, dedicated-friendly) ## 9. Multiplayer model (listen-server first, dedicated-friendly)
> **Status: transport is DESIGN ONLY — nothing is networked in-tree yet** (no `Replicated`/`HasAuthority`/RPCs; a > **Status: transport is DESIGN ONLY — nothing is networked in-tree yet** (no `Replicated`/`HasAuthority`/RPCs; a
+6 -3
View File
@@ -26,9 +26,12 @@ try to run anything.
- **Density sign: negative = solid, positive = air** (MC convention at the mesher). - **Density sign: negative = solid, positive = air** (MC convention at the mesher).
`FVoxelModification::Strength` negative = carve. *The #1 source of confusion.* `FVoxelModification::Strength` negative = carve. *The #1 source of confusion.*
- **Density functions take VOXEL coords, not cm.** The legacy plugin field uses 12.5 cm voxels; - **Density functions take VOXEL coords, not cm.** The legacy plugin field uses 12.5 cm voxels;
the opt-in Core field uses 25 cm voxels and its own tile keys. One legacy 32³ chunk is 4 m. the opt-in Core field uses 25 cm voxels and its own 32³-voxel storage tile. The legacy 32³ chunk
Conversions live in `VoxelTypes.h` and the Core bridge; do not mix scales in queries, anchors, edits, spans 4 m at 12.5 cm. Strate placement uses the separate world-level `StrateLayoutChunkSizeMeters`
or surface lookups. setting (8 m by default), resolved once and shared by every generator. At 25 cm that layout unit is
32 Core voxels; at 20 cm it is 40. Never infer the layout unit from `CHUNK_SIZE` or the Core tile.
Conversions live in `VoxelTypes.h`, the director, and the Core bridge; do not mix scales in queries,
anchors, edits, or surface lookups.
- **Determinism:** all randomness = hash of (coord, seed, strateIndex). No RNG state — same seed ⇒ - **Determinism:** all randomness = hash of (coord, seed, strateIndex). No RNG state — same seed ⇒
same world. Player edits (diff layer) are the only non-deterministic overlay. same world. Player edits (diff layer) are the only non-deterministic overlay.
- **Core world invariants:** Core density keeps the same sign (negative solid, positive air), but Core - **Core world invariants:** Core density keeps the same sign (negative solid, positive air), but Core
+133 -11
View File
@@ -29,7 +29,9 @@ A **density-field voxel terrain** plugin for Unreal Engine, built around undergr
### Core terminology ### Core terminology
| Term | Meaning | | Term | Meaning |
|------|---------| |------|---------|
| Chunk | 32×32×32 voxels (`CHUNK_SIZE`). Voxel = 12.5 cm (`VOXEL_SIZE`), so a chunk is 4 m. | | Legacy chunk | 32×32×32 voxels (`CHUNK_SIZE`). At the legacy 12.5 cm voxel size it spans 4 m; it is not the strate-layout unit or the Core tile. |
| Strate-layout chunk | World-level `StrateLayoutChunkSizeMeters`, default 8 m, shared by all generators and independent of voxel size. The director resolves it once and Core reads the resolved snapshot. At 25 cm it is 32 Core voxels; at 20 cm it is 40 Core voxels. |
| Core tile | Internal 32×32×32 Core voxel tile. Its metre size follows the Core voxel size and stays separate from the configurable layout chunk. |
| Density | Scalar field. `< 0` solid, `> 0` air, `0` = surface (`IsoLevel`). | | Density | Scalar field. `< 0` solid, `> 0` air, `0` = surface (`IsoLevel`). |
| Strate | Vertical layer of the world, stacked downward. Has its own generator + params. | | Strate | Vertical layer of the world, stacked downward. Has its own generator + params. |
| Generator type | Archetype per strate: `TunnelNetwork`, `FlatPlain`, `CrystalChamber`, `Maze`, `SurfaceWorld`, `VerticalShafts`, `FloatingIslands`, `Underwater`. See §8. | | Generator type | Archetype per strate: `TunnelNetwork`, `FlatPlain`, `CrystalChamber`, `Maze`, `SurfaceWorld`, `VerticalShafts`, `FloatingIslands`, `Underwater`. See §8. |
@@ -78,10 +80,12 @@ what generator type, and is there a passage/elevator SDF near here?"
Paths relative to `Source/VoxelForge/`. `Public/` = headers, `Private/` = impl. Paths relative to `Source/VoxelForge/`. `Public/` = headers, `Private/` = impl.
### 3.0 Human-scale generation contract (2026-10-01) ### 3.0 Human-scale generation contract (2026-10-01)
`VOXEL_SIZE` is **12.5 cm**; 32³ voxels make each chunk **4 m**. The gameplay capsule remains `VOXEL_SIZE` is **12.5 cm** for the legacy generator. Its 32³-voxel chunks span **4 m**. The
**0.34 m radius / 1.76 m tall** (**2.72 / 14.08 voxels**). The default strate envelope is world-level strate-layout unit is a separate setting with an **8 m default**; a 16-chunk strate is
**16 chunks / 512 voxels / 64 m**; serialized owner strate assets that still say 8 chunks must be therefore **128 m**, and a 64-chunk strate is **512 m**. Core still stores work in 32³-voxel tiles;
changed to 16. Research-field dimensions are authored in metres and converted at runtime. The live at 25 cm those tiles happen to span 8 m, but they are not the layout unit. The gameplay capsule remains
**0.34 m radius / 1.76 m tall** (**2.72 / 14.08 legacy voxels**). Research-field dimensions are authored
in metres and converted at runtime. The live
strate generator continues to read voxel-valued parameters from its assets, so those authored strate generator continues to read voxel-valued parameters from its assets, so those authored
dimensions become half as large in metres unless their asset values are doubled. dimensions become half as large in metres unless their asset values are doubled.
@@ -158,15 +162,19 @@ remains `0`, and lateral regions remain gated off.
| `VoxelForge.Build.cs` | Deps: Core, CoreUObject, Engine, **GameplayTags**, **RealtimeMeshComponent**, `VoxelForgeCore`. `AVoxelWorld::bUseVoxelForgeCore` opts into the Core runtime route; it defaults off. | | `VoxelForge.Build.cs` | Deps: Core, CoreUObject, Engine, **GameplayTags**, **RealtimeMeshComponent**, `VoxelForgeCore`. `AVoxelWorld::bUseVoxelForgeCore` opts into the Core runtime route; it defaults off. |
| `../../VoxelForgeCore/VoxelForgeCore.Build.cs` | C++20 runtime module. Reads `Standalone/Core/core_sources.txt`, validates one include shim per canonical source, and fails UBT on missing, extra, or mismatched shims. No unity/PCH; private copied implementation stays under `vfcore::detail`. | | `../../VoxelForgeCore/VoxelForgeCore.Build.cs` | C++20 runtime module. Reads `Standalone/Core/core_sources.txt`, validates one include shim per canonical source, and fails UBT on missing, extra, or mismatched shims. No unity/PCH; private copied implementation stays under `vfcore::detail`. |
| `../../VoxelForgeCore/Private/Manifest/VFCore_*.cpp` | Eighteen one-source UBT shims that include canonical files under `Standalone/`; they do not copy Core implementation. The API-boundary row includes `Core/src/VoxelForgeCore.cpp` directly. | | `../../VoxelForgeCore/Private/Manifest/VFCore_*.cpp` | Eighteen one-source UBT shims that include canonical files under `Standalone/`; they do not copy Core implementation. The API-boundary row includes `Core/src/VoxelForgeCore.cpp` directly. |
| `../../Standalone/Core/include/VoxelForgeCore/ThreadLocalStorage.h` | `VoxelForgeCoreThreadLocal::FLazy<T>`: thread-local handle that heap-allocates a worker-private cache on first use. Large worker-local caches use it (HeightfieldColumnCache, IslandColumnCache, GFloorReliefCache, GRoomGraphCache, GSurfColCache, tunnel/diff caches). See ARCHITECTURE §8.10. |
| `../../Standalone/Core/include/VoxelForgeCore/SharedColumnCache.h` | Bounded four-way second-tier cache for exact per-column values. Readers use versioned atomic slots without a lock; misses use a set-local spin lock. World-owned lifetime, recipe/plan identity and content hashes, XY and optional sub-domain identity. SurfaceWorld and FloatingIslands share this mechanism; see ARCHITECTURE §8.35. |
| `../../Standalone/Core/src/CoreNamespacePreamble.h` | First include of every Core TU. Forces FP contraction off per compiler (Clang/MSVC/GCC pragmas; unknown compiler = `#error`) and defines `vfcore::fp_contract::selfTest`, which `World::compile` runs before building: a fused multiply-add (e.g. Clang `-ffp-contract=fast`) refuses world generation. The world depends on contraction (Linux2/Linux3 reports), so never remove either. |
| `../../VoxelForgeCore/Private/ModuleEntry/` | Unreal module entry and an isolated `CoreMinimal.h` shim for the actual engine header. | | `../../VoxelForgeCore/Private/ModuleEntry/` | Unreal module entry and an isolated `CoreMinimal.h` shim for the actual engine header. |
| `../../Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` | Standard-library-only public Core API. `VOXELFORGECORE_API` exports the API from the Unreal module and is empty for standalone builds. | | `../../Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` | Standard-library-only public Core API. `VOXELFORGECORE_API` exports the API from the Unreal module and is empty for standalone builds. |
| `../../Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` / `../../Standalone/Core/src/ResolvedLayoutInternal.h` | `ResolvedLayoutSnapshotV3`: physical layout-chunk width, versioned micrometre intervals, owned ceiling/content/bedrock bands, transition and dispatch provenance, recipe anchors, director-planned passages, canonical JSON/FNV identity, compatibility/strict validators, and negative-control audit. Built once from the director-resolved plan and consumed by bounds planning, Core dispatch, composition, and validation. §8.40–8.41. |
| `../../Standalone/Core/src/FloatingIslandsInternal.h` | Canonical standalone/Core floating-island planner, geometry-versioned field, manifest serializer, influence bounds, capsule-route checks, and thickness audit. | | `../../Standalone/Core/src/FloatingIslandsInternal.h` | Canonical standalone/Core floating-island planner, geometry-versioned field, manifest serializer, influence bounds, capsule-route checks, and thickness audit. |
| `Tools/VoxelForgeTest.ps1` | The single guarded test entry point. `-Scenario canonical|owner|probe|perf|tests|surface-fall|crossing|gate-stress|visual-edit|visual-lod|visual-gap-walk|visual-gap-inject|dig-motion|parity|horizon|horizon-render|determinism|region-eval|step2d|step2e|step2f|step2f-capture|step3-scale|step3-game`, optional `-Build`, `-Assets owner|default`, `-Cvars`, absolute `-Out`, `-Label`, `-HorizonLevel`, `-HorizonRenderDistanceChunks`, `-Step2fProfile=0..7`, `-Step2fCaptureView=inside|wall-closeup`, `-ParityExportSize=32|64|128`, `-ParityExportTile=x,y,z`, `-SharedDDC`, `-SampleDensityStacks`, `-StackSampleIntervalUs`, and `-RegionHashProbe -RegionWorkers N -RegionReferenceHash HASH`; stages the host/assets, isolates user/DDC/config state, serializes one Unreal launch at a time, enforces the 8 GiB/30-minute guards, waits for 6 GiB free RAM before launches, and emits compact `result.json`/`summary.txt` plus full logs. Parity can render its game leg with `-EnableRender` and compares the selected export region against the exact streamed tile hashes. `visual-gap-walk` records camera-frustum surface-point coverage at 6000 cm/s; `visual-gap-inject` proves an early component hide is detected; `dig-motion` logs per-frame vertical velocity, gate, support readiness, and movement mode. `-Cvars @{ 'voxel.TestGapAuditLegacyHandoff'=1 }` replays the old visibility handoff for A/B audit baselines. Horizon traces report desired/loaded tiles, resident stream geometry, worker seconds, steady wall time, and peak private memory; `horizon-render` captures the owner view; `step2f-capture` selects one of eight parameter sets, finds a positive-density camera point and aims at a sampled rock wall for an inside or wall-closeup view, then saves it under `Saved/Research/step2f/captures` (pass the persistent render DDC with `-SharedDDC`); `determinism` compares per-tile hashes across the default CRT path and `-voxel.CrtFma3=0`; `region-eval` compares the live path with the default-off editor chunk program on the 259³ lattice and five-seed probe set; `step2d` retains the earlier independent field; `step2e` retains its earlier benchmark; `step2f` compares frozen step 2e and the coherent field for all eight profiles on the same 259³ ring, applies geometry gates, and checks sound bounds, seams, and 1-vs-6-worker hashes. `-RegionHashProbe -RegionWorkers N -RegionReferenceHash HASH` checks a full-ring hash at another partition count. `-SampleDensityStacks` captures profiles, and `-StackSampleIntervalUs` sets the sampling interval. | `Tools/VoxelForgeTest.ps1` | The single guarded test entry point. `-Scenario canonical|owner|probe|perf|tests|surface-fall|crossing|gate-stress|visual-edit|visual-lod|visual-gap-walk|visual-gap-inject|dig-motion|parity|horizon|horizon-render|determinism|region-eval|step2d|step2e|step2f|step2f-capture|step3-scale|step3-game`, optional `-Build`, `-Assets owner|default`, `-Cvars`, absolute `-Out`, `-Label`, `-HorizonLevel`, `-HorizonRenderDistanceChunks`, `-Step2fProfile=0..7`, `-Step2fCaptureView=inside|wall-closeup`, `-ParityExportSize=32|64|128`, `-ParityExportTile=x,y,z`, `-SharedDDC`, `-SampleDensityStacks`, `-StackSampleIntervalUs`, and `-RegionHashProbe -RegionWorkers N -RegionReferenceHash HASH`; stages the host/assets, isolates user/DDC/config state, serializes one Unreal launch at a time, enforces the 8 GiB/30-minute guards, waits for 6 GiB free RAM before launches, and emits compact `result.json`/`summary.txt` plus full logs. Parity can render its game leg with `-EnableRender` and compares the selected export region against the exact streamed tile hashes. `visual-gap-walk` records camera-frustum surface-point coverage at 6000 cm/s; `visual-gap-inject` proves an early component hide is detected; `dig-motion` logs per-frame vertical velocity, gate, support readiness, and movement mode. `-Cvars @{ 'voxel.TestGapAuditLegacyHandoff'=1 }` replays the old visibility handoff for A/B audit baselines. Horizon traces report desired/loaded tiles, resident stream geometry, worker seconds, steady wall time, and peak private memory; `horizon-render` captures the owner view; `step2f-capture` selects one of eight parameter sets, finds a positive-density camera point and aims at a sampled rock wall for an inside or wall-closeup view, then saves it under `Saved/Research/step2f/captures` (pass the persistent render DDC with `-SharedDDC`); `determinism` compares per-tile hashes across the default CRT path and `-voxel.CrtFma3=0`; `region-eval` compares the live path with the default-off editor chunk program on the 259³ lattice and five-seed probe set; `step2d` retains the earlier independent field; `step2e` retains its earlier benchmark; `step2f` compares frozen step 2e and the coherent field for all eight profiles on the same 259³ ring, applies geometry gates, and checks sound bounds, seams, and 1-vs-6-worker hashes. `-RegionHashProbe -RegionWorkers N -RegionReferenceHash HASH` checks a full-ring hash at another partition count. `-SampleDensityStacks` captures profiles, and `-StackSampleIntervalUs` sets the sampling interval.
| Step-3 scale and game validation | `step3-scale` measures the same 519³ and 259³ six-worker lattices at 12.5 cm. The cached medians are 7.347496 s and 1.169567 s respectively; determinism and brick sound-proof audits pass. `step3-game` routes in-game generation through the brick evaluator and records tile timings, spawn fill, moving frames, and profile-switch rebuilds. The visible D3D12 run measured tile generation p50/p95/max 3.326/31.045/169.867 ms, full-detail L0 fill 12.369 s for 2,765 tiles, and moving-frame p50/p95/p99/max 4.856/8.922/13.090/80.575 ms. Switching profiles rebuilt 5,815 loaded tiles. Both high-resolution screenshot requests were logged, but the harness found only one fresh PNG and it is a blank pale viewport; no lit comparison capture is accepted. Raw output: `Saved/TestHarness/step3_game_visible_final`; scale output: `Saved/Research/step3/scale/step3_scale_cacheperf_v1`. | | Step-3 scale and game validation | `step3-scale` measures the same 519³ and 259³ six-worker lattices at 12.5 cm. The cached medians are 7.347496 s and 1.169567 s respectively; determinism and brick sound-proof audits pass. `step3-game` routes in-game generation through the brick evaluator and records tile timings, spawn fill, moving frames, and profile-switch rebuilds. The visible D3D12 run measured tile generation p50/p95/max 3.326/31.045/169.867 ms, full-detail L0 fill 12.369 s for 2,765 tiles, and moving-frame p50/p95/p99/max 4.856/8.922/13.090/80.575 ms. Switching profiles rebuilt 5,815 loaded tiles. Both high-resolution screenshot requests were logged, but the harness found only one fresh PNG and it is a blank pale viewport; no lit comparison capture is accepted. Raw output: `Saved/TestHarness/step3_game_visible_final`; scale output: `Saved/Research/step3/scale/step3_scale_cacheperf_v1`. |
| `Public/VoxelForgeModule.h` / `Private/VoxelForgeModule.cpp` | `FVoxelForgeModule` boilerplate (Startup/Shutdown just log). | | `Public/VoxelForgeModule.h` / `Private/VoxelForgeModule.cpp` | `FVoxelForgeModule` boilerplate (Startup/Shutdown just log). |
| `Source/VoxelForgeEditor/VoxelForgeEditor.Build.cs` / `Private/VoxelForgeExploreCommandlet.*` | Editor/commandlet-only `-run=VoxelForgeExplore`; schema-v1 owner-asset export check and BuildHost Core actor tests. `-coreworldassembly=PATH` supplies a reviewed manifest transiently to `-coreworldtest=1`; it does not save a data asset. `FStandaloneCoreAdapterScheduler` runs Core work at 1/8/16 workers; `VerifyStandaloneCoreAdapter` checks hashes and walkability. Existing bounded render/`VF_` walk/OBJ orchestration and research options remain editor/commandlet-only and are not linked by Game/Shipping. | | `Source/VoxelForgeEditor/VoxelForgeEditor.Build.cs` / `Private/VoxelForgeExploreCommandlet.*` | Editor/commandlet-only `-run=VoxelForgeExplore`; schema-v1 owner-asset export check and BuildHost Core actor tests. `-coreworldassembly=PATH` supplies a reviewed manifest transiently to `-coreworldtest=1`; it does not save a data asset. `FStandaloneCoreAdapterScheduler` runs Core work at 1/8/16 workers; `VerifyStandaloneCoreAdapter` checks hashes and walkability. Existing bounded render/`VF_` walk/OBJ orchestration and research options remain editor/commandlet-only and are not linked by Game/Shipping. |
| `Source/VoxelForge/Public/VoxelSettings.h` / `Private/VoxelSettings.cpp` | `UVoxelSettings` owns optional canonical world-assembly JSON and its Core digest. The editor file picker plus `ImportWorldAssemblyManifestJson` imports the reviewed manifest into the cooked settings asset and validates the recipe seed against the effective settings seed. | | `Source/VoxelForge/Public/VoxelSettings.h` / `Private/VoxelSettings.cpp` | `UVoxelSettings` owns optional canonical world-assembly JSON and its Core digest. The editor file picker plus `ImportWorldAssemblyManifestJson` imports the reviewed manifest into the cooked settings asset and validates the recipe seed against the effective settings seed. |
| `Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp` | Validates the optional manifest against each resolved `SurfaceWorld` slot (unique strate index and exact top/bottom chunks), then places canonical `world_assembly` JSON and its hash in the Core snapshot. Invalid plans fail Core initialization. | | `Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp` | Validates the optional manifest against each resolved `SurfaceWorld` slot (unique strate index and exact top/bottom chunks), then exports canonical `resolved_layout` separately from `world_assembly` and its hash. The layout digest does not alter recipe hashes. Invalid plans fail Core initialization. |
| `Source/VoxelForgeEditor/Private/VoxelForgeRegionEvalExperiment.*` | Six-worker lattice drivers for step 2c through step 2f. The original path still compares live `GetDensityAt` with the editor chunk program. Research modes assign contiguous batches dynamically so surface-heavy work balances across workers; steps 2e and 2f use 4³ proof bricks and stage each evaluated brick before copying contiguous X rows, while step 2d retains 8³. Each skip requires a macro Lipschitz bound plus the complete final-detail supremum; uncertain bricks retain every 12.5 cm detail sample. Timings split classification, point evaluation, and uniform fill; step 2f compares all profiles and hashes workers 1 and 6. | | `Source/VoxelForgeEditor/Private/VoxelForgeRegionEvalExperiment.*` | Six-worker lattice drivers for step 2c through step 2f. The original path still compares live `GetDensityAt` with the editor chunk program. Research modes assign contiguous batches dynamically so surface-heavy work balances across workers; steps 2e and 2f use 4³ proof bricks and stage each evaluated brick before copying contiguous X rows, while step 2d retains 8³. Each skip requires a macro Lipschitz bound plus the complete final-detail supremum; uncertain bricks retain every 12.5 cm detail sample. Timings split classification, point evaluation, and uniform fill; step 2f compares all profiles and hashes workers 1 and 6. |
| `Public/VoxelRedefinedDensityField.h` / `Private/VoxelRedefinedDensityField.cpp` | Two default-off `WITH_EDITOR` research fields, selected by `voxel.ResearchRedefinedDensityField` (step 2d) and `voxel.ResearchParameterizedCave` (steps 2e/2f). Step 2f retains a metre-scaled 2e baseline for its rejection audit. New profiles use strongly jittered, individually rotated elliptical rooms capped against nearest neighbors and curved cubic-Bezier passages with deterministic centerline and width variation along each edge. Room heights and feature rolls vary by cell; ledges, occasional pillars, stalactites/stalagmites, basin floors, and bounded hanging masses remain features. Point and brick detail sampling share independently rotated 96/48/24-sample bands and a smooth ridge response, preserving 12/6/3 m wavelengths at 12.5 cm per sample. The parameterized mesher evaluates the exact field through prepared 4³ bricks and the same sound skip proof in commandlet and editor-game meshing. In-editor and in-game profile changes invalidate and rebuild all loaded tiles. In an editor game with this field enabled, sealed-solid, out-of-layout, and outer-classifier verdicts are declined without changing their console switches. | | `Public/VoxelRedefinedDensityField.h` / `Private/VoxelRedefinedDensityField.cpp` | Two default-off `WITH_EDITOR` research fields, selected by `voxel.ResearchRedefinedDensityField` (step 2d) and `voxel.ResearchParameterizedCave` (steps 2e/2f). Step 2f retains a metre-scaled 2e baseline for its rejection audit. New profiles use strongly jittered, individually rotated elliptical rooms capped against nearest neighbors and curved cubic-Bezier passages with deterministic centerline and width variation along each edge. Room heights and feature rolls vary by cell; ledges, occasional pillars, stalactites/stalagmites, basin floors, and bounded hanging masses remain features. Point and brick detail sampling share independently rotated 96/48/24-sample bands and a smooth ridge response, preserving 12/6/3 m wavelengths at 12.5 cm per sample. The parameterized mesher evaluates the exact field through prepared 4³ bricks and the same sound skip proof in commandlet and editor-game meshing. In-editor and in-game profile changes invalidate and rebuild all loaded tiles. In an editor game with this field enabled, sealed-solid, out-of-layout, and outer-classifier verdicts are declined without changing their console switches. |
| `Private/Tests/VoxelForgeParameterizedGenerationTest.cpp` | Separate three-seed functional sweep for the step 2f parameterized field; passage landing air/floor brackets and arrival-to-exit walking routes are checked without changing the live-world tests. | | `Private/Tests/VoxelForgeParameterizedGenerationTest.cpp` | Separate three-seed functional sweep for the step 2f parameterized field; passage landing air/floor brackets and arrival-to-exit walking routes are checked without changing the live-world tests. |
@@ -178,7 +186,7 @@ remains `0`, and lateral regions remain gated off.
| Symbol | Line | Notes | | Symbol | Line | Notes |
|--------|------|-------| |--------|------|-------|
| `CHUNK_SIZE` (32) | 211 | Chunk dimensions. 64³ would cut draw calls but makes streaming too bursty; fps is fixed render-side instead. | | `CHUNK_SIZE` (32) | 211 | Chunk dimensions. 64³ would cut draw calls but makes streaming too bursty; fps is fixed render-side instead. |
| `VOXEL_SIZE` (12.5f cm) | 213 | World scale; one 32³ chunk is 4 m. | | `VOXEL_SIZE` (12.5f cm) | 213 | Legacy generator scale; `CHUNK_SIZE` 32 spans 4 m here. Keep separate from the 8 m default layout chunk and 32³ Core tile. |
| `EVoxelFace` enum | 266 | 6 cube faces. | | `EVoxelFace` enum | 266 | 6 cube faces. |
| `WorldToChunkCoord` | 287 | World cm → chunk coord (handles negatives via floor). | | `WorldToChunkCoord` | 287 | World cm → chunk coord (handles negatives via floor). |
| `VoxelMath::IsFiniteFast` / `IsFinite` | 24 / 45 | Exact IEEE bit test (`voxel.FastIsFinite` A/B switch). | | `VoxelMath::IsFiniteFast` / `IsFinite` | 24 / 45 | Exact IEEE bit test (`voxel.FastIsFinite` A/B switch). |
@@ -205,14 +213,16 @@ all eight archetypes; there is no other path. See [Docs/archive/OPSTACK-PLAN.md]
| `FVoxelBoxHypotheses` + `FVoxelBoxSdfInterval` + `VF_ForceHypotheses` / `VF_FoldEffect` / `VF_FoldOp` | The fold that turns a stack into an `EVoxelTileClass`, carrying the SDF interval between independent writers and consumers. Unknown is biased toward `Mixed`; the mapping and soundness rule are written out in the header. | | `FVoxelBoxHypotheses` + `FVoxelBoxSdfInterval` + `VF_ForceHypotheses` / `VF_FoldEffect` / `VF_FoldOp` | The fold that turns a stack into an `EVoxelTileClass`, carrying the SDF interval between independent writers and consumers. Unknown is biased toward `Mixed`; the mapping and soundness rule are written out in the header. |
### 3.2c Structural primitives — `Public/VoxelDensityPrimitives.h` ### 3.2c Structural primitives — `Public/VoxelDensityPrimitives.h`
`VF_ApplyOriginSpine` · `VF_ApplyBoundarySeal` · `VF_ApplyPassageCarving` · `VF_ApplyXYEdgeSeal` — `VF_ApplyOriginSpine` · `VF_ApplyBoundarySeal` · `VF_ApplyUpperBoundarySeal` · `VF_ApplyPassageCarving` · `VF_ApplyXYEdgeSeal` —
the four world invariants every archetype appends, with landing/floor geometry joined by the the four world invariants every archetype appends, with landing/floor geometry joined by the
manager passage post, **moved here 2026-07-27** so the generator and manager passage post, **moved here 2026-07-27** so the generator and
the operator stack share ONE copy. The XY helper is a radial smooth ramp in actor-space and is a the operator stack share ONE copy. The XY helper is a radial smooth ramp in actor-space and is a
true no-op when `WorldRadiusVoxels == 0`; `VF_XYEdgeSealForcedMarginOverBox` is the shared sound true no-op when `WorldRadiusVoxels == 0`; `VF_XYEdgeSealForcedMarginOverBox` is the shared sound
proof for `ClassifyBox` and T1.d's global shell skip. `VoxelGenerator.cpp` keeps same-named proof for `ClassifyBox` and T1.d's global shell skip. `VoxelGenerator.cpp` keeps same-named
`static FORCEINLINE` forwarders for `ApplyBoundarySeal` and `ApplyOriginSpine`; the passage and `static FORCEINLINE` forwarders for `ApplyBoundarySeal` and `ApplyOriginSpine`; the passage and
edge helpers are called directly. **Convention: INTERNAL (positive = solid); `VF_ApplyXYEdgeSealMC` is the output wrapper.** edge helpers are called directly. `VF_ApplyUpperBoundarySealValue` contains the common upper-band
math used by both one-sided and two-sided seals. **Convention: INTERNAL (positive = solid);
`VF_ApplyXYEdgeSealMC` is the output wrapper.**
### 3.2d Operator stack — `Public/VoxelDensityOpStack.h` + `Private/VoxelDensityOpStack.cpp` ### 3.2d Operator stack — `Public/VoxelDensityOpStack.h` + `Private/VoxelDensityOpStack.cpp`
⚠️ **This IS the game's generation path.** `GetDensityAt` builds the stack in its per-chunk refetch ⚠️ **This IS the game's generation path.** `GetDensityAt` builds the stack in its per-chunk refetch
@@ -874,8 +884,14 @@ round-2 matched capture source and results are under
[`Standalone/Research/WorldAssemblerM3/Round2/`](Standalone/Research/WorldAssemblerM3/Round2/). [`Standalone/Research/WorldAssemblerM3/Round2/`](Standalone/Research/WorldAssemblerM3/Round2/).
`RefineLod8NativeCap` in [`Standalone/Core/src/VoxelForgeCore.cpp`](Standalone/Core/src/VoxelForgeCore.cpp) `RefineLod8NativeCap` in [`Standalone/Core/src/VoxelForgeCore.cpp`](Standalone/Core/src/VoxelForgeCore.cpp)
replaces coarse LOD8 ceiling surfaces with the planned 2D cap field while retaining ceiling skirts. replaces coarse LOD8 ceiling surfaces with the planned 2D cap field while retaining ceiling skirts.
The standalone SurfaceWorld plan composer and capture/audit entry point live in The standalone SurfaceWorld plan composer (`AttachRound1WorldAssemblyPrototype`) lives in
[`Standalone/Source/StandaloneViewer.cpp`](Standalone/Source/StandaloneViewer.cpp). [`Standalone/Source/WorldAssemblyPrototype.h`](Standalone/Source/WorldAssemblyPrototype.h), and the
streaming benchmark/hash pipeline (`RunPipelinedStreamingBenchmark`, `HashTileRows`) in
[`Standalone/Source/StreamBenchmarkPipeline.h`](Standalone/Source/StreamBenchmarkPipeline.h); both are
shared by the D3D11 viewer ([`StandaloneViewer.cpp`](Standalone/Source/StandaloneViewer.cpp), which
keeps the capture/audit entry points) and the Linux headless tool
([`StreamBenchmarkHeadless.cpp`](Standalone/Source/StreamBenchmarkHeadless.cpp), built by
`Standalone/BuildLinux.sh`; see `Standalone/Research/WorldAssemblerM3/Linux1/REPORT.md`).
`RunStandaloneWorldExport` in `VoxelForgeExploreCommandlet.cpp` serializes owner assets on the game `RunStandaloneWorldExport` in `VoxelForgeExploreCommandlet.cpp` serializes owner assets on the game
thread to schema-v1 JSON. The adapter parses it through `ResolvedWorldSnapshot::FromJson` and keeps thread to schema-v1 JSON. The adapter parses it through `ResolvedWorldSnapshot::FromJson` and keeps
@@ -1095,6 +1111,112 @@ generation output. Measurement-only stride and octave probes are confined to the
audit and are not runtime controls. The result and limits are recorded in audit and are not runtime controls. The result and limits are recorded in
[`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md). [`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md).
### 3.20 MC stage audit and coarse column-cache conflicts — World Assembler S14 / M3 Round 18
`Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp` records the sampled density
grid, cell classification, grid-gradient normals, edge interpolation, and vertex/dedup stream
stages for the BuildHost audit. Its exact per-worker gradient memo is controlled and trace-read
back through `voxel.CoreMCGradientMemoization`. `Standalone/Core/src/WorldAssemblerInternal.h`
keeps the 65,536-entry worker-local column cache, using the S13 direct-map for LOD0–2 and a
deterministic four-way set-associative route for LOD3–8; `voxel.CoreColumnCacheDirectMapped=1`
restores the S13 path for the negative control. Runtime CVar capture lives in
`Source/VoxelForge/Private/VoxelWorld.cpp`; stage and conflict counts are reported by
`Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp`. The measurements, controls, and
cold-path decision are in
[`Standalone/Research/WorldAssemblerM3/Round18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round18/REPORT.md).
### 3.21 LOD1 uniform-block proof — World Assembler M3 Linux9
`FStandaloneShapeWorld::IsNativeSurfaceBox` gates the step-2 proof to a single native SurfaceWorld
stratum. `ClassifyBoxDetailed(..., bUseNativeLatticeProof)` delegates to
`Heightfield2D::classifyLatticeBox`, whose ground/cap extrema cover the MC lattice and normal halo.
`UVoxelMarchingCubesMesher::GenerateMesh` sparsely fills only Mixed blocks and their sample halo;
Mixed/Unknown remains on the fill path. The headless `--audit-uniform-block-proofs` forces sample
verification, while `--profile-lod-work` reports per-LOD filled samples; both are off by default.
Implementation and evidence: [`Standalone/Research/WorldAssemblerM3/Linux9/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux9/REPORT.md).
### 3.22 Route-invariant Core density — World Assembler M3 Linux13
| Symbol | Canonical file | Role |
|---|---|---|
| `FStandaloneShapeWorld::SetSharedDensitySource`, `SharedDensitySource` | `Standalone/Core/src/ShapeWorldInternal.h`, bound before publication in `Standalone/Core/src/VoxelForgeCore.cpp` | Makes compiled analytic pages delegate field, lattice, detail, classification, and solid queries to the Core world's base shape; `WorldAssemblyEvaluatorVersion` is 6. |
The base manifest field is authoritative for tile generation and exact queries. See ARCHITECTURE
§8.36 and [`Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md).
### 3.23 Shared strate boundaries and FloatingIslands seal — World Assembler M3 Linux18
| Symbol | Canonical file | Role |
|---|---|---|
| `FStandaloneShapeWorld::FResolvedStratumBounds`, `MakeResolvedStratumBounds`, `GetResolvedStratumBounds` | `Standalone/Core/src/ShapeWorldInternal.h` | Resolves each strate's physical lower/upper range and seal width for layer ranges, far-field sample protection, and far-shell continuity. Native FloatingIslands uses its plan's owner/Core ratio; SurfaceWorld retains its `32` Core voxels per slot chunk. |
| `VF_ApplyUpperBoundarySeal` / `VF_ApplyUpperBoundarySealValue` | `Standalone/Source/VoxelForge/Public/VoxelDensityPrimitives.h` and `Source/VoxelForge/Public/VoxelDensityPrimitives.h` | Shared one-sided top seal used by version-3 native FloatingIslands; the two-sided seal reuses the same upper-band math. |
Geometry version 3 removes the FI lower all-XY seal while retaining its ceiling through the shared
upper-bound path. Versions 1 and 2 retain their serialized two-sided behavior. See ARCHITECTURE §8.37
and [`Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md).
### 3.24 Resolved inter-strate passages — World Assembler M3 L23
| Symbol | Canonical file | Role |
|---|---|---|
| `PlanResolvedLayoutPassagesV1`, `ResolvedLayoutPassageV1::lowerMouthControlIndex` | `Standalone/Core/src/ResolvedLayoutInternal.h`, public record in `VoxelForgeCore.h` | Plans deterministic fixed-metre passages from adjacent director-resolved strata, binds route departure/arrival mouths, and records the derived split between the monotone descent and route-bound landing tail. |
| `FStandaloneShapeWorld::ApplyResolvedStrateComposition`, `ApplyResolvedStratePassageCarves` | `Standalone/Core/src/ShapeWorldInternal.h` | Applies boundary bands first, then opens the passage capsule and supported floor along the passage for every native generator. |
| `--audit-resolved-layout-passages` | `Standalone/Source/StreamBenchmarkPipeline.h` | Samples passage capsules, floor support, mouth ownership/radius, in-strate route bindings, and a blocked-passage negative control. |
The evaluator version is 9. See ARCHITECTURE §8.41 and
[`Standalone/Research/WorldAssemblerM3/Linux23/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux23/REPORT.md).
### 3.25 Per-strate natural passages and FloatingIslands anchor helix — World Assembler L24
| Symbol | Canonical file | Role |
|---|---|---|
| `FStratePassageConfig::Style`, `EVoxelPassageStyle` | `Source/VoxelForge/Public/VoxelStrateTypes.h` | Selects Straight, Worm, Spiral or Cascading per upper strate; Worm is the default. |
| `PlanResolvedLayoutPassagesV1` | `Standalone/Core/src/ResolvedLayoutInternal.h` | Applies the selected style in the shared planner; a configured FI Spiral follows the anchor root into the bedrock and smoothly transitions into the inter-strate route. |
| Anchor root recipe fields and `EvaluateIslandSDF` | `Standalone/Core/src/FloatingIslandsInternal.h` | Add the seed-stable ordinal-2 island/root without changing other island placements; geometry version 5. |
| `ApplyResolvedStratePassageCarves` | `Standalone/Core/src/ShapeWorldInternal.h` | Applies deterministic rough wall relief and the supported route profile to all native generator fields. |
| `--audit-resolved-layout-passages` naturalness checks | `Standalone/Source/StreamBenchmarkPipeline.h` | Checks 8 m maximum flat run, 0.20 m minimum wall relief, capsule/support/grade, mouths, routes and the blocked-passage control. |
| `--headlamp=on`, `--clip-plane=NX,NY,NZ,D` | `Standalone/Source/LinuxOffscreenCapture.cpp` | Adds camera-directed light or discards the plane's negative half-space for offscreen cutaways; neither affects Core output. |
The shared evaluator is version 10, the FI recipe geometry is version 5, and resolved-layout schema
V3 is unchanged. See ARCHITECTURE §8.42 and
[`Standalone/Research/WorldAssemblerM3/Linux24/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux24/REPORT.md).
### 3.26 Enclosed FloatingIslands helix and open-air support gate — World Assembler L25
| Symbol | Canonical file | Role |
|---|---|---|
| `ApplyResolvedStratePassageCarves` | `Standalone/Core/src/ShapeWorldInternal.h` | Emits route-mouth support, tread and fallback support only over pre-passage native solid density, shared by every passage style. |
| `auditPassageOpenAir` / `--audit-resolved-layout-passages` | `Standalone/Source/StreamBenchmarkPipeline.h` | Samples the support footprint at 0.25 m spacing and two depths; compares against L24 ungated support as a required negative control. |
| Anchor root dimensions and relief | `Standalone/Core/src/FloatingIslandsInternal.h` | Raises the FI anchor root from a 6 m cylinder to a nominal 13.25 m relief-bearing rock column sized around the 3 m helix and 4.5 m mouth. |
| Passage route and root measures | `Standalone/Core/src/ResolvedLayoutInternal.h`, `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` | Binds the Spiral to the root and reports measured centreline/root clearance. |
The shared evaluator is version 12 and FI geometry version is 7; resolved-layout schema V3 is
unchanged. See ARCHITECTURE §8.43 and
[`Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md).
### 3.27 Tunnels in native rock with grounded passage bridges — World Assembler L26
| Symbol | Canonical file | Role |
|---|---|---|
| `BuildPassageBridgePlan` / `PassageBridgeSignedDistance` | `Standalone/Core/src/ShapeWorldInternal.h` | Uses native density sign to plan cached, connected rock spans only across unsupported route ranges; shared by both recipes and all passage styles. |
| `PassageBridgeCache` | `Standalone/Source/OwnerWorldLoader.h` | Shares deterministic ranges by resolved-layout identity across shape instances. |
| `ApplyResolvedStratePassageCarves` | `Standalone/Core/src/ShapeWorldInternal.h` | Adds bridge density before carving the bore; gates native floor support on solid input and player-capsule clearance. |
| `auditPassageBridges` / `auditPassageOpenAir` / `--audit-resolved-layout-passages` | `Standalone/Source/StreamBenchmarkPipeline.h` | Measures bridge width, thickness, relief and connected ends; checks capsule support, open air, naturalness, route binding and the L24 negative control. |
| `PassageBridgeRangeAuditV1` / `passageBridgeRanges()` / `isPassageBridgeSample()` | `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`, `Standalone/Core/src/VoxelForgeCore.cpp` | Exposes audit-only bridge ranges and density queries to the standalone validator. |
The shared evaluator is version 13; FloatingIslands geometry remains version 7 and resolved-layout
schema V3 is unchanged. See ARCHITECTURE §8.44 and
[`Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md).
### 3.28 Tile-bounded passage evaluation — World Assembler M3 Linux L28
| Symbol | Canonical file | Role |
|---|---|---|
| FScopedPassageTileQueries / BuildPassageFeatureTileList / ResolvedPassageIntersectsBox | Standalone/Core/src/ShapeWorldInternal.h; scope entered by GenerateMesh in Standalone/Core/src/VoxelForgeCore.cpp | Builds conservative per-tile route, column and mouth-support candidates from an AABB BVH; long paths use a nearest-segment BVH and L9 box checks use a separate passage-bound BVH. Empty native-only proof indexes fall back conservatively. The density arithmetic and serialized versions stay unchanged. |
See ARCHITECTURE §8.45 and
[Linux28 report](Standalone/Research/WorldAssemblerM3/Linux28/REPORT.md).
## 4. The density pipeline (most-edited hot path) ## 4. The density pipeline (most-edited hot path)
### 4.1 `GetDensityWithParams` (TunnelNetwork) — VoxelGenerator.cpp:3749 ### 4.1 `GetDensityWithParams` (TunnelNetwork) — VoxelGenerator.cpp:3749
@@ -32,6 +32,38 @@ namespace
using FCoreJsonWriter = TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>; using FCoreJsonWriter = TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>;
constexpr double OwnerVoxelSizeCm = VOXEL_SIZE; constexpr double OwnerVoxelSizeCm = VOXEL_SIZE;
float StrateBoundarySealThickness(const UVoxelStrateDefinition& Definition)
{
switch(Definition.GeneratorType)
{
case ECaveGeneratorType::SurfaceWorld:return Definition.SurfaceParams.BoundarySealThickness;
case ECaveGeneratorType::FloatingIslands:return Definition.FloatingIslandParams.BoundarySealThickness;
case ECaveGeneratorType::Maze:return Definition.MazeParams.BoundarySealThickness;
case ECaveGeneratorType::VerticalShafts:return Definition.VerticalShaftParams.BoundarySealThickness;
case ECaveGeneratorType::TunnelNetwork:
case ECaveGeneratorType::FlatPlain:
case ECaveGeneratorType::CrystalChamber:
case ECaveGeneratorType::Underwater:return Definition.GenerationParams.BoundarySealThickness;
}
return Definition.GenerationParams.BoundarySealThickness;
}
float StrateBoundarySolidDensity(const UVoxelStrateDefinition& Definition)
{
switch(Definition.GeneratorType)
{
case ECaveGeneratorType::SurfaceWorld:return Definition.SurfaceParams.BaseDensity;
case ECaveGeneratorType::FloatingIslands:return Definition.FloatingIslandParams.BaseDensity;
case ECaveGeneratorType::Maze:return Definition.MazeParams.BaseDensity;
case ECaveGeneratorType::VerticalShafts:return Definition.VerticalShaftParams.BaseDensity;
case ECaveGeneratorType::TunnelNetwork:
case ECaveGeneratorType::FlatPlain:
case ECaveGeneratorType::CrystalChamber:
case ECaveGeneratorType::Underwater:return Definition.GenerationParams.BaseDensity;
}
return Definition.GenerationParams.BaseDensity;
}
std::int64_t WorldAssemblyFixed(double Voxels) std::int64_t WorldAssemblyFixed(double Voxels)
{ {
return static_cast<std::int64_t>(std::llround( return static_cast<std::int64_t>(std::llround(
@@ -287,8 +319,10 @@ bool BuildSurfaceStratumPlan(const UVoxelStrateManager* StrateManager,
const FSurfaceGenerationParams Surface = StrateManager->GetSurfaceParamsForChunk(Chunk); const FSurfaceGenerationParams Surface = StrateManager->GetSurfaceParamsForChunk(Chunk);
const FBiomeContext BiomeContext = StrateManager->GetBiomeContextForChunk(Chunk); const FBiomeContext BiomeContext = StrateManager->GetBiomeContextForChunk(Chunk);
const UVoxelStrateDefinition* Definition = Slot.Definition; const UVoxelStrateDefinition* Definition = Slot.Definition;
const double BottomVoxel = static_cast<double>(Slot.BottomChunkZ) * CHUNK_SIZE; const double LayoutChunkVoxels = static_cast<double>(Recipe.layoutChunkWidthSubvoxels)
const double HeightVoxels = static_cast<double>(Slot.TopChunkZ - Slot.BottomChunkZ + 1) * CHUNK_SIZE; / WorldAssemblySubvoxelsPerVoxel;
const double BottomVoxel = static_cast<double>(Slot.BottomChunkZ) * LayoutChunkVoxels;
const double HeightVoxels = static_cast<double>(Slot.TopChunkZ - Slot.BottomChunkZ + 1) * LayoutChunkVoxels;
const FBiomeMapParams& Map = BiomeContext.Map; const FBiomeMapParams& Map = BiomeContext.Map;
Recipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed()); Recipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed());
Recipe.biomeCellSizeSubvoxels = WorldAssemblyFixed(Map.CellSize); Recipe.biomeCellSizeSubvoxels = WorldAssemblyFixed(Map.CellSize);
@@ -422,7 +456,7 @@ bool BuildSurfaceStratumPlan(const UVoxelStrateManager* StrateManager,
Shelf.minimumSubvoxels = {WorldAssemblyFixed(MinX), WorldAssemblyFixed(MinY), Shelf.minimumSubvoxels = {WorldAssemblyFixed(MinX), WorldAssemblyFixed(MinY),
std::max(WorldAssemblyFixed(BottomVoxel), LowestGround - WorldAssemblyFixed(4.0))}; std::max(WorldAssemblyFixed(BottomVoxel), LowestGround - WorldAssemblyFixed(4.0))};
Shelf.maximumSubvoxels = {WorldAssemblyFixed(MaxX), WorldAssemblyFixed(MaxY), Shelf.maximumSubvoxels = {WorldAssemblyFixed(MaxX), WorldAssemblyFixed(MaxY),
std::min(WorldAssemblyFixed((Slot.TopChunkZ + 1) * CHUNK_SIZE), std::min(WorldAssemblyFixed((Slot.TopChunkZ + 1) * LayoutChunkVoxels),
HighestGround + WorldAssemblyFixed(ShelfHeight + 4.0))}; HighestGround + WorldAssemblyFixed(ShelfHeight + 4.0))};
Shelf.parametersSubvoxels = {WorldAssemblyFixed(DirX), WorldAssemblyFixed(DirY), Shelf.parametersSubvoxels = {WorldAssemblyFixed(DirX), WorldAssemblyFixed(DirY),
WorldAssemblyFixed(ShelfHeight), WorldAssemblyFixed(Reach)}; WorldAssemblyFixed(ShelfHeight), WorldAssemblyFixed(Reach)};
@@ -440,17 +474,19 @@ bool BuildSurfaceStratumPlan(const UVoxelStrateManager* StrateManager,
bool BuildFloatingIslandStratumPlan(const UVoxelStrateManager* StrateManager, bool BuildFloatingIslandStratumPlan(const UVoxelStrateManager* StrateManager,
const FStrateSlot& Slot, VoxelForgeCore::WorldAssemblyManifest& Manifest, const FStrateSlot& Slot, VoxelForgeCore::WorldAssemblyManifest& Manifest,
double CoreVoxelSizeCm, FString& OutError) double CoreVoxelSizeCm, std::int64_t LayoutChunkWidthSubvoxels, FString& OutError)
{ {
using namespace VoxelForgeCore; using namespace VoxelForgeCore;
const FIntVector Chunk(0, 0, Slot.TopChunkZ); const FIntVector Chunk(0, 0, Slot.TopChunkZ);
const FFloatingIslandParams Params = StrateManager->GetFloatingIslandParamsForChunk(Chunk); const FFloatingIslandParams Params = StrateManager->GetFloatingIslandParamsForChunk(Chunk);
const FStratePassageConfig& Passage = Slot.Definition->PassageConfig;
WorldAssemblyFloatingIslandPlanV1 IslandPlan; WorldAssemblyFloatingIslandPlanV1 IslandPlan;
IslandPlan.strateIndex = Slot.StrateIndex; IslandPlan.strateIndex = Slot.StrateIndex;
IslandPlan.topChunkZ = Slot.TopChunkZ; IslandPlan.topChunkZ = Slot.TopChunkZ;
IslandPlan.bottomChunkZ = Slot.BottomChunkZ; IslandPlan.bottomChunkZ = Slot.BottomChunkZ;
auto& Recipe = IslandPlan.manifest.recipe; auto& Recipe = IslandPlan.manifest.recipe;
Recipe.geometryVersion = 2; Recipe.geometryVersion = 8;
Recipe.layoutChunkWidthSubvoxels = LayoutChunkWidthSubvoxels;
Recipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed()); Recipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed());
Recipe.ownerVoxelSizeMicrons = static_cast<std::uint32_t>(std::llround(OwnerVoxelSizeCm * 10000.0)); Recipe.ownerVoxelSizeMicrons = static_cast<std::uint32_t>(std::llround(OwnerVoxelSizeCm * 10000.0));
Recipe.coreVoxelSizeMicrons = static_cast<std::uint32_t>(std::llround(CoreVoxelSizeCm * 10000.0)); Recipe.coreVoxelSizeMicrons = static_cast<std::uint32_t>(std::llround(CoreVoxelSizeCm * 10000.0));
@@ -463,12 +499,10 @@ bool BuildFloatingIslandStratumPlan(const UVoxelStrateManager* StrateManager,
} }
Recipe.ownerToCoreScaleNumerator = Recipe.ownerVoxelSizeMicrons / ScaleGcd; Recipe.ownerToCoreScaleNumerator = Recipe.ownerVoxelSizeMicrons / ScaleGcd;
Recipe.ownerToCoreScaleDenominator = Recipe.coreVoxelSizeMicrons / ScaleGcd; Recipe.ownerToCoreScaleDenominator = Recipe.coreVoxelSizeMicrons / ScaleGcd;
const double CoreVoxelsPerOwnerChunk = static_cast<double>(CHUNK_SIZE) Recipe.layoutMinimumZSubvoxels = static_cast<std::int64_t>(Slot.BottomChunkZ)
* Recipe.ownerToCoreScaleNumerator / Recipe.ownerToCoreScaleDenominator; * LayoutChunkWidthSubvoxels;
Recipe.layoutMinimumZSubvoxels = WorldAssemblyFixed( Recipe.layoutMaximumZSubvoxels = static_cast<std::int64_t>(Slot.TopChunkZ + 1)
static_cast<double>(Slot.BottomChunkZ) * CoreVoxelsPerOwnerChunk); * LayoutChunkWidthSubvoxels;
Recipe.layoutMaximumZSubvoxels = WorldAssemblyFixed(
static_cast<double>(Slot.TopChunkZ + 1) * CoreVoxelsPerOwnerChunk);
Recipe.layoutCenterTopZSubvoxels = (Recipe.layoutMinimumZSubvoxels Recipe.layoutCenterTopZSubvoxels = (Recipe.layoutMinimumZSubvoxels
+ Recipe.layoutMaximumZSubvoxels) / 2; + Recipe.layoutMaximumZSubvoxels) / 2;
Recipe.islandDensityQ16 = WorldAssemblyQ16(FMath::Clamp(Params.IslandDensity, 0.0f, 1.0f)); Recipe.islandDensityQ16 = WorldAssemblyQ16(FMath::Clamp(Params.IslandDensity, 0.0f, 1.0f));
@@ -483,6 +517,28 @@ bool BuildFloatingIslandStratumPlan(const UVoxelStrateManager* StrateManager,
Recipe.roughnessSubvoxels = WorldAssemblyFixed(Params.SurfaceRoughness * OwnerToCoreScale); Recipe.roughnessSubvoxels = WorldAssemblyFixed(Params.SurfaceRoughness * OwnerToCoreScale);
Recipe.blendRadiusSubvoxels = WorldAssemblyFixed(Params.SDFBlendRadius * OwnerToCoreScale); Recipe.blendRadiusSubvoxels = WorldAssemblyFixed(Params.SDFBlendRadius * OwnerToCoreScale);
Recipe.boundarySealSubvoxels = WorldAssemblyFixed(Params.BoundarySealThickness * OwnerToCoreScale); Recipe.boundarySealSubvoxels = WorldAssemblyFixed(Params.BoundarySealThickness * OwnerToCoreScale);
const auto OwnerVoxelsToCoreQ=[&](double Value)
{
return static_cast<std::int64_t>(std::llround(Value*Recipe.ownerVoxelSizeMicrons
*WorldAssemblySubvoxelsPerVoxel/Recipe.coreVoxelSizeMicrons));
};
Recipe.anchorIslandOrdinal=Recipe.primaryIslandCount-1;
Recipe.anchorPlacementRadiusSubvoxels=OwnerVoxelsToCoreQ(Passage.DistanceMax);
const std::int64_t spiralRadius=OwnerVoxelsToCoreQ(Passage.SpiralRadius);
// Reserve at least a 1.5 m mid-bore through the anchor root.
constexpr double AnchorPassageMinimumBoreOwnerVoxels=12.0;
const std::int64_t mouthBore=std::max(OwnerVoxelsToCoreQ(Passage.MouthRadius),
OwnerVoxelsToCoreQ(12.0));
const std::int64_t bore=std::max(OwnerVoxelsToCoreQ(Passage.MidRadius),
OwnerVoxelsToCoreQ(AnchorPassageMinimumBoreOwnerVoxels));
const std::int64_t wallReserve=OwnerVoxelsToCoreQ(12.0);
Recipe.anchorMouthOffsetSubvoxels=spiralRadius+mouthBore+OwnerVoxelsToCoreQ(4.0);
const std::int64_t excursion=std::max(OwnerVoxelsToCoreQ(Passage.Wander),spiralRadius);
Recipe.anchorRootRadiusSubvoxels=excursion+bore+wallReserve;
Recipe.anchorIslandMinimumRadiusSubvoxels=std::max(Recipe.minimumRadiusSubvoxels,
Recipe.anchorMouthOffsetSubvoxels+mouthBore+OwnerVoxelsToCoreQ(4.0));
Recipe.anchorRootBottomZSubvoxels=Recipe.layoutMinimumZSubvoxels
+Recipe.boundarySealSubvoxels;
std::string PlanError; std::string PlanError;
const std::optional<FloatingIslandManifestV1> Planned = PlanFloatingIslandCluster(Recipe, PlanError); const std::optional<FloatingIslandManifestV1> Planned = PlanFloatingIslandCluster(Recipe, PlanError);
if (!Planned) if (!Planned)
@@ -758,6 +814,12 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
const TSharedRef<FJsonObject>& Root, const TSharedRef<FJsonObject>& Root,
FString& OutError) FString& OutError)
{ {
const std::uint32_t LayoutChunkSizeMicrometres=StrateManager->GetStrateLayoutChunkSizeMicrometres();
const std::uint32_t CoreVoxelMicrometres=static_cast<std::uint32_t>(std::llround(CoreVoxelSizeCm*10000.0));
const std::int64_t LayoutChunkWidthSubvoxels=static_cast<std::int64_t>(std::llround(
static_cast<double>(LayoutChunkSizeMicrometres)*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel
/std::max<std::uint32_t>(1,CoreVoxelMicrometres)));
StrateManager->SetHardTransitionFallbackForAssembly(true);
FString ManifestJson; FString ManifestJson;
FString ManifestHash; FString ManifestHash;
if (!Settings->GetWorldAssemblyManifestJson(ManifestJson, ManifestHash, OutError)) if (!Settings->GetWorldAssemblyManifestJson(ManifestJson, ManifestHash, OutError))
@@ -783,6 +845,7 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
{ {
VoxelForgeCore::WorldAssemblyManifest Generated; VoxelForgeCore::WorldAssemblyManifest Generated;
Generated.recipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed()); Generated.recipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed());
Generated.recipe.layoutChunkWidthSubvoxels=LayoutChunkWidthSubvoxels;
int32 SurfaceSlotCount = 0; int32 SurfaceSlotCount = 0;
int32 IslandSlotCount = 0; int32 IslandSlotCount = 0;
for (const FStrateSlot& Slot : StrateManager->GetLayout()) for (const FStrateSlot& Slot : StrateManager->GetLayout())
@@ -815,6 +878,7 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
{ {
VoxelForgeCore::WorldAssemblyRecipeV1 SlotRecipe; VoxelForgeCore::WorldAssemblyRecipeV1 SlotRecipe;
SlotRecipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed()); SlotRecipe.seed = static_cast<std::uint32_t>(StrateManager->GetWorldSeed());
SlotRecipe.layoutChunkWidthSubvoxels=LayoutChunkWidthSubvoxels;
VoxelForgeCore::WorldAssemblyStratumPlanV1 Stratum; VoxelForgeCore::WorldAssemblyStratumPlanV1 Stratum;
if (!BuildSurfaceStratumPlan(StrateManager, Slot, if (!BuildSurfaceStratumPlan(StrateManager, Slot,
SlotRecipe, Stratum, OutError)) SlotRecipe, Stratum, OutError))
@@ -829,7 +893,7 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
else if (Type == ECaveGeneratorType::FloatingIslands) else if (Type == ECaveGeneratorType::FloatingIslands)
{ {
if (!BuildFloatingIslandStratumPlan(StrateManager, Slot, Generated, if (!BuildFloatingIslandStratumPlan(StrateManager, Slot, Generated,
CoreVoxelSizeCm, OutError)) CoreVoxelSizeCm, LayoutChunkWidthSubvoxels, OutError))
{ {
return false; return false;
} }
@@ -873,7 +937,11 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
OutError = TEXT("floating-island override uses a different Core voxel size; regenerate the plan."); OutError = TEXT("floating-island override uses a different Core voxel size; regenerate the plan.");
return false; return false;
} }
if(Island.manifest.recipe.layoutChunkWidthSubvoxels!=LayoutChunkWidthSubvoxels)
{OutError=TEXT("floating-island override uses a different strate-layout chunk width; regenerate the plan.");return false;}
} }
if(Manifest->recipe.layoutChunkWidthSubvoxels!=LayoutChunkWidthSubvoxels)
{OutError=TEXT("world assembly manifest uses a different strate-layout chunk width; regenerate the plan.");return false;}
int32 SurfaceSlotCount = 0; int32 SurfaceSlotCount = 0;
int32 FloatingIslandSlotCount = 0; int32 FloatingIslandSlotCount = 0;
@@ -944,6 +1012,247 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
MatchedStrateIndices.Add(Plan.strateIndex); MatchedStrateIndices.Add(Plan.strateIndex);
} }
// Keep the inspectable physical-layout export separate from the manifest identity: it is
// assembled from the same resolved slots/plans, but adding it must not salt evaluation hashes.
VoxelForgeCore::ResolvedLayoutSnapshotV3 Layout;
Layout.worldIdentity = std::string("owner-world/seed/")
+ std::to_string(StrateManager->GetWorldSeed());
Layout.ownerVoxelSizeMicrometres = static_cast<std::uint32_t>(std::llround(OwnerVoxelSizeCm * 10000.0));
Layout.coreVoxelSizeMicrometres = ExpectedCoreVoxelMicrons;
Layout.strateLayoutChunkSizeMicrometres=LayoutChunkSizeMicrometres;
Layout.strateLayoutChunkWidthSubvoxels=LayoutChunkWidthSubvoxels;
const auto generatorName = [](ECaveGeneratorType Type) -> const char*
{
switch (Type)
{
case ECaveGeneratorType::TunnelNetwork: return "TunnelNetwork";
case ECaveGeneratorType::FlatPlain: return "FlatPlain";
case ECaveGeneratorType::CrystalChamber: return "CrystalChamber";
case ECaveGeneratorType::Maze: return "Maze";
case ECaveGeneratorType::SurfaceWorld: return "SurfaceWorld";
case ECaveGeneratorType::VerticalShafts: return "VerticalShafts";
case ECaveGeneratorType::FloatingIslands: return "FloatingIslands";
case ECaveGeneratorType::Underwater: return "Underwater";
}
return "Unknown";
};
const auto transitionName = [](EVoxelStrateTransition Type) -> const char*
{
switch (Type)
{
case EVoxelStrateTransition::Gradient: return "Gradient";
case EVoxelStrateTransition::Hard: return "Hard";
case EVoxelStrateTransition::Interleaved: return "Interleaved";
}
return "Unknown";
};
const std::int64_t OwnerVoxelMicrons = Layout.ownerVoxelSizeMicrometres;
const auto FixedToMicrons = [ExpectedCoreVoxelMicrons](std::int64_t Fixed)
{
return static_cast<std::int64_t>(std::llround(static_cast<double>(Fixed)
* ExpectedCoreVoxelMicrons / VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));
};
std::vector<VoxelForgeCore::ResolvedLayoutPassageConfigV1> PassageConfigs;
for (const FStrateSlot& Slot : StrateManager->GetLayout())
{
if (Slot.Definition == nullptr) continue;
const FStratePassageConfig& AuthoredPassage = Slot.Definition->PassageConfig;
const auto OwnerVoxelsToCoreQ = [OwnerVoxelMicrons, ExpectedCoreVoxelMicrons](double Value)
{
return static_cast<std::int64_t>(std::llround(Value * OwnerVoxelMicrons
* VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel / ExpectedCoreVoxelMicrons));
};
VoxelForgeCore::ResolvedLayoutPassageConfigV1 PassageConfig;
PassageConfig.upperStrateIndex = Slot.StrateIndex;
PassageConfig.connections = AuthoredPassage.Connections;
PassageConfig.style = static_cast<std::uint32_t>(AuthoredPassage.Style);
PassageConfig.mouthRadiusSubvoxels = std::max(OwnerVoxelsToCoreQ(AuthoredPassage.MouthRadius),
OwnerVoxelsToCoreQ(12.0));
PassageConfig.midRadiusSubvoxels = std::max(OwnerVoxelsToCoreQ(AuthoredPassage.MidRadius),
OwnerVoxelsToCoreQ(12.0));
PassageConfig.reachMinimumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.ReachMin);
PassageConfig.reachMaximumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.ReachMax);
PassageConfig.distanceMinimumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.DistanceMin);
PassageConfig.distanceMaximumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.DistanceMax);
PassageConfig.wanderSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.Wander);
PassageConfig.segments = static_cast<std::uint32_t>(FMath::Clamp(AuthoredPassage.Segments,1,48));
PassageConfig.verticalWobbleSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.VerticalWobble);
PassageConfig.spiralRadiusSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.SpiralRadius);
PassageConfig.spiralTurnsQ16 = static_cast<std::int64_t>(std::llround(
static_cast<double>(AuthoredPassage.SpiralTurns)*65536.0));
PassageConfig.cascadeSteps = static_cast<std::uint32_t>(FMath::Clamp(AuthoredPassage.CascadeSteps,1,16));
PassageConfig.cascadeLedgeSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.CascadeLedge);
PassageConfigs.push_back(PassageConfig);
const ECaveGeneratorType Type = StrateManager->GetGeneratorTypeForChunk(
FIntVector(0, 0, Slot.TopChunkZ));
VoxelForgeCore::ResolvedLayoutStratumV2 Item;
Item.strateIndex = Slot.StrateIndex;
Item.generatorKind = generatorName(Type);
Item.stableId = Layout.worldIdentity + "/strate/" + std::to_string(Slot.StrateIndex)
+ "/generator/" + generatorName(Type);
Item.recipeId = Type == ECaveGeneratorType::SurfaceWorld ? "SurfaceWorld.Heightfield2D"
: Type == ECaveGeneratorType::FloatingIslands ? "FloatingIslands.ClusterField"
: std::string("legacy.") + generatorName(Type);
Item.recipeVersion = Type == ECaveGeneratorType::SurfaceWorld ? Manifest->recipe.schemaVersion : 0;
Item.voxelSizeMicrometres = ExpectedCoreVoxelMicrons;
Item.interiorBottomMicrometres = static_cast<std::int64_t>(Slot.BottomChunkZ)
* LayoutChunkSizeMicrometres;
Item.interiorTopMicrometres = static_cast<std::int64_t>(Slot.TopChunkZ + 1)
* LayoutChunkSizeMicrometres;
Item.managerChunkWidthMicrometres = LayoutChunkSizeMicrometres;
Item.dispatchChunkWidthMicrometres = LayoutChunkSizeMicrometres;
Item.transitionMode = transitionName(Slot.Definition->TransitionType);
Item.transitionBlendChunks = Slot.Definition->TransitionBlendChunks;
Item.transitionWidthMicrometres = static_cast<std::int64_t>(Item.transitionBlendChunks)
* Item.managerChunkWidthMicrometres;
Item.transitionWarpAmplitudeMicrometres = Item.transitionMode == "Interleaved"
? 2 * Item.managerChunkWidthMicrometres : 0;
Item.transitionInterpenetrationMicrometres = 0;
Item.transitionHonouredInCore = Slot.Definition->TransitionType == EVoxelStrateTransition::Hard;
Item.transitionFallsBackToHard = Slot.Definition->TransitionType != EVoxelStrateTransition::Hard;
Item.transitionDispatchPath = Item.transitionFallsBackToHard
? "declared Gradient/Interleaved recorded; Core uses an explicit Hard transition fallback with zero interpenetration"
: "declared Hard transition is applied at this interface";
Item.managerLookup = "UVoxelStrateManager::GetGeneratorTypeForChunk; transition is controlled by upper strate";
if (Type == ECaveGeneratorType::SurfaceWorld)
{
Item.boundDispatchPath = "BuildSurfaceStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV3";
Item.queryDispatchPath = "NativeSurfaceDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV3";
const auto Plan = std::find_if(Manifest->plan.strates.begin(), Manifest->plan.strates.end(),
[&Slot](const auto& Entry) { return Entry.strateIndex == Slot.StrateIndex; });
if (Plan != Manifest->plan.strates.end())
{
for (const auto& Profile : Manifest->recipe.biomes)
if (Profile.hasCapProfile)
{
VoxelForgeCore::ResolvedLayoutAnchorV2 Anchor;
Anchor.kind = "cap_profile";
Anchor.stableId = "biome/" + std::to_string(Profile.stableId);
Anchor.units = "1/256 Core voxel";
Anchor.values = { Profile.capHeightSubvoxels, Profile.capUndulationSubvoxels,
Profile.capWavelengthSubvoxels, Profile.capDetailAmplitudeSubvoxels,
Profile.capRidgeAmplitudeSubvoxels };
Item.anchors.push_back(std::move(Anchor));
}
for (std::size_t RouteIndex = 0; RouteIndex < Plan->route.size(); ++RouteIndex)
{
const auto& Point = Plan->route[RouteIndex];
VoxelForgeCore::ResolvedLayoutAnchorV2 Anchor;
Anchor.kind = "route_point"; Anchor.stableId = "route/" + std::to_string(RouteIndex);
Anchor.units = "1/256 Core voxel";
Anchor.values = { Point.positionSubvoxels[0], Point.positionSubvoxels[1],
Point.positionSubvoxels[2], Point.radiusSubvoxels };
Item.anchors.push_back(std::move(Anchor));
}
}
}
else if (Type == ECaveGeneratorType::FloatingIslands)
{
Item.boundDispatchPath = "BuildFloatingIslandStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV3";
Item.queryDispatchPath = "NativeFloatingIslandDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV3";
const auto Plan = std::find_if(Manifest->floatingIslands.begin(), Manifest->floatingIslands.end(),
[&Slot](const auto& Entry) { return Entry.strateIndex == Slot.StrateIndex; });
std::int64_t SealMicrometres = 0;
if (Plan != Manifest->floatingIslands.end())
{
Item.interiorBottomMicrometres = FixedToMicrons(Plan->manifest.recipe.layoutMinimumZSubvoxels);
Item.interiorTopMicrometres = FixedToMicrons(Plan->manifest.recipe.layoutMaximumZSubvoxels);
Item.recipeVersion = Plan->manifest.recipe.geometryVersion;
for (std::size_t IslandIndex = 0; IslandIndex < Plan->manifest.plan.islands.size(); ++IslandIndex)
{
const auto& Island = Plan->manifest.plan.islands[IslandIndex];
VoxelForgeCore::ResolvedLayoutAnchorV2 Anchor;
Anchor.kind = "island_anchor"; Anchor.stableId = "island/" + std::to_string(IslandIndex);
Anchor.units = "1/256 Core voxel";
Anchor.values = { Island.centerSubvoxels[0], Island.centerSubvoxels[1],
Island.centerSubvoxels[2], Island.radiusSubvoxels, Island.topHalfSubvoxels };
Item.anchors.push_back(std::move(Anchor));
if(IslandIndex==Plan->manifest.recipe.anchorIslandOrdinal
&&Plan->manifest.recipe.geometryVersion>=5)
{
VoxelForgeCore::ResolvedLayoutAnchorV2 PassageAnchor;
PassageAnchor.kind="passage_anchor";
PassageAnchor.stableId="passage-anchor/island/"+std::to_string(IslandIndex);
PassageAnchor.units="1/256 Core voxel";
PassageAnchor.values={Island.centerSubvoxels[0],Island.centerSubvoxels[1],
Plan->manifest.recipe.anchorRootRadiusSubvoxels,
Plan->manifest.recipe.anchorMouthOffsetSubvoxels,
Plan->manifest.recipe.anchorPlacementRadiusSubvoxels,
Plan->manifest.recipe.anchorRootBottomZSubvoxels,
Island.radiusSubvoxels};
Item.anchors.push_back(std::move(PassageAnchor));
}
}
for (std::size_t RouteIndex = 0; RouteIndex < Plan->manifest.plan.route.size(); ++RouteIndex)
{
const auto& Point = Plan->manifest.plan.route[RouteIndex];
VoxelForgeCore::ResolvedLayoutAnchorV2 Anchor;
Anchor.kind = "route_point"; Anchor.stableId = "route/" + std::to_string(RouteIndex);
Anchor.units = "1/256 Core voxel";
Anchor.values = { Point.positionSubvoxels[0], Point.positionSubvoxels[1],
Point.positionSubvoxels[2], Point.radiusSubvoxels };
Item.anchors.push_back(std::move(Anchor));
}
}
}
else
{
Item.boundDispatchPath = "resolved manager slot scaled by ResolvedLayoutSnapshotV3 chunk width";
Item.queryDispatchPath = "legacy Core route selects manager chunk by floor(CoreZ / resolved layout chunk width)";
}
const std::int64_t SealMicrometres=static_cast<std::int64_t>(std::llround(
std::max(0.0f,StrateBoundarySealThickness(*Slot.Definition))*OwnerVoxelMicrons));
if(SealMicrometres<=0)
{OutError=FString::Printf(TEXT("Strate %d has no positive BoundarySealThickness for shared ceiling and bedrock bands."),Slot.StrateIndex);return false;}
const std::int64_t SolidDensityQ16=std::max<std::int64_t>(1,WorldAssemblyQ16(
std::max(0.05f,StrateBoundarySolidDensity(*Slot.Definition))));
Item.ceiling={"ceiling",Item.interiorTopMicrometres-SealMicrometres,
Item.interiorTopMicrometres,true,true,false,"solid ceiling from strate BoundarySealThickness; breakable by default",
"interior-facing lower surface","shared resolved-layout density band",SolidDensityQ16};
Item.bedrock={"bedrock",Item.interiorBottomMicrometres,
Item.interiorBottomMicrometres+SealMicrometres,true,true,false,
"solid bedrock floor from strate BoundarySealThickness; breakable by default",
"interior-facing upper surface","shared resolved-layout density band",SolidDensityQ16};
Item.content = { "content", Item.interiorBottomMicrometres,
Item.interiorTopMicrometres, true, true, false, "resolved generator interior",
"none", "none" };
Item.content.bottomMicrometres+=SealMicrometres;
Item.content.topMicrometres-=SealMicrometres;
Layout.strates.push_back(std::move(Item));
}
std::string PassagePlanError;
if (!VoxelForgeCore::PlanResolvedLayoutPassagesV1(Layout,
StrateManager->GetWorldSeed(), PassageConfigs, PassagePlanError))
{
OutError = FString::Printf(TEXT("Resolved inter-strate passage planning failed: %s"),
UTF8_TO_TCHAR(PassagePlanError.c_str()));
return false;
}
std::string LayoutError;
if (!Layout.finalize(LayoutError))
{
OutError = FString::Printf(TEXT("Core resolved-layout export failed: %s"), UTF8_TO_TCHAR(LayoutError.c_str()));
return false;
}
const std::string LayoutJson = Layout.ToJson();
Root->SetStringField(TEXT("resolved_layout_json"),UTF8_TO_TCHAR(LayoutJson.c_str()));
const auto SurfaceSpawnPlan=std::find_if(Manifest->plan.strates.begin(),Manifest->plan.strates.end(),
[](const auto& Plan){return !Plan.route.empty();});
if(SurfaceSpawnPlan!=Manifest->plan.strates.end())
{
const auto& Spawn=SurfaceSpawnPlan->route.front();
TSharedRef<FJsonObject> ViewerStart=MakeShared<FJsonObject>();
ViewerStart->SetBoolField(TEXT("found_open_space"),true);
ViewerStart->SetNumberField(TEXT("x"),static_cast<double>(Spawn.positionSubvoxels[0])
/VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
ViewerStart->SetNumberField(TEXT("y"),static_cast<double>(Spawn.positionSubvoxels[1])
/VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
ViewerStart->SetNumberField(TEXT("z"),static_cast<double>(Spawn.positionSubvoxels[2])
/VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
Root->SetObjectField(TEXT("viewer_start"),ViewerStart);
}
const std::string CanonicalJson = Manifest->ToJson(); const std::string CanonicalJson = Manifest->ToJson();
if (CanonicalJson.empty()) if (CanonicalJson.empty())
{ {
@@ -1013,6 +1322,8 @@ bool VoxelForgeCoreAdapter::SerializeResolvedWorld(
// Override only the temporary schema copy. Clipmap tuning on the owner's asset is preserved. // Override only the temporary schema copy. Clipmap tuning on the owner's asset is preserved.
SettingsValue->AsObject()->SetNumberField(TEXT("ClipRadius"), CoreClipRadius); SettingsValue->AsObject()->SetNumberField(TEXT("ClipRadius"), CoreClipRadius);
SettingsValue->AsObject()->SetNumberField(TEXT("MaxClipLevel"), CoreMaxClipLevel); SettingsValue->AsObject()->SetNumberField(TEXT("MaxClipLevel"), CoreMaxClipLevel);
SettingsValue->AsObject()->SetNumberField(TEXT("StrateLayoutChunkSizeMeters"),
Settings->StrateLayoutChunkSizeMeters);
TSharedRef<FJsonObject> Root = MakeShared<FJsonObject>(); TSharedRef<FJsonObject> Root = MakeShared<FJsonObject>();
Root->SetNumberField(TEXT("schema_version"), 1); Root->SetNumberField(TEXT("schema_version"), 1);
@@ -1032,6 +1343,8 @@ bool VoxelForgeCoreAdapter::SerializeResolvedWorld(
Root->SetNumberField(TEXT("edge_seal_thickness"), Settings->EdgeSealThickness); Root->SetNumberField(TEXT("edge_seal_thickness"), Settings->EdgeSealThickness);
Root->SetNumberField(TEXT("total_strates"), StrateManager->GetNumStrates()); Root->SetNumberField(TEXT("total_strates"), StrateManager->GetNumStrates());
Root->SetNumberField(TEXT("inter_strate_gap_chunks"), Settings->InterStrateGapChunks); Root->SetNumberField(TEXT("inter_strate_gap_chunks"), Settings->InterStrateGapChunks);
Root->SetNumberField(TEXT("strate_layout_chunk_size_um"),
std::llround(Settings->StrateLayoutChunkSizeMeters*1000000.0));
Root->SetNumberField(TEXT("clip_radius"), CoreClipRadius); Root->SetNumberField(TEXT("clip_radius"), CoreClipRadius);
Root->SetNumberField(TEXT("max_clip_level"), CoreMaxClipLevel); Root->SetNumberField(TEXT("max_clip_level"), CoreMaxClipLevel);
Root->SetNumberField(TEXT("full_res_clip_levels"), Settings->FullResClipLevels); Root->SetNumberField(TEXT("full_res_clip_levels"), Settings->FullResClipLevels);
@@ -1099,12 +1412,15 @@ bool VoxelForgeCoreAdapter::SerializeResolvedWorld(
return false; return false;
} }
Root->SetArrayField(TEXT("density_samples"), {}); Root->SetArrayField(TEXT("density_samples"), {});
TSharedRef<FJsonObject> ViewerStart = MakeShared<FJsonObject>(); if(!Root->HasField(TEXT("viewer_start")))
ViewerStart->SetBoolField(TEXT("found_open_space"), false); {
ViewerStart->SetNumberField(TEXT("x"), 0.0); TSharedRef<FJsonObject> ViewerStart = MakeShared<FJsonObject>();
ViewerStart->SetNumberField(TEXT("y"), 0.0); ViewerStart->SetBoolField(TEXT("found_open_space"), false);
ViewerStart->SetNumberField(TEXT("z"), 0.0); ViewerStart->SetNumberField(TEXT("x"), 0.0);
Root->SetObjectField(TEXT("viewer_start"), ViewerStart); ViewerStart->SetNumberField(TEXT("y"), 0.0);
ViewerStart->SetNumberField(TEXT("z"), 0.0);
Root->SetObjectField(TEXT("viewer_start"), ViewerStart);
}
FString WriterBuffer; FString WriterBuffer;
TSharedRef<FCoreJsonWriter> Writer = TJsonWriterFactory<TCHAR, TSharedRef<FCoreJsonWriter> Writer = TJsonWriterFactory<TCHAR,
@@ -321,7 +321,7 @@ namespace
const FVector ChunkCenter( const FVector ChunkCenter(
(ChunkCoord.X + 0.5f) * (float)CHUNK_SIZE, (ChunkCoord.X + 0.5f) * (float)CHUNK_SIZE,
(ChunkCoord.Y + 0.5f) * (float)CHUNK_SIZE, (ChunkCoord.Y + 0.5f) * (float)CHUNK_SIZE,
(ChunkCoord.Z + 0.5f) * (float)CHUNK_SIZE); (ChunkCoord.Z + 0.5f) * Manager->GetStrateLayoutChunkWidthVoxels());
const float ChunkRadius = (float)CHUNK_SIZE * 0.8660254f + 3.0f; const float ChunkRadius = (float)CHUNK_SIZE * 0.8660254f + 3.0f;
const TArray<FVoxelPassage>& Passages = Manager->GetPassages(); const TArray<FVoxelPassage>& Passages = Manager->GetPassages();
Cache.FloorProjections.SetNum(Passages.Num()); Cache.FloorProjections.SetNum(Passages.Num());
@@ -1103,7 +1103,7 @@ static bool VF_FindWalkableTunnelAir(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(Position.X / (float)CHUNK_SIZE), FMath::FloorToInt(Position.X / (float)CHUNK_SIZE),
FMath::FloorToInt(Position.Y / (float)CHUNK_SIZE), FMath::FloorToInt(Position.Y / (float)CHUNK_SIZE),
FMath::FloorToInt(Position.Z / (float)CHUNK_SIZE)); FMath::FloorToInt(Position.Z / Manager->GetStrateLayoutChunkWidthVoxels()));
const TArray<int32>& Nearby = VF_GetNearbyPassages(Manager, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(Manager, ChunkCoord);
const TArray<FVoxelPassage>& Passages = Manager->GetPassages(); const TArray<FVoxelPassage>& Passages = Manager->GetPassages();
const FVoxelPassage* PassageData = Passages.GetData(); const FVoxelPassage* PassageData = Passages.GetData();
@@ -1138,7 +1138,7 @@ static bool VF_IsAnyPassageFloorAt(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(Position.X / (float)CHUNK_SIZE), FMath::FloorToInt(Position.X / (float)CHUNK_SIZE),
FMath::FloorToInt(Position.Y / (float)CHUNK_SIZE), FMath::FloorToInt(Position.Y / (float)CHUNK_SIZE),
FMath::FloorToInt(Position.Z / (float)CHUNK_SIZE)); FMath::FloorToInt(Position.Z / Manager->GetStrateLayoutChunkWidthVoxels()));
const TArray<int32>& Nearby = VF_GetNearbyPassages(Manager, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(Manager, ChunkCoord);
const TArray<FVoxelPassage>& Passages = Manager->GetPassages(); const TArray<FVoxelPassage>& Passages = Manager->GetPassages();
const FVoxelPassage* PassageData = Passages.GetData(); const FVoxelPassage* PassageData = Passages.GetData();
@@ -1169,6 +1169,17 @@ bool UVoxelStrateManager::Initialize(UVoxelSettings* Settings, int32 WorldSeed)
UE_LOG(LogTemp, Error, TEXT("[StrateManager] No settings provided!")); UE_LOG(LogTemp, Error, TEXT("[StrateManager] No settings provided!"));
return false; return false;
} }
if (!FMath::IsFinite(Settings->StrateLayoutChunkSizeMeters)
|| Settings->StrateLayoutChunkSizeMeters < 0.25f
|| Settings->StrateLayoutChunkSizeMeters > 64.0f)
{
UE_LOG(LogTemp, Error, TEXT("[StrateManager] StrateLayoutChunkSizeMeters must be in [0.25, 64] m."));
return false;
}
StrateLayoutChunkSizeMicrometres = static_cast<uint32>(std::llround(
static_cast<double>(Settings->StrateLayoutChunkSizeMeters) * 1000000.0));
StrateLayoutChunkWidthVoxels = static_cast<float>(
static_cast<double>(StrateLayoutChunkSizeMicrometres) / (10000.0 * VOXEL_SIZE));
FVoxelSeasonManifest SeasonManifest; FVoxelSeasonManifest SeasonManifest;
bool bUseSeason = false; bool bUseSeason = false;
@@ -1342,10 +1353,11 @@ bool UVoxelStrateManager::Initialize(UVoxelSettings* Settings, int32 WorldSeed)
Slot.Definition->FloatingIslandParams = SeasonStrate.Params.FloatingIslandParams; Slot.Definition->FloatingIslandParams = SeasonStrate.Params.FloatingIslandParams;
Slot.HeightInChunks = SeasonStrate.HeightInChunks; Slot.HeightInChunks = SeasonStrate.HeightInChunks;
Slot.TopChunkZ = SeasonStrate.TopWorldZ / CHUNK_SIZE - 1; const int32 LayoutChunkVoxels=FMath::RoundToInt(StrateLayoutChunkWidthVoxels);
Slot.BottomChunkZ = SeasonStrate.BottomWorldZ / CHUNK_SIZE; Slot.TopChunkZ = SeasonStrate.TopWorldZ / LayoutChunkVoxels - 1;
if (SeasonStrate.TopWorldZ % CHUNK_SIZE != 0 Slot.BottomChunkZ = SeasonStrate.BottomWorldZ / LayoutChunkVoxels;
|| SeasonStrate.BottomWorldZ % CHUNK_SIZE != 0 if (SeasonStrate.TopWorldZ % LayoutChunkVoxels != 0
|| SeasonStrate.BottomWorldZ % LayoutChunkVoxels != 0
|| Slot.TopChunkZ != CurrentTopZ || Slot.TopChunkZ != CurrentTopZ
|| Slot.BottomChunkZ != CurrentTopZ - (Slot.HeightInChunks - 1)) || Slot.BottomChunkZ != CurrentTopZ - (Slot.HeightInChunks - 1))
{ {
@@ -1525,8 +1537,8 @@ bool UVoxelStrateManager::SetComposerOverrideForStrate(
} }
VF_SetComposerRuntimeBounds( VF_SetComposerRuntimeBounds(
Override->Params, Override->Params,
(float)(TargetSlot->TopChunkZ + 1) * CHUNK_SIZE, (float)(TargetSlot->TopChunkZ + 1) * StrateLayoutChunkWidthVoxels,
(float)TargetSlot->BottomChunkZ * CHUNK_SIZE); (float)TargetSlot->BottomChunkZ * StrateLayoutChunkWidthVoxels);
Override->bUseRecipe = bUseRecipe; Override->bUseRecipe = bUseRecipe;
if (Recipe != nullptr) if (Recipe != nullptr)
{ {
@@ -1545,8 +1557,8 @@ bool UVoxelStrateManager::SetComposerOverrideForStrate(
Override->bUseRegions = true; Override->bUseRegions = true;
Override->Regions = *InRegions; Override->Regions = *InRegions;
VF_RekeyStrateRegionManifest(Override->Regions, CandidateSeed, StrateIndex); VF_RekeyStrateRegionManifest(Override->Regions, CandidateSeed, StrateIndex);
Override->Regions.StrateTopWorldZ = (float)(TargetSlot->TopChunkZ + 1) * CHUNK_SIZE; Override->Regions.StrateTopWorldZ = (float)(TargetSlot->TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Override->Regions.StrateBottomWorldZ = (float)TargetSlot->BottomChunkZ * CHUNK_SIZE; Override->Regions.StrateBottomWorldZ = (float)TargetSlot->BottomChunkZ * StrateLayoutChunkWidthVoxels;
VF_SetStrateArchetypeRuntimeBounds(Override->Params, VF_SetStrateArchetypeRuntimeBounds(Override->Params,
Override->Regions.StrateTopWorldZ, Override->Regions.StrateTopWorldZ,
Override->Regions.StrateBottomWorldZ); Override->Regions.StrateBottomWorldZ);
@@ -1796,11 +1808,11 @@ void UVoxelStrateManager::GeneratePassages()
const FStratePassageConfig& Cfg = UpperDef->PassageConfig; const FStratePassageConfig& Cfg = UpperDef->PassageConfig;
// Upper strate floor and lower strate ceiling (differ when there's a bedrock gap). // Upper strate floor and lower strate ceiling (differ when there's a bedrock gap).
const float UpperTopZ = (float)(Upper.TopChunkZ + 1) * CHUNK_SIZE; const float UpperTopZ = (float)(Upper.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
const float UpperBottomZ = (float)(Upper.BottomChunkZ) * CHUNK_SIZE; const float UpperBottomZ = (float)(Upper.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
const float LowerTopZ = (float)(Lower.TopChunkZ + 1) * CHUNK_SIZE; const float LowerTopZ = (float)(Lower.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
const float UpperMax = (float)Upper.HeightInChunks * CHUNK_SIZE * 0.9f; const float UpperMax = (float)Upper.HeightInChunks * StrateLayoutChunkWidthVoxels * 0.9f;
const float LowerMax = (float)Lower.HeightInChunks * CHUNK_SIZE * 0.9f; const float LowerMax = (float)Lower.HeightInChunks * StrateLayoutChunkWidthVoxels * 0.9f;
const float DistLo = FMath::Min(Cfg.DistanceMin, Cfg.DistanceMax); const float DistLo = FMath::Min(Cfg.DistanceMin, Cfg.DistanceMax);
const float DistHi = FMath::Max(Cfg.DistanceMin, Cfg.DistanceMax); const float DistHi = FMath::Max(Cfg.DistanceMin, Cfg.DistanceMax);
@@ -1930,7 +1942,7 @@ void UVoxelStrateManager::GeneratePassages()
LowerDef->FloatingIslandParams, LowerDef->FloatingIslandParams,
LowerQuerySeed, LowerQuerySeed,
LowerTopZ, LowerTopZ,
(float)(Lower.BottomChunkZ) * CHUNK_SIZE, (float)(Lower.BottomChunkZ) * StrateLayoutChunkWidthVoxels,
PX, PX,
PY, PY,
MaxLateralSnap, MaxLateralSnap,
@@ -1990,7 +2002,7 @@ void UVoxelStrateManager::GeneratePassages()
if (bAimedLowerAtPlayerFitPoint) if (bAimedLowerAtPlayerFitPoint)
{ {
const float LowerSealThickness = BoundarySealThicknessFor(*LowerDef); const float LowerSealThickness = BoundarySealThicknessFor(*LowerDef);
const float LowerBottomZ = (float)(Lower.BottomChunkZ) * CHUNK_SIZE; const float LowerBottomZ = (float)(Lower.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
const float InnerBottomZ = LowerBottomZ + LowerSealThickness; const float InnerBottomZ = LowerBottomZ + LowerSealThickness;
const float InnerTopZ = LowerTopZ - LowerSealThickness; const float InnerTopZ = LowerTopZ - LowerSealThickness;
if (VoxelMath::IsFinite(SuggestedLowerPoint.X) if (VoxelMath::IsFinite(SuggestedLowerPoint.X)
@@ -2158,7 +2170,7 @@ void UVoxelStrateManager::GeneratePassages()
Cfg.MouthRadius, Cfg.MouthRadius,
LowerDoorDirection, LowerDoorDirection,
LowerTopZ, LowerTopZ,
(float)(Lower.BottomChunkZ) * CHUNK_SIZE, (float)(Lower.BottomChunkZ) * StrateLayoutChunkWidthVoxels,
LowerDef ? BoundarySealThicknessFor(*LowerDef) : 0.0f, LowerDef ? BoundarySealThicknessFor(*LowerDef) : 0.0f,
bAimedLowerAtPlayerFitPoint); bAimedLowerAtPlayerFitPoint);
Passage.UpperPoint = Passage.UpperLanding.StandingPoint; Passage.UpperPoint = Passage.UpperLanding.StandingPoint;
@@ -2583,8 +2595,8 @@ void UVoxelStrateManager::GeneratePassages()
if (bOpenSurfaceEntry && OriginSpineRadius > 0.0f && StrateLayout.Num() > 0) if (bOpenSurfaceEntry && OriginSpineRadius > 0.0f && StrateLayout.Num() > 0)
{ {
const FStrateSlot& Top = StrateLayout[0]; const FStrateSlot& Top = StrateLayout[0];
const float TopZ = (float)(Top.TopChunkZ + 1) * CHUNK_SIZE; const float TopZ = (float)(Top.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
const float BottomZ = (float)Top.BottomChunkZ * CHUNK_SIZE; const float BottomZ = (float)Top.BottomChunkZ * StrateLayoutChunkWidthVoxels;
const float TopSeal = Top.Definition const float TopSeal = Top.Definition
? BoundarySealThicknessFor(*Top.Definition) : 0.0f; ? BoundarySealThicknessFor(*Top.Definition) : 0.0f;
const VoxelPassageGeometry::FOriginLandingGeometry OriginLanding = const VoxelPassageGeometry::FOriginLandingGeometry OriginLanding =
@@ -2607,7 +2619,7 @@ void UVoxelStrateManager::GeneratePassages()
// the top seal into the finite landing room; lower strate seals remain untouched. // the top seal into the finite landing room; lower strate seals remain untouched.
Entry.Radius = FMath::Max(OriginSpineRadius, Entry.Radius = FMath::Max(OriginSpineRadius,
VoxelPassageGeometry::MetersToVoxels(0.25f)); VoxelPassageGeometry::MetersToVoxels(0.25f));
Entry.UpperPoint = FVector(0.0f, 0.0f, TopZ + CHUNK_SIZE); Entry.UpperPoint = FVector(0.0f, 0.0f, TopZ + StrateLayoutChunkWidthVoxels);
// The capsule's lower tangent meets the room ceiling; it never bores through the // The capsule's lower tangent meets the room ceiling; it never bores through the
// room's floor or creates an origin column in strate 0. // room's floor or creates an origin column in strate 0.
Entry.LowerPoint = FVector( Entry.LowerPoint = FVector(
@@ -2671,7 +2683,7 @@ float UVoxelStrateManager::EvaluateModifierSDF(float WorldX, float WorldY, float
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldZ / (float)CHUNK_SIZE)); FMath::FloorToInt(WorldZ / StrateLayoutChunkWidthVoxels));
// The shortlist is rebuilt once for a (manager, version, chunk) and is shared by the tube, // The shortlist is rebuilt once for a (manager, version, chunk) and is shared by the tube,
// landing, and floor paths. No source-fit stencil or topology search is allowed below it. // landing, and floor paths. No source-fit stencil or topology search is allowed below it.
@@ -2817,7 +2829,7 @@ void UVoxelStrateManager::ApplyPassageModifier(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldZ / (float)CHUNK_SIZE)); FMath::FloorToInt(WorldZ / StrateLayoutChunkWidthVoxels));
const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord);
const FVoxelPassage* PassageData = Passages.GetData(); const FVoxelPassage* PassageData = Passages.GetData();
const FVector Position(WorldX, WorldY, WorldZ); const FVector Position(WorldX, WorldY, WorldZ);
@@ -2910,7 +2922,7 @@ void UVoxelStrateManager::ApplyPassageLandingAir(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldZ / (float)CHUNK_SIZE)); FMath::FloorToInt(WorldZ / StrateLayoutChunkWidthVoxels));
const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord);
if (Nearby.Num() == 0) return; if (Nearby.Num() == 0) return;
@@ -3021,7 +3033,7 @@ void UVoxelStrateManager::ApplyPassageLandingFloorMC(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldZ / (float)CHUNK_SIZE)); FMath::FloorToInt(WorldZ / StrateLayoutChunkWidthVoxels));
const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord);
const FVoxelPassage* PassageData = Passages.GetData(); const FVoxelPassage* PassageData = Passages.GetData();
const FVector Position(WorldX, WorldY, WorldZ); const FVector Position(WorldX, WorldY, WorldZ);
@@ -3117,7 +3129,7 @@ void UVoxelStrateManager::ApplyPassageStructuralPostsMC(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldZ / (float)CHUNK_SIZE)); FMath::FloorToInt(WorldZ / StrateLayoutChunkWidthVoxels));
const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord);
if (Nearby.Num() == 0) return; if (Nearby.Num() == 0) return;
@@ -3244,7 +3256,7 @@ void UVoxelStrateManager::ApplyPassageNativeFloorMC(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldZ / (float)CHUNK_SIZE)); FMath::FloorToInt(WorldZ / StrateLayoutChunkWidthVoxels));
const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord);
if (Nearby.Num() == 0 if (Nearby.Num() == 0
|| VoxelPassageGeometry::VerticalShaftConnectorAirMarker()) || VoxelPassageGeometry::VerticalShaftConnectorAirMarker())
@@ -3435,7 +3447,7 @@ void UVoxelStrateManager::ApplyPassageLandingRoomFloorMC(
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldZ / (float)CHUNK_SIZE)); FMath::FloorToInt(WorldZ / StrateLayoutChunkWidthVoxels));
const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord); const TArray<int32>& Nearby = VF_GetNearbyPassages(this, ChunkCoord);
const FVoxelPassage* PassageData = Passages.GetData(); const FVoxelPassage* PassageData = Passages.GetData();
const FVector Position(WorldX, WorldY, WorldZ); const FVector Position(WorldX, WorldY, WorldZ);
@@ -5909,8 +5921,8 @@ bool UVoxelStrateManager::AnyLandingFloorAtLattice(
for (const FStrateSlot& Slot : StrateLayout) for (const FStrateSlot& Slot : StrateLayout)
{ {
if (Slot.Definition == nullptr) continue; if (Slot.Definition == nullptr) continue;
const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * CHUNK_SIZE; const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * StrateLayoutChunkWidthVoxels;
const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition); const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition);
const VoxelPassageGeometry::FOriginLandingGeometry Geometry = const VoxelPassageGeometry::FOriginLandingGeometry Geometry =
VoxelPassageGeometry::BuildOriginLandingGeometry( VoxelPassageGeometry::BuildOriginLandingGeometry(
@@ -5952,8 +5964,8 @@ bool UVoxelStrateManager::AnyOriginLandingNearBox(
for (const FStrateSlot& Slot : StrateLayout) for (const FStrateSlot& Slot : StrateLayout)
{ {
if (Slot.Definition == nullptr) continue; if (Slot.Definition == nullptr) continue;
const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * CHUNK_SIZE; const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * StrateLayoutChunkWidthVoxels;
const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
if (VoxelPassageGeometry::OriginLandingRoomTouchesBox( if (VoxelPassageGeometry::OriginLandingRoomTouchesBox(
VoxelBox, TopZ, BottomZ, VoxelBox, TopZ, BottomZ,
VF_BoundarySealThicknessForDefinition(*Slot.Definition), VF_BoundarySealThicknessForDefinition(*Slot.Definition),
@@ -5973,8 +5985,8 @@ bool UVoxelStrateManager::AnyOriginLandingFloorNearBox(
for (const FStrateSlot& Slot : StrateLayout) for (const FStrateSlot& Slot : StrateLayout)
{ {
if (Slot.Definition == nullptr) continue; if (Slot.Definition == nullptr) continue;
const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * CHUNK_SIZE; const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * StrateLayoutChunkWidthVoxels;
const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
if (VoxelPassageGeometry::OriginLandingFloorTouchesBox( if (VoxelPassageGeometry::OriginLandingFloorTouchesBox(
VoxelBox, TopZ, BottomZ, VoxelBox, TopZ, BottomZ,
VF_BoundarySealThicknessForDefinition(*Slot.Definition), VF_BoundarySealThicknessForDefinition(*Slot.Definition),
@@ -5998,8 +6010,8 @@ bool UVoxelStrateManager::AnyOriginLandingNearLattice(
for (const FStrateSlot& Slot : StrateLayout) for (const FStrateSlot& Slot : StrateLayout)
{ {
if (Slot.Definition == nullptr) continue; if (Slot.Definition == nullptr) continue;
const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * CHUNK_SIZE; const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * StrateLayoutChunkWidthVoxels;
const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition); const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition);
if (VoxelPassageGeometry::OriginLandingRoomTouchesLattice( if (VoxelPassageGeometry::OriginLandingRoomTouchesLattice(
VoxelBox, LatticeOrigin, Step, TopZ, BottomZ, Seal, OriginSpineRadius, VoxelBox, LatticeOrigin, Step, TopZ, BottomZ, Seal, OriginSpineRadius,
@@ -6036,8 +6048,8 @@ bool UVoxelStrateManager::AnyOriginLandingAirNearLattice(
{ {
continue; continue;
} }
const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * CHUNK_SIZE; const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * StrateLayoutChunkWidthVoxels;
const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition); const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition);
const VoxelPassageGeometry::FOriginLandingGeometry Geometry = const VoxelPassageGeometry::FOriginLandingGeometry Geometry =
VoxelPassageGeometry::BuildOriginLandingGeometry( VoxelPassageGeometry::BuildOriginLandingGeometry(
@@ -6113,8 +6125,8 @@ bool UVoxelStrateManager::AnyOriginLandingFloorNearLattice(
for (const FStrateSlot& Slot : StrateLayout) for (const FStrateSlot& Slot : StrateLayout)
{ {
if (Slot.Definition == nullptr) continue; if (Slot.Definition == nullptr) continue;
const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * CHUNK_SIZE; const float TopZ = (static_cast<float>(Slot.TopChunkZ) + 1.0f) * StrateLayoutChunkWidthVoxels;
const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition); const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition);
if (VoxelPassageGeometry::OriginLandingFloorTouchesLattice( if (VoxelPassageGeometry::OriginLandingFloorTouchesLattice(
VoxelBox, LatticeOrigin, Step, TopZ, BottomZ, Seal, OriginSpineRadius)) VoxelBox, LatticeOrigin, Step, TopZ, BottomZ, Seal, OriginSpineRadius))
@@ -6148,7 +6160,7 @@ int32 UVoxelStrateManager::FindSlotIndexForChunkZ(int32 ChunkZ) const
UVoxelStrateDefinition* UVoxelStrateManager::GetStrateAt(float WorldZ) const UVoxelStrateDefinition* UVoxelStrateManager::GetStrateAt(float WorldZ) const
{ {
// Convert world Z to chunk Z coordinate // Convert world Z to chunk Z coordinate
int32 ChunkZ = FMath::FloorToInt((WorldZ / VOXEL_SIZE) / CHUNK_SIZE); int32 ChunkZ = FMath::FloorToInt((WorldZ / VOXEL_SIZE) / StrateLayoutChunkWidthVoxels);
int32 SlotIdx = FindSlotIndexForChunkZ(ChunkZ); int32 SlotIdx = FindSlotIndexForChunkZ(ChunkZ);
if (SlotIdx >= 0) if (SlotIdx >= 0)
{ {
@@ -6159,7 +6171,7 @@ UVoxelStrateDefinition* UVoxelStrateManager::GetStrateAt(float WorldZ) const
int32 UVoxelStrateManager::GetStrateIndex(float WorldZ) const int32 UVoxelStrateManager::GetStrateIndex(float WorldZ) const
{ {
int32 ChunkZ = FMath::FloorToInt((WorldZ / VOXEL_SIZE) / CHUNK_SIZE); int32 ChunkZ = FMath::FloorToInt((WorldZ / VOXEL_SIZE) / StrateLayoutChunkWidthVoxels);
int32 SlotIdx = FindSlotIndexForChunkZ(ChunkZ); int32 SlotIdx = FindSlotIndexForChunkZ(ChunkZ);
if (SlotIdx >= 0) if (SlotIdx >= 0)
{ {
@@ -6318,9 +6330,9 @@ FSlabGenerationParams UVoxelStrateManager::GetSlabParamsForChunk(const FIntVecto
// Fill in the runtime Z bounds (voxel coordinates, same convention as // Fill in the runtime Z bounds (voxel coordinates, same convention as
// FStrateGenerationParams::StrateTopWorldZ / StrateBottomWorldZ). // FStrateGenerationParams::StrateTopWorldZ / StrateBottomWorldZ).
// TopChunkZ+1 because the top chunk's CEILING is at (TopChunkZ+1)*CHUNK_SIZE. // TopChunkZ+1 because the top chunk's CEILING is at (TopChunkZ+1)*StrateLayoutChunkWidthVoxels.
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)(Slot.BottomChunkZ) * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
return Result; return Result;
} }
@@ -6353,8 +6365,8 @@ FMazeGenerationParams UVoxelStrateManager::GetMazeParamsForChunk(const FIntVecto
} }
} }
#endif #endif
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * StrateLayoutChunkWidthVoxels;
return Result; return Result;
} }
@@ -6380,8 +6392,8 @@ FSurfaceGenerationParams UVoxelStrateManager::GetSurfaceParamsForChunk(const FIn
} }
} }
#endif #endif
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * StrateLayoutChunkWidthVoxels;
return Result; return Result;
} }
@@ -6407,8 +6419,8 @@ FVerticalShaftParams UVoxelStrateManager::GetVerticalShaftParamsForChunk(const F
} }
} }
#endif #endif
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * StrateLayoutChunkWidthVoxels;
return Result; return Result;
} }
@@ -6434,8 +6446,8 @@ FFloatingIslandParams UVoxelStrateManager::GetFloatingIslandParamsForChunk(const
} }
} }
#endif #endif
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * StrateLayoutChunkWidthVoxels;
return Result; return Result;
} }
@@ -6469,14 +6481,14 @@ FBiomeContext UVoxelStrateManager::GetBiomeContextForChunk(const FIntVector& Chu
bool UVoxelStrateManager::GetStrateUnrealZRange(float WorldZ, float& OutTopZ, float& OutBottomZ) const bool UVoxelStrateManager::GetStrateUnrealZRange(float WorldZ, float& OutTopZ, float& OutBottomZ) const
{ {
const int32 ChunkZ = FMath::FloorToInt((WorldZ / VOXEL_SIZE) / CHUNK_SIZE); const int32 ChunkZ = FMath::FloorToInt((WorldZ / VOXEL_SIZE) / StrateLayoutChunkWidthVoxels);
const int32 SlotIdx = FindSlotIndexForChunkZ(ChunkZ); const int32 SlotIdx = FindSlotIndexForChunkZ(ChunkZ);
if (SlotIdx < 0) return false; if (SlotIdx < 0) return false;
const FStrateSlot& Slot = StrateLayout[SlotIdx]; const FStrateSlot& Slot = StrateLayout[SlotIdx];
// Voxel-space Z bounds → Unreal units. Ceiling = top chunk's upper edge. // Voxel-space Z bounds → Unreal units. Ceiling = top chunk's upper edge.
OutTopZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE * VOXEL_SIZE; OutTopZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels * VOXEL_SIZE;
OutBottomZ = (float)(Slot.BottomChunkZ) * CHUNK_SIZE * VOXEL_SIZE; OutBottomZ = (float)(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels * VOXEL_SIZE;
return true; return true;
} }
@@ -6489,8 +6501,8 @@ FStrateDisturbanceParams UVoxelStrateManager::GetDisturbanceParamsForChunk(const
} }
const FStrateSlot& Slot = StrateLayout[SlotIdx]; const FStrateSlot& Slot = StrateLayout[SlotIdx];
FStrateDisturbanceParams Result = Slot.Definition->Disturbances; FStrateDisturbanceParams Result = Slot.Definition->Disturbances;
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)(Slot.BottomChunkZ) * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
return Result; return Result;
} }
@@ -6522,8 +6534,8 @@ float UVoxelStrateManager::GetWaterLevelWorldZForChunk(const FIntVector& ChunkCo
} }
if (Rel <= 0.0f) return -FLT_MAX; if (Rel <= 0.0f) return -FLT_MAX;
const float BottomZ = (float)(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = (float)(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
const float TopZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; const float TopZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
return FMath::Lerp(BottomZ, TopZ, FMath::Clamp(Rel, 0.0f, 1.0f)); return FMath::Lerp(BottomZ, TopZ, FMath::Clamp(Rel, 0.0f, 1.0f));
} }
@@ -6567,8 +6579,8 @@ FStrateGenerationParams UVoxelStrateManager::GetGenerationParams(const FIntVecto
FindComposerOverride(Slot.StrateIndex)) FindComposerOverride(Slot.StrateIndex))
{ {
FStrateGenerationParams Result = Override->Params.TunnelNetworkParams; FStrateGenerationParams Result = Override->Params.TunnelNetworkParams;
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * StrateLayoutChunkWidthVoxels;
// A candidate is a hard replacement of this slot. Do not blend its rolled vector with an // A candidate is a hard replacement of this slot. Do not blend its rolled vector with an
// authored neighbour at a boundary; this is also how the offline fixture measures it. // authored neighbour at a boundary; this is also how the offline fixture measures it.
return ResolveFinalParams(Result); return ResolveFinalParams(Result);
@@ -6578,8 +6590,8 @@ FStrateGenerationParams UVoxelStrateManager::GetGenerationParams(const FIntVecto
if (SeasonStrates.IsValidIndex(SlotIdx)) if (SeasonStrates.IsValidIndex(SlotIdx))
{ {
FStrateGenerationParams Result = SeasonStrates[SlotIdx].Params.TunnelNetworkParams; FStrateGenerationParams Result = SeasonStrates[SlotIdx].Params.TunnelNetworkParams;
Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; Result.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * CHUNK_SIZE; Result.StrateBottomWorldZ = (float)Slot.BottomChunkZ * StrateLayoutChunkWidthVoxels;
// Season vectors are already final, measured slot records. Vertical structural posts own // Season vectors are already final, measured slot records. Vertical structural posts own
// their boundary; blending them with another selected recipe would describe neither one. // their boundary; blending them with another selected recipe would describe neither one.
return ResolveFinalParams(Result); return ResolveFinalParams(Result);
@@ -6596,8 +6608,17 @@ FStrateGenerationParams UVoxelStrateManager::GetGenerationParams(const FIntVecto
// //
// TopChunkZ=0, CHUNK_SIZE=32: top of the strate = chunk 0's top edge = voxel Z=32 // TopChunkZ=0, CHUNK_SIZE=32: top of the strate = chunk 0's top edge = voxel Z=32
// BottomChunkZ=-3: bottom of the strate = chunk -3's bottom edge = voxel Z=-3*32 = -96 // BottomChunkZ=-3: bottom of the strate = chunk -3's bottom edge = voxel Z=-3*32 = -96
BaseParams.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * CHUNK_SIZE; BaseParams.StrateTopWorldZ = (float)(Slot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
BaseParams.StrateBottomWorldZ = (float)(Slot.BottomChunkZ) * CHUNK_SIZE; BaseParams.StrateBottomWorldZ = (float)(Slot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
// Core currently dispatches one generator field per resolved strate. Gradient and
// interleaved metadata therefore use the explicitly declared Hard fallback for every
// legacy parameter lookup as well; mixing parameter vectors here would disagree with the
// shared ceiling/content/bedrock composition layer.
if (bHardTransitionFallbackForAssembly)
{
return ResolveFinalParams(BaseParams);
}
//========================================================================= //=========================================================================
// BOUNDARY BLENDING (transition-type aware) // BOUNDARY BLENDING (transition-type aware)
@@ -6670,8 +6691,8 @@ FStrateGenerationParams UVoxelStrateManager::GetGenerationParams(const FIntVecto
if (EffectiveBlend > 0 && DistFromBottom < EffectiveBlend) if (EffectiveBlend > 0 && DistFromBottom < EffectiveBlend)
{ {
FStrateGenerationParams BelowParams = BuildParamsFromDefinition(BelowSlot.Definition); FStrateGenerationParams BelowParams = BuildParamsFromDefinition(BelowSlot.Definition);
BelowParams.StrateTopWorldZ = (float)(BelowSlot.TopChunkZ + 1) * CHUNK_SIZE; BelowParams.StrateTopWorldZ = (float)(BelowSlot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
BelowParams.StrateBottomWorldZ = (float)(BelowSlot.BottomChunkZ) * CHUNK_SIZE; BelowParams.StrateBottomWorldZ = (float)(BelowSlot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
// Linear alpha: 0 at EffectiveBlend chunks away, 1 at the boundary // Linear alpha: 0 at EffectiveBlend chunks away, 1 at the boundary
float Alpha = 1.0f - ((float)DistFromBottom / (float)EffectiveBlend); float Alpha = 1.0f - ((float)DistFromBottom / (float)EffectiveBlend);
@@ -6708,8 +6729,8 @@ FStrateGenerationParams UVoxelStrateManager::GetGenerationParams(const FIntVecto
if (DistFromBottom < CheckRange) if (DistFromBottom < CheckRange)
{ {
FStrateGenerationParams BelowParams = BuildParamsFromDefinition(BelowSlot.Definition); FStrateGenerationParams BelowParams = BuildParamsFromDefinition(BelowSlot.Definition);
BelowParams.StrateTopWorldZ = (float)(BelowSlot.TopChunkZ + 1) * CHUNK_SIZE; BelowParams.StrateTopWorldZ = (float)(BelowSlot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
BelowParams.StrateBottomWorldZ = (float)(BelowSlot.BottomChunkZ) * CHUNK_SIZE; BelowParams.StrateBottomWorldZ = (float)(BelowSlot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
// Sample 3D Perlin noise to warp the boundary position. // Sample 3D Perlin noise to warp the boundary position.
// XY frequency 0.15 gives medium-scale variation (~6-7 chunks per cycle). // XY frequency 0.15 gives medium-scale variation (~6-7 chunks per cycle).
@@ -6769,8 +6790,8 @@ FStrateGenerationParams UVoxelStrateManager::GetGenerationParams(const FIntVecto
if (EffectiveBlend > 0 && DistFromTop < EffectiveBlend) if (EffectiveBlend > 0 && DistFromTop < EffectiveBlend)
{ {
FStrateGenerationParams AboveParams = BuildParamsFromDefinition(AboveSlot.Definition); FStrateGenerationParams AboveParams = BuildParamsFromDefinition(AboveSlot.Definition);
AboveParams.StrateTopWorldZ = (float)(AboveSlot.TopChunkZ + 1) * CHUNK_SIZE; AboveParams.StrateTopWorldZ = (float)(AboveSlot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
AboveParams.StrateBottomWorldZ = (float)(AboveSlot.BottomChunkZ) * CHUNK_SIZE; AboveParams.StrateBottomWorldZ = (float)(AboveSlot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
float Alpha = 1.0f - ((float)DistFromTop / (float)EffectiveBlend); float Alpha = 1.0f - ((float)DistFromTop / (float)EffectiveBlend);
Alpha = FMath::Clamp(Alpha, 0.0f, 1.0f); Alpha = FMath::Clamp(Alpha, 0.0f, 1.0f);
@@ -6791,8 +6812,8 @@ FStrateGenerationParams UVoxelStrateManager::GetGenerationParams(const FIntVecto
if (DistFromTop < CheckRange) if (DistFromTop < CheckRange)
{ {
FStrateGenerationParams AboveParams = BuildParamsFromDefinition(AboveSlot.Definition); FStrateGenerationParams AboveParams = BuildParamsFromDefinition(AboveSlot.Definition);
AboveParams.StrateTopWorldZ = (float)(AboveSlot.TopChunkZ + 1) * CHUNK_SIZE; AboveParams.StrateTopWorldZ = (float)(AboveSlot.TopChunkZ + 1) * StrateLayoutChunkWidthVoxels;
AboveParams.StrateBottomWorldZ = (float)(AboveSlot.BottomChunkZ) * CHUNK_SIZE; AboveParams.StrateBottomWorldZ = (float)(AboveSlot.BottomChunkZ) * StrateLayoutChunkWidthVoxels;
// Same noise function but with a different seed offset to avoid // Same noise function but with a different seed offset to avoid
// symmetry between top and bottom boundaries of adjacent strates // symmetry between top and bottom boundaries of adjacent strates
+77 -7
View File
@@ -146,6 +146,10 @@ public:
FVoxelForgeCoreTaskScheduler Scheduler; FVoxelForgeCoreTaskScheduler Scheduler;
std::unordered_set<VoxelForgeCore::TileKey, VoxelForgeCore::TileKeyHash> RetainedTiles; std::unordered_set<VoxelForgeCore::TileKey, VoxelForgeCore::TileKeyHash> RetainedTiles;
FCriticalSection RetainedTilesLock; FCriticalSection RetainedTilesLock;
FCriticalSection ShapeReadinessLock;
std::unordered_set<VoxelForgeCore::TileKey, VoxelForgeCore::TileKeyHash> ShapeFreeTiles;
std::unordered_set<VoxelForgeCore::TileKey, VoxelForgeCore::TileKeyHash> ShapeDependentTiles;
std::atomic<bool> bSnapshotReady{false};
std::atomic<bool> bReady{false}; std::atomic<bool> bReady{false};
std::atomic<bool> bInitialFailed{false}; std::atomic<bool> bInitialFailed{false};
std::atomic<bool> bRegionCompileInFlight{false}; std::atomic<bool> bRegionCompileInFlight{false};
@@ -235,6 +239,18 @@ namespace
GVoxelForgeStreamingBackgroundWorkerCap, GVoxelForgeStreamingBackgroundWorkerCap,
TEXT("Size tile admission slots to the TaskGraph background workers used by tile tasks; 0 restores the logical-core cap.")); TEXT("Size tile admission slots to the TaskGraph background workers used by tile tasks; 0 restores the logical-core cap."));
int32 GVoxelForgeCoreColumnCacheDirectMapped = 0;
FAutoConsoleVariableRef CVarVoxelForgeCoreColumnCacheDirectMapped(
TEXT("voxel.CoreColumnCacheDirectMapped"),
GVoxelForgeCoreColumnCacheDirectMapped,
TEXT("Negative control: 0 uses the four-way deterministic XY column cache; 1 restores S13 direct-map indexing."));
int32 GVoxelForgeCoreMCGradientMemoization = 1;
FAutoConsoleVariableRef CVarVoxelForgeCoreMCGradientMemoization(
TEXT("voxel.CoreMCGradientMemoization"),
GVoxelForgeCoreMCGradientMemoization,
TEXT("Negative control: 1 reuses exact LOD0 lattice gradients across adjacent MC cells; 0 restores per-cell gradient probes."));
int32 GVoxelForgeProfileTileGeneration = 0; int32 GVoxelForgeProfileTileGeneration = 0;
FAutoConsoleVariableRef CVarVoxelForgeProfileTileGeneration( FAutoConsoleVariableRef CVarVoxelForgeProfileTileGeneration(
TEXT("voxel.ProfileTileGeneration"), TEXT("voxel.ProfileTileGeneration"),
@@ -2080,6 +2096,8 @@ void AVoxelWorld::BeginPlay()
int32 CommandLineStreamingResultBacklogCap = GVoxelForgeStreamingResultBacklogCap; int32 CommandLineStreamingResultBacklogCap = GVoxelForgeStreamingResultBacklogCap;
int32 CommandLineStreamingReadyQueueDepth = GVoxelForgeStreamingReadyQueueDepth; int32 CommandLineStreamingReadyQueueDepth = GVoxelForgeStreamingReadyQueueDepth;
int32 CommandLineStreamingBackgroundWorkerCap = GVoxelForgeStreamingBackgroundWorkerCap; int32 CommandLineStreamingBackgroundWorkerCap = GVoxelForgeStreamingBackgroundWorkerCap;
int32 CommandLineCoreColumnCacheDirectMapped = GVoxelForgeCoreColumnCacheDirectMapped;
int32 CommandLineCoreMCGradientMemoization = GVoxelForgeCoreMCGradientMemoization;
int32 CommandLineStep1GenerationCap = GVoxelForgeStep1GenerationCap; int32 CommandLineStep1GenerationCap = GVoxelForgeStep1GenerationCap;
int32 CommandLineStep1ExitAfterFrames = GVoxelForgeStep1ExitAfterFrames; int32 CommandLineStep1ExitAfterFrames = GVoxelForgeStep1ExitAfterFrames;
int32 CommandLineStep1CsvCaptureOnBeginPlay = GVoxelForgeStep1CsvCaptureOnBeginPlay; int32 CommandLineStep1CsvCaptureOnBeginPlay = GVoxelForgeStep1CsvCaptureOnBeginPlay;
@@ -2186,6 +2204,18 @@ void AVoxelWorld::BeginPlay()
GVoxelForgeStreamingBackgroundWorkerCap = GVoxelForgeStreamingBackgroundWorkerCap =
CommandLineStreamingBackgroundWorkerCap != 0 ? 1 : 0; CommandLineStreamingBackgroundWorkerCap != 0 ? 1 : 0;
} }
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.CoreColumnCacheDirectMapped="),
CommandLineCoreColumnCacheDirectMapped))
{
GVoxelForgeCoreColumnCacheDirectMapped=
CommandLineCoreColumnCacheDirectMapped!=0?1:0;
}
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.CoreMCGradientMemoization="),
CommandLineCoreMCGradientMemoization))
{
GVoxelForgeCoreMCGradientMemoization=
CommandLineCoreMCGradientMemoization!=0?1:0;
}
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.Step1PrequeueVisibleLOD0="), if (FParse::Value(FCommandLine::Get(), TEXT("voxel.Step1PrequeueVisibleLOD0="),
CommandLineStep1PrequeueVisibleLOD0)) CommandLineStep1PrequeueVisibleLOD0))
{ {
@@ -2609,7 +2639,9 @@ void AVoxelWorld::BeginPlay()
"\"streaming_legacy_pending_result_cap\":%d," "\"streaming_legacy_pending_result_cap\":%d,"
"\"streaming_collision_lookahead\":%d,\"core_region_concurrent_admission\":%d," "\"streaming_collision_lookahead\":%d,\"core_region_concurrent_admission\":%d,"
"\"collision_gate\":%d," "\"collision_gate\":%d,"
"\"streaming_result_backlog_cap\":%d,\"streaming_startup_apply_boost\":%d"), "\"streaming_result_backlog_cap\":%d,\"streaming_startup_apply_boost\":%d,"
"\"core_column_cache_direct_mapped\":%d,"
"\"core_mc_gradient_memoization\":%d"),
FPlatformMisc::NumberOfCoresIncludingHyperthreads(), GetMaxConcurrentStreamingTasks(), FPlatformMisc::NumberOfCoresIncludingHyperthreads(), GetMaxConcurrentStreamingTasks(),
TaskScheduler.GetNumWorkers(), TaskScheduler.GetMaxNumWorkers(), TaskScheduler.GetNumWorkers(), TaskScheduler.GetMaxNumWorkers(),
static_cast<int32>(TaskScheduler.GetWorkerPriority()), static_cast<int32>(TaskScheduler.GetWorkerPriority()),
@@ -2622,7 +2654,9 @@ void AVoxelWorld::BeginPlay()
GVoxelForgeStreamingLegacyPendingResultCap, GVoxelForgeStreamingLegacyPendingResultCap,
GVoxelForgeStreamingCollisionLookahead, GVoxelForgeCoreRegionConcurrentAdmission, GVoxelForgeStreamingCollisionLookahead, GVoxelForgeCoreRegionConcurrentAdmission,
GVoxelForgeCollisionGate, GVoxelForgeCollisionGate,
GVoxelForgeStreamingResultBacklogCap, GVoxelForgeStreamingStartupApplyBoost)); GVoxelForgeStreamingResultBacklogCap, GVoxelForgeStreamingStartupApplyBoost,
GVoxelForgeCoreColumnCacheDirectMapped,
GVoxelForgeCoreMCGradientMemoization));
VoxelForgeStartupTrace::RecordEvent(TEXT("streaming_worker_cap_readback"), FString::Printf( VoxelForgeStartupTrace::RecordEvent(TEXT("streaming_worker_cap_readback"), FString::Printf(
TEXT("\"streaming_background_worker_cap\":%d,\"background_worker_threads\":%d," TEXT("\"streaming_background_worker_cap\":%d,\"background_worker_threads\":%d,"
"\"effective_tile_slots\":%d"), "\"effective_tile_slots\":%d"),
@@ -7659,6 +7693,7 @@ bool AVoxelWorld::InitializeVoxelForgeCoreWorld(FString& OutFailureReason)
Request.includeFarWorld = true; Request.includeFarWorld = true;
VoxelForgeCoreState = State; VoxelForgeCoreState = State;
State->bSnapshotReady.store(true, std::memory_order_release);
ActiveTaskCount.fetch_add(1, std::memory_order_relaxed); ActiveTaskCount.fetch_add(1, std::memory_order_relaxed);
UE::Tasks::Launch(TEXT("VoxelForgeCoreCompile"), UE::Tasks::Launch(TEXT("VoxelForgeCoreCompile"),
[this, State, Request, InitialDesired, ActiveCoreClipRadius, ActiveCoreMaxClipLevel, [this, State, Request, InitialDesired, ActiveCoreClipRadius, ActiveCoreMaxClipLevel,
@@ -7678,10 +7713,17 @@ bool AVoxelWorld::InitializeVoxelForgeCoreWorld(FString& OutFailureReason)
std::string Error; std::string Error;
bool bCompiled = false; bool bCompiled = false;
bCompiled = State->World->compile(Request, State->Scheduler, Error);
if (bCompiled)
{ {
// The initial compile builds into local state and atomically publishes an immutable
// shape. Proven native-only tiles may hold shared WorldLock readers during this work;
// take the writer only for region retention after publication.
// La compilation initiale construit un etat local puis publie une forme immuable.
// Les tuiles natives validees gardent le verrou lecteur partage; le verrou ecrivain
// ne sert qu'a retenir les regions apres publication.
FWriteScopeLock Lock(State->WorldLock); FWriteScopeLock Lock(State->WorldLock);
bCompiled = State->World->compile(Request, State->Scheduler, Error); if (State->World)
if (bCompiled)
{ {
State->World->retainTileRegions(InitialDesired); State->World->retainTileRegions(InitialDesired);
FScopeLock RetainedLock(&State->RetainedTilesLock); FScopeLock RetainedLock(&State->RetainedTilesLock);
@@ -12989,9 +13031,33 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
return; return;
} }
} }
if (PendingTiles.Contains(Tile) || !IsVoxelForgeCoreReady()) return; if (PendingTiles.Contains(Tile)) return;
const TSharedPtr<FVoxelForgeCoreRuntimeState, ESPMode::ThreadSafe> State = VoxelForgeCoreState; const TSharedPtr<FVoxelForgeCoreRuntimeState, ESPMode::ThreadSafe> State = VoxelForgeCoreState;
if (!State.IsValid() || State->bRegionCompileFailed.load(std::memory_order_acquire)) return; if (!State.IsValid()||State->bInitialFailed.load(std::memory_order_acquire)
||State->bRegionCompileFailed.load(std::memory_order_acquire)
||State->bShuttingDown.load(std::memory_order_acquire))return;
const bool bShapeReady=State->bReady.load(std::memory_order_acquire);
if(!bShapeReady)
{
if(!State->bSnapshotReady.load(std::memory_order_acquire))return;
const VoxelForgeCore::TileKey CoreKey{
{Tile.Coord.X,Tile.Coord.Y,Tile.Coord.Z},Tile.Level};
bool bShapeFree=false;
{
FScopeLock ReadinessLock(&State->ShapeReadinessLock);
if(State->ShapeFreeTiles.contains(CoreKey))bShapeFree=true;
else if(State->ShapeDependentTiles.contains(CoreKey))return;
else
{
FReadScopeLock WorldReadLock(State->WorldLock);
if(!State->World)return;
bShapeFree=State->World->isTileShapeFree(CoreKey);
if(bShapeFree)State->ShapeFreeTiles.insert(CoreKey);
else State->ShapeDependentTiles.insert(CoreKey);
}
}
if(!bShapeFree)return;
}
if (IsStreamingResultBacklogCapped()) if (IsStreamingResultBacklogCapped())
{ {
StreamingResultBacklogCapStops.fetch_add(1, std::memory_order_relaxed); StreamingResultBacklogCapStops.fetch_add(1, std::memory_order_relaxed);
@@ -13043,13 +13109,15 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
VoxelForgeStartupTrace::RecordRequest(RequestSample, TaskEpoch); VoxelForgeStartupTrace::RecordRequest(RequestSample, TaskEpoch);
} }
const bool bCaptureHashes = bCaptureVoxelForgeCoreHashesForValidation; const bool bCaptureHashes = bCaptureVoxelForgeCoreHashesForValidation;
const bool bLegacyDirectMappedColumnCache=GVoxelForgeCoreColumnCacheDirectMapped!=0;
const bool bMemoizeCoreMCGradients=GVoxelForgeCoreMCGradientMemoization!=0;
const UE::Tasks::ETaskPriority TaskPriority = bNearPriority const UE::Tasks::ETaskPriority TaskPriority = bNearPriority
? UE::Tasks::ETaskPriority::BackgroundHigh ? UE::Tasks::ETaskPriority::BackgroundHigh
: UE::Tasks::ETaskPriority::BackgroundNormal; : UE::Tasks::ETaskPriority::BackgroundNormal;
UE::Tasks::Launch(TEXT("VoxelForgeCoreTile"), UE::Tasks::Launch(TEXT("VoxelForgeCoreTile"),
[this, State, Cancellation, Tile, WorkPriority, TaskEpoch, TaskDesiredEpoch, [this, State, Cancellation, Tile, WorkPriority, TaskEpoch, TaskDesiredEpoch,
TaskModificationEpoch, RequestStartCycles, RequestOrdinal, bResidentAtRequest, TaskModificationEpoch, RequestStartCycles, RequestOrdinal, bResidentAtRequest,
bCaptureHashes]() bCaptureHashes,bLegacyDirectMappedColumnCache,bMemoizeCoreMCGradients]()
{ {
struct FTaskGuard struct FTaskGuard
{ {
@@ -13153,6 +13221,8 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
break; break;
} }
Options.hashDensity = bCaptureHashes; Options.hashDensity = bCaptureHashes;
Options.legacyDirectMappedColumnCache=bLegacyDirectMappedColumnCache;
Options.memoizeMcGradients=bMemoizeCoreMCGradients;
std::string CoreError; std::string CoreError;
std::optional<VoxelForgeCore::TileMesh> CoreMesh; std::optional<VoxelForgeCore::TileMesh> CoreMesh;
{ {
@@ -41,21 +41,27 @@
// SealFactor > 0 et BaseDensity > 0, le résultat est solide GARANTI quelle qu'ait été l'entrée. // SealFactor > 0 et BaseDensity > 0, le résultat est solide GARANTI quelle qu'ait été l'entrée.
// C'est exactement ce qu'encode `IVoxelDensityOp::ClassifyBox` (voir VoxelDensityOp.h), et la // C'est exactement ce qu'encode `IVoxelDensityOp::ClassifyBox` (voir VoxelDensityOp.h), et la
// raison pour laquelle cette méthode existe. // raison pour laquelle cette méthode existe.
FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ, FORCEINLINE void VF_ApplyUpperBoundarySealValue(float& Density, float WorldZ,
float StrateTopZ, float StrateBottomZ, float StrateTopZ, float Thickness, float BaseDensity)
float Thickness, float BaseDensity)
{ {
if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return; const float DistTop = StrateTopZ - WorldZ;
const float DistTop = StrateTopZ - WorldZ; // + si on est sous le plafond
const float DistBot = WorldZ - StrateBottomZ; // + si on est au-dessus du sol
if (DistTop >= 0.0f && DistTop < Thickness) if (DistTop >= 0.0f && DistTop < Thickness)
{ {
float SealFactor = 1.0f - (DistTop / Thickness); float SealFactor = 1.0f - (DistTop / Thickness);
SealFactor = SmoothStep01(SealFactor); SealFactor = SmoothStep01(SealFactor);
Density = FMath::Max(Density, SealFactor * BaseDensity); Density = FMath::Max(Density, SealFactor * BaseDensity);
} }
}
FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ,
float StrateTopZ, float StrateBottomZ,
float Thickness, float BaseDensity)
{
if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return;
const float DistBot = WorldZ - StrateBottomZ; // + si on est au-dessus du sol
VF_ApplyUpperBoundarySealValue(Density, WorldZ, StrateTopZ, Thickness, BaseDensity);
if (DistBot >= 0.0f && DistBot < Thickness) if (DistBot >= 0.0f && DistBot < Thickness)
{ {
float SealFactor = 1.0f - (DistBot / Thickness); float SealFactor = 1.0f - (DistBot / Thickness);
@@ -64,6 +70,16 @@ FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ,
} }
} }
// The same structural seal, limited to a strate's upper boundary. Native finite fields use this
// when their lower boundary intentionally has no seal; keeping the math here makes that ceiling
// use the same shared density primitive as every two-sided strate seal.
FORCEINLINE void VF_ApplyUpperBoundarySeal(float& Density, float WorldZ,
float StrateTopZ, float Thickness, float BaseDensity)
{
if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return;
VF_ApplyUpperBoundarySealValue(Density, WorldZ, StrateTopZ, Thickness, BaseDensity);
}
//============================================================================= //=============================================================================
// CARVE DE PASSAGE / PASSAGE CARVING // CARVE DE PASSAGE / PASSAGE CARVING
//============================================================================= //=============================================================================
+7
View File
@@ -419,6 +419,13 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel|Strates", meta = (ClampMin = "0", ClampMax = "16")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel|Strates", meta = (ClampMin = "0", ClampMax = "16"))
int32 InterStrateGapChunks = 0; int32 InterStrateGapChunks = 0;
// Physical width of one vertical strate-layout chunk. This is independent of the
// Core tile width (32^3 voxels) and of the source generator's voxel resolution.
// 8 m preserves the owner's current SurfaceWorld extent at 25 cm Core voxels.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel|Strates|World Assembly",
meta = (ClampMin = "0.25", ClampMax = "64.0", Units = "m"))
float StrateLayoutChunkSizeMeters = 8.0f;
//========================================================================= //=========================================================================
// SPINE & INTER-STRATE CONNECTIONS (the (0,0) descent axis) // SPINE & INTER-STRATE CONNECTIONS (the (0,0) descent axis)
//========================================================================= //=========================================================================
@@ -244,6 +244,13 @@ public:
UFUNCTION(BlueprintCallable, Category = "Strate") UFUNCTION(BlueprintCallable, Category = "Strate")
int32 GetStrateIndex(float WorldZ) const; int32 GetStrateIndex(float WorldZ) const;
// Director-resolved physical strate chunk width expressed in owner voxel units.
// This is independent of Core's 32^3 tile width.
float GetStrateLayoutChunkWidthVoxels() const { return StrateLayoutChunkWidthVoxels; }
uint32 GetStrateLayoutChunkSizeMicrometres() const { return StrateLayoutChunkSizeMicrometres; }
void SetHardTransitionFallbackForAssembly(bool bEnabled)
{ bHardTransitionFallbackForAssembly = bEnabled; }
/** Layout/passage generation counter (bumped by every Initialize → GeneratePassages). /** Layout/passage generation counter (bumped by every Initialize → GeneratePassages).
* Hot-path callers key thread_local memos on this so an editor rebuild (RebuildStrates / * Hot-path callers key thread_local memos on this so an editor rebuild (RebuildStrates /
* live edit) can never serve a stale strate index or passage shortlist. */ * live edit) can never serve a stale strate index or passage shortlist. */
@@ -525,6 +532,11 @@ protected:
// VoxelSettings::InterStrateGapChunks during Initialize(). // VoxelSettings::InterStrateGapChunks during Initialize().
int32 InterStrateGapChunks = 0; int32 InterStrateGapChunks = 0;
// Resolved once from VoxelSettings::StrateLayoutChunkSizeMeters during Initialize().
float StrateLayoutChunkWidthVoxels = 32.0f;
uint32 StrateLayoutChunkSizeMicrometres = 8000000;
bool bHardTransitionFallbackForAssembly = false;
// Production keeps the legacy writer available only as a fail-closed fallback for a // Production keeps the legacy writer available only as a fail-closed fallback for a
// non-native/malformed passage; native D-floors bypass it. This switch never changes the // non-native/malformed passage; native D-floors bypass it. This switch never changes the
// passage carve or air contract. // passage carve or air contract.
+7 -11
View File
@@ -1852,8 +1852,6 @@ struct VOXELFORGE_API FStrateDisturbanceParams
UENUM(BlueprintType) UENUM(BlueprintType)
enum class EVoxelPassageStyle : uint8 enum class EVoxelPassageStyle : uint8
{ {
// “Straight” is retained as the authored style name for the base connection, but its runtime
// geometry is a gentle two-leg switchback rather than a vertical shaft.
Straight UMETA(DisplayName = "Straight (walkable sloped tunnel)"), Straight UMETA(DisplayName = "Straight (walkable sloped tunnel)"),
Worm UMETA(DisplayName = "Worm (organic meander around the axis)"), Worm UMETA(DisplayName = "Worm (organic meander around the axis)"),
Spiral UMETA(DisplayName = "Spiral (corkscrew descent)"), Spiral UMETA(DisplayName = "Spiral (corkscrew descent)"),
@@ -1878,14 +1876,12 @@ struct VOXELFORGE_API FStratePassageConfig
// Tunnel shape. // Tunnel shape.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage")
EVoxelPassageStyle Style = EVoxelPassageStyle::Straight; EVoxelPassageStyle Style = EVoxelPassageStyle::Worm;
// ----- WIDTH (tapers along the length) ----- // ----- WIDTH (tapers along the length) -----
// Radius at the two mouths (entry/exit) and at the middle. Equal = uniform tube; // Radius at the two mouths (entry/exit) and at the middle. Equal = uniform tube;
// The walkable default is 1.5x the original comfortable profile: 2.25 m diameter at mouths // Core raises both radii to at least 12 owner voxels (1.5 m) for capsule clearance.
// and 1.875 m at the waist when the stored radii remain 9/7.5 voxels at 12.5 cm per voxel. // The passage landing remains wider for turning.
// Double these asset values to retain the previous 4.5/3.75 m dimensions. The §6.5 landing
// room remains wider for turning.
// Mouth > Mid = chambers at the ends with a squeeze between; Mid > Mouth = a bulge. // Mouth > Mid = chambers at the ends with a squeeze between; Mid > Mouth = a bulge.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Width", meta = (ClampMin = "1.0")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Width", meta = (ClampMin = "1.0"))
float MouthRadius = 9.0f; float MouthRadius = 9.0f;
@@ -1912,8 +1908,8 @@ struct VOXELFORGE_API FStratePassageConfig
float DistanceMax = 192.0f; float DistanceMax = 192.0f;
// ----- SHAPE detail ----- // ----- SHAPE detail -----
// Exotic styles only: max sideways excursion from the axis (voxels). 24 = 6 m; 0 = straight // Max sideways variation from the winding path's axis (voxels). Core keeps the route inside
// even in Worm style. The default walkable switchback does not use this wander value. // DistanceMax and adds enough distance to meet the walkable grade.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Shape", meta = (ClampMin = "0.0")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Shape", meta = (ClampMin = "0.0"))
float Wander = 24.0f; float Wander = 24.0f;
@@ -1926,8 +1922,8 @@ struct VOXELFORGE_API FStratePassageConfig
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Shape", meta = (ClampMin = "0.0")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Shape", meta = (ClampMin = "0.0"))
float VerticalWobble = 0.0f; float VerticalWobble = 0.0f;
// Spiral style: helix radius (voxels) and number of full turns over the descent. The default // Spiral style: helix radius (voxels) and minimum number of turns. Core adds turns when
// radius is 6 m. // needed to meet the walkable grade. The default stored radius is 3 m at the legacy scale.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Spiral", meta = (ClampMin = "1.0")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Passage|Spiral", meta = (ClampMin = "1.0"))
float SpiralRadius = 24.0f; float SpiralRadius = 24.0f;
@@ -16204,10 +16204,10 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
} }
VoxelForgeCore::Heightfield2D::resetThreadColumnCacheStats(false,true,0); VoxelForgeCore::Heightfield2D::resetThreadColumnCacheStats(false,true,0);
} }
for (const int32 LOD : {0,1,3,4,5,8}) for (const int32 LOD : {0,1,2,3,4,5,6,7,8})
{ {
TArray<double> FullTimes,CandidateTimes,FullShellTimes,CandidateShellTimes,ListTimes; TArray<double> FullTimes,CandidateTimes,FullShellTimes,CandidateShellTimes,ListTimes;
TArray<double> UnknownBoxes,FieldCalls,ColumnMisses,StratumShellTimes,ConnectorShellTimes; TArray<double> UnknownBoxes,FieldCalls,UnclampedFieldCalls,ColumnMisses,ColumnConflictMisses,StratumShellTimes,ConnectorShellTimes;
TArray<double> DensitySamples,ClassificationTimes,ClassificationExclusiveTimes; TArray<double> DensitySamples,ClassificationTimes,ClassificationExclusiveTimes;
TArray<double> ColumnComputeTimes,MeshingTimes,HorizonTimes,RepairSkipped; TArray<double> ColumnComputeTimes,MeshingTimes,HorizonTimes,RepairSkipped;
TArray<double> ColumnEvalExclusiveTimes,MarchingExclusiveTimes,GroundRefineExclusiveTimes; TArray<double> ColumnEvalExclusiveTimes,MarchingExclusiveTimes,GroundRefineExclusiveTimes;
@@ -16216,13 +16216,29 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
TArray<double> ClassificationNsPerSample,ColumnNsPerSample,MarchingNsPerSample; TArray<double> ClassificationNsPerSample,ColumnNsPerSample,MarchingNsPerSample;
TArray<double> GroundNsPerSample,CapNsPerSample,AssemblyNsPerSample,ListNsPerSample; TArray<double> GroundNsPerSample,CapNsPerSample,AssemblyNsPerSample,ListNsPerSample;
TArray<double> MarchingColumnNsPerSample,GroundColumnNsPerSample,CapColumnNsPerSample; TArray<double> MarchingColumnNsPerSample,GroundColumnNsPerSample,CapColumnNsPerSample;
TArray<double> McProfileTotalTimes,McProfileGridTimes,McProfileGridExclusiveTimes;
TArray<double> McProfileCellTimes,McProfileNormalTimes,McProfileInterpolationTimes;
TArray<double> McProfileStreamTimes,McProfileOtherTimes,McProfileResidualTimes;
TArray<double> McProfileGradientFallbackCalls,McProfileEdgeMidpointCalls,McProfileGradientMemoHits;
TArray<double> McProfileGridNsPerSample,McProfileGridExclusiveNsPerSample;
TArray<double> McProfileCellNsPerSample,McProfileNormalNsPerSample;
TArray<double> McProfileInterpolationNsPerSample,McProfileStreamNsPerSample;
TArray<double> McProfileOtherNsPerSample,McProfileResidualNsPerSample;
TArray<double> StratumFieldCalls,ConnectorFieldCalls,ShellTriangles,GroundTriangles,GroundRemoved,CapTriangles; TArray<double> StratumFieldCalls,ConnectorFieldCalls,ShellTriangles,GroundTriangles,GroundRemoved,CapTriangles;
const bool bMcStageAudit=FParse::Param(FCommandLine::Get(),TEXT("coremcstageaudit"));
int32 AuditDirectMappedColumnCache=0,AuditMemoizeMcGradients=1;
FParse::Value(FCommandLine::Get(),TEXT("voxel.CoreColumnCacheDirectMapped="),
AuditDirectMappedColumnCache);
FParse::Value(FCommandLine::Get(),TEXT("voxel.CoreMCGradientMemoization="),
AuditMemoizeMcGradients);
for (const auto& Key : Keys) for (const auto& Key : Keys)
{ {
if (Key.lod!=LOD || FullTimes.Num()>=8) continue; if (Key.lod!=LOD || FullTimes.Num()>=8) continue;
VoxelForgeCore::TileGenerationOptions Options; VoxelForgeCore::TileGenerationOptions Options;
Options.hashDensity=true; Options.hashDensity=true;
Options.useAssemblyFeatureQueries=false; Options.useAssemblyFeatureQueries=false;
Options.legacyDirectMappedColumnCache=AuditDirectMappedColumnCache!=0;
Options.memoizeMcGradients=AuditMemoizeMcGradients!=0;
std::string Error; std::string Error;
// Check density and mesh parity with hashes, then time uncached runtime generation. // Check density and mesh parity with hashes, then time uncached runtime generation.
// Verifier la parite avec hashes, puis mesurer la generation sans cache de colonnes. // Verifier la parite avec hashes, puis mesurer la generation sans cache de colonnes.
@@ -16256,7 +16272,9 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
DensitySamples.Add(static_cast<double>(Candidate->densitySampleCount)); DensitySamples.Add(static_cast<double>(Candidate->densitySampleCount));
UnknownBoxes.Add(static_cast<double>(Diagnostics.unknownBoxes)); UnknownBoxes.Add(static_cast<double>(Diagnostics.unknownBoxes));
FieldCalls.Add(static_cast<double>(Diagnostics.fieldCalls)); FieldCalls.Add(static_cast<double>(Diagnostics.fieldCalls));
UnclampedFieldCalls.Add(static_cast<double>(Diagnostics.unclampedFieldCalls));
ColumnMisses.Add(static_cast<double>(Diagnostics.columnCacheMisses)); ColumnMisses.Add(static_cast<double>(Diagnostics.columnCacheMisses));
ColumnConflictMisses.Add(static_cast<double>(Diagnostics.columnCacheConflictMisses));
ClassificationTimes.Add(Diagnostics.classificationMilliseconds); ClassificationTimes.Add(Diagnostics.classificationMilliseconds);
ClassificationExclusiveTimes.Add(Diagnostics.classificationExclusiveMilliseconds); ClassificationExclusiveTimes.Add(Diagnostics.classificationExclusiveMilliseconds);
ColumnComputeTimes.Add(Diagnostics.columnComputeMilliseconds); ColumnComputeTimes.Add(Diagnostics.columnComputeMilliseconds);
@@ -16301,13 +16319,66 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
*1000000.0/SampleCount); *1000000.0/SampleCount);
ListNsPerSample.Add(Diagnostics.featureListMilliseconds*1000000.0/SampleCount); ListNsPerSample.Add(Diagnostics.featureListMilliseconds*1000000.0/SampleCount);
} }
if(bMcStageAudit)
{
// Profile a separate cold tile so the audit's ordinary timing rows keep the
// uninstrumented path and comparable clock scope.
// Profiler une tuile froide separee pour garder les mesures ordinaires sans instrumentation.
Options.profileMesherStages=true;
VoxelForgeCore::Heightfield2D::resetThreadColumnCacheStats(false,true);
auto Profiled=World.generateTile(Key,Options,Error);
Options.profileMesherStages=false;
if(!Profiled)
{ OutError=TEXT("Cold MC stage profile tile generation failed."); return false; }
const auto& Mc=Profiled->diagnostics;
const double Total=Mc.marchingCubesExclusiveMilliseconds
+Mc.marchingCubesColumnComputeMilliseconds;
const double Grid=Mc.marchingCubesDensityGridMilliseconds;
const double GridExclusive=FMath::Max(0.0,Grid
-Mc.marchingCubesColumnComputeMilliseconds);
const double Cell=Mc.marchingCubesCellClassificationMilliseconds;
const double Normal=Mc.marchingCubesGradientNormalsMilliseconds;
const double Interpolation=Mc.marchingCubesEdgeInterpolationMilliseconds;
const double Stream=Mc.marchingCubesVertexDedupStreamMilliseconds;
const double Other=Mc.marchingCubesOtherMilliseconds;
const double Residual=FMath::Max(0.0,Mc.marchingCubesExclusiveMilliseconds
-GridExclusive-Cell-Normal-Interpolation-Stream);
McProfileTotalTimes.Add(Total);
McProfileGridTimes.Add(Grid);
McProfileGridExclusiveTimes.Add(GridExclusive);
McProfileCellTimes.Add(Cell);
McProfileNormalTimes.Add(Normal);
McProfileInterpolationTimes.Add(Interpolation);
McProfileStreamTimes.Add(Stream);
McProfileOtherTimes.Add(Other);
McProfileResidualTimes.Add(Residual);
McProfileGradientFallbackCalls.Add(static_cast<double>(
Mc.marchingCubesGradientFallbackDensityCalls));
McProfileEdgeMidpointCalls.Add(static_cast<double>(
Mc.marchingCubesEdgeMidpointDensityCalls));
McProfileGradientMemoHits.Add(static_cast<double>(
Mc.marchingCubesGradientMemoHits));
const double ProfileSamples=static_cast<double>(Profiled->densitySampleCount);
if(ProfileSamples>0.0)
{
McProfileGridNsPerSample.Add(Grid*1000000.0/ProfileSamples);
McProfileGridExclusiveNsPerSample.Add(GridExclusive*1000000.0/ProfileSamples);
McProfileCellNsPerSample.Add(Cell*1000000.0/ProfileSamples);
McProfileNormalNsPerSample.Add(Normal*1000000.0/ProfileSamples);
McProfileInterpolationNsPerSample.Add(Interpolation*1000000.0/ProfileSamples);
McProfileStreamNsPerSample.Add(Stream*1000000.0/ProfileSamples);
McProfileOtherNsPerSample.Add(Other*1000000.0/ProfileSamples);
McProfileResidualNsPerSample.Add(Residual*1000000.0/ProfileSamples);
}
}
} }
const auto P95=[](TArray<double> Values) const auto P95=[](TArray<double> Values)
{ Values.Sort(); return Values.IsEmpty() ? 0.0 : Values[FMath::Clamp( { Values.Sort(); return Values.IsEmpty() ? 0.0 : Values[FMath::Clamp(
FMath::CeilToInt(Values.Num()*0.95f)-1,0,Values.Num()-1)]; }; FMath::CeilToInt(Values.Num()*0.95f)-1,0,Values.Num()-1)]; };
UE_LOG(LogTemp,Display, UE_LOG(LogTemp,Display,
TEXT("[VoxelForgeSharedFeatureCost] label=%s lod=%d tiles=%d hashes_identical=1 full_p95_ms=%.5f candidate_p95_ms=%.5f list_p95_ms=%.5f classification_wall_p95_ms=%.5f classification_exclusive_p95_ms=%.5f column_compute_p95_ms=%.5f column_eval_exclusive_p95_ms=%.5f mc_column_compute_p95_ms=%.5f mc_exclusive_p95_ms=%.5f ground_column_compute_p95_ms=%.5f ground_refine_exclusive_p95_ms=%.5f cap_column_compute_p95_ms=%.5f cap_refine_exclusive_p95_ms=%.5f mesh_assembly_p95_ms=%.5f meshing_p95_ms=%.5f horizon_p95_ms=%.5f samples_p95=%.0f classification_ns_per_sample_p95=%.2f column_ns_per_sample_p95=%.2f mc_column_ns_per_sample_p95=%.2f mc_ns_per_sample_p95=%.2f ground_column_ns_per_sample_p95=%.2f ground_ns_per_sample_p95=%.2f cap_column_ns_per_sample_p95=%.2f cap_ns_per_sample_p95=%.2f assembly_ns_per_sample_p95=%.2f feature_list_ns_per_sample_p95=%.2f full_shell_p95_ms=%.5f candidate_shell_p95_ms=%.5f repair_skipped_p95=%.0f unknown_boxes_p95=%.0f field_calls_p95=%.0f column_misses_p95=%.0f stratum_shell_p95_ms=%.5f stratum_field_calls_p95=%.0f connector_shell_p95_ms=%.5f connector_field_calls_p95=%.0f shell_triangles_p95=%.0f horizon_ground_triangles_p95=%.0f horizon_ground_removed_p95=%.0f horizon_cap_triangles_p95=%.0f"), TEXT("[VoxelForgeSharedFeatureCost] label=%s lod=%d column_cache_direct_mapped=%d gradient_memoization=%d tiles=%d hashes_identical=1 full_p95_ms=%.5f candidate_p95_ms=%.5f list_p95_ms=%.5f classification_wall_p95_ms=%.5f classification_exclusive_p95_ms=%.5f column_compute_p95_ms=%.5f column_eval_exclusive_p95_ms=%.5f mc_column_compute_p95_ms=%.5f mc_exclusive_p95_ms=%.5f ground_column_compute_p95_ms=%.5f ground_refine_exclusive_p95_ms=%.5f cap_column_compute_p95_ms=%.5f cap_refine_exclusive_p95_ms=%.5f mesh_assembly_p95_ms=%.5f meshing_p95_ms=%.5f horizon_p95_ms=%.5f samples_p95=%.0f classification_ns_per_sample_p95=%.2f column_ns_per_sample_p95=%.2f mc_column_ns_per_sample_p95=%.2f mc_ns_per_sample_p95=%.2f ground_column_ns_per_sample_p95=%.2f ground_ns_per_sample_p95=%.2f cap_column_ns_per_sample_p95=%.2f cap_ns_per_sample_p95=%.2f assembly_ns_per_sample_p95=%.2f feature_list_ns_per_sample_p95=%.2f full_shell_p95_ms=%.5f candidate_shell_p95_ms=%.5f repair_skipped_p95=%.0f unknown_boxes_p95=%.0f field_calls_p95=%.0f unclamped_field_calls_p95=%.0f column_misses_p95=%.0f column_conflict_misses_p95=%.0f stratum_shell_p95_ms=%.5f stratum_field_calls_p95=%.0f connector_shell_p95_ms=%.5f connector_field_calls_p95=%.0f shell_triangles_p95=%.0f horizon_ground_triangles_p95=%.0f horizon_ground_removed_p95=%.0f horizon_cap_triangles_p95=%.0f"),
Label,LOD,FullTimes.Num(),P95(FullTimes),P95(CandidateTimes),P95(ListTimes), Label,LOD,AuditDirectMappedColumnCache!=0?1:0,AuditMemoizeMcGradients!=0?1:0,
FullTimes.Num(),P95(FullTimes),P95(CandidateTimes),P95(ListTimes),
P95(ClassificationTimes),P95(ClassificationExclusiveTimes),P95(ColumnComputeTimes), P95(ClassificationTimes),P95(ClassificationExclusiveTimes),P95(ColumnComputeTimes),
P95(ColumnEvalExclusiveTimes),P95(MarchingColumnTimes),P95(MarchingExclusiveTimes), P95(ColumnEvalExclusiveTimes),P95(MarchingColumnTimes),P95(MarchingExclusiveTimes),
P95(GroundColumnTimes),P95(GroundRefineExclusiveTimes),P95(CapColumnTimes), P95(GroundColumnTimes),P95(GroundRefineExclusiveTimes),P95(CapColumnTimes),
@@ -16317,9 +16388,24 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
P95(MarchingNsPerSample),P95(GroundColumnNsPerSample),P95(GroundNsPerSample), P95(MarchingNsPerSample),P95(GroundColumnNsPerSample),P95(GroundNsPerSample),
P95(CapColumnNsPerSample),P95(CapNsPerSample),P95(AssemblyNsPerSample),P95(ListNsPerSample), P95(CapColumnNsPerSample),P95(CapNsPerSample),P95(AssemblyNsPerSample),P95(ListNsPerSample),
P95(FullShellTimes),P95(CandidateShellTimes),P95(RepairSkipped),P95(UnknownBoxes),P95(FieldCalls), P95(FullShellTimes),P95(CandidateShellTimes),P95(RepairSkipped),P95(UnknownBoxes),P95(FieldCalls),
P95(ColumnMisses),P95(StratumShellTimes),P95(StratumFieldCalls), P95(UnclampedFieldCalls),
P95(ColumnMisses),P95(ColumnConflictMisses),P95(StratumShellTimes),P95(StratumFieldCalls),
P95(ConnectorShellTimes),P95(ConnectorFieldCalls),P95(ShellTriangles), P95(ConnectorShellTimes),P95(ConnectorFieldCalls),P95(ShellTriangles),
P95(GroundTriangles),P95(GroundRemoved),P95(CapTriangles)); P95(GroundTriangles),P95(GroundRemoved),P95(CapTriangles));
if(bMcStageAudit)
{
UE_LOG(LogTemp,Display,
TEXT("[VoxelForgeMCStageCost] label=%s lod=%d tiles=%d sampling=row_total_and_1_of_8_cells total_p95_ms=%.5f density_grid_inclusive_p95_ms=%.5f density_grid_ex_column_p95_ms=%.5f cell_classification_p95_ms=%.5f gradient_normals_p95_ms=%.5f edge_interpolation_p95_ms=%.5f vertex_dedup_stream_p95_ms=%.5f setup_finalization_p95_ms=%.5f unassigned_residual_p95_ms=%.5f grid_ns_per_sample_p95=%.2f grid_ex_column_ns_per_sample_p95=%.2f cell_ns_per_sample_p95=%.2f normals_ns_per_sample_p95=%.2f interpolation_ns_per_sample_p95=%.2f dedup_stream_ns_per_sample_p95=%.2f setup_finalization_ns_per_sample_p95=%.2f residual_ns_per_sample_p95=%.2f gradient_fallback_density_calls_p95=%.0f edge_midpoint_density_probes_p95=%.0f gradient_memo_hits_p95=%.0f"),
Label,LOD,McProfileTotalTimes.Num(),P95(McProfileTotalTimes),P95(McProfileGridTimes),
P95(McProfileGridExclusiveTimes),P95(McProfileCellTimes),P95(McProfileNormalTimes),
P95(McProfileInterpolationTimes),P95(McProfileStreamTimes),P95(McProfileOtherTimes),
P95(McProfileResidualTimes),P95(McProfileGridNsPerSample),
P95(McProfileGridExclusiveNsPerSample),P95(McProfileCellNsPerSample),
P95(McProfileNormalNsPerSample),P95(McProfileInterpolationNsPerSample),
P95(McProfileStreamNsPerSample),P95(McProfileOtherNsPerSample),
P95(McProfileResidualNsPerSample),P95(McProfileGradientFallbackCalls),
P95(McProfileEdgeMidpointCalls),P95(McProfileGradientMemoHits));
}
} }
if(Assembly!=nullptr&&!Assembly->plan.strates.empty()) if(Assembly!=nullptr&&!Assembly->plan.strates.empty())
{ {
+129
View File
@@ -0,0 +1,129 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ "${VOXELFORGE_LIMITED_BUILD:-0}" != "1" ]]; then
exec taskset -c 0-11 prlimit --as=6442450944 -- env VOXELFORGE_LIMITED_BUILD=1 "$0" "$@"
fi
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$SCRIPT_DIR"
COMPILER="clang++-19"
VARIANT="clang19"
FP_CONTRACT="off"
JOBS=12
while (($#)); do
case "$1" in
--compiler=*) COMPILER="${1#*=}" ;;
--variant=*) VARIANT="${1#*=}" ;;
--fp-contract=*) FP_CONTRACT="${1#*=}" ;;
--jobs=*) JOBS="${1#*=}" ;;
*) printf 'Unknown build option: %s\n' "$1" >&2; exit 2 ;;
esac
shift
done
if [[ ! "$JOBS" =~ ^[0-9]+$ ]] || ((JOBS < 1 || JOBS > 12)); then
printf 'jobs must be from 1 to 12\n' >&2
exit 2
fi
if [[ "$FP_CONTRACT" != "default" && "$FP_CONTRACT" != "off" && "$FP_CONTRACT" != "on" && "$FP_CONTRACT" != "fast" ]]; then
printf 'fp-contract must be default, off, on, or fast\n' >&2
exit 2
fi
command -v "$COMPILER" >/dev/null || { printf 'Compiler not found: %s\n' "$COMPILER" >&2; exit 2; }
command -v ar >/dev/null || { printf 'ar not found\n' >&2; exit 2; }
command -v pkg-config >/dev/null || { printf 'pkg-config not found\n' >&2; exit 2; }
pkg-config --exists egl glesv2 libpng || { printf 'EGL, GLESv2, and libpng development files are required\n' >&2; exit 2; }
BUILD_ROOT="${VOXELFORGE_BUILD_ROOT:-$ROOT/Build}"
BIN_DIR="${VOXELFORGE_BIN_DIR:-$ROOT/bin/linux}"
BUILD_DIR="$BUILD_ROOT/linux-$VARIANT"
mkdir -p "$BUILD_DIR/wrappers" "$BUILD_DIR/objects" "$BIN_DIR"
INCLUDES=(
"-I$ROOT/Core/include"
"-I$ROOT/Core/src"
"-I$ROOT/Compat"
"-I$ROOT/Source"
"-I$ROOT/Source/VoxelForge/Public"
"-I$ROOT/Source/VoxelForge/Private"
)
FLAGS=(
-std=c++20 -O2 -mavx2 -mfma -fno-fast-math
-fexceptions -pthread "${INCLUDES[@]}"
)
if [[ "$FP_CONTRACT" != "default" ]]; then
FLAGS+=("-ffp-contract=$FP_CONTRACT")
fi
if [[ "$($COMPILER --version | head -n 1)" == *clang* ]]; then
FLAGS+=(-Wno-c++11-narrowing)
else
FLAGS+=(-Wno-narrowing)
fi
CORE_OBJECTS=()
LEGACY_OBJECTS=()
PIDS=()
wait_oldest() {
local pid="${PIDS[0]}"
wait "$pid"
PIDS=("${PIDS[@]:1}")
}
compile_background() {
local source="$1" output="$2"
"$COMPILER" "${FLAGS[@]}" -c "$source" -o "$output" &
PIDS+=("$!")
if ((${#PIDS[@]} >= JOBS)); then wait_oldest; fi
}
while IFS= read -r source_name || [[ -n "$source_name" ]]; do
source_name="${source_name%%#*}"
source_name="${source_name//[[:space:]]/}"
[[ -z "$source_name" ]] && continue
source_path="$ROOT/$source_name"
[[ -f "$source_path" ]] || { printf 'Missing source from core_sources.txt: %s\n' "$source_name" >&2; exit 2; }
if [[ "$source_name" == "Core/src/VoxelForgeCore.cpp" ]]; then
object="$BUILD_DIR/objects/VoxelForgeCore.o"
compile_background "$source_path" "$object"
CORE_OBJECTS+=("$object")
continue
fi
wrapper_name="vfcore_${source_name//[^A-Za-z0-9]/_}"
wrapper="$BUILD_DIR/wrappers/$wrapper_name.cpp"
cat > "$wrapper" <<WRAPPER
#include "CoreNamespacePreamble.h"
namespace vfcore::detail
{
#include "$source_path"
}
WRAPPER
object="$BUILD_DIR/objects/$wrapper_name.o"
compile_background "$wrapper" "$object"
CORE_OBJECTS+=("$object")
# The same copied compatibility implementations are also needed by the standalone owner
# loader/mesher host. They are compiled globally for that reference layer, as in Build.ps1.
legacy_object="$BUILD_DIR/objects/legacy_${wrapper_name}.o"
compile_background "$source_path" "$legacy_object"
LEGACY_OBJECTS+=("$legacy_object")
done < "$ROOT/Core/core_sources.txt"
headless_object="$BUILD_DIR/objects/StreamBenchmarkHeadless.o"
compile_background "$ROOT/Source/StreamBenchmarkHeadless.cpp" "$headless_object"
LEGACY_OBJECTS+=("$headless_object")
for pid in "${PIDS[@]}"; do wait "$pid"; done
PIDS=()
CORE_LIBRARY="$BUILD_DIR/libVoxelForgeCore.a"
"$(command -v ar)" rcs "$CORE_LIBRARY" "${CORE_OBJECTS[@]}"
OUTPUT="$BIN_DIR/VoxelForgeCoreHeadless-$VARIANT"
"$COMPILER" -pthread "${LEGACY_OBJECTS[@]}" "$CORE_LIBRARY" -o "$OUTPUT"
CAPTURE_OUTPUT="$BIN_DIR/VoxelForgeOffscreenCapture-$VARIANT"
"$COMPILER" -std=c++20 -O2 -fno-fast-math -pthread \
"$ROOT/Source/LinuxOffscreenCapture.cpp" -o "$CAPTURE_OUTPUT" \
$(pkg-config --cflags --libs egl glesv2 libpng)
printf 'Built Core library: %s\nBuilt headless benchmark: %s\n' "$CORE_LIBRARY" "$OUTPUT"
printf 'Built EGL offscreen capture: %s\n' "$CAPTURE_OUTPUT"
printf 'Compiler: %s | variant: %s | fp-contract: %s | jobs: %s\n' "$COMPILER" "$VARIANT" "$FP_CONTRACT" "$JOBS"
+1
View File
@@ -10,6 +10,7 @@
#include <chrono> #include <chrono>
#include <charconv> #include <charconv>
#include <cctype> #include <cctype>
#include <cfloat>
#include <cstdarg> #include <cstdarg>
#include <cmath> #include <cmath>
#include <cstdint> #include <cstdint>
@@ -11,6 +11,11 @@ void UVoxelStrateDefinition::PostLoad()
GenerationParams.bTunnelFloorEnabled = true; GenerationParams.bTunnelFloorEnabled = true;
} }
FPrimaryAssetId UVoxelSeasonAsset::GetPrimaryAssetId() const
{
return FPrimaryAssetId(TEXT("VoxelSeason"),GetFName());
}
bool UVoxelSeasonAsset::LoadManifest(FVoxelSeasonManifest& OutManifest, FString& OutReport) const bool UVoxelSeasonAsset::LoadManifest(FVoxelSeasonManifest& OutManifest, FString& OutReport) const
{ {
OutManifest = FVoxelSeasonManifest(); OutManifest = FVoxelSeasonManifest();
+7 -2
View File
@@ -153,8 +153,13 @@ radius range, top flattening, taper, bounded contour warp, roughness, blend, con
route constraints. `PlanFloatingIslandCluster` emits stable island and connector IDs, a connected route constraints. `PlanFloatingIslandCluster` emits stable island and connector IDs, a connected
cluster graph, conservative influence AABBs, and a centerline route. At least the primary chain is cluster graph, conservative influence AABBs, and a centerline route. At least the primary chain is
always planned; `islandDensityQ16` controls up to two optional side sites. Connectors carry a sharp-tag always planned; `islandDensityQ16` controls up to two optional side sites. Connectors carry a sharp-tag
ready bit for a later hybrid-mesher adapter. The schema accepts geometry version 1 and 2. Manifests ready bit for a later hybrid-mesher adapter. The schema accepts geometry versions 1 through 3.
without a geometry version retain version-1 evaluation and canonical hashes. Version 3 keeps the version-2 island form, removes the all-XY lower seal, and obtains its ceiling from
the shared upper-strate boundary seal. The resolved upper bound comes from the strate's own chunk
range; `boundarySealSubvoxels` sets the shared seal thickness and remains a planning margin for island
features. It does not define a FloatingIslands-specific ceiling height. Versions 1 and 2 retain their
recorded two-sided boundary seals. Manifests without a geometry version retain version-1 evaluation
and canonical hashes.
`FloatingIslandFieldV1::densitySubvoxels` evaluates the canonical island and connector field. `FloatingIslandFieldV1::densitySubvoxels` evaluates the canonical island and connector field.
`interval` returns unknown for boxes overlapping any influence AABB and a certified all-air range `interval` returns unknown for boxes overlapping any influence AABB and a certified all-air range
@@ -0,0 +1,183 @@
#pragma once
#include <array>
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <thread>
#include <type_traits>
#include <utility>
namespace VoxelForgeCoreShared
{
// Exact input identity for a pure XY column value. LOD is deliberately not part of this key:
// the same recipe/plan column has the same bits at every sampling step.
struct FColumnCacheKey
{
std::uint64_t recipeIdentity = 0;
std::uint64_t recipeContentHash = 0;
std::uint64_t planIdentity = 0;
std::uint64_t planContentHash = 0;
std::int64_t xSubvoxels = 0;
std::int64_t ySubvoxels = 0;
// Optional exact sub-domain identity for recipes with several independent columns
// at the same XY (for example, a floating-island anchor).
std::uint64_t contextIdentity = 0;
std::array<std::uint64_t, 7> words() const noexcept
{
return {recipeIdentity, recipeContentHash, planIdentity, planContentHash,
static_cast<std::uint64_t>(xSubvoxels), static_cast<std::uint64_t>(ySubvoxels),
contextIdentity};
}
};
// A bounded, world-owned second-level cache. Existing thread-local caches stay first, so
// their ordinary hit path remains private and lock-free. Shared hits read atomic words; only
// a shared miss takes the set spin lock. Entries are four-way set associative, evict on
// collision, and carry pointer identities plus content hashes to reject stale reuse.
// Les caches TLS restent le premier niveau; seul un defaut partage prend le verrou du groupe.
template <typename TValue, std::size_t SetCount, std::size_t Ways = 4>
class TSharedColumnValueCache
{
static_assert(SetCount > 0 && (SetCount & (SetCount - 1)) == 0,
"column cache set count must be a power of two");
static_assert(Ways > 0 && Ways <= 16, "unsupported column cache associativity");
static_assert(std::is_trivially_copyable_v<TValue>,
"shared column values must be trivially copyable");
static constexpr std::size_t ValueWordCount = (sizeof(TValue) + 7) / 8;
using FKeyWords = std::array<std::uint64_t, 7>;
using FValueWords = std::array<std::uint64_t, ValueWordCount>;
struct FEntry
{
std::atomic<std::uint64_t> Version{0};
std::atomic<std::uint64_t> Tag{0};
std::array<std::atomic<std::uint64_t>, 7> Key{};
std::array<std::atomic<std::uint64_t>, ValueWordCount> Value{};
};
struct FSet
{
std::atomic_flag Writer = ATOMIC_FLAG_INIT;
std::uint8_t NextWay = 0;
std::array<FEntry, Ways> Entries{};
};
struct FSpinGuard
{
explicit FSpinGuard(std::atomic_flag& value) : Flag(value)
{
while (Flag.test_and_set(std::memory_order_acquire))
std::this_thread::yield();
}
~FSpinGuard() { Flag.clear(std::memory_order_release); }
std::atomic_flag& Flag;
};
public:
TSharedColumnValueCache() : Sets(std::make_unique<FSet[]>(SetCount)) {}
TSharedColumnValueCache(const TSharedColumnValueCache&) = delete;
TSharedColumnValueCache& operator=(const TSharedColumnValueCache&) = delete;
static TSharedColumnValueCache* setThreadActive(TSharedColumnValueCache* value) noexcept
{
TSharedColumnValueCache* previous = Active;
Active = value;
return previous;
}
static TSharedColumnValueCache* threadActive() noexcept { return Active; }
template <typename TFactory>
TValue getOrCompute(const FColumnCacheKey& key, TFactory&& factory,
bool& computed)
{
computed = false;
const FKeyWords keyWords = key.words();
const std::uint64_t tag = Hash(keyWords);
const std::size_t setIndex = static_cast<std::size_t>(tag) & (SetCount - 1);
FSet& set = Sets[setIndex];
TValue value{};
if (TryReadSet(set, keyWords, tag, value)) return value;
FSpinGuard lock(set.Writer);
if (TryReadSet(set, keyWords, tag, value)) return value;
value = std::forward<TFactory>(factory)();
computed = true;
FValueWords valueWords{};
std::memcpy(valueWords.data(), &value, sizeof(TValue));
std::size_t replacement = Ways;
for (std::size_t way = 0; way < Ways; ++way)
if (set.Entries[way].Version.load(std::memory_order_seq_cst) == 0)
{ replacement = way; break; }
if (replacement == Ways)
{
replacement = set.NextWay;
set.NextWay = static_cast<std::uint8_t>((set.NextWay + 1) % Ways);
}
FEntry& entry = set.Entries[replacement];
std::uint64_t version = entry.Version.load(std::memory_order_seq_cst);
if (version & 1u) ++version;
entry.Version.store(version + 1, std::memory_order_seq_cst);
for (std::size_t word = 0; word < keyWords.size(); ++word)
entry.Key[word].store(keyWords[word], std::memory_order_seq_cst);
for (std::size_t word = 0; word < valueWords.size(); ++word)
entry.Value[word].store(valueWords[word], std::memory_order_seq_cst);
entry.Tag.store(tag, std::memory_order_seq_cst);
entry.Version.store(version + 2, std::memory_order_seq_cst);
return value;
}
private:
static std::uint64_t Hash(const FKeyWords& words) noexcept
{
std::uint64_t hash = 0x9E3779B185EBCA87ull;
for (const std::uint64_t word : words)
{
hash ^= word + 0x9E3779B97F4A7C15ull + (hash << 6) + (hash >> 2);
hash ^= hash >> 30;
hash *= 0xBF58476D1CE4E5B9ull;
hash ^= hash >> 27;
hash *= 0x94D049BB133111EBull;
hash ^= hash >> 31;
}
return hash == 0 ? 1 : hash;
}
static bool TryRead(const FEntry& entry, const FKeyWords& keyWords,
std::uint64_t tag, TValue& out)
{
const std::uint64_t before = entry.Version.load(std::memory_order_seq_cst);
if (before == 0 || (before & 1u)
|| entry.Tag.load(std::memory_order_seq_cst) != tag) return false;
FKeyWords foundKey{};
for (std::size_t word = 0; word < foundKey.size(); ++word)
foundKey[word] = entry.Key[word].load(std::memory_order_seq_cst);
if (foundKey != keyWords) return false;
FValueWords foundValue{};
for (std::size_t word = 0; word < foundValue.size(); ++word)
foundValue[word] = entry.Value[word].load(std::memory_order_seq_cst);
const std::uint64_t after = entry.Version.load(std::memory_order_seq_cst);
if (before != after || (after & 1u)) return false;
std::memcpy(&out, foundValue.data(), sizeof(TValue));
return true;
}
static bool TryReadSet(const FSet& set, const FKeyWords& keyWords,
std::uint64_t tag, TValue& out)
{
for (const FEntry& entry : set.Entries)
if (TryRead(entry, keyWords, tag, out)) return true;
return false;
}
std::unique_ptr<FSet[]> Sets;
inline static thread_local TSharedColumnValueCache* Active = nullptr;
};
}
@@ -0,0 +1,33 @@
#pragma once
// Keep large worker caches out of each thread's eager ELF TLS image. Each handle is itself
// thread-local; its payload is allocated on the first use by that thread and released when the
// thread exits. The payload is never shared and this type has no synchronization.
namespace VoxelForgeCoreThreadLocal
{
template <typename T>
class FLazy
{
public:
FLazy() noexcept = default;
FLazy(const FLazy&) = delete;
FLazy& operator=(const FLazy&) = delete;
~FLazy()
{
delete Value;
}
T& Get()
{
if (Value == nullptr)
{
Value = new T{};
}
return *Value;
}
private:
T* Value = nullptr;
};
}
@@ -110,9 +110,19 @@ namespace VoxelForgeCore
enum class TileClass : std::uint8_t { allSolid, allAir, mixed, unknown }; enum class TileClass : std::uint8_t { allSolid, allAir, mixed, unknown };
struct HeightfieldColumnEvaluation
{
std::int64_t x = 0, y = 0;
std::uint64_t sequence = 0;
bool outsideTileFootprint = false;
};
struct TileGenerationStats struct TileGenerationStats
{ {
TileClass tileClass = TileClass::unknown; TileClass tileClass = TileClass::unknown;
bool nativeOnlyRoute = false;
bool analyticRegionPageRoute = false;
bool nativeSurfaceTile = false;
std::uint64_t solidBoxes = 0; std::uint64_t solidBoxes = 0;
std::uint64_t airBoxes = 0; std::uint64_t airBoxes = 0;
std::uint64_t mixedBoxes = 0; std::uint64_t mixedBoxes = 0;
@@ -123,6 +133,14 @@ namespace VoxelForgeCore
std::uint64_t unclampedFieldCalls = 0; std::uint64_t unclampedFieldCalls = 0;
std::uint64_t columnCacheHits = 0; std::uint64_t columnCacheHits = 0;
std::uint64_t columnCacheMisses = 0; std::uint64_t columnCacheMisses = 0;
std::uint64_t columnCacheConflictMisses = 0;
std::uint64_t sharedColumnCacheHits = 0;
std::uint64_t columnEvaluations = 0;
std::uint64_t uniformBlockProofsChecked = 0;
std::uint64_t uniformBlockProofSamplesChecked = 0;
std::uint64_t uniformBlockProofFallbackBlocks = 0;
std::uint64_t uniformBlockProofUnknownBlocks = 0;
std::uint64_t uniformBlockProofViolations = 0;
double classificationMilliseconds = 0.0; double classificationMilliseconds = 0.0;
double columnComputeMilliseconds = 0.0; double columnComputeMilliseconds = 0.0;
double columnEvaluationExclusiveMilliseconds = 0.0; double columnEvaluationExclusiveMilliseconds = 0.0;
@@ -131,6 +149,16 @@ namespace VoxelForgeCore
double capRefinementColumnComputeMilliseconds = 0.0; double capRefinementColumnComputeMilliseconds = 0.0;
double classificationExclusiveMilliseconds = 0.0; double classificationExclusiveMilliseconds = 0.0;
double marchingCubesExclusiveMilliseconds = 0.0; double marchingCubesExclusiveMilliseconds = 0.0;
double marchingCubesDensityGridMilliseconds = 0.0;
double marchingCubesCellClassificationMilliseconds = 0.0;
double marchingCubesGradientNormalsMilliseconds = 0.0;
double marchingCubesEdgeInterpolationMilliseconds = 0.0;
double marchingCubesVertexDedupStreamMilliseconds = 0.0;
double marchingCubesSkirtMilliseconds = 0.0;
double marchingCubesOtherMilliseconds = 0.0;
std::uint64_t marchingCubesGradientFallbackDensityCalls = 0;
std::uint64_t marchingCubesEdgeMidpointDensityCalls = 0;
std::uint64_t marchingCubesGradientMemoHits = 0;
double groundRefinementExclusiveMilliseconds = 0.0; double groundRefinementExclusiveMilliseconds = 0.0;
double capRefinementExclusiveMilliseconds = 0.0; double capRefinementExclusiveMilliseconds = 0.0;
double meshAssemblyMilliseconds = 0.0; double meshAssemblyMilliseconds = 0.0;
@@ -142,6 +170,20 @@ namespace VoxelForgeCore
double farHorizonMilliseconds = 0.0; double farHorizonMilliseconds = 0.0;
std::uint64_t farStratumFieldCalls = 0; std::uint64_t farStratumFieldCalls = 0;
std::uint64_t farConnectorFieldCalls = 0; std::uint64_t farConnectorFieldCalls = 0;
std::uint64_t farStratumColumnPointCalls = 0;
std::uint64_t farStratumColumnCacheHits = 0;
std::uint64_t farStratumColumnCacheMisses = 0;
std::uint64_t farStratumColumnConflictMisses = 0;
std::uint64_t farStratumSharedColumnCacheHits = 0;
std::uint64_t farStratumColumnEvaluations = 0;
std::uint64_t farConnectorColumnPointCalls = 0;
std::uint64_t farConnectorColumnCacheHits = 0;
std::uint64_t farConnectorColumnCacheMisses = 0;
std::uint64_t farConnectorColumnConflictMisses = 0;
std::uint64_t farConnectorSharedColumnCacheHits = 0;
std::uint64_t farConnectorColumnEvaluations = 0;
double farStratumColumnComputeMilliseconds = 0.0;
double farConnectorColumnComputeMilliseconds = 0.0;
std::uint64_t farShellTrianglesAdded = 0; std::uint64_t farShellTrianglesAdded = 0;
std::uint64_t horizonGroundTriangles = 0; std::uint64_t horizonGroundTriangles = 0;
std::uint64_t horizonGroundTrianglesRemoved = 0; std::uint64_t horizonGroundTrianglesRemoved = 0;
@@ -157,7 +199,7 @@ namespace VoxelForgeCore
bool capRefined = false; bool capRefined = false;
std::uint64_t columnEvaluationWorkerHash = 0; std::uint64_t columnEvaluationWorkerHash = 0;
bool columnCoordinateCaptureComplete = true; bool columnCoordinateCaptureComplete = true;
std::vector<std::array<std::int64_t, 2>> evaluatedColumnCoordinates; std::vector<HeightfieldColumnEvaluation> evaluatedColumnCoordinates;
}; };
struct TileMesh struct TileMesh
@@ -206,8 +248,9 @@ namespace VoxelForgeCore
// This is independent of tile size and is the fixed input scale for Core field blocks. // This is independent of tile size and is the fixed input scale for Core field blocks.
// L'assembleur v1 encode coordonnees et scalaires en 1/256 de voxel, independamment des tuiles. // L'assembleur v1 encode coordonnees et scalaires en 1/256 de voxel, independamment des tuiles.
inline constexpr std::int64_t WorldAssemblySubvoxelsPerVoxel = 256; inline constexpr std::int64_t WorldAssemblySubvoxelsPerVoxel = 256;
inline constexpr std::uint32_t WorldAssemblySchemaVersion = 1; inline constexpr std::uint32_t WorldAssemblySchemaVersion = 2;
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 5; // Version 14 adds shared passage columns for long native open-air crossings.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 14;
enum class FieldChannel : std::uint32_t enum class FieldChannel : std::uint32_t
{ {
@@ -259,6 +302,8 @@ namespace VoxelForgeCore
std::uint32_t schemaVersion = WorldAssemblySchemaVersion; std::uint32_t schemaVersion = WorldAssemblySchemaVersion;
std::uint32_t evaluatorVersion = WorldAssemblyEvaluatorVersion; std::uint32_t evaluatorVersion = WorldAssemblyEvaluatorVersion;
std::uint32_t unitsPerVoxel = static_cast<std::uint32_t>(WorldAssemblySubvoxelsPerVoxel); std::uint32_t unitsPerVoxel = static_cast<std::uint32_t>(WorldAssemblySubvoxelsPerVoxel);
// Resolved physical strate chunk width in 1/256 Core voxel units; tileVoxelCount remains 32.
std::int64_t layoutChunkWidthSubvoxels = 8192;
std::uint32_t seed = 0; std::uint32_t seed = 0;
std::int64_t biomeCellSizeSubvoxels = 256 * 800; std::int64_t biomeCellSizeSubvoxels = 256 * 800;
std::int64_t biomeWarpSubvoxels = 256 * 250; std::int64_t biomeWarpSubvoxels = 256 * 250;
@@ -349,7 +394,12 @@ namespace VoxelForgeCore
std::uint32_t schemaVersion = 1; std::uint32_t schemaVersion = 1;
// Profile 1 preserves the original shallow pads. Profile 2 adds a thick crust, // Profile 1 preserves the original shallow pads. Profile 2 adds a thick crust,
// bounded lobed roots and arched spans without changing the feature-family schema. // bounded lobed roots and arched spans without changing the feature-family schema.
std::uint32_t geometryVersion = 2; // Version 3 keeps the version-2 island shapes, removes the all-XY lower boundary seal,
// and routes its upper seal through the shared strate-boundary primitive. Version 4
// records the director-resolved strate layout width. Version 5 adds one passage-rooted
// island whose root reaches the owned bedrock and whose surface route ends at its mouth.
// New production adapters opt in explicitly; the compatibility default remains version 4.
std::uint32_t geometryVersion = 4;
std::uint32_t unitsPerVoxel = static_cast<std::uint32_t>(WorldAssemblySubvoxelsPerVoxel); std::uint32_t unitsPerVoxel = static_cast<std::uint32_t>(WorldAssemblySubvoxelsPerVoxel);
// Import scale is explicit in microns; the reduced ratio maps owner-authored lengths to Core voxels. // Import scale is explicit in microns; the reduced ratio maps owner-authored lengths to Core voxels.
// L'echelle d'import est explicite en microns; le rapport reduit convertit les longueurs owner. // L'echelle d'import est explicite en microns; le rapport reduit convertit les longueurs owner.
@@ -363,6 +413,9 @@ namespace VoxelForgeCore
std::int64_t layoutCenterTopZSubvoxels = -64 * WorldAssemblySubvoxelsPerVoxel; std::int64_t layoutCenterTopZSubvoxels = -64 * WorldAssemblySubvoxelsPerVoxel;
std::int64_t layoutMinimumZSubvoxels = -128 * WorldAssemblySubvoxelsPerVoxel; std::int64_t layoutMinimumZSubvoxels = -128 * WorldAssemblySubvoxelsPerVoxel;
std::int64_t layoutMaximumZSubvoxels = 0; std::int64_t layoutMaximumZSubvoxels = 0;
// Director-resolved physical strate layout chunk in 1/256 Core voxel units.
// This is independent of the internal 32-voxel Core tile.
std::int64_t layoutChunkWidthSubvoxels = 8192;
std::uint32_t primaryIslandCount = 3; std::uint32_t primaryIslandCount = 3;
std::int64_t islandDensityQ16 = 1ll << 15; std::int64_t islandDensityQ16 = 1ll << 15;
// Legacy owner lengths use ownerVoxelSizeMicrons; the scale ratio converts them to Core voxels. // Legacy owner lengths use ownerVoxelSizeMicrons; the scale ratio converts them to Core voxels.
@@ -383,6 +436,14 @@ namespace VoxelForgeCore
std::int64_t boundarySealSubvoxels = 2 * WorldAssemblySubvoxelsPerVoxel; std::int64_t boundarySealSubvoxels = 2 * WorldAssemblySubvoxelsPerVoxel;
std::int64_t bridgeHalfWidthSubvoxels = 3 * WorldAssemblySubvoxelsPerVoxel; std::int64_t bridgeHalfWidthSubvoxels = 3 * WorldAssemblySubvoxelsPerVoxel;
std::int64_t bridgeThicknessSubvoxels = 4 * WorldAssemblySubvoxelsPerVoxel; std::int64_t bridgeThicknessSubvoxels = 4 * WorldAssemblySubvoxelsPerVoxel;
// Version 5 anchor-island inputs are resolved from that strate's passage config.
// The anchor is the last primary route island and must stay inside the passage disk.
std::uint32_t anchorIslandOrdinal = 2;
std::int64_t anchorPlacementRadiusSubvoxels = 0;
std::int64_t anchorRootRadiusSubvoxels = 0;
std::int64_t anchorIslandMinimumRadiusSubvoxels = 0;
std::int64_t anchorRootBottomZSubvoxels = 0;
std::int64_t anchorMouthOffsetSubvoxels = 0;
WorldAssemblyRouteConstraintsV1 routeConstraints; WorldAssemblyRouteConstraintsV1 routeConstraints;
std::uint64_t contentHash = 0; std::uint64_t contentHash = 0;
}; };
@@ -486,7 +547,8 @@ namespace VoxelForgeCore
std::uint64_t contentHash = 0; std::uint64_t contentHash = 0;
static std::optional<FloatingIslandManifestV1> FromJson( static std::optional<FloatingIslandManifestV1> FromJson(
std::string_view json, std::string& error); std::string_view json, std::string& error,
std::int64_t resolvedLayoutChunkWidthSubvoxels = 0);
bool finalize(std::string& error); bool finalize(std::string& error);
bool validate(std::string& error) const; bool validate(std::string& error) const;
std::string ToJson() const; std::string ToJson() const;
@@ -518,6 +580,169 @@ namespace VoxelForgeCore
std::string ToJson() const; std::string ToJson() const;
}; };
// Read-only, versioned account of the physical layout resolved by the director and the
// Core adapter. Coordinates are half-open micrometre intervals; recipe anchors retain their
// source fixed-point units so this record never rounds the recipe itself.
inline constexpr std::uint32_t ResolvedLayoutSchemaVersionV3 = 3;
enum class ResolvedLayoutValidationModeV3 : std::uint8_t { compatibility, strict };
struct ResolvedLayoutAnchorV2
{
std::string kind;
std::string stableId;
std::string units;
std::vector<std::int64_t> values;
};
struct ResolvedLayoutBandV2
{
std::string kind; // ceiling, content, bedrock
std::int64_t bottomMicrometres = 0;
std::int64_t topMicrometres = 0;
bool presentInCurrentField = false;
bool diggable = true;
bool protectedBand = false;
std::string behaviour;
std::string densitySide;
std::string capPath;
std::int64_t solidDensityQ16 = 1ll << 16;
};
struct ResolvedLayoutStratumV2
{
std::string stableId;
std::int32_t order = 0;
std::int32_t strateIndex = -1;
std::string generatorKind;
std::string recipeId;
std::uint32_t recipeVersion = 0;
std::int64_t interiorBottomMicrometres = 0;
std::int64_t interiorTopMicrometres = 0;
std::uint32_t voxelSizeMicrometres = 0;
std::array<std::int64_t, 3> latticeOriginMicrometres{};
ResolvedLayoutBandV2 ceiling;
ResolvedLayoutBandV2 content;
ResolvedLayoutBandV2 bedrock;
std::string transitionMode; // mode at this strate's lower interface
std::int32_t transitionBlendChunks = 0;
std::int64_t transitionWidthMicrometres = 0;
std::int64_t transitionWarpAmplitudeMicrometres = 0;
std::int64_t transitionInterpenetrationMicrometres = 0;
bool transitionHonouredInCore = false;
bool transitionFallsBackToHard = false;
std::string transitionDispatchPath;
std::string boundDispatchPath;
std::string queryDispatchPath;
std::string managerLookup;
std::int64_t managerChunkWidthMicrometres = 0;
std::int64_t dispatchChunkWidthMicrometres = 0;
std::vector<ResolvedLayoutAnchorV2> anchors;
};
struct ResolvedLayoutIssueV2
{
std::string code;
std::string detail;
};
struct ResolvedLayoutPassagePointV1
{
std::array<std::int64_t, 3> positionSubvoxels{};
std::int64_t radiusSubvoxels = 0;
};
struct ResolvedLayoutPassageV1
{
std::string stableId;
std::int32_t upperStrateIndex = -1;
std::int32_t lowerStrateIndex = -1;
std::int64_t placementRadiusSubvoxels = 0;
std::array<std::int64_t, 3> upperMouthSubvoxels{};
std::array<std::int64_t, 3> lowerMouthSubvoxels{};
std::int64_t mouthRadiusSubvoxels = 0;
std::int64_t midRadiusSubvoxels = 0;
// Derived from the mouth binding; the main descent is monotone through this point.
std::size_t lowerMouthControlIndex = 0;
std::vector<ResolvedLayoutPassagePointV1> controlPoints;
};
struct PassageVoidCrossingAuditV1
{
std::size_t passageIndex = 0;
std::size_t firstSegment = 0;
std::size_t lastSegment = 0;
std::uint64_t unsupportedSamples = 0;
double unsupportedLengthMetres = 0.0;
std::array<double, 4> startPointSubvoxels{};
std::array<double, 4> endPointSubvoxels{};
bool needsColumn = false;
bool connectedAtStart = false;
bool connectedAtEnd = false;
std::array<std::int64_t, 2> columnAxisSubvoxels{};
std::int64_t columnTopZSubvoxels = 0;
std::int64_t columnBottomZSubvoxels = 0;
std::int64_t columnMinimumRadiusSubvoxels = 0;
std::int64_t columnNominalRadiusSubvoxels = 0;
std::int64_t columnMaximumRadiusSubvoxels = 0;
double maximumRouteOffsetMetres = 0.0;
double maximumBoreRadiusMetres = 0.0;
};
struct ResolvedLayoutPassageConfigV1
{
std::int32_t upperStrateIndex = -1;
std::int32_t connections = 1;
// EVoxelPassageStyle numeric values: Straight=0, Worm=1, Spiral=2, Cascading=3.
std::uint32_t style = 1;
std::int64_t mouthRadiusSubvoxels = 0;
std::int64_t midRadiusSubvoxels = 0;
std::int64_t reachMinimumSubvoxels = 0;
std::int64_t reachMaximumSubvoxels = 0;
std::int64_t distanceMinimumSubvoxels = 0;
std::int64_t distanceMaximumSubvoxels = 0;
std::int64_t wanderSubvoxels = 0;
std::uint32_t segments = 20;
std::int64_t verticalWobbleSubvoxels = 0;
std::int64_t spiralRadiusSubvoxels = 0;
std::int64_t spiralTurnsQ16 = 2ll << 16;
std::uint32_t cascadeSteps = 4;
std::int64_t cascadeLedgeSubvoxels = 0;
};
struct VFCORE_API ResolvedLayoutSnapshotV3
{
std::uint32_t schemaVersion = ResolvedLayoutSchemaVersionV3;
std::string worldIdentity;
std::uint32_t ownerVoxelSizeMicrometres = 0;
std::uint32_t coreVoxelSizeMicrometres = 0;
std::uint32_t strateLayoutChunkSizeMicrometres = 8000000;
std::int64_t strateLayoutChunkWidthSubvoxels = 8192;
std::vector<ResolvedLayoutStratumV2> strates;
std::vector<ResolvedLayoutPassageV1> passages;
std::string stableIdentity;
bool finalize(std::string& error);
bool validate(ResolvedLayoutValidationModeV3 mode,
std::vector<ResolvedLayoutIssueV2>& issues,
std::string& error) const;
std::string ToJson() const;
static std::optional<ResolvedLayoutSnapshotV3> FromJson(
std::string_view json, std::string& error);
};
struct ResolvedLayoutValidatorAuditV3
{
std::uint32_t controlsRun = 0;
std::uint32_t controlsRejectedAsExpected = 0;
bool passed = false;
std::vector<ResolvedLayoutIssueV2> failures;
};
VFCORE_API ResolvedLayoutValidatorAuditV3 AuditResolvedLayoutValidatorV3();
VFCORE_API bool PlanResolvedLayoutPassagesV1(
ResolvedLayoutSnapshotV3& layout, std::int32_t seed,
const std::vector<ResolvedLayoutPassageConfigV1>& configs,
std::string& error);
struct FloatingIslandBoundsAuditResult struct FloatingIslandBoundsAuditResult
{ {
std::uint64_t boxesTested = 0; std::uint64_t boxesTested = 0;
@@ -639,10 +864,13 @@ namespace VoxelForgeCore
std::uint64_t pointCalls = 0; std::uint64_t pointCalls = 0;
std::uint64_t columnHits = 0; std::uint64_t columnHits = 0;
std::uint64_t columnMisses = 0; std::uint64_t columnMisses = 0;
std::uint64_t columnConflictMisses = 0;
std::uint64_t sharedColumnHits = 0;
std::uint64_t columnEvaluations = 0;
double columnComputeMilliseconds = 0.0; double columnComputeMilliseconds = 0.0;
bool captureCoordinates = false; bool captureCoordinates = false;
bool coordinateCaptureComplete = true; bool coordinateCaptureComplete = true;
std::vector<std::array<std::int64_t, 2>> evaluatedCoordinates; std::vector<HeightfieldColumnEvaluation> evaluatedCoordinates;
}; };
struct FieldInfluenceBounds struct FieldInfluenceBounds
@@ -693,6 +921,14 @@ namespace VoxelForgeCore
std::int64_t maximumZSubvoxels, std::int32_t stepVoxels) const noexcept; std::int64_t maximumZSubvoxels, std::int32_t stepVoxels) const noexcept;
static void resetThreadColumnCacheStats(bool captureCoordinates = false, static void resetThreadColumnCacheStats(bool captureCoordinates = false,
bool clearCache = false, std::uint32_t octaveDrop = 0) noexcept; bool clearCache = false, std::uint32_t octaveDrop = 0) noexcept;
static void setThreadColumnCaptureBounds(std::int64_t minimumXSubvoxels,
std::int64_t minimumYSubvoxels, std::int64_t maximumXSubvoxels,
std::int64_t maximumYSubvoxels) noexcept;
static void setThreadColumnOctaveDrop(std::uint32_t octaveDrop) noexcept;
static std::uint32_t threadColumnOctaveDrop() noexcept;
static void setThreadColumnInterpolationStrideSubvoxels(std::int64_t stride) noexcept;
static std::int64_t threadColumnInterpolationStrideSubvoxels() noexcept;
static void setThreadColumnCacheLegacyDirectMapped(bool enabled) noexcept;
static const HeightfieldColumnCacheStats& threadColumnCacheStats() noexcept; static const HeightfieldColumnCacheStats& threadColumnCacheStats() noexcept;
FieldInterval interval(std::int64_t minimumXSubvoxels, FieldInterval interval(std::int64_t minimumXSubvoxels,
std::int64_t minimumYSubvoxels, std::int64_t minimumYSubvoxels,
@@ -784,6 +1020,8 @@ namespace VoxelForgeCore
explicit operator bool() const noexcept { return static_cast<bool>(data_); } explicit operator bool() const noexcept { return static_cast<bool>(data_); }
const WorldConfiguration& configuration() const; const WorldConfiguration& configuration() const;
const WorldAssemblyManifest* worldAssembly() const noexcept; const WorldAssemblyManifest* worldAssembly() const noexcept;
const ResolvedLayoutSnapshotV3* resolvedLayout() const noexcept;
ResolvedWorldSnapshot withoutResolvedLayoutPassages() const;
private: private:
struct Data; struct Data;
@@ -1011,6 +1249,9 @@ namespace VoxelForgeCore
std::int32_t bandMaxZVoxel = 2147483647; std::int32_t bandMaxZVoxel = 2147483647;
bool hashDensity = false; bool hashDensity = false;
bool captureDensitySamples = false; bool captureDensitySamples = false;
// Diagnostic only; materialize the full density lattice even when block proofs
// establish that the tile has no surface.
bool forceFullDensityCapture = false;
bool skipUvAndColors = false; bool skipUvAndColors = false;
bool skipUv = false; bool skipUv = false;
bool skipColors = false; bool skipColors = false;
@@ -1021,14 +1262,36 @@ namespace VoxelForgeCore
// Opt-in diagnostic only; records XY columns evaluated by this LOD8 tile. // Opt-in diagnostic only; records XY columns evaluated by this LOD8 tile.
// Diagnostic seulement; enregistre les colonnes XY evaluees par cette tuile LOD8. // Diagnostic seulement; enregistre les colonnes XY evaluees par cette tuile LOD8.
bool captureColumnCoordinates = false; bool captureColumnCoordinates = false;
bool useSharedColumnCache = true;
// Separate cold pass only; samples the MC inner stages without changing output.
// Passe froide separee seulement; mesure les etapes internes MC sans changer la sortie.
bool profileMesherStages = false;
// Diagnostic only; fills and checks every lattice sample in blocks certified uniform.
// Diagnostic seulement; evalue et verifie tous les echantillons des blocs uniformes.
bool auditUniformBlockProofs = false;
// Negative control for the shared XY-column cache; 1 restores the old direct-map indexing.
// Controle negatif du cache XY partage; 1 restaure l'ancien indexage direct.
bool legacyDirectMappedColumnCache = false;
// Diagnostic/performance control; memoizes exact MC lattice gradients at LOD0.
// Controle de mesure/performance; memorise les gradients MC exacts au LOD0.
bool memoizeMcGradients = true;
// LOD8-only planar horizon interior grid; zero follows the MC step, 128 restores S9. // LOD8-only planar horizon interior grid; zero follows the MC step, 128 restores S9.
// Grille interieure LOD8 seulement; zero suit la maille MC, 128 restaure S9. // Grille interieure LOD8 seulement; zero suit la maille MC, 128 restaure S9.
std::int32_t lod8HorizonInteriorStepVoxels = 0; std::int32_t lod8HorizonInteriorStepVoxels = 0;
// Bump when the distant cap representation changes. LOD4-8 mesh hashes are salted; // Bump when shared stratum-boundary caps or the distant horizon representation changes.
// density and LOD0-3 hashes remain unchanged. // LOD4-8 mesh hashes are salted; density and LOD0-3 keep their direct identities.
// Incremente quand le plafond lointain change. Les hashes LOD4-8 incluent cette version; // Incremente quand les plafonds partages ou l'horizon lointain changent.
// densite et hashes LOD0-3 restent inchanges. // Les hashes de maillage LOD4-8 incluent cette version; LOD0-3 gardent leur identite directe.
std::uint32_t farHorizonVersion = 3; std::uint32_t farHorizonVersion = 4;
// Linux research controls for reproducing L5 negative controls. Defaults preserve output.
std::uint32_t diagnosticGlobalOctaveDrop = 0;
std::uint32_t diagnosticCellStride = 1;
std::uint32_t diagnosticColumnInterpolationStride = 1;
// Diagnostic negative control only: deliberately bypass the native-only readiness
// proof and require the sampling guard to reject any shape-dependent tile.
// Controle negatif diagnostique: contourne volontairement la preuve native seule
// et exige que la garde rejette toute tuile dependante de la forme.
bool diagnosticForceNativeOnly = false;
}; };
class VFCORE_API World class VFCORE_API World
@@ -1046,16 +1309,26 @@ namespace VoxelForgeCore
// True only when a fine tile needs a separately compiled region before generation. // True only when a fine tile needs a separately compiled region before generation.
// Vrai seulement si une tuile fine doit attendre la compilation d'une region dediee. // Vrai seulement si une tuile fine doit attendre la compilation d'une region dediee.
bool needsTileRegion(const TileKey& tile) const; bool needsTileRegion(const TileKey& tile) const;
// Conservative precompile proof: true only for a tile that can sample the native
// SurfaceWorld heightfield throughout its padded mesh domain without compiled shape data.
// Preuve prudente avant compilation: vrai seulement si toute la zone maillee avec marge
// utilise le champ SurfaceWorld natif, sans lire la forme compilee.
bool isTileShapeFree(const TileKey& tile) const;
// Compile missing detail regions for entering fine tiles. Generated tile keys map to // Compile missing detail regions for entering fine tiles. Generated tile keys map to
// shared world-coordinate regions. The default analyticOnly path coalesces each entering // bounded, world-aligned pages. The default analyticOnly path builds each page's
// LOD slab, builds its primitives/bins, and evaluates density on demand without // primitives/bins and evaluates density on demand without rasterizing unused lattice
// rasterizing unused lattice volumes. Set false to use fixed absolute packed pages. The // volumes. Set false to use fixed absolute packed pages. The optional count is newly
// optional count is newly covered tile keys; regions stay resident until retainTileRegions. // covered tile keys; regions stay resident until retainTileRegions.
// Compile les regions de detail manquantes. Les tuiles entrantes sont regroupees en pages
// bornees alignees au monde; analyticOnly construit les primitives et bins sans rasteriser
// de volume inutilise. Sinon, utilise les pages compactes fixes; le compteur indique les
// nouvelles tuiles couvertes et retainTileRegions libere les anciennes regions.
bool compileTileRegion(std::span<const TileKey> tiles, std::uint32_t workerLimit, bool compileTileRegion(std::span<const TileKey> tiles, std::uint32_t workerLimit,
const JobScheduler& scheduler, std::string& error, const JobScheduler& scheduler, std::string& error,
std::size_t* outCompiledTiles = nullptr, std::size_t* outCompiledTiles = nullptr,
TileRegionCompileStats* outStats = nullptr, TileRegionCompileStats* outStats = nullptr,
bool analyticOnly = true); bool analyticOnly = true,
bool diagnosticIncludeBaseCoveredTiles = false);
void retainTileRegions(std::span<const TileKey> desiredTiles); void retainTileRegions(std::span<const TileKey> desiredTiles);
void buildFarWorld(); void buildFarWorld();
bool isCompiled() const noexcept; bool isCompiled() const noexcept;
@@ -1063,6 +1336,14 @@ namespace VoxelForgeCore
ShapeBuildStats buildStats() const; ShapeBuildStats buildStats() const;
float densityAt(Vec3d voxelPosition) const; float densityAt(Vec3d voxelPosition) const;
// Audit-only view of density-field columns and short spans supporting passage voids.
std::vector<PassageVoidCrossingAuditV1> passageVoidCrossings() const;
bool isPassageColumnSample(std::size_t passageIndex, std::size_t segmentIndex,
Vec3d voxelPosition) const;
bool isPassageShortSpanSample(std::size_t passageIndex, std::size_t segmentIndex,
Vec3d voxelPosition) const;
// Audit-only selector provenance for the same point evaluator; never used by meshing.
std::string densityDispatchPathAt(Vec3d voxelPosition) const;
// Analytic source distance without the occupancy-preserving near-zero clamp or packed proxy. // Analytic source distance without the occupancy-preserving near-zero clamp or packed proxy.
float unclampedDensityAt(Vec3d voxelPosition) const; float unclampedDensityAt(Vec3d voxelPosition) const;
DetailFieldSample detailSampleAt(Vec3d voxelPosition) const; DetailFieldSample detailSampleAt(Vec3d voxelPosition) const;
@@ -10,6 +10,7 @@
#include <cassert> #include <cassert>
#include <cctype> #include <cctype>
#include <charconv> #include <charconv>
#include <cfloat>
#include <chrono> #include <chrono>
#include <cmath> #include <cmath>
#include <condition_variable> #include <condition_variable>
@@ -53,3 +54,42 @@
// value tree shared lets the viewer resolve its reference world and Core snapshot from one parse. // value tree shared lets the viewer resolve its reference world and Core snapshot from one parse.
#include "Json.h" #include "Json.h"
#include "VoxelForgeCore/VoxelForgeCore.h" #include "VoxelForgeCore/VoxelForgeCore.h"
#include "VoxelForgeCore/ThreadLocalStorage.h"
#include "VoxelForgeCore/SharedColumnCache.h"
// Keep Core's expression-level FMA behavior fixed regardless of the toolchain setting.
// Clang's "fast" mode ignores the pragma, so Core's runtime self-test rejects that build.
#if defined(__clang__)
#pragma clang fp contract(off)
#elif defined(_MSC_VER)
#pragma fp_contract(off)
#elif defined(__GNUC__)
#pragma GCC optimize ("fp-contract=off")
#else
#error "VoxelForge Core requires a compiler-specific FP contraction control"
#endif
namespace vfcore::fp_contract
{
#if defined(_MSC_VER)
#define VFCORE_FP_PROBE_NOINLINE __declspec(noinline)
#else
#define VFCORE_FP_PROBE_NOINLINE __attribute__((noinline))
#endif
[[maybe_unused]] static VFCORE_FP_PROBE_NOINLINE double multiplyAddProbe(
double a, double b, double c) noexcept
{
return a * b + c;
}
[[maybe_unused]] static bool selfTest() noexcept
{
volatile double a = 1.0 + 0x1p-27;
volatile double b = 1.0 - 0x1p-27;
volatile double c = -1.0;
return multiplyAddProbe(a, b, c) == 0.0;
}
#undef VFCORE_FP_PROBE_NOINLINE
}
+340 -8
View File
@@ -817,8 +817,9 @@ inline void AppendFarConnectorShells(const FStandaloneShapeWorld& Shape,const FV
struct FFarMeshColumnIndex struct FFarMeshColumnIndex
{ {
FFarMeshColumnIndex(const FVoxelMeshData& InMesh,const FIntVector& InOrigin,int32 InExtent, FFarMeshColumnIndex(const FVoxelMeshData& InMesh,const FIntVector& InOrigin,int32 InExtent,
int32 InCells,double InStep) int32 InCells,double InStep,double InVoxelSizeCm)
:Mesh(InMesh),Origin(InOrigin),Extent(InExtent),Cells(InCells),Step(InStep), :Mesh(InMesh),Origin(InOrigin),Extent(InExtent),Cells(InCells),Step(InStep),
VoxelSizeCm(InVoxelSizeCm),
ByColumn(static_cast<size_t>(InCells)*InCells) ByColumn(static_cast<size_t>(InCells)*InCells)
{ {
for(int32 Triangle=0;Triangle+2<Mesh.Triangles.Num();Triangle+=3) for(int32 Triangle=0;Triangle+2<Mesh.Triangles.Num();Triangle+=3)
@@ -864,16 +865,98 @@ struct FFarMeshColumnIndex
return Hits; return Hits;
} }
bool HasDownwardHit(double X,double Y,double Z,double Tolerance) const
{
const int32 CX=std::clamp(static_cast<int32>(std::floor((X-Origin.X)/Step)),0,Cells-1);
const int32 CY=std::clamp(static_cast<int32>(std::floor((Y-Origin.Y)/Step)),0,Cells-1);
const auto& Candidates=ByColumn[static_cast<size_t>(CY)*Cells+CX];
for(const int32 Triangle:Candidates)
{
const int32 IA=Mesh.Triangles[Triangle*3],IB=Mesh.Triangles[Triangle*3+1],
IC=Mesh.Triangles[Triangle*3+2];
if(IA<0||IB<0||IC<0||IA>=Mesh.Normals.Num()||IB>=Mesh.Normals.Num()
||IC>=Mesh.Normals.Num())continue;
if(Mesh.Normals[IA].Z+Mesh.Normals[IB].Z+Mesh.Normals[IC].Z>=-1.5)continue;
const double AX=PositionAxis(IA,0),AY=PositionAxis(IA,1),AZ=PositionAxis(IA,2);
const double BX=PositionAxis(IB,0),BY=PositionAxis(IB,1),BZ=PositionAxis(IB,2);
const double CXv=PositionAxis(IC,0),CYv=PositionAxis(IC,1),CZ=PositionAxis(IC,2);
const double Den=(BX-AX)*(CYv-AY)-(BY-AY)*(CXv-AX);
if(std::abs(Den)<1.0e-10)continue;
const double U=((X-AX)*(CYv-AY)-(Y-AY)*(CXv-AX))/Den;
const double V=((BX-AX)*(Y-AY)-(BY-AY)*(X-AX))/Den;
const double W=1.0-U-V;
if(U<-1.0e-7||V<-1.0e-7||W<-1.0e-7)continue;
const double Hit=AZ+U*(BZ-AZ)+V*(CZ-AZ);
if(std::abs(Hit-Z)<=Tolerance)return true;
}
return false;
}
bool HasDownwardCellCoverage(double X0,double Y0,double X1,double Y1,
double Z,double Tolerance) const
{
// Probe the perimeter as well as the interior: sparse interior-only probes can
// incorrectly hide a missing ceiling quad at an MC grid vertex.
// Sonder le perimetre et l'interieur: des sondes seulement interieures peuvent
// masquer un carre de plafond manquant sur un sommet de la grille MC.
constexpr double Samples[5]={0.0,0.25,0.5,0.75,1.0};
for(const double V:Samples)for(const double U:Samples)
{
const double X=X0+(X1-X0)*U;
const double Y=Y0+(Y1-Y0)*V;
if(!HasDownwardHit(X,Y,Z,Tolerance))return false;
}
return true;
}
bool HasUpwardHit(double X,double Y,double Z,double Tolerance) const
{
const int32 CX=std::clamp(static_cast<int32>(std::floor((X-Origin.X)/Step)),0,Cells-1);
const int32 CY=std::clamp(static_cast<int32>(std::floor((Y-Origin.Y)/Step)),0,Cells-1);
const auto& Candidates=ByColumn[static_cast<size_t>(CY)*Cells+CX];
for(const int32 Triangle:Candidates)
{
const int32 IA=Mesh.Triangles[Triangle*3],IB=Mesh.Triangles[Triangle*3+1],
IC=Mesh.Triangles[Triangle*3+2];
if(IA<0||IB<0||IC<0||IA>=Mesh.Normals.Num()||IB>=Mesh.Normals.Num()
||IC>=Mesh.Normals.Num())continue;
if(Mesh.Normals[IA].Z+Mesh.Normals[IB].Z+Mesh.Normals[IC].Z<=1.5)continue;
const double AX=PositionAxis(IA,0),AY=PositionAxis(IA,1),AZ=PositionAxis(IA,2);
const double BX=PositionAxis(IB,0),BY=PositionAxis(IB,1),BZ=PositionAxis(IB,2);
const double CXv=PositionAxis(IC,0),CYv=PositionAxis(IC,1),CZ=PositionAxis(IC,2);
const double Den=(BX-AX)*(CYv-AY)-(BY-AY)*(CXv-AX);
if(std::abs(Den)<1.0e-10)continue;
const double U=((X-AX)*(CYv-AY)-(Y-AY)*(CXv-AX))/Den;
const double V=((BX-AX)*(Y-AY)-(BY-AY)*(X-AX))/Den;
const double W=1.0-U-V;
if(U<-1.0e-7||V<-1.0e-7||W<-1.0e-7)continue;
const double Hit=AZ+U*(BZ-AZ)+V*(CZ-AZ);
if(std::abs(Hit-Z)<=Tolerance)return true;
}
return false;
}
bool HasUpwardCellCoverage(double X0,double Y0,double X1,double Y1,
double Z,double Tolerance) const
{
constexpr double Samples[5]={0.0,0.25,0.5,0.75,1.0};
for(const double V:Samples)for(const double U:Samples)
if(!HasUpwardHit(X0+(X1-X0)*U,Y0+(Y1-Y0)*V,Z,Tolerance))return false;
return true;
}
private: private:
double PositionAxis(int32 Index,int32 Axis) const double PositionAxis(int32 Index,int32 Axis) const
{ {
const FVector& P=Mesh.Vertices[Index]; const FVector& P=Mesh.Vertices[Index];
return (Axis==0?P.X:(Axis==1?P.Y:P.Z))*0.04; const double WorldCentimetres=Axis==0?P.X:(Axis==1?P.Y:P.Z);
return WorldCentimetres/VoxelSizeCm;
} }
const FVoxelMeshData& Mesh; const FVoxelMeshData& Mesh;
FIntVector Origin; FIntVector Origin;
int32 Extent=0,Cells=0; int32 Extent=0,Cells=0;
double Step=1.0; double Step=1.0;
double VoxelSizeCm=25.0;
std::vector<std::vector<int32>> ByColumn; std::vector<std::vector<int32>> ByColumn;
}; };
@@ -974,11 +1057,11 @@ inline void AppendFarStratumShells(const FStandaloneOwnerWorld& World,const FSta
std::vector<FBoundary> Boundaries; std::vector<FBoundary> Boundaries;
for(const FStrateSlot& Slot:Layout) for(const FStrateSlot& Slot:Layout)
{ {
const FStrateGenerationParams Params=World.Manager->GetGenerationParams( FStandaloneShapeWorld::FResolvedStratumBounds Resolved;
FIntVector(0,0,(Slot.TopChunkZ+Slot.BottomChunkZ)/2)); if(!Shape.GetResolvedStratumBounds(Slot,Resolved))continue;
const double HalfWidth=std::max(8.0,static_cast<double>(Params.BoundarySealThickness)+8.0); const double HalfWidth=std::max(8.0,Resolved.SealThickness+8.0);
Boundaries.push_back({static_cast<double>(Slot.BottomChunkZ)*CHUNK_SIZE,HalfWidth}); Boundaries.push_back({Resolved.BottomZ,HalfWidth});
Boundaries.push_back({static_cast<double>(Slot.TopChunkZ+1)*CHUNK_SIZE,HalfWidth}); Boundaries.push_back({Resolved.TopZ,HalfWidth});
} }
std::sort(Boundaries.begin(),Boundaries.end(),[](const FBoundary& A,const FBoundary& B){return A.Z<B.Z;}); std::sort(Boundaries.begin(),Boundaries.end(),[](const FBoundary& A,const FBoundary& B){return A.Z<B.Z;});
Boundaries.erase(std::unique(Boundaries.begin(),Boundaries.end(),[](const FBoundary& A,const FBoundary& B) Boundaries.erase(std::unique(Boundaries.begin(),Boundaries.end(),[](const FBoundary& A,const FBoundary& B)
@@ -996,7 +1079,8 @@ inline void AppendFarStratumShells(const FStandaloneOwnerWorld& World,const FSta
const bool bHasColors=Mesh.Colors.Num()==OldVertexCount; const bool bHasColors=Mesh.Colors.Num()==OldVertexCount;
const FColor Color=bHasColors&&OldVertexCount>0?Mesh.Colors[0]:FColor(160,160,160,255); const FColor Color=bHasColors&&OldVertexCount>0?Mesh.Colors[0]:FColor(160,160,160,255);
const int32 Cells=std::max(1,World.CoarseTileCells); const int32 Cells=std::max(1,World.CoarseTileCells);
FFarMeshColumnIndex MeshIndex(Mesh,Origin,Extent,Cells,Step); FFarMeshColumnIndex MeshIndex(Mesh,Origin,Extent,Cells,Step,
static_cast<double>(World.CoreVoxelSizeMicrons)/10000.0);
std::vector<FVector> NewVertices,NewNormals; std::vector<FVector> NewVertices,NewNormals;
std::vector<FVector2f> NewUVs;std::vector<FColor> NewColors; std::vector<FVector2f> NewUVs;std::vector<FColor> NewColors;
std::vector<int32> NewTriangles; std::vector<int32> NewTriangles;
@@ -1132,3 +1216,251 @@ inline void AppendFarStratumShells(const FStandaloneOwnerWorld& World,const FSta
Mesh.TriangleSkirtFaceMasks=std::move(CombinedFaceMasks); Mesh.TriangleSkirtFaceMasks=std::move(CombinedFaceMasks);
Mesh.NumSurfaceVertices=OldSurfaceVertices+AddedVertices; Mesh.NumSurfaceVertices=OldSurfaceVertices+AddedVertices;
} }
inline void AppendStratumBoundaryCeilings(const FStandaloneOwnerWorld& World,
const FStandaloneShapeWorld& Shape,const FVoxelTileKey& Key,int32 Step,FVoxelMeshData& Mesh)
{
if(Key.Level<0||Step<=0||!World.Manager)return;
const FIntVector Origin=Key.OriginVoxels();
const int32 Extent=Key.ExtentVoxels();
const int32 GridStep=Step;
if(Extent<=0||GridStep<=0||Extent%GridStep!=0)return;
const int32 GridSide=Extent/GridStep+1;
struct FCandidate
{
double FaceZ=0.0;
double Thickness=0.0;
std::vector<uint8> SolidAbove;
};
std::vector<FCandidate> Candidates;
const double CoreMicrons=std::max<std::uint32_t>(1,World.CoreVoxelSizeMicrons);
for(const FStrateSlot& Slot:World.Manager->GetLayout())
{
const auto* Stratum=Shape.FindResolvedLayoutStratum(Slot.StrateIndex);
if(!Stratum||!Stratum->ceiling.presentInCurrentField
||Stratum->ceiling.topMicrometres<=Stratum->ceiling.bottomMicrometres)continue;
FCandidate Candidate;
Candidate.FaceZ=static_cast<double>(Stratum->ceiling.bottomMicrometres)/CoreMicrons;
Candidate.Thickness=static_cast<double>(Stratum->ceiling.topMicrometres
-Stratum->ceiling.bottomMicrometres)/CoreMicrons;
if(Candidate.FaceZ<Origin.Z-1.0e-6||Candidate.FaceZ>Origin.Z+Extent+1.0e-6)continue;
const double Epsilon=std::min(0.5,Candidate.Thickness*0.25);
if(Epsilon<=0.0)continue;
Candidate.SolidAbove.resize(static_cast<std::size_t>(GridSide)*GridSide,0);
bool AnySolidAbove=false;
for(int32 Y=0;Y<GridSide;++Y)for(int32 X=0;X<GridSide;++X)
{
const double WorldX=Origin.X+X*GridStep;
const double WorldY=Origin.Y+Y*GridStep;
const float Above=Shape.DensityAt(static_cast<float>(WorldX),static_cast<float>(WorldY),
static_cast<float>(Candidate.FaceZ+Epsilon));
const bool bSolidAbove=std::isfinite(Above)&&Above<0.0f;
Candidate.SolidAbove[static_cast<std::size_t>(Y*GridSide+X)]=bSolidAbove?1:0;
AnySolidAbove=AnySolidAbove||bSolidAbove;
}
if(AnySolidAbove)Candidates.push_back(std::move(Candidate));
}
if(Candidates.empty())return;
const int32 Cells=std::max(1,World.CoarseTileCells);
FFarMeshColumnIndex MeshIndex(Mesh,Origin,Extent,Cells,Step,
static_cast<double>(World.CoreVoxelSizeMicrons)/10000.0);
const int32 OldVertexCount=Mesh.Vertices.Num();
const int32 OldSurfaceVertices=std::clamp(Mesh.NumSurfaceVertices,0,OldVertexCount);
const bool bHasUVs=Mesh.UVs.Num()==OldVertexCount;
const bool bHasColors=Mesh.Colors.Num()==OldVertexCount;
const FColor Color=bHasColors&&OldVertexCount>0?Mesh.Colors[0]:FColor(160,160,160,255);
const double VoxelSizeCm=static_cast<double>(World.CoreVoxelSizeMicrons)/10000.0;
std::vector<FVector> NewVertices,NewNormals;
std::vector<FVector2f> NewUVs;
std::vector<FColor> NewColors;
std::vector<int32> NewTriangles;
for(const FCandidate& Candidate:Candidates)
{
std::vector<int32> VertexMap(static_cast<std::size_t>(GridSide)*GridSide,INDEX_NONE);
const double CeilingZ=Candidate.FaceZ;
const auto AddVertex=[&](int32 X,int32 Y)
{
const std::size_t GridIndex=static_cast<std::size_t>(Y*GridSide+X);
int32& Mapped=VertexMap[GridIndex];
if(Mapped!=INDEX_NONE)return Mapped;
Mapped=static_cast<int32>(NewVertices.size());
const double WorldX=Origin.X+X*GridStep,WorldY=Origin.Y+Y*GridStep;
NewVertices.emplace_back(WorldX*VoxelSizeCm,WorldY*VoxelSizeCm,CeilingZ*VoxelSizeCm);
NewNormals.emplace_back(0.0,0.0,-1.0);
if(bHasUVs)NewUVs.emplace_back(static_cast<float>(WorldX),static_cast<float>(WorldY));
if(bHasColors)NewColors.push_back(Color);
return Mapped;
};
for(int32 Y=0;Y+1<GridSide;++Y)for(int32 X=0;X+1<GridSide;++X)
{
const std::size_t I00=static_cast<std::size_t>(Y*GridSide+X);
const std::size_t I10=I00+1,I01=I00+GridSide,I11=I01+1;
if(!Candidate.SolidAbove[I00]||!Candidate.SolidAbove[I10]
||!Candidate.SolidAbove[I01]||!Candidate.SolidAbove[I11])continue;
const double CellX0=Origin.X+X*GridStep,CellY0=Origin.Y+Y*GridStep;
const double CellX1=CellX0+GridStep,CellY1=CellY0+GridStep;
// Suppress a coincident plane only when it covers the full cell. A hit at just the
// center of a curved shell triangle is not enough to leave the rest of this cap cell open.
if(MeshIndex.HasDownwardCellCoverage(CellX0,CellY0,CellX1,CellY1,CeilingZ,0.001))continue;
const int32 A=AddVertex(X,Y),B=AddVertex(X+1,Y);
const int32 C=AddVertex(X+1,Y+1),D=AddVertex(X,Y+1);
NewTriangles.insert(NewTriangles.end(),{A,C,B,A,D,C});
}
}
if(NewTriangles.empty())return;
const int32 AddedVertices=static_cast<int32>(NewVertices.size());
auto InsertVertices=[&](auto& Existing,const auto& Added)
{
using TArrayType=std::remove_reference_t<decltype(Existing)>;
TArrayType Combined;Combined.Reserve(Existing.Num()+static_cast<int32>(Added.size()));
for(int32 I=0;I<OldSurfaceVertices;++I)Combined.Add(Existing[I]);
for(const auto& Value:Added)Combined.Add(Value);
for(int32 I=OldSurfaceVertices;I<Existing.Num();++I)Combined.Add(Existing[I]);
Existing=std::move(Combined);
};
InsertVertices(Mesh.Vertices,NewVertices);InsertVertices(Mesh.Normals,NewNormals);
if(bHasUVs)InsertVertices(Mesh.UVs,NewUVs);
if(bHasColors)InsertVertices(Mesh.Colors,NewColors);
for(int32& Index:Mesh.Triangles)if(Index>=OldSurfaceVertices)Index+=AddedVertices;
const int32 CeilingStart=std::max(0,Mesh.Triangles.Num()-Mesh.NumCeilingTriangles*3);
TArray<int32> CombinedTriangles;CombinedTriangles.Reserve(
Mesh.Triangles.Num()+static_cast<int32>(NewTriangles.size()));
for(int32 I=0;I<CeilingStart;++I)CombinedTriangles.Add(Mesh.Triangles[I]);
for(const int32 Index:NewTriangles)CombinedTriangles.Add(OldSurfaceVertices+Index);
for(int32 I=CeilingStart;I<Mesh.Triangles.Num();++I)CombinedTriangles.Add(Mesh.Triangles[I]);
const int32 OldTriangleCount=Mesh.Triangles.Num()/3;
TArray<uint8> ExistingFaceMasks=Mesh.TriangleSkirtFaceMasks;
ExistingFaceMasks.SetNum(OldTriangleCount);
TArray<uint8> CombinedFaceMasks;CombinedFaceMasks.Reserve(
OldTriangleCount+static_cast<int32>(NewTriangles.size()/3));
for(int32 Triangle=0;Triangle<CeilingStart/3;++Triangle)
CombinedFaceMasks.Add(ExistingFaceMasks[Triangle]);
for(std::size_t Triangle=0;Triangle<NewTriangles.size()/3;++Triangle)
CombinedFaceMasks.Add(0);
for(int32 Triangle=CeilingStart/3;Triangle<OldTriangleCount;++Triangle)
CombinedFaceMasks.Add(ExistingFaceMasks[Triangle]);
Mesh.Triangles=std::move(CombinedTriangles);
Mesh.TriangleSkirtFaceMasks=std::move(CombinedFaceMasks);
Mesh.NumSurfaceVertices=OldSurfaceVertices+AddedVertices;
Mesh.NumCeilingTriangles+=static_cast<int32>(NewTriangles.size()/3);
}
// Add the interior-facing top of each bedrock band. The density composition already
// makes this band solid and editable; this planar closure keeps its visible floor
// continuous when a coarse marching-cubes step would otherwise skip a sub-voxel band.
inline void AppendStratumBoundaryFloors(const FStandaloneOwnerWorld& World,
const FStandaloneShapeWorld& Shape,const FVoxelTileKey& Key,int32 Step,FVoxelMeshData& Mesh)
{
if(Key.Level<0||Step<=0||!World.Manager||!Shape.ResolvedLayout)return;
const FIntVector Origin=Key.OriginVoxels();
const int32 Extent=Key.ExtentVoxels();
if(Extent<=0||Extent%Step!=0)return;
const int32 GridSide=Extent/Step+1;
struct FCandidate { double FloorZ=0.0; double Thickness=0.0; };
std::vector<FCandidate> Candidates;
const double CoreMicrons=std::max<std::uint32_t>(1,World.CoreVoxelSizeMicrons);
for(const FStrateSlot& Slot:World.Manager->GetLayout())
{
const auto* Stratum=Shape.FindResolvedLayoutStratum(Slot.StrateIndex);
if(!Stratum||!Stratum->bedrock.presentInCurrentField
||Stratum->bedrock.topMicrometres<=Stratum->bedrock.bottomMicrometres)continue;
const double FloorZ=static_cast<double>(Stratum->bedrock.topMicrometres)/CoreMicrons;
if(FloorZ<Origin.Z-1.0e-6||FloorZ>Origin.Z+Extent+1.0e-6)continue;
Candidates.push_back({FloorZ,static_cast<double>(Stratum->bedrock.topMicrometres
-Stratum->bedrock.bottomMicrometres)/CoreMicrons});
}
if(Candidates.empty())return;
const int32 Cells=std::max(1,World.CoarseTileCells);
FFarMeshColumnIndex MeshIndex(Mesh,Origin,Extent,Cells,Step,
static_cast<double>(World.CoreVoxelSizeMicrons)/10000.0);
const int32 OldVertexCount=Mesh.Vertices.Num();
const int32 OldSurfaceVertices=std::clamp(Mesh.NumSurfaceVertices,0,OldVertexCount);
const bool bHasUVs=Mesh.UVs.Num()==OldVertexCount;
const bool bHasColors=Mesh.Colors.Num()==OldVertexCount;
const FColor Color=bHasColors&&OldVertexCount>0?Mesh.Colors[0]:FColor(160,160,160,255);
const double VoxelSizeCm=static_cast<double>(World.CoreVoxelSizeMicrons)/10000.0;
std::vector<FVector> NewVertices,NewNormals;
std::vector<FVector2f> NewUVs;
std::vector<FColor> NewColors;
std::vector<int32> NewTriangles;
for(const FCandidate& Candidate:Candidates)
{
const double Epsilon=std::min(0.5,Candidate.Thickness*0.25);
if(Epsilon<=0.0)continue;
std::vector<uint8> SolidBelow(static_cast<std::size_t>(GridSide)*GridSide,0);
for(int32 Y=0;Y<GridSide;++Y)for(int32 X=0;X<GridSide;++X)
{
const double WorldX=Origin.X+X*Step,WorldY=Origin.Y+Y*Step;
const float Density=Shape.DensityAt(static_cast<float>(WorldX),static_cast<float>(WorldY),
static_cast<float>(Candidate.FloorZ-Epsilon));
SolidBelow[static_cast<std::size_t>(Y*GridSide+X)]=
std::isfinite(Density)&&Density<0.0f?1:0;
}
std::vector<int32> VertexMap(static_cast<std::size_t>(GridSide)*GridSide,INDEX_NONE);
const auto AddVertex=[&](int32 X,int32 Y)
{
const std::size_t GridIndex=static_cast<std::size_t>(Y*GridSide+X);
int32& Mapped=VertexMap[GridIndex];
if(Mapped!=INDEX_NONE)return Mapped;
Mapped=static_cast<int32>(NewVertices.size());
const double WorldX=Origin.X+X*Step,WorldY=Origin.Y+Y*Step;
NewVertices.emplace_back(WorldX*VoxelSizeCm,WorldY*VoxelSizeCm,
Candidate.FloorZ*VoxelSizeCm);
NewNormals.emplace_back(0.0,0.0,1.0);
if(bHasUVs)NewUVs.emplace_back(static_cast<float>(WorldX),static_cast<float>(WorldY));
if(bHasColors)NewColors.push_back(Color);
return Mapped;
};
for(int32 Y=0;Y+1<GridSide;++Y)for(int32 X=0;X+1<GridSide;++X)
{
const std::size_t I00=static_cast<std::size_t>(Y*GridSide+X);
const std::size_t I10=I00+1,I01=I00+GridSide,I11=I01+1;
if(!SolidBelow[I00]||!SolidBelow[I10]||!SolidBelow[I01]||!SolidBelow[I11])continue;
const double X0=Origin.X+X*Step,Y0=Origin.Y+Y*Step;
const double X1=X0+Step,Y1=Y0+Step;
if(MeshIndex.HasUpwardCellCoverage(X0,Y0,X1,Y1,Candidate.FloorZ,0.001))continue;
const int32 A=AddVertex(X,Y),B=AddVertex(X+1,Y);
const int32 C=AddVertex(X+1,Y+1),D=AddVertex(X,Y+1);
NewTriangles.insert(NewTriangles.end(),{A,B,C,A,C,D});
}
}
if(NewTriangles.empty())return;
const int32 AddedVertices=static_cast<int32>(NewVertices.size());
auto InsertVertices=[&](auto& Existing,const auto& Added)
{
using TArrayType=std::remove_reference_t<decltype(Existing)>;
TArrayType Combined;Combined.Reserve(Existing.Num()+static_cast<int32>(Added.size()));
for(int32 I=0;I<OldSurfaceVertices;++I)Combined.Add(Existing[I]);
for(const auto& Value:Added)Combined.Add(Value);
for(int32 I=OldSurfaceVertices;I<Existing.Num();++I)Combined.Add(Existing[I]);
Existing=std::move(Combined);
};
InsertVertices(Mesh.Vertices,NewVertices);InsertVertices(Mesh.Normals,NewNormals);
if(bHasUVs)InsertVertices(Mesh.UVs,NewUVs);
if(bHasColors)InsertVertices(Mesh.Colors,NewColors);
for(int32& Index:Mesh.Triangles)if(Index>=OldSurfaceVertices)Index+=AddedVertices;
const int32 CeilingStart=std::max(0,Mesh.Triangles.Num()-Mesh.NumCeilingTriangles*3);
TArray<int32> CombinedTriangles;CombinedTriangles.Reserve(
Mesh.Triangles.Num()+static_cast<int32>(NewTriangles.size()));
for(int32 I=0;I<CeilingStart;++I)CombinedTriangles.Add(Mesh.Triangles[I]);
for(const int32 Index:NewTriangles)CombinedTriangles.Add(OldSurfaceVertices+Index);
for(int32 I=CeilingStart;I<Mesh.Triangles.Num();++I)CombinedTriangles.Add(Mesh.Triangles[I]);
const int32 OldTriangleCount=Mesh.Triangles.Num()/3;
TArray<uint8> ExistingFaceMasks=Mesh.TriangleSkirtFaceMasks;
ExistingFaceMasks.SetNum(OldTriangleCount);
TArray<uint8> CombinedFaceMasks;CombinedFaceMasks.Reserve(
OldTriangleCount+static_cast<int32>(NewTriangles.size()/3));
for(int32 Triangle=0;Triangle<CeilingStart/3;++Triangle)
CombinedFaceMasks.Add(ExistingFaceMasks[Triangle]);
for(std::size_t Triangle=0;Triangle<NewTriangles.size()/3;++Triangle)
CombinedFaceMasks.Add(0);
for(int32 Triangle=CeilingStart/3;Triangle<OldTriangleCount;++Triangle)
CombinedFaceMasks.Add(ExistingFaceMasks[Triangle]);
Mesh.Triangles=std::move(CombinedTriangles);
Mesh.TriangleSkirtFaceMasks=std::move(CombinedFaceMasks);
Mesh.NumSurfaceVertices=OldSurfaceVertices+AddedVertices;
}
+236 -51
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "VoxelForgeCore/ThreadLocalStorage.h"
#include "Json.h" #include "Json.h"
#include "VoxelForgeCore/VoxelForgeCore.h" #include "VoxelForgeCore/VoxelForgeCore.h"
@@ -169,6 +170,8 @@ namespace floating_island_detail
HashWord(hash, static_cast<std::uint64_t>(recipe.layoutCenterTopZSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.layoutCenterTopZSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.layoutMinimumZSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.layoutMinimumZSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.layoutMaximumZSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.layoutMaximumZSubvoxels), 8);
if(recipe.geometryVersion>=4)
HashWord(hash,static_cast<std::uint64_t>(recipe.layoutChunkWidthSubvoxels),8);
HashWord(hash, recipe.primaryIslandCount, 4); HashWord(hash, recipe.primaryIslandCount, 4);
HashWord(hash, static_cast<std::uint64_t>(recipe.islandDensityQ16), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.islandDensityQ16), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.spacingSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.spacingSubvoxels), 8);
@@ -185,6 +188,15 @@ namespace floating_island_detail
HashWord(hash, static_cast<std::uint64_t>(recipe.crustDepthBonusQ16), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.crustDepthBonusQ16), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.rootDepthRatioQ16), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.rootDepthRatioQ16), 8);
} }
if (recipe.geometryVersion >= 5)
{
HashWord(hash, recipe.anchorIslandOrdinal, 4);
HashWord(hash, static_cast<std::uint64_t>(recipe.anchorPlacementRadiusSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.anchorRootRadiusSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.anchorIslandMinimumRadiusSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.anchorRootBottomZSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.anchorMouthOffsetSubvoxels), 8);
}
HashWord(hash, static_cast<std::uint64_t>(recipe.blendRadiusSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.blendRadiusSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.contourWarpSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.contourWarpSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.roughnessSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.roughnessSubvoxels), 8);
@@ -244,10 +256,10 @@ namespace floating_island_detail
inline bool ValidateRecipe(const FloatingIslandRecipeV1& recipe, std::string& error) inline bool ValidateRecipe(const FloatingIslandRecipeV1& recipe, std::string& error)
{ {
const std::array<std::int64_t, 25> values = { const std::array<std::int64_t, 32> values = {
recipe.layoutOriginXSubvoxels, recipe.layoutOriginYSubvoxels, recipe.layoutOriginXSubvoxels, recipe.layoutOriginYSubvoxels,
recipe.layoutCenterTopZSubvoxels, recipe.layoutMinimumZSubvoxels, recipe.layoutCenterTopZSubvoxels, recipe.layoutMinimumZSubvoxels,
recipe.layoutMaximumZSubvoxels, recipe.islandDensityQ16, recipe.layoutMaximumZSubvoxels, recipe.layoutChunkWidthSubvoxels, recipe.islandDensityQ16,
recipe.spacingSubvoxels, recipe.minimumRadiusSubvoxels, recipe.spacingSubvoxels, recipe.minimumRadiusSubvoxels,
recipe.maximumRadiusSubvoxels, recipe.thicknessRatioQ16, recipe.maximumRadiusSubvoxels, recipe.thicknessRatioQ16,
recipe.verticalJitterQ16, recipe.topFlattenQ16, recipe.verticalJitterQ16, recipe.topFlattenQ16,
@@ -256,6 +268,10 @@ namespace floating_island_detail
recipe.blendRadiusSubvoxels, recipe.contourWarpSubvoxels, recipe.blendRadiusSubvoxels, recipe.contourWarpSubvoxels,
recipe.roughnessSubvoxels, recipe.boundarySealSubvoxels, recipe.roughnessSubvoxels, recipe.boundarySealSubvoxels,
recipe.bridgeHalfWidthSubvoxels, recipe.bridgeThicknessSubvoxels, recipe.bridgeHalfWidthSubvoxels, recipe.bridgeThicknessSubvoxels,
static_cast<std::int64_t>(recipe.anchorIslandOrdinal),
recipe.anchorPlacementRadiusSubvoxels, recipe.anchorRootRadiusSubvoxels,
recipe.anchorIslandMinimumRadiusSubvoxels, recipe.anchorRootBottomZSubvoxels,
recipe.anchorMouthOffsetSubvoxels,
recipe.routeConstraints.capsuleRadiusSubvoxels, recipe.routeConstraints.capsuleRadiusSubvoxels,
recipe.routeConstraints.capsuleHeightSubvoxels, recipe.routeConstraints.capsuleHeightSubvoxels,
recipe.routeConstraints.maximumGradeQ16}; recipe.routeConstraints.maximumGradeQ16};
@@ -265,7 +281,7 @@ namespace floating_island_detail
? recipe.ownerVoxelSizeMicrons / ScaleGcd : 0; ? recipe.ownerVoxelSizeMicrons / ScaleGcd : 0;
const std::uint32_t ExpectedDenominator = ScaleGcd > 0 const std::uint32_t ExpectedDenominator = ScaleGcd > 0
? recipe.coreVoxelSizeMicrons / ScaleGcd : 0; ? recipe.coreVoxelSizeMicrons / ScaleGcd : 0;
if (recipe.schemaVersion != 1 || (recipe.geometryVersion != 1 && recipe.geometryVersion != 2) if (recipe.schemaVersion != 1 || recipe.geometryVersion < 1 || recipe.geometryVersion > 8
|| (recipe.geometryVersion == 1 || (recipe.geometryVersion == 1
&& (recipe.crustDepthBonusQ16 != 0 || recipe.rootDepthRatioQ16 != 0)) && (recipe.crustDepthBonusQ16 != 0 || recipe.rootDepthRatioQ16 != 0))
|| recipe.unitsPerVoxel != Q || recipe.unitsPerVoxel != Q
@@ -274,6 +290,11 @@ namespace floating_island_detail
|| recipe.ownerToCoreScaleNumerator != ExpectedNumerator || recipe.ownerToCoreScaleNumerator != ExpectedNumerator
|| recipe.ownerToCoreScaleDenominator != ExpectedDenominator || recipe.ownerToCoreScaleDenominator != ExpectedDenominator
|| recipe.primaryIslandCount < 3 || recipe.primaryIslandCount > 9 || recipe.primaryIslandCount < 3 || recipe.primaryIslandCount > 9
|| recipe.layoutChunkWidthSubvoxels <= 0
|| static_cast<long double>(recipe.layoutChunkWidthSubvoxels)*recipe.coreVoxelSizeMicrons
< 250000.0L*Q
|| static_cast<long double>(recipe.layoutChunkWidthSubvoxels)*recipe.coreVoxelSizeMicrons
> 64000000.0L*Q
|| recipe.layoutMaximumZSubvoxels <= recipe.layoutMinimumZSubvoxels || recipe.layoutMaximumZSubvoxels <= recipe.layoutMinimumZSubvoxels
|| recipe.layoutMaximumZSubvoxels - recipe.layoutMinimumZSubvoxels > 2048 * Q || recipe.layoutMaximumZSubvoxels - recipe.layoutMinimumZSubvoxels > 2048 * Q
|| std::any_of(values.begin(), values.end(), [](auto value) { return !ValidScalar(value); })) || std::any_of(values.begin(), values.end(), [](auto value) { return !ValidScalar(value); }))
@@ -315,6 +336,21 @@ namespace floating_island_detail
|| constraints.minimumClearanceSubvoxels < 0 || constraints.minimumClearanceSubvoxels < 0
|| constraints.minimumSupportProbes == 0 || constraints.minimumSupportProbes > 5) || constraints.minimumSupportProbes == 0 || constraints.minimumSupportProbes > 5)
{ error = "floating-island shape or route parameters are outside the supported range"; return false; } { error = "floating-island shape or route parameters are outside the supported range"; return false; }
if (recipe.geometryVersion >= 5
&& (recipe.anchorIslandOrdinal != recipe.primaryIslandCount - 1
|| recipe.anchorPlacementRadiusSubvoxels <= 0
|| recipe.anchorRootRadiusSubvoxels < recipe.anchorMouthOffsetSubvoxels
+ recipe.routeConstraints.capsuleRadiusSubvoxels + Q
|| recipe.anchorIslandMinimumRadiusSubvoxels
< recipe.anchorMouthOffsetSubvoxels
+ recipe.routeConstraints.capsuleRadiusSubvoxels + Q
|| recipe.anchorIslandMinimumRadiusSubvoxels > 64 * Q
|| recipe.anchorRootBottomZSubvoxels < recipe.layoutMinimumZSubvoxels
+ recipe.boundarySealSubvoxels
|| recipe.anchorRootBottomZSubvoxels >= recipe.layoutCenterTopZSubvoxels
|| recipe.anchorMouthOffsetSubvoxels <= 0
|| recipe.anchorMouthOffsetSubvoxels > 64 * Q))
{ error = "floating-island bedrock anchor is outside its passage or rock-thickness bounds"; return false; }
return true; return true;
} }
@@ -424,6 +460,9 @@ namespace floating_island_detail
struct FIslandColumnCacheEntry struct FIslandColumnCacheEntry
{ {
bool bValid=false; bool bValid=false;
const FloatingIslandRecipeV1* RecipeIdentity=nullptr;
const FloatingIslandPlanV1* PlanIdentity=nullptr;
std::uint64_t RecipeContentHash=0,PlanContentHash=0;
std::uint32_t Seed=0; std::uint32_t Seed=0;
std::uint64_t StableId=0; std::uint64_t StableId=0;
std::int64_t SampleX=0,SampleY=0,CenterX=0,CenterY=0,TopZ=0,Radius=0,TopHalf=0; std::int64_t SampleX=0,SampleY=0,CenterX=0,CenterY=0,TopZ=0,Radius=0,TopHalf=0;
@@ -431,9 +470,12 @@ namespace floating_island_detail
double DeltaX=0.0,DeltaY=0.0,Radial=0.0,Angle=0.0,LobePhase=0.0,TopSurface=0.0; double DeltaX=0.0,DeltaY=0.0,Radial=0.0,Angle=0.0,LobePhase=0.0,TopSurface=0.0;
}; };
using FSharedIslandColumnCache =
VoxelForgeCoreShared::TSharedColumnValueCache<FIslandColumnCacheEntry,16384,4>;
inline const FIslandColumnCacheEntry& IslandColumnCache( inline const FIslandColumnCacheEntry& IslandColumnCache(
const FloatingIslandRecipeV1& recipe,const FloatingIslandAnchorV1& island, const FloatingIslandRecipeV1& recipe,const FloatingIslandPlanV1& plan,
double x,double y) const FloatingIslandAnchorV1& island,double x,double y)
{ {
// Density samples arrive on integer Core lattice columns; reuse the exact column metrics // Density samples arrive on integer Core lattice columns; reuse the exact column metrics
// across Z samples without changing the field value or touching shared world state. // across Z samples without changing the field value or touching shared world state.
@@ -441,22 +483,29 @@ namespace floating_island_detail
constexpr std::size_t Ways=4; constexpr std::size_t Ways=4;
constexpr std::size_t SetCount=2048; constexpr std::size_t SetCount=2048;
static_assert((SetCount&(SetCount-1))==0); static_assert((SetCount&(SetCount-1))==0);
static thread_local std::array<FIslandColumnCacheEntry,SetCount*Ways> Cache{}; static thread_local VoxelForgeCoreThreadLocal::FLazy<
std::array<FIslandColumnCacheEntry,SetCount*Ways>> Cache;
auto& cache=Cache.Get();
const std::int64_t SampleX=static_cast<std::int64_t>(x); const std::int64_t SampleX=static_cast<std::int64_t>(x);
const std::int64_t SampleY=static_cast<std::int64_t>(y); const std::int64_t SampleY=static_cast<std::int64_t>(y);
std::uint64_t IndexKey=island.stableId std::uint64_t IndexKey=island.stableId
^(static_cast<std::uint64_t>(SampleX)*0x9e3779b97f4a7c15ull) ^(static_cast<std::uint64_t>(SampleX)*0x9e3779b97f4a7c15ull)
^(static_cast<std::uint64_t>(SampleY)*0xc2b2ae3d27d4eb4full) ^(static_cast<std::uint64_t>(SampleY)*0xc2b2ae3d27d4eb4full)
^(static_cast<std::uint64_t>(recipe.seed)<<23); ^(static_cast<std::uint64_t>(recipe.seed)<<23)
^recipe.contentHash^std::rotl(plan.contentHash,17)
^static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe))
^std::rotl(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),31);
IndexKey^=IndexKey>>33; IndexKey^=IndexKey>>33;
IndexKey*=0xff51afd7ed558ccdull; IndexKey*=0xff51afd7ed558ccdull;
IndexKey^=IndexKey>>33; IndexKey^=IndexKey>>33;
const std::size_t Base=static_cast<std::size_t>(IndexKey&(SetCount-1))*Ways; const std::size_t Base=static_cast<std::size_t>(IndexKey&(SetCount-1))*Ways;
FIslandColumnCacheEntry* Replacement=&Cache[Base+((IndexKey>>11)&(Ways-1))]; FIslandColumnCacheEntry* Replacement=&cache[Base+((IndexKey>>11)&(Ways-1))];
for(std::size_t Way=0;Way<Ways;++Way) for(std::size_t Way=0;Way<Ways;++Way)
{ {
FIslandColumnCacheEntry& Entry=Cache[Base+Way]; FIslandColumnCacheEntry& Entry=cache[Base+Way];
const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed const bool bKeyMatches=Entry.bValid&&Entry.RecipeIdentity==&recipe
&&Entry.PlanIdentity==&plan&&Entry.RecipeContentHash==recipe.contentHash
&&Entry.PlanContentHash==plan.contentHash&&Entry.Seed==recipe.seed
&&Entry.StableId==island.stableId &&Entry.StableId==island.stableId
&&Entry.SampleX==SampleX&&Entry.SampleY==SampleY &&Entry.SampleX==SampleX&&Entry.SampleY==SampleY
&&Entry.CenterX==island.centerSubvoxels[0] &&Entry.CenterX==island.centerSubvoxels[0]
@@ -470,32 +519,53 @@ namespace floating_island_detail
if(!Entry.bValid)Replacement=&Entry; if(!Entry.bValid)Replacement=&Entry;
} }
FIslandColumnCacheEntry& Entry=*Replacement; const auto build=[&]()
Entry.bValid=true; {
Entry.Seed=recipe.seed; FIslandColumnCacheEntry Entry;
Entry.StableId=island.stableId; Entry.bValid=true;
Entry.SampleX=SampleX; Entry.RecipeIdentity=&recipe;
Entry.SampleY=SampleY; Entry.PlanIdentity=&plan;
Entry.CenterX=island.centerSubvoxels[0]; Entry.RecipeContentHash=recipe.contentHash;
Entry.CenterY=island.centerSubvoxels[1]; Entry.PlanContentHash=plan.contentHash;
Entry.TopZ=island.topZSubvoxels; Entry.Seed=recipe.seed;
Entry.Radius=island.radiusSubvoxels; Entry.StableId=island.stableId;
Entry.TopHalf=island.topHalfSubvoxels; Entry.SampleX=SampleX;
Entry.TopFlattenQ16=recipe.topFlattenQ16; Entry.SampleY=SampleY;
Entry.ContourWarp=recipe.contourWarpSubvoxels; Entry.CenterX=island.centerSubvoxels[0];
Entry.DeltaX=x-static_cast<double>(island.centerSubvoxels[0]); Entry.CenterY=island.centerSubvoxels[1];
Entry.DeltaY=y-static_cast<double>(island.centerSubvoxels[1]); Entry.TopZ=island.topZSubvoxels;
Entry.Radial=std::hypot(Entry.DeltaX,Entry.DeltaY); Entry.Radius=island.radiusSubvoxels;
Entry.Angle=std::atan2(Entry.DeltaY,Entry.DeltaX); Entry.TopHalf=island.topHalfSubvoxels;
Entry.LobePhase=LobePhase(recipe,island); Entry.TopFlattenQ16=recipe.topFlattenQ16;
const double EffectiveRadius=std::max(1.0,static_cast<double>(island.radiusSubvoxels) Entry.ContourWarp=recipe.contourWarpSubvoxels;
+LobeOffsetWithPhase(recipe,Entry.Angle,static_cast<double>(island.topZSubvoxels), Entry.DeltaX=x-static_cast<double>(island.centerSubvoxels[0]);
Entry.LobePhase)); Entry.DeltaY=y-static_cast<double>(island.centerSubvoxels[1]);
const double Edge=std::clamp(Entry.Radial/EffectiveRadius,0.0,1.0); Entry.Radial=std::hypot(Entry.DeltaX,Entry.DeltaY);
const double Drop=(1.0-Q16ToDouble(recipe.topFlattenQ16)) Entry.Angle=std::atan2(Entry.DeltaY,Entry.DeltaX);
*static_cast<double>(island.topHalfSubvoxels)*2.0*Edge*Edge; Entry.LobePhase=LobePhase(recipe,island);
Entry.TopSurface=static_cast<double>(island.topZSubvoxels)-Drop; const double EffectiveRadius=std::max(1.0,static_cast<double>(island.radiusSubvoxels)
return Entry; +LobeOffsetWithPhase(recipe,Entry.Angle,static_cast<double>(island.topZSubvoxels),
Entry.LobePhase));
const double Edge=std::clamp(Entry.Radial/EffectiveRadius,0.0,1.0);
const double Drop=(1.0-Q16ToDouble(recipe.topFlattenQ16))
*static_cast<double>(island.topHalfSubvoxels)*2.0*Edge*Edge;
Entry.TopSurface=static_cast<double>(island.topZSubvoxels)-Drop;
return Entry;
};
FIslandColumnCacheEntry Entry{};
if(auto* shared=FSharedIslandColumnCache::threadActive())
{
const VoxelForgeCoreShared::FColumnCacheKey key{
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe)),
recipe.contentHash,
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),
plan.contentHash,SampleX,SampleY,island.stableId};
bool computed=false;
Entry=shared->getOrCompute(key,build,computed);
}
else Entry=build();
*Replacement=Entry;
return *Replacement;
} }
inline std::int64_t ScaledQ16(std::int64_t value, std::int64_t scaleQ16) inline std::int64_t ScaledQ16(std::int64_t value, std::int64_t scaleQ16)
@@ -559,11 +629,13 @@ namespace floating_island_detail
// Mettre en cache les constantes par worker; la cle complete evite tout partage d'etat. // Mettre en cache les constantes par worker; la cle complete evite tout partage d'etat.
constexpr std::size_t CacheSize=1024; constexpr std::size_t CacheSize=1024;
static_assert((CacheSize&(CacheSize-1))==0); static_assert((CacheSize&(CacheSize-1))==0);
static thread_local std::array<FRootLobeCacheEntry,CacheSize> Cache{}; static thread_local VoxelForgeCoreThreadLocal::FLazy<
std::array<FRootLobeCacheEntry,CacheSize>> Cache;
auto& cache=Cache.Get();
const std::uint64_t IndexKey=island.stableId^(island.stableId>>33) const std::uint64_t IndexKey=island.stableId^(island.stableId>>33)
^(static_cast<std::uint64_t>(recipe.seed)<<17) ^(static_cast<std::uint64_t>(recipe.seed)<<17)
^(static_cast<std::uint64_t>(static_cast<std::uint32_t>(rootIndex))*0x9e3779b97f4a7c15ull); ^(static_cast<std::uint64_t>(static_cast<std::uint32_t>(rootIndex))*0x9e3779b97f4a7c15ull);
FRootLobeCacheEntry& Entry=Cache[static_cast<std::size_t>(IndexKey)&(CacheSize-1)]; FRootLobeCacheEntry& Entry=cache[static_cast<std::size_t>(IndexKey)&(CacheSize-1)];
const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed
&&Entry.StableId==island.stableId&&Entry.RootIndex==rootIndex &&Entry.StableId==island.stableId&&Entry.RootIndex==rootIndex
&&Entry.GeometryVersion==recipe.geometryVersion &&Entry.GeometryVersion==recipe.geometryVersion
@@ -636,6 +708,7 @@ namespace floating_island_detail
} }
inline double IslandDensity(const FloatingIslandRecipeV1& recipe, inline double IslandDensity(const FloatingIslandRecipeV1& recipe,
const FloatingIslandPlanV1& plan,
const FloatingIslandAnchorV1& island, const FloatingIslandAnchorV1& island,
double x, double y, double z) double x, double y, double z)
{ {
@@ -660,7 +733,7 @@ namespace floating_island_detail
std::max({z - top, radial - envelope, bottomZ - z}), x, y, z); std::max({z - top, radial - envelope, bottomZ - z}), x, y, z);
} }
const FIslandColumnCacheEntry& Column=IslandColumnCache(recipe,island,x,y); const FIslandColumnCacheEntry& Column=IslandColumnCache(recipe,plan,island,x,y);
const double dx=Column.DeltaX; const double dx=Column.DeltaX;
const double dy=Column.DeltaY; const double dy=Column.DeltaY;
const double radial=Column.Radial; const double radial=Column.Radial;
@@ -680,6 +753,28 @@ namespace floating_island_detail
const double rootBlend = std::clamp(radius * 0.12, 2.0 * Q, 5.0 * Q); const double rootBlend = std::clamp(radius * 0.12, 2.0 * Q, 5.0 * Q);
for (std::int32_t root = 0; root < rootCount; ++root) for (std::int32_t root = 0; root < rootCount; ++root)
sdf = SmoothMin(sdf, RootLobeDensity(recipe, island, root, x, y, z), rootBlend); sdf = SmoothMin(sdf, RootLobeDensity(recipe, island, root, x, y, z), rootBlend);
if (recipe.geometryVersion >= 5 && recipe.geometryVersion < 8
&& island.ordinal == recipe.anchorIslandOrdinal
&& recipe.anchorRootBottomZSubvoxels < island.bottomZSubvoxels)
{
// The central buttress must meet the island crust underside. IslandBottom
// also includes the four shorter root lobes and sits below that surface.
const double rootTop = static_cast<double>(IslandCrustBottom(recipe, island));
const double rootBottom = static_cast<double>(recipe.anchorRootBottomZSubvoxels);
const double depth = std::max(1.0, rootTop - rootBottom);
const double blend = std::clamp(static_cast<double>(recipe.anchorRootRadiusSubvoxels)
* 0.12, 3.0 * Q, 6.0 * Q);
// A slightly flared lower buttress joins the island's own root lobes to bedrock.
// Une base legerement evasee relie les racines de l'ile a la roche de fond.
const double t = std::clamp((rootTop - z) / depth, 0.0, 1.0);
const double rootRadius = static_cast<double>(recipe.anchorRootRadiusSubvoxels)
* (0.92 + 0.08 * SmoothStep(t));
double rootSdf = std::max({Column.Radial - rootRadius,
rootBottom - z, z - rootTop});
rootSdf = ApplySurfaceDetail(recipe, island.stableId ^ 0x414e43484f52524full,
rootSdf, x, y, z, 0.75);
sdf = SmoothMin(sdf, rootSdf, blend);
}
const double topDetailScale = topDistance >= std::max(sideDistance, undersideDistance) const double topDetailScale = topDistance >= std::max(sideDistance, undersideDistance)
|| z >= static_cast<double>(IslandCrustBottom(recipe, island)) + radius * 0.45 || z >= static_cast<double>(IslandCrustBottom(recipe, island)) + radius * 0.45
? 0.25 : 1.0; ? 0.25 : 1.0;
@@ -728,7 +823,7 @@ namespace floating_island_detail
double result = static_cast<double>(MaxDensity); double result = static_cast<double>(MaxDensity);
for (const auto& island : plan.islands) for (const auto& island : plan.islands)
{ {
double group = IslandDensity(recipe, island, double group = IslandDensity(recipe, plan, island,
static_cast<double>(x), static_cast<double>(y), static_cast<double>(z)); static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
for (const auto& edge : plan.clusterEdges) for (const auto& edge : plan.clusterEdges)
{ {
@@ -764,7 +859,7 @@ namespace floating_island_detail
const auto evaluateLocalGroup = [&](std::size_t islandIndex) const auto evaluateLocalGroup = [&](std::size_t islandIndex)
{ {
const auto& island = plan.islands[islandIndex]; const auto& island = plan.islands[islandIndex];
double group = IslandDensity(recipe, island, double group = IslandDensity(recipe, plan, island,
static_cast<double>(x), static_cast<double>(y), static_cast<double>(z)); static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
for (const std::uint32_t edgeIndex : featureIndices) for (const std::uint32_t edgeIndex : featureIndices)
{ {
@@ -790,7 +885,7 @@ namespace floating_island_detail
const auto evaluateDistantGroup = [&](std::size_t islandIndex) const auto evaluateDistantGroup = [&](std::size_t islandIndex)
{ {
const auto& island = plan.islands[islandIndex]; const auto& island = plan.islands[islandIndex];
double group = IslandDensity(recipe, island, double group = IslandDensity(recipe, plan, island,
static_cast<double>(x), static_cast<double>(y), static_cast<double>(z)); static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
for (const auto& edge : plan.clusterEdges) for (const auto& edge : plan.clusterEdges)
{ {
@@ -850,9 +945,15 @@ namespace floating_island_detail
FloatingIslandAnchorV1& island) FloatingIslandAnchorV1& island)
{ {
const std::int64_t pad = IslandBlendMargin(recipe) + recipe.roughnessSubvoxels; const std::int64_t pad = IslandBlendMargin(recipe) + recipe.roughnessSubvoxels;
const std::int64_t reach = island.radiusSubvoxels + recipe.contourWarpSubvoxels + pad; const bool isAnchorRoot=recipe.geometryVersion>=5&&recipe.geometryVersion<8
&&island.ordinal==recipe.anchorIslandOrdinal;
const std::int64_t reach = std::max(island.radiusSubvoxels,
isAnchorRoot?recipe.anchorRootRadiusSubvoxels:std::int64_t{0})
+ recipe.contourWarpSubvoxels + pad;
island.influenceMinimumSubvoxels = {island.centerSubvoxels[0] - reach, island.influenceMinimumSubvoxels = {island.centerSubvoxels[0] - reach,
island.centerSubvoxels[1] - reach, island.bottomZSubvoxels - pad}; island.centerSubvoxels[1] - reach,
(isAnchorRoot?std::min(island.bottomZSubvoxels,recipe.anchorRootBottomZSubvoxels)
:island.bottomZSubvoxels)-pad};
island.influenceMaximumSubvoxels = {island.centerSubvoxels[0] + reach, island.influenceMaximumSubvoxels = {island.centerSubvoxels[0] + reach,
island.centerSubvoxels[1] + reach, island.topZSubvoxels + pad}; island.centerSubvoxels[1] + reach, island.topZSubvoxels + pad};
} }
@@ -897,12 +998,19 @@ namespace floating_island_detail
std::unordered_set<std::uint64_t> islandIds; std::unordered_set<std::uint64_t> islandIds;
std::unordered_set<std::uint32_t> ordinals; std::unordered_set<std::uint32_t> ordinals;
const FloatingIslandAnchorV1* anchorIsland = nullptr;
for (const auto& island : plan.islands) for (const auto& island : plan.islands)
{ {
const bool isAnchor=recipe.geometryVersion>=5
&&island.ordinal==recipe.anchorIslandOrdinal;
if(isAnchor)anchorIsland=&island;
if (island.stableId == 0 || !islandIds.insert(island.stableId).second if (island.stableId == 0 || !islandIds.insert(island.stableId).second
|| !ordinals.insert(island.ordinal).second || !ordinals.insert(island.ordinal).second
|| island.radiusSubvoxels < recipe.minimumRadiusSubvoxels || island.radiusSubvoxels < (isAnchor?recipe.anchorIslandMinimumRadiusSubvoxels
|| island.radiusSubvoxels > recipe.maximumRadiusSubvoxels :recipe.minimumRadiusSubvoxels)
|| island.radiusSubvoxels > (isAnchor
?std::max(recipe.anchorIslandMinimumRadiusSubvoxels,recipe.maximumRadiusSubvoxels)
:recipe.maximumRadiusSubvoxels)
|| island.topHalfSubvoxels <= 0 || island.topZSubvoxels <= island.bottomZSubvoxels || island.topHalfSubvoxels <= 0 || island.topZSubvoxels <= island.bottomZSubvoxels
|| island.taperEndQ16 < recipe.taperEndMinimumQ16 || island.taperEndQ16 < recipe.taperEndMinimumQ16
|| island.taperEndQ16 > recipe.taperEndMaximumQ16 || island.taperEndQ16 > recipe.taperEndMaximumQ16
@@ -919,12 +1027,17 @@ namespace floating_island_detail
{ error = "floating-island anchor has invalid coordinates or an inverted bound"; return false; } { error = "floating-island anchor has invalid coordinates or an inverted bound"; return false; }
} }
const std::int64_t pad = IslandBlendMargin(recipe) + recipe.roughnessSubvoxels; const std::int64_t pad = IslandBlendMargin(recipe) + recipe.roughnessSubvoxels;
const std::int64_t reach = island.radiusSubvoxels + recipe.contourWarpSubvoxels + pad; const bool hasAnchorRoot=recipe.geometryVersion>=5&&recipe.geometryVersion<8&&isAnchor;
const std::int64_t reach = std::max(island.radiusSubvoxels,
hasAnchorRoot?recipe.anchorRootRadiusSubvoxels:std::int64_t{0})
+ recipe.contourWarpSubvoxels + pad;
if (island.influenceMinimumSubvoxels[0] > island.centerSubvoxels[0] - reach if (island.influenceMinimumSubvoxels[0] > island.centerSubvoxels[0] - reach
|| island.influenceMaximumSubvoxels[0] < island.centerSubvoxels[0] + reach || island.influenceMaximumSubvoxels[0] < island.centerSubvoxels[0] + reach
|| island.influenceMinimumSubvoxels[1] > island.centerSubvoxels[1] - reach || island.influenceMinimumSubvoxels[1] > island.centerSubvoxels[1] - reach
|| island.influenceMaximumSubvoxels[1] < island.centerSubvoxels[1] + reach || island.influenceMaximumSubvoxels[1] < island.centerSubvoxels[1] + reach
|| island.influenceMinimumSubvoxels[2] > island.bottomZSubvoxels - pad || island.influenceMinimumSubvoxels[2] > (hasAnchorRoot
?std::min(island.bottomZSubvoxels,recipe.anchorRootBottomZSubvoxels)
:island.bottomZSubvoxels) - pad
|| island.influenceMaximumSubvoxels[2] < island.topZSubvoxels + pad || island.influenceMaximumSubvoxels[2] < island.topZSubvoxels + pad
|| island.bottomZSubvoxels < recipe.layoutMinimumZSubvoxels + recipe.boundarySealSubvoxels || island.bottomZSubvoxels < recipe.layoutMinimumZSubvoxels + recipe.boundarySealSubvoxels
|| island.topZSubvoxels > recipe.layoutMaximumZSubvoxels - recipe.boundarySealSubvoxels) || island.topZSubvoxels > recipe.layoutMaximumZSubvoxels - recipe.boundarySealSubvoxels)
@@ -933,6 +1046,19 @@ namespace floating_island_detail
for (std::uint32_t ordinal = 0; ordinal < recipe.primaryIslandCount; ++ordinal) for (std::uint32_t ordinal = 0; ordinal < recipe.primaryIslandCount; ++ordinal)
if (!ordinals.contains(ordinal)) if (!ordinals.contains(ordinal))
{ error = "floating-island route chain is missing a primary seeded anchor"; return false; } { error = "floating-island route chain is missing a primary seeded anchor"; return false; }
if(recipe.geometryVersion>=5)
{
if(!anchorIsland)
{error="floating-island plan is missing its unique passage anchor island";return false;}
const double anchorDistance=std::hypot(
static_cast<double>(anchorIsland->centerSubvoxels[0]),
static_cast<double>(anchorIsland->centerSubvoxels[1]));
if(anchorDistance>recipe.anchorPlacementRadiusSubvoxels
||recipe.anchorRootBottomZSubvoxels>=anchorIsland->bottomZSubvoxels
||recipe.anchorMouthOffsetSubvoxels+recipe.routeConstraints.capsuleRadiusSubvoxels
>=anchorIsland->radiusSubvoxels)
{error="floating-island anchor island or its mouth leaves the passage radius or rock envelope";return false;}
}
std::unordered_set<std::uint64_t> edgeIds; std::unordered_set<std::uint64_t> edgeIds;
std::unordered_map<std::uint64_t, std::vector<std::uint64_t>> adjacency; std::unordered_map<std::uint64_t, std::vector<std::uint64_t>> adjacency;
@@ -1158,7 +1284,8 @@ namespace floating_island_detail
} }
std::optional<FloatingIslandManifestV1> FloatingIslandManifestV1::FromJson( std::optional<FloatingIslandManifestV1> FloatingIslandManifestV1::FromJson(
std::string_view json, std::string& error) std::string_view json, std::string& error,
std::int64_t resolvedLayoutChunkWidthSubvoxels)
{ {
VFJson::Value root; VFJson::Value root;
if (!VFJson::Parser(std::string(json)).Parse(root, error)) return std::nullopt; if (!VFJson::Parser(std::string(json)).Parse(root, error)) return std::nullopt;
@@ -1184,6 +1311,31 @@ std::optional<FloatingIslandManifestV1> FloatingIslandManifestV1::FromJson(
manifest.recipe.crustDepthBonusQ16 = 0; manifest.recipe.crustDepthBonusQ16 = 0;
manifest.recipe.rootDepthRatioQ16 = 0; manifest.recipe.rootDepthRatioQ16 = 0;
} }
if(manifest.recipe.geometryVersion>=4)
{
if(!floating_island_detail::ReadInteger(recipeValue.Get("layout_chunk_width_q"),
manifest.recipe.layoutChunkWidthSubvoxels))
{error="floating-island recipe is missing its resolved layout chunk width";return std::nullopt;}
if(resolvedLayoutChunkWidthSubvoxels>0
&& manifest.recipe.layoutChunkWidthSubvoxels!=resolvedLayoutChunkWidthSubvoxels)
{error="floating-island recipe layout width disagrees with the resolved world layout";return std::nullopt;}
}
if(manifest.recipe.geometryVersion>=5)
{
if(!floating_island_detail::ReadU32(recipeValue.Get("anchor_island_ordinal"),
manifest.recipe.anchorIslandOrdinal)
||!floating_island_detail::ReadInteger(recipeValue.Get("anchor_placement_radius_q"),
manifest.recipe.anchorPlacementRadiusSubvoxels)
||!floating_island_detail::ReadInteger(recipeValue.Get("anchor_root_radius_q"),
manifest.recipe.anchorRootRadiusSubvoxels)
||!floating_island_detail::ReadInteger(recipeValue.Get("anchor_island_minimum_radius_q"),
manifest.recipe.anchorIslandMinimumRadiusSubvoxels)
||!floating_island_detail::ReadInteger(recipeValue.Get("anchor_root_bottom_z_q"),
manifest.recipe.anchorRootBottomZSubvoxels)
||!floating_island_detail::ReadInteger(recipeValue.Get("anchor_mouth_offset_q"),
manifest.recipe.anchorMouthOffsetSubvoxels))
{error="floating-island geometry version 7 is missing a passage-rooted anchor field";return std::nullopt;}
}
if (!floating_island_detail::ReadU32(root.Get("schema_version"), schema) if (!floating_island_detail::ReadU32(root.Get("schema_version"), schema)
|| !floating_island_detail::ReadHash(root.Get("content_hash"), manifestHash) || !floating_island_detail::ReadHash(root.Get("content_hash"), manifestHash)
|| !floating_island_detail::ReadU32(recipeValue.Get("schema_version"), manifest.recipe.schemaVersion) || !floating_island_detail::ReadU32(recipeValue.Get("schema_version"), manifest.recipe.schemaVersion)
@@ -1219,6 +1371,10 @@ std::optional<FloatingIslandManifestV1> FloatingIslandManifestV1::FromJson(
|| !floating_island_detail::ReadHash(planValue.Get("content_hash"), planHash) || !floating_island_detail::ReadHash(planValue.Get("content_hash"), planHash)
|| schema != 1) || schema != 1)
{ error = "floating-island manifest is missing a required versioned recipe or plan field"; return std::nullopt; } { error = "floating-island manifest is missing a required versioned recipe or plan field"; return std::nullopt; }
if(manifest.recipe.geometryVersion<4 && resolvedLayoutChunkWidthSubvoxels>0)
manifest.recipe.layoutChunkWidthSubvoxels=resolvedLayoutChunkWidthSubvoxels;
else if(manifest.recipe.geometryVersion<4)
{ error="legacy floating-island manifest requires the world's resolved layout chunk width"; return std::nullopt; }
manifest.recipe.contentHash = recipeHash; manifest.recipe.contentHash = recipeHash;
manifest.contentHash = manifestHash; manifest.contentHash = manifestHash;
manifest.plan.contentHash = planHash; manifest.plan.contentHash = planHash;
@@ -1330,6 +1486,15 @@ std::string FloatingIslandManifestV1::ToJson() const
out << ",\"geometry_version\":" << recipe.geometryVersion out << ",\"geometry_version\":" << recipe.geometryVersion
<< ",\"crust_depth_bonus_q16\":" << recipe.crustDepthBonusQ16 << ",\"crust_depth_bonus_q16\":" << recipe.crustDepthBonusQ16
<< ",\"root_depth_ratio_q16\":" << recipe.rootDepthRatioQ16; << ",\"root_depth_ratio_q16\":" << recipe.rootDepthRatioQ16;
if(recipe.geometryVersion>=4)
out << ",\"layout_chunk_width_q\":" << recipe.layoutChunkWidthSubvoxels;
if(recipe.geometryVersion>=5)
out << ",\"anchor_island_ordinal\":" << recipe.anchorIslandOrdinal
<< ",\"anchor_placement_radius_q\":" << recipe.anchorPlacementRadiusSubvoxels
<< ",\"anchor_root_radius_q\":" << recipe.anchorRootRadiusSubvoxels
<< ",\"anchor_island_minimum_radius_q\":" << recipe.anchorIslandMinimumRadiusSubvoxels
<< ",\"anchor_root_bottom_z_q\":" << recipe.anchorRootBottomZSubvoxels
<< ",\"anchor_mouth_offset_q\":" << recipe.anchorMouthOffsetSubvoxels;
out << ",\"blend_radius_q\":" << recipe.blendRadiusSubvoxels out << ",\"blend_radius_q\":" << recipe.blendRadiusSubvoxels
<< ",\"contour_warp_q\":" << recipe.contourWarpSubvoxels << ",\"contour_warp_q\":" << recipe.contourWarpSubvoxels
<< ",\"roughness_q\":" << recipe.roughnessSubvoxels << ",\"roughness_q\":" << recipe.roughnessSubvoxels
@@ -1491,6 +1656,9 @@ std::optional<FloatingIslandManifestV1> PlanFloatingIslandCluster(
auto island = floating_island_detail::MakeIsland(recipe, i, auto island = floating_island_detail::MakeIsland(recipe, i,
primaryXY[i][0], primaryXY[i][1], tops[i], site); primaryXY[i][0], primaryXY[i][1], tops[i], site);
island.radiusSubvoxels = radii[i]; island.radiusSubvoxels = radii[i];
if(recipe.geometryVersion>=5&&i==recipe.anchorIslandOrdinal)
island.radiusSubvoxels=std::max(island.radiusSubvoxels,
recipe.anchorIslandMinimumRadiusSubvoxels);
island.topHalfSubvoxels = std::max<std::int64_t>(1, island.radiusSubvoxels / 5); island.topHalfSubvoxels = std::max<std::int64_t>(1, island.radiusSubvoxels / 5);
island.centerSubvoxels[2] = island.topZSubvoxels - island.topHalfSubvoxels; island.centerSubvoxels[2] = island.topZSubvoxels - island.topHalfSubvoxels;
island.bottomZSubvoxels = floating_island_detail::IslandBottom(recipe, island.bottomZSubvoxels = floating_island_detail::IslandBottom(recipe,
@@ -1577,14 +1745,31 @@ std::optional<FloatingIslandManifestV1> PlanFloatingIslandCluster(
static_cast<double>(a.centerSubvoxels[0]) + dx * t); static_cast<double>(a.centerSubvoxels[0]) + dx * t);
const std::int64_t y = floating_island_detail::RoundQ( const std::int64_t y = floating_island_detail::RoundQ(
static_cast<double>(a.centerSubvoxels[1]) + dy * t); static_cast<double>(a.centerSubvoxels[1]) + dy * t);
std::int64_t routeX=x,routeY=y;
if(recipe.geometryVersion>=5&&segment+2==count&&piece==pieces)
{
const auto& anchor=islands[recipe.anchorIslandOrdinal];
const std::uint32_t side=static_cast<std::uint32_t>(
floating_island_detail::UnitQ16(recipe.seed,anchor.stableId,
0x414e43484f524d50ull)&1u);
const double routeAngle=std::atan2(dy,dx);
const double angle=routeAngle+(side?1.0:-1.0)
*floating_island_detail::Pi/2.0;
const double mouthX=static_cast<double>(anchor.centerSubvoxels[0])
+static_cast<double>(recipe.anchorMouthOffsetSubvoxels)*std::cos(angle);
const double mouthY=static_cast<double>(anchor.centerSubvoxels[1])
+static_cast<double>(recipe.anchorMouthOffsetSubvoxels)*std::sin(angle);
routeX=floating_island_detail::RoundQ(mouthX);
routeY=floating_island_detail::RoundQ(mouthY);
}
const auto surface = floating_island_detail::FindCapsuleFootingTopZ( const auto surface = floating_island_detail::FindCapsuleFootingTopZ(
recipe, manifest.plan, x, y); recipe, manifest.plan, routeX, routeY);
if (!surface) if (!surface)
{ error = "island planner could not find a full capsule-width support surface along its connector chain"; return std::nullopt; } { error = "island planner could not find a full capsule-width support surface along its connector chain"; return std::nullopt; }
WorldAssemblyRoutePointV1 point; WorldAssemblyRoutePointV1 point;
point.stableFeatureId = floating_island_detail::StableId(recipe.seed, point.stableFeatureId = floating_island_detail::StableId(recipe.seed,
0x500000000ull + routeOrdinal, 0x524f555445ull); 0x500000000ull + routeOrdinal, 0x524f555445ull);
point.positionSubvoxels = {x, y, *surface + capsuleHalf point.positionSubvoxels = {routeX, routeY, *surface + capsuleHalf
+ recipe.routeConstraints.minimumClearanceSubvoxels + recipe.routeConstraints.minimumClearanceSubvoxels
+ (recipe.geometryVersion >= 2 ? floating_island_detail::Q / 8 : 0)}; + (recipe.geometryVersion >= 2 ? floating_island_detail::Q / 8 : 0)};
point.radiusSubvoxels = routeRadius; point.radiusSubvoxels = routeRadius;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+214 -46
View File
@@ -1,9 +1,11 @@
#pragma once #pragma once
#include "VoxelForgeCore/ThreadLocalStorage.h"
#include "Json.h" #include "Json.h"
#include "VoxelForgeCore/VoxelForgeCore.h" #include "VoxelForgeCore/VoxelForgeCore.h"
#include <algorithm> #include <algorithm>
#include <atomic>
#include <bit> #include <bit>
#include <charconv> #include <charconv>
#include <chrono> #include <chrono>
@@ -120,6 +122,9 @@ WorldAssemblyFeatureColumnRangeV1 BuildWorldAssemblyFeatureColumnRangeV1(
namespace world_assembly_detail namespace world_assembly_detail
{ {
using FSharedHeightfieldColumnCache =
VoxelForgeCoreShared::TSharedColumnValueCache<HeightfieldPointSample,131072,4>;
// Preserve recipe order without allocating or looking up metadata in the point loop. // Preserve recipe order without allocating or looking up metadata in the point loop.
// Garder l'ordre de recette sans allocation ni recherche de metadonnees par point. // Garder l'ordre de recette sans allocation ni recherche de metadonnees par point.
struct FeatureRange struct FeatureRange
@@ -230,6 +235,9 @@ namespace world_assembly_detail
|| recipe.evaluatorVersion > WorldAssemblyEvaluatorVersion || recipe.evaluatorVersion > WorldAssemblyEvaluatorVersion
|| recipe.unitsPerVoxel != WorldAssemblySubvoxelsPerVoxel) || recipe.unitsPerVoxel != WorldAssemblySubvoxelsPerVoxel)
{ error = "world assembly recipe version, evaluator or fixed scale is unsupported"; return false; } { error = "world assembly recipe version, evaluator or fixed scale is unsupported"; return false; }
if (recipe.layoutChunkWidthSubvoxels <= 0
|| recipe.layoutChunkWidthSubvoxels > 256ll * 512ll)
{ error = "resolved strate-layout chunk width is outside the supported physical range"; return false; }
if (recipe.biomes.empty() || recipe.biomes.size() > MaxBiomeCount) if (recipe.biomes.empty() || recipe.biomes.size() > MaxBiomeCount)
{ error = "world assembly recipe must contain one to eight biome profiles"; return false; } { error = "world assembly recipe must contain one to eight biome profiles"; return false; }
if (recipe.biomeCellSizeSubvoxels <= 0 || recipe.biomeCellSizeSubvoxels > 100000000ll if (recipe.biomeCellSizeSubvoxels <= 0 || recipe.biomeCellSizeSubvoxels > 100000000ll
@@ -291,7 +299,8 @@ namespace world_assembly_detail
return true; return true;
} }
inline bool ValidateStratum(const WorldAssemblyStratumPlanV1& stratum, std::string& error) inline bool ValidateStratum(const WorldAssemblyStratumPlanV1& stratum,
std::int64_t layoutChunkWidthSubvoxels, std::string& error)
{ {
if (stratum.strateIndex < 0 || stratum.topChunkZ < stratum.bottomChunkZ if (stratum.strateIndex < 0 || stratum.topChunkZ < stratum.bottomChunkZ
|| stratum.capWavelengthSubvoxels <= 0 || stratum.capUndulationSubvoxels < 0 || stratum.capWavelengthSubvoxels <= 0 || stratum.capUndulationSubvoxels < 0
@@ -325,9 +334,9 @@ namespace world_assembly_detail
if (feature.type == 2 || feature.type == 4) if (feature.type == 2 || feature.type == 4)
{ {
const std::int64_t stratumMinZ = static_cast<std::int64_t>(stratum.bottomChunkZ) const std::int64_t stratumMinZ = static_cast<std::int64_t>(stratum.bottomChunkZ)
* 32 * WorldAssemblySubvoxelsPerVoxel; * layoutChunkWidthSubvoxels;
const std::int64_t stratumMaxZ = (static_cast<std::int64_t>(stratum.topChunkZ) + 1) const std::int64_t stratumMaxZ = (static_cast<std::int64_t>(stratum.topChunkZ) + 1)
* 32 * WorldAssemblySubvoxelsPerVoxel; * layoutChunkWidthSubvoxels;
constexpr std::int64_t maximumExceptionExtent = 1024 constexpr std::int64_t maximumExceptionExtent = 1024
* WorldAssemblySubvoxelsPerVoxel; * WorldAssemblySubvoxelsPerVoxel;
for (std::size_t axis = 0; axis < 3; ++axis) for (std::size_t axis = 0; axis < 3; ++axis)
@@ -415,6 +424,7 @@ namespace world_assembly_detail
std::uint64_t hash = StartHash(); std::uint64_t hash = StartHash();
HashWord(hash, recipe.schemaVersion, 4); HashWord(hash, recipe.evaluatorVersion, 4); HashWord(hash, recipe.schemaVersion, 4); HashWord(hash, recipe.evaluatorVersion, 4);
HashWord(hash, recipe.unitsPerVoxel, 4); HashWord(hash, recipe.seed, 4); HashWord(hash, recipe.unitsPerVoxel, 4); HashWord(hash, recipe.seed, 4);
HashWord(hash, static_cast<std::uint64_t>(recipe.layoutChunkWidthSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.biomeCellSizeSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.biomeCellSizeSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.biomeWarpSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.biomeWarpSubvoxels), 8);
HashWord(hash, static_cast<std::uint64_t>(recipe.biomeWarpWavelengthSubvoxels), 8); HashWord(hash, static_cast<std::uint64_t>(recipe.biomeWarpWavelengthSubvoxels), 8);
@@ -623,6 +633,7 @@ namespace world_assembly_detail
if (!value.IsObject() || !ReadU32(value.Get("schema_version"), recipe.schemaVersion) if (!value.IsObject() || !ReadU32(value.Get("schema_version"), recipe.schemaVersion)
|| !ReadU32(value.Get("evaluator_version"), recipe.evaluatorVersion) || !ReadU32(value.Get("evaluator_version"), recipe.evaluatorVersion)
|| !ReadU32(value.Get("units_per_voxel"), recipe.unitsPerVoxel) || !ReadU32(value.Get("units_per_voxel"), recipe.unitsPerVoxel)
|| !ReadInteger(value.Get("layout_chunk_width_q"), recipe.layoutChunkWidthSubvoxels)
|| !ReadU32(value.Get("seed"), recipe.seed) || !ReadU32(value.Get("seed"), recipe.seed)
|| !ReadInteger(value.Get("biome_cell_size_q"), recipe.biomeCellSizeSubvoxels) || !ReadInteger(value.Get("biome_cell_size_q"), recipe.biomeCellSizeSubvoxels)
|| !ReadInteger(value.Get("biome_warp_q"), recipe.biomeWarpSubvoxels) || !ReadInteger(value.Get("biome_warp_q"), recipe.biomeWarpSubvoxels)
@@ -688,6 +699,7 @@ namespace world_assembly_detail
out << "{\"schema_version\":" << recipe.schemaVersion out << "{\"schema_version\":" << recipe.schemaVersion
<< ",\"evaluator_version\":" << recipe.evaluatorVersion << ",\"evaluator_version\":" << recipe.evaluatorVersion
<< ",\"units_per_voxel\":" << recipe.unitsPerVoxel << ",\"units_per_voxel\":" << recipe.unitsPerVoxel
<< ",\"layout_chunk_width_q\":" << recipe.layoutChunkWidthSubvoxels
<< ",\"seed\":" << recipe.seed << ",\"seed\":" << recipe.seed
<< ",\"biome_cell_size_q\":" << recipe.biomeCellSizeSubvoxels << ",\"biome_cell_size_q\":" << recipe.biomeCellSizeSubvoxels
<< ",\"biome_warp_q\":" << recipe.biomeWarpSubvoxels << ",\"biome_warp_q\":" << recipe.biomeWarpSubvoxels
@@ -856,7 +868,8 @@ namespace world_assembly_detail
|| !ReadI32(islandValue.Get("bottom_chunk_z"), entry.bottomChunkZ)) || !ReadI32(islandValue.Get("bottom_chunk_z"), entry.bottomChunkZ))
{ error = "world assembly floating-island slot is missing its resolved strate bounds"; return std::nullopt; } { error = "world assembly floating-island slot is missing its resolved strate bounds"; return std::nullopt; }
const std::string nestedJson = JsonText(islandValue.Get("manifest")); const std::string nestedJson = JsonText(islandValue.Get("manifest"));
auto parsedIsland = FloatingIslandManifestV1::FromJson(nestedJson, error); auto parsedIsland = FloatingIslandManifestV1::FromJson(
nestedJson, error, manifest.recipe.layoutChunkWidthSubvoxels);
if (!parsedIsland) return std::nullopt; if (!parsedIsland) return std::nullopt;
entry.manifest = std::move(*parsedIsland); entry.manifest = std::move(*parsedIsland);
manifest.floatingIslands.push_back(std::move(entry)); manifest.floatingIslands.push_back(std::move(entry));
@@ -1030,6 +1043,7 @@ namespace world_assembly_detail
// Audit-only override; normal tile generation resets this to zero before evaluating a recipe. // Audit-only override; normal tile generation resets this to zero before evaluating a recipe.
// Surcharge reservee aux mesures; la generation remet zero avant d'evaluer une recette. // Surcharge reservee aux mesures; la generation remet zero avant d'evaluer une recette.
inline thread_local std::uint32_t HeightfieldColumnOctaveDrop = 0; inline thread_local std::uint32_t HeightfieldColumnOctaveDrop = 0;
inline thread_local std::int64_t HeightfieldColumnInterpolationStrideSubvoxels = 0;
inline std::int32_t FractalNoiseQ16(std::int64_t xQ16, std::int64_t yQ16, inline std::int32_t FractalNoiseQ16(std::int64_t xQ16, std::int64_t yQ16,
std::int64_t zQ16, std::uint32_t octaves, bool ridged = false) std::int64_t zQ16, std::uint32_t octaves, bool ridged = false)
@@ -1361,11 +1375,39 @@ namespace world_assembly_detail
std::int64_t x = 0, y = 0; std::int64_t x = 0, y = 0;
HeightfieldPointSample column{}; HeightfieldPointSample column{};
}; };
// Coarse LOD tiles revisit a wider set of gradient-sample columns than the full-resolution // Keep 65,536 entries in each worker cache; four ways tolerate coordinate families that
// band. Keep those columns resident for a complete worker tile so the 3D mesher does not // deliberately share low hash bits at coarse LODs.
// repeat the procedural biome evaluation for every Z sample. // Chaque cache worker garde 65 536 entrees; quatre voies absorbent les coordonnees grossieres
inline thread_local std::array<HeightfieldColumnCacheEntry, 65536> HeightfieldColumnCache{}; // qui partagent les bits faibles du hash.
constexpr std::size_t HeightfieldColumnCacheWays=4;
constexpr std::size_t HeightfieldColumnCacheSetCount=65536/HeightfieldColumnCacheWays;
inline thread_local VoxelForgeCoreThreadLocal::FLazy<
std::array<HeightfieldColumnCacheEntry, 65536>> HeightfieldColumnCache;
inline thread_local VoxelForgeCoreThreadLocal::FLazy<
std::array<std::uint8_t, HeightfieldColumnCacheSetCount>> HeightfieldColumnCacheNextWay;
inline thread_local HeightfieldColumnCacheStats HeightfieldColumnStats{}; inline thread_local HeightfieldColumnCacheStats HeightfieldColumnStats{};
inline thread_local bool HeightfieldColumnCacheLegacyDirectMapped=false;
inline thread_local std::array<std::int64_t,4> HeightfieldColumnCaptureBounds{};
inline thread_local bool HeightfieldColumnCaptureBoundsValid=false;
inline std::atomic<std::uint64_t> HeightfieldColumnCaptureSequence{0};
inline std::size_t HeightfieldColumnCacheSet(const WorldAssemblyRecipeV1& recipe,
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y) noexcept
{
// Avalanche every coordinate bit before masking. The old direct hash kept too little
// entropy from widely spaced coarse LOD coordinates in its low 16 bits.
// Melanger tous les bits de coordonnee avant le masque; l'ancien hash perdait de
// l'entropie sur les coordonnees espacees des LOD grossiers.
std::uint64_t mixed=static_cast<std::uint64_t>(x)*0x9E3779B185EBCA87ull
^std::rotl(static_cast<std::uint64_t>(y)*0xC2B2AE3D27D4EB4Full,29)
^recipe.contentHash^std::rotl(plan.contentHash,17);
mixed^=mixed>>30;
mixed*=0xBF58476D1CE4E5B9ull;
mixed^=mixed>>27;
mixed*=0x94D049BB133111EBull;
mixed^=mixed>>31;
return static_cast<std::size_t>(mixed)&(HeightfieldColumnCacheSetCount-1);
}
inline HeightfieldPointSample EvaluateColumn(const WorldAssemblyRecipeV1& recipe, inline HeightfieldPointSample EvaluateColumn(const WorldAssemblyRecipeV1& recipe,
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y) const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y)
@@ -1480,31 +1522,126 @@ namespace world_assembly_detail
inline HeightfieldPointSample CachedColumn(const WorldAssemblyRecipeV1& recipe, inline HeightfieldPointSample CachedColumn(const WorldAssemblyRecipeV1& recipe,
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y) const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y)
{ {
const std::uint64_t mixed=(static_cast<std::uint64_t>(x)*0x9E3779B185EBCA87ull) const std::int64_t InterpolationStride=HeightfieldColumnInterpolationStrideSubvoxels;
^std::rotl(static_cast<std::uint64_t>(y)*0xC2B2AE3D27D4EB4Full,23) if(InterpolationStride>0)
^static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe))
^std::rotl(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),41);
auto& entry=HeightfieldColumnCache[static_cast<std::size_t>(mixed)&
(HeightfieldColumnCache.size()-1)];
if(entry.recipe==&recipe&&entry.plan==&plan&&entry.recipeHash==recipe.contentHash
&&entry.planHash==plan.contentHash&&entry.x==x&&entry.y==y)
{++HeightfieldColumnStats.columnHits;return entry.column;}
const auto start=std::chrono::steady_clock::now();
HeightfieldPointSample column=EvaluateColumn(recipe,plan,x,y);
HeightfieldColumnStats.columnComputeMilliseconds+=std::chrono::duration<double,std::milli>(
std::chrono::steady_clock::now()-start).count();
++HeightfieldColumnStats.columnMisses;
if(HeightfieldColumnStats.captureCoordinates&&HeightfieldColumnStats.coordinateCaptureComplete)
{ {
try const std::int64_t X0=FloorDiv(x,InterpolationStride)*InterpolationStride;
const std::int64_t Y0=FloorDiv(y,InterpolationStride)*InterpolationStride;
const std::int64_t X1=X0+InterpolationStride,Y1=Y0+InterpolationStride;
const std::int64_t Fx=x-X0,Fy=y-Y0;
struct FScopedInterpolationSampling
{ {
HeightfieldColumnStats.evaluatedCoordinates.push_back({x,y}); std::int64_t Previous=HeightfieldColumnInterpolationStrideSubvoxels;
} ~FScopedInterpolationSampling()
catch(...) {HeightfieldColumnInterpolationStrideSubvoxels=Previous;}
} SamplingScope;
HeightfieldColumnInterpolationStrideSubvoxels=0;
const HeightfieldPointSample C00=CachedColumn(recipe,plan,X0,Y0);
const HeightfieldPointSample C10=CachedColumn(recipe,plan,X1,Y0);
const HeightfieldPointSample C01=CachedColumn(recipe,plan,X0,Y1);
const HeightfieldPointSample C11=CachedColumn(recipe,plan,X1,Y1);
const auto Lerp=[&](std::int64_t A,std::int64_t B,std::int64_t T)
{return A+((B-A)*T)/InterpolationStride;};
const auto Bilinear=[&](std::int64_t A,std::int64_t B,
std::int64_t C,std::int64_t D)
{ {
HeightfieldColumnStats.coordinateCaptureComplete=false; const std::int64_t Top=Lerp(A,B,Fx),Bottom=Lerp(C,D,Fx);
} return Lerp(Top,Bottom,Fy);
};
HeightfieldPointSample Out=C00;
Out.groundHeightSubvoxels=Bilinear(C00.groundHeightSubvoxels,
C10.groundHeightSubvoxels,C01.groundHeightSubvoxels,
C11.groundHeightSubvoxels);
Out.capHeightSubvoxels=Bilinear(C00.capHeightSubvoxels,
C10.capHeightSubvoxels,C01.capHeightSubvoxels,
C11.capHeightSubvoxels);
return Out;
} }
if(HeightfieldColumnOctaveDrop!=0)
return EvaluateColumn(recipe,plan,x,y);
auto& cache=HeightfieldColumnCache.Get();
auto& nextWay=HeightfieldColumnCacheNextWay.Get();
HeightfieldColumnCacheEntry* replacement=nullptr;
if(HeightfieldColumnCacheLegacyDirectMapped)
{
// Preserve S13's exact direct-map index as an in-process negative control.
// Conserver l'index direct exact de S13 comme controle negatif en cours d'execution.
const std::uint64_t mixed=(static_cast<std::uint64_t>(x)*0x9E3779B185EBCA87ull)
^std::rotl(static_cast<std::uint64_t>(y)*0xC2B2AE3D27D4EB4Full,23)
^static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe))
^std::rotl(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),41);
replacement=&cache[static_cast<std::size_t>(mixed)&(cache.size()-1)];
if(replacement->recipe==&recipe&&replacement->plan==&plan
&&replacement->recipeHash==recipe.contentHash
&&replacement->planHash==plan.contentHash&&replacement->x==x&&replacement->y==y)
{++HeightfieldColumnStats.columnHits;return replacement->column;}
if(replacement->recipe!=nullptr)++HeightfieldColumnStats.columnConflictMisses;
}
else
{
const std::size_t set=HeightfieldColumnCacheSet(recipe,plan,x,y);
const std::size_t first=set*HeightfieldColumnCacheWays;
std::size_t replacementWay=HeightfieldColumnCacheWays;
for(std::size_t way=0;way<HeightfieldColumnCacheWays;++way)
{
auto& candidate=cache[first+way];
if(candidate.recipe==&recipe&&candidate.plan==&plan
&&candidate.recipeHash==recipe.contentHash&&candidate.planHash==plan.contentHash
&&candidate.x==x&&candidate.y==y)
{++HeightfieldColumnStats.columnHits;return candidate.column;}
if(candidate.recipe==nullptr&&replacementWay==HeightfieldColumnCacheWays)
replacementWay=way;
}
if(replacementWay==HeightfieldColumnCacheWays)
{
++HeightfieldColumnStats.columnConflictMisses;
replacementWay=nextWay[set];
}
nextWay[set]=static_cast<std::uint8_t>(
(replacementWay+1)%HeightfieldColumnCacheWays);
replacement=&cache[first+replacementWay];
}
auto& entry=*replacement;
++HeightfieldColumnStats.columnMisses;
const auto compute=[&]()
{
const std::uint64_t sequence=HeightfieldColumnStats.captureCoordinates
?HeightfieldColumnCaptureSequence.fetch_add(1,std::memory_order_relaxed):0;
const auto start=std::chrono::steady_clock::now();
HeightfieldPointSample result=EvaluateColumn(recipe,plan,x,y);
HeightfieldColumnStats.columnComputeMilliseconds+=std::chrono::duration<double,std::milli>(
std::chrono::steady_clock::now()-start).count();
++HeightfieldColumnStats.columnEvaluations;
if(HeightfieldColumnStats.captureCoordinates
&&HeightfieldColumnStats.coordinateCaptureComplete)
{
try
{
const bool outside=HeightfieldColumnCaptureBoundsValid
&&(x<HeightfieldColumnCaptureBounds[0]||x>HeightfieldColumnCaptureBounds[2]
||y<HeightfieldColumnCaptureBounds[1]||y>HeightfieldColumnCaptureBounds[3]);
HeightfieldColumnStats.evaluatedCoordinates.push_back({x,y,sequence,outside});
}
catch(...)
{
HeightfieldColumnStats.coordinateCaptureComplete=false;
}
}
return result;
};
HeightfieldPointSample column{};
if(auto* shared=FSharedHeightfieldColumnCache::threadActive())
{
const VoxelForgeCoreShared::FColumnCacheKey key{
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe)),
recipe.contentHash,
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),
plan.contentHash,x,y};
bool computed=false;
column=shared->getOrCompute(key,compute,computed);
if(!computed)++HeightfieldColumnStats.sharedColumnHits;
}
else column=compute();
entry={&recipe,&plan,recipe.contentHash,plan.contentHash,x,y,column}; entry={&recipe,&plan,recipe.contentHash,plan.contentHash,x,y,column};
return column; return column;
} }
@@ -1622,15 +1759,15 @@ bool WorldAssemblyManifest::finalize(std::string& error)
{ error = "SurfaceWorld stratum recipe seed does not match the world assembly season seed"; return false; } { error = "SurfaceWorld stratum recipe seed does not match the world assembly season seed"; return false; }
stratum.recipeOverride.contentHash = world_assembly_detail::HashRecipe(stratum.recipeOverride); stratum.recipeOverride.contentHash = world_assembly_detail::HashRecipe(stratum.recipeOverride);
} }
if (!world_assembly_detail::ValidateStratum(stratum, error)) return false; if (!world_assembly_detail::ValidateStratum(stratum, recipe.layoutChunkWidthSubvoxels, error)) return false;
if (recipe.evaluatorVersion >= 4) if (recipe.evaluatorVersion >= 4)
{ {
if (stratum.routeConstraints.version != 1 || stratum.route.size() < 2) if (stratum.routeConstraints.version != 1 || stratum.route.size() < 2)
{ error = "world assembly evaluator 4 requires a versioned entrance-to-exit route"; return false; } { error = "world assembly evaluator 4 requires a versioned entrance-to-exit route"; return false; }
const std::int64_t bottomZ = static_cast<std::int64_t>(stratum.bottomChunkZ) const std::int64_t bottomZ = static_cast<std::int64_t>(stratum.bottomChunkZ)
* 32 * WorldAssemblySubvoxelsPerVoxel; * recipe.layoutChunkWidthSubvoxels;
const std::int64_t topZ = (static_cast<std::int64_t>(stratum.topChunkZ) + 1) const std::int64_t topZ = (static_cast<std::int64_t>(stratum.topChunkZ) + 1)
* 32 * WorldAssemblySubvoxelsPerVoxel; * recipe.layoutChunkWidthSubvoxels;
const std::int64_t halfHeight = stratum.routeConstraints.capsuleHeightSubvoxels / 2; const std::int64_t halfHeight = stratum.routeConstraints.capsuleHeightSubvoxels / 2;
for (const auto& point : stratum.route) for (const auto& point : stratum.route)
{ {
@@ -1660,14 +1797,12 @@ bool WorldAssemblyManifest::finalize(std::string& error)
const auto& Scale = islands.manifest.recipe; const auto& Scale = islands.manifest.recipe;
if (Scale.ownerToCoreScaleNumerator == 0 || Scale.ownerToCoreScaleDenominator == 0) if (Scale.ownerToCoreScaleNumerator == 0 || Scale.ownerToCoreScaleDenominator == 0)
{ error = "floating-island owner-to-Core scale is invalid"; return false; } { error = "floating-island owner-to-Core scale is invalid"; return false; }
const double CoreVoxelsPerOwnerChunk = static_cast<double>(CoreTileVoxelCount) if(Scale.layoutChunkWidthSubvoxels<=0)
* Scale.ownerToCoreScaleNumerator / Scale.ownerToCoreScaleDenominator; {error="floating-island strate has no resolved layout chunk width";return false;}
const std::int64_t bottomQ = static_cast<std::int64_t>(std::llround( const std::int64_t bottomQ = static_cast<std::int64_t>(islands.bottomChunkZ)
static_cast<double>(islands.bottomChunkZ) * CoreVoxelsPerOwnerChunk *Scale.layoutChunkWidthSubvoxels;
* WorldAssemblySubvoxelsPerVoxel)); const std::int64_t topQ = (static_cast<std::int64_t>(islands.topChunkZ)+1)
const std::int64_t topQ = static_cast<std::int64_t>(std::llround( *Scale.layoutChunkWidthSubvoxels;
static_cast<double>(static_cast<std::int64_t>(islands.topChunkZ) + 1)
* CoreVoxelsPerOwnerChunk * WorldAssemblySubvoxelsPerVoxel));
if (islands.manifest.recipe.layoutMinimumZSubvoxels < bottomQ if (islands.manifest.recipe.layoutMinimumZSubvoxels < bottomQ
|| islands.manifest.recipe.layoutMaximumZSubvoxels > topQ) || islands.manifest.recipe.layoutMaximumZSubvoxels > topQ)
{ error = "floating-island recipe layout escapes the resolved owner strate bounds"; return false; } { error = "floating-island recipe layout escapes the resolved owner strate bounds"; return false; }
@@ -1871,7 +2006,7 @@ std::array<std::int64_t,2> Heightfield2D::capHeightBounds() const noexcept
if(recipe_->evaluatorVersion>=5) if(recipe_->evaluatorVersion>=5)
{ {
const long double TopSubvoxels=(static_cast<long double>(plan_->topChunkZ)+1.0L) const long double TopSubvoxels=(static_cast<long double>(plan_->topChunkZ)+1.0L)
*CoreTileVoxelCount*WorldAssemblySubvoxelsPerVoxel; *recipe_->layoutChunkWidthSubvoxels;
Minimum=std::min(Minimum,TopSubvoxels); Minimum=std::min(Minimum,TopSubvoxels);
Maximum=std::min(Maximum,TopSubvoxels); Maximum=std::min(Maximum,TopSubvoxels);
} }
@@ -1890,7 +2025,7 @@ std::int64_t Heightfield2D::farSurfaceCapHeightSubvoxels(std::int64_t x,
// Clip only the far render surface. Keep the near density evaluator bit-identical. // Clip only the far render surface. Keep the near density evaluator bit-identical.
// Borner uniquement le plafond lointain. L'evaluateur de densite proche reste identique. // Borner uniquement le plafond lointain. L'evaluateur de densite proche reste identique.
const std::int64_t ownedUpperBoundary=(static_cast<std::int64_t>(plan_->topChunkZ)+1) const std::int64_t ownedUpperBoundary=(static_cast<std::int64_t>(plan_->topChunkZ)+1)
*CoreTileVoxelCount*WorldAssemblySubvoxelsPerVoxel; *recipe_->layoutChunkWidthSubvoxels;
return std::min(column.capHeightSubvoxels,ownedUpperBoundary); return std::min(column.capHeightSubvoxels,ownedUpperBoundary);
} }
@@ -1977,19 +2112,52 @@ void Heightfield2D::resetThreadColumnCacheStats(bool captureCoordinates, bool cl
{ {
// Diagnostic probes may clear old tile entries before comparing isolated sample grids. // Diagnostic probes may clear old tile entries before comparing isolated sample grids.
// Les sondes de mesure peuvent vider les entrees d'une tuile avant de comparer deux grilles. // Les sondes de mesure peuvent vider les entrees d'une tuile avant de comparer deux grilles.
if(clearCache)world_assembly_detail::HeightfieldColumnCache.fill( if(clearCache)
world_assembly_detail::HeightfieldColumnCacheEntry{}); {
world_assembly_detail::HeightfieldColumnCache.Get().fill(
world_assembly_detail::HeightfieldColumnCacheEntry{});
world_assembly_detail::HeightfieldColumnCacheNextWay.Get().fill(0);
}
auto& Stats=world_assembly_detail::HeightfieldColumnStats; auto& Stats=world_assembly_detail::HeightfieldColumnStats;
world_assembly_detail::HeightfieldColumnOctaveDrop=octaveDrop; world_assembly_detail::HeightfieldColumnOctaveDrop=octaveDrop;
Stats.pointCalls=0; Stats.pointCalls=0;
Stats.columnHits=0; Stats.columnHits=0;
Stats.columnMisses=0; Stats.columnMisses=0;
Stats.columnConflictMisses=0;
Stats.sharedColumnHits=0;
Stats.columnEvaluations=0;
Stats.columnComputeMilliseconds=0.0; Stats.columnComputeMilliseconds=0.0;
Stats.captureCoordinates=captureCoordinates; Stats.captureCoordinates=captureCoordinates;
Stats.coordinateCaptureComplete=true; Stats.coordinateCaptureComplete=true;
Stats.evaluatedCoordinates.clear(); Stats.evaluatedCoordinates.clear();
world_assembly_detail::HeightfieldColumnCaptureBoundsValid=false;
} }
void Heightfield2D::setThreadColumnCaptureBounds(std::int64_t minimumXSubvoxels,
std::int64_t minimumYSubvoxels,std::int64_t maximumXSubvoxels,
std::int64_t maximumYSubvoxels) noexcept
{
world_assembly_detail::HeightfieldColumnCaptureBounds={minimumXSubvoxels,
minimumYSubvoxels,maximumXSubvoxels,maximumYSubvoxels};
world_assembly_detail::HeightfieldColumnCaptureBoundsValid=true;
}
void Heightfield2D::setThreadColumnCacheLegacyDirectMapped(bool enabled) noexcept
{ world_assembly_detail::HeightfieldColumnCacheLegacyDirectMapped=enabled; }
void Heightfield2D::setThreadColumnOctaveDrop(std::uint32_t octaveDrop) noexcept
{ world_assembly_detail::HeightfieldColumnOctaveDrop=octaveDrop; }
std::uint32_t Heightfield2D::threadColumnOctaveDrop() noexcept
{ return world_assembly_detail::HeightfieldColumnOctaveDrop; }
void Heightfield2D::setThreadColumnInterpolationStrideSubvoxels(std::int64_t stride) noexcept
{ world_assembly_detail::HeightfieldColumnInterpolationStrideSubvoxels=std::max<std::int64_t>(0,stride); }
std::int64_t Heightfield2D::threadColumnInterpolationStrideSubvoxels() noexcept
{ return world_assembly_detail::HeightfieldColumnInterpolationStrideSubvoxels; }
const HeightfieldColumnCacheStats& Heightfield2D::threadColumnCacheStats() noexcept const HeightfieldColumnCacheStats& Heightfield2D::threadColumnCacheStats() noexcept
{ return world_assembly_detail::HeightfieldColumnStats; } { return world_assembly_detail::HeightfieldColumnStats; }
@@ -2136,8 +2304,8 @@ FieldInfluenceBounds Heightfield2D::influenceBounds() const noexcept
{ {
FieldInfluenceBounds out; FieldInfluenceBounds out;
if (!isValid()) return out; if (!isValid()) return out;
out.minimumZSubvoxels = static_cast<std::int64_t>(plan_->bottomChunkZ) * 32 * WorldAssemblySubvoxelsPerVoxel; out.minimumZSubvoxels = static_cast<std::int64_t>(plan_->bottomChunkZ) * recipe_->layoutChunkWidthSubvoxels;
out.maximumZSubvoxels = (static_cast<std::int64_t>(plan_->topChunkZ) + 1) * 32 * WorldAssemblySubvoxelsPerVoxel; out.maximumZSubvoxels = (static_cast<std::int64_t>(plan_->topChunkZ) + 1) * recipe_->layoutChunkWidthSubvoxels;
return out; return out;
} }
@@ -0,0 +1,263 @@
# VoxelForge strata, units, and generation layers
**Design round L20 — 2026-10-20**
## Summary
Author strate layout in metres and give each strate a voxel size. Keep Core's internal tile at 32³
voxels; its physical width follows that strate's voxel size and the tile's LOD. Use one director to
resolve the season, layout, seed, generator recipe, resolution, and interfaces before workers start.
Generators then evaluate an immutable, common field contract. A shared composition layer applies
strata boundaries, gaps, seals, edits, caches, and proofs. The mesher consumes that composed field
and generic surface hints; it should not branch on SurfaceWorld, FloatingIslands, or feature type IDs.
The code already has parts of this shape, but not the boundaries between them. In particular,
`FStandaloneShapeWorld` is both a dispatch layer and a collection of field adapters, while
`World::generateTile` contains generator-aware far-surface and feature refinement. The Unreal
adapter currently translates two different meanings of “chunk” into Core coordinates.
The L19 ledges are not explained by a different density recipe per LOD. The ring audit found
upward-facing terrain from the same lower SurfaceWorld field at different extracted heights on
adjacent LODs. At the default 25 cm Core voxel size, LOD1, LOD2, and LOD3 sample at 0.5 m, 1 m,
and 2 m. The maximum LOD1→2 ring difference is 1.49862 m; LOD2→3 reaches 7.73318 m, with 8
no-hit samples among 308. An explicit shared surface contract can give all LODs common boundary
geometry and a controlled transition band. A planar ceiling alone will not fix these ground ledges.
One conversion issue needs an explicit preservation target. The current Core path maps one
SurfaceWorld slot chunk to 32 Core voxels (8 m at 25 cm), but one FloatingIslands slot chunk to
32 owner voxels at 12.5 cm (4 m). Converting each current interpretation independently into metres
can preserve each field's current positions, but it does not make shared chunk indices one common
physical boundary. The converter must record the actual per-strate bounds and any resulting gap or
overlap before choosing a unified interface. Do not promise a no-movement migration from a single
global “metres per chunk” constant.
Metres are not a runtime cost concern. Resolution is. Halving voxel spacing in all three axes means
about eight times as many density samples for the same physical volume, plus more tiles, queue work,
and cache entries because each internal tile remains 32³ voxels. With 25 cm as the default for all
strates, the proposed starting resolution matches today's Core sampling resolution.
## 1. Current code mapped to the three layers
There is no single class called “director” today. The director work is split between Unreal's
season/layout code, the Core adapter, and Core's tile scheduler.
| Intended layer | Current location and symbols | Current responsibility and boundary issue |
|---|---|---|
| **Director / orchestrator** | `VoxelStrateComposer.cpp`; `VoxelSeasonManifest.cpp`; `VoxelStrateManager.cpp` (`Initialize`, `GetGeneratorTypeForChunk`, `GetGenerationParams`); `VoxelWorld.cpp` (`BuildDesiredTiles`, tile scheduling, epochs); `VoxelForgeCoreAdapter.cpp` (`BuildSurfaceStratumPlan`, `BuildFloatingIslandStratumPlan`, `AttachValidatedWorldAssembly`) | Composes season params and stacked slots, resolves generator kind and seed, and serializes the Core snapshot. `WorldAssemblyManifest`, `WorldAssemblyPlanV1`, and their `FromJson`/`finalize`/`validate` functions in `WorldAssemblerInternal.h` are the current plan/manifest format. Resolution and bounds are not fully resolved here: Core re-derives them using generator-specific conversions. `TopWorldZ`, `BottomWorldZ`, `HeightInChunks`, and `InterStrateGapChunks` remain chunk/voxel-coordinate based in owner-facing data. |
| **Generators** | SurfaceWorld: `Heightfield2D` in `VoxelForgeCore.h` and `WorldAssemblerInternal.h`; plan construction in `VoxelForgeCoreAdapter.cpp`. FloatingIslands: `FloatingIslandFieldV1` in `VoxelForgeCore.h` and `FloatingIslandsInternal.h`; plan construction in the adapter. Legacy: `UVoxelGenerator::GetDensityAt` in `VoxelGenerator.cpp`, `VoxelDensityOpStack.cpp`, and `VoxelCaveMorphology.cpp`. | SurfaceWorld and FloatingIslands have distinct plan and evaluator APIs. Legacy generation still asks the manager for the current chunk's params and generator type. In Core, the “generator” boundary is obscured by `FStandaloneShapeWorld`, which selects native fields or falls back to the copied owner generator. |
| **Shared field / composition library** | Noise and fixed-point evaluation: `WorldAssemblerInternal.h`, `FloatingIslandsInternal.h`. CPU/HLSL far-field math: `VoxelForgeFieldShared.h`. FP contract: `CoreNamespacePreamble.h`. Feature culling and caches: `BuildWorldAssemblyFeatureTileListV1`, `ScopedWorldAssemblyFeatureQueriesV1`, `SharedColumnCache.h`, `ThreadLocalStorage.h`. Field bounds/proofs: `Heightfield2D::interval`, FloatingIslands bounds, `FStandaloneShapeWorld::ClassifyBoxDetailed` and `BuildShapeDependencyProof`. Density seals: `VoxelDensityPrimitives.h`. | Useful shared pieces exist, but only for subsets of recipes. Noise is not one library used by every legacy and native generator. Bounds, density, and output identity still use subvoxels of a Core voxel. The canonical stratum bounds descriptor `FResolvedStratumBounds` is private to `ShapeWorldInternal.h`, not part of the plan contract. `AppendStratumBoundaryCeilings` is under far-shell/meshing code, even though the boundary meaning is shared composition policy. |
| **Mesher** | `UVoxelMarchingCubesMesher::GenerateMesh` in `VoxelMarchingCubesMesher.cpp`; dispatch and mesh assembly in `World::generateTile` in `VoxelForgeCore.cpp`; `FarShellsInternal.h`; hybrid sharp support in `VoxelHybridSharpMesher.h` and `VoxelMarchingCubesMesher.cpp`. | MC, skirts, far shells, connector repair panels, LOD refinement, and cap repair are spread across the production mesher and Core tile builder. `World::generateTile` scans recipe feature type IDs, refines type-4 shelves only at LOD0–2, selects a native SurfaceWorld horizon, and invokes separate ground/cap repair. `FStandaloneShapeWorld::BuildFarFieldTileInput` constructs FloatingIslands connector panels. These are recipe-aware mesh paths. |
### What crosses a boundary today that should not
- `FStandaloneShapeWorld` reads `UVoxelStrateManager`, `FStrateSlot`, `WorldAssemblyManifest`, legacy
generator params, and generator type. It selects a recipe, evaluates a field, resolves its bounds,
applies a seal, and builds GPU far-field input. That combines director, generator adapter, shared
field, and renderer responsibilities.
- `World::generateTile` knows `WorldAssemblyPlanV1`, SurfaceWorld heightfields, feature numeric IDs,
and FloatingIslands presence. The generic mesher should receive capabilities and surface data,
not know those recipe identities.
- The adapter exports one layout but encodes physical positions in `WorldAssemblySubvoxelsPerVoxel`.
That makes a physical length's fixed integer depend on the selected Core voxel size.
- Core `WorldAssemblyStratumPlanV1` carries `topChunkZ`/`bottomChunkZ`; validation in
`WorldAssemblerInternal.h` multiplies those values by `32`. FloatingIslands additionally stores
its own owner-to-Core size ratio and metric-equivalent bounds in Core-voxel units.
- The Core boundary path calls `GetResolvedStratumBounds` differently for SurfaceWorld and
FloatingIslands. The director should resolve a single physical boundary record once.
- Legacy density still reaches into manager-owned params and operations. It must become a generator
adapter that consumes the same resolved request as a native recipe, or remain explicitly marked as
a compatibility route until it can be ported.
## 2. Violations, ranked by risk
Rank 1 is the highest risk to correct physical layout and cross-LOD output.
| Rank | Risk | Violation and evidence | Why it matters |
|---:|---|---|---|
| 1 | **Critical** | **No single physical bounds/interface contract.** `FResolvedStratumBounds` in `ShapeWorldInternal.h` derives SurfaceWorld bounds from `Slot.*ChunkZ × 32`, but derives native FloatingIslands bounds from `layout*ZSubvoxels` and an owner/Core scale ratio. `GetResolvedStratumBounds` is then reused by field classification, far-field protection, and far ceiling generation. | A shared logical slot boundary can map to different metre positions depending on generator. This can make an apparent seam a gap, overlap, or misplaced terrain surface before the mesher samples it. It also makes “preserve the old heights” ambiguous unless the old per-field physical bounds are recorded. |
| 2 | **Critical** | **LOD extraction has no required shared surface representation.** `World::generateTile` uses normal MC sampling for LOD1–3; native SurfaceWorld ground refinement is only invoked at LOD4+. L19's strict ring probe excludes skirts and masked triangles and measured 149.862 cm max at LOD1→2 and 773.318 cm max at LOD2→3. | A coordinate-stable density function does not guarantee equal extracted surfaces when sample grids differ. Thin seals can be skipped, and a heightfield root can shift with coarse XY/Z samples. This is the measured ledge failure. |
| 3 | **High** | **Chunk, owner-voxel, Core-voxel, and fixed-point units are mixed.** `WorldAssemblyFixed` in the Unreal adapter serializes lengths as 1/256 Core voxel. SurfaceWorld plan bounds use `Slot.BottomChunkZ * 32` and `(TopChunkZ-BottomChunkZ+1)*32`. FloatingIslands uses `32 × ownerToCoreScaleNumerator / denominator`. `ShapeWorldInternal.h` reverses Core Z to legacy chunk coordinates with `/ GetCoreVoxelsPerOwnerChunk()`. | A parameter's physical interpretation depends on generator and runtime Core size. `/32`, `*32`, and scale-ratio logic are reasonable only in a single boundary adapter or for the internal fixed tile; they are incorrect as the authored layout contract. |
| 4 | **High** | **The Unreal adapter and manager both resolve the same layout.** `VoxelStrateManager.cpp` creates chunk slots and per-generator runtime params; `VoxelForgeCoreAdapter.cpp` re-reads those params and builds distinct native plans; `ShapeWorldInternal.h` maps Core samples back through the manager again. `WorldAssemblyStratumPlanV1::topChunkZ/bottomChunkZ` are checked against the manager in `AttachValidatedWorldAssembly`. | The runtime can validate matching integer slots without validating that the resulting physical bounds mean the same thing for both generators. The future adapter should serialize already-resolved metres and per-strate resolution. |
| 5 | **High** | **Generators read director state.** Legacy `UVoxelGenerator::GetDensityAt` asks the manager for type/params and builds/refetches operator stacks. Core native lookup also asks the manager which generator applies at a Core sample. | The generator cannot be a pure evaluator of a resolved recipe. It is hard to cache, audit, or replay independently, and unit conversion is repeated in worker code. |
| 6 | **High** | **Boundary behavior is split between recipe and shared paths.** FloatingIslands geometry v3 special-cases top seal evaluation in `NativeFloatingIslandDensityAt`; older geometry versions retain two-sided seals. `VF_ApplyBoundarySeal`/`VF_ApplyUpperBoundarySeal` provide shared density math, while `AppendStratumBoundaryCeilings` separately patches missing mesh coverage. SurfaceWorld also owns a heightfield cap. | Density closure, boundary ownership, and visible cap geometry can disagree. A shared operator alone does not guarantee a shared, LOD-stable surface. Preserve versioned historical fields during migration, then route new plans through one contract. |
| 7 | **Medium-high** | **Mesher contains recipe policy.** `World::generateTile` has SurfaceWorld native-horizon selection, a SurfaceWorld-only far skip condition, type-2 sharp boxes, type-4 shelf refinement, separate native ground/cap refinement, and a `farHorizonVersion` identity. `ShapeWorldInternal.h` creates connector panel repairs from FloatingIslands. | A new recipe requires mesher edits and generator details leak into extraction. The mesher should consume explicit surfaces, generic feature constraints, and a requested error/refinement hint. |
| 8 | **Medium-high** | **Legacy paths do not share the new generator format.** `UVoxelGenerator`, operator stacks, morphology caches, Core's native `Heightfield2D`, and `FloatingIslandFieldV1` have separate recipe/parameter routes. | “One generator format” is not yet true. A migration wrapper is needed so behavior can be ported in small, hash-checked steps instead of reimplementing all legacy archetypes at once. |
| 9 | **Medium** | **Shared helpers and numeric policies are partial.** Core's FP preamble/self-test applies to Core translation units; fixed-point noise is implemented in assembler code, island noise is in a separate implementation, and far CPU/HLSL math has its own shared header. Feature bounds/caches are more reusable than the field interfaces. | Keep the tested Core determinism contract, but promote the shared numeric/noise primitives only where their exact semantics can be versioned. “Shared” code is not automatically cross-platform identical if separate float evaluators remain. |
### Unit measurements relevant to migration
`CHUNK_SIZE` is 32 and `VOXEL_SIZE` is 12.5 cm, so the owner's legacy chunk is 4 m
([`VoxelTypes.h`](../Source/VoxelForge/Public/VoxelTypes.h), [`Round5`](Research/WorldAssemblerM3/Round5/REPORT.md)). The current default Core voxel is 25 cm. In the current native Core routes:
| Route | Current conversion | Physical chunk width at default | Evidence |
|---|---|---:|---|
| SurfaceWorld | `32` Core voxels per slot chunk | 8 m | `BuildSurfaceStratumPlan` uses chunk bounds directly in Core voxel units; L18 records the preserved `topChunkZ × 32` mapping. |
| FloatingIslands | `32 × 125000/250000 = 16` Core voxels per owner chunk | 4 m | `BuildFloatingIslandStratumPlan` serializes the ratio and applies it to layout bounds; `GetCoreVoxelsPerOwnerChunk` uses the same ratio. |
This confirms the claimed factor of two. It does **not** prove that this conversion alone caused
the L19 ring delta. L19 isolated the observed step to coarse extraction of lower SurfaceWorld
terrain, and the reported LOD4+ horizon refiner cannot affect those LOD1→2 and LOD2→3 values.
## 3. Generator contract and one-time interface handling
### What the director resolves before generation
The director should publish an immutable `ResolvedWorld` (exact type/schema is an implementation
choice) containing:
- a stable world/season identity and seed;
- an ordered list of strates with a stable ID, generator kind and recipe version;
- each strate's physical minimum and maximum bounds in metres, including height as their difference;
- a voxel size in metres per strate (25 cm default for every strate);
- route points, island anchors/connectors, and all top/bottom/ceiling positions in the same physical
coordinate space;
- one resolved interface record per adjacent pair, including any explicit void, bedrock gap,
sealed contact, upper cap, passage, or open boundary;
- any season-level values that affect world output, such as routes, islands, water datum, or biome
selection, already attached to their owning strate or interface;
- a canonical identity over the sorted resolved layout, seed, resolution map, recipes, and interface
records.
Do not make generators ask the director for the active `FStrateSlot`, chunk number, season, or
neighbour generator while evaluating a point.
### Request to every generator
A worker request should give the generator:
1. The immutable resolved recipe and stable stratum ID.
2. Physical query/tile bounds in metres, including the exact halo requested by the mesher.
3. The canonical sample coordinates or a clearly defined lattice origin and step. Voxel coordinates
are useful as an internal derived lattice, but metres/physical fixed units are the identity space.
4. The resolved per-strate voxel size and seed. LOD can be included as a sampling hint; the canonical
field value itself must not change just because the caller chose another LOD.
5. Read-only interface descriptors that touch the request bounds. Pass boundary records, not a
pointer back to the neighbour's manager or mutable generator.
### Result from every generator
The common result should provide a deterministic field evaluator and its declared capabilities:
- signed density using one documented solid/air sign convention;
- optional material or surface-class data;
- conservative interval/classification proofs and conservative feature/influence bounds, or an
explicit “unknown, evaluate” result;
- optional semantic 2D surfaces such as a ground heightfield or a cap, in physical coordinates;
- a detail envelope / maximum safe sample spacing hint. It is a hint to generic LOD/refinement
policy, not permission for a recipe to choose its own mesh path;
- generator/schema/evaluator versions for stable plan and output identity.
Keep the established fail-open behavior: an unknown interval or influence bound causes evaluation,
not a solid/air skip. Existing feature candidate lists and worker caches fit this contract as
optimizations beneath the evaluator.
### Interfaces, seals, caps, and voids belong to shared composition
The director resolves the meaning and exact physical location of each interface once. The shared
composition layer then combines generator fields and applies boundary semantics in a fixed order:
1. Evaluate each generator only for its declared physical domain, retaining its ordinary
field/feature behavior.
2. Apply the interface contract once: for example, a physically measured seal band, a cap surface,
open void, bedrock gap, or permitted passage. The contract declares ownership, sidedness, material
class, collision/support policy, and whether player edits may cut it. A gap is data, not an
accidental “no generator found” branch.
3. Apply world edits through the canonical composed field, so both sides see the same edit in
physical space.
4. Give the resulting field, proofs, and any explicit surfaces to the mesher.
This centralizes the semantics currently spread across generator density wrappers,
`FResolvedStratumBounds`, and `AppendStratumBoundaryCeilings`. Existing versioned manifests still
need compatibility adapters: do not silently reinterpret old `boundarySealSubvoxels` values.
For two different generator kinds that meet at a plane, both should reference the same stable
interface ID and exact physical boundary. Their density fields can remain independent; shared
composition owns the boundary rule. If the plan intentionally has open space between them, the
resolved layout records that metre-valued interval explicitly.
## 4. Why LOD changes thin features, and the interface surface contract
MC samples density at lattice corners. A thin seal or cap can be narrower than one coarse cell, so
the coarse grid may see no sign change at all. If it does see a crossing, interpolation uses the
coarse cell's endpoint values; its root can differ from the finer grid's root. A shared analytic
density function guarantees the same values at the same physical coordinates, not the same triangles
from different sample grids.
For a physical strate boundary, use an explicit surface descriptor with exact height/shape in metres
and a globally stable sample phase. Every LOD must use common anchors along tile and LOD transition
edges. The mesher can fill the interior at its chosen rate, then build a deterministic transition
band from those common anchors into its coarser interior. A seal/cap should not rely on a sub-cell
thin density strip surviving arbitrary MC sampling.
For the L19 lower-ground ledge, the same rule needs a SurfaceWorld ground profile available to the
mesher as semantic surface data. A shared planar boundary cap would only close the strate ceiling;
it would not align these upward-facing ground triangles. The surface can be band-limited by LOD, but
the adjacent LODs must share their transition samples and be checked against a physical error
tolerance. If that cannot be met with a transition band, refine only the affected boundary tiles.
The costs are extra boundary vertices/triangles and some CPU work to construct common transition
strips. Collision/support must consume the same interface representation where that surface is
collision-relevant. The owner would see caps and ledges hold one physical height as the camera moves
between LODs, instead of steps or holes appearing at the ring. Authoring remains in metres; internal
tile and transition details stay hidden.
This is not free geometry, but it is bounded to boundaries and LOD transition bands. L19 has already
shown why “add a thin density seal and sample it normally” is not a sufficient all-LOD guarantee.
## 5. Keep the per-strate resolution door open
Yes. A 25 cm per-strate default preserves the current Core sample spacing, and the common physical
field coordinate contract leaves room for later different sizes. Do not enable mixed resolutions
until the Round5 boundary contract is met:
1. Canonical physical-space field queries and explicit ownership at a shared boundary.
2. Deterministic transition meshes with common LOD ancestry on both resolutions.
3. Physical-space edit rasterization/replay that reaches both grids exactly once, with no holes or
double application.
4. A stable, canonically sorted strate-ID-to-size map included in plan/season identity and border
hashes.
5. Streaming and collision rules for tiles that touch or span two resolutions.
At today's one-size setting, the size map has one value (250,000 microns) for every strate. It adds
no mixed-resolution mesh, edit, or streaming cost. Tile width remains `32 × voxel size × 2^LOD`;
different future sizes change physical tile width and workload, but never change the 32³ internal
tile format.
## 6. Migration plan with “worlds don't move” checks
The checkpoints distinguish expected equality from a deliberately changed interface mesh. A plan
or schema identity can change even when field output remains equal; record both identities and mesh
hashes separately.
| Step | Work | Expected equality / check | Changes output? / Unreal PC? |
|---:|---|---|---|
| 0 | Freeze the L19 evidence as the baseline: W12, Clang with FP contraction off; retain the whole-view hashes, full-detail hashes, strict ceiling audit, captures, and FI/SW ring tables. | Baseline hashes recorded below; pin the protected SW LOD0–2 hashes too. Capture byte/pixel comparisons and ring samples must retain location, LOD, and skirt exclusion. | No. No new build needed for this design round. |
| 1 | Add a versioned resolved-metre layout representation and a read-only conversion/audit path. The audit reports, per strate, old input units, resolved old physical bounds, new metre bounds, voxel size, interfaces, and identity. Keep the old evaluator active. | Exact old-vs-new resolved positions at all authored top, bottom, height, route, island, and cap anchors. Old Core density/mesh/payload/topology hashes remain equal where the conversion is exactly representable; otherwise list the precise quantization delta before accepting a new baseline. | No. Core parser/audit can be Linux-only; adapter export needs Unreal BuildHost on the owner's PC. |
| 2 | Change owner-facing layout authoring and season serialization to metres. Convert each old slot using its **current resolved physical bounds**, not one global chunk multiplier. Represent any historical gap/overlap explicitly. Default each strate's voxel size to 25 cm. | Same physical top/bottom/height values and field anchors before/after. Run default W12 hashes and matched captures. The report must call out any interface whose two old generator bounds disagree instead of silently forcing them together. | Intended no. Touches `VoxelForgeCoreAdapter.cpp`, `VoxelStrateManager`, season manifest/composer and likely `VoxelWorld`; compile and actor validation require the owner's Unreal PC. |
| 3 | Add the common generator request/result contract and adapt `Heightfield2D` and `FloatingIslandFieldV1`; wrap the legacy `UVoxelGenerator` route without moving it yet. Move manager lookups out of evaluator calls in stages. | Per-strate exact density queries, proof classifications, full-detail hashes, whole-view hashes, W1/W8/W12 determinism, and generator-to-legacy route parity. Existing current output hashes remain equal for adapters that preserve their exact physical recipe. | No intended visual change. Unreal adapter/legacy wrappers need owner-PC UHT/build and actor validation; native Core pieces can be audited on Linux. |
| 4 | Resolve interface records once in the director; route new seal, cap, void, bedrock-gap, and passage behavior through shared composition. Keep old manifest versions on compatibility adapters. | Preserve density hashes where only a mesh closure was missing. Run the strict LOD0–8 ceiling interior/perimeter audit, edge pairing, same-LOD border hashes, matched captures, and field proofs. Any newly closed boundary is a named expected mesh/payload/topology delta. | Affected boundary mesh may change. Adapter serialization needs owner-PC validation; Core audit can run here. This step fixes thin seals/caps, not the L19 ground ledges. |
| 5 | Add the generic explicit-surface and LOD-transition contract. Feed SurfaceWorld ground-profile data into common transition bands; prototype on the measured FI/SW interface. | Produce before/after matched readable captures and full ring tables. Require zero no-hit interface samples and a chosen physical seam-error limit; retain L19 hash equality for unaffected tiles/LODs. For intended changes, list changed mesh/payload/topology hashes and keep density unchanged if the field itself is unchanged. | **This is the step that fixes the L19 ledges.** It changes protected SurfaceWorld LOD2 output, so implement only after the owner approves that specific output change. Unreal capture/collision review is on the owner's PC. |
| 6 | Enable a per-strate size map behind the already-resolved contract, initially set to 25 cm on all strates. Add one non-default diagnostic size case only after the default remains green. | At all-25-cm map, reproduce the approved default hashes and captures. Include sorted size-map identity in a negative control; boundary/transition hashes must change when one size changes. Re-run edit-across-boundary, collision, streaming, and W1/W8/W12 checks. | No default change; non-default diagnostic intentionally changes sampling. Touches Unreal reflected settings, snapshot adapter, and world identity; full compile/run requires the owner's PC. |
### L19 reference hashes
Representative W12 Clang `-ffp-contract=off`, density / mesh / payload / topology:
| Whole view | L19 hash |
|---|---|
| SurfaceWorld | `c10697a8f48380c7 / 4197fc1072f0ff58 / 7b3e616ec9459851 / c879e35592bf33e5` |
| FloatingIslands | `00bc3607a7839854 / 4baa66127c2b0892 / e11ef05e851a1517 / 1278bc4b1fffb869` |
Protected SurfaceWorld LOD0–2 hashes are in the L19 report and should be retained through steps
1–4 except for explicitly approved boundary geometry. The whole-view hash gate alone cannot prove
that a ring improved; step 5 needs the strict ring table and readable captures as well.
### Owner decisions this design needs
1. **Preservation target:** confirm that migration snapshots each current generator's resolved
physical bounds (including any current overlap or gap) before later tuning them into a single
authored metre layout. If instead the initial migration should force currently different bounds
to meet, that is a deliberate world change and needs its own baseline/capture review.
2. **Ledge output:** approve the specific SurfaceWorld LOD2/transition change before step 5
implementation, as required by the existing protected-output rule.
@@ -0,0 +1,34 @@
#!/usr/bin/env python3
"""Run one child and report its wait4 peak RSS without /usr/bin/time."""
import os
import resource
import sys
import time
if len(sys.argv) < 2:
raise SystemExit("usage: MeasureProcess.py executable [arguments ...]")
address_limit, _ = resource.getrlimit(resource.RLIMIT_AS)
stack_limit, _ = resource.getrlimit(resource.RLIMIT_STACK)
if address_limit in (resource.RLIM_INFINITY, -1) or address_limit > 6 * 1024**3:
raise SystemExit("run under prlimit --as=6442450944")
if stack_limit in (resource.RLIM_INFINITY, -1) or stack_limit < 64 * 1024**2:
raise SystemExit("run under prlimit --stack=67108864:67108864")
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
print(f"[ProcessLimits] address_limit={address_limit} stack_limit={stack_limit} affinity={sorted(os.sched_getaffinity(0))}", flush=True)
started = time.monotonic()
pid = os.fork()
if pid == 0:
try:
os.execvp(sys.argv[1], sys.argv[1:])
except OSError as error:
print(f"MeasureProcess: exec failed: {error}", file=sys.stderr, flush=True)
os._exit(127)
_, status, usage = os.wait4(pid, 0)
wall = time.monotonic() - started
exit_code = os.waitstatus_to_exitcode(status)
print(f"[ProcessResources] exit_code={exit_code} wall_s={wall:.6f} peak_rss_kib={usage.ru_maxrss}", flush=True)
raise SystemExit(exit_code)
@@ -0,0 +1,153 @@
# L1 — Linux baseline (abyss)
## What changed
- `Standalone/Source/StreamBenchmarkPipeline.h` now holds the S13 streaming benchmark, hash helpers, and per-LOD reporting. The Windows viewer and the headless executable call the same functions.
- `Standalone/Source/WorldAssemblyPrototype.h` holds the existing Round 1 plan builder; both executables call it.
- `Standalone/Source/StreamBenchmarkHeadless.cpp` is the Linux CLI entry point. It loads the same owner JSON, resolves it through `StandaloneOwnerLoader`, builds the same Core snapshot, and runs the shared pipeline. It has no window, renderer, D3D11, or Win32 setup.
- `Standalone/BuildLinux.sh` builds the Core library and headless executable. `Linux1/MeasureProcess.py` checks affinity and memory/stack limits and records child peak RSS.
- `Standalone/Source/StandaloneViewer.cpp` now includes and calls the shared headers. `Standalone/Core/src/CoreNamespacePreamble.h` and `Standalone/Compat/CoreMinimal.h` include `<cfloat>` for existing `FLT_MAX` use. `Standalone/Compat/StandaloneDataAssetGlue.cpp` now supplies the standalone `UVoxelSeasonAsset::GetPrimaryAssetId` implementation matching the engine source.
The headless entry point retains the parsed JSON root for the existing snapshot adapter. The route planner, Core shape compile, tile generator, hash code, and pipeline counters are shared with the viewer, rather than reimplemented. Viewer-only command switches for process affinity, priority, and frame limit are accepted for command-line parity; the Linux runner pins and limits itself externally.
**Windows compile risk:** MSVC was unavailable here, so the Windows viewer was not compiled. The likely risk spots are the new includes and namespaced calls in `StandaloneViewer.cpp`, and the moved inline bodies in `StreamBenchmarkPipeline.h` and `WorldAssemblyPrototype.h`; `Build.ps1` compiles that viewer with `/std:c++20`. The Linux-only main, script, and RSS helper are not in the explicit Windows source list. The compatibility `GetPrimaryAssetId` mirrors `VoxelSeasonAsset.cpp`; keep the engine `.cpp` out of the Standalone compatibility manifest to avoid a duplicate if that manifest is expanded later. No density formula changed, so no recipe-version bump is needed.
## Build and run commands
Run from the repo root. `BuildLinux.sh` enforces CPUs 0–11 and a 6 GiB address-space limit itself; the explicit wrapper below makes those limits visible at the call site too. The build output is under `Standalone/Build/linux-*` and `Standalone/bin/linux/`.
```bash
taskset -c 0-11 prlimit --as=6442450944 -- \
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19 --jobs=12 --fp-contract=off \
> Saved/Linux/build-clang19-final.log 2>&1
taskset -c 0-11 prlimit --as=6442450944 -- \
bash Standalone/BuildLinux.sh --compiler=g++-14 --variant=gcc14 --jobs=12 --fp-contract=off \
> Saved/Linux/build-gcc14.log 2>&1
```
The measured build flags were `-std=c++20 -O2 -mavx2 -mfma -ffp-contract=off -fno-fast-math`; Clang also suppresses the legacy narrowing diagnostic that MSVC accepts. The benchmark wrapper below enforces the 6 GiB address-space cap, a 64 MiB stack, and CPU affinity, then records `wait4` peak RSS. These are the exact run calls; `yes` adds `--profile-column-overlap`.
```bash
run_bench() {
local variant="$1" workers="$2" overlap="$3" name="$4"
local profile=()
if [[ "$overlap" == yes ]]; then profile+=(--profile-column-overlap); fi
taskset -c 0-11 prlimit --as=6442450944 --stack=67108864:67108864 -- \
python3 Standalone/Research/WorldAssemblerM3/Linux1/MeasureProcess.py \
"Standalone/bin/linux/VoxelForgeCoreHeadless-$variant" Standalone/data/owner_world.json \
--workers="$workers" --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash \
--force-generate --clip-radius=3 --max-clip-level=8 \
--camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 \
--process-priority=Normal --process-affinity=4095 --frame-limit=60 \
"${profile[@]}" > "Saved/Linux/$name.log" 2>&1
}
run_bench clang19 1 no bench-clang19-w1-r1
run_bench clang19 8 no bench-clang19-w8-r1
run_bench clang19 12 no bench-clang19-w12-r1
run_bench clang19 8 no bench-clang19-w8-r2
run_bench clang19 12 no bench-clang19-w12-r2
run_bench clang19 1 no bench-clang19-w1-r2
run_bench clang19 12 no bench-clang19-w12-r3
run_bench clang19 1 no bench-clang19-w1-r3
run_bench clang19 8 no bench-clang19-w8-r3
run_bench clang19 8 yes bench-clang19-w8-columns-r1
run_bench clang19 8 yes bench-clang19-w8-columns-r2
run_bench clang19 8 yes bench-clang19-w8-columns-r3
run_bench gcc14 8 no bench-gcc14-w8
```
Every run used a fresh process and a newly constructed streamer; the pipeline reported `cache_hits=0`, so no process or thread-local tile/column cache carried over. `--force-generate` was passed for CLI parity, not relied on for isolation. The kernel file cache was not purged: doing so would require a system-wide setting outside the allowed write boundary. Owner JSON load is included in the cold-start timer and took about 5 ms.
## Hashes and determinism
Every Linux hash below covers the same 2,553-tile Round17 view. Clang used `-ffp-contract=off`, matching the intended MSVC `/fp:precise` behavior; GCC used the same contraction setting. Both builds enabled AVX2/FMA instructions but disabled contraction.
| Build / workers | Runs | Density | Mesh | Payload | Topology | Tiles |
|---|---:|---|---|---|---|---:|
| Windows S13 reference, W1/W8/W12 | S13 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
| Linux Clang 19, W1 | 3 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
| Linux Clang 19, W8 | 3 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
| Linux Clang 19, W12 | 3 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
| Linux GCC 14, W8 | 1 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
There was no divergence in this owner seed/view, so there is no first sample or stage to bisect and no density fix to make. The result covers the full hashed view, not every possible seed or platform math-library input. The tested flags show no observable FMA, libm, integer-width, container-order, or SIMD difference here; they do not establish what default Clang contraction would do.
Clang W1/W8/W12 each produced identical hashes across all three runs. The GCC W8 run agreed too. The overlap-capture counts varied slightly with worker scheduling, while the generated hashes stayed fixed.
## Linux timing and per-LOD cost
Machine: Debian 13, Intel i9-12900H, 15 GB RAM, 24 MiB L3. Processes were pinned to logical CPUs 0–11 (the six P-cores and their SMT siblings); CPUs 12–19 remained free. CPUs 0–11 reported `powersave` governor and `balance_performance` EPP. No governor or system setting was changed; priority remained normal. `RLIMIT_AS` was 6 GiB for every build and benchmark process. The benchmark stack was limited to 64 MiB after the default-stack failures below. No run reached the 30-minute limit.
`whole_view_ready` is the cold-start timer from process start through all 2,553 tiles, including owner load, plan, shape compile, and streamed generation. Values are median `[min–max]` of three interleaved runs. Peak RSS values are the three `wait4` readings in KiB, in run order; the maximum across all successful runs was 604,652 KiB.
| Workers | `whole_view_ready` median [range] | Peak RSS per run (KiB) |
|---:|---:|---|
| W1 | 16.555 s [16.069–16.660] | 218,372 / 329,308 / 329,012 |
| W8 | 3.562 s [3.558–3.602] | 445,884 / 462,588 / 462,216 |
| W12 | 3.512 s [3.482–3.557] | 536,884 / 537,208 / 539,036 |
| W8 with overlap capture | 3.718 s [3.638–3.718] | 603,820 / 603,480 / 604,652 |
| GCC 14 W8 hash check | 3.789 s (one run) | 463,276 |
The S13 W8 Windows reference was 3.518 s on the owner’s 5800X3D. The Linux W8 result is 44 ms (about 1.3%) slower for the same source view and timer, but these are different CPUs and this is a baseline comparison, not an optimization result. Round17 documents no corresponding W1/W12 timing for a direct comparison.
The next table divides S13’s accumulated `worker_sum_s` by tile count. Each cell is median `[min–max]` milliseconds per tile across the three Clang runs. It is average worker time per tile, not a per-tile p95 or whole-pipeline elapsed time.
| LOD | W1 ms/tile | W8 ms/tile | W12 ms/tile |
|---:|---:|---:|---:|
| 0 | 2.131 [2.066–2.144] | 4.222 [4.146–4.343] | 6.405 [6.364–6.489] |
| 1 | 4.429 [4.281–4.441] | 7.394 [7.335–7.491] | 11.084 [11.000–11.296] |
| 2 | 1.319 [1.282–1.319] | 1.871 [1.842–1.943] | 2.771 [2.740–2.813] |
| 3 | 5.520 [5.366–5.527] | 7.916 [7.860–8.179] | 11.777 [11.670–11.916] |
| 4 | 16.305 [15.787–16.344] | 23.403 [23.382–23.798] | 34.479 [34.229–34.654] |
| 5 | 7.389 [7.223–7.443] | 10.714 [10.567–10.926] | 15.520 [15.288–15.605] |
| 6 | 15.521 [15.021–15.638] | 22.183 [21.813–22.350] | 32.063 [31.641–32.163] |
| 7 | 17.203 [16.495–17.226] | 24.476 [23.925–24.560] | 33.760 [33.085–33.885] |
| 8 | 12.087 [11.673–12.228] | 16.591 [16.559–16.617] | 22.738 [22.610–23.673] |
S13’s exclusive stage counters are also retained per LOD: column evaluation, marching cubes, ground/cap refinement, and mesh assembly. At W8, column evaluation averaged 21.124 ms/tile at LOD4 `[21.083–21.462]`, versus 6.815 ms at LOD3 `[6.761–7.014]`; LOD4 remains the standout cost. Standalone has matching aggregate stage sums, but no BuildHost-style per-tile p95 or per-LOD classify-exclusive p95. It also has no counterpart for full-scan versus candidate feature-list p95, field-point calls p95, column misses p95, or approximate per-LOD hit rate; its field/cache totals are whole-run totals, and its overlap capture measures cross-tile XY reuse instead. BuildHost `UWorld::Tick`, apply, and stationary-ring timings also have no headless equivalent.
The W8 overlap capture completed for all tiles and all LODs. Each cell is median `[min–max]` across three captures.
| LOD | Unique XY columns | Repeated tile evaluations | Neighbor repeats | Cross-worker neighbor repeats |
|---:|---:|---:|---:|---:|
| 0 | 128,240 [128,240–128,240] | 360,764 [359,953–364,225] | 301,491 [300,316–301,913] | 296,573 [294,996–297,862] |
| 1 | 103,957 [103,464–104,384] | 300,707 [296,768–312,183] | 243,479 [236,767–246,556] | 238,030 [228,885–241,780] |
| 2 | 32,267 [32,263–32,271] | 106,072 [104,091–106,939] | 90,338 [88,410–90,534] | 87,693 [84,976–87,921] |
| 3 | 33,286 [33,286–33,286] | 87,531 [87,310–88,408] | 81,853 [79,915–83,171] | 78,814 [76,126–78,903] |
| 4 | 91,325 [91,325–91,325] | 231,088 [230,967–231,122] | 228,336 [226,998–228,369] | 207,383 [191,310–207,789] |
| 5 | 71,960 [71,960–71,960] | 118,805 [118,676–118,806] | 118,665 [117,782–118,797] | 111,453 [108,197–112,585] |
| 6 | 280,336 [280,336–280,336] | 63,463 [63,148–63,624] | 63,463 [63,148–63,624] | 63,204 [62,944–63,579] |
| 7 | 71,530 [71,530–71,530] | 7,762 [7,752–7,807] | 7,762 [7,752–7,807] | 7,155 [7,074–7,262] |
| 8 | 106,219 [106,219–106,219] | 32,092 [32,013–32,155] | 32,092 [32,013–32,155] | 28,393 [27,959–28,598] |
## Failed and retried attempts
- `build-clang19.log` failed because `FLT_MAX` was undeclared; adding `<cfloat>` fixed it.
- `build-clang19-retry1.log` failed on existing double-to-float list initializers in `VoxelStrateManager.cpp` and an incorrect dereference in the new runner. The Linux build suppresses that legacy Clang narrowing diagnostic and passes the snapshot value correctly.
- `build-clang19-retry2.log` linked with unresolved `typeinfo for UVoxelSeasonAsset`; the compatibility glue now provides the missing `GetPrimaryAssetId`. `build-clang19-retry3.log` and `build-clang19-final.log` succeeded.
- A temporary diagnostic relink in `rebuild-headless-crash-handler.log` omitted `main` and failed; `relink-headless-crash-handler.log` corrected it. This was only for diagnosis and is not part of the final source.
- `smoke-clang19-w1.log` stopped before launching because `/usr/bin/time` was absent. No package was installed; `MeasureProcess.py` replaced it.
- Seven default-stack W1 attempts (`smoke-clang19-w1-r1.log` through `r7.log`) and three instrumented diagnostic runs (`smoke-clang19-direct.log`, `smoke-clang19-entry.log`, `smoke-clang19-stack.log`) exited with SIGSEGV while entering `FStandaloneStreamingGenerator::Generate` under the default 8 MiB stack. Their peak RSS was 211,056–329,008 KiB. A 64 MiB stack completed the diagnostic run (`smoke-clang19-stack64m.log`, 330,288 KiB peak RSS); temporary tracing pointed to worker stack exhaustion. That diagnostic included an extra direct tile and was excluded from the baseline. All clean baseline runs used the 64 MiB stack.
## Note for the owner
For this owner seed and view, a Linux server and Windows client generate identical hashed density, mesh, payload, and topology, and the hashes stayed stable across Linux worker counts and compilers. This i9-12900H result is a local Linux speed baseline; the W8 time is close to the S13 Windows number, but the machines differ and it should not be read as a speedup.
## Orchestrator review (Claude)
- **The default-stack crash is thread-local storage, not deep recursion.** `-fstack-usage` shows no frame over
~4 KB in Core or the headless tool (`Generate` is 8 KB). But the binary's TLS segment is
`0x115068d` = **17.3 MiB per thread** (6.1 MiB of it initialised data), and glibc carves static TLS out of
each thread's stack, so an 8 MiB default stack overflows before any work runs. Largest pieces:
`world_assembly_detail::HeightfieldColumnCache` 6.8 MB, `GFloorReliefCache` 1.3 MB (x2: Core and
legacy copies), `IslandColumnCache` 1.1 MB, `GRoomGraphCache` 0.97 MB (x2), `GSurfColCache` 0.83 MB (x2).
Windows allocates TLS separately from the 1 MB thread stack, which is why it never showed there.
It matters for a Linux dedicated server: every worker thread pays ~17 MB and copies 6 MB on start.
Open for a later round (after S14, which reworks the column cache).
- **Untested:** the hash match is with `-ffp-contract=off`. Whether the hash would *detect* contraction
(`on`/`fast`) has not been shown, so it is not yet proven the flag is load-bearing.
- Viewer move checked: of 738 removed viewer lines, all but 12 signature lines (now `inline`/namespaced)
reappear verbatim in the two shared headers; every remaining viewer use is qualified or `using`-imported.
MSVC compile still unverified.
@@ -0,0 +1,115 @@
# Linux10 — startup and region crossing
**Result:** no world-generation optimization was shipped. The dominant spawn gate is full shape compilation; the current Core API does not let tiles consume a partially built shape safely. L10 adds opt-in phase and crossing telemetry to the headless research path.
Runs used CPUs 0–11, normal priority, at most `-j12`, a 6 GiB address-space cap, and the unchanged `powersave` governor. Peak monitored RSS was 624,996 KiB (610.3 MiB). Final builds: Clang 19 with FP contraction off, SHA-256 `7d5360e2baa637f8b2b4679df9616580bffe689afd101470e311260f0ecd4975`; GCC 14 default, `5041cf15019766f453eb59fe8ff7fc4cd98ca6a904208b645e3d7ca4584e1195`. The L9 Clang timing/hash baseline is `Standalone/bin/linux/VoxelForgeCoreHeadless-linux9-clang`, SHA-256 `0cd3f0ef993ced2c615418c6e2b37b83f57eff6d024d7d1568c30ea51490384a`.
## 1. Startup phases
SurfaceWorld seed 0, W12, no hash; five runs on the optimized Clang build. Wall and process CPU are medians. Process CPU sums work across threads. First-tile time is from cold start; its CPU column is CPU since pool start.
| Phase | Wall ms | Process CPU ms | Threads used |
|---|---:|---:|---|
| Owner data load and resolve | 5.05 | 5.05 | 1 |
| Assembly plan build | 51.04 | 51.03 | 1 |
| Core snapshot | 0.53 | 0.54 | 1 |
| First desired-set build, 2,553 tiles | 0.74 | 0.74 | 1 |
| Shape request setup | 0.03 | 0.03 | 1 |
| Shape compile | 222.59 | 856.79 | caller + up to 8 scheduler workers |
| Streamer setup | 0.01 | 0.01 | 1 |
| Worker-pool start | 0.41 | 1.27 | 12 requested; 8–11 had entered at print |
| First tile starts at 299.62 ms | — | 1.59 since pool start | 12/12 entered |
Shape-compile wall ranged 215.89–324.88 ms; first tile started at 286.56–409.76 ms. Owner load, plan, local shape setup, and far-parent construction are serial. Before the pool starts, there are no sleeping stream workers, but most of the 12 allowed CPUs are unused. During the interval and detail-band phases the scheduler uses at most 8 workers, leaving up to 4 CPUs unused.
The phase-trace mode’s whole-view median was 1.436 s, versus 1.372 s with tracing off. The phase runs are for decomposition only; the performance ranking and A/B below use the optimized build with tracing disabled and hashing off. In that flag-off path, shape wall time was 0.222 s median, consistent with the phase trace.
## 2. Shape contents and first-tile dependencies
| Shape phase | Wall ms | Process CPU ms | Work / concurrency |
|---|---:|---:|---|
| Local owner shapes and spatial bins | 40.46 | 40.44 | Extracts owner primitives; 1 thread |
| Rock intervals, signs, candidate bands | 40.20 | 187.14 | Packed column signs and candidate masks; up to 8 workers |
| Detail band and sign-edge distances | 81.00 | 568.78 | Applies coherent detail to candidate nodes and builds distance proxies; up to 8 workers |
| Route validation and shared-field setup | 1.12 | 1.13 | 5,642 passage samples; then shared primitive form |
| Far parents and bins | 55.56 | 55.57 | 6,050 far rooms / 18,348 links; 1 thread |
The compile extracts 18,348 owner primitives (71 rooms, 74 tunnels, 2 passages), covers 138,188,413 sign nodes, allocates 36.71 MiB of packed words and 263.57 MiB of proxy address capacity, and visits 214,538 detail candidates (6,098 flips).
For this SurfaceWorld fixture, the first LOD0 tile’s density queries take the native `Heightfield2D` path before packed-shape lookup. Far-parent shapes are not needed by that first tile. However, `World::generateTile` rejects requests until the full base shape is marked built, and `compileTileRegion` also requires that base shape. So the current API gates the near tile on the interval, detail, validation, and far-parent work even when that tile does not sample those arrays. Other recipes and fallback/query paths do use the analytic primitives and packed signs/proxies.
There is no seed-independent owner shape payload to cache at build time. The assembly plan is built from owner data; region pages also re-run owner primitive extraction, spatial-bin construction, and shared-field packing. Those immutable owner-derived structures are a possible per-world reuse target, but the measured short crossings below built no pages, so this run does not price that work.
## 3. Moving crossing
Hashing off, W12, same camera and already-streamed initial view. Region compile was called, but all entering fine keys were covered by the initial shape bounds; it built zero regions.
| Camera step | New tiles | LOD breakdown | Region compile | Tile work wall | Crossing total |
|---|---:|---|---:|---:|---:|
| 8 m | 144 | LOD2: 128, LOD3: 16 | 0.010 ms | 12.61 ms | 12.81 ms |
| 16 m | 288 | LOD0: 128, LOD1: 16, LOD2: 128, LOD3: 16 | 0.010 ms | 60.49 ms | 60.68 ms |
The 16 m crossing’s worker-time sum was 633 ms; its wall time was 60.5 ms. No plan or full shape compile repeated. A 24 m attempt terminated with `std::bad_alloc` after base shape compilation and before crossing metrics; the failing allocation site is unknown.
## 4. Ranked levers
| Rank | Lever | Upper bound from these measurements | Assessment |
|---:|---|---|---|
| 1 | Overlap near-tile work with shape compilation | 222.6 ms, 16.2% of 1.372 s whole-view-ready; first tile could start earlier by up to the compile time | Largest opportunity. Not built: tiles and region compilation currently require a fully built base shape. A safe version needs immutable partial-page publication and a wait before any tile reads an unfinished sign, proxy, primitive bin, or far field. |
| 2 | Defer far-parent construction until far tiles need it | 55.6 ms, at most 4.1% of whole-view-ready and 18.6% of the first-tile delay | Could improve spawn, but far and near paths share mutable spatial-bin state today. Needs separate immutable bins and a synchronized readiness state; no crossing benefit was measured. |
| 3 | Parallelize assembly-plan construction | 51.0 ms, at most 3.7% of whole-view-ready | Serial and seed/owner-specific. No safe deterministic parallel split was established. |
| 4 | Raise shape scheduler cap from 8 to 12 | About 121 ms currently lies in the two worker phases; ideal linear scaling saves about 40 ms (2.9% of whole-view-ready) | Below the 3% bar before overhead, and no crossing benefit. Not built. |
For any future partial or deferred build, hashes can fail if a tile observes a partially written sign/proxy array, if region publication races with tile lookup, or if shared bins change while a tile is sampling. The page must be immutable before publication; worker-count and timing tests must compare W1 with W12 and repeat W12. Any asynchronous result must also follow the Epoch/MPSC shutdown-drain rules.
## 5. Final-build timing and hashes
Five interleaved W12 runs, no hash. Pair values are `whole_view_ready / stream_wall` in seconds.
| Pair | L9 `7650abb` Clang | L10 Clang | Delta, ms |
|---:|---:|---:|---:|
| 1 | 1.336 / 1.050 | 1.346 / 1.060 | +10 / +10 |
| 2 | 1.351 / 1.062 | 1.365 / 1.073 | +14 / +11 |
| 3 | 1.359 / 1.073 | 1.374 / 1.083 | +15 / +10 |
| 4 | 1.363 / 1.077 | 1.375 / 1.081 | +12 / +4 |
| 5 | 1.387 / 1.089 | 1.372 / 1.092 | −15 / +3 |
| **Median** | **1.359 / 1.073** | **1.372 / 1.081** | **+13 / +8** |
The measurement-only candidate is +1.0% whole-view-ready and +0.7% stream median; this is no demonstrated speedup. Hashing was off for these timings.
Final rebuilt binaries passed SurfaceWorld and FloatingIslands seed-0 hash checks at W1, W8, and five W12 runs per compiler: Clang FP contraction off and GCC default. Every full-detail, whole-view, LOD0–8, and exact-query row matches the compiler-matched L9 baseline. Audit files: `Saved/Linux/l10_final_surface_hash_audit.txt` and `Saved/Linux/l10_islands_hash_audit.txt`.
| Recipe / scope | Density | Mesh | Payload | Topology |
|---|---|---|---|---|
| SurfaceWorld full detail | `0x0ee0579bd15cbbe4` | `0x32e5d4964d610fee` | `0x1932b96ee4b1d910` | `0x69743c6bad3447dc` |
| SurfaceWorld whole view | `0xc10697a8f48380c7` | `0xe75c9119a1498cd5` | `0x49a9a8d1835a6c8c` | `0xedcb23288b5e8724` |
| FloatingIslands full detail | `0x6d842d2878b08ef6` | `0x4b868a3184f08035` | `0x2cedf2236788752d` | `0xeac17d5e0cb5044a` |
| FloatingIslands whole view | `0x5be4d8cde79b2a76` | `0x96f75041f6861b3a` | `0x3700a516cc89d50c` | `0x6b99948d6eab4f21` |
Exact-query hashes also match: SurfaceWorld density `0xe4d4a8eb95b35933`, detail `0xefcba20c0c70c415`, collision `0xe604823a249029bf`; FloatingIslands density `0x61daded9c303becb`, detail `0xefcba20c0c70c415`, collision `0x84d37463be9b0573`.
## 6. Failed or retried runs
- One phase smoke omitted the explicit owner-data path and resolved it under `Standalone/bin/data`; reran with `Standalone/data/owner_world.json`.
- A no-camera phase smoke produced 2,370 tiles instead of the 2,553-tile fixture; discarded it and reran with the fixed camera.
- A malformed `--workers=w8` command exited during argument parsing; reran with numeric `--workers=8`.
- The first FloatingIslands matrix invocation omitted the three required streaming-mode switches. All 14 attempts exited before generation; corrected the command and all 14 final runs passed.
- The 24 m crossing attempt failed with `std::bad_alloc` as described above.
- The first hash-audit parser expected 13 rows; the actual audit contains 12 scopes. Corrected the parser and all final comparisons passed.
At spawn, the first tile starts about 300 ms after cold start, with roughly 223 ms in full shape compilation and 51 ms in the single-threaded plan; this round did not make that wait shorter. While moving, the 16 m crossing completed 288 entering tiles in about 61 ms and repeated no shape compile, so the measured delay was tile work rather than region setup.
## Orchestrator review (Claude)
- **Not committed:** the L10 telemetry code. It is +1.0% whole-view median with tracing off (4 of 5
pairs slower), and the rule is zero cost when off. Saved as `Saved/Linux/claude/l10-telemetry.patch`
(gitignored) for reuse; the tree is reset to `7650abb`.
- **Key finding, for L11:** the first SurfaceWorld tiles take the native `Heightfield2D` path and don't
read the cave shape, yet `World::generateTile` waits for the full base shape (~223 ms). A per-tile
readiness check (start tiles whose recipe path provably never touches shape arrays) is lever #1 in
safe form.
- **Open bug, for L11:** the 24 m crossing died with `std::bad_alloc` under the 6 GiB **address-space**
cap (`RLIMIT_AS`). That cap counts reservations, not resident memory; L10 also reports 263.57 MiB
of proxy address *capacity*. It is not yet known whether this is a real memory blow-up on larger
crossings or the cap counting reserved address space. L7's 32 m step also hit the 160M-node
interval bound.
@@ -0,0 +1,74 @@
# VoxelForge L11 — Linux report
## 24 m crossing crash
The crash is real. The original binary threw `std::bad_alloc` after base shape compilation with both 6 GiB and 16 GiB `RLIMIT_AS`; the 16 GiB run peaked at 476,128 KiB RSS and 1,542,284 KiB virtual size. The allocation trace identifies a 432,345,551,342,665,824-byte resize in `BuildSpatialBins`, reached from `BuildAnalyticRegion` during `World::compileTileRegion`. The crossing code had coalesced disjoint entering tiles into a large LOD rectangle and tried to allocate dense per-axis bins that the analytic fallback never reads. L10's 263.57 MiB figure is the proxies' reserved virtual capacity; RSS samples record resident usage separately.
Analytic regions now skip those dense bins and compile in world-aligned 128-voxel pages. Pages are built privately and published together; coordinate, `bad_alloc`, and size failures return errors before partial pages are published. On the final L11 binary, 24 m and 32 m both passed (16 pages each); 1,000 m passed with 2,260 entering keys, 72 pages, 63 ms region-build wall time, 700,232 KiB peak RSS, and 2,578,588 KiB peak virtual size. The fixed 24 m run peaked at 533,420 KiB RSS and 2,578,588 KiB virtual size. Crossing pages build no packed interval nodes (`lattice_nodes=0`) and do not expand the immutable base sign/proxy arrays; they add analytic primitive/bin data. `retainTileRegions` prunes pages outside the desired set. The largest empirically verified step is 1,000 m. Work follows the destination's entering tile set; once the old and new views are disjoint, its page count stays bounded by the active view as travel distance increases. Keys outside Core's signed 32-bit voxel range are rejected with `tile region coordinate is out of range` before page construction. The earlier L7 32 m / 160-million-node failure was the same unbounded region geometry.
| Step | Entering keys | Pages | Added interval nodes | Base proxy nodes / virtual capacity |
|---:|---:|---:|---:|---:|
| 24 m | 432 | 16 | 0 | 185,024 / 263.57 MiB |
| 1,000 m | 2,260 | 72 | 0 | 185,024 / 263.57 MiB |
## Shape readiness
`isTileShapeFree` accepts only LOD0 tiles whose padded mesh box maps to one valid SurfaceWorld plan, excludes FloatingIslands, plan features, routes, passages, edits, and overlaps with owner shape primitives or detail bounds. This covers the MC skirt and sample margin. Higher LODs are conservatively shape-dependent; the accepted path cannot use far parents. The native-only context is initialized without building sign arrays, proxies, owner primitive vectors, or spatial bins. Native sampling and classification paths check the padded bounds, reject unsupported fallbacks, and count any attempted shape-dependent read; tile generation then fails instead of returning a partial mesh.
The SurfaceWorld spawn view proved 27/27 near-ring tiles shape-free. A deliberately mis-marked distant tile `(0,0,100000,lod0)` reached the sampler and was rejected by the guard. After shape publication, native-only and full-shape generation matched all four hashes for all 27 tiles. Shape-dependent tiles waited for the release-published shape; tile jobs continue through the existing Epoch and MPSC result path, and published shape/page data is immutable. The FloatingIslands spawn proof accepted 0/27 tiles, so all waited for its shape. Slow-shape delay defaults to zero; audit and negative-control work is opt-in.
## No-hash timing pairs
Five interleaved W12 pairs, camera `0,-35,-487.94`, seed 0, Clang `-ffp-contract=off`, hashing off. Times are from process start. The L9 executable does not emit a first-tile completion event and starts tile workers only after shape compilation; its first-tile cell is therefore unavailable.
| Pair | First tile L9 / L11 | Near ring L9 / L11 | Whole view L9 / L11 |
|---:|---:|---:|---:|
| 1 | — / 153 ms | 343 / 166 ms | 1,439 / 1,429 ms |
| 2 | — / 160 ms | 424 / 173 ms | 1,526 / 1,447 ms |
| 3 | — / 145 ms | 347 / 163 ms | 1,447 / 1,443 ms |
| 4 | — / 146 ms | 353 / 170 ms | 1,457 / 1,449 ms |
| 5 | — / 153 ms | 376 / 173 ms | 1,478 / 1,464 ms |
| Median | — / 153 ms | 353 / 170 ms | 1,457 / 1,447 ms |
The delayed maximum-overlap W12 run held shape compilation for 1.5 s: first tile 133 ms, near ring 166 ms, shape ready 1.696 s. Shape-free and full-shape near-ring hashes matched, and whole-view, full-detail, per-LOD, and exact-query hashes matched the baseline.
## Hashes
All 28 configurations passed against L10's committed `b370908` baseline: SurfaceWorld and FloatingIslands, seed 0, W1/W8/W12, Clang `-ffp-contract=off` and GCC default, with five W12 repeats per compiler and recipe. Each run matched all 12 rows: full-detail, whole-view, nine LODs, and exact queries. The delayed-overlap run also matched.
| Recipe | Full-detail density / mesh / payload / topology | Whole-view density / mesh / payload / topology | Exact-query density & unclamped / detail / collision |
|---|---|---|---|
| SurfaceWorld | `0x0ee0579bd15cbbe4` / `0x32e5d4964d610fee` / `0x1932b96ee4b1d910` / `0x69743c6bad3447dc` | `0xc10697a8f48380c7` / `0xe75c9119a1498cd5` / `0x49a9a8d1835a6c8c` / `0xedcb23288b5e8724` | `0xe4d4a8eb95b35933` / `0xefcba20c0c70c415` / `0xe604823a249029bf` |
| FloatingIslands | `0x6d842d2878b08ef6` / `0x4b868a3184f08035` / `0x2cedf2236788752d` / `0xeac17d5e0cb5044a` | `0x5be4d8cde79b2a76` / `0x96f75041f6861b3a` / `0x3700a516cc89d50c` / `0x6b99948d6eab4f21` | `0x61daded9c303becb` / `0xefcba20c0c70c415` / `0x84d37463be9b0573` |
The per-LOD D/M/P/T rows match exactly in every configuration; the complete comparison is recorded in `Saved/Linux/l11_hash_audit.txt`.
## Failed and retried runs
- The 24 m reproduction failed with `std::bad_alloc` under both address-space caps (`l11-cross24-as6g.log`, `l11-cross24-as16g.log`); the allocation trace above isolated the oversized bin resize. Final-binary 24 m, 32 m, and 1,000 m reruns passed (`l11-final-cross-24m.log`, `l11-final-cross-32m.log`, `l11-final-cross-1000m.log`).
- The first readiness proof admitted 512 LOD0 keys (`l11-readiness-audit.log`, `l11-readiness-audit2.log`). Although the 27 near-ring equivalence check passed, distant owner-shape tiles changed the whole-view density hash. Tightening the proof to test owner primitive bounds reduced early admission to the 27 safe near-ring tiles and restored every hash (`l11-readiness-audit-final.log`).
- One rebuilt audit invocation omitted the owner JSON path and exited 2 before generation (`l11-readiness-audit-path-error.log`; `Standalone/bin/data/owner_world.json` was missing). It was rerun with `Standalone/data/owner_world.json` and passed.
- The required hash matrix and five timing pairs had no failed runs. All monitored run processes stayed below the 6,000,000,000-byte RSS ceiling; governor remained `powersave`.
The standalone Core/headless builds passed with Clang and GCC. The Unreal adapter change was source-reviewed but could not be built here because UnrealBuildTool/UnrealEditor are not installed on this Linux machine.
At spawn on SurfaceWorld, the near ring is ready at a 170 ms median versus 353 ms on L9, and the first L11 tile is ready at 153 ms median before shape publication; L9 gates tile work on shape compilation and does not report that milestone. For fast movement, destination-page work stays bounded through the tested 1 km crossing, while invalid Core coordinates return an error before allocation.
## Orchestrator review (Claude)
- **Re-run by me, 5 interleaved W12 pairs, no hashing.** Near ring (`neighborhood_ready`) L9
0.338/0.338/0.337/0.326/0.334 s vs L11 0.159/0.159/0.167/0.169/0.159 s (median 0.337 → 0.159 s,
−53%). Whole view 1.337 → 1.365 s median (+2.1%, 4 of 5 pairs slower): a small cost, accepted for a
2× faster spawn ring. W12 hash runs give density `c10697a8f48380c7`.
- **Crossings re-run by me on L11** (`--region-crossing --camera-step=S,0,0`): 24 m gives 432 tiles,
0.867 s wall, 10.05 worker-s, rc 0; 1,000 m gives 2,260 tiles, 5.90 s wall, 70.4 worker-s, rc 0. The L9
binary lacks the option, so the original crash rests on Luna's reproduction and allocation trace.
- **New finding, for L12:** the 24 m crossing costs ~23 ms of work per tile, against ~2 ms for L10's 16 m
crossing (288 tiles, 0.633 worker-s). Tiles outside the base shape bounds, served from analytic
region pages, look about 10× more expensive. That is a moving-player cost.
- **Concurrency read:** `World::compile` builds the shape privately, then sets `impl_->shape` and
`buildRequest` before a release store of `shapeReady`. Every shape reader acquire-checks
`shapeReady` first (short-circuit), and shape-free tiles use a private native-only context. Sound.
- **Unreal:** `Source/VoxelForge/Private/VoxelWorld.cpp` changed (compile outside the writer lock;
proven shape-free tiles start before `bReady`). It is NOT compiled here, so it must be built on the
owner's PC before it is trusted in game.
@@ -0,0 +1,62 @@
# VoxelForge L12 — Linux report
Governor stayed `powersave`. Builds and runs used CPUs 0–11, at most 12 jobs, a 6 GiB address-space cap, and RSS monitors. Clang and GCC builds passed; peak sampled RSS was 881 MiB for one GCC compiler process and 679 MiB for the 1 km crossing. The GCC build process group peaked at 4.35 GiB. No Unreal adapter files changed.
## LOD cost and change
The 24 m profile is like-for-like at LOD1 in the same SurfaceWorld crossing. L11 generated 160 LOD1 tiles: 32 base-shape tiles averaged 2.73 ms each, while 128 analytic-page tiles averaged 71.72 ms. Of the LOD1 worker time, 9.06 of 9.27 seconds went to the marching-cubes density grid; the page compiler added 15 ms and built no packed lattice nodes. The page route lacked the manifest input needed for the exact LOD1 block proofs. Across all 160 LOD1 tiles, the sample counter reported 5.64 million density samples, or 35,271 per tile.
Analytic pages now retain the immutable shared manifest for block classification while continuing to sample the legacy density field. The proof audit checked 27,479 blocks and 36,574,549 samples, with zero violations. On the plain 24 m profile, page-backed LOD1 fell to 5.60 ms per tile; all 160 LOD1 tiles reported 432,000 samples (2,700 per tile) and 435 ms in density-grid work. Base LOD1 tiles averaged 2.51 ms, so page tiles are now about 2.2× their base cost. No base-shape bounds changed; pages remain privately built, immutably published, and bounded, with 16 pages at 24/32 m and 72 at 1 km.
## Plain W12 crossings
Worker time is the sum across tile workers; per-tile values use that sum. L11 values are from the L11 executable and logs. L12 values include region compilation in wall time.
| Step | Tiles | L11 wall / worker-s / ms per tile | L12 wall / worker-s / ms per tile |
|---:|---:|---:|---:|
| 8 m | 144 | 0.038 s / 0.381 / 2.65 | 0.035 s / 0.360 / 2.50 |
| 16 m | 288 | 0.831 s / 9.476 / 32.90 | 0.125 s / 1.096 / 3.80 |
| 24 m | 432 | 0.869 s / 9.912 / 22.95 | 0.164 s / 1.596 / 3.69 |
| 32 m | 576 | 0.898 s / 10.261 / 17.81 | 0.172 s / 1.691 / 2.94 |
| 1 km | 2,260 | 5.892 s / 69.534 / 30.77 | 1.247 s / 14.003 / 6.20 |
All five L12 steps passed; peak crossing RSS was 679 MiB. The 8 m L11 comparison is `l12-baseline-8m-page.log`; 16 m is `l12-baseline-16m-page.log`; 24 m, 32 m, and 1 km are the L11 final crossing logs.
## Spawn and hashes
Three plain W12 spawn runs had medians of 146 ms first tile, 161 ms near ring, and 1.361 s whole view. L11 medians were 153 ms, 170 ms, and 1.447 s.
All 28 requested L1 hash configurations matched L11: SurfaceWorld and FloatingIslands seed 0, Clang `-ffp-contract=off` and GCC default, W1/W8/W12, with five W12 repeats. Every run matched all 12 rows: full detail, whole view, nine LODs, and exact queries. Clang/GCC full-detail and whole-view D/M/P/T plus exact-query values are unchanged from the L11 report. The L3 FP-contract preamble/self-test remains in place.
| Recipe | Full-detail density / mesh / payload / topology | Whole-view density / mesh / payload / topology | Exact density+unclamped / detail / collision |
|---|---|---|---|
| SurfaceWorld | `0x0ee0579bd15cbbe4` / `0x32e5d4964d610fee` / `0x1932b96ee4b1d910` / `0x69743c6bad3447dc` | `0xc10697a8f48380c7` / `0xe75c9119a1498cd5` / `0x49a9a8d1835a6c8c` / `0xedcb23288b5e8724` | `0xe4d4a8eb95b35933` / `0xefcba20c0c70c415` / `0xe604823a249029bf` |
| FloatingIslands | `0x6d842d2878b08ef6` / `0x4b868a3184f08035` / `0x2cedf2236788752d` / `0xeac17d5e0cb5044a` | `0x5be4d8cde79b2a76` / `0x96f75041f6861b3a` / `0x3700a516cc89d50c` / `0x6b99948d6eab4f21` | `0x61daded9c303becb` / `0xefcba20c0c70c415` / `0x84d37463be9b0573` |
The 24 m crossing hash also matches L11 at W1 and W12 (432 rows each): density `0x174588abdc8c0d2c`, mesh `0x4c401e27d9d05dea`, payload `0xeb10d9801c5ef125`, topology `0xf59d12304d0dcb4a`.
The route-verified base/page audit does **not** pass the requested exact-tile invariant. For `(0,-5,-31,lod1)`, the base density hash is `0xe0672dae7528f8d7` and page density hash is `0x882280f67bfddd77`; mesh, payload, and topology match. All 48 base-covered LOD1 candidates had density mismatches; 10 also differed in mesh/payload/topology. Across eight route-verified LOD0/LOD1 pairs, all eight density hashes differed. The base SurfaceWorld route uses manifest density while L11 pages use the legacy density evaluator; switching page samples to the base field would change the L11 crossing hashes. I kept the legacy page field to preserve the required crossing output, so this pre-existing parity conflict remains unresolved.
## Failed and retried runs
- An attempted 24 m base-shape expansion exited 2 at the 160-million-node bound (`l12-baseline-24m-base.log`). A separate per-tile native-only proof promotion failed with `region OOM` and was reverted (`l12-probe-cross24-profile-w12.log`).
- The first plain step command passed `32` as the camera distance while labeling it 8 m; output identified it as 32 m. It was retained as the 32 m result, and 8 m was rerun with the correct distance.
- The first FloatingIslands matrix omitted `--auto-surface-camera`, so it hashed the wrong 2,553-tile view. It was rerun with the L11 seed-0 island placement; all 28 corrected matrix configurations passed. The comparison helper also needed two small script fixes before it reported the final 28/28 result.
- One base/page audit initially treated a LOD2 base-route fallback (`page_keys=0`) as a match. The audit now verifies the generated route; that apparent pass was rejected and the route-verified parity failure above is the final result.
Walking into new ground should feel much better: the plain 24 m crossing fell from 0.869 s to 0.164 s, and the 1 km crossing from 5.892 s to 1.247 s. Page-backed LOD1 tiles are down from 71.7 to 5.6 ms each while the L11 crossing hashes stay exact; base/page density-hash parity remains a separate unresolved constraint.
## Orchestrator review (Claude)
- Re-run by me (W12, no hashing, 3 interleaved pairs): 24 m crossing L11 0.874/0.914/0.898 s vs L12
0.154/0.166/0.166 s (median 0.898 → 0.166 s, 5.4×). Spawn is unchanged (near ring 0.160–0.184 s).
The 24 m crossing hash (density `0x174588abdc8c0d2c`, mesh `0x4c401e27d9d05dea`) matches L11 at W1
and W12. Hash runs refill skipped samples, so time crossings with hashing off.
- **Soundness of page-tile skipping:** the proof audit figures (27,479 blocks / 36,574,549 samples)
are the base-shape audit from L9, not page tiles. The evidence for pages is the crossing hash
equalling L11 (which filled every sample). That is necessary but narrow: one crossing, one seed.
- ⚠️ **Route-dependent output (a pre-existing multiplayer bug, now measured):** the same tile key
gives different density from the base shape (manifest field) than from an analytic page (legacy
field). All 48 base-covered LOD1 candidates differed in density, 10 also in mesh/payload/topology.
A tile's geometry then depends on streaming history (spawned near it vs walked to it), which
breaks peer determinism. Top priority for L13.
@@ -0,0 +1,140 @@
# 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.
@@ -0,0 +1,157 @@
# Linux14 — far spawn work
No mesh or density code changed. The source changes add opt-in profiling for far-shell column
lookups; counter snapshots are behind the existing profile guard, with no added timing or counter
increments when profiling is off. The final plain build has the same output as L13.
## Far LOD cost and ranking
The first table is from five interleaved, W12, hashing-off pairs: L13 binary before and L14 binary
after. Values are median worker-sums across that LOD; per-tile time is the L14 median divided by
tile count. The ranking is L6, L8, L4, L5, L7 on both binaries.
| LOD | Tiles | L13 → L14 median worker-s (s) | L14 worker-ms/tile |
|---:|---:|---:|---:|
| 4 | 320 | 1.600 → 1.572 | 4.91 |
| 5 | 144 | 1.421 → 1.411 | 9.80 |
| 6 | 96 | 2.624 → 2.585 | 26.93 |
| 7 | 48 | 1.152 → 1.158 | 24.13 |
| 8 | 153 | 2.044 → 2.046 | 13.37 |
Phase detail below is one W12 `--profile-lod-work` run on the final Clang binary. Cache counters
include all column work for that LOD, not just refinement. A “shared hit” is a hit from the
world-shared cache; formula evaluations equal local misses minus shared hits.
| LOD | Calls | Local hits / misses | Shared hits | Formula evaluations (per tile) | Column compute (ms) | MC non-column (ms) | Ground/cap non-column (ms) | Connector shell non-column (ms) | Skirt (ms) | Assembly (ms) |
|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
| 4 | 1,845,787 | 1,579,868 / 265,919 | 175,805 | 90,114 (282) | 521 | 472 | 385 | 0 | 186 | 3 |
| 5 | 877,542 | 701,124 / 176,418 | 105,477 | 70,941 (493) | 408 | 135 | 705 | 0 | 159 | 2 |
| 6 | 760,952 | 418,443 / 342,509 | 63,209 | 279,300 (2,909) | 1,594 | 90 | 474 | 210 | 158 | 2 |
| 7 | 337,328 | 257,969 / 79,359 | 8,878 | 70,481 (1,468) | 395 | 59 | 514 | 0 | 145 | 4 |
| 8 | 644,565 | 508,799 / 135,766 | 29,545 | 106,221 (694) | 608 | 374 | 783 | 0 | 278 | 6 |
MC and refinement column-compute / non-column times (ms) were L4 `221/472` MC and `281/385`
ground/cap; L5 `199/135` MC and `209/705` ground/cap; L6 `196/90` MC and `205/474` ground/cap;
L7 `184/59` MC and `211/514` ground/cap; L8 `413/374` MC and `195/783` ground/cap. The column
compute column overlaps those column portions. Timers are worker sums and may differ by a few ms
from their subphase sums.
Stratum shells made zero field calls at LOD4–8 and took under 0.03 ms total. The profiler run
measured about 1.408 s whole-view-ready; the unprofiled interleaved runs below are the timing result.
## Connector-shell repair
`AppendFarConnectorShells` is guarded to LOD6 and above. Coarse marching cubes can leave gaps in a
route connector wall, so the repair checks four axial rays at connector stations and adds only the
panels where the nearest coarse-mesh hit misses the source-field radius tolerance. LOD6 checks at
128-voxel stations; LOD7–8 use 256-voxel stations. Only LOD6 had repair candidates in this spawn
view: 5,066 triangles were added. The shell took 1.403 worker-s, including 1.193 s of column
evaluation (about 0.210 s shell work outside those evaluations).
The LOD6 repair made 251,475 source/column calls: 44,596 worker-local hits, 206,879 local misses,
30 shared-cache hits, and 206,849 formula evaluations. Thus 82.3% of calls evaluated a formula;
the work is mostly uncached. A cache miss can include a point evicted by the four-way worker cache,
so these counters do not prove every evaluated XY is unique. The L13-bound base evaluator already
feeds the shared exact-XY cache; neighboring LOD samples mostly use different XY coordinates, and
only 30 repair samples hit the shared cache. Reducing stations or rays would change the repair
geometry, and no bit-identical reduction was proved.
## Ground and cap refinement
Ground refinement starts at LOD5 (32-voxel grid there, 64 at LOD6, then 128 at LOD7–8). Cap
refinement starts at LOD4 (16-voxel grid there, then 128 at LOD5–7; LOD8 may use its configured
interior override). Both query exact `Heightfield2D` columns and use those values for heights,
normals, materials, clipping, and replacing nearby coarse faces. The existing shared cache is keyed
by recipe/plan and exact XY, so aligned samples can already be reused across tiles and levels. The
LOD-wide shared-hit counts are in the table above; they are not refinement-only counts.
Current safe skips are the plan Z-range check for ground and the cap-height-bound check for caps.
No additional tile/cell skip was shown to preserve every sample that affects output; a grid point
can also supply a neighboring normal or clipped cell. No new refinement sharing or skip was built.
## Ranked exact-output work
No exact-output change with a measured saving above 3% was proved, so no geometry optimization was
built. The ranked work buckets are:
1. Ground/cap refinement across LOD4–8: about 3.95 worker-s including its column work. Removing all
of it would be an unrealistic idealized 23% of 1.419 s at 12-way division; the sampled values
currently affect geometry/materials/normals.
2. LOD6 connector repair: 1.403 worker-s inclusive, an idealized upper bound near 8.2% at 12-way
division. Most calls are uncached, and the missing panels are required for the current mesh.
3. Far-LOD column formula work: 3.53 worker-s across LOD4–8, overlapping the two buckets above.
Exact-XY sharing is already active; no redundant set large enough to remove was demonstrated.
4. Marching-cubes non-column work is 1.13 worker-s and skirts 0.93 worker-s. Assembly is only
0.017 worker-s; stratum shells are negligible. No exact reduction was established.
These idealized conversions divide worker-s by 12 and are not predicted wall-time gains. The L6
screen-space gate was not used because this round made no geometry change.
## Interleaved cost, builds, and hashes
Five hashing-off W12 pairs ran in one session, alternating
`Standalone/bin/linux/VoxelForgeCoreHeadless-linux13-clang` and
`Standalone/bin/linux/VoxelForgeCoreHeadless-linux14-clang`. Every run generated 2,553 tiles at
seed 0 and camera `0,-35,-487.94,0,-22`.
| Pair | L13 whole-view-ready (s) | L14 whole-view-ready (s) |
|---:|---:|---:|
| 1 | 1.416 | 1.410 |
| 2 | 1.436 | 1.388 |
| 3 | 1.416 | 1.424 |
| 4 | 1.429 | 1.419 |
| 5 | 1.430 | 1.426 |
Median was 1.429 s before and 1.419 s after (−0.7%, within this run spread). The telemetry is
opt-in; the plain run shows no measurable cost when off.
Final binaries `Standalone/bin/linux/VoxelForgeCoreHeadless-linux14-clang` and
`Standalone/bin/linux/VoxelForgeCoreHeadless-linux14-gcc` were rebuilt with `Standalone/BuildLinux.sh`,
`-j12`, CPUs 0–11, and a 6 GiB address-space cap: Clang 19 with FP contraction off and GCC 14 with
default contraction. Builds passed. Runtime peak RSS was 926,520 KiB; largest individual
build-process RSS was 901,968 KiB (GCC), with a 4,557,196 KiB process-group peak. Governor remained
`powersave`.
The final hash matrix passed 28/28: SurfaceWorld seed 0 and FloatingIslands seed 0, Clang/GCC,
W1/W8/W12, with five W12 repeats per recipe/compiler. Full-detail, whole-view, all nine per-LOD,
and exact-query rows match L13 exactly. Route parity also passed for SurfaceWorld seeds 0,
1, and 17 and FloatingIslands seed 0: page/native-only routes, edits, history, higher-LOD exact
queries, and proof checks had zero mismatches. The final 24 m crossing hash matched at W1/W12 on
both compilers: `0x337ca62131576728 / 0x7612f48e2ddbbaab / 0x69a67ed4add83b87 / 0xf11ac1ebd0f7ddb8`
(density/mesh/payload/topology).
| 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` |
Hash logs and the 28-row comparator are in `Saved/Linux/l14-final-hash-*.log` and
`Saved/Linux/l14-final-hash-audit.txt`. Final route logs are `Saved/Linux/l14-final-route-*.log`;
crossing and pair logs use the `l14-final-crossing-*` and `l14-final-cost-*` names.
## Failed or retried runs
- The first SurfaceWorld hash matrix and first crossing checks omitted the spawn camera and used the
headless origin. Their comparisons differed from L13; all 14 SurfaceWorld configurations and all
four crossing configurations were rerun with the spawn camera and passed. FloatingIslands used
its auto-surface camera and matched on the first run.
- The first route probes also used the wrong camera selection. A later seed-1 probe used the fixed
seed-0 camera, exited 9 on two LOD2 exact-query checks, and was rerun with `--auto-surface-camera`;
the corrected seed-1 and seed-17 audits passed. The origin-camera route probes returned success
but were not used as reference results.
- Clang was rebuilt after the connector counters were added and again after folding aggregation
into the existing opt-in guard. Both Clang builds and the final GCC build succeeded. No run hit
the RSS, 15-minute stuck-step, or 30-minute limits.
Owner note: the highest measured far cost is still LOD6 connector repair, but its formula work is
mostly uncached and its panels preserve the coarse route wall. The final interleaved plain runs show
no measurable diagnostic overhead; no geometry change or L6 budget claim is made.
## Orchestrator review (Claude)
- Accepted as a counting round. Interleaved W12, no hashing: L13 1.429 s vs L14 1.419 s median, so the
opt-in counters cost nothing measurable when off; committed with the report.
- Conclusion: exact-output far work has no remaining lever above 3%. The big buckets
(ground/cap refinement ~3.95 worker-s, LOD6 connector repair ~1.40 worker-s) produce visible
geometry. Further far savings need geometry changes, judged against today's same-LOD mesh within
the owner's budget (1 px at 1440p, at the LOD's closest display distance, display only).
@@ -0,0 +1,195 @@
# Linux15 report
## Result
Null result. No far-mesh shortcut passed the full 1 px, shading, swap, and topology gates, so no
recipe enables one by default. Evaluator version 6→7 adds the optional `far_display_mesh` declaration;
omitting it keeps the L14 output path. The controls are in the shared Core layer and do not touch
LOD0–2, exact queries, collision, edits, or server state.
Candidates measured:
- Refinement grid scale ×2 at LOD4, 5, 6, 7, and 8. The all-tile LOD4 and LOD5 runs reject; the
remaining per-LOD probes exceed 1 px or change shading, and the LOD6–8 candidates worsen at
least one adjacent swap.
- Reusing connector station radii leaves geometry p99 at 1.07 px but reaches 15.23 px maximum;
shading delta reaches 0.667 and the normal changes by 73.3°.
- Coarsening refinement at LOD4–8 is the largest measured saving, but exceeds the display budget.
Halving connector station density also saves time but opens gaps. Removing
any one ray direction also opens gaps, and the removed-panel control finds 99 new holes.
## Screen-space gate
The gate samples 65×65 surface grids across all 1,145 displayed LOD3–8 tiles (5,208,134 samples;
skirts excluded). Geometry is projected normal displacement against today's same-LOD mesh at its
closest display distance, using 90° horizontal FOV and 2,560 px (0.000613592 rad/px). Shading delta
is the maximum of fixed-light normalized Lambert change and material selector/blend-channel change;
the limit is 1/255. Each number below is p50/p99/max. Exact-path baseline values are all zero.
The gate rejects geometry max above 1 px, shading max above 1/255, any worse per-sample swap,
missing surface, or new hole/crack/floater. Its own validation fails if S13, stride-2, missing
surface, floating surface, missing fine-ring, or removed-panel controls are not rejected; the
panel control must expose at least one new connector hole.
| LOD | Tiles | Geometry px: baseline → refine×2 all | Shading delta: baseline → refine×2 all | Refine×2 holes / cracks / floating |
|---:|---:|---:|---:|---:|
| 3 | 384 | 0/0/0 → 0/0/0 | 0/0/0 → 0/0/0 | 0 / 0 / 0 |
| 4 | 320 | 0/0/0 → 0/2.370/606.562 | 0/0/0 → 0/0.023529/1 | 254 / 400 / 254 |
| 5 | 144 | 0/0/0 → 0/12.728/95.453 | 0/0/0 → 0/1/1 | 1,183 / 76 / 138 |
| 6 | 96 | 0/0/0 → 0.023/13.408/799.596 | 0/0/0 → 0/1/1 | 476 / 0 / 201 |
| 7 | 48 | 0/0/0 → 0/13.242/248.905 | 0/0/0 → 0/1/1 | 30 / 0 / 1 |
| 8 | 153 | 0/0/0 → 0.158/19.250/187.465 | 0/0/0 → 0.003922/1/1 | 45 / 0 / 946 |
The selected-patch swap report compares each baseline with refine×2 all. Values are p50/p99/max px.
| Swap (distance) | Before | After refine×2 all |
|---|---:|---:|
| 3→2 (96 m) | 0.611/3.767/6.045 | 0.611/3.767/6.045 |
| 4→3 (192 m) | 0.752/4.630/7.513 | 0.752/4.630/7.513 |
| 5→4 (384 m) | 0/9.580/31.783 | 2.435/32.321/86.615 |
| 6→5 (768 m) | 0/9.754/70.340 | 0.343/19.142/78.077 |
| 7→6 (1,536 m) | 0/9.040/42.355 | 0.200/15.109/50.994 |
| 8→7 (3,072 m) | 0.826/18.030/47.182 | 1.528/24.547/64.449 |
The station×2 LOD6 screen scan measures 0/2/813.571 px, shading 0/0/1, with 1,349 holes and 1,690
floaters. Its connector audit counts missing ray stations by stable tile/ray/station ID: holes 8→221
(216 new), floating classifications 464→405 (111 new IDs). In the refine×2 all row above, the
screen scan reports those all-tile holes, cracks, and floaters. Station×2 leaves all six selected-patch
swap p50/p99/max rows at baseline values, including 6→5 at 0/9.754/70.340 px. All four ray directions are required:
the four one-ray-removed
controls create 1,008, 1,022, 1,171, and 1,158 new holes. The explicit panel-removal control creates
99 new holes. The exact-path audit has zero new holes, cracks, or floating pieces; its raw connector
audit counts remain 8 holes and 464 pre-existing floating classifications.
The LOD4×2 and LOD5×2 candidates also fail in isolation. Reusing station radii misses the LOD6
geometry and shading limits. The four one-ray-removed masks add 1,008, 1,022, 1,171, and 1,158
connector holes, respectively.
## Negative controls
- The S13 global-octave-drop and stride-2 column-interpolation controls are rejected at every LOD3–8.
- Missing displayed surface, a floating surface, and missing fine-ring surface controls are rejected.
- Removing connector panels is rejected with 99 new holes. The exact connector path has zero new
station IDs classified as holes, cracks, or floaters.
## Speed
Five interleaved W12 pairs per candidate, hashing off, same 2,553-tile L1 view.
`whole_view_ready` is the metric. Both candidates fail the quality gate.
Station×2 connector stations:
| Pair | L14 baseline | Station×2 | Change |
|---:|---:|---:|---:|
| 1 | 1.320 s | 1.304 s | −1.2% |
| 2 | 1.363 s | 1.330 s | −2.4% |
| 3 | 1.371 s | 1.332 s | −2.8% |
| 4 | 1.393 s | 1.341 s | −3.7% |
| 5 | 1.391 s | 1.345 s | −3.3% |
| Median | 1.371 s | 1.332 s | −2.8% (3.3% median paired gain) |
Refinement grid scale ×2 at LOD4–8:
| Pair | L14 baseline | Refine×2 all | Change |
|---:|---:|---:|---:|
| 1 | 1.305 s | 1.164 s | −10.8% |
| 2 | 1.336 s | 1.177 s | −11.9% |
| 3 | 1.362 s | 1.169 s | −14.2% |
| 4 | 1.378 s | 1.178 s | −14.5% |
| 5 | 1.384 s | 1.190 s | −14.0% |
| Median | 1.362 s | 1.177 s | −13.6% (14.0% median paired gain) |
## Hashes and invariants
The undeclared/default recipe path matches L14. LOD0–2 density/mesh/payload/topology hashes:
| LOD | Density | Mesh | Payload | Topology |
|---:|---|---|---|---|
| 0 | `769f2a706d585a72` | `33eeeb39fa443816` | `645621a1d968983f` | `c2457ed905036c9d` |
| 1 | `69cc5a5c0a2c60af` | `b48335f5410c57d5` | `d15c5480162ab8ba` | `feca1bd025823604` |
| 2 | `85deed5683a77202` | `53469895987aeea2` | `e55f8ae7e1532033` | `d5feb12a0e85c09b` |
Exact queries (density / unclamped / detail / collision) remain
`e4d4a8eb95b35933 / e4d4a8eb95b35933 / efcba20c0c70c415 / e604823a249029bf`. The 24 m crossing's
432 moved tiles match L14 at W1/W12 with Clang off and GCC default:
`337ca62131576728 / 7612f48e2ddbbaab / 69a67ed4add83b87 / f11ac1ebd0f7ddb8` (D/M/P/T).
Its LOD0–2 per-LOD hashes also match the three rows above.
Determinism passed 28/28 configurations: SurfaceWorld seed 0 and FloatingIslands seed 0, Clang 19
FP-contract off and GCC 14 default, W1/W8/W12 and five W12 repeats. All per-LOD and whole-view
hashes match L14. L13 route parity passed for SurfaceWorld seeds 0, 1, and 17 and FloatingIslands
seed 0; page, native-only, higher-LOD, edit, and history mismatch counts are zero.
The L3 FP-contract preamble/self-test, L4 `FLazy`, L7 shared cache, L9/L12 proofs, L11 readiness and
crash fix, L13 route binding, and CLAUDE.md async rules remain in place. The evaluator and optional
recipe declaration are shared by all recipes. Builds and runs used CPUs 0–11, up to W12, normal
priority, 6 GiB address-space limits, and the unchanged `powersave` governor. Peak RSS was 904,400 KB
(GCC build); peak runtime RSS was 736,432 KB. No run exceeded the time or memory limits.
## Capture pairs
JPEGs are 1280×720 and each is under 74 KB. Before is L14; after is the rejected refinement×2
candidate applied at LOD4–8.
The L1 view uses `(0,-35,-487.94) m`, yaw 0°, pitch −22°. Horizon uses the same location at pitch −2°.
The mesa frame aims from the L1 location at the L6 mesa band (`(-472,-1432,-463.151) m` in the
gate) with yaw −161° and pitch 0.9°.
| View | Before | After refine×2 all |
|---|---|---|
| L1 camera | [l1-camera-before.jpg](captures/l1-camera-before.jpg) (59 KB) | [l1-camera-after-refineall.jpg](captures/l1-camera-after-refineall.jpg) (57 KB) |
| Horizon | [horizon-before.jpg](captures/horizon-before.jpg) (63 KB) | [horizon-after-refineall.jpg](captures/horizon-after-refineall.jpg) (60 KB) |
| LOD6 mesa rim | [lod6-mesa-rim-before.jpg](captures/lod6-mesa-rim-before.jpg) (74 KB) | [lod6-mesa-rim-after-refineall.jpg](captures/lod6-mesa-rim-after-refineall.jpg) (67 KB) |
## Failed and retried runs
- The first Clang build wrapper exited 127 because `/usr/bin/time` is absent; the direct Clang
`-ffp-contract=off` build succeeded. GCC 14 default also built successfully.
- A later sequential-build monitor was interrupted after Clang completed and before its GCC step
launched. Clang and GCC were rebuilt separately with the same compiler settings and 6 GiB cap.
- The first hash matrix omitted `--seed=0` and was discarded. A second FloatingIslands matrix used
the SurfaceWorld spawn camera; it was rerun with the L14 auto-surface camera. The corrected matrix
passed all 28 configurations.
- Initial SurfaceWorld route probes used no camera for seed 0 (the 2,370-tile bound), omitted
`--region-crossing` for seed 0 (shape compiler safety bound), and used the fixed seed-0 camera for
seed 1 (LOD2/exact-query parity mismatch; seed 17 was not run with that setup). They were rerun
with L14's camera selection and region-crossing option; all four final route audits passed. The
first 24 m crossing also omitted `--region-crossing` and exceeded the shape-build safety bound;
all four corrected compiler/worker combinations passed.
- The first connector audit compared aggregate counts. It was replaced with stable per-ray station
ID comparison before the final gate. The initial L4 selected-tile gate missed a changed tile; the
all-desired-tile coverage gate found and rejected it. The full-view gate is used in the table above.
- The first JPEG encoding pass did not set CPU affinity or an address-space cap. All six files were
re-encoded under CPUs 0–11 and the 6 GiB cap; sizes and pixels stayed the same.
- The first five speed pairs included screen-gate color capture on ordinary streaming tiles. That
diagnostic copy is now enabled only for gate runs; all five cost pairs were rerun and the table
above uses only the final logs. The final exact gate passed and station×2 remained rejected.
- No builds, captures, final audits, or cost runs timed out or breached their memory limits. The
intentional candidate rejections are listed above, not treated as infrastructure failures.
Evidence logs are in `Saved/Linux`: the final baseline and station×2 all-tile gates are
`l15-final-gatecolors-exact.log` and `l15-final-gatecolors-station2.log`; the best-payoff
refinement×2 all-tile gate is `l15-final-gatecolors-refineall.log`. Single-LOD refinement coverage is in
`l15-gate-alltiles-refine-l4x2.log` and `l15-gate-alltiles-refine-l5x2.log`. Single-LOD refinement
and connector-ray probes are `l15-gate-refine-l{x}x2.log`, `l15-gate-reuse.log`, and
`l15-gate-rays{14,13,11,7}.log`. Hash, route, and crossing evidence is in
`l15-final-hash-audit.txt`, `l15-final-route-*.log`, and `l15-final-crossing-24m-*.log`; final
station×2 speed pairs are `l15-final-speed-pair{1..5}-{before,after}.log`; refinement×2 pairs are
`l15-final-speed-refineall-pair{1..5}-{before,after}.log`.
## Note for the owner
The default far terrain stays the same because every measured reduction exceeded the 1 px geometry
or shading limit, worsened a swap, or opened holes. Refinement×2 across LOD4–8 saves 13.6% by the
median whole-view ratio, but creates hundreds-pixel errors and visible gaps, so the captures show it
for review only and it is not enabled.
## Orchestrator review (Claude)
- I looked at the LOD6 mesa-rim pair. After refine×2, the jagged crests are visibly smoothed, black
holes appear in the cap/ceiling, and a dark sliver shows on the left horizon. That confirms the
gate's rejection: the instrument is right this time, not the world.
- **Not merged into `assembler/world`:** the candidate knobs and the evaluator 6→7 bump add no default
output and would invalidate version stamps for nothing. The full L15 code (the extended gate with
shading, swap and connector-ID audits, and the candidate controls) is kept on side branch
`wip/l15-far-budget`. `assembler/world` stays at L14 code plus this report.
- Conclusion of L14+L15: far terrain has no exact or within-budget saving left with today's design. The
remaining far cost is the price of the current refinement and connector-repair geometry.
Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

@@ -0,0 +1,232 @@
# Linux16 — terrain cache design and Core prototype
This is a persistence feature. The measurements judge exactness, storage, and worker responsiveness;
first-time terrain generation remains a separate cost. The prototype is headless and opt-in. Unreal
integration remains for the owner's PC.
## Design
- **Cache identity.** Production keys should include a stable world ID; season ID and canonical
season-content hash; seed and RNG contract; recipe, plan, biome/manifest and owner-content hashes;
schema and `WorldAssemblyEvaluatorVersion` (6 here); tile coordinate and LOD; voxel size and tile
dimensions; generation options; material/payload-section schema; mesher contract; and a generator
build/FP-contract identity. Include a platform or compiler identity unless cross-build output has
been proven equivalent. Clang and GCC matched this round's full hash matrix, but that alone does
not make every future build interchangeable. Use canonical content hashes so whitespace or JSON
key order does not change the world identity.
- **Prototype identity.** The header and file name include the raw owner-snapshot hash, Core
configuration, recipe/plan/manifest hashes, seed, schema, evaluator, voxel size, tile size,
mesher/FP contract, generation-options hash, tile key and LOD. The edited-tile probe also includes
edit sequence and tile edit digest. The prototype uses 64-bit FNV for identity inputs and CRC32
for accidental file corruption. Production should use a 256-bit content hash and a stable world
ID; the prototype hashes are evidence machinery, not a security boundary.
- **Edits.** Keep the reusable cache pristine. On load, apply the authoritative versioned diff layer
in sequence, then build the edited render/collision result. A derived edited-tile cache, if useful,
must key on the last applied sequence and a digest of edits intersecting that tile. A newer edit
invalidates only derived entries for touched tiles; it leaves pristine entries valid. The edit
probe wrote and reread sequence 1 with digest `3cd5603ebf707d0c` and matched every array and hash.
- **Server.** Never accept a client's cached mesh or collision as authoritative. The server may use
its own locally generated cache for pristine meshes, then apply its ordered edit layer and build
collision from that result. Client cache contents never cross the network; only validated edits
do. A server restart can reuse its own cache after identity and payload validation.
- **Invalidation and verification.** Season/content, seed/RNG, recipe, plan, evaluator, generator,
mesher, FP, voxel-grid, LOD, options, or payload-schema changes select a different key. Evaluator
bump and edit-sequence bump were rejected by the prototype. A canonical uncompressed-payload hash
should be stored and verified at load; corruption or a mismatch is a cache miss, followed by
regeneration on a worker. The prototype verifies CRCs and structure on every load, compares the
complete mesh arrays and Core D/M/P/T hashes after every generated write/read, and regenerates a
deliberately corrupted cached tile. This proves the sampled write/read route; a file's own hash
cannot independently prove generator semantics on every later hit, so complete identity and
version discipline remain essential.
- **Stored data.** The prototype stores the final Core mesh: exact double positions/normals, float
UVs, RGBA, section/group counts, indices, skirt masks, density sample count, and D/M/P/T hashes.
This avoids remeshing on a hit and maps directly to future RMC sections. The indices and section
ranges can feed server-side collision construction after edits. Density/sign tiles offer more
freedom for future meshers but require meshing, materials, and collision work on load; density
sizes were not benchmarked here. Keep collision ownership server-side in either design.
- **Worker/smoothness path.** Cache reads, zlib decode, integrity checks, serialization, and writes
run in the existing headless Core tile worker/result route. The Unreal game thread was not
present on this machine; its later integration should submit cache work through the same worker
queue and return the ordinary tile result. The prototype uses that route for all recipes and
changes no recipe implementation. It exercises SurfaceWorld for cache round trips; the cache-off
matrix and route audits cover SurfaceWorld and FloatingIslands.
- **Read versus regenerate.** Track per-LOD generation and load/decode EWMA. If a demanded tile's
estimated read/decode time exceeds generation time, schedule generation directly; if an attempted
load fails, discard it and regenerate without blocking the result queue. Keep the same tile
priority and permit the previous coarser LOD to remain visible while work finishes. On this L1
set, warm read/decode averaged about 0.11 ms per LOD0 tile and 0.91–1.61 ms per LOD8/7 tile,
compared with 3.97 ms LOD0 and 12.89–24.24 ms LOD8/6 mesh generation in the instrumented fill.
- **Layout, crash safety, and eviction.** One file per tile under a world-content directory keeps
reads and eviction independent; the prototype has 2,553 L1 records and 2,986 touched records after
the 24 m crossing. It writes a same-directory `.tmp`, flushes and `fsync`s it, atomically renames
to `.vftile`, then syncs the directory. Readers only open final `.vftile` names and reject bad
lengths, versions, identities, CRCs, counts, indices, and padding. A crash before rename leaves a
non-loadable temp file. Production startup should remove old temp files. Use a global 2 GB cap
with an LRU index by last use, protect entries currently in use, reserve space under one lock,
evict oldest unpinned records before writes, and skip the write if space still cannot be made.
The prototype enforces the cap and skips writes when full; it does not implement LRU eviction.
Its 4 KiB padding enabled `O_DIRECT` measurements and can be removed in production buffered I/O.
## Compression measurements
Available system zlib headers/library (zlib 1.3.1) were linked with `-lz`. The existing zstd 1.5.7
CLI had no development headers, so it was tested as a per-tile CLI codec in LOD batches; its times
include one process start per LOD. No installs or system changes were made. All totals below cover
all 2,553 L1 tiles except Q16, whose first run had five route-audit tiles prepopulated before codec
sampling. Sizes are payload bytes; the lossless cache also has headers and per-file 4 KiB padding.
| Encoding | Total bytes | Relative to raw | Exact Core arrays? | L1 gate |
|---|---:|---:|---|---|
| Raw canonical mesh | 107,342,349 | 100% | Yes | Pass |
| zlib level 6 | 47,388,401 | 44.15% | Yes | Pass |
| zstd level 1 (CLI, per tile) | 46,513,479 | 43.33% | Yes | Pass; 1.85% smaller than zlib payload |
| Q16 positions + oct16 normals + delta-varint indices | 38,672,768 (2,548 tiles sampled) | 36.17% | No | Fail: 11.4482 px at LOD0; 6 degeneracy changes (2 at LOD4, 4 at LOD6) |
| Q24 positions + oct16 normals + delta-varint indices | 42,862,996 | 39.94% | No | Pass: 0.0458 px max, 0.000060 Lambert delta max, 0.00361° normal error max, no winding/degeneracy changes |
Q24 is about 9.5% smaller than zlib's payload, but it changes floating-point positions/normals and
cannot satisfy exact loaded-versus-regenerated hashes. The selected cache path is lossless zlib.
The zstd CLI decoded every tile byte-for-byte, and was modestly smaller/faster in this test. There
are no zstd development headers here, so it was not linked into the worker prototype. The L1 zlib
records occupied 55,685,120 bytes on disk, including record framing and page padding.
Per-tile size averages by LOD:
| LOD | Tiles | Raw B | zlib B | zstd B | Q16 B* | Q24 B |
|---:|---:|---:|---:|---:|---:|---:|
| 0 | 512 | 19,232.6 | 7,901.7 | 8,009.4 | 7,115.2 | 7,797.3 |
| 1 | 448 | 15,437.8 | 6,715.2 | 6,715.6 | 5,394.2 | 6,244.9 |
| 2 | 448 | 11,152.2 | 4,452.4 | 4,516.8 | 4,129.9 | 4,548.7 |
| 3 | 384 | 11,750.3 | 4,813.1 | 4,885.5 | 4,361.7 | 4,801.7 |
| 4 | 320 | 49,186.9 | 18,865.3 | 18,352.3 | 17,858.1 | 19,738.2 |
| 5 | 144 | 83,106.3 | 37,693.0 | 37,004.3 | 30,247.6 | 33,494.7 |
| 6 | 96 | 128,102.3 | 59,624.7 | 56,521.2 | 46,390.6 | 51,437.7 |
| 7 | 48 | 308,206.8 | 141,387.7 | 139,348.3 | 110,361.7 | 121,997.0 |
| 8 | 153 | 171,712.3 | 81,805.0 | 79,662.9 | 60,755.8 | 67,046.4 |
*Q16 averages are over the 2,548 newly generated tiles; five prepopulated tiles did not enter its
codec sample. Raw, zlib, and Q24 averages are from the clean 2,553-tile fill.
Average codec encode/decode time per tile, microseconds:
| LOD | Raw E/D | zlib E/D | zstd CLI E/D | Q24 mesh E/D |
|---:|---:|---:|---:|---:|
| 0 | 38.60 / 12.31 | 736.63 / 79.49 | 72.14 / 47.97 | 16.28 / 18.78 |
| 1 | 30.13 / 9.47 | 608.30 / 68.07 | 62.71 / 40.53 | 14.26 / 16.04 |
| 2 | 18.94 / 4.64 | 286.44 / 37.86 | 48.50 / 34.65 | 8.20 / 7.55 |
| 3 | 20.21 / 5.18 | 313.54 / 41.77 | 50.73 / 35.90 | 8.81 / 8.07 |
| 4 | 90.46 / 27.53 | 1,508.23 / 189.40 | 134.50 / 78.66 | 41.58 / 41.93 |
| 5 | 163.48 / 55.53 | 2,935.24 / 370.92 | 220.23 / 140.52 | 76.90 / 79.86 |
| 6 | 254.98 / 96.01 | 4,900.50 / 611.07 | 361.50 / 184.35 | 127.39 / 136.19 |
| 7 | 621.57 / 211.84 | 11,944.70 / 1,475.82 | 861.84 / 442.64 | 327.72 / 391.27 |
| 8 | 325.34 / 109.80 | 6,478.56 / 784.32 | 486.54 / 289.96 | 167.25 / 186.01 |
## Smoothness, prototype, and budgets
- A clean write generated, losslessly stored, reloaded, and exactly compared all 2,553 L1 tiles.
The whole-view D/M/P/T hash matched L14. The warm run hit 2,553/2,553 tiles, returned the same
hash, and reached whole-view-ready in 0.450 s including 0.193 s of shape setup; tile streaming
took 0.243 s.
- The 24 m crossing covered 432 entering tiles. Its D/M/P/T hash was
`337ca62131576728 / 7612f48e2ddbbaab / 69a67ed4add83b87 / f11ac1ebd0f7ddb8`, equal to L14.
The cache route audit passed 9 pristine pairs, one edited pair, and one movement-history pair,
all with exact arrays and zero D/M/P/T mismatches. The crossing fill generated and round-tripped
428 tiles; four had already been created by the route audit.
- Safety controls passed: evaluator bump rejected, edit-sequence bump rejected, a flipped compressed
payload byte rejected by record CRC, and a truncated file rejected by size validation. A separate
L1 run with one real tile corrupted regenerated that tile, hit the other 2,552, and restored the
exact L14 whole-view hash.
- `O_DIRECT` bypassed the kernel page cache for the 55,685,120-byte L1 record set: 0.269 s
(197.6 MiB/s). Buffered first touch was 0.0191 s and the repeat was 0.0126 s, but those passes
followed file writes/verification and were page-cache warm. No page cache was dropped; device
firmware may also cache blocks, so `O_DIRECT` is page-cache-cold evidence rather than proof of a
physical cold-device read. The ordinary worker hit path includes buffered read, zlib decode,
validation, and tile construction.
- The instrumentation measures raw, zlib, and mesh candidates on a miss, so its clean-fill
whole-view-ready time was 2.674 s versus 1.718 s for the hash-on no-cache L1 run. This includes
benchmark-only extra codec work. Production should encode only its selected lossless format on a
miss. Warm disk work and decode stay on workers; the first tile was ready in 0.226 s on fill and
0.208 s warm. These headless timings show worker completion; an Unreal frame-time check is still
for the integration round.
- The cache root peaked at 60,835,840 bytes after L1, the 24 m crossing, edit probe, and corruption
controls; the enforced limit is 2,000,000,000 bytes. No eviction was needed. The actual cache
implementation is a headless Core-worker prototype, not the Unreal plugin integration.
## Default-path cost and compatibility
Five interleaved W12 L1 pairs, hash off, 2,553 tiles each:
| Pair | L14 seconds | L16 cache-disabled seconds |
|---:|---:|---:|
| 1 | 1.450 | 1.446 |
| 2 | 1.464 | 1.457 |
| 3 | 1.458 | 1.453 |
| 4 | 1.525 | 1.472 |
| 5 | 1.459 | 1.483 |
Median: 1.459 s L14, 1.457 s L16, −0.14%; no measurable cache-off cost in this run.
All 28 L14 hash configurations passed (SurfaceWorld and FloatingIslands; Clang 19 FP off and GCC
14 default FP; W1/W8/W12 with five W12 repeats). Every one matched all 12 full-detail, whole-view,
nine LOD, and exact-query rows. The four default 24 m crossing checks (W1/W12 on both compilers)
matched all 13 rows, including the 432-tile crossing hash. Default route parity passed for both
compilers across SurfaceWorld seeds 0, 1, and 17 and FloatingIslands seed 0, using the existing
96 m history probe. The cache route passed its separate L1 and 24 m crossing audits.
Representative SurfaceWorld seed-0 hashes (D/M/P/T):
| View | Density / mesh / payload / topology |
|---|---|
| Full detail, 960 tiles | `0ee0579bd15cbbe4 / 32e5d4964d610fee / 1932b96ee4b1d910 / 69743c6bad3447dc` |
| Whole L1, 2,553 tiles | `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724` |
| LOD0, 512 tiles | `769f2a706d585a72 / 33eeeb39fa443816 / 645621a1d968983f / c2457ed905036c9d` |
| LOD1, 448 tiles | `69cc5a5c0a2c60af / b48335f5410c57d5 / d15c5480162ab8ba / feca1bd025823604` |
| LOD2, 448 tiles | `85deed5683a77202 / 53469895987aeea2 / e55f8ae7e1532033 / d5feb12a0e85c09b` |
| LOD3, 384 tiles | `6518caefb3be7e7f / ec513c90b853a614 / f62fa1137ff17f82 / ccf1dcf681965816` |
| LOD4, 320 tiles | `62d4be96021992f4 / f1e4c6efcc2615a9 / 9dc5f9c88be02f33 / fe6f55125a07c3bf` |
| LOD5, 144 tiles | `5e4a8c38b8cea6fc / 08ee56998aaf21e5 / 541eea8558f26cc8 / 6539374a8b3336d8` |
| LOD6, 96 tiles | `e036e95b9006945b / 624a33f941a99b02 / 81b73e14f68bdf86 / 4de4c63ce1f80a56` |
| LOD7, 48 tiles | `8ee358af56a30d8d / 46ab3c6184048b7c / 0a6164b7e68e80c5 / 0c26b85bb03bc831` |
| LOD8, 153 tiles | `c3458e1cbdb9c471 / 46c03d0994d75192 / 8f89fc5bde12d230 / d16dc0cf62031898` |
| Exact queries: density / unclamped / detail / collision | `e4d4a8eb95b35933 / e4d4a8eb95b35933 / efcba20c0c70c415 / e604823a249029bf` |
FloatingIslands full-detail was `6d842d2878b08ef6 / 4b868a3184f08035 / 2cedf2236788752d / eac17d5e0cb5044a`; whole-view was `5be4d8cde79b2a76 / 96f75041f6861b3a / 3700a516cc89d50c / 6b99948d6eab4f21`. Its exact-query hashes also matched L14: `61daded9c303becb / 61daded9c303becb / efcba20c0c70c415 / 84d37463be9b0573`.
## Runs and limits
- First Clang build was interrupted during a silent compile phase. The next build exposed a const
error in the prototype file index; making that index mutable fixed it. Final Clang and GCC builds
passed.
- The first L1 command used the binary's incorrect default data path (`Standalone/bin/data`) and
exited before writing. Supplying `Standalone/data/owner_world.json` passed.
- The first codec run sampled 2,548 tiles because route parity had prepopulated five; it was kept
for Q16 measurements. A clean fill then sampled all 2,553 Q24 tiles.
- A route wrapper first required a moving hash when hashing was disabled; the route audit itself
passed. Seed 17's 24 m history probe had no departed-tile candidate and failed on both L16 and
the L14 control. The same L14 96 m history setup passed on both L16 compilers. The required 24 m
crossing was separately checked and passed.
- The first crossing-hash comparator used an incorrect old-log filename; correcting the filename
let all four comparisons pass. No run exceeded 30 minutes or stalled for 15 minutes.
- Final review found that the cache-hit route audit's `exact_arrays` field initially reported hash
agreement without comparing the arrays themselves. The audit was changed to compare complete
arrays; after rebuilding, both L1 and 24 m crossing route audits passed with zero mismatches.
Runs used CPUs 0–11, at most 12 build jobs, a 6 GiB address-space cap, and normal priority. The
governor stayed `powersave`; peak sampled single-process RSS was 943,844 KiB (FloatingIslands route
audit, GCC). No installs, system changes, or page-cache drops were made. The L3 FP-contract preamble
and self-test, L4 `FLazy`, L7 shared cache, L9/L12 proofs, L11 readiness/crash fix, L13 route binding,
and async worker/result rules remain enabled. Cache logic is recipe-agnostic.
**Owner note:** Saving generated terrain works exactly and fits well under the round's disk cap.
Lossless zlib saved about 56% of the serialized payload. The smaller Q24 mesh encoding passed the
screen gate but changed exact hashes, so the feature should use the lossless record format.
## Orchestrator review (Claude)
- Design accepted: the key, the pristine cache plus ordered edits, a server that never trusts client
caches, corruption/stale rejection, lossless zlib, and atomic writes.
- **Not merged into `assembler/world`:** `Standalone/Source/StreamBenchmarkPipeline.h` (included by the
Windows viewer `StandaloneViewer.cpp`) now unconditionally includes `TileCachePrototype.h`, which
includes `<unistd.h>`, `<fcntl.h>` and `<zlib.h>`. That would break the MSVC build. Kept on side
branch `wip/l16-tile-cache`. Before merging, the prototype must be platform-guarded (or the cache
given a portable I/O and codec layer), and zlib needs a Windows source (UE ships zlib).
- Cache-off cost re-checked by Luna at −0.14% (within noise).
@@ -0,0 +1,26 @@
# Owner note — L17 FloatingIslands steps
The ledges were real generated mesh geometry caused by two boundary mistakes that made empty space
look like flat ground: the FloatingIslands seal was applied as a solid cap across XY, and owner
chunks were treated as 8 m of Core voxels instead of their actual 4 m. At the measured flat square,
the native island field is air and cave/floor influence is zero. The point is about 100 m from the
four islands.
I removed the false cap and corrected the shared owner/Core coordinate conversion. Evaluator version
is 7. The before/after captures show the false sheet disappear and the actual island shape remain.
SurfaceWorld’s L1 hash changes because it now selects its intended `Heightfield2D` route; its route,
readiness and proof audits pass.
The export has nonempty meshes at LOD0–8, and the standalone viewer enables and draws all levels by
default. I cannot identify the screenshot’s dark square as a whole missing LOD from the Linux data;
it may be a specific tile or viewer draw/upload issue. I did not change the Windows viewer. Please
capture the view below and, if the square remains, repeat with `--capture-only-lod=0` through `8`.
The low-view camera is `(-22,-19,-22.8) m`, yaw 0°, pitch −4°, matching the Linux island pair.
```bat
VoxelForgeCoreStandalone.exe --world-assembler-prototype --recipe=floating-islands --clip-radius=3 --max-clip-level=8 --workers=12 --camera=-22,-19,-22.8,0,-4 --capture=Standalone\Research\WorldAssemblerM3\Linux17\captures\floating-islands-windows.png --frame-limit=60
```
Use a different `--capture=` filename for each isolated LOD. Send the all-level image plus the
isolated image that corresponds to the square.
@@ -0,0 +1,182 @@
# VoxelForge L17 — FloatingIslands boundary report
Branch `assembler/world`, starting HEAD `9a7c87e`. No cache code was changed. The shared evaluator
version is now 7; the recipe schema stays at 1.
## Cause and fix
FloatingIslands uses the sparse `FloatingIslandFieldV1` manifest field. SurfaceWorld uses the
separate planar `Heightfield2D` field. The owner voxel is 12.5 cm and the Core voxel is 25 cm, so
one 32-voxel owner chunk is **16 Core voxels / 4 m**. Several shared paths divided Core positions
by 32 directly, treating that chunk as 8 m. That doubled stratum bounds, selected the wrong
generator route near the SurfaceWorld boundary, and made the legacy layer envelope extend over
empty FloatingIslands space.
The FloatingIslands `boundarySeal` also had been applied as a solid cap over all XY. At the owner’s
flat-square probe `(-11.612444,-118.221237) m`, the raw island field is air: at Z=3.25 m it was
`+81,809` subvoxels. The old seal added `−82,065`, yielding `−256` (`−1` Core voxel, or −25 cm);
at Z=3.50 m it yielded `−1` subvoxel (−0.098 cm), then air again at Z=3.75 m. The wrong 8 m
legacy layer bound produced a second false top near Z=8 m (old world density at 7.75 m was
−0.743 Core voxels; at 8 m it was +0.073). The owner’s 4.5 m LOD0 jump is real mesh geometry
created by those bad boundaries, often inside a tile; it is not a renderer artifact or island relief.
Nested clipmap rectangles made its placement look like a tile-boundary-only issue.
The fix uses the resolved owner/Core scale for manager lookups, layer bounds, readiness, and
adjacent native strata; removes the XY-wide FloatingIslands seal cap and its all-solid proof; and
clips adjacent native FI/SW signed-distance fields at their shared physical boundary. This is in
Core and applies to every generator route. SurfaceWorld still uses `Heightfield2D`.
The cave-floor lead does not match the samples. Cave and floor influence were exactly zero at the
flat square, the island center, and the sampled ledge/ring point. The native FI field and its island
or connector bounds account for the surface. The owner world compiled 70 rooms, 69 tunnels and 2
passages in this run; those legacy primitives do not contribute to the measured FI ledge.
## Before/after measurements
`RingProbe.py` samples upward-facing mesh surfaces on adjacent XY tile edges only when the tiles’
vertical bands overlap. Values are median / p95 / maximum absolute height difference, in cm. `n/a`
means this sparse-island export had no same-band LOD0↔1 surface pair after removing the false cap;
it is not a zero-error result. Higher rings include the deep SurfaceWorld boundary and other deep
surfaces, so those rows are not all FloatingIslands ground.
| LOD edge | Before (cm) | After (cm) |
|---|---:|---:|
| 0→1 | 3.451 / 8.920 / 449.158 (266 samples) | n/a (no same-band pair) |
| 1→2 | 26.642 / 148.262 / 149.862 (514) | 0 / 0 / 0 (234) |
| 2→3 | 0.134 / 198.730 / 773.318 (596) | 0 / 0 / 0 (207) |
| 3→4 | 3.269 / 47.875 / 188.531 (277) | 0 / 0 / 0 (288) |
| 4→5 | 29.975 / 130.496 / 445.444 (544) | 0 / 0 / 30.957 (258) |
| 5→6 | 12.234 / 127.224 / 536.573 (266) | 12.234 / 127.224 / 536.573 (266) |
| 6→7 | 29.013 / 301.752 / 42,624.479 (264) | 28.892 / 291.861 / 945.477 (264) |
| 7→8 | 83.843 / 1,225.416 / 3,755.407 (275) | 83.843 / 1,225.416 / 3,755.407 (275) |
The valid worst pre-fix LOD0↔1 sample is the false cap: 3.500 m vs 7.992 m, a 449.158 cm
difference. Upward-face within-tile span p95 / maximum changed from 4.490 / 4.491 m to 1.186 /
1.927 m on LOD0. The remaining LOD0 span is the actual island shape. LOD1–3 after-fix upward
faces at the measured lower boundary are exactly at −60 m. The island tops around the matched
camera are roughly −30 to −25 m.
A separate exploratory column comparison initially reported a 34.7 m difference by pairing an
island top near −25 m with a −60 m SurfaceWorld surface from a vertically disjoint tile. That
comparison was rejected: it is not a same-band ring seam. The saved `RingProbe.py` output is the
cross-LOD evidence used above.
## History, viewer and SurfaceWorld
Prebuilt L7, L9, L12, L13 and L14 binaries/logs all have the same legacy hashes: whole-view D/M/P/T
`92ba6a57a8690c00 / 9c6b56dfab6241c9 / 82394dd7c368a061 / 445e40bdb69b0bdb`; full-detail
`93ee3b6fb6b446f3 / 3ebc72d2027ab80b / cd5f55a96de12458 / 2f61c29af247b547`. The pattern
predates L7; these measurements show no output change at L9 or L13. S9 `e7586a1`, S12 `212814a`
and S14 `ec2afe9` do not contain the headless pipeline source, so they cannot be measured this way.
No old commit was rebuilt: `git worktree add` failed because `.git/worktrees` is read-only, and the
available old binaries were used as-is.
The headless mesh export has nonempty tiles at **all** LODs 0–8 (matched view counts:
15, 64, 40, 48, 48, 96, 48, 48, 153). The standalone viewer initializes all nine `bShowLevel`
flags to true and its draw loop visits all streaming batches. There is no evidence that a whole LOD
is absent from generated data or globally filtered by the viewer. The screenshot’s dark square
cannot be mapped to a particular tile/LOD from this Linux export; a localized viewer draw/upload
or camera issue remains unconfirmed. No viewer change was made because the Windows D3D11 build and
capture are unavailable here. The Unreal comparison does not identify the cause of that square.
SurfaceWorld L1 hashes changed for the shared coordinate fix. Old L14 LOD1 D/M/P/T was
`5043975b1e5b5a3d / 1c2a5658f10fdeaa / 23b6779ef35c3a0a / 1a6d2e2d152b4f84`; L17 is
`393ad79fd8c07132 / 47c9ba17e9f5ceaa / d5d6a948ac880e17 / 8b85ea08b2c440c4`. Before, readiness
was 0/27; now it is 27/27 on the near ring. The old mapping selected the wrong route at the
SurfaceWorld stratum; the corrected mapping selects its manifest `Heightfield2D` plan. Page/native
route parity and exact queries pass, so this is the intended shared-route output change.
## Gates, captures and limits
All 28 determinism rows passed: FI and SW, Clang 19 `-ffp-contract=off` and GCC 14 default,
W1/W8/W12 with five W12 repeats. Each recipe had one unique full, whole, nine-LOD and exact-query
hash tuple across all configurations. FI whole-view D/M/P/T is
`8339509b4d5ec231 / 70e5b2b9085b517c / 4e72e53745f20ed0 / 1a2643e5138e0407`; SW whole-view is
`b286ee4f4c38b7fc / 6862deb8ab9c2af9 / f23480a4953457f9 / 62977edfd04b3afe`.
FI route parity: 8 page pairs, 14 higher-LOD exact pairs, 782,026 exact samples, zero mismatches;
uniform proof: 19,288 blocks / 25,672,328 samples / zero violations. SW: 5 page and 9 native-only
pairs, 814,625 exact samples, zero mismatches; uniform proof: 13,297 blocks / 17,698,307 samples /
zero violations. Readiness negative controls were caught. The Clang FP-contraction-off and GCC
default builds passed; the Core startup FP self-test did not reject either. No async/MPSC/Epoch
code changed; `FLazy`, shared column caches, L9/L12 proof paths and L13 route binding remain in the
tested build.
Readable Linux capture mode adds directional light with soft ambient, gentle height tint, and an
optional faint tile-edge overlay. Five 1600×900 JPEGs, all below 300 KB, are in `captures/`:
- `floating-islands-flat-square-before.jpg` / `floating-islands-flat-square-after.jpg`: same owner
probe camera `(-11.6124,-118.2212,-19.8452) m`, yaw 0, pitch 0, before/after.
- `floating-islands-island-view-before.jpg` / `floating-islands-island-view-after.jpg`: same low
island camera `(-22,-19,-22.8) m`, yaw 0, pitch −4°, before/after.
- `surface-world-l1-readable-tiles.jpg`: SurfaceWorld L1 sanity view, camera `(0,-35,30) m`, yaw 0,
pitch −60°.
All are 1600×900 JPEGs; SHA256 is included for byte-level review.
| Capture | Bytes | SHA256 |
|---|---:|---|
| `floating-islands-flat-square-before.jpg` | 70,166 | `c41ed7645735ebefea97fbc1aed167b66a3e06c019c25b1c7d8cae9449713999` |
| `floating-islands-flat-square-after.jpg` | 47,612 | `f8fb5f937ac65be9db70a41473c7a10d7f35943ba6ef5c94ab03fde9ded5c544` |
| `floating-islands-island-view-before.jpg` | 70,813 | `5c7a8eda446f51a51ab22e45ed7286bf4180e69d8e3b2180780349facadacd32` |
| `floating-islands-island-view-after.jpg` | 51,429 | `3aeedef903fce62e81ea1f07bb460dd2beb42b893bbd9bf29220973951295b4c` |
| `surface-world-l1-readable-tiles.jpg` | 53,351 | `23f1753ed100c87607e22d2adc4f8e8a2856b8af3f1d37aa4f4cec9420a92b93` |
Clang/GCC compile peak RSS was 435,588 / 902,000 KiB. Determinism peak was 538,140 KiB; FI/SW
route-audit peaks were 621,404 / 763,112 KiB. The governor remained `powersave`; runs were limited
to CPUs 0–11, at most 12 workers, 6 GiB address space; llvmpipe used 12 threads.
## Failed or retried attempts
- The first headless invocation omitted the explicit owner-world input; it was rerun with
`Standalone/data/owner_world.json`.
- An initial SurfaceWorld export failed the native-only readiness guard; corrected owner/Core
mapping and rerun passed.
- A SurfaceWorld `--max-clip-level=1` attempt expanded to 35,435,983 tiles and failed the bounded
compiler (20.985 s, 3,988,160 KiB peak RSS). Retried with `--max-level=1` (960 tiles), which
passed.
- `BoundaryProbe.py` was first called with unsupported named Z arguments; rerun with positional
bounds passed.
- The first XY-only ring comparison mixed vertically disjoint surfaces; replaced by the
overlapping-band `RingProbe.py` used above. The exploratory column probe was also rejected for
pairing different vertical bands.
- The first offscreen SurfaceWorld command reversed scene/output arguments and failed to open the
mesh; rerun with the documented order passed.
- The first density-probe invocation used `Standalone/data/owner_world.json` without a resolved FI
manifest and failed. It was rerun with `Saved/Linux/l17-fi-owner-snapshot.json` and passed.
- `/usr/bin/time` was unavailable and an early process monitor mishandled a zombie child; the
process-tree monitor in `MeasureBuild.py` replaced both attempts.
- `git worktree add` could not write `.git/worktrees`; no worktree was created and no old commit was
built outside the repository.
- Mesa could not create `/home/jahni/.cache` in the read-only environment, disabled shader caching,
and completed all captures. No file was written outside the repository.
## Windows confirmation
Run from the repository root on Windows to capture the low island view:
```bat
VoxelForgeCoreStandalone.exe --world-assembler-prototype --recipe=floating-islands --clip-radius=3 --max-clip-level=8 --workers=12 --camera=-22,-19,-22.8,0,-4 --capture=Standalone\Research\WorldAssemblerM3\Linux17\captures\floating-islands-windows.png --frame-limit=60
```
For isolation, repeat with `--capture-only-lod=0` through `--capture-only-lod=8`, changing the
capture filename each time. Please send the all-level image and the isolated image matching the
dark square; those will identify whether it is a per-tile draw gap or a particular LOD payload.
## Orchestrator review (Claude) — NOT MERGED
- **The fix breaks SurfaceWorld.** I exported the L1 view (camera `0,-35,-487.94`) from L14 and from
L17 and rendered both in the new readable mode (`Saved/Linux/claude/sw/{before,after}-{l1,hz}.jpg`).
After L17, the ground under the spawn camera is gone (black void below), the terrain sits far
away, and the mesh export shrank from 58.7 MB to 31.7 MB. Halving the strate chunk size (8 m → 4 m)
moves and squashes every stratum: a world change, not a fix.
- **What the approved world uses:** the Core world the owner played and approved places strata
with 8 m chunks (32 Core voxels of 25 cm). The "owner chunk = 4 m" claim must be checked against
what the Unreal Core route actually does (`AVoxelWorld::CoreVoxelSizeCm`, the Core bridge,
`ResolvedWorldSnapshot`), not assumed.
- **Probably real and separable:** the FloatingIslands `boundarySeal` applied as a solid cap over all
XY (the false floors at 3.5/8 m). That needs its own minimal fix with SurfaceWorld unchanged.
- **Still open in FloatingIslands after the fix:** dark tile-aligned rectangles on the ground (the L17
"after" captures, lower left).
- Kept on side branch `wip/l17-fi-scale`. Only the capture tool's readable shading
(`LinuxOffscreenCapture.cpp`) is taken into `assembler/world`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

@@ -0,0 +1,9 @@
# L18 build resources
Limits: CPUs 0–11, `-j12`, normal priority, 6 GiB address-space cap. Governor stayed `powersave`.
These are the final builds after the cell-coverage and owner ceiling corrections.
- Clang 19, `-ffp-contract=off`: exit 0, 31.689 s, peak process RSS 436,088 KiB, peak VMS 586,240 KiB.
- GCC 14, default FP contraction: exit 0, 48.648 s, peak process RSS 903,168 KiB, peak VMS 1,014,716 KiB.
- Largest measured runtime process was the final Clang gate run at 897,276 KiB RSS. The determinism matrix peaked at 603,172 KiB and the crossing matrix at 548,664 KiB.
- An earlier GCC build was interrupted by owner steering before producing a binary; the final GCC build above completed successfully.
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
"""Render the matched L18 review views as small readable JPEGs."""
import os
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
CAPTURE = ROOT / "Standalone/bin/linux/VoxelForgeOffscreenCapture-linux18-clang"
EXPORTS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux18/exports"
OUT = ROOT / "Standalone/Research/WorldAssemblerM3/Linux18/captures"
LOGS = ROOT / "Saved/Linux"
OUT.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(ROOT / "Saved/Linux/mesa-cache")
views = [
("floating-islands-flat-square-after", "floating-islands-flat-square.vfmesh",
(-11.612444, -118.221237, -19.8452), 0, 0, True),
("floating-islands-flat-square-no-edges", "floating-islands-flat-square.vfmesh",
(-11.612444, -118.221237, -19.8452), 0, 0, False),
("floating-islands-island-view-after", "floating-islands-island-view.vfmesh",
(-22, -19, -22.8), 0, -4, True),
("floating-islands-ceiling-up", "floating-islands-island-view.vfmesh",
(-22, -19, -22.8), 0, 80, True),
("surface-world-l1-spawn-after", "surface-world-l1-spawn.vfmesh",
(0, -35, -487.94), 0, -22, False),
("surface-world-horizon-after", "surface-world-l1-spawn.vfmesh",
(0, -35, -487.94), 0, 0, False),
]
for name, scene_name, camera, yaw, pitch, tile_edges in views:
scene = EXPORTS / scene_name
png = LOGS / f"l18-{name}.png"
jpg = OUT / f"{name}.jpg"
render_log = LOGS / f"l18-{name}-render.log"
convert_log = LOGS / f"l18-{name}-jpeg.log"
command = [str(CAPTURE), str(scene), str(png), "--size=1600x900",
"--shade=readable", f"--tile-edges={'on' if tile_edges else 'off'}",
"--tile-edge-width-m=0.15", "--camera-m="+",".join(map(str, camera)),
f"--yaw-deg={yaw}", f"--pitch-deg={pitch}"]
with render_log.open("w", encoding="utf-8") as stream:
subprocess.run(command, cwd=ROOT, env=env, stdout=stream,
stderr=subprocess.STDOUT, check=True)
ffmpeg = ["ffmpeg", "-nostdin", "-hide_banner", "-loglevel", "error", "-y",
"-i", str(png), "-frames:v", "1", "-q:v", "4", str(jpg)]
with convert_log.open("w", encoding="utf-8") as stream:
subprocess.run(ffmpeg, cwd=ROOT, env=env, stdout=stream,
stderr=subprocess.STDOUT, check=True)
if jpg.stat().st_size > 300_000:
raise SystemExit(f"{jpg.name} exceeds the 300 KB review limit")
print(f"[Capture] {jpg.relative_to(ROOT)} bytes={jpg.stat().st_size} status=PASS")
@@ -0,0 +1,165 @@
#!/usr/bin/env python3
"""Audit the emitted FloatingIslands roof faces and same-LOD tile-edge continuity."""
import array
import collections
import math
import struct
import sys
def read_exact(stream, size):
data = stream.read(size)
if len(data) != size:
raise EOFError(f"wanted {size} bytes, got {len(data)}")
return data
def height_at(triangles, x, y, preferred_z):
best = None
for (x0, y0, z0), (x1, y1, z1), (x2, y2, z2) in triangles:
den = (y1-y2)*(x0-x2)+(x2-x1)*(y0-y2)
if abs(den) < 1.0e-10:
continue
a = ((y1-y2)*(x-x2)+(x2-x1)*(y-y2))/den
b = ((y2-y0)*(x-x2)+(x0-x2)*(y-y2))/den
c = 1.0-a-b
if min(a,b,c) >= -1.0e-5:
z = a*z0+b*z1+c*z2
if best is None or abs(z-preferred_z) < abs(best-preferred_z):
best = z
return best
def quantile(values, fraction):
if not values:
return math.nan
ordered = sorted(values)
return ordered[math.floor(fraction*(len(ordered)-1))]
if len(sys.argv) != 3:
raise SystemExit("usage: CeilingContinuity.py scene.vfmesh expected-cap-plane-metres")
scene_path = sys.argv[1]
root_z = float(sys.argv[2])
tiles = {}
voxel_size_m = None
with open(scene_path, "rb") as stream:
if read_exact(stream, 8) != b"VFMSH001":
raise SystemExit("invalid VFMSH001 scene")
version, voxel_um, tile_count = struct.unpack("<3I", read_exact(stream, 12))
camera = struct.unpack("<3d", read_exact(stream, 24))
yaw, pitch = struct.unpack("<2d", read_exact(stream, 16))
voxel_size_m = voxel_um/1_000_000.0
for _ in range(tile_count):
key = struct.unpack("<4i", read_exact(stream, 16))
surface_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack(
"<5I", read_exact(stream, 20))
positions = array.array("f")
positions.frombytes(read_exact(stream, vertex_count*12))
normals = array.array("f")
normals.frombytes(read_exact(stream, vertex_count*12))
indices = array.array("I")
indices.frombytes(read_exact(stream, index_count*4))
masks = read_exact(stream, mask_count)
if sys.byteorder != "little":
positions.byteswap()
normals.byteswap()
indices.byteswap()
extent = 32*(1 << key[3])*voxel_size_m
z0, z1 = key[2]*extent, (key[2]+1)*extent
ceiling = []
for triangle in range(index_count//3):
if masks and masks[triangle] != 0:
continue
a,b,c = indices[triangle*3:triangle*3+3]
if max(a,b,c) >= surface_vertices:
continue
nz = (normals[a*3+2]+normals[b*3+2]+normals[c*3+2])/3.0
if nz > -0.65:
continue
points = tuple((positions[v*3],positions[v*3+1],positions[v*3+2])
for v in (a,b,c))
center_z = sum(point[2] for point in points)/3.0
if abs(center_z-root_z) <= 1.0:
ceiling.append(points)
tiles[key] = {
"extent": extent, "x0": key[0]*extent, "y0": key[1]*extent,
"x1": (key[0]+1)*extent, "y1": (key[1]+1)*extent,
"z0": z0, "z1": z1, "ceiling": ceiling,
}
by_lod = collections.defaultdict(dict)
for key, tile in tiles.items():
if tile["z0"] <= root_z+1.0 and tile["z1"] >= root_z-1.0:
by_lod[key[3]][key] = tile
print(f"scene={scene_path} version={version} voxel_um={voxel_um} tiles={tile_count} "
f"camera_m={camera} yaw={yaw} pitch={pitch} expected_cap_m={root_z:.9f}")
print("lod zband_tiles cap_tiles missing_tiles cap_triangles face_z_m_p05/median/p95 "
"tile_samples hit_samples max_abs_root_delta_cm shared_edges shared_hits edge_gaps "
"edge_delta_cm_median/p95/max")
all_pass = True
for lod in range(9):
target = by_lod[lod]
cap_tiles = {key: tile for key,tile in target.items() if tile["ceiling"]}
face_z = [point[2] for tile in cap_tiles.values() for tri in tile["ceiling"]
for point in tri]
deltas = []
sample_count = 0
hit_count = 0
for key,tile in target.items():
if not tile["ceiling"]:
continue
for iy in range(16):
for ix in range(16):
x = tile["x0"]+(ix+0.5)*tile["extent"]/16
y = tile["y0"]+(iy+0.5)*tile["extent"]/16
sample_count += 1
height = height_at(tile["ceiling"],x,y,root_z)
if height is not None:
hit_count += 1
deltas.append(abs(height-root_z)*100.0)
edge_deltas = []
edge_count = 0
edge_gaps = 0
for key,a in cap_tiles.items():
x,y,z,level = key
for neighbor_key,axis in (((x+1,y,z,level),"x"),((x,y+1,z,level),"y")):
b = cap_tiles.get(neighbor_key)
if b is None:
continue
edge_count += 1
epsilon = min(0.02,a["extent"]*1.0e-4)
matched = 0
for index in range(33):
t = (index+0.5)/33
if axis == "x":
fixed = a["x1"]
varying = a["y0"]+(a["y1"]-a["y0"])*t
za = height_at(a["ceiling"],fixed-epsilon,varying,root_z)
zb = height_at(b["ceiling"],fixed+epsilon,varying,root_z)
else:
fixed = a["y1"]
varying = a["x0"]+(a["x1"]-a["x0"])*t
za = height_at(a["ceiling"],varying,fixed-epsilon,root_z)
zb = height_at(b["ceiling"],varying,fixed+epsilon,root_z)
if za is not None and zb is not None:
edge_deltas.append(abs(za-zb)*100.0)
matched += 1
if matched == 0:
edge_gaps += 1
missing = len(target)-len(cap_tiles)
max_root = max(deltas) if deltas else math.nan
print(f"{lod} {len(target)} {len(cap_tiles)} {missing} "
f"{sum(len(tile['ceiling']) for tile in cap_tiles.values())} "
f"{quantile(face_z,.05):.6f}/{quantile(face_z,.5):.6f}/{quantile(face_z,.95):.6f} "
f"{sample_count} {hit_count} {max_root:.3f} {edge_count} {len(edge_deltas)} "
f"{edge_gaps} {quantile(edge_deltas,.5):.3f}/{quantile(edge_deltas,.95):.3f}/"
f"{max(edge_deltas) if edge_deltas else math.nan:.3f}")
if lod >= 4 and target and (missing or hit_count != sample_count or edge_gaps):
all_pass = False
print(f"[CeilingContinuity] result={'PASS' if all_pass else 'FAIL'} "
"criteria=LOD4-8 requested z-band tiles emit an upper-boundary ceiling; 16x16 ray samples hit; "
"shared same-LOD tile edges have paired hits")
raise SystemExit(0 if all_pass else 1)
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
"""Compare all L18 crossing configurations to the L14 24 m crossing hashes."""
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
RUNS = ROOT / "Saved/Linux/l18-crossing"
PATTERN = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
failed = []
logs = sorted(RUNS.glob("*-w*-r*.log"))
for path in logs:
parts = path.stem.split("-")
compiler = parts[0]
reference_compiler = "clang" if compiler == "clang" else "gcc"
reference_path = ROOT / f"Saved/Linux/l14-final-crossing-24m-{reference_compiler}-w12.log"
expected = PATTERN.findall(reference_path.read_text(encoding="utf-8"))
actual = PATTERN.findall(path.read_text(encoding="utf-8", errors="replace"))
if actual != expected:
failed.append(path.name)
print(f"[CrossingReferenceMismatch] {path.name} expected_rows={len(expected)} "
f"actual_rows={len(actual)}")
print(f"[CrossingSurfaceHashGate] reference=L14-final-crossing-24m-W12 rows={len(logs)} "
f"result={'FAIL' if failed else 'PASS'}")
raise SystemExit(1 if failed or len(logs) != 14 else 0)
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
"""Compare every L18 SurfaceWorld matrix hash row with the approved L14 reference."""
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
RUNS = ROOT / "Saved/Linux/l18-matrix"
REFERENCE = ROOT / "Saved/Linux/l14-final-hash-sw-clang-off-w12-r5.log"
PATTERN = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
expected = PATTERN.findall(REFERENCE.read_text(encoding="utf-8"))
if not expected or len(expected) != 12:
raise SystemExit(f"invalid L14 reference hash rows: {len(expected)}")
logs = sorted(RUNS.glob("surface-world-*.log"))
if len(logs) != 14:
raise SystemExit(f"expected 14 SurfaceWorld matrix logs, found {len(logs)}")
failed = []
for path in logs:
actual = PATTERN.findall(path.read_text(encoding="utf-8", errors="replace"))
if actual != expected:
failed.append(path.name)
print(f"[SurfaceHashMismatch] {path.name} expected={len(expected)} actual={len(actual)}")
print(f"[SurfaceHashGate] reference={REFERENCE.name} rows={len(logs)} expected_rows=14 "
f"result={'FAIL' if failed else 'PASS'}")
raise SystemExit(1 if failed else 0)
@@ -0,0 +1,149 @@
#include "Json.h"
#include "OwnerWorldLoader.h"
#include "StandaloneCoreScheduler.h"
#include "WorldAssemblyPrototype.h"
#include "StandaloneSnapshotAdapter.h"
#include <cmath>
#include <cstdio>
#include <fstream>
#include <iterator>
#include <memory>
#include <string>
namespace
{
constexpr double CoreVoxelsPerMeter=4.0;
constexpr std::int64_t SubvoxelsPerCoreVoxel=
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
void PrintDensity(VoxelForgeCore::World& World,const char* Label,double X,double Y,double Z)
{
const VoxelForgeCore::Vec3d Point{X*CoreVoxelsPerMeter,Y*CoreVoxelsPerMeter,
Z*CoreVoxelsPerMeter};
const double Density=World.densityAt(Point);
const double Raw=World.unclampedDensityAt(Point);
std::printf("[DensitySample] label=%s xyz_m=%.6f,%.6f,%.6f density_core_vox=%.9f "
"density_cm=%.4f unclamped_core_vox=%.9f sign=%s\n",Label,X,Y,Z,Density,
Density*25.0,Raw,Density<0.0?"solid":"air");
}
void PrintCrossing(VoxelForgeCore::World& World,const char* Label,double X,double Y,
double BottomM,double TopM)
{
const auto DensityAt=[&](double Z)
{
return World.densityAt({X*CoreVoxelsPerMeter,Y*CoreVoxelsPerMeter,
Z*CoreVoxelsPerMeter});
};
double Lo=BottomM,Hi=TopM;
double LoDensity=DensityAt(Lo),HiDensity=DensityAt(Hi);
if((LoDensity<0.0)==(HiDensity<0.0))
{
std::printf("[DensityCrossing] label=%s bracket_m=%.6f..%.6f signs=%s/%s result=none\n",
Label,Lo,Hi,LoDensity<0.0?"solid":"air",HiDensity<0.0?"solid":"air");
return;
}
for(int Iteration=0;Iteration<64;++Iteration)
{
const double Mid=(Lo+Hi)*0.5;
const double MidDensity=DensityAt(Mid);
if((MidDensity<0.0)==(LoDensity<0.0))
{Lo=Mid;LoDensity=MidDensity;}
else
{Hi=Mid;HiDensity=MidDensity;}
}
std::printf("[DensityCrossing] label=%s z_m=%.9f bracket_m=%.6f..%.6f "
"density_core_vox=%.9f/%.9f\n",Label,(Lo+Hi)*0.5,BottomM,TopM,
LoDensity,HiDensity);
}
}
int main(int argc,char** argv)
{
if(argc!=2)
{
std::fprintf(stderr,"usage: %s owner-world.json\n",argv[0]);
return 2;
}
VFJson::Value Root;
std::string Error;
{
std::ifstream Input(argv[1],std::ios::binary);
if(!Input){std::fprintf(stderr,"owner JSON open failed\n");return 2;}
std::string Text{std::istreambuf_iterator<char>(Input),std::istreambuf_iterator<char>{}};
if(!VFJson::Parser(std::move(Text)).Parse(Root,Error))
{std::fprintf(stderr,"owner JSON parse failed: %s\n",Error.c_str());return 2;}
}
if(!StandaloneWorldAssemblyPrototype::SelectTopStrateAsFloatingIslands(Root,Error))
{std::fprintf(stderr,"FI selection failed: %s\n",Error.c_str());return 2;}
auto Owner=std::make_shared<FStandaloneOwnerWorld>();
if(!StandaloneOwnerLoader::Resolve(Root,*Owner,Error))
{std::fprintf(stderr,"owner resolve failed: %s\n",Error.c_str());return 2;}
VoxelForgeCore::WorldAssemblyManifest Assembly;
if(!StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype(
*Owner,Root,Error,{},&Assembly)
||!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly(
*Owner,Root,Assembly,Error))
{std::fprintf(stderr,"plan construction failed: %s\n",Error.c_str());return 2;}
auto Snapshot=VoxelForgeCore::MakeStandaloneSnapshotFromParsedJson(Root,Owner->Seed,3,8,
false,false,Error);
if(!Snapshot)
{std::fprintf(stderr,"snapshot resolve failed: %s\n",Error.c_str());return 2;}
const auto* ResolvedAssembly=Snapshot.worldAssembly();
if(!ResolvedAssembly||ResolvedAssembly->floatingIslands.empty())
{std::fprintf(stderr,"resolved FloatingIslands plan missing\n");return 2;}
VoxelForgeCore::World World(std::move(Snapshot));
VoxelForgeCore::ShapeBuildRequest Request;
Request.minVoxel={-96,-512,-288};
Request.maxVoxel={96,96,64};
Request.clipMinVoxel=Request.minVoxel;
Request.clipMaxVoxel=Request.maxVoxel;
Request.workerLimit=12;
Request.includeFarWorld=false;
FStandaloneCoreScheduler Scheduler;
if(!World.compile(Request,Scheduler,Error))
{std::fprintf(stderr,"shape compile failed: %s\n",Error.c_str());return 2;}
const auto& Plan=ResolvedAssembly->floatingIslands.front();
const auto& Recipe=Plan.manifest.recipe;
std::printf("[FloatingIslandBounds] geometry_version=%u owner_voxel_um=%u core_voxel_um=%u "
"owner_to_core=%u/%u chunks=%d..%d layout_z_m=%.6f..%.6f ceiling_start_m=%.6f "
"seal_m=%.6f bottom_cap=%s\n",Recipe.geometryVersion,Recipe.ownerVoxelSizeMicrons,
Recipe.coreVoxelSizeMicrons,Recipe.ownerToCoreScaleNumerator,
Recipe.ownerToCoreScaleDenominator,Plan.topChunkZ,Plan.bottomChunkZ,
static_cast<double>(Recipe.layoutMinimumZSubvoxels)/SubvoxelsPerCoreVoxel/4.0,
static_cast<double>(Recipe.layoutMaximumZSubvoxels)/SubvoxelsPerCoreVoxel/4.0,
static_cast<double>(Recipe.layoutMaximumZSubvoxels-Recipe.boundarySealSubvoxels)
/SubvoxelsPerCoreVoxel/4.0,
static_cast<double>(Recipe.boundarySealSubvoxels)/SubvoxelsPerCoreVoxel/4.0,
Recipe.geometryVersion<3?"legacy":"removed");
std::printf("[DensityProbe] flat_square_xy_m=-11.612444,-118.221237 "
"compiled=%d core_voxel_size_cm=25\n",World.isCompiled()?1:0);
constexpr double X=-11.612443923950195;
constexpr double Y=-118.22123718261719;
for(double Z:{2.75,2.99,3.00,3.01,3.25,3.49,3.50,3.51,3.75,3.99,4.00,4.01,
4.05,4.125,4.25,4.50,5.00,
7.75,8.00,8.25,-60.25,-60.00,-59.75,-59.50,-59.25})
PrintDensity(World,"flat-square",X,Y,Z);
PrintCrossing(World,"shared-upper-ceiling",X,Y,3.50,3.75);
PrintCrossing(World,"upper-boundary-cap",X,Y,4.00,4.25);
PrintCrossing(World,"old-eight-metre-wrapper",X,Y,7.75,8.25);
PrintCrossing(World,"removed-lower-boundary-seal",X,Y,-60.25,-59.75);
for(const auto& Probe:std::array<std::array<double,2>,3>{{
{{-66.3,-38.7}},{{-62.3,-54.6}},{{-53.34,-22.84}}}})
{
std::printf("[DensityProbeXY] xy_m=%.3f,%.3f\n",Probe[0],Probe[1]);
for(double Z:{3.49,3.50,3.51,3.75,3.875,3.99,4.00,4.01,4.05,4.125})
PrintDensity(World,"boundary-ray",Probe[0],Probe[1],Z);
PrintCrossing(World,"boundary-ray",Probe[0],Probe[1],3.49,4.125);
}
for(const auto& Probe:std::array<std::array<double,2>,4>{{
{{-67.0,-39.0}},{{-66.0,-39.0}},{{-67.0,-38.0}},{{-66.0,-38.0}}}})
{
PrintDensity(World,"boundary-grid-node",Probe[0],Probe[1],3.875);
PrintDensity(World,"boundary-grid-node",Probe[0],Probe[1],4.125);
}
return 0;
}
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""Measure peak per-process RSS for a build process tree under the L17 limits."""
import os
import subprocess
import sys
import time
from pathlib import Path
def descendants(root):
pending = [root]
seen = set()
while pending:
pid = pending.pop()
if pid in seen:
continue
seen.add(pid)
try:
children = Path(f"/proc/{pid}/task/{pid}/children").read_text().split()
pending.extend(int(child) for child in children)
except (FileNotFoundError, PermissionError, ProcessLookupError):
pass
return seen
def status(pid):
try:
fields = {}
for line in Path(f"/proc/{pid}/status").read_text().splitlines():
if line.startswith(("Name:", "VmRSS:", "VmSize:")):
key, *value = line.split()
fields[key[:-1]] = value[0] if value else ""
return (int(fields.get("VmRSS", "0")), int(fields.get("VmSize", "0")),
fields.get("Name", ""))
except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError):
return None
if len(sys.argv) < 2:
raise SystemExit("usage: MeasureBuild.py command [arguments ...]")
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
started = time.monotonic()
process = subprocess.Popen(sys.argv[1:], start_new_session=True)
peak_rss = (0, 0, "")
peak_vms = (0, 0, "")
while process.poll() is None:
for pid in descendants(process.pid):
measured = status(pid)
if measured is None:
continue
rss, vms, name = measured
if rss > peak_rss[0]:
peak_rss = (rss, pid, name)
if vms > peak_vms[0]:
peak_vms = (vms, pid, name)
time.sleep(0.1)
exit_code = process.wait()
elapsed = time.monotonic() - started
print(f"[BuildTreeResources] exit_code={exit_code} wall_s={elapsed:.3f} "
f"peak_process_rss_kib={peak_rss[0]} peak_rss_pid={peak_rss[1]} "
f"peak_rss_name={peak_rss[2]} peak_process_vms_kib={peak_vms[0]} "
f"peak_vms_pid={peak_vms[1]} peak_vms_name={peak_vms[2]} "
"monitor_interval_s=0.1", flush=True)
raise SystemExit(exit_code)
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
"""Summarize exported tile geometry and upward-facing ground for L17."""
import array
import collections
import math
import struct
import sys
def read_exact(stream, size):
data = stream.read(size)
if len(data) != size:
raise EOFError(f"wanted {size} bytes, got {len(data)}")
return data
path = sys.argv[1]
with open(path, "rb") as stream:
if read_exact(stream, 8) != b"VFMSH001":
raise SystemExit("bad VFMSH001 header")
version, voxel_um, tile_count = struct.unpack("<3I", read_exact(stream, 12))
camera = struct.unpack("<3d", read_exact(stream, 24))
yaw, pitch = struct.unpack("<2d", read_exact(stream, 16))
per_lod = collections.defaultdict(lambda: {"tiles": 0, "vertices": 0,
"triangles": 0, "surface_triangles": 0, "up_triangles": 0,
"up_centroids": [], "tile_spans": [], "empty": 0})
tile_rows = []
for _ in range(tile_count):
key = struct.unpack("<4i", read_exact(stream, 16))
surf_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack(
"<5I", read_exact(stream, 20))
p = array.array("f")
p.frombytes(read_exact(stream, vertex_count * 12))
n = array.array("f")
n.frombytes(read_exact(stream, vertex_count * 12))
if sys.byteorder != "little":
p.byteswap(); n.byteswap()
indices = array.array("I")
indices.frombytes(read_exact(stream, index_count * 4))
masks = read_exact(stream, mask_count)
if sys.byteorder != "little":
indices.byteswap()
lod = key[3]
row = per_lod[lod]
row["tiles"] += 1
row["vertices"] += vertex_count
row["triangles"] += index_count // 3
row["surface_triangles"] += index_count // 3 - skirt_count
up = []
for tri in range(index_count // 3):
if masks and masks[tri] != 0:
continue
a, b, c = indices[tri * 3:tri * 3 + 3]
if max(a, b, c) >= surf_vertices:
continue
if (n[a * 3 + 2] + n[b * 3 + 2] + n[c * 3 + 2]) / 3.0 < 0.65:
continue
up.append((p[a * 3 + 2] + p[b * 3 + 2] + p[c * 3 + 2]) / 3.0)
row["up_triangles"] += len(up)
row["up_centroids"].extend(up)
if up:
up.sort()
span = up[math.floor(0.95 * (len(up) - 1))] - up[math.floor(0.05 * (len(up) - 1))]
row["tile_spans"].append(span)
tile_rows.append((key, vertex_count, index_count // 3, skirt_count,
len(up), up[0], up[len(up) // 2], up[-1], span))
else:
row["empty"] += 1
tile_rows.append((key, vertex_count, index_count // 3, skirt_count,
0, math.nan, math.nan, math.nan, math.nan))
print(f"version={version} voxel_um={voxel_um} tiles={tile_count} camera_m={camera} yaw={yaw} pitch={pitch}")
print("lod tiles mesh_tiles vertices triangles skirt_triangles upward_surface_triangles "
"upward_centroid_z_m_p05/median/p95 tile_up_z_span_m_p50/p95/max")
for lod in sorted(per_lod):
r = per_lod[lod]
z = sorted(r["up_centroids"])
s = sorted(r["tile_spans"])
def q(values, fraction):
return values[math.floor(fraction * (len(values) - 1))] if values else math.nan
print(f"{lod} {r['tiles']} {r['tiles']-r['empty']} {r['vertices']} {r['triangles']} "
f"{sum(row[3] for row in tile_rows if row[0][3] == lod)} {r['up_triangles']} "
f"{q(z,.05):.4f}/{q(z,.5):.4f}/{q(z,.95):.4f} "
f"{q(s,.5):.4f}/{q(s,.95):.4f}/{max(s) if s else math.nan:.4f}")
print("near_camera_up_tiles (sorted by XY tile-centre distance):")
near = []
for row in tile_rows:
key = row[0]
lod = key[3]
extent = 32 * (1 << lod) * voxel_um / 1_000_000.0
cx = (key[0] + 0.5) * extent
cy = (key[1] + 0.5) * extent
near.append((math.hypot(cx-camera[0], cy-camera[1]), row))
for distance, row in sorted(near)[:30]:
key, verts, tris, skirts, ups, lo, med, hi, span = row
if ups:
print(f"key={key} xy_distance_m={distance:.2f} vertices={verts} triangles={tris} "
f"skirt_triangles={skirts} upward_triangles={ups} z_m={lo:.3f}/{med:.3f}/{hi:.3f} "
f"tile_span_p05_p95_m={span:.3f}")
@@ -0,0 +1,152 @@
#!/usr/bin/env python3
"""Trace review-image pixels through the exported clipmap mesh."""
import array
import math
import struct
import sys
def read_exact(f, count):
data = f.read(count)
if len(data) != count:
raise EOFError((len(data), count))
return data
def floor_div(n, d):
q, r = divmod(n, d)
return q - (r < 0)
def visible_mask(key, desired):
x, y, z, lod = key
extent = 32 << lod
origin = (x * extent, y * extent, z * extent)
mask = 0
for axis in range(3):
for side in range(2):
probe = [origin[i] + extent // 2 for i in range(3)]
probe[axis] = origin[axis] + (extent if side else -1)
neighbor = None
for level in range(9):
neighbor_extent = 32 << level
coord = tuple(floor_div(probe[i], neighbor_extent) for i in range(3)) + (level,)
if coord in desired:
neighbor = level
break
if neighbor is None or neighbor != lod:
mask |= 1 << (axis * 2 + side)
return mask
def ray_box(origin, direction, low, high):
lo, hi = 0.1, 20000.0
for axis in range(3):
if abs(direction[axis]) < 1e-12:
if origin[axis] < low[axis] or origin[axis] > high[axis]:
return None
else:
a = (low[axis] - origin[axis]) / direction[axis]
b = (high[axis] - origin[axis]) / direction[axis]
if a > b:
a, b = b, a
lo, hi = max(lo, a), min(hi, b)
if lo > hi:
return None
return lo, hi
def ray_tri(origin, direction, a, b, c):
e1 = tuple(b[i] - a[i] for i in range(3))
e2 = tuple(c[i] - a[i] for i in range(3))
p = (direction[1]*e2[2]-direction[2]*e2[1],
direction[2]*e2[0]-direction[0]*e2[2],
direction[0]*e2[1]-direction[1]*e2[0])
det = sum(e1[i]*p[i] for i in range(3))
if abs(det) < 1e-10:
return None
inv = 1.0/det
tvec = tuple(origin[i]-a[i] for i in range(3))
u = sum(tvec[i]*p[i] for i in range(3))*inv
if u < 0 or u > 1:
return None
q = (tvec[1]*e1[2]-tvec[2]*e1[1],
tvec[2]*e1[0]-tvec[0]*e1[2],
tvec[0]*e1[1]-tvec[1]*e1[0])
v = sum(direction[i]*q[i] for i in range(3))*inv
if v < 0 or u+v > 1:
return None
t = sum(e2[i]*q[i] for i in range(3))*inv
return t if t >= 0.1 else None
if len(sys.argv) < 8 or len(sys.argv) % 2 != 1:
raise SystemExit("usage: ProbeCaptureRays.py scene.vfmesh camX camY camZ yaw pitch pixelX pixelY [pixelX pixelY ...]")
scene_path = sys.argv[1]
cam = tuple(map(float, sys.argv[2:5]))
yaw, pitch = map(math.radians, map(float, sys.argv[5:7]))
pixels = [(int(sys.argv[i]), int(sys.argv[i+1])) for i in range(7, len(sys.argv), 2)]
width, height, fov = 1600, 900, math.radians(90)
tan_h = math.tan(fov/2)
tan_v = tan_h / (width/height)
forward = (math.sin(yaw)*math.cos(pitch), math.cos(yaw)*math.cos(pitch), math.sin(pitch))
right = (math.cos(yaw), -math.sin(yaw), 0.0)
up = (right[1]*forward[2]-right[2]*forward[1], right[2]*forward[0]-right[0]*forward[2], right[0]*forward[1]-right[1]*forward[0])
with open(scene_path, "rb") as f:
if read_exact(f, 8) != b"VFMSH001":
raise SystemExit("bad scene")
version, voxel_um, count = struct.unpack("<3I", read_exact(f, 12))
scene_cam = struct.unpack("<3d", read_exact(f, 24))
scene_yaw, scene_pitch = struct.unpack("<2d", read_exact(f, 16))
voxel_m = voxel_um / 1_000_000.0
tiles = []
desired = set()
for _ in range(count):
key = struct.unpack("<4i", read_exact(f, 16))
surface_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack("<5I", read_exact(f, 20))
positions = array.array("f"); positions.frombytes(read_exact(f, vertex_count*12))
normals = array.array("f"); normals.frombytes(read_exact(f, vertex_count*12))
indices = array.array("I"); indices.frombytes(read_exact(f, index_count*4))
masks = read_exact(f, mask_count)
if sys.byteorder != "little":
positions.byteswap(); normals.byteswap(); indices.byteswap()
desired.add(key)
tiles.append((key, surface_vertices, skirt_count, positions, normals, indices, masks))
print(f"scene={scene_path} tiles={count} camera={cam} yaw={math.degrees(yaw):.3f} pitch={math.degrees(pitch):.3f}")
for px, py in pixels:
nx = 2*px/width - 1
ny = 1 - 2*py/height
direction0 = tuple(forward[i] + nx*tan_h*right[i] + ny*tan_v*up[i] for i in range(3))
length = math.sqrt(sum(v*v for v in direction0))
direction = tuple(v/length for v in direction0)
hits = []
candidate_tiles = 0
for key, surface_vertices, skirt_count, positions, normals, indices, masks in tiles:
x,y,z,lod = key
extent = 32*(1<<lod)*voxel_m
low = (x*extent, y*extent, z*extent)
high = tuple(v+extent for v in low)
if ray_box(cam, direction, low, high) is None:
continue
candidate_tiles += 1
show_mask = visible_mask(key, desired)
for tri in range(len(indices)//3):
m = masks[tri] if masks else 0
if m and (m & show_mask) == 0:
continue
ia,ib,ic = indices[tri*3:tri*3+3]
a,b,c = [],[],[]
for idx, out in ((ia,a),(ib,b),(ic,c)):
base=idx*3
out.extend((positions[base],positions[base+1],positions[base+2]))
t=ray_tri(cam,direction,a,b,c)
if t is None: continue
p=tuple(cam[i]+t*direction[i] for i in range(3))
nz=(normals[ia*3+2]+normals[ib*3+2]+normals[ic*3+2])/3
hits.append((t,key,tri,m,p,nz,ia>=surface_vertices or ib>=surface_vertices or ic>=surface_vertices))
hits.sort(key=lambda h:h[0])
print(f"pixel=({px},{py}) ray={direction} candidate_tiles={candidate_tiles} hits={len(hits)}")
for t,key,tri,m,p,nz,skirt in hits[:12]:
print(f" t={t:.3f}m key={key} tri={tri} mask={m} skirt={skirt} z={p[2]:.3f} normal_z={nz:.3f} xyz=({p[0]:.3f},{p[1]:.3f},{p[2]:.3f})")
@@ -0,0 +1,132 @@
# Linux18 — FloatingIslands stratum boundaries
**Result:** FloatingIslands geometry v3 removes its false lower all-XY seal, keeps the ceiling from the shared upper-boundary seal, and projects missing ceiling cells for every generator. SurfaceWorld hashes match the approved L14 baseline at `8704129` in every checked configuration.
## Scale in the Unreal route
`AVoxelWorld::CoreVoxelSizeCm` defaults to 25 cm, and `GetActiveVoxelSizeCm()` resolves the runtime value ([VoxelWorld.h:300](../../../../Source/VoxelForge/Public/VoxelWorld.h), [VoxelWorld.cpp:7495](../../../../Source/VoxelForge/Private/VoxelWorld.cpp)). The adapter writes the resolved size to the snapshot ([VoxelForgeCoreAdapter.cpp:1019](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp)); `AVoxelWorld` imports it with `ResolvedWorldSnapshot::FromJson` ([VoxelWorld.cpp:7597](../../../../Source/VoxelForge/Private/VoxelWorld.cpp), [VoxelForgeCore.cpp:916](../../../../Standalone/Core/src/VoxelForgeCore.cpp)). S1 records this single active size source and the 32-Core-voxel tile rule ([Round5 REPORT.md](../Round5/REPORT.md#1-one-core-voxel-size-source)).
At the current 25 cm setting, **SurfaceWorld strata use 8 m per slot chunk**: the Unreal surface plan multiplies the slot range by 32 Core voxels ([VoxelForgeCoreAdapter.cpp:280](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp); `CHUNK_SIZE=32` in [VoxelTypes.h:211](../../../../Source/VoxelForge/Public/VoxelTypes.h)). **FloatingIslands uses 4 m per owner-authored chunk**: the adapter’s owner size is `VOXEL_SIZE` ([VoxelForgeCoreAdapter.cpp:33](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp); 12.5 cm in [VoxelTypes.h:213](../../../../Source/VoxelForge/Public/VoxelTypes.h)), and its plan multiplies 32 owner voxels by the serialized owner/Core ratio, currently 12.5/25 = 1/2, or 16 Core voxels ([VoxelForgeCoreAdapter.cpp:441](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp)). For chunks 0…−15 that gives z bounds −60…+4 m. This is the two explicit coordinate conventions in the game route, not a global change from 8 m to 4 m.
Standalone uses the same owner/Core ratio and chunk formula ([OwnerWorldLoader.h:302](../../../../Standalone/Source/OwnerWorldLoader.h), [WorldAssemblyPrototype.h:488](../../../../Standalone/Source/WorldAssemblyPrototype.h)); no current Unreal/standalone scale disagreement was found. L18 also removed the standalone-only two-Core-voxel bounds inset so recipe bounds match the Unreal plan. The owner decides whether either authored scale changes.
## Fix and ceiling
Geometry version 3 preserves the island shapes and removes only the lower all-XY seal. The upper seal calls the shared `VF_ApplyUpperBoundarySeal` density primitive; the shared two-sided seal uses the same upper-band math ([VoxelDensityPrimitives.h:44](../../../../Source/VoxelForge/Public/VoxelDensityPrimitives.h)). Resolved bounds come from each strate’s own range. The shared `AppendStratumBoundaryCeilings` mesh path runs for every generator and LOD, adding a plane at the resolved upper boundary where the mesh lacks coverage. It suppresses an existing plane only when nine probes show full cell coverage ([ShapeWorldInternal.h:36](../../../../Standalone/Core/src/ShapeWorldInternal.h), [FarShellsInternal.h:894](../../../../Standalone/Core/src/FarShellsInternal.h), [VoxelForgeCore.cpp:2207](../../../../Standalone/Core/src/VoxelForgeCore.cpp)). The underside normal points into the room, so the existing material lighting renders the interior face. This adds no FloatingIslands-specific height.
For the captured FloatingIslands strate, the upper bound is **z=+4 m** and its configured 0.5 m seal gives an interior-facing ceiling surface beginning around **z=+3.5 m**. The density probe crosses into the seal at 3.5 m and exits at z=4.019 m; z=7.75, 8.0, and 8.25 m remain air with no crossing. The lower all-XY seal is removed; remaining geometry below −60 m belongs to the lower world and is visible in the ray traces. Thus the apparent 3.5 m “floor” is the retained ceiling when viewed from inside; the 8 m floor is absent. No chunk size changed.
The owner’s decision and version-3 recipe say an underground strate has a ceiling at its configured upper boundary. “Farther to breathe” comes from a taller configured range. I updated the stale architecture-table wording “open void” to say the islands sit beneath the shared ceiling.
## Ceiling continuity
The final audit used 16×16 interior samples per tile and paired samples along same-LOD tile edges. Far LODs pass continuously:
| LOD | Tiles with cap | Interior hits | Max root delta | Edge gaps |
|---:|---:|---:|---:|---:|
| 4 | 48/48 | 12,288/12,288 | 0 cm | 0 |
| 5 | 48/48 | 12,288/12,288 | 0 cm | 0 |
| 6 | 48/48 | 12,288/12,288 | 0 cm | 0 |
| 7 | 48/48 | 12,288/12,288 | 0 cm | 0 |
| 8 | 153/153 | 39,168/39,168 | 0 cm | 0 |
LOD0, 2, and 3 also hit all tested samples. LOD1 missed 3 of 12,288 interior samples (0.387 cm maximum root delta) and had no shared-edge gaps. The readable upward view is `captures/floating-islands-ceiling-up.jpg`.
## Dark tile-aligned patches
They are lower SurfaceWorld triangles visible below the removed false lower cap, not empty rays and not a viewer dark-square overlay. Traces in the final island export found:
- Pixel (700,720): first hit at 104.924 m on non-skirt LOD2 tile `(-2,2,-2,2)`, z=−62.925 m, normal-z 0.266; another LOD2 tile hits z=−69.942 m.
- Pixel (1050,650): first hit at 168.051 m on non-skirt LOD3 tile `(0,2,-2,3)`, z=−72.594 m, normal-z 0.895; lower LOD4 geometry is also hit at z=−112.229 m and −120 m.
The ring probe measures real LOD height steps on those lower surfaces. I left them visible: suppressing those triangles would hide valid lower-stratum geometry, while changing the lower strata or SurfaceWorld would exceed this local fix. The sampled rectangles are not missing tiles or floor holes.
## Cross-LOD ring steps
Entries are median / p95 / maximum absolute edge-height difference in centimetres, then gap count. The L18 column is the final matched island camera. The large remaining steps are lower-stratum terrain, not the upper ceiling.
| LOD edge | L17 before | L17 after | L18 final |
|---|---:|---:|---:|
| 0→1 | 3.451 / 8.920 / 449.158; 14 | —; 0 samples | —; 0 samples |
| 1→2 | 26.642 / 148.262 / 149.862; 0 | 0 / 0 / 0; 0 | 147.141 / 148.403 / 149.862; 0 |
| 2→3 | 0.134 / 198.730 / 773.318; 8 | 0 / 0 / 0; 0 | 128.603 / 200.789 / 773.318; 8 |
| 3→4 | 3.269 / 47.875 / 188.531; 27 | 0 / 0 / 0; 0 | 3.269 / 47.774 / 188.531; 27 |
| 4→5 | 29.975 / 130.496 / 445.444; 6 | 0 / 0 / 30.957; 1 | 29.992 / 124.373 / 443.482; 6 |
| 5→6 | 12.234 / 127.224 / 536.573; 32 | 12.234 / 127.224 / 536.573; 32 | 12.234 / 127.224 / 536.573; 21 |
| 6→7 | 29.013 / 301.752 / 42,624.479; 0 | 28.892 / 291.861 / 945.477; 0 | 29.013 / 301.752 / 42,624.479; 0 |
| 7→8 | 83.843 / 1,225.416 / 3,755.407; 32 | 83.843 / 1,225.416 / 3,755.407; 0 | 83.843 / 1,225.416 / 3,755.407; 0 |
## SurfaceWorld regression hashes
The 14-run check compared each final output to `Saved/Linux/l14-final-hash-sw-clang-off-w12-r5.log` from the L14/`8704129` baseline: Clang `-ffp-contract=off` and GCC default, W1/W8/W12, with five W12 repeats. All 14 matched the whole-view, full-detail, LOD0–8, and exact-query rows. The 24 m crossing check likewise passed all 14 compiler/worker configurations against their L14 compiler-specific references.
Whole view D/M/P/T: `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724`.
Full detail D/M/P/T: `0ee0579bd15cbbe4 / 32e5d4964d610fee / 1932b96ee4b1d910 / 69743c6bad3447dc`.
| LOD | Density | Mesh | Payload | Topology |
|---:|---|---|---|---|
| 0 | `769f2a706d585a72` | `33eeeb39fa443816` | `645621a1d968983f` | `c2457ed905036c9d` |
| 1 | `69cc5a5c0a2c60af` | `b48335f5410c57d5` | `d15c5480162ab8ba` | `feca1bd025823604` |
| 2 | `85deed5683a77202` | `53469895987aeea2` | `e55f8ae7e1532033` | `d5feb12a0e85c09b` |
| 3 | `6518caefb3be7e7f` | `ec513c90b853a614` | `f62fa1137ff17f82` | `ccf1dcf681965816` |
| 4 | `62d4be96021992f4` | `f1e4c6efcc2615a9` | `9dc5f9c88be02f33` | `fe6f55125a07c3bf` |
| 5 | `5e4a8c38b8cea6fc` | `08ee56998aaf21e5` | `541eea8558f26cc8` | `6539374a8b3336d8` |
| 6 | `e036e95b9006945b` | `624a33f941a99b02` | `81b73e14f68bdf86` | `4de4c63ce1f80a56` |
| 7 | `8ee358af56a30d8d` | `46ab3c6184048b7c` | `0a6164b7e68e80c5` | `0c26b85bb03bc831` |
| 8 | `c3458e1cbdb9c471` | `46c03d0994d75192` | `8f89fc5bde12d230` | `d16dc0cf62031898` |
Exact query: 9 probes; density/unclamped `e4d4a8eb95b35933`, detail `efcba20c0c70c415`, collision `e604823a249029bf`.
The 24 m crossing W12×5 hashes match those same aggregate whole-view, full-detail, and exact-query values on both compiler references; the full check compared all 12 rows per run.
FloatingIslands’ representative W12×5 whole-view D/M/P/T is `ca7f375cded78f1d / da003331c554f8f3 / 0d2e74862b4ee500 / b7a7177af8915a21`; full-detail is `fc71abf85f5b9373 / e139b32d42ecfa29 / 28a2414e41de59bd / d61ca68ca64f74ca`. Exact query is `4ef614485815ee30` density/unclamped, `efcba20c0c70c415` detail, `e604823a249029bf` collision. Clang and GCC representative hashes agree, and all nine LOD rows stayed stable across the 28-run matrix.
## Other invariants and Unreal edits
- Final matrix: 28/28 rows passed; repeated runs were stable within each compiler. Route parity had 0 mismatches across 782,026 FI and 910,651 SurfaceWorld exact samples. Proof audits had 0 violations: FI 9,048 blocks / 12,042,888 samples; SurfaceWorld 27,479 / 36,574,549. Readiness negative controls were caught; walkability passed 4,000/4,000 FI and 5,642/5,642 SurfaceWorld samples.
- L3 FP-contract preamble/self-test, L4 `FLazy`, L7 shared cache, L9/L12 proofs, L11 readiness/crash handling, L13 route binding, ARCHITECTURE §8.10, and async/MPSC/Epoch paths remain intact. Both final compiler runs started without the Core FP-contract self-test refusing the build. No async route was added.
- Unreal-side edits are limited to [VoxelForgeCoreAdapter.cpp](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:453), bumping FI geometry version 2→3 so serialized recipes pick up the lower-seal removal, and the shared [VoxelDensityPrimitives.h](../../../../Source/VoxelForge/Public/VoxelDensityPrimitives.h:44), extracting the common upper-seal math used by v3. The Unreal target could not be compiled on this Linux host.
## Captures
All JPEGs are below 300 KB. Before/after pairs use matched cameras: FI flat square `(-11.6124,-118.2212,-19.8452), yaw/pitch 0/0`; FI island `(-22,-19,-22.8), 0/−4`; SurfaceWorld spawn `(0,-35,-487.94), 0/−22`; horizon uses the same spawn camera with pitch 0. The ceiling view uses the island camera with pitch 80. The SurfaceWorld pairs look the same; the exact hash checks certify its output bit-for-bit.
- FI flat square: `captures/floating-islands-flat-square-before.jpg`, `captures/floating-islands-flat-square-after.jpg`.
- FI low island: `captures/floating-islands-island-view-before.jpg`, `captures/floating-islands-island-view-after.jpg`.
- FI upward ceiling: `captures/floating-islands-ceiling-up.jpg`.
- SurfaceWorld L1 spawn: `captures/surface-world-l1-spawn-before.jpg`, `captures/surface-world-l1-spawn-after.jpg`.
- SurfaceWorld horizon: `captures/surface-world-horizon-before.jpg`, `captures/surface-world-horizon-after.jpg`.
- Flat-square diagnostic without tile edges: `captures/floating-islands-flat-square-no-edges.jpg`.
## Failed or retried runs
- The first density-probe link omitted legacy compatibility objects and failed with undefined references. Relinking with the legacy implementation objects succeeded; both boundary probes then ran.
- The initial 4×4 continuity audit failed at far LODs 4–6 and found edge gaps. The shared all-LOD boundary cap and final full-cell coverage check replaced the center-only deduplication; final 16×16 LOD4–8 continuity passed with zero edge gaps.
- An early matrix checker compared Clang contraction-off hashes directly with GCC default hashes and reported FI mismatches. The checker was corrected to test repeated runs within each compiler and the L14 compiler-specific references; the final 28-row matrix passed.
- An early offscreen capture drew all skirts and showed an artificial slab. The capture now applies the viewer’s hidden-skirt mask; final matched captures were regenerated.
- A GCC build interrupted by owner steering produced no binary and was rerun. A pre-correction Clang build was superseded by the final build. No final build or matrix run failed or exceeded the runtime limits.
## Resources and owner note
Final builds: Clang 19 exit 0 in 31.689 s, peak RSS 436,088 KiB; GCC 14 exit 0 in 48.648 s, peak RSS 903,168 KiB. The largest measured runtime process was 897,276 KiB RSS. All processes stayed below the 6 GiB address-space cap; CPU affinity was 0–11, worker maximum 12, normal priority, and governor `powersave`. No run exceeded 30 minutes or stalled for 15 minutes. See [BuildResources.md](BuildResources.md).
**Owner note:** SurfaceWorld stayed bit-identical to L14. FloatingIslands now retains a ceiling at its configured upper strate boundary while removing the false lower all-XY floor. At the current plan that is a z=+4 m boundary with a 0.5 m seal; its distance above the islands comes from the configured range. The small Unreal edits are listed above and need an owner-machine UBT compile.
## Orchestrator review (Claude)
- **Merged.** SurfaceWorld is bit-identical (14 configs plus the 24 m crossing); the FI false all-XY lower seal
is removed; the ceiling comes from the shared, strate-parameter upper-boundary seal and ceiling path
(owner rule: every strate has a ceiling, height from its own parameters). The Unreal edits are a pure
extraction of the existing upper-seal math plus the FI `geometryVersion` 2→3; they need a UBT compile on
the owner PC.
- **The scale answer:** both conventions are deliberate and agree between Unreal and the standalone
(SurfaceWorld 32 Core voxels per chunk; FloatingIslands 32 owner voxels = 16 Core voxels). Nothing
rescaled.
- **Still open (L19):**
1. Small black holes in the FI ceiling, visible near the top of `floating-islands-flat-square-after.jpg`;
compare LOD1 missing 3/12,288 continuity samples.
2. The owner's ledges are most likely the LOWER stratum's terrain seen through the floorless FI void:
ring steps of 147 cm median at LOD1→2 and 129 cm at 2→3 remain in that terrain. "Valid lower-stratum
geometry" with metre-scale cross-LOD steps is still a bug the owner can see.
- Exports (229 MB `.vfmesh`) are not committed.
@@ -0,0 +1,151 @@
#!/usr/bin/env python3
"""Compare upward mesh heights on shared XY edges between adjacent LOD rings."""
import array
import collections
import math
import struct
import sys
def read_scene(path):
tiles = []
with open(path, "rb") as f:
if f.read(8) != b"VFMSH001":
raise SystemExit(f"{path}: invalid mesh header")
version, voxel_um, count = struct.unpack("<3I", f.read(12))
camera = struct.unpack("<3d", f.read(24))
yaw, pitch = struct.unpack("<2d", f.read(16))
voxel_m = voxel_um / 1_000_000.0
for _ in range(count):
key = struct.unpack("<4i", f.read(16))
surface_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack(
"<5I", f.read(20))
positions = array.array("f")
positions.frombytes(f.read(vertex_count * 12))
normals = array.array("f")
normals.frombytes(f.read(vertex_count * 12))
indices = array.array("I")
indices.frombytes(f.read(index_count * 4))
masks = f.read(mask_count)
if sys.byteorder != "little":
positions.byteswap(); normals.byteswap(); indices.byteswap()
triangles = []
for i in range(0, index_count, 3):
if masks and masks[i // 3] != 0:
continue
a, b, c = indices[i:i + 3]
if max(a, b, c) >= surface_vertices:
continue
nz = (normals[a * 3 + 2] + normals[b * 3 + 2] + normals[c * 3 + 2]) / 3.0
if nz < 0.65:
continue
tri = tuple((positions[j * 3], positions[j * 3 + 1], positions[j * 3 + 2])
for j in (a, b, c))
triangles.append(tri)
if triangles:
lod = key[3]
extent = 32 * (1 << lod) * voxel_m
tiles.append({"key": key, "lod": lod, "extent": extent,
"x0": key[0] * extent, "y0": key[1] * extent,
"x1": (key[0] + 1) * extent, "y1": (key[1] + 1) * extent,
"z0": key[2] * extent, "z1": (key[2] + 1) * extent,
"triangles": triangles})
return camera, yaw, pitch, tiles
def height_at(tile, x, y):
best = None
for tri in tile["triangles"]:
(x0, y0, z0), (x1, y1, z1), (x2, y2, z2) = tri
den = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2)
if abs(den) < 1.0e-10:
continue
a = ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2)) / den
b = ((y2 - y0) * (x - x2) + (x0 - x2) * (y - y2)) / den
c = 1.0 - a - b
if min(a, b, c) >= -1.0e-5:
z = a * z0 + b * z1 + c * z2
if best is None or z > best:
best = z
return best
path = sys.argv[1]
camera, yaw, pitch, tiles = read_scene(path)
by_lod = collections.defaultdict(list)
for tile in tiles:
by_lod[tile["lod"]].append(tile)
print(f"scene={path} camera_m={camera} yaw={yaw} pitch={pitch} nonempty_mesh_tiles={len(tiles)}")
print("lod_pair shared_edges samples_both median_abs_cm p95_abs_cm max_abs_cm median_delta_cm gaps")
for lod in range(8):
fine = by_lod[lod]
coarse = by_lod[lod + 1]
deltas = []
edge_rows = []
edge_count = 0
gap_count = 0
# Shared XY edges occur only where tile extents touch and overlap on the other axis.
for a in fine:
for b in coarse:
zlo, zhi = max(a["z0"], b["z0"]), min(a["z1"], b["z1"])
if zhi - zlo <= 1.0e-4:
continue
edge = None
if abs(a["x1"] - b["x0"]) < 1.0e-4 or abs(b["x1"] - a["x0"]) < 1.0e-4:
lo, hi = max(a["y0"], b["y0"]), min(a["y1"], b["y1"])
if hi - lo > 1.0e-4:
edge = ("x", a["x1"] if abs(a["x1"] - b["x0"]) < 1.0e-4 else a["x0"], lo, hi)
if edge is None and (abs(a["y1"] - b["y0"]) < 1.0e-4 or abs(b["y1"] - a["y0"]) < 1.0e-4):
lo, hi = max(a["x0"], b["x0"]), min(a["x1"], b["x1"])
if hi - lo > 1.0e-4:
edge = ("y", a["y1"] if abs(a["y1"] - b["y0"]) < 1.0e-4 else a["y0"], lo, hi)
if edge is None:
continue
edge_count += 1
axis, fixed, lo, hi = edge
epsilon = min(0.02, a["extent"] * 0.001, b["extent"] * 0.001)
samples = 9
matched = 0
edge_deltas = []
for i in range(samples):
t = (i + 0.5) / samples
varying = lo + (hi - lo) * t
if axis == "x":
side_a = 1.0 if abs(a["x1"] - fixed) < 1.0e-4 else -1.0
side_b = 1.0 if abs(b["x1"] - fixed) < 1.0e-4 else -1.0
za = height_at(a, fixed - side_a * epsilon, varying)
zb = height_at(b, fixed - side_b * epsilon, varying)
else:
side_a = 1.0 if abs(a["y1"] - fixed) < 1.0e-4 else -1.0
side_b = 1.0 if abs(b["y1"] - fixed) < 1.0e-4 else -1.0
za = height_at(a, varying, fixed - side_a * epsilon)
zb = height_at(b, varying, fixed - side_b * epsilon)
if za is not None and not zlo - 1.0e-3 <= za <= zhi + 1.0e-3:
za = None
if zb is not None and not zlo - 1.0e-3 <= zb <= zhi + 1.0e-3:
zb = None
if za is not None and zb is not None:
delta = (za - zb) * 100.0
deltas.append(delta)
edge_deltas.append((delta, za, zb, varying))
matched += 1
if matched == 0:
gap_count += 1
elif edge_deltas:
edge_rows.append((max(abs(row[0]) for row in edge_deltas),
a["key"], b["key"], edge, edge_deltas))
if deltas:
absolute = sorted(abs(x) for x in deltas)
signed = sorted(deltas)
p95 = absolute[math.floor(0.95 * (len(absolute) - 1))]
median_abs = absolute[len(absolute) // 2]
median_delta = signed[len(signed) // 2]
print(f"{lod}->{lod+1} {edge_count} {len(deltas)} {median_abs:.3f} {p95:.3f} {max(absolute):.3f} {median_delta:.3f} {gap_count}")
for worst, fine_key, coarse_key, edge, rows in sorted(edge_rows, reverse=True)[:2]:
row = max(rows, key=lambda item: abs(item[0]))
print(f" worst_edge max_abs_cm={worst:.3f} fine={fine_key} coarse={coarse_key} "
f"axis={edge[0]} fixed_m={edge[1]:.3f} span_m={edge[2]:.3f}..{edge[3]:.3f} "
f"sample_v_m={row[3]:.3f} fine_z_m={row[1]:.3f} "
f"coarse_z_m={row[2]:.3f} delta_cm={row[0]:.3f}")
else:
print(f"{lod}->{lod+1} {edge_count} 0 n/a n/a n/a n/a {gap_count}")
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""Run the L18 24 m SurfaceWorld crossing hash matrix."""
import os
import re
import signal
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l18-crossing"
OUT.mkdir(parents=True, exist_ok=True)
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
BINARIES = {
"clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-clang",
"gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-gcc",
}
PATTERN = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
rows = []
passed = True
for compiler, binary in BINARIES.items():
for workers, repeat in [(1, 1), (8, 1), (12, 1), (12, 2), (12, 3), (12, 4), (12, 5)]:
name = f"{compiler}-w{workers}-r{repeat}"
logfile = OUT / f"{name}.log"
command = ["prlimit", "--as=6442450944", "--", str(binary),
str(ROOT / "Standalone/data/owner_world.json"),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--stream-hash", "--force-generate", "--clip-radius=3", "--max-clip-level=8",
f"--workers={workers}", "--camera=0,-35,-487.94,0,-22",
"--camera-step=24,0,0", "--region-crossing", "--recipe=surface-world"]
started = time.monotonic()
peak_rss = 0
with logfile.open("w", encoding="utf-8") as stream:
process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT,
start_new_session=True)
while process.poll() is None:
pending = [process.pid]
seen = set()
while pending:
pid = pending.pop()
if pid in seen:
continue
seen.add(pid)
try:
pending.extend(int(value) for value in
Path(f"/proc/{pid}/task/{pid}/children").read_text().split())
for line in Path(f"/proc/{pid}/status").read_text().splitlines():
if line.startswith("VmRSS:"):
peak_rss = max(peak_rss, int(line.split()[1]))
break
except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError):
pass
if time.monotonic() - started > 900:
os.killpg(process.pid, signal.SIGTERM)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
passed = False
break
time.sleep(0.1)
code = process.wait()
elapsed = time.monotonic() - started
actual = PATTERN.findall(logfile.read_text(encoding="utf-8", errors="replace"))
ok = code == 0 and len(actual) == 12
passed &= ok
rows.append((compiler, workers, repeat, code, elapsed, peak_rss, ok, actual))
print(f"[CrossingRun] {name} exit={code} seconds={elapsed:.3f} "
f"peak_rss_kib={peak_rss} hash_rows={len(actual)} status={'PASS' if ok else 'FAIL'}",
flush=True)
reference = None
for compiler, workers, repeat, code, elapsed, peak_rss, ok, hashes in rows:
if reference is None:
reference = hashes
elif hashes != reference:
passed = False
print(f"[CrossingHashMismatch] {compiler} workers={workers} repeat={repeat}", flush=True)
print(f"[CrossingSummary] rows={len(rows)} expected=14 result={'PASS' if passed else 'FAIL'} "
f"path={OUT}", flush=True)
raise SystemExit(0 if passed and len(rows) == 14 else 1)
@@ -0,0 +1,132 @@
#!/usr/bin/env python3
"""Run the L18 deterministic W1/W8/W12 x5 matrix on both supported Linux builds."""
import os
import re
import signal
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l18-matrix"
OUT.mkdir(parents=True, exist_ok=True)
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
BINARIES = {
"clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-clang",
"gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-gcc",
}
RECIPES = {
"floating-islands": "-10,-31,-22,0,-8",
"surface-world": "0,-35,-487.94,0,-22",
}
HASH_PATTERNS = {
"full": re.compile(r"^\[PipelineFullDetailHash\].*$", re.M),
"whole": re.compile(r"^\[PipelineWholeViewHash\].*$", re.M),
"lod": re.compile(r"^\[PipelineLODHash\].*$", re.M),
"exact": re.compile(r"^\[PipelineExactQueryHash\].*$", re.M),
}
rows = []
all_pass = True
for recipe, camera in RECIPES.items():
for compiler, binary in BINARIES.items():
if not binary.exists():
raise SystemExit(f"missing binary: {binary}")
for workers, repeat in [(1, 1), (8, 1), (12, 1), (12, 2), (12, 3), (12, 4), (12, 5)]:
name = f"{recipe}-{compiler}-w{workers}-r{repeat}"
logfile = OUT / f"{name}.log"
command = ["prlimit", "--as=6442450944", "--", str(binary),
str(ROOT / "Standalone/data/owner_world.json"),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--stream-hash", "--force-generate", "--clip-radius=3",
"--max-clip-level=8", f"--workers={workers}", f"--camera={camera}",
f"--recipe={recipe}"]
started = time.monotonic()
peak_rss_kib = 0
with logfile.open("w", encoding="utf-8") as stream:
process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT,
start_new_session=True)
while process.poll() is None:
pending = [process.pid]
seen = set()
while pending:
pid = pending.pop()
if pid in seen:
continue
seen.add(pid)
try:
children = Path(f"/proc/{pid}/task/{pid}/children").read_text().split()
pending.extend(int(value) for value in children)
for line in Path(f"/proc/{pid}/status").read_text().splitlines():
if line.startswith("VmRSS:"):
peak_rss_kib = max(peak_rss_kib, int(line.split()[1]))
break
except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError):
pass
if time.monotonic() - started > 900:
os.killpg(process.pid, signal.SIGTERM)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
all_pass = False
break
time.sleep(0.1)
code = process.wait()
elapsed = time.monotonic() - started
output = logfile.read_text(encoding="utf-8", errors="replace")
matched = {key: pattern.findall(output) for key, pattern in HASH_PATTERNS.items()}
ok = code == 0 and all(matched.values()) and len(matched["lod"]) == 9
if not ok:
all_pass = False
row = {"recipe": recipe, "compiler": compiler, "workers": workers,
"repeat": repeat, "exit": code, "seconds": elapsed,
"peak_rss_kib": peak_rss_kib, "ok": ok,
"full": matched["full"][-1] if matched["full"] else "",
"whole": matched["whole"][-1] if matched["whole"] else "",
"lod": " || ".join(matched["lod"]),
"exact": matched["exact"][-1] if matched["exact"] else ""}
rows.append(row)
print(f"[MatrixRun] {name} exit={code} seconds={elapsed:.3f} "
f"peak_rss_kib={peak_rss_kib} hash_rows={sum(map(len,matched.values()))} "
f"status={'PASS' if ok else 'FAIL'}", flush=True)
summary = OUT / "summary.tsv"
columns = ["recipe", "compiler", "workers", "repeat", "exit", "seconds", "peak_rss_kib",
"ok", "full", "whole", "lod", "exact"]
with summary.open("w", encoding="utf-8") as f:
f.write("\t".join(columns) + "\n")
for row in rows:
f.write("\t".join(str(row[key]) for key in columns) + "\n")
for recipe in RECIPES:
for compiler in BINARIES:
reference = None
for row in rows:
if row["recipe"] != recipe or row["compiler"] != compiler:
continue
signature = (row["full"], row["whole"], row["lod"], row["exact"])
if reference is None:
reference = signature
elif signature != reference:
print(f"[MatrixMismatch] recipe={recipe} workers={row['workers']} "
f"compiler={compiler} repeat={row['repeat']}", flush=True)
all_pass = False
# Compiler defaults are intentionally recorded separately: Clang uses contraction off,
# while GCC default is the owner-requested control. Report rather than hide any cross-build
# difference; worker/repeat determinism is asserted within each compiler above.
compiler_signatures = {}
for row in rows:
if row["recipe"] == recipe:
compiler_signatures.setdefault(row["compiler"],
(row["full"], row["whole"], row["lod"], row["exact"]))
if len(set(compiler_signatures.values())) > 1:
print(f"[MatrixCompilerDifference] recipe={recipe} compilers="
f"{','.join(compiler_signatures)}", flush=True)
print(f"[MatrixSummary] rows={len(rows)} expected=28 result={'PASS' if all_pass else 'FAIL'} "
f"path={summary}", flush=True)
raise SystemExit(0 if all_pass and len(rows) == 28 else 1)
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

@@ -0,0 +1,70 @@
#!/usr/bin/env python3
"""Render matched L19 review captures from the L18 and L19 scene exports."""
import os
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
CAPTURE = ROOT / "Standalone/bin/linux/VoxelForgeOffscreenCapture-linux19-clang"
BEFORE = ROOT / "Standalone/Research/WorldAssemblerM3/Linux18/exports"
AFTER = ROOT / "Saved/Linux/l19-diagnostics"
OUT = ROOT / "Standalone/Research/WorldAssemblerM3/Linux19/captures"
PNG_OUT = ROOT / "Saved/Linux/l19-captures-temp"
LOGS = ROOT / "Saved/Linux/l19-diagnostics"
OUT.mkdir(parents=True, exist_ok=True)
PNG_OUT.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(ROOT / "Saved/Linux/mesa-cache")
views = [
("floating-islands-flat-square-before", BEFORE / "floating-islands-flat-square.vfmesh",
(-11.612444, -118.221237, -19.8452), 0, 0, True),
("floating-islands-flat-square-after", AFTER / "floating-islands-flat-square-after.vfmesh",
(-11.612444, -118.221237, -19.8452), 0, 0, True),
("floating-islands-owner-angle-before", BEFORE / "floating-islands-island-view.vfmesh",
(-22, -19, -22.8), 0, -4, True),
("floating-islands-owner-angle-after", AFTER / "floating-islands-island-view-after.vfmesh",
(-22, -19, -22.8), 0, -4, True),
("floating-islands-owner-ground-before", AFTER / "floating-islands-owner-ground-before.vfmesh",
(-6.3, -19.06, -21.0), 0, -4, True),
("floating-islands-owner-ground-after", AFTER / "floating-islands-owner-ground-after.vfmesh",
(-6.3, -19.06, -21.0), 0, -4, True),
("floating-islands-ceiling-up-after", AFTER / "floating-islands-island-view-after.vfmesh",
(-22, -19, -22.8), 0, 80, True),
("surface-world-l1-spawn-before", BEFORE / "surface-world-l1-spawn.vfmesh",
(0, -35, -487.94), 0, -22, False),
("surface-world-l1-spawn-after", AFTER / "surface-world-l1-spawn-after.vfmesh",
(0, -35, -487.94), 0, -22, False),
("surface-world-horizon-before", BEFORE / "surface-world-l1-spawn.vfmesh",
(0, -35, -487.94), 0, 0, False),
("surface-world-horizon-after", AFTER / "surface-world-l1-spawn-after.vfmesh",
(0, -35, -487.94), 0, 0, False),
("surface-world-rings-above-before", BEFORE / "surface-world-l1-spawn.vfmesh",
(0, -35, -280), 0, -90, True),
("surface-world-rings-above-after", AFTER / "surface-world-l1-spawn-after.vfmesh",
(0, -35, -280), 0, -90, True),
]
for name, scene, camera, yaw, pitch, tile_edges in views:
if not scene.exists():
raise SystemExit(f"missing scene: {scene}")
png = PNG_OUT / f"{name}.png"
jpg = OUT / f"{name}.jpg"
render_log = LOGS / f"{name}-render.log"
convert_log = LOGS / f"{name}-jpeg.log"
command = [str(CAPTURE), str(scene), str(png), "--size=1600x900",
"--shade=readable", f"--tile-edges={'on' if tile_edges else 'off'}",
"--tile-edge-width-m=0.15", "--camera-m="+",".join(map(str, camera)),
f"--yaw-deg={yaw}", f"--pitch-deg={pitch}"]
with render_log.open("w", encoding="utf-8") as stream:
subprocess.run(command, cwd=ROOT, env=env, stdout=stream,
stderr=subprocess.STDOUT, check=True)
ffmpeg = ["ffmpeg", "-nostdin", "-hide_banner", "-loglevel", "error", "-y",
"-i", str(png), "-frames:v", "1", "-q:v", "4", str(jpg)]
with convert_log.open("w", encoding="utf-8") as stream:
subprocess.run(ffmpeg, cwd=ROOT, env=env, stdout=stream,
stderr=subprocess.STDOUT, check=True)
if jpg.stat().st_size > 300_000:
raise SystemExit(f"{jpg.name} exceeds the 300 KB review limit")
print(f"[Capture] {jpg.relative_to(ROOT)} bytes={jpg.stat().st_size} status=PASS", flush=True)
@@ -0,0 +1,172 @@
#!/usr/bin/env python3
"""Strict L19 audit of FloatingIslands roof coverage at every LOD."""
import array
import collections
import math
import struct
import sys
def read_exact(stream, size):
data = stream.read(size)
if len(data) != size:
raise EOFError(f"wanted {size} bytes, got {len(data)}")
return data
def height_at(triangles, x, y, preferred_z):
best = None
for (x0, y0, z0), (x1, y1, z1), (x2, y2, z2) in triangles:
den = (y1-y2)*(x0-x2)+(x2-x1)*(y0-y2)
if abs(den) < 1.0e-10:
continue
a = ((y1-y2)*(x-x2)+(x2-x1)*(y-y2))/den
b = ((y2-y0)*(x-x2)+(x0-x2)*(y-y2))/den
c = 1.0-a-b
if min(a,b,c) >= -1.0e-5:
z = a*z0+b*z1+c*z2
if best is None or abs(z-preferred_z) < abs(best-preferred_z):
best = z
return best
def quantile(values, fraction):
if not values:
return math.nan
ordered = sorted(values)
return ordered[math.floor(fraction*(len(ordered)-1))]
if len(sys.argv) != 3:
raise SystemExit("usage: CeilingContinuity.py scene.vfmesh expected-cap-plane-metres")
scene_path = sys.argv[1]
root_z = float(sys.argv[2])
tiles = {}
voxel_size_m = None
with open(scene_path, "rb") as stream:
if read_exact(stream, 8) != b"VFMSH001":
raise SystemExit("invalid VFMSH001 scene")
version, voxel_um, tile_count = struct.unpack("<3I", read_exact(stream, 12))
camera = struct.unpack("<3d", read_exact(stream, 24))
yaw, pitch = struct.unpack("<2d", read_exact(stream, 16))
voxel_size_m = voxel_um/1_000_000.0
for _ in range(tile_count):
key = struct.unpack("<4i", read_exact(stream, 16))
surface_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack(
"<5I", read_exact(stream, 20))
positions = array.array("f")
positions.frombytes(read_exact(stream, vertex_count*12))
normals = array.array("f")
normals.frombytes(read_exact(stream, vertex_count*12))
indices = array.array("I")
indices.frombytes(read_exact(stream, index_count*4))
masks = read_exact(stream, mask_count)
if sys.byteorder != "little":
positions.byteswap()
normals.byteswap()
indices.byteswap()
extent = 32*(1 << key[3])*voxel_size_m
z0, z1 = key[2]*extent, (key[2]+1)*extent
ceiling = []
for triangle in range(index_count//3):
if masks and masks[triangle] != 0:
continue
a,b,c = indices[triangle*3:triangle*3+3]
if max(a,b,c) >= surface_vertices:
continue
nz = (normals[a*3+2]+normals[b*3+2]+normals[c*3+2])/3.0
if nz > -0.65:
continue
points = tuple((positions[v*3],positions[v*3+1],positions[v*3+2])
for v in (a,b,c))
center_z = sum(point[2] for point in points)/3.0
if abs(center_z-root_z) <= 1.0:
ceiling.append(points)
tiles[key] = {
"extent": extent, "x0": key[0]*extent, "y0": key[1]*extent,
"x1": (key[0]+1)*extent, "y1": (key[1]+1)*extent,
"z0": z0, "z1": z1, "ceiling": ceiling,
}
by_lod = collections.defaultdict(dict)
for key, tile in tiles.items():
if tile["z0"] <= root_z+1.0 and tile["z1"] >= root_z-1.0:
by_lod[key[3]][key] = tile
print(f"scene={scene_path} version={version} voxel_um={voxel_um} tiles={tile_count} "
f"camera_m={camera} yaw={yaw} pitch={pitch} expected_cap_m={root_z:.9f}")
print("lod zband_tiles cap_tiles missing_tiles cap_triangles face_z_m_p05/median/p95 "
"tile_samples hit_samples max_abs_root_delta_cm shared_edges expected_edge_samples "
"paired_edge_samples edge_gaps edge_delta_cm_median/p95/max")
all_pass = True
all_misses = []
for lod in range(9):
target = by_lod[lod]
cap_tiles = {key: tile for key,tile in target.items() if tile["ceiling"]}
face_z = [point[2] for tile in cap_tiles.values() for tri in tile["ceiling"]
for point in tri]
deltas = []
sample_count = 0
hit_count = 0
for key,tile in target.items():
if not tile["ceiling"]:
continue
for iy in range(16):
for ix in range(16):
x = tile["x0"]+(ix+0.5)*tile["extent"]/16
y = tile["y0"]+(iy+0.5)*tile["extent"]/16
sample_count += 1
height = height_at(tile["ceiling"],x,y,root_z)
if height is not None:
hit_count += 1
deltas.append(abs(height-root_z)*100.0)
else:
all_misses.append((lod,key,ix,iy,x,y))
edge_deltas = []
edge_count = 0
edge_gaps = 0
edge_gap_samples = 0
for key,a in cap_tiles.items():
x,y,z,level = key
for neighbor_key,axis in (((x+1,y,z,level),"x"),((x,y+1,z,level),"y")):
b = cap_tiles.get(neighbor_key)
if b is None:
continue
edge_count += 1
epsilon = min(0.02,a["extent"]*1.0e-4)
matched = 0
for index in range(33):
t = (index+0.5)/33
if axis == "x":
fixed = a["x1"]
varying = a["y0"]+(a["y1"]-a["y0"])*t
za = height_at(a["ceiling"],fixed-epsilon,varying,root_z)
zb = height_at(b["ceiling"],fixed+epsilon,varying,root_z)
else:
fixed = a["y1"]
varying = a["x0"]+(a["x1"]-a["x0"])*t
za = height_at(a["ceiling"],varying,fixed-epsilon,root_z)
zb = height_at(b["ceiling"],varying,fixed+epsilon,root_z)
if za is not None and zb is not None:
edge_deltas.append(abs(za-zb)*100.0)
matched += 1
edge_gap_samples += 33-matched
if matched != 33:
edge_gaps += 1
missing = len(target)-len(cap_tiles)
max_root = max(deltas) if deltas else math.nan
print(f"{lod} {len(target)} {len(cap_tiles)} {missing} "
f"{sum(len(tile['ceiling']) for tile in cap_tiles.values())} "
f"{quantile(face_z,.05):.6f}/{quantile(face_z,.5):.6f}/{quantile(face_z,.95):.6f} "
f"{sample_count} {hit_count} {max_root:.3f} {edge_count} {edge_count*33} {len(edge_deltas)} "
f"{edge_gaps} {quantile(edge_deltas,.5):.3f}/{quantile(edge_deltas,.95):.3f}/"
f"{max(edge_deltas) if edge_deltas else math.nan:.3f}")
if target and (missing or hit_count != sample_count or edge_gap_samples):
all_pass = False
for lod,key,ix,iy,x,y in all_misses:
print(f" miss lod={lod} key={key} sample=({ix},{iy}) xy_m=({x:.6f},{y:.6f})")
print(f"[CeilingContinuityL19] total_misses={len(all_misses)} "
f"result={'PASS' if all_pass else 'FAIL'} criteria=LOD0-8 every 16x16 interior ray hits; "
"every shared same-LOD edge sample has paired hits")
raise SystemExit(0 if all_pass else 1)
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""Check deterministic matrices and protected SurfaceWorld identities against L14."""
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
MATRIX = ROOT / "Saved/Linux/l19-matrix"
CROSSING = ROOT / "Saved/Linux/l19-crossing"
ROW = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
LOD = re.compile(r"^\[PipelineLODHash\] lod=(\d+) .*$", re.M)
failed = []
def stable_rows(path):
rows = ROW.findall(path.read_text(encoding="utf-8", errors="replace"))
full = next((row for row in rows if row.startswith("[PipelineFullDetailHash]")), None)
exact = next((row for row in rows if row.startswith("[PipelineExactQueryHash]")), None)
lods = {int(match.group(1)): match.group(0) for match in LOD.finditer(
path.read_text(encoding="utf-8", errors="replace"))}
return rows, full, exact, {level: lods.get(level) for level in range(3)}
for compiler in ("clang-off", "gcc-default"):
baseline_name = "clang-off" if compiler == "clang-off" else "gcc-default"
baseline = ROOT / f"Saved/Linux/l14-final-hash-sw-{baseline_name}-w12-r5.log"
expected = stable_rows(baseline)
logs = sorted(MATRIX.glob(f"surface-world-{compiler}-w*-r*.log"))
if len(logs) != 7:
failed.append(f"matrix {compiler}: expected 7 rows, found {len(logs)}")
for path in logs:
actual = stable_rows(path)
if len(actual[0]) != 12 or actual[1:] != expected[1:]:
failed.append(f"protected SurfaceWorld mismatch: {path.name}")
crossing_baseline_name = "clang" if compiler == "clang-off" else "gcc"
crossing_baseline = ROOT / f"Saved/Linux/l14-final-crossing-24m-{crossing_baseline_name}-w12.log"
expected_crossing = stable_rows(crossing_baseline)
crossing_logs = sorted(CROSSING.glob(f"{compiler}-w*-r*.log"))
if len(crossing_logs) != 7:
failed.append(f"crossing {compiler}: expected 7 rows, found {len(crossing_logs)}")
for path in crossing_logs:
actual = stable_rows(path)
if len(actual[0]) != 12 or actual[1:] != expected_crossing[1:]:
failed.append(f"protected crossing identity mismatch: {path.name}")
print(f"[L19ProtectedHashGate] SurfaceWorld LOD0-2, full-detail, and exact query hashes "
f"result={'FAIL' if failed else 'PASS'}")
for failure in failed:
print(f"[L19HashMismatch] {failure}")
raise SystemExit(1 if failed else 0)
@@ -0,0 +1,123 @@
# Linux19 — FloatingIslands ceiling and LOD ledges
**Status:** The ceiling is now closed at every LOD. The lower-terrain ledges are diagnosed but remain visible: the required change affects protected SurfaceWorld LOD2 output, so I stopped before changing it and asked for your decision.
## Findings and changes
The ceiling holes came from two checks in the shared boundary-cap path. It required density to cross from solid just below a strate's configured top to air just above it. Some of the field remains solid above that top, so the old test omitted those cap cells. The duplicate-cap check also sampled only inside each cell and could miss partial perimeter coverage. The path now emits a cap wherever the field is solid just below the configured top, and checks a 5×5 grid including the perimeter before suppressing a fallback cap.
The ledges are real upward-facing, non-skirt terrain triangles from the lower SurfaceWorld stratum visible below the FloatingIslands stratum. The combined recipe log identifies the SurfaceWorld field as strate index 1, chunks −16…−79, built from the owner surface parameters and biome map; the FloatingIslands plan is index 0, chunks 0…−15. At the worst LOD1→2 sample, the fine mesh is at z=−60.497 m and the coarse mesh at z=−61.996 m (149.862 cm apart). The LOD2→3 maximum is 773.318 cm, at z=−73.080 m versus −65.347 m.
The ring probe excludes skirts and masked triangles. The far-ground refinement routine only runs at LOD4 and above, so it cannot cause the LOD1→2 or LOD2→3 steps. Density dispatch is coordinate-based rather than LOD-based; the meshes sample that field on progressively coarser grids (0.5 m, 1 m, and 2 m at LOD1–3). The evidence points to resolution-dependent surface extraction of the lower SurfaceWorld terrain near the strate transition, not a different LOD recipe or a ceiling triangle. The L13 route audit also found no page/native or exact-query mismatches. The owner’s lower-stratum reading is supported.
SurfaceWorld at its L1 spawn has small L1→2 and L2→3 median differences, but it has larger outliers at farther rings: L3→4 reaches 1,190.974 cm, and L4→5 reaches 491.570 cm. Those high far-ring values are in the table below; the matched spawn, horizon, and above-ring captures are byte-identical before and after.
I did not change the ledge geometry. The most direct fix needs to change SurfaceWorld LOD2, which your rule protects pending an owner decision. The pending question is whether to allow that change.
The shared Core fix changes the recipe output identity version from `farHorizonVersion` 3 to 4. It changes no density query, stratum position, scale, or async route. No Unreal files were edited.
## Ring tables
Values are median / p95 / maximum absolute edge-height difference in cm, then the probe's no-hit edge count. `Before → after` is identical for every row because this round changed the ceiling path, not the lower upward-facing terrain.
### FloatingIslands camera
| LOD edge | Edges / samples | Before (cm; gaps) | After (cm; gaps) |
|---|---:|---:|---:|
| 0→1 | 0 / 0 | — | — |
| 1→2 | 33 / 231 | 147.141 / 148.403 / 149.862; 0 | 147.141 / 148.403 / 149.862; 0 |
| 2→3 | 49 / 308 | 128.603 / 200.789 / 773.318; 8 | 128.603 / 200.789 / 773.318; 8 |
| 3→4 | 64 / 277 | 3.269 / 47.774 / 188.531; 27 | 3.269 / 47.774 / 188.531; 27 |
| 4→5 | 72 / 544 | 29.992 / 124.373 / 443.482; 6 | 29.992 / 124.373 / 443.482; 6 |
| 5→6 | 64 / 266 | 12.234 / 127.224 / 536.573; 32 | 12.234 / 127.224 / 536.573; 32 |
| 6→7 | 32 / 264 | 29.013 / 301.752 / 42,624.479; 0 | 29.013 / 301.752 / 42,624.479; 0 |
| 7→8 | 64 / 275 | 83.843 / 1,225.416 / 3,755.407; 32 | 83.843 / 1,225.416 / 3,755.407; 32 |
### SurfaceWorld L1 spawn camera
| LOD edge | Edges / samples | Before (cm; gaps) | After (cm; gaps) |
|---|---:|---:|---:|
| 0→1 | 46 / 288 | 0.178 / 0.594 / 1.171; 10 | 0.178 / 0.594 / 1.171; 10 |
| 1→2 | 32 / 288 | 1.419 / 4.990 / 10.438; 0 | 1.419 / 4.990 / 10.438; 0 |
| 2→3 | 34 / 256 | 2.179 / 12.648 / 35.355; 2 | 2.179 / 12.648 / 35.355; 2 |
| 3→4 | 40 / 265 | 5.099 / 35.999 / 1,190.974; 5 | 5.099 / 35.999 / 1,190.974; 5 |
| 4→5 | 58 / 270 | 0.235 / 3.694 / 491.570; 14 | 0.235 / 3.694 / 491.570; 14 |
| 5→6 | 65 / 266 | 12.234 / 127.224 / 536.573; 33 | 12.234 / 127.224 / 536.573; 33 |
| 6→7 | 41 / 269 | 28.238 / 291.861 / 945.477; 7 | 28.238 / 291.861 / 945.477; 7 |
| 7→8 | 32 / 275 | 83.843 / 1,225.416 / 3,755.407; 0 | 83.843 / 1,225.416 / 3,755.407; 0 |
## Ceiling continuity
The strict audit casts 16×16 interior rays per tile and pairs every shared same-LOD edge sample. Before the fix it found three LOD1 interior misses, one LOD2 interior miss, and 10 unpaired LOD1 perimeter samples. After the fix it found zero misses and zero edge gaps at all LODs.
| LOD | Cap tiles | Interior hits | Paired edge samples | Max root delta (cm) | Misses / gaps |
|---:|---:|---:|---:|---:|---:|
| 0 | 64/64 | 16,384/16,384 | 3,696/3,696 | 0 | 0 / 0 |
| 1 | 48/48 | 12,288/12,288 | 2,376/2,376 | 0 | 0 / 0 |
| 2 | 48/48 | 12,288/12,288 | 2,376/2,376 | 0.025 | 0 / 0 |
| 3 | 48/48 | 12,288/12,288 | 2,376/2,376 | 0.025 | 0 / 0 |
| 4 | 48/48 | 12,288/12,288 | 2,376/2,376 | 0 | 0 / 0 |
| 5 | 48/48 | 12,288/12,288 | 2,376/2,376 | 0 | 0 / 0 |
| 6 | 48/48 | 12,288/12,288 | 2,376/2,376 | 0 | 0 / 0 |
| 7 | 48/48 | 12,288/12,288 | 2,376/2,376 | 0 | 0 / 0 |
| 8 | 153/153 | 39,168/39,168 | 8,976/8,976 | 0 | 0 / 0 |
Full output is in `Saved/Linux/l19-diagnostics/fi_roof_after.log`; the pre-fix strict audit is `Saved/Linux/l19-diagnostics/baseline-fi-ceiling-strict.log`.
## Hashes and audits
Clang 19 (`-ffp-contract=off`) and GCC 14 (default) passed 28/28 runs: FI and SW, W1/W8/W12, with W12 repeated five times. The 24 m crossing passed 14/14 runs, with 12 matching hash rows each; its W1/W8/W12×5 hashes also matched the L14 compiler-specific references. The protected SurfaceWorld hash gate passed across the matrix and crossing. SurfaceWorld LOD0–2, full-detail, and exact-query hashes match L14 across the matrix and crossing; the representative W12 LOD3 hash also matches. LOD4–8 mesh/payload/topology hashes include the version-4 salt, and the tested captures show no visible SW change.
Representative Clang W12 hashes (density / mesh / payload / topology):
| Output | Full detail | Whole view |
|---|---|---|
| FloatingIslands | `43034299d33f2536 / a41e8353ec4bbe9c / cd0e3e15eef827b0 / 0b3c3f13cc1d6f8a` | `00bc3607a7839854 / 4baa66127c2b0892 / e11ef05e851a1517 / 1278bc4b1fffb869` |
| SurfaceWorld | `0ee0579bd15cbbe4 / 32e5d4964d610fee / 1932b96ee4b1d910 / 69743c6bad3447dc` | `c10697a8f48380c7 / 4197fc1072f0ff58 / 7b3e616ec9459851 / c879e35592bf33e5` |
SurfaceWorld LOD0–2 hashes (density / mesh / payload / topology):
| LOD | Hash |
|---:|---|
| 0 | `769f2a706d585a72 / 33eeeb39fa443816 / 645621a1d968983f / c2457ed905036c9d` |
| 1 | `69cc5a5c0a2c60af / b48335f5410c57d5 / d15c5480162ab8ba / feca1bd025823604` |
| 2 | `85deed5683a77202 / 53469895987aeea2 / e55f8ae7e1532033 / d5feb12a0e85c09b` |
Exact queries: FI density/unclamped `87e5c0dbf9ee9ee2`; SW density/unclamped `e4d4a8eb95b35933`; both detail `efcba20c0c70c415`, collision `e604823a249029bf`.
L13 route parity passed in all four audit runs (both recipes, both compilers), with zero mismatches. FI checked 782,026 exact-query samples; SW checked 910,651. L9 proof audits reported zero violations: FI 9,192 blocks / 12,234,552 samples; SW 27,479 / 36,574,549 samples. Full logs are in `Saved/Linux/l19-audits/`.
L3 FP-contract preamble/self-test, L4 `FLazy`, L7 shared cache, L9/L12 proofs, L11 readiness and crash handling, L13 route binding, the L18 shared ceiling, `ARCHITECTURE.md` §8.10, and the CLAUDE.md async rules remain intact. The only source edits are in shared Core; the only architecture addition is §8.38.
## Captures
Every JPEG is at most 50 KiB (limit 300 KB). `floating-islands-owner-ground-after.jpg` is the low view across the FI ground, matching the owner's angle. SurfaceWorld spawn, horizon, and above-ring before/after JPEGs are byte-identical.
- FI: `captures/floating-islands-flat-square-before.jpg`, `captures/floating-islands-flat-square-after.jpg`, `captures/floating-islands-owner-angle-before.jpg`, `captures/floating-islands-owner-angle-after.jpg`, `captures/floating-islands-owner-ground-before.jpg`, `captures/floating-islands-owner-ground-after.jpg`, `captures/floating-islands-ceiling-up-after.jpg`.
- SW: `captures/surface-world-l1-spawn-before.jpg`, `captures/surface-world-l1-spawn-after.jpg`, `captures/surface-world-horizon-before.jpg`, `captures/surface-world-horizon-after.jpg`, `captures/surface-world-rings-above-before.jpg`, `captures/surface-world-rings-above-after.jpg`.
## Failed and retried runs
- The pre-fix strict FI ceiling audit failed as expected: 4 interior misses and 10 unpaired LOD1 edge samples. The earlier loose report had counted only the 3 LOD1 interior misses. The final strict audit passed.
- A ceiling audit was mistakenly run on the ordinary SW terrain export; it reported 47,837 non-roof ray misses. That was the wrong target for this audit and was discarded.
- The first continuity-audit attempt was interrupted before results. `/usr/bin/time` was unavailable (exit 127); the repository `MeasureBuild.py` wrapper was used instead.
- The first FI auto-camera export used clip radius 0 / max LOD 0 and exited with `std::bad_alloc` (1.710 s, peak RSS 2,151,292 KiB). Retrying at radius 3 / LOD8 / W12 succeeded (10.786 s, peak RSS 597,976 KiB).
- An exploratory native-heightfield refinement extension did not change the FI L1→2 or L2→3 ring values and was reverted. A temporary debug probe/build used to inspect the ceiling field was also removed before the final build.
- The first hash-gate run happened before crossing logs existed and failed for zero crossing rows. After the 24 m crossing completed, the gate passed.
- The first SW ring probe did not inherit the CPU affinity limit; it was rerun under `taskset -c 0-11`, and the constrained table is unchanged.
- `renice -n 0` was denied by the environment. Runs stayed at inherited nice level 5 (below normal priority); the governor was left unchanged at `powersave`.
No build or run exceeded 15 minutes or 30 minutes. All final builds and run children used CPUs 0–11, at most 12 workers, `LP_NUM_THREADS=12` for llvmpipe, and the 6 GiB address-space cap. Peak RSS was 903,324 KiB (GCC build); the matrix, crossing, audits, roof audit, and captures peaked at 583,180, 550,832, 857,964, 541,972, and 510,680 KiB respectively. The outer matrix took 343.684 s; the crossing took 46.354 s. Governor: `powersave`.
**Owner note:** The FI ceiling now closes cleanly at z=+4 m. The visible ledges are lower SurfaceWorld terrain and are a real LOD sampling mismatch, not skirts. SurfaceWorld L1→2 and L2→3 agree closely at the spawn, but its far rings have larger outliers. The ledge fix needs permission to change SurfaceWorld LOD2; no such mesh change is included here. Nothing was committed, pushed, or stashed.
## Orchestrator review (Claude)
- Merged. The ceiling specks seen in L18's flat-square capture are gone in the L19 capture (checked by me),
and the strict audit reads 0 misses / 0 gaps at all LODs. SurfaceWorld LOD0–2, full-detail and exact
queries are unchanged; the far mesh hashes carry the `farHorizonVersion` 3→4 salt, with byte-identical
captures.
- Luna correctly stopped at the protected SurfaceWorld LOD2 rule. Ledge decision: the defect is at the
strate interface (lower stratum top near z≈−60…−73 m, sampled on 0.5/1/2 m grids at LOD1–3), which is
where the two chunk-unit conventions meet. It goes into L20 (the units/layers design round) as its
concrete test case, rather than being patched alone first.
@@ -0,0 +1,79 @@
#!/usr/bin/env python3
"""Run the L9 uniform-block proof and L13 route parity audits."""
import os
import signal
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l19-audits"
OUT.mkdir(parents=True, exist_ok=True)
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
BINARIES = {
"clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux19-clang",
"gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux19-gcc",
}
RECIPES = {
"floating-islands": ("-22,-19,-22.8,0,-4", "--recipe=floating-islands"),
"surface-world": ("0,-35,-487.94,0,-22", "--recipe=surface-world"),
}
passed = True
for recipe, (camera, recipe_flag) in RECIPES.items():
for compiler, binary in BINARIES.items():
name = f"{recipe}-{compiler}"
logfile = OUT / f"{name}.log"
command = ["prlimit", "--as=6442450944", "--", str(binary),
str(ROOT / "Standalone/data/owner_world.json"),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--stream-hash", "--force-generate", "--clip-radius=3", "--max-clip-level=8",
"--workers=12", f"--camera={camera}", recipe_flag,
"--audit-uniform-block-proofs", "--audit-route-parity"]
started = time.monotonic()
peak_rss = 0
timed_out = False
with logfile.open("w", encoding="utf-8") as stream:
process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT,
start_new_session=True)
while process.poll() is None:
pending, seen = [process.pid], set()
while pending:
pid = pending.pop()
if pid in seen:
continue
seen.add(pid)
try:
pending.extend(int(value) for value in
Path(f"/proc/{pid}/task/{pid}/children").read_text().split())
for line in Path(f"/proc/{pid}/status").read_text().splitlines():
if line.startswith("VmRSS:"):
peak_rss = max(peak_rss, int(line.split()[1]))
break
except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError):
pass
if time.monotonic() - started > 900:
os.killpg(process.pid, signal.SIGTERM)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
timed_out = True
passed = False
break
time.sleep(0.1)
code = process.wait()
elapsed = time.monotonic() - started
log = logfile.read_text(encoding="utf-8", errors="replace")
route_lines = [line for line in log.splitlines() if line.startswith("[RouteParityAudit]")]
proof_lines = [line for line in log.splitlines() if line.startswith("[UniformBlockProofAudit]")]
route_ok = bool(route_lines) and route_lines[-1].endswith("status=PASS")
proof_ok = bool(proof_lines) and "violations=0" in proof_lines[-1]
ok = code == 0 and not timed_out and route_ok and proof_ok
passed &= ok
print(f"[AuditRun] {name} exit={code} seconds={elapsed:.3f} peak_rss_kib={peak_rss} "
f"route={route_ok} proofs={proof_ok} status={'PASS' if ok else 'FAIL'}", flush=True)
print(f"[AuditSummary] rows={len(RECIPES)*len(BINARIES)} expected=4 "
f"result={'PASS' if passed else 'FAIL'} path={OUT}", flush=True)
raise SystemExit(0 if passed else 1)
@@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""Run the L19 24 m SurfaceWorld crossing hash matrix."""
import os
import re
import signal
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l19-crossing"
OUT.mkdir(parents=True, exist_ok=True)
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
BINARIES = {
"clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux19-clang",
"gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux19-gcc",
}
PATTERN = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
RUNS = [(1, 1), (8, 1), (12, 1), (12, 2), (12, 3), (12, 4), (12, 5)]
passed = True
for compiler, binary in BINARIES.items():
reference = None
for workers, repeat in RUNS:
name = f"{compiler}-w{workers}-r{repeat}"
logfile = OUT / f"{name}.log"
command = ["prlimit", "--as=6442450944", "--", str(binary),
str(ROOT / "Standalone/data/owner_world.json"),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--stream-hash", "--force-generate", "--clip-radius=3", "--max-clip-level=8",
f"--workers={workers}", "--camera=0,-35,-487.94,0,-22",
"--camera-step=24,0,0", "--region-crossing", "--recipe=surface-world"]
started = time.monotonic()
peak_rss = 0
timed_out = False
with logfile.open("w", encoding="utf-8") as stream:
process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT,
start_new_session=True)
while process.poll() is None:
pending, seen = [process.pid], set()
while pending:
pid = pending.pop()
if pid in seen:
continue
seen.add(pid)
try:
pending.extend(int(value) for value in
Path(f"/proc/{pid}/task/{pid}/children").read_text().split())
for line in Path(f"/proc/{pid}/status").read_text().splitlines():
if line.startswith("VmRSS:"):
peak_rss = max(peak_rss, int(line.split()[1]))
break
except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError):
pass
if time.monotonic() - started > 900:
os.killpg(process.pid, signal.SIGTERM)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
timed_out = True
passed = False
break
time.sleep(0.1)
code = process.wait()
elapsed = time.monotonic() - started
hashes = PATTERN.findall(logfile.read_text(encoding="utf-8", errors="replace"))
ok = code == 0 and not timed_out and len(hashes) == 12
if reference is None:
reference = hashes
elif hashes != reference:
ok = False
print(f"[CrossingMismatch] {name}", flush=True)
passed &= ok
print(f"[CrossingRun] {name} exit={code} seconds={elapsed:.3f} "
f"peak_rss_kib={peak_rss} hash_rows={len(hashes)} "
f"status={'PASS' if ok else 'FAIL'}", flush=True)
print(f"[CrossingSummary] rows={len(BINARIES)*len(RUNS)} expected=14 "
f"result={'PASS' if passed else 'FAIL'} path={OUT}", flush=True)
raise SystemExit(0 if passed else 1)
@@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""Run the L19 W1/W8/W12 x5 matrix under inherited taskset limits."""
import os
import re
import signal
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l19-matrix"
OUT.mkdir(parents=True, exist_ok=True)
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
BINARIES = {
"clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux19-clang",
"gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux19-gcc",
}
RECIPES = {
"floating-islands": "-22,-19,-22.8,0,-4",
"surface-world": "0,-35,-487.94,0,-22",
}
PATTERN = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
RUNS = [(1, 1), (8, 1), (12, 1), (12, 2), (12, 3), (12, 4), (12, 5)]
passed = True
for recipe, camera in RECIPES.items():
for compiler, binary in BINARIES.items():
if not binary.exists():
raise SystemExit(f"missing binary: {binary}")
reference = None
for workers, repeat in RUNS:
name = f"{recipe}-{compiler}-w{workers}-r{repeat}"
logfile = OUT / f"{name}.log"
command = ["prlimit", "--as=6442450944", "--", str(binary),
str(ROOT / "Standalone/data/owner_world.json"),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--stream-hash", "--force-generate", "--clip-radius=3",
"--max-clip-level=8", f"--workers={workers}", f"--camera={camera}",
f"--recipe={recipe}"]
started = time.monotonic()
peak_rss = 0
timed_out = False
with logfile.open("w", encoding="utf-8") as stream:
process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT,
start_new_session=True)
while process.poll() is None:
pending, seen = [process.pid], set()
while pending:
pid = pending.pop()
if pid in seen:
continue
seen.add(pid)
try:
pending.extend(int(value) for value in
Path(f"/proc/{pid}/task/{pid}/children").read_text().split())
for line in Path(f"/proc/{pid}/status").read_text().splitlines():
if line.startswith("VmRSS:"):
peak_rss = max(peak_rss, int(line.split()[1]))
break
except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError):
pass
if time.monotonic() - started > 900:
os.killpg(process.pid, signal.SIGTERM)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
timed_out = True
passed = False
break
time.sleep(0.1)
code = process.wait()
elapsed = time.monotonic() - started
hashes = PATTERN.findall(logfile.read_text(encoding="utf-8", errors="replace"))
ok = code == 0 and not timed_out and len(hashes) == 12
if reference is None:
reference = hashes
elif hashes != reference:
ok = False
print(f"[MatrixMismatch] {name}", flush=True)
passed &= ok
print(f"[MatrixRun] {name} exit={code} seconds={elapsed:.3f} "
f"peak_rss_kib={peak_rss} hash_rows={len(hashes)} "
f"status={'PASS' if ok else 'FAIL'}", flush=True)
print(f"[MatrixSummary] rows={len(RECIPES)*len(BINARIES)*len(RUNS)} expected=28 "
f"result={'PASS' if passed else 'FAIL'} path={OUT}", flush=True)
raise SystemExit(0 if passed else 1)
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

@@ -0,0 +1,34 @@
#!/usr/bin/env python3
"""Run one child and print its wait4 peak RSS under the Linux2 process limits."""
import os
import resource
import sys
import time
if len(sys.argv) < 2:
raise SystemExit("usage: MeasureProcess.py executable [arguments ...]")
address_limit, _ = resource.getrlimit(resource.RLIMIT_AS)
stack_limit, _ = resource.getrlimit(resource.RLIMIT_STACK)
if address_limit in (resource.RLIM_INFINITY, -1) or address_limit > 6 * 1024**3:
raise SystemExit("run under prlimit --as=6442450944")
if stack_limit in (resource.RLIM_INFINITY, -1) or stack_limit < 8 * 1024**2:
raise SystemExit("run with the ordinary process stack limit of at least 8 MiB")
if not os.sched_getaffinity(0).issubset(set(range(12))):
raise SystemExit("run under taskset -c 0-11")
print(f"[ProcessLimits] address_limit={address_limit} stack_limit={stack_limit} affinity={sorted(os.sched_getaffinity(0))}", flush=True)
started = time.monotonic()
pid = os.fork()
if pid == 0:
try:
os.execvp(sys.argv[1], sys.argv[1:])
except OSError as error:
print(f"MeasureProcess: exec failed: {error}", file=sys.stderr, flush=True)
os._exit(127)
_, status, usage = os.wait4(pid, 0)
wall = time.monotonic() - started
exit_code = os.waitstatus_to_exitcode(status)
print(f"[ProcessResources] exit_code={exit_code} wall_s={wall:.6f} peak_rss_kib={usage.ru_maxrss}")
raise SystemExit(exit_code)
@@ -0,0 +1,97 @@
# WorldAssemblerM3 Linux2
## Result and changes
The hash check can go red. `-ffp-contract=on`, `fast`, and GCC's default each change the first stage hash (density) on the L1 view; contraction off still reproduces all four L1 hashes at W1 and W12. No Core cache or density source was changed.
The standalone now accepts `--seed`, `--recipe`, and `--render-distance-chunks`; the viewer uses those same options for Windows replay. Linux standalone workers use 32 MiB pthread stacks, while the process retains its ordinary 8 MiB stack limit. The build script still defaults to contraction off; `--fp-contract=default` omits that override for the compiler-default probe.
Environment: i9-12900H, CPUs 0–11, Clang 19.1.7, GCC 14.2.0, governor `powersave`, EPP `balance_performance`. Runs used `taskset -c 0-11`, `RLIMIT_AS=6,442,450,944`, normal priority, and no 64 MiB stack limit. Peak `wait4` RSS was 539,648 KiB on the 2,553-tile checks and 293,460 KiB in the seed sweep.
## Commands
Build variants, with `--fp-contract=off`, `on`, and `fast` as named; `default` leaves the compiler flag unset:
```bash
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19-l2-off --jobs=12 --fp-contract=off
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19-l2-on --jobs=12 --fp-contract=on
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19-l2-fast --jobs=12 --fp-contract=fast
bash Standalone/BuildLinux.sh --compiler=g++-14 --variant=gcc14-l2-off --jobs=12 --fp-contract=off
bash Standalone/BuildLinux.sh --compiler=g++-14 --variant=gcc14-l2-default --jobs=12 --fp-contract=default
```
The L1-view call was `taskset -c 0-11 prlimit --as=6442450944 -- python3 Standalone/Research/WorldAssemblerM3/Linux2/MeasureProcess.py <binary> Standalone/data/owner_world.json --workers=<1|12> --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0`. The per-variant commands and resource records are in `Saved/Linux/linux2-contract-final-*.log`.
The seed matrix ran with:
```bash
python3 Standalone/Research/WorldAssemblerM3/Linux2/RunSeedSweep.py 1800
```
## Contraction sensitivity
All rows cover the same 2,553-tile L1 view, W12. `g++-14 -Q --help=optimizers -O2 -fno-fast-math` reports `-ffp-contract=fast` when no override is given.
| Build | Density | Mesh | Payload | Topology | First divergence from off |
|---|---|---|---|---|---|
| Clang 19 off; GCC 14 off | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | — |
| Clang 19 on | `acfa7023c3671dd6` | `adacc34b568be881` | `7c1de424738166e3` | `78e77fd29674920f` | density |
| Clang 19 fast | `f04bb87094a92a25` | `07596ba1a83f91d5` | `1292f277745a876d` | `b07b82bfb52166f5` | density |
| GCC 14 default (effective fast) | `03ed0b826a9ff773` | `07596ba1a83f91d5` | `fb6f82e779be56b2` | `9e5d549138ef2bc0` | density |
The hashes come from the whole-view pipeline stages in order: density, mesh, payload, topology. The same contraction-off binaries reproduce L1 at W1 as well as W12.
## Seed sweep
`seeds.txt` contains seed 0 plus 47 distinct values sampled without replacement from signed int32 using `random.Random(0x564F58454C464F52)`. With no mismatch among the 47 random draws, the one-sided 95% binomial upper bound is 6.18% for a random seed to mismatch on this exact matrix; seed 0 is included as the fixed L1 baseline.
| Recipe | Seeds | Linux combinations | Coverage per seed |
|---|---:|---|---|
| SurfaceWorld | 48 | Clang/GCC × W1/W12 (192 rows) | 27 LOD0 tiles; voxels `(-32,-192,-1984)` to `(64,-96,-1888)`, a 96³ cube (24 m per side) |
| FloatingIslands | 48 | Clang/GCC × W1/W12 (192 rows) | 27 LOD0 tiles; voxels `(-32,-32,-160)` to `(64,64,-64)`, a 96³ cube (24 m per side) |
All 384 runs passed. Clang/GCC matched at both worker counts in 192 comparisons; W1/W12 also matched within each compiler in 192 comparisons. The full per-seed, per-stage hashes, tile extents, wall time, and RSS are in [seed_hashes.csv](seed_hashes.csv); the summary is in [seed_sweep_summary.txt](seed_sweep_summary.txt). The sweep took 290.1 seconds; its maximum per-process peak RSS was 293,460 KiB. Coverage is limited to these fixed local cubes.
For seed 0, SurfaceWorld hashes are `e93491225d0202f9 / 6b2a630951428df2 / fc2798d6a5478b25 / 0c08d7d980a84301`; FloatingIslands hashes are `ea74d3354b5ce671 / 476d49ae2a4ba2a6 / 16078fcd36b68ff0 / cfb6c412b7118172`. Each sequence is density / mesh / payload / topology and matched across both compilers and worker counts.
The viewer seed override was added in `StandaloneViewer.cpp` and the standalone recipe helper; no Core change is needed. [windows_commands.txt](windows_commands.txt) contains all 192 PowerShell commands. Example from the repository root:
```powershell
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
```
Build the viewer with `powershell -ExecutionPolicy Bypass -File Standalone\Build.ps1`, then run the full replay with `powershell -ExecutionPolicy Bypass -File Standalone\Research\WorldAssemblerM3\Linux2\WindowsReplay.ps1`; it writes logs under `Saved\Linux`. Windows/MSVC compilation was unavailable here. Portability risk spots are the new C++20 helpers in `WorldAssemblyPrototype.h`, `strtoll` argument parsing in `StandaloneViewer.cpp`, and the `__linux__`/`std::thread` split in `StandaloneWorkerThread.h`; the pthread path is Linux-guarded.
## TLS cost and follow-up
`readelf -lW` reports `PT_TLS` FileSiz 6,093,024 bytes (5.81 MiB initialized image) and MemSiz 18,155,149 bytes (17.31 MiB per thread). Three 12-worker probes under the ordinary 8 MiB process stack measured a median spawn-to-ready time of 5.63 ms per thread (5.07–6.44 ms), and a resident increase of 17,736 KiB per worker after the first (17,936 KiB for the first). At 12 workers, `/proc/self/statm` rose by 213,036 KiB (208.0 MiB); the 32 MiB worker stacks reserve a further 32,772 KiB of virtual address space each. The largest wait4 peak across TLS probes was 268,476 KiB.
The large TLS symbols include `HeightfieldColumnCache` (0x680000 bytes, about 6.8 MB), `IslandColumnCache` (0x110000), plus duplicated `GFloorReliefCache` (0x140000 each), `GRoomGraphCache` (0xed000 each), and `GSurfColCache` (0xc9e78 each). `GPlayerFitMemo` is also duplicated as a process-wide object in ordinary `.bss`. [core_sources.txt](../../../Core/core_sources.txt) has 18 translation units: `VoxelForgeCore.cpp` is compiled once; each other 17 is compiled both as a `vfcore::detail` wrapper for Core and as a global legacy object for the standalone owner loader/mesher. This isolates the Core copy from Unreal-shaped global symbols and preserves the legacy reference path; the duplicate objects also duplicate cache state.
The L2 executable's static TLS measurement does not establish the Unreal plugin's model. Inference: a runtime-loaded shared object using general-dynamic TLS can obtain per-thread blocks through the dynamic loader, so it may avoid this exact static-TLS-in-stack footprint; the actual UBT `.so` flags and relocations must be inspected. glibc documents the TLS/dlopen compatibility concern for initial-exec TLS and recommends global-dynamic for more general shared-object loading ([glibc Dynamic Linker Hardening](https://www.sourceware.org/glibc/manual/latest/html_node/Dynamic-Linker-Hardening.html)); GCC describes the per-thread storage model and its loader/libc support ([GCC Thread-Local Storage](https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Thread-Local.html)).
After S14, prototype a small per-thread TLS handle backed by a bounded worker scratch pool or explicit generation context; share immutable initialized data and remove the Core/legacy duplicate cache where practical. This is a proposal only. The standalone stack wrapper already avoids the external 64 MiB process-stack setting: its own Linux workers request 32 MiB, and the L1 hashes stayed unchanged.
## Failed and retried runs
- The first Clang-off build failed because one join loop still named `std::thread&`; it was changed to `FStandaloneWorkerThread&` and rebuilt successfully (`linux2-build-clang-off.log`, then the retry logs). One later GCC-off build attempt stopped with `headless_object: unbound variable` (`linux2-build-gcc-off-final2.log`); an immediate identical build under the same CPU/address-space limits succeeded (`linux2-build-gcc-off-debug.log`), and the failure did not recur.
- The first FloatingIslands smoke used the default far ring and planned 186,911 tiles; it was stopped after about 10 seconds before generation (`linux2-floating-smoke-clang-w1.log`). With `--render-distance-chunks=0`, a radius-2/max-LOD-4 smoke completed 791 tiles in 18.94 seconds (`linux2-floating-smoke-clang-w1-r2.log`); the sweep uses radius 1/max-LOD 0 (27 tiles).
- The first contraction pass omitted the L1 camera and covered 2,370 tiles (`linux2-contract-*-w12.log`), so those hashes were discarded. The exact L1 camera rerun covered 2,553 tiles and produced the table above (`linux2-contract-final-*.log`).
- An optional one-ULP diagnostic attempt did not trigger (no injection line and no hash change; `linux2-negative-one-ulp-clang-off-w12.log`), so that switch was removed. It was unnecessary after the contraction variants made the check go red. The seed sweep had no failed or retried runs.
## Note for the owner
Contraction off reproduces L1 at W1/W12, while Clang on/fast and GCC default diverge first at density, so the Unreal Linux build's effective FP flags are decisive. The 48-seed sample matched across compilers and worker counts on 24 m-sided cubes in both recipes; the Windows replay commands are ready, with their MSVC build still unverified.
## Orchestrator review (Claude)
- **Surface sweep coverage is 14 effective seeds, not 48.** In `seed_hashes.csv`, 34 of the 48 SurfaceWorld
seeds give seed 0's exact density hash `0xe93491225d0202f9`, i.e. the fixed 24 m cube carries no
seed-dependent surface for them. Only 14 seeds exercise distinct terrain, so the 6.18% bound applies to
FloatingIslands (48 distinct hashes) but not to SurfaceWorld. Future sweeps should place the cube on each
seed's surface and report a per-seed non-empty-mesh count, so an empty cube can't count as a pass.
- Re-run by me: `VoxelForgeCoreHeadless-clang19-l2-off`, W12, plain 8 MiB `ulimit -s`, L1 view:
whole view 3.361 s, hashes `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724`.
- **Consequence of the contraction table:** Core's world now provably depends on the toolchain's FP-contract
setting, which every build outside `Build.ps1`/`BuildLinux.sh` (UBT on Windows and Linux) sets for itself.
Next: make Core immune to, or loudly detect, contraction instead of relying on flags.
@@ -0,0 +1,164 @@
#!/usr/bin/env python3
"""Run the deterministic Linux2 seed/compiler/worker matrix under the owner limits."""
import csv
import re
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path.cwd()
ROUND = ROOT / "Standalone/Research/WorldAssemblerM3/Linux2"
LOG_DIR = ROOT / "Saved/Linux"
MEASURE = ROUND / "MeasureProcess.py"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"clang19": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-clang19-l2-off",
"gcc14": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-gcc14-l2-off",
}
CAMERAS = {
"surface-world": "0,-35,-487.94,0,-22",
"floating-islands": "0,0,-32,0,-22",
}
HASH_RE = re.compile(
r"\[PipelineWholeViewHash\] tiles=(\d+) density=0x([0-9a-f]+) "
r"mesh=0x([0-9a-f]+) payload=0x([0-9a-f]+) topology=0x([0-9a-f]+)"
)
VOLUME_RE = re.compile(
r"\[PipelineVolume\] tiles=(\d+) lod=(\d+)\.\.(\d+) "
r"min_voxel=\((-?\d+),(-?\d+),(-?\d+)\) "
r"max_voxel=\((-?\d+),(-?\d+),(-?\d+)\)"
)
READY_RE = re.compile(r"\[StreamPipeline\].*whole_view_ready=([0-9.]+)s")
RESOURCE_RE = re.compile(r"\[ProcessResources\] exit_code=(-?\d+) wall_s=([0-9.]+) peak_rss_kib=(\d+)")
def main() -> int:
if not (1 <= len(sys.argv) <= 2):
raise SystemExit("usage: RunSeedSweep.py [budget-seconds; default 1800]")
budget_seconds = int(sys.argv[1]) if len(sys.argv) == 2 else 1800
seeds = [int(line.strip()) for line in (ROUND / "seeds.txt").read_text().splitlines() if line.strip()]
if len(seeds) != 48 or len(set(seeds)) != len(seeds):
raise SystemExit("seeds.txt must contain 48 unique signed int32 seeds")
missing = [str(path) for path in [MEASURE, DATA, *BINARIES.values()] if not path.is_file()]
if missing:
raise SystemExit("missing sweep input/build: " + ", ".join(missing))
LOG_DIR.mkdir(parents=True, exist_ok=True)
output_path = ROUND / "seed_hashes.csv"
fields = [
"seed", "recipe", "compiler", "workers", "tiles", "lod_min", "lod_max",
"min_x", "min_y", "min_z", "max_x", "max_y", "max_z",
"density_hash", "mesh_hash", "payload_hash", "topology_hash",
"whole_view_ready_s", "wall_s", "peak_rss_kib", "exit_code", "status",
]
started = time.monotonic()
total = len(seeds) * len(CAMERAS) * len(BINARIES) * 2
print(f"Sweep: {len(seeds)} seeds × 2 recipes × 2 compilers × W1/W12 = {total} runs; budget={budget_seconds}s", flush=True)
with output_path.open("w", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=fields)
writer.writeheader()
for seed in seeds:
for recipe, camera in CAMERAS.items():
for compiler, binary in BINARIES.items():
for workers in (1, 12):
remaining = budget_seconds - (time.monotonic() - started)
if remaining <= 0:
print("Sweep exceeded its 30 minute budget; stopping.", file=sys.stderr, flush=True)
return 124
stem = f"linux2-seed-{seed}-{recipe}-{compiler}-w{workers}"
log_path = LOG_DIR / f"{stem}.log"
args = [
str(binary), str(DATA), f"--seed={seed}", f"--recipe={recipe}",
"--render-distance-chunks=0", f"--workers={workers}",
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--stream-hash", "--force-generate", "--clip-radius=1",
"--max-clip-level=0", f"--camera={camera}", "--far-horizon-lod8-step=0",
]
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"python3", str(MEASURE), *args,
]
with log_path.open("w") as log_file:
log_file.write("[SweepCommand] " + " ".join(command) + "\n")
log_file.flush()
try:
result = subprocess.run(
command, cwd=ROOT, stdout=log_file, stderr=subprocess.STDOUT,
timeout=min(900, max(1, remaining)), check=False,
)
exit_code = result.returncode
except subprocess.TimeoutExpired:
exit_code = 124
log_file.write("\n[SweepTimeout] run reached its allotted limit\n")
output = log_path.read_text(errors="replace")
volume = VOLUME_RE.search(output)
hashes = HASH_RE.search(output)
ready = READY_RE.search(output)
resources = RESOURCE_RE.search(output)
passed = exit_code == 0 and volume and hashes and ready and resources
row = {
"seed": seed, "recipe": recipe, "compiler": compiler, "workers": workers,
"tiles": "", "lod_min": "", "lod_max": "",
"min_x": "", "min_y": "", "min_z": "", "max_x": "", "max_y": "", "max_z": "",
"density_hash": "", "mesh_hash": "", "payload_hash": "", "topology_hash": "",
"whole_view_ready_s": "", "wall_s": "", "peak_rss_kib": "",
"exit_code": exit_code, "status": "PASS" if passed else "FAIL",
}
if passed:
row.update({
"tiles": hashes.group(1),
"lod_min": volume.group(2), "lod_max": volume.group(3),
"min_x": volume.group(4), "min_y": volume.group(5), "min_z": volume.group(6),
"max_x": volume.group(7), "max_y": volume.group(8), "max_z": volume.group(9),
"density_hash": "0x" + hashes.group(2), "mesh_hash": "0x" + hashes.group(3),
"payload_hash": "0x" + hashes.group(4), "topology_hash": "0x" + hashes.group(5),
"whole_view_ready_s": ready.group(1), "wall_s": resources.group(2),
"peak_rss_kib": resources.group(3),
})
writer.writerow(row)
csv_file.flush()
completed = sum(1 for _ in output_path.open()) - 1
elapsed = time.monotonic() - started
print(f"[{completed}/{total}] seed={seed} recipe={recipe} compiler={compiler} W{workers} "
f"tiles={row['tiles']} wall={row['wall_s']}s status={row['status']} "
f"elapsed={elapsed:.1f}s", flush=True)
if not passed:
print(f"Run failed; details: {log_path}", file=sys.stderr, flush=True)
return exit_code or 1
rows = list(csv.DictReader(output_path.open(newline="")))
keys = ("density_hash", "mesh_hash", "payload_hash", "topology_hash")
checks = []
for seed in seeds:
for recipe in CAMERAS:
for workers in (1, 12):
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
and int(r["workers"]) == workers]
equal = len(pair) == 2 and all(pair[0][key] == pair[1][key] for key in keys)
checks.append((seed, recipe, workers, equal))
worker_checks = []
for seed in seeds:
for recipe in CAMERAS:
for compiler in BINARIES:
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
and r["compiler"] == compiler]
equal = len(pair) == 2 and all(pair[0][key] == pair[1][key] for key in keys)
worker_checks.append((seed, recipe, compiler, equal))
summary_path = ROUND / "seed_sweep_summary.txt"
mismatch_count = sum(not equal for _, _, _, equal in checks)
worker_mismatch_count = sum(not equal for _, _, _, equal in worker_checks)
summary_path.write_text(
f"runs={len(rows)} seeds={len(seeds)} recipes={len(CAMERAS)} compilers={len(BINARIES)} "
f"workers=1,12 cross_compiler_comparisons={len(checks)} cross_compiler_mismatches={mismatch_count} "
f"cross_worker_comparisons={len(worker_checks)} cross_worker_mismatches={worker_mismatch_count} "
f"elapsed_s={time.monotonic()-started:.3f}\n"
)
print(summary_path.read_text(), end="", flush=True)
return 0 if mismatch_count == 0 and worker_mismatch_count == 0 else 3
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,46 @@
$ErrorActionPreference = 'Stop'
$Root = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..\..\..'))
$Viewer = Join-Path $Root 'Standalone\bin\VoxelForgeCoreStandalone.exe'
$Data = Join-Path $Root 'Standalone\data\owner_world.json'
$SeedFile = Join-Path $PSScriptRoot 'seeds.txt'
$LogDir = Join-Path $Root 'Saved\Linux'
[IO.Directory]::CreateDirectory($LogDir) | Out-Null
$Recipes = @(
@{ Name = 'surface-world'; Camera = '0,-35,-487.94,0,-22' },
@{ Name = 'floating-islands'; Camera = '0,0,-32,0,-22' }
)
$Seeds = @(Get-Content -LiteralPath $SeedFile | ForEach-Object { [int]$_.Trim() })
if ($Seeds.Count -ne 48) { throw "Expected 48 seeds in $SeedFile" }
if (-not (Test-Path -LiteralPath $Viewer -PathType Leaf)) { throw "Viewer not found: $Viewer" }
foreach ($Recipe in $Recipes) {
foreach ($Seed in $Seeds) {
foreach ($Workers in @(1, 12)) {
$Arguments = @(
$Data,
"--seed=$Seed",
"--recipe=$($Recipe.Name)",
'--render-distance-chunks=0',
"--workers=$Workers",
'--world-assembler-prototype',
'--stream-benchmark',
'--stream-pipeline',
'--stream-hash',
'--force-generate',
'--clip-radius=1',
'--max-clip-level=0',
"--camera=$($Recipe.Camera)",
'--far-horizon-lod8-step=0',
'--process-affinity=4095',
'--process-priority=Normal',
'--frame-limit=60'
)
$Stem = "windows2-seed-$Seed-$($Recipe.Name)-w$Workers"
$Log = Join-Path $LogDir "$Stem.log"
Write-Host "& `"$Viewer`" $($Arguments -join ' ')"
& $Viewer @Arguments *> $Log
if ($LASTEXITCODE -ne 0) { throw "Viewer failed ($LASTEXITCODE); see $Log" }
}
}
}
@@ -0,0 +1,385 @@
seed,recipe,compiler,workers,tiles,lod_min,lod_max,min_x,min_y,min_z,max_x,max_y,max_z,density_hash,mesh_hash,payload_hash,topology_hash,whole_view_ready_s,wall_s,peak_rss_kib,exit_code,status
-1990830953,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.124,0.139871,82432,0,PASS
-1990830953,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.447,0.472868,277576,0,PASS
-1990830953,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.104,0.120573,83292,0,PASS
-1990830953,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.418,0.444282,277964,0,PASS
-1990830953,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,0.913,0.929393,83896,0,PASS
-1990830953,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,0.611,0.639175,286112,0,PASS
-1990830953,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,1.007,1.024022,84836,0,PASS
-1990830953,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,0.604,0.631134,287396,0,PASS
-1900684165,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.122,0.138823,87580,0,PASS
-1900684165,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.443,0.470531,282936,0,PASS
-1900684165,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.115,0.131311,88568,0,PASS
-1900684165,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.430,0.455647,283260,0,PASS
-1900684165,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,1.468,1.485107,88252,0,PASS
-1900684165,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,0.724,0.749926,291776,0,PASS
-1900684165,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,1.654,1.671498,88740,0,PASS
-1900684165,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,0.722,0.748795,292444,0,PASS
-1766412538,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.123,0.139772,82472,0,PASS
-1766412538,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.421,0.446302,277376,0,PASS
-1766412538,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.118,0.135907,82932,0,PASS
-1766412538,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.413,0.439059,278060,0,PASS
-1766412538,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,1.182,1.198659,83916,0,PASS
-1766412538,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,0.635,0.661517,288544,0,PASS
-1766412538,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,1.217,1.234070,84676,0,PASS
-1766412538,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,0.641,0.668605,289160,0,PASS
-1721984596,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.135727,82528,0,PASS
-1721984596,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.412,0.437074,277672,0,PASS
-1721984596,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.111,0.126643,83176,0,PASS
-1721984596,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.443825,278120,0,PASS
-1721984596,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,1.217,1.234173,84404,0,PASS
-1721984596,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,0.637,0.663034,287872,0,PASS
-1721984596,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,1.317,1.333028,84808,0,PASS
-1721984596,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,0.655,0.681308,287700,0,PASS
-1239598758,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.298,0.314757,83276,0,PASS
-1239598758,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.445,0.471042,288560,0,PASS
-1239598758,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.285,0.301659,84036,0,PASS
-1239598758,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.443,0.468361,288380,0,PASS
-1239598758,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,1.387,1.403191,84688,0,PASS
-1239598758,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,0.673,0.699757,289244,0,PASS
-1239598758,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,1.443,1.458164,85260,0,PASS
-1239598758,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,0.687,0.712986,289888,0,PASS
-1085993262,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.146,0.161610,83596,0,PASS
-1085993262,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.434,0.459626,280092,0,PASS
-1085993262,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.137,0.155311,84108,0,PASS
-1085993262,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.429,0.457999,280480,0,PASS
-1085993262,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,1.270,1.286525,86016,0,PASS
-1085993262,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,0.627,0.653909,289560,0,PASS
-1085993262,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,1.410,1.427078,86780,0,PASS
-1085993262,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,0.648,0.673667,290288,0,PASS
-1033703345,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.153,0.171501,82920,0,PASS
-1033703345,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.433,0.459168,278696,0,PASS
-1033703345,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.146,0.161211,83612,0,PASS
-1033703345,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.436,0.462555,279276,0,PASS
-1033703345,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,2.179,2.196290,84960,0,PASS
-1033703345,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,0.837,0.862488,286132,0,PASS
-1033703345,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,2.229,2.245540,85384,0,PASS
-1033703345,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,0.854,0.878634,286968,0,PASS
-854671705,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.168,0.184503,81968,0,PASS
-854671705,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.458,0.482105,276888,0,PASS
-854671705,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.156,0.172642,82296,0,PASS
-854671705,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.440,0.463845,277156,0,PASS
-854671705,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,1.997,2.014139,83980,0,PASS
-854671705,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,0.777,0.803614,286988,0,PASS
-854671705,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,1.975,1.991424,84460,0,PASS
-854671705,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,0.827,0.853700,287876,0,PASS
-713963806,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.116,0.133079,83972,0,PASS
-713963806,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.403,0.432000,278940,0,PASS
-713963806,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.103,0.119423,84248,0,PASS
-713963806,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.395,0.419569,279096,0,PASS
-713963806,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,1.614,1.634105,84584,0,PASS
-713963806,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,0.696,0.722153,287504,0,PASS
-713963806,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,1.642,1.658169,84804,0,PASS
-713963806,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,0.702,0.728362,287544,0,PASS
-621039221,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.108,0.123847,84240,0,PASS
-621039221,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.404,0.429052,279360,0,PASS
-621039221,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.097,0.114239,84872,0,PASS
-621039221,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.418,0.445942,279796,0,PASS
-621039221,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,1.740,1.756998,85916,0,PASS
-621039221,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,0.736,0.762822,290788,0,PASS
-621039221,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,1.779,1.795250,86420,0,PASS
-621039221,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,0.767,0.793669,291496,0,PASS
-474448608,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.126682,82408,0,PASS
-474448608,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.420,0.445710,277208,0,PASS
-474448608,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.131780,83016,0,PASS
-474448608,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.408,0.434334,277788,0,PASS
-474448608,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,1.639,1.655937,85268,0,PASS
-474448608,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,0.748,0.775722,289208,0,PASS
-474448608,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,1.756,1.771783,86096,0,PASS
-474448608,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,0.758,0.784193,289568,0,PASS
-432690581,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.249,0.264467,83624,0,PASS
-432690581,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.457,0.482472,286124,0,PASS
-432690581,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.251,0.267531,83844,0,PASS
-432690581,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.456,0.481234,286612,0,PASS
-432690581,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,1.465,1.481966,84272,0,PASS
-432690581,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,0.651,0.678094,286596,0,PASS
-432690581,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,1.518,1.534396,84508,0,PASS
-432690581,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,0.675,0.700961,287236,0,PASS
-380556572,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.122,0.138061,83744,0,PASS
-380556572,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.443950,278968,0,PASS
-380556572,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.119,0.136000,84296,0,PASS
-380556572,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.409,0.435025,279452,0,PASS
-380556572,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.903,0.918921,85380,0,PASS
-380556572,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.587,0.614393,289360,0,PASS
-380556572,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.983,0.998686,85572,0,PASS
-380556572,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.567,0.592607,290168,0,PASS
-238925630,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121729,82080,0,PASS
-238925630,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.426,0.453650,277360,0,PASS
-238925630,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.120742,82848,0,PASS
-238925630,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.391,0.417157,277784,0,PASS
-238925630,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,2.159,2.174883,84956,0,PASS
-238925630,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,0.798,0.823378,286820,0,PASS
-238925630,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,2.135,2.151003,86032,0,PASS
-238925630,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,0.848,0.872951,287200,0,PASS
-216679974,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.113,0.128975,84840,0,PASS
-216679974,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.424,0.448196,279868,0,PASS
-216679974,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.110,0.125699,85388,0,PASS
-216679974,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.443897,280212,0,PASS
-216679974,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,1.154,1.170155,87404,0,PASS
-216679974,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,0.599,0.627832,291380,0,PASS
-216679974,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,1.244,1.260024,88080,0,PASS
-216679974,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,0.652,0.682174,292220,0,PASS
-133096164,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.137668,83564,0,PASS
-133096164,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.416,0.440317,278792,0,PASS
-133096164,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.129823,84168,0,PASS
-133096164,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.430509,278888,0,PASS
-133096164,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,0.922,0.937785,84360,0,PASS
-133096164,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,0.589,0.618394,288344,0,PASS
-133096164,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,1.012,1.027635,84716,0,PASS
-133096164,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,0.635,0.660045,288680,0,PASS
-112366806,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.243,0.260958,84464,0,PASS
-112366806,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.493,0.519148,283500,0,PASS
-112366806,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.227,0.243726,84772,0,PASS
-112366806,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.465,0.489473,284084,0,PASS
-112366806,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,1.309,1.326524,85228,0,PASS
-112366806,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,0.701,0.726986,287836,0,PASS
-112366806,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,1.395,1.411147,85016,0,PASS
-112366806,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,0.739,0.765027,288736,0,PASS
0,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.119,0.135072,84800,0,PASS
0,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.426,0.451782,279552,0,PASS
0,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.113,0.128723,84848,0,PASS
0,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.420,0.445716,280480,0,PASS
0,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,1.559,1.574177,85036,0,PASS
0,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,0.717,0.744287,287992,0,PASS
0,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,1.736,1.751668,85428,0,PASS
0,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,0.739,0.765220,288024,0,PASS
5808593,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.138,0.152855,82892,0,PASS
5808593,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.442,0.467475,277756,0,PASS
5808593,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.135,0.152123,83220,0,PASS
5808593,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.455,0.480133,278336,0,PASS
5808593,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,1.035,1.051725,84148,0,PASS
5808593,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,0.590,0.616756,287312,0,PASS
5808593,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,1.066,1.081777,85048,0,PASS
5808593,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,0.607,0.633661,287888,0,PASS
28573228,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.129946,83304,0,PASS
28573228,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.413,0.438628,278012,0,PASS
28573228,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121266,83976,0,PASS
28573228,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.430367,278532,0,PASS
28573228,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,1.328,1.344479,84096,0,PASS
28573228,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,0.657,0.682189,287896,0,PASS
28573228,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,1.475,1.493744,84604,0,PASS
28573228,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,0.688,0.715502,288240,0,PASS
70955227,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.122,0.139162,83836,0,PASS
70955227,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.446187,279048,0,PASS
70955227,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.118,0.133338,84804,0,PASS
70955227,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.428654,279540,0,PASS
70955227,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,1.560,1.576865,86016,0,PASS
70955227,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,0.849,0.882918,288164,0,PASS
70955227,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,1.635,1.651152,86548,0,PASS
70955227,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,0.767,0.793113,288924,0,PASS
75274690,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.129015,83520,0,PASS
75274690,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.432266,278808,0,PASS
75274690,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.107,0.122969,84248,0,PASS
75274690,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.400,0.425046,279232,0,PASS
75274690,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,1.140,1.158530,86028,0,PASS
75274690,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,0.635,0.661364,290020,0,PASS
75274690,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,1.237,1.253451,86900,0,PASS
75274690,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,0.629,0.657284,290424,0,PASS
81375760,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.302,0.321425,84348,0,PASS
81375760,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.473,0.498702,288596,0,PASS
81375760,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.284,0.300131,84776,0,PASS
81375760,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.465,0.493912,289032,0,PASS
81375760,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,1.644,1.660225,85756,0,PASS
81375760,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,0.738,0.765107,289596,0,PASS
81375760,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,1.724,1.741866,86704,0,PASS
81375760,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,0.751,0.778126,289620,0,PASS
146979566,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.146,0.162199,83420,0,PASS
146979566,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.434165,281384,0,PASS
146979566,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.154,0.171817,84220,0,PASS
146979566,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.404,0.429003,282144,0,PASS
146979566,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,1.638,1.654237,86300,0,PASS
146979566,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,0.698,0.725703,289448,0,PASS
146979566,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,1.845,1.861845,86680,0,PASS
146979566,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,0.759,0.786078,290128,0,PASS
244951180,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.195,0.213011,86480,0,PASS
244951180,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.452,0.479860,284556,0,PASS
244951180,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.181,0.197358,87220,0,PASS
244951180,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.434,0.459596,284852,0,PASS
244951180,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,1.121,1.137204,86652,0,PASS
244951180,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,0.603,0.628602,289720,0,PASS
244951180,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,1.192,1.207485,87296,0,PASS
244951180,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,0.638,0.665330,290548,0,PASS
245433414,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.131222,82516,0,PASS
245433414,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.408,0.432991,277848,0,PASS
245433414,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.100,0.115984,83136,0,PASS
245433414,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.444156,277616,0,PASS
245433414,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,1.203,1.220959,86352,0,PASS
245433414,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,0.630,0.655544,290084,0,PASS
245433414,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,1.279,1.296620,86904,0,PASS
245433414,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,0.664,0.692096,290640,0,PASS
277442974,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.190,0.206505,84588,0,PASS
277442974,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.498,0.524538,279420,0,PASS
277442974,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.188,0.203434,85052,0,PASS
277442974,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.493,0.518404,279564,0,PASS
277442974,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,1.322,1.338231,87924,0,PASS
277442974,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,0.676,0.700980,292844,0,PASS
277442974,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,1.366,1.382495,88588,0,PASS
277442974,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,0.701,0.727447,293072,0,PASS
297746112,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.245,0.260033,85384,0,PASS
297746112,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.465,0.490415,288008,0,PASS
297746112,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.243,0.258435,86024,0,PASS
297746112,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.471,0.498359,288480,0,PASS
297746112,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,1.652,1.667443,86192,0,PASS
297746112,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,0.747,0.773312,289872,0,PASS
297746112,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,1.731,1.748813,86708,0,PASS
297746112,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,0.764,0.789221,290484,0,PASS
336768467,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.128946,82460,0,PASS
336768467,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.445300,277468,0,PASS
336768467,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.110,0.125258,83208,0,PASS
336768467,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.397,0.423317,278004,0,PASS
336768467,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,1.629,1.646272,85052,0,PASS
336768467,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,0.728,0.754451,288124,0,PASS
336768467,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,1.705,1.720538,85388,0,PASS
336768467,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,0.738,0.766954,288356,0,PASS
512532080,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.153,0.168716,82560,0,PASS
512532080,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.440,0.467645,277488,0,PASS
512532080,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.143,0.159069,82904,0,PASS
512532080,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.445,0.469304,277704,0,PASS
512532080,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,1.226,1.242263,84388,0,PASS
512532080,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,0.629,0.654951,288556,0,PASS
512532080,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,1.360,1.375755,85232,0,PASS
512532080,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,0.672,0.697654,289308,0,PASS
821120640,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.153,0.168054,82828,0,PASS
821120640,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.462,0.487309,277536,0,PASS
821120640,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.149,0.163984,82908,0,PASS
821120640,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.445,0.471081,277668,0,PASS
821120640,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,1.491,1.507224,85000,0,PASS
821120640,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,0.700,0.726549,289052,0,PASS
821120640,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,1.661,1.677544,85416,0,PASS
821120640,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,0.775,0.801706,289404,0,PASS
853538490,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.351,0.367197,83708,0,PASS
853538490,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.498,0.524390,287376,0,PASS
853538490,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.309,0.325235,84408,0,PASS
853538490,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.503,0.529485,287824,0,PASS
853538490,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,1.594,1.609537,84548,0,PASS
853538490,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,0.744,0.770634,287636,0,PASS
853538490,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,1.565,1.581727,85352,0,PASS
853538490,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,0.783,0.809731,287652,0,PASS
861026696,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.140722,84164,0,PASS
861026696,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.424,0.450365,279168,0,PASS
861026696,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.128137,84788,0,PASS
861026696,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.404,0.429204,279848,0,PASS
861026696,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,1.511,1.528290,85840,0,PASS
861026696,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,0.690,0.716270,288668,0,PASS
861026696,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,1.581,1.598332,86244,0,PASS
861026696,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,0.737,0.763910,288720,0,PASS
1026251636,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.125,0.140307,87376,0,PASS
1026251636,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.431,0.456676,282440,0,PASS
1026251636,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.136933,87768,0,PASS
1026251636,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.410,0.435138,282592,0,PASS
1026251636,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,2.194,2.209401,90204,0,PASS
1026251636,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,0.851,0.878001,292176,0,PASS
1026251636,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,2.274,2.290952,90476,0,PASS
1026251636,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,0.835,0.863009,292140,0,PASS
1077415394,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.146,0.163297,86188,0,PASS
1077415394,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.414,0.439121,283756,0,PASS
1077415394,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.148,0.168584,86796,0,PASS
1077415394,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.426,0.450855,284368,0,PASS
1077415394,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,1.601,1.617268,87912,0,PASS
1077415394,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,0.699,0.725603,292220,0,PASS
1077415394,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,1.727,1.745677,88476,0,PASS
1077415394,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,0.833,0.867727,292828,0,PASS
1130999017,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.291,0.307690,85160,0,PASS
1130999017,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.452,0.481022,289968,0,PASS
1130999017,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.266,0.282332,85784,0,PASS
1130999017,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.444,0.470657,290324,0,PASS
1130999017,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,1.472,1.489302,84108,0,PASS
1130999017,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,0.713,0.738699,287528,0,PASS
1130999017,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,1.530,1.545977,84776,0,PASS
1130999017,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,0.685,0.710911,288188,0,PASS
1156488597,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.121,0.139125,83040,0,PASS
1156488597,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.403,0.428569,278288,0,PASS
1156488597,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.109,0.125855,83948,0,PASS
1156488597,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.425,0.450644,278660,0,PASS
1156488597,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,1.216,1.232170,85424,0,PASS
1156488597,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,0.645,0.670839,287908,0,PASS
1156488597,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,1.312,1.328475,86080,0,PASS
1156488597,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,0.704,0.729815,288444,0,PASS
1172304228,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.109,0.123809,82616,0,PASS
1172304228,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.431733,277580,0,PASS
1172304228,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.101,0.115688,82980,0,PASS
1172304228,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.432724,277708,0,PASS
1172304228,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.869,0.885113,85556,0,PASS
1172304228,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.584,0.611186,288244,0,PASS
1172304228,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.964,0.980259,85884,0,PASS
1172304228,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.611,0.636011,289012,0,PASS
1370340570,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121360,82860,0,PASS
1370340570,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.413,0.439779,277640,0,PASS
1370340570,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.105,0.120822,83596,0,PASS
1370340570,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.406,0.430247,278132,0,PASS
1370340570,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,1.678,1.694262,85176,0,PASS
1370340570,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,0.691,0.717560,287996,0,PASS
1370340570,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,1.820,1.836129,85504,0,PASS
1370340570,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,0.768,0.793448,288372,0,PASS
1383925073,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.129033,81792,0,PASS
1383925073,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.401,0.427476,277224,0,PASS
1383925073,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.105,0.120673,82892,0,PASS
1383925073,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.402,0.425822,277488,0,PASS
1383925073,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,1.772,1.788831,84816,0,PASS
1383925073,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,0.882,0.907588,287224,0,PASS
1383925073,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,1.870,1.886415,84956,0,PASS
1383925073,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,0.907,0.933394,287936,0,PASS
1401164998,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.287,0.303400,84652,0,PASS
1401164998,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.478,0.503793,287484,0,PASS
1401164998,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.275,0.290885,85324,0,PASS
1401164998,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.467,0.494139,288496,0,PASS
1401164998,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,1.963,1.979104,84732,0,PASS
1401164998,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,0.747,0.775087,287448,0,PASS
1401164998,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,1.910,1.926095,85012,0,PASS
1401164998,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,0.798,0.823400,288392,0,PASS
1558879574,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.115,0.132445,81992,0,PASS
1558879574,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.422,0.447714,276768,0,PASS
1558879574,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.103,0.119871,82376,0,PASS
1558879574,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.421,0.447570,277272,0,PASS
1558879574,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.920,0.936756,83620,0,PASS
1558879574,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.595,0.621724,287708,0,PASS
1558879574,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.939,0.954884,84488,0,PASS
1558879574,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.600,0.626689,288548,0,PASS
1753015542,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121516,83192,0,PASS
1753015542,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.420,0.448397,278160,0,PASS
1753015542,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.110,0.129636,83988,0,PASS
1753015542,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.431222,278696,0,PASS
1753015542,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,1.661,1.678331,85292,0,PASS
1753015542,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,0.725,0.750781,288032,0,PASS
1753015542,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,1.786,1.802204,86188,0,PASS
1753015542,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,0.739,0.765903,288808,0,PASS
1827697875,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.122073,84540,0,PASS
1827697875,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.412,0.435966,279476,0,PASS
1827697875,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.105,0.121830,84676,0,PASS
1827697875,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.409,0.434709,279752,0,PASS
1827697875,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,1.666,1.681850,89140,0,PASS
1827697875,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,0.739,0.764550,292172,0,PASS
1827697875,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,1.784,1.800585,89620,0,PASS
1827697875,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,0.774,0.801097,293460,0,PASS
1909311298,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.126,0.140793,81792,0,PASS
1909311298,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.454,0.479793,277000,0,PASS
1909311298,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.119,0.138021,82780,0,PASS
1909311298,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.439,0.465770,277320,0,PASS
1909311298,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,1.677,1.692282,84504,0,PASS
1909311298,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,0.726,0.753056,287464,0,PASS
1909311298,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,1.895,1.911071,84364,0,PASS
1909311298,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,0.754,0.781499,287952,0,PASS
2011898099,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.113,0.129139,83892,0,PASS
2011898099,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.433,0.459151,278756,0,PASS
2011898099,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.103,0.117822,84760,0,PASS
2011898099,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.428,0.456161,279268,0,PASS
2011898099,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,1.148,1.163696,87080,0,PASS
2011898099,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,0.624,0.651689,289916,0,PASS
2011898099,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,1.234,1.252059,87640,0,PASS
2011898099,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,0.650,0.677250,290788,0,PASS
2015768509,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.319,0.335248,82712,0,PASS
2015768509,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.497,0.523192,286708,0,PASS
2015768509,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.280,0.296244,83728,0,PASS
2015768509,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.479,0.505113,287436,0,PASS
2015768509,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,1.490,1.506239,84120,0,PASS
2015768509,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,0.717,0.744393,288996,0,PASS
2015768509,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,1.600,1.617351,84900,0,PASS
2015768509,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,0.742,0.769135,289484,0,PASS
2070776516,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.126,0.141678,81840,0,PASS
2070776516,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.430,0.456364,276976,0,PASS
2070776516,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.131120,82540,0,PASS
2070776516,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.401,0.425293,277436,0,PASS
2070776516,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,0.998,1.014096,84548,0,PASS
2070776516,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,0.575,0.600529,286932,0,PASS
2070776516,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,1.054,1.070063,84768,0,PASS
2070776516,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,0.597,0.622079,287140,0,PASS
1 seed recipe compiler workers tiles lod_min lod_max min_x min_y min_z max_x max_y max_z density_hash mesh_hash payload_hash topology_hash whole_view_ready_s wall_s peak_rss_kib exit_code status
2 -1990830953 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.124 0.139871 82432 0 PASS
3 -1990830953 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.447 0.472868 277576 0 PASS
4 -1990830953 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.104 0.120573 83292 0 PASS
5 -1990830953 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.418 0.444282 277964 0 PASS
6 -1990830953 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xbd4dd4a500b8d62e 0xe1d28012b857510b 0x3ecc1269ee435844 0x10c100e1503e62f6 0.913 0.929393 83896 0 PASS
7 -1990830953 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xbd4dd4a500b8d62e 0xe1d28012b857510b 0x3ecc1269ee435844 0x10c100e1503e62f6 0.611 0.639175 286112 0 PASS
8 -1990830953 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xbd4dd4a500b8d62e 0xe1d28012b857510b 0x3ecc1269ee435844 0x10c100e1503e62f6 1.007 1.024022 84836 0 PASS
9 -1990830953 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xbd4dd4a500b8d62e 0xe1d28012b857510b 0x3ecc1269ee435844 0x10c100e1503e62f6 0.604 0.631134 287396 0 PASS
10 -1900684165 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.122 0.138823 87580 0 PASS
11 -1900684165 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.443 0.470531 282936 0 PASS
12 -1900684165 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.115 0.131311 88568 0 PASS
13 -1900684165 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.430 0.455647 283260 0 PASS
14 -1900684165 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x6579d1933b1981fa 0xfd19fc2d3a0c84b3 0xb8c9aa5ec03bea15 0x854620bb0b15a2da 1.468 1.485107 88252 0 PASS
15 -1900684165 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x6579d1933b1981fa 0xfd19fc2d3a0c84b3 0xb8c9aa5ec03bea15 0x854620bb0b15a2da 0.724 0.749926 291776 0 PASS
16 -1900684165 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x6579d1933b1981fa 0xfd19fc2d3a0c84b3 0xb8c9aa5ec03bea15 0x854620bb0b15a2da 1.654 1.671498 88740 0 PASS
17 -1900684165 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x6579d1933b1981fa 0xfd19fc2d3a0c84b3 0xb8c9aa5ec03bea15 0x854620bb0b15a2da 0.722 0.748795 292444 0 PASS
18 -1766412538 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.123 0.139772 82472 0 PASS
19 -1766412538 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.421 0.446302 277376 0 PASS
20 -1766412538 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.118 0.135907 82932 0 PASS
21 -1766412538 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.413 0.439059 278060 0 PASS
22 -1766412538 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x2a92f5e32e60e02f 0x8f64e72825b53b77 0xc8ef053d65d9a8f2 0xf908b7c927a221be 1.182 1.198659 83916 0 PASS
23 -1766412538 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x2a92f5e32e60e02f 0x8f64e72825b53b77 0xc8ef053d65d9a8f2 0xf908b7c927a221be 0.635 0.661517 288544 0 PASS
24 -1766412538 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x2a92f5e32e60e02f 0x8f64e72825b53b77 0xc8ef053d65d9a8f2 0xf908b7c927a221be 1.217 1.234070 84676 0 PASS
25 -1766412538 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x2a92f5e32e60e02f 0x8f64e72825b53b77 0xc8ef053d65d9a8f2 0xf908b7c927a221be 0.641 0.668605 289160 0 PASS
26 -1721984596 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.120 0.135727 82528 0 PASS
27 -1721984596 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.412 0.437074 277672 0 PASS
28 -1721984596 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.111 0.126643 83176 0 PASS
29 -1721984596 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.419 0.443825 278120 0 PASS
30 -1721984596 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x232835b6d49194bf 0x1caaf34cc5d6cd64 0x03053c530184f232 0xb660395e0dc7fd90 1.217 1.234173 84404 0 PASS
31 -1721984596 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x232835b6d49194bf 0x1caaf34cc5d6cd64 0x03053c530184f232 0xb660395e0dc7fd90 0.637 0.663034 287872 0 PASS
32 -1721984596 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x232835b6d49194bf 0x1caaf34cc5d6cd64 0x03053c530184f232 0xb660395e0dc7fd90 1.317 1.333028 84808 0 PASS
33 -1721984596 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x232835b6d49194bf 0x1caaf34cc5d6cd64 0x03053c530184f232 0xb660395e0dc7fd90 0.655 0.681308 287700 0 PASS
34 -1239598758 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x0bf609e90c8c98cd 0x73cd83a10b4aada9 0x4eba3fd151b267a4 0x559a118b768faf58 0.298 0.314757 83276 0 PASS
35 -1239598758 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x0bf609e90c8c98cd 0x73cd83a10b4aada9 0x4eba3fd151b267a4 0x559a118b768faf58 0.445 0.471042 288560 0 PASS
36 -1239598758 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x0bf609e90c8c98cd 0x73cd83a10b4aada9 0x4eba3fd151b267a4 0x559a118b768faf58 0.285 0.301659 84036 0 PASS
37 -1239598758 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x0bf609e90c8c98cd 0x73cd83a10b4aada9 0x4eba3fd151b267a4 0x559a118b768faf58 0.443 0.468361 288380 0 PASS
38 -1239598758 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x13ec8dd8009a6ca3 0xa834791c4bf4a3a6 0xf75429e19a3d3f57 0xec51f6ca14f0103f 1.387 1.403191 84688 0 PASS
39 -1239598758 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x13ec8dd8009a6ca3 0xa834791c4bf4a3a6 0xf75429e19a3d3f57 0xec51f6ca14f0103f 0.673 0.699757 289244 0 PASS
40 -1239598758 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x13ec8dd8009a6ca3 0xa834791c4bf4a3a6 0xf75429e19a3d3f57 0xec51f6ca14f0103f 1.443 1.458164 85260 0 PASS
41 -1239598758 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x13ec8dd8009a6ca3 0xa834791c4bf4a3a6 0xf75429e19a3d3f57 0xec51f6ca14f0103f 0.687 0.712986 289888 0 PASS
42 -1085993262 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x58d4e8746928d967 0x40dd37203989d7ba 0x912a7f27bda7e867 0x3aaea1143bebf060 0.146 0.161610 83596 0 PASS
43 -1085993262 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x58d4e8746928d967 0x40dd37203989d7ba 0x912a7f27bda7e867 0x3aaea1143bebf060 0.434 0.459626 280092 0 PASS
44 -1085993262 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x58d4e8746928d967 0x40dd37203989d7ba 0x912a7f27bda7e867 0x3aaea1143bebf060 0.137 0.155311 84108 0 PASS
45 -1085993262 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x58d4e8746928d967 0x40dd37203989d7ba 0x912a7f27bda7e867 0x3aaea1143bebf060 0.429 0.457999 280480 0 PASS
46 -1085993262 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x2f2773f2a0da46ab 0x3bc615085f3da506 0xf696b9a9fcf6e3e6 0x7726f0e025442908 1.270 1.286525 86016 0 PASS
47 -1085993262 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x2f2773f2a0da46ab 0x3bc615085f3da506 0xf696b9a9fcf6e3e6 0x7726f0e025442908 0.627 0.653909 289560 0 PASS
48 -1085993262 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x2f2773f2a0da46ab 0x3bc615085f3da506 0xf696b9a9fcf6e3e6 0x7726f0e025442908 1.410 1.427078 86780 0 PASS
49 -1085993262 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x2f2773f2a0da46ab 0x3bc615085f3da506 0xf696b9a9fcf6e3e6 0x7726f0e025442908 0.648 0.673667 290288 0 PASS
50 -1033703345 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x5e33a829837b74bd 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.153 0.171501 82920 0 PASS
51 -1033703345 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x5e33a829837b74bd 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.433 0.459168 278696 0 PASS
52 -1033703345 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x5e33a829837b74bd 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.146 0.161211 83612 0 PASS
53 -1033703345 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x5e33a829837b74bd 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.436 0.462555 279276 0 PASS
54 -1033703345 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x65b606ed9df8b9dd 0x874360dc2d5480ad 0xe1a7c4c63c916b8a 0xf8bfac0093f57137 2.179 2.196290 84960 0 PASS
55 -1033703345 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x65b606ed9df8b9dd 0x874360dc2d5480ad 0xe1a7c4c63c916b8a 0xf8bfac0093f57137 0.837 0.862488 286132 0 PASS
56 -1033703345 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x65b606ed9df8b9dd 0x874360dc2d5480ad 0xe1a7c4c63c916b8a 0xf8bfac0093f57137 2.229 2.245540 85384 0 PASS
57 -1033703345 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x65b606ed9df8b9dd 0x874360dc2d5480ad 0xe1a7c4c63c916b8a 0xf8bfac0093f57137 0.854 0.878634 286968 0 PASS
58 -854671705 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.168 0.184503 81968 0 PASS
59 -854671705 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.458 0.482105 276888 0 PASS
60 -854671705 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.156 0.172642 82296 0 PASS
61 -854671705 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.440 0.463845 277156 0 PASS
62 -854671705 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xb324a85fd9f31fa1 0x92f35776d53f0bbe 0x5b4e0dc015e5a4b1 0x3dcce3ff950e5940 1.997 2.014139 83980 0 PASS
63 -854671705 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xb324a85fd9f31fa1 0x92f35776d53f0bbe 0x5b4e0dc015e5a4b1 0x3dcce3ff950e5940 0.777 0.803614 286988 0 PASS
64 -854671705 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xb324a85fd9f31fa1 0x92f35776d53f0bbe 0x5b4e0dc015e5a4b1 0x3dcce3ff950e5940 1.975 1.991424 84460 0 PASS
65 -854671705 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xb324a85fd9f31fa1 0x92f35776d53f0bbe 0x5b4e0dc015e5a4b1 0x3dcce3ff950e5940 0.827 0.853700 287876 0 PASS
66 -713963806 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.116 0.133079 83972 0 PASS
67 -713963806 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.403 0.432000 278940 0 PASS
68 -713963806 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.103 0.119423 84248 0 PASS
69 -713963806 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.395 0.419569 279096 0 PASS
70 -713963806 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x38a60c8389c671eb 0xcbca321fa24f4d74 0x6aa8ea9d8c735dbb 0x8b9d8e479ea5329e 1.614 1.634105 84584 0 PASS
71 -713963806 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x38a60c8389c671eb 0xcbca321fa24f4d74 0x6aa8ea9d8c735dbb 0x8b9d8e479ea5329e 0.696 0.722153 287504 0 PASS
72 -713963806 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x38a60c8389c671eb 0xcbca321fa24f4d74 0x6aa8ea9d8c735dbb 0x8b9d8e479ea5329e 1.642 1.658169 84804 0 PASS
73 -713963806 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x38a60c8389c671eb 0xcbca321fa24f4d74 0x6aa8ea9d8c735dbb 0x8b9d8e479ea5329e 0.702 0.728362 287544 0 PASS
74 -621039221 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.108 0.123847 84240 0 PASS
75 -621039221 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.404 0.429052 279360 0 PASS
76 -621039221 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.097 0.114239 84872 0 PASS
77 -621039221 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.418 0.445942 279796 0 PASS
78 -621039221 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xa70bd050fb2e002e 0x93c9bfa37a0cd298 0x5fd74cd54a52292b 0x194b571023058cf7 1.740 1.756998 85916 0 PASS
79 -621039221 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xa70bd050fb2e002e 0x93c9bfa37a0cd298 0x5fd74cd54a52292b 0x194b571023058cf7 0.736 0.762822 290788 0 PASS
80 -621039221 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xa70bd050fb2e002e 0x93c9bfa37a0cd298 0x5fd74cd54a52292b 0x194b571023058cf7 1.779 1.795250 86420 0 PASS
81 -621039221 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xa70bd050fb2e002e 0x93c9bfa37a0cd298 0x5fd74cd54a52292b 0x194b571023058cf7 0.767 0.793669 291496 0 PASS
82 -474448608 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.112 0.126682 82408 0 PASS
83 -474448608 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.420 0.445710 277208 0 PASS
84 -474448608 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.114 0.131780 83016 0 PASS
85 -474448608 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.408 0.434334 277788 0 PASS
86 -474448608 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x80da251d7da20717 0x54a773cac2ae0da4 0xb42e970d98e5e448 0x08d56fddf5a487d6 1.639 1.655937 85268 0 PASS
87 -474448608 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x80da251d7da20717 0x54a773cac2ae0da4 0xb42e970d98e5e448 0x08d56fddf5a487d6 0.748 0.775722 289208 0 PASS
88 -474448608 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x80da251d7da20717 0x54a773cac2ae0da4 0xb42e970d98e5e448 0x08d56fddf5a487d6 1.756 1.771783 86096 0 PASS
89 -474448608 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x80da251d7da20717 0x54a773cac2ae0da4 0xb42e970d98e5e448 0x08d56fddf5a487d6 0.758 0.784193 289568 0 PASS
90 -432690581 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x1e3b98fa361c46b9 0x510dd77a7ca94d0e 0x4e6917a7b06f3f41 0x09791c912e85d14a 0.249 0.264467 83624 0 PASS
91 -432690581 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x1e3b98fa361c46b9 0x510dd77a7ca94d0e 0x4e6917a7b06f3f41 0x09791c912e85d14a 0.457 0.482472 286124 0 PASS
92 -432690581 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x1e3b98fa361c46b9 0x510dd77a7ca94d0e 0x4e6917a7b06f3f41 0x09791c912e85d14a 0.251 0.267531 83844 0 PASS
93 -432690581 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x1e3b98fa361c46b9 0x510dd77a7ca94d0e 0x4e6917a7b06f3f41 0x09791c912e85d14a 0.456 0.481234 286612 0 PASS
94 -432690581 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x85185a56cb2ff97a 0x656076e11a4da13b 0x708d7e58be02ab16 0xfa20cfd819664d48 1.465 1.481966 84272 0 PASS
95 -432690581 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x85185a56cb2ff97a 0x656076e11a4da13b 0x708d7e58be02ab16 0xfa20cfd819664d48 0.651 0.678094 286596 0 PASS
96 -432690581 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x85185a56cb2ff97a 0x656076e11a4da13b 0x708d7e58be02ab16 0xfa20cfd819664d48 1.518 1.534396 84508 0 PASS
97 -432690581 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x85185a56cb2ff97a 0x656076e11a4da13b 0x708d7e58be02ab16 0xfa20cfd819664d48 0.675 0.700961 287236 0 PASS
98 -380556572 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.122 0.138061 83744 0 PASS
99 -380556572 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.419 0.443950 278968 0 PASS
100 -380556572 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.119 0.136000 84296 0 PASS
101 -380556572 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.409 0.435025 279452 0 PASS
102 -380556572 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x18cb13a590f41d1f 0xdb9b7450859f053a 0x5dc9ac331ba35450 0x8cda9fbcede81e46 0.903 0.918921 85380 0 PASS
103 -380556572 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x18cb13a590f41d1f 0xdb9b7450859f053a 0x5dc9ac331ba35450 0x8cda9fbcede81e46 0.587 0.614393 289360 0 PASS
104 -380556572 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x18cb13a590f41d1f 0xdb9b7450859f053a 0x5dc9ac331ba35450 0x8cda9fbcede81e46 0.983 0.998686 85572 0 PASS
105 -380556572 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x18cb13a590f41d1f 0xdb9b7450859f053a 0x5dc9ac331ba35450 0x8cda9fbcede81e46 0.567 0.592607 290168 0 PASS
106 -238925630 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.106 0.121729 82080 0 PASS
107 -238925630 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.426 0.453650 277360 0 PASS
108 -238925630 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.106 0.120742 82848 0 PASS
109 -238925630 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.391 0.417157 277784 0 PASS
110 -238925630 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x3b99d22e2baa2ad7 0xf8a56dd82f8dbe0f 0x91fbb129908c4373 0x0d0d12d4bc8eca05 2.159 2.174883 84956 0 PASS
111 -238925630 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x3b99d22e2baa2ad7 0xf8a56dd82f8dbe0f 0x91fbb129908c4373 0x0d0d12d4bc8eca05 0.798 0.823378 286820 0 PASS
112 -238925630 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x3b99d22e2baa2ad7 0xf8a56dd82f8dbe0f 0x91fbb129908c4373 0x0d0d12d4bc8eca05 2.135 2.151003 86032 0 PASS
113 -238925630 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x3b99d22e2baa2ad7 0xf8a56dd82f8dbe0f 0x91fbb129908c4373 0x0d0d12d4bc8eca05 0.848 0.872951 287200 0 PASS
114 -216679974 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.113 0.128975 84840 0 PASS
115 -216679974 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.424 0.448196 279868 0 PASS
116 -216679974 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.110 0.125699 85388 0 PASS
117 -216679974 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.419 0.443897 280212 0 PASS
118 -216679974 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x329264ded82099ac 0x4fe355cb337a1fd9 0x0f1cf173f8b6da09 0x29c9025339a1891c 1.154 1.170155 87404 0 PASS
119 -216679974 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x329264ded82099ac 0x4fe355cb337a1fd9 0x0f1cf173f8b6da09 0x29c9025339a1891c 0.599 0.627832 291380 0 PASS
120 -216679974 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x329264ded82099ac 0x4fe355cb337a1fd9 0x0f1cf173f8b6da09 0x29c9025339a1891c 1.244 1.260024 88080 0 PASS
121 -216679974 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x329264ded82099ac 0x4fe355cb337a1fd9 0x0f1cf173f8b6da09 0x29c9025339a1891c 0.652 0.682174 292220 0 PASS
122 -133096164 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.120 0.137668 83564 0 PASS
123 -133096164 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.416 0.440317 278792 0 PASS
124 -133096164 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.112 0.129823 84168 0 PASS
125 -133096164 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.407 0.430509 278888 0 PASS
126 -133096164 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xd365848036423e24 0x8357d602689e662a 0x71d6cc040cfb374d 0xe50280db1b51428d 0.922 0.937785 84360 0 PASS
127 -133096164 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xd365848036423e24 0x8357d602689e662a 0x71d6cc040cfb374d 0xe50280db1b51428d 0.589 0.618394 288344 0 PASS
128 -133096164 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xd365848036423e24 0x8357d602689e662a 0x71d6cc040cfb374d 0xe50280db1b51428d 1.012 1.027635 84716 0 PASS
129 -133096164 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xd365848036423e24 0x8357d602689e662a 0x71d6cc040cfb374d 0xe50280db1b51428d 0.635 0.660045 288680 0 PASS
130 -112366806 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x117219c29ee67785 0x997b517646187e1a 0x85cb430517cbbf42 0x685ea038d9f06065 0.243 0.260958 84464 0 PASS
131 -112366806 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x117219c29ee67785 0x997b517646187e1a 0x85cb430517cbbf42 0x685ea038d9f06065 0.493 0.519148 283500 0 PASS
132 -112366806 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x117219c29ee67785 0x997b517646187e1a 0x85cb430517cbbf42 0x685ea038d9f06065 0.227 0.243726 84772 0 PASS
133 -112366806 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x117219c29ee67785 0x997b517646187e1a 0x85cb430517cbbf42 0x685ea038d9f06065 0.465 0.489473 284084 0 PASS
134 -112366806 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x9014ca6f9bc869cb 0x8b4f78faf1311e89 0x9556cf42e66d3d0a 0x74d6915603c033ad 1.309 1.326524 85228 0 PASS
135 -112366806 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x9014ca6f9bc869cb 0x8b4f78faf1311e89 0x9556cf42e66d3d0a 0x74d6915603c033ad 0.701 0.726986 287836 0 PASS
136 -112366806 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x9014ca6f9bc869cb 0x8b4f78faf1311e89 0x9556cf42e66d3d0a 0x74d6915603c033ad 1.395 1.411147 85016 0 PASS
137 -112366806 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x9014ca6f9bc869cb 0x8b4f78faf1311e89 0x9556cf42e66d3d0a 0x74d6915603c033ad 0.739 0.765027 288736 0 PASS
138 0 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.119 0.135072 84800 0 PASS
139 0 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.426 0.451782 279552 0 PASS
140 0 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.113 0.128723 84848 0 PASS
141 0 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.420 0.445716 280480 0 PASS
142 0 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xea74d3354b5ce671 0x476d49ae2a4ba2a6 0x16078fcd36b68ff0 0xcfb6c412b7118172 1.559 1.574177 85036 0 PASS
143 0 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xea74d3354b5ce671 0x476d49ae2a4ba2a6 0x16078fcd36b68ff0 0xcfb6c412b7118172 0.717 0.744287 287992 0 PASS
144 0 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xea74d3354b5ce671 0x476d49ae2a4ba2a6 0x16078fcd36b68ff0 0xcfb6c412b7118172 1.736 1.751668 85428 0 PASS
145 0 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xea74d3354b5ce671 0x476d49ae2a4ba2a6 0x16078fcd36b68ff0 0xcfb6c412b7118172 0.739 0.765220 288024 0 PASS
146 5808593 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.138 0.152855 82892 0 PASS
147 5808593 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.442 0.467475 277756 0 PASS
148 5808593 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.135 0.152123 83220 0 PASS
149 5808593 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.455 0.480133 278336 0 PASS
150 5808593 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xebd71c4fe9dd2dc6 0x9ffa12a70e6f7875 0x1a4ca0cc9847ee58 0xf19d80d6dd09e180 1.035 1.051725 84148 0 PASS
151 5808593 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xebd71c4fe9dd2dc6 0x9ffa12a70e6f7875 0x1a4ca0cc9847ee58 0xf19d80d6dd09e180 0.590 0.616756 287312 0 PASS
152 5808593 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xebd71c4fe9dd2dc6 0x9ffa12a70e6f7875 0x1a4ca0cc9847ee58 0xf19d80d6dd09e180 1.066 1.081777 85048 0 PASS
153 5808593 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xebd71c4fe9dd2dc6 0x9ffa12a70e6f7875 0x1a4ca0cc9847ee58 0xf19d80d6dd09e180 0.607 0.633661 287888 0 PASS
154 28573228 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.114 0.129946 83304 0 PASS
155 28573228 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.413 0.438628 278012 0 PASS
156 28573228 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.106 0.121266 83976 0 PASS
157 28573228 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.405 0.430367 278532 0 PASS
158 28573228 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x8bc79bd6b4d338f9 0xac4276d07d65ceb0 0x357351bb0d2f1cb8 0x900a254512dfc430 1.328 1.344479 84096 0 PASS
159 28573228 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x8bc79bd6b4d338f9 0xac4276d07d65ceb0 0x357351bb0d2f1cb8 0x900a254512dfc430 0.657 0.682189 287896 0 PASS
160 28573228 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x8bc79bd6b4d338f9 0xac4276d07d65ceb0 0x357351bb0d2f1cb8 0x900a254512dfc430 1.475 1.493744 84604 0 PASS
161 28573228 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x8bc79bd6b4d338f9 0xac4276d07d65ceb0 0x357351bb0d2f1cb8 0x900a254512dfc430 0.688 0.715502 288240 0 PASS
162 70955227 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.122 0.139162 83836 0 PASS
163 70955227 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.419 0.446187 279048 0 PASS
164 70955227 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.118 0.133338 84804 0 PASS
165 70955227 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.405 0.428654 279540 0 PASS
166 70955227 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xdaf7faa124800a90 0x0e2038b6f58233ec 0x9df861ebdd4ad5a0 0x50b94b2a529261d7 1.560 1.576865 86016 0 PASS
167 70955227 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xdaf7faa124800a90 0x0e2038b6f58233ec 0x9df861ebdd4ad5a0 0x50b94b2a529261d7 0.849 0.882918 288164 0 PASS
168 70955227 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xdaf7faa124800a90 0x0e2038b6f58233ec 0x9df861ebdd4ad5a0 0x50b94b2a529261d7 1.635 1.651152 86548 0 PASS
169 70955227 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xdaf7faa124800a90 0x0e2038b6f58233ec 0x9df861ebdd4ad5a0 0x50b94b2a529261d7 0.767 0.793113 288924 0 PASS
170 75274690 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.112 0.129015 83520 0 PASS
171 75274690 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.405 0.432266 278808 0 PASS
172 75274690 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.107 0.122969 84248 0 PASS
173 75274690 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.400 0.425046 279232 0 PASS
174 75274690 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xdf250106794ae38c 0x76706ba6a26f55ce 0x533b1070a58f2158 0x4f2ac497b8e00d2c 1.140 1.158530 86028 0 PASS
175 75274690 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xdf250106794ae38c 0x76706ba6a26f55ce 0x533b1070a58f2158 0x4f2ac497b8e00d2c 0.635 0.661364 290020 0 PASS
176 75274690 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xdf250106794ae38c 0x76706ba6a26f55ce 0x533b1070a58f2158 0x4f2ac497b8e00d2c 1.237 1.253451 86900 0 PASS
177 75274690 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xdf250106794ae38c 0x76706ba6a26f55ce 0x533b1070a58f2158 0x4f2ac497b8e00d2c 0.629 0.657284 290424 0 PASS
178 81375760 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x55d1e034d67632f5 0xf493f363535135e7 0xf1081c7533a6b533 0x24c1ef771b2e29df 0.302 0.321425 84348 0 PASS
179 81375760 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x55d1e034d67632f5 0xf493f363535135e7 0xf1081c7533a6b533 0x24c1ef771b2e29df 0.473 0.498702 288596 0 PASS
180 81375760 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x55d1e034d67632f5 0xf493f363535135e7 0xf1081c7533a6b533 0x24c1ef771b2e29df 0.284 0.300131 84776 0 PASS
181 81375760 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x55d1e034d67632f5 0xf493f363535135e7 0xf1081c7533a6b533 0x24c1ef771b2e29df 0.465 0.493912 289032 0 PASS
182 81375760 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x5e5bc1daf1855a5d 0x6d9a375c60771dd6 0x0e23381363a677c9 0xcd4cbbab580c6da6 1.644 1.660225 85756 0 PASS
183 81375760 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x5e5bc1daf1855a5d 0x6d9a375c60771dd6 0x0e23381363a677c9 0xcd4cbbab580c6da6 0.738 0.765107 289596 0 PASS
184 81375760 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x5e5bc1daf1855a5d 0x6d9a375c60771dd6 0x0e23381363a677c9 0xcd4cbbab580c6da6 1.724 1.741866 86704 0 PASS
185 81375760 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x5e5bc1daf1855a5d 0x6d9a375c60771dd6 0x0e23381363a677c9 0xcd4cbbab580c6da6 0.751 0.778126 289620 0 PASS
186 146979566 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x28dc20a8ab6fb2d0 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.146 0.162199 83420 0 PASS
187 146979566 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x28dc20a8ab6fb2d0 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.407 0.434165 281384 0 PASS
188 146979566 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x28dc20a8ab6fb2d0 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.154 0.171817 84220 0 PASS
189 146979566 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x28dc20a8ab6fb2d0 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.404 0.429003 282144 0 PASS
190 146979566 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xac33a725e13e3886 0x86611ee4c12947c9 0x2991daf2b7f1f2e4 0x91e98f0e880b1f3d 1.638 1.654237 86300 0 PASS
191 146979566 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xac33a725e13e3886 0x86611ee4c12947c9 0x2991daf2b7f1f2e4 0x91e98f0e880b1f3d 0.698 0.725703 289448 0 PASS
192 146979566 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xac33a725e13e3886 0x86611ee4c12947c9 0x2991daf2b7f1f2e4 0x91e98f0e880b1f3d 1.845 1.861845 86680 0 PASS
193 146979566 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xac33a725e13e3886 0x86611ee4c12947c9 0x2991daf2b7f1f2e4 0x91e98f0e880b1f3d 0.759 0.786078 290128 0 PASS
194 244951180 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x1cc26cbbf38ba8e9 0xeaace7e8b8443be0 0x61a9b62f2967c453 0xd0358bf6bbc94bb9 0.195 0.213011 86480 0 PASS
195 244951180 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x1cc26cbbf38ba8e9 0xeaace7e8b8443be0 0x61a9b62f2967c453 0xd0358bf6bbc94bb9 0.452 0.479860 284556 0 PASS
196 244951180 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x1cc26cbbf38ba8e9 0xeaace7e8b8443be0 0x61a9b62f2967c453 0xd0358bf6bbc94bb9 0.181 0.197358 87220 0 PASS
197 244951180 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x1cc26cbbf38ba8e9 0xeaace7e8b8443be0 0x61a9b62f2967c453 0xd0358bf6bbc94bb9 0.434 0.459596 284852 0 PASS
198 244951180 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x8bd265dfa2c428c4 0x47904e96f2a9213c 0xa9683a3e3251c768 0x585c686bcfe6be65 1.121 1.137204 86652 0 PASS
199 244951180 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x8bd265dfa2c428c4 0x47904e96f2a9213c 0xa9683a3e3251c768 0x585c686bcfe6be65 0.603 0.628602 289720 0 PASS
200 244951180 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x8bd265dfa2c428c4 0x47904e96f2a9213c 0xa9683a3e3251c768 0x585c686bcfe6be65 1.192 1.207485 87296 0 PASS
201 244951180 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x8bd265dfa2c428c4 0x47904e96f2a9213c 0xa9683a3e3251c768 0x585c686bcfe6be65 0.638 0.665330 290548 0 PASS
202 245433414 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.112 0.131222 82516 0 PASS
203 245433414 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.408 0.432991 277848 0 PASS
204 245433414 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.100 0.115984 83136 0 PASS
205 245433414 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.419 0.444156 277616 0 PASS
206 245433414 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x8740ccf600a029e2 0x04589dea4d5c0710 0x15ebf34a211b4233 0x1249a8b782a9ff85 1.203 1.220959 86352 0 PASS
207 245433414 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x8740ccf600a029e2 0x04589dea4d5c0710 0x15ebf34a211b4233 0x1249a8b782a9ff85 0.630 0.655544 290084 0 PASS
208 245433414 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x8740ccf600a029e2 0x04589dea4d5c0710 0x15ebf34a211b4233 0x1249a8b782a9ff85 1.279 1.296620 86904 0 PASS
209 245433414 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x8740ccf600a029e2 0x04589dea4d5c0710 0x15ebf34a211b4233 0x1249a8b782a9ff85 0.664 0.692096 290640 0 PASS
210 277442974 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.190 0.206505 84588 0 PASS
211 277442974 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.498 0.524538 279420 0 PASS
212 277442974 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.188 0.203434 85052 0 PASS
213 277442974 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.493 0.518404 279564 0 PASS
214 277442974 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x175a35be1d6f3efe 0xec304bc7b17ae96e 0x3559b943893fa981 0x491b549b23966102 1.322 1.338231 87924 0 PASS
215 277442974 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x175a35be1d6f3efe 0xec304bc7b17ae96e 0x3559b943893fa981 0x491b549b23966102 0.676 0.700980 292844 0 PASS
216 277442974 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x175a35be1d6f3efe 0xec304bc7b17ae96e 0x3559b943893fa981 0x491b549b23966102 1.366 1.382495 88588 0 PASS
217 277442974 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x175a35be1d6f3efe 0xec304bc7b17ae96e 0x3559b943893fa981 0x491b549b23966102 0.701 0.727447 293072 0 PASS
218 297746112 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xca1d94b876e4eeab 0xa25988b781b26dd4 0x054762688f50e323 0x71019e04b6b0de40 0.245 0.260033 85384 0 PASS
219 297746112 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xca1d94b876e4eeab 0xa25988b781b26dd4 0x054762688f50e323 0x71019e04b6b0de40 0.465 0.490415 288008 0 PASS
220 297746112 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xca1d94b876e4eeab 0xa25988b781b26dd4 0x054762688f50e323 0x71019e04b6b0de40 0.243 0.258435 86024 0 PASS
221 297746112 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xca1d94b876e4eeab 0xa25988b781b26dd4 0x054762688f50e323 0x71019e04b6b0de40 0.471 0.498359 288480 0 PASS
222 297746112 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x87cc040ef39b9130 0x0a2ea7d615d2f513 0x22cdcf9ca191de12 0xe2f6e225caca52f0 1.652 1.667443 86192 0 PASS
223 297746112 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x87cc040ef39b9130 0x0a2ea7d615d2f513 0x22cdcf9ca191de12 0xe2f6e225caca52f0 0.747 0.773312 289872 0 PASS
224 297746112 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x87cc040ef39b9130 0x0a2ea7d615d2f513 0x22cdcf9ca191de12 0xe2f6e225caca52f0 1.731 1.748813 86708 0 PASS
225 297746112 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x87cc040ef39b9130 0x0a2ea7d615d2f513 0x22cdcf9ca191de12 0xe2f6e225caca52f0 0.764 0.789221 290484 0 PASS
226 336768467 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.114 0.128946 82460 0 PASS
227 336768467 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.419 0.445300 277468 0 PASS
228 336768467 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.110 0.125258 83208 0 PASS
229 336768467 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.397 0.423317 278004 0 PASS
230 336768467 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x51c11d2bb0b34ea1 0x7b5968648098e169 0x6671281233fba737 0xf6d98fa4825abf1c 1.629 1.646272 85052 0 PASS
231 336768467 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x51c11d2bb0b34ea1 0x7b5968648098e169 0x6671281233fba737 0xf6d98fa4825abf1c 0.728 0.754451 288124 0 PASS
232 336768467 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x51c11d2bb0b34ea1 0x7b5968648098e169 0x6671281233fba737 0xf6d98fa4825abf1c 1.705 1.720538 85388 0 PASS
233 336768467 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x51c11d2bb0b34ea1 0x7b5968648098e169 0x6671281233fba737 0xf6d98fa4825abf1c 0.738 0.766954 288356 0 PASS
234 512532080 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.153 0.168716 82560 0 PASS
235 512532080 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.440 0.467645 277488 0 PASS
236 512532080 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.143 0.159069 82904 0 PASS
237 512532080 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.445 0.469304 277704 0 PASS
238 512532080 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x072b184717239693 0x9fac948bbd70a853 0xc00c647e52d9427e 0x4cc2ff6aed2ad23d 1.226 1.242263 84388 0 PASS
239 512532080 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x072b184717239693 0x9fac948bbd70a853 0xc00c647e52d9427e 0x4cc2ff6aed2ad23d 0.629 0.654951 288556 0 PASS
240 512532080 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x072b184717239693 0x9fac948bbd70a853 0xc00c647e52d9427e 0x4cc2ff6aed2ad23d 1.360 1.375755 85232 0 PASS
241 512532080 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x072b184717239693 0x9fac948bbd70a853 0xc00c647e52d9427e 0x4cc2ff6aed2ad23d 0.672 0.697654 289308 0 PASS
242 821120640 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.153 0.168054 82828 0 PASS
243 821120640 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.462 0.487309 277536 0 PASS
244 821120640 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.149 0.163984 82908 0 PASS
245 821120640 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.445 0.471081 277668 0 PASS
246 821120640 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x799f3dddb77b2373 0x2ff216b7c9c0a0f7 0xbd06c753c834d621 0xe6452e48c09c779c 1.491 1.507224 85000 0 PASS
247 821120640 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x799f3dddb77b2373 0x2ff216b7c9c0a0f7 0xbd06c753c834d621 0xe6452e48c09c779c 0.700 0.726549 289052 0 PASS
248 821120640 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x799f3dddb77b2373 0x2ff216b7c9c0a0f7 0xbd06c753c834d621 0xe6452e48c09c779c 1.661 1.677544 85416 0 PASS
249 821120640 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x799f3dddb77b2373 0x2ff216b7c9c0a0f7 0xbd06c753c834d621 0xe6452e48c09c779c 0.775 0.801706 289404 0 PASS
250 853538490 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe9c955bb88ef453e 0xf6ff06a22d87a886 0x8affd2ace9c02ca9 0xa87ab0dfc3a7abaf 0.351 0.367197 83708 0 PASS
251 853538490 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe9c955bb88ef453e 0xf6ff06a22d87a886 0x8affd2ace9c02ca9 0xa87ab0dfc3a7abaf 0.498 0.524390 287376 0 PASS
252 853538490 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe9c955bb88ef453e 0xf6ff06a22d87a886 0x8affd2ace9c02ca9 0xa87ab0dfc3a7abaf 0.309 0.325235 84408 0 PASS
253 853538490 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe9c955bb88ef453e 0xf6ff06a22d87a886 0x8affd2ace9c02ca9 0xa87ab0dfc3a7abaf 0.503 0.529485 287824 0 PASS
254 853538490 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xf325b1581a7f5166 0x375b7d2ab1227a19 0xa5b6bfe633662d7e 0xaceab7327811c4f7 1.594 1.609537 84548 0 PASS
255 853538490 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xf325b1581a7f5166 0x375b7d2ab1227a19 0xa5b6bfe633662d7e 0xaceab7327811c4f7 0.744 0.770634 287636 0 PASS
256 853538490 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xf325b1581a7f5166 0x375b7d2ab1227a19 0xa5b6bfe633662d7e 0xaceab7327811c4f7 1.565 1.581727 85352 0 PASS
257 853538490 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xf325b1581a7f5166 0x375b7d2ab1227a19 0xa5b6bfe633662d7e 0xaceab7327811c4f7 0.783 0.809731 287652 0 PASS
258 861026696 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.120 0.140722 84164 0 PASS
259 861026696 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.424 0.450365 279168 0 PASS
260 861026696 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.112 0.128137 84788 0 PASS
261 861026696 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.404 0.429204 279848 0 PASS
262 861026696 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xca1edaff577a4e1c 0xd032eac020ae2194 0x573cba10f70617e8 0xa8ef305116ad999c 1.511 1.528290 85840 0 PASS
263 861026696 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xca1edaff577a4e1c 0xd032eac020ae2194 0x573cba10f70617e8 0xa8ef305116ad999c 0.690 0.716270 288668 0 PASS
264 861026696 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xca1edaff577a4e1c 0xd032eac020ae2194 0x573cba10f70617e8 0xa8ef305116ad999c 1.581 1.598332 86244 0 PASS
265 861026696 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xca1edaff577a4e1c 0xd032eac020ae2194 0x573cba10f70617e8 0xa8ef305116ad999c 0.737 0.763910 288720 0 PASS
266 1026251636 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.125 0.140307 87376 0 PASS
267 1026251636 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.431 0.456676 282440 0 PASS
268 1026251636 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.120 0.136933 87768 0 PASS
269 1026251636 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.410 0.435138 282592 0 PASS
270 1026251636 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x389074d90273f26e 0xa38bcee9be5ec7eb 0x640d982fa1ac7f9c 0xe03c1c060ff49cca 2.194 2.209401 90204 0 PASS
271 1026251636 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x389074d90273f26e 0xa38bcee9be5ec7eb 0x640d982fa1ac7f9c 0xe03c1c060ff49cca 0.851 0.878001 292176 0 PASS
272 1026251636 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x389074d90273f26e 0xa38bcee9be5ec7eb 0x640d982fa1ac7f9c 0xe03c1c060ff49cca 2.274 2.290952 90476 0 PASS
273 1026251636 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x389074d90273f26e 0xa38bcee9be5ec7eb 0x640d982fa1ac7f9c 0xe03c1c060ff49cca 0.835 0.863009 292140 0 PASS
274 1077415394 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x87ee69cb17aba224 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.146 0.163297 86188 0 PASS
275 1077415394 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x87ee69cb17aba224 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.414 0.439121 283756 0 PASS
276 1077415394 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x87ee69cb17aba224 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.148 0.168584 86796 0 PASS
277 1077415394 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x87ee69cb17aba224 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.426 0.450855 284368 0 PASS
278 1077415394 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x9584311b92b45072 0xee776f01c536080b 0x6648ac4dfaf4abfd 0x18119783a47a0df1 1.601 1.617268 87912 0 PASS
279 1077415394 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x9584311b92b45072 0xee776f01c536080b 0x6648ac4dfaf4abfd 0x18119783a47a0df1 0.699 0.725603 292220 0 PASS
280 1077415394 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x9584311b92b45072 0xee776f01c536080b 0x6648ac4dfaf4abfd 0x18119783a47a0df1 1.727 1.745677 88476 0 PASS
281 1077415394 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x9584311b92b45072 0xee776f01c536080b 0x6648ac4dfaf4abfd 0x18119783a47a0df1 0.833 0.867727 292828 0 PASS
282 1130999017 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x38c8b5c86fc861ed 0x0871f41c7adbcbec 0x983b9c5b7bfc9c68 0x920b30bf2774555b 0.291 0.307690 85160 0 PASS
283 1130999017 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x38c8b5c86fc861ed 0x0871f41c7adbcbec 0x983b9c5b7bfc9c68 0x920b30bf2774555b 0.452 0.481022 289968 0 PASS
284 1130999017 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x38c8b5c86fc861ed 0x0871f41c7adbcbec 0x983b9c5b7bfc9c68 0x920b30bf2774555b 0.266 0.282332 85784 0 PASS
285 1130999017 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x38c8b5c86fc861ed 0x0871f41c7adbcbec 0x983b9c5b7bfc9c68 0x920b30bf2774555b 0.444 0.470657 290324 0 PASS
286 1130999017 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x519dd11ec1b6fd25 0x03655ab9c5d71117 0xbd12d3dae54569a6 0x80d8d87e27a7de44 1.472 1.489302 84108 0 PASS
287 1130999017 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x519dd11ec1b6fd25 0x03655ab9c5d71117 0xbd12d3dae54569a6 0x80d8d87e27a7de44 0.713 0.738699 287528 0 PASS
288 1130999017 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x519dd11ec1b6fd25 0x03655ab9c5d71117 0xbd12d3dae54569a6 0x80d8d87e27a7de44 1.530 1.545977 84776 0 PASS
289 1130999017 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x519dd11ec1b6fd25 0x03655ab9c5d71117 0xbd12d3dae54569a6 0x80d8d87e27a7de44 0.685 0.710911 288188 0 PASS
290 1156488597 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.121 0.139125 83040 0 PASS
291 1156488597 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.403 0.428569 278288 0 PASS
292 1156488597 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.109 0.125855 83948 0 PASS
293 1156488597 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.425 0.450644 278660 0 PASS
294 1156488597 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x640a6e138f3d100a 0x89a1c96de1216f8a 0xabb2594c0f2aa5e1 0xbdaec02426d2a060 1.216 1.232170 85424 0 PASS
295 1156488597 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x640a6e138f3d100a 0x89a1c96de1216f8a 0xabb2594c0f2aa5e1 0xbdaec02426d2a060 0.645 0.670839 287908 0 PASS
296 1156488597 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x640a6e138f3d100a 0x89a1c96de1216f8a 0xabb2594c0f2aa5e1 0xbdaec02426d2a060 1.312 1.328475 86080 0 PASS
297 1156488597 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x640a6e138f3d100a 0x89a1c96de1216f8a 0xabb2594c0f2aa5e1 0xbdaec02426d2a060 0.704 0.729815 288444 0 PASS
298 1172304228 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.109 0.123809 82616 0 PASS
299 1172304228 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.407 0.431733 277580 0 PASS
300 1172304228 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.101 0.115688 82980 0 PASS
301 1172304228 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.407 0.432724 277708 0 PASS
302 1172304228 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xfb46579ab737c12d 0x0a000a703c549cc1 0xfea6b41d2c3dda0e 0x9640bd6047c9a630 0.869 0.885113 85556 0 PASS
303 1172304228 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xfb46579ab737c12d 0x0a000a703c549cc1 0xfea6b41d2c3dda0e 0x9640bd6047c9a630 0.584 0.611186 288244 0 PASS
304 1172304228 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xfb46579ab737c12d 0x0a000a703c549cc1 0xfea6b41d2c3dda0e 0x9640bd6047c9a630 0.964 0.980259 85884 0 PASS
305 1172304228 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xfb46579ab737c12d 0x0a000a703c549cc1 0xfea6b41d2c3dda0e 0x9640bd6047c9a630 0.611 0.636011 289012 0 PASS
306 1370340570 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.106 0.121360 82860 0 PASS
307 1370340570 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.413 0.439779 277640 0 PASS
308 1370340570 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.105 0.120822 83596 0 PASS
309 1370340570 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.406 0.430247 278132 0 PASS
310 1370340570 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x34624cba09f42b66 0xd81a376b1e97ec8b 0xf965f89b36b5d843 0xf6abf6a7f4a15687 1.678 1.694262 85176 0 PASS
311 1370340570 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x34624cba09f42b66 0xd81a376b1e97ec8b 0xf965f89b36b5d843 0xf6abf6a7f4a15687 0.691 0.717560 287996 0 PASS
312 1370340570 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x34624cba09f42b66 0xd81a376b1e97ec8b 0xf965f89b36b5d843 0xf6abf6a7f4a15687 1.820 1.836129 85504 0 PASS
313 1370340570 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x34624cba09f42b66 0xd81a376b1e97ec8b 0xf965f89b36b5d843 0xf6abf6a7f4a15687 0.768 0.793448 288372 0 PASS
314 1383925073 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.112 0.129033 81792 0 PASS
315 1383925073 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.401 0.427476 277224 0 PASS
316 1383925073 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.105 0.120673 82892 0 PASS
317 1383925073 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.402 0.425822 277488 0 PASS
318 1383925073 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x32c8a3f9cd2d249e 0xe504e184d0529243 0x58408898b37b6d53 0x3154f68bf8585d9e 1.772 1.788831 84816 0 PASS
319 1383925073 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x32c8a3f9cd2d249e 0xe504e184d0529243 0x58408898b37b6d53 0x3154f68bf8585d9e 0.882 0.907588 287224 0 PASS
320 1383925073 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x32c8a3f9cd2d249e 0xe504e184d0529243 0x58408898b37b6d53 0x3154f68bf8585d9e 1.870 1.886415 84956 0 PASS
321 1383925073 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x32c8a3f9cd2d249e 0xe504e184d0529243 0x58408898b37b6d53 0x3154f68bf8585d9e 0.907 0.933394 287936 0 PASS
322 1401164998 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x539b7c44ed2d40c4 0x2daa8cf5e08fb16e 0xd87700809feafff4 0xc2e832153a03b5d7 0.287 0.303400 84652 0 PASS
323 1401164998 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x539b7c44ed2d40c4 0x2daa8cf5e08fb16e 0xd87700809feafff4 0xc2e832153a03b5d7 0.478 0.503793 287484 0 PASS
324 1401164998 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x539b7c44ed2d40c4 0x2daa8cf5e08fb16e 0xd87700809feafff4 0xc2e832153a03b5d7 0.275 0.290885 85324 0 PASS
325 1401164998 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x539b7c44ed2d40c4 0x2daa8cf5e08fb16e 0xd87700809feafff4 0xc2e832153a03b5d7 0.467 0.494139 288496 0 PASS
326 1401164998 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xec2a42ee2976845f 0xa295763ea8d9e67f 0xe9c0bff6914243ba 0x62b04de967523696 1.963 1.979104 84732 0 PASS
327 1401164998 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xec2a42ee2976845f 0xa295763ea8d9e67f 0xe9c0bff6914243ba 0x62b04de967523696 0.747 0.775087 287448 0 PASS
328 1401164998 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xec2a42ee2976845f 0xa295763ea8d9e67f 0xe9c0bff6914243ba 0x62b04de967523696 1.910 1.926095 85012 0 PASS
329 1401164998 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xec2a42ee2976845f 0xa295763ea8d9e67f 0xe9c0bff6914243ba 0x62b04de967523696 0.798 0.823400 288392 0 PASS
330 1558879574 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.115 0.132445 81992 0 PASS
331 1558879574 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.422 0.447714 276768 0 PASS
332 1558879574 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.103 0.119871 82376 0 PASS
333 1558879574 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.421 0.447570 277272 0 PASS
334 1558879574 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x6a6961f63402e799 0xcdeb03b89b00d39d 0x0b036e09b5273b49 0x971cac1901dff195 0.920 0.936756 83620 0 PASS
335 1558879574 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x6a6961f63402e799 0xcdeb03b89b00d39d 0x0b036e09b5273b49 0x971cac1901dff195 0.595 0.621724 287708 0 PASS
336 1558879574 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x6a6961f63402e799 0xcdeb03b89b00d39d 0x0b036e09b5273b49 0x971cac1901dff195 0.939 0.954884 84488 0 PASS
337 1558879574 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x6a6961f63402e799 0xcdeb03b89b00d39d 0x0b036e09b5273b49 0x971cac1901dff195 0.600 0.626689 288548 0 PASS
338 1753015542 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.106 0.121516 83192 0 PASS
339 1753015542 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.420 0.448397 278160 0 PASS
340 1753015542 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.110 0.129636 83988 0 PASS
341 1753015542 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.405 0.431222 278696 0 PASS
342 1753015542 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xb91a6e87bdb9610e 0xfdbb714aa24253d8 0xfea893be04158e3f 0x3365335c4b56e58c 1.661 1.678331 85292 0 PASS
343 1753015542 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xb91a6e87bdb9610e 0xfdbb714aa24253d8 0xfea893be04158e3f 0x3365335c4b56e58c 0.725 0.750781 288032 0 PASS
344 1753015542 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xb91a6e87bdb9610e 0xfdbb714aa24253d8 0xfea893be04158e3f 0x3365335c4b56e58c 1.786 1.802204 86188 0 PASS
345 1753015542 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xb91a6e87bdb9610e 0xfdbb714aa24253d8 0xfea893be04158e3f 0x3365335c4b56e58c 0.739 0.765903 288808 0 PASS
346 1827697875 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.106 0.122073 84540 0 PASS
347 1827697875 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.412 0.435966 279476 0 PASS
348 1827697875 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.105 0.121830 84676 0 PASS
349 1827697875 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.409 0.434709 279752 0 PASS
350 1827697875 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x699dd931ec3a2699 0x88331e1e5644593e 0xaa2288bc01794464 0xf92b0fbeb4ea279b 1.666 1.681850 89140 0 PASS
351 1827697875 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x699dd931ec3a2699 0x88331e1e5644593e 0xaa2288bc01794464 0xf92b0fbeb4ea279b 0.739 0.764550 292172 0 PASS
352 1827697875 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x699dd931ec3a2699 0x88331e1e5644593e 0xaa2288bc01794464 0xf92b0fbeb4ea279b 1.784 1.800585 89620 0 PASS
353 1827697875 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x699dd931ec3a2699 0x88331e1e5644593e 0xaa2288bc01794464 0xf92b0fbeb4ea279b 0.774 0.801097 293460 0 PASS
354 1909311298 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.126 0.140793 81792 0 PASS
355 1909311298 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.454 0.479793 277000 0 PASS
356 1909311298 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.119 0.138021 82780 0 PASS
357 1909311298 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.439 0.465770 277320 0 PASS
358 1909311298 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x15c0afb4c79cdd4e 0xc5f83ce7199a4708 0x1a923e880b787190 0xb9ca42e4a6e19d87 1.677 1.692282 84504 0 PASS
359 1909311298 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x15c0afb4c79cdd4e 0xc5f83ce7199a4708 0x1a923e880b787190 0xb9ca42e4a6e19d87 0.726 0.753056 287464 0 PASS
360 1909311298 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x15c0afb4c79cdd4e 0xc5f83ce7199a4708 0x1a923e880b787190 0xb9ca42e4a6e19d87 1.895 1.911071 84364 0 PASS
361 1909311298 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x15c0afb4c79cdd4e 0xc5f83ce7199a4708 0x1a923e880b787190 0xb9ca42e4a6e19d87 0.754 0.781499 287952 0 PASS
362 2011898099 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.113 0.129139 83892 0 PASS
363 2011898099 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.433 0.459151 278756 0 PASS
364 2011898099 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.103 0.117822 84760 0 PASS
365 2011898099 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.428 0.456161 279268 0 PASS
366 2011898099 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x4e5bc61fa6d60b4e 0x3c54a6c3cc817e24 0xa9a3c69c604071a5 0x53009044905f1269 1.148 1.163696 87080 0 PASS
367 2011898099 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x4e5bc61fa6d60b4e 0x3c54a6c3cc817e24 0xa9a3c69c604071a5 0x53009044905f1269 0.624 0.651689 289916 0 PASS
368 2011898099 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x4e5bc61fa6d60b4e 0x3c54a6c3cc817e24 0xa9a3c69c604071a5 0x53009044905f1269 1.234 1.252059 87640 0 PASS
369 2011898099 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x4e5bc61fa6d60b4e 0x3c54a6c3cc817e24 0xa9a3c69c604071a5 0x53009044905f1269 0.650 0.677250 290788 0 PASS
370 2015768509 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x5d69d4a0b6a3d1c3 0x300ab4e08dc23479 0xb1638622b8b616ad 0x082af297bc0e2595 0.319 0.335248 82712 0 PASS
371 2015768509 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x5d69d4a0b6a3d1c3 0x300ab4e08dc23479 0xb1638622b8b616ad 0x082af297bc0e2595 0.497 0.523192 286708 0 PASS
372 2015768509 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0x5d69d4a0b6a3d1c3 0x300ab4e08dc23479 0xb1638622b8b616ad 0x082af297bc0e2595 0.280 0.296244 83728 0 PASS
373 2015768509 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0x5d69d4a0b6a3d1c3 0x300ab4e08dc23479 0xb1638622b8b616ad 0x082af297bc0e2595 0.479 0.505113 287436 0 PASS
374 2015768509 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0xd9c1ee0b4c2e8ce8 0x7d2329c4b87bc6f1 0x8f9d279d8d590839 0x7ac25c667e165fa7 1.490 1.506239 84120 0 PASS
375 2015768509 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0xd9c1ee0b4c2e8ce8 0x7d2329c4b87bc6f1 0x8f9d279d8d590839 0x7ac25c667e165fa7 0.717 0.744393 288996 0 PASS
376 2015768509 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0xd9c1ee0b4c2e8ce8 0x7d2329c4b87bc6f1 0x8f9d279d8d590839 0x7ac25c667e165fa7 1.600 1.617351 84900 0 PASS
377 2015768509 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0xd9c1ee0b4c2e8ce8 0x7d2329c4b87bc6f1 0x8f9d279d8d590839 0x7ac25c667e165fa7 0.742 0.769135 289484 0 PASS
378 2070776516 surface-world clang19 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.126 0.141678 81840 0 PASS
379 2070776516 surface-world clang19 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.430 0.456364 276976 0 PASS
380 2070776516 surface-world gcc14 1 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.114 0.131120 82540 0 PASS
381 2070776516 surface-world gcc14 12 27 0 0 -32 -192 -1984 64 -96 -1888 0xe93491225d0202f9 0x6b2a630951428df2 0xfc2798d6a5478b25 0x0c08d7d980a84301 0.401 0.425293 277436 0 PASS
382 2070776516 floating-islands clang19 1 27 0 0 -32 -32 -160 64 64 -64 0x2cc0f6dce797b31f 0x8760f9677ab58f62 0x03d2511d3ea2f55b 0x2f55edd35d7b78ef 0.998 1.014096 84548 0 PASS
383 2070776516 floating-islands clang19 12 27 0 0 -32 -32 -160 64 64 -64 0x2cc0f6dce797b31f 0x8760f9677ab58f62 0x03d2511d3ea2f55b 0x2f55edd35d7b78ef 0.575 0.600529 286932 0 PASS
384 2070776516 floating-islands gcc14 1 27 0 0 -32 -32 -160 64 64 -64 0x2cc0f6dce797b31f 0x8760f9677ab58f62 0x03d2511d3ea2f55b 0x2f55edd35d7b78ef 1.054 1.070063 84768 0 PASS
385 2070776516 floating-islands gcc14 12 27 0 0 -32 -32 -160 64 64 -64 0x2cc0f6dce797b31f 0x8760f9677ab58f62 0x03d2511d3ea2f55b 0x2f55edd35d7b78ef 0.597 0.622079 287140 0 PASS
@@ -0,0 +1 @@
runs=384 seeds=48 recipes=2 compilers=2 workers=1,12 cross_compiler_comparisons=192 cross_compiler_mismatches=0 cross_worker_comparisons=192 cross_worker_mismatches=0 elapsed_s=290.100
@@ -0,0 +1,48 @@
-1990830953
-1900684165
-1766412538
-1721984596
-1239598758
-1085993262
-1033703345
-854671705
-713963806
-621039221
-474448608
-432690581
-380556572
-238925630
-216679974
-133096164
-112366806
0
5808593
28573228
70955227
75274690
81375760
146979566
244951180
245433414
277442974
297746112
336768467
512532080
821120640
853538490
861026696
1026251636
1077415394
1130999017
1156488597
1172304228
1370340570
1383925073
1401164998
1558879574
1753015542
1827697875
1909311298
2011898099
2015768509
2070776516
@@ -0,0 +1,192 @@
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
@@ -0,0 +1,81 @@
# Linux20 — design research for metre-based strata and generation layers
**Date:** 2026-10-20
**Scope:** read current owner/Core code and L19 evidence; measure unit conversions and LOD ring
errors; write the L20 design only.
## Findings
- `CHUNK_SIZE` is 32 and legacy `VOXEL_SIZE` is 12.5 cm, so the owner chunk is 4 m
(`Source/VoxelForge/Public/VoxelTypes.h`). Core defaults to 25 cm and keeps 32 voxels per tile.
- `BuildSurfaceStratumPlan` computes SurfaceWorld layout from `Slot.*ChunkZ × CHUNK_SIZE` in Core
voxel units. This is 32 × 25 cm = **8 m per slot chunk**. L18 records this as the retained
SurfaceWorld `topChunkZ × 32` interpretation.
- `BuildFloatingIslandStratumPlan` serializes owner/Core voxel size and the reduced ratio. At the
default 12.5/25 cm ratio, its slot chunk is 32 × 0.5 = 16 Core voxels = **4 m**. Core reverses
sample Z using `GetCoreVoxelsPerOwnerChunk` in `ShapeWorldInternal.h`.
- This factor-of-two difference is real, but it is not enough to claim that it caused the L19 ring
heights. L19's ring evidence points to LOD-dependent extraction of the lower SurfaceWorld field.
It does mean there is no single metres-per-chunk conversion that both preserves the current native
bounds and makes their shared slot indices one physical interface. The design records the current
resolved bounds and treats a later interface unification as an explicit change.
- The L19 FloatingIslands-camera table reports LOD1→2 median / p95 / max = 147.141 / 148.403 /
149.862 cm, zero no-hit samples; LOD2→3 = 128.603 / 200.789 / 773.318 cm, with 8 no-hit samples
among 308. LOD1/2/3 step sizes at 25 cm are 0.5/1/2 m. The ring audit excludes skirts and masked
triangles. Native far-ground refinement starts at LOD4, so it cannot fix those two transitions.
- The exact location and current geometry evidence are from `Linux19/REPORT.md`: lower SurfaceWorld
terrain at approximately −60…−73 m; its terrain triangles remain visible below FloatingIslands.
The worst sampled LOD1→2 roots are −60.497 m and −61.996 m. The LOD2→3 pair is −73.080 m and
−65.347 m.
## Layer map
The owner-facing layout is composed by `VoxelStrateComposer.cpp`, stored/loaded by
`VoxelSeasonManifest.cpp`, and resolved into `FStrateSlot`s by `VoxelStrateManager.cpp`. The Core
snapshot adapter (`VoxelForgeCoreAdapter.cpp`) builds separate SurfaceWorld and FloatingIslands
plans. Core streams work from `VoxelForgeCore.cpp` and evaluates native fields in
`WorldAssemblerInternal.h` / `FloatingIslandsInternal.h`; legacy `UVoxelGenerator::GetDensityAt`
and operator-stack/cave paths remain in `VoxelGenerator.cpp`, `VoxelDensityOpStack.cpp`, and
`VoxelCaveMorphology.cpp`.
Shared pieces already include Core's FP-contract preamble, fixed-point field code, feature bounds,
column caches, and interval proofs. `ShapeWorldInternal.h` still chooses among native fields, manager
state, and the copied legacy evaluator. `World::generateTile` in `VoxelForgeCore.cpp` owns MC setup,
recipe feature branches, native SurfaceWorld far-ground/cap refinement, and recipe identity salts.
`FarShellsInternal.h` adds shared boundary ceilings and GPU far-shell repairs; its connector repair
input is prepared from FloatingIslands geometry in `ShapeWorldInternal.h`.
The complete mapping, boundary proposal, ranked violations, generator contract, and migration plan
are in [`DESIGN_STRATA_UNITS_AND_LAYERS.md`](../../../DESIGN_STRATA_UNITS_AND_LAYERS.md).
## Direction review
The proposed metre authoring, 25 cm per-strate default, fixed 32³ internal tiles, and separation of
director/generators/shared composition/mesher are sound. Two qualifications are recorded in the
design:
1. “Units cost nothing” is true for metre conversion itself. Voxel size affects the physical width
of 32³ tiles and the number of tiles/tasks/caches; halving spacing in XYZ implies about 8× the
density samples per physical volume, with more per-tile overhead on top.
2. A no-movement migration cannot use one global chunk-to-metre multiplier. Current Core paths use
8 m per SurfaceWorld slot chunk and 4 m per FloatingIslands slot chunk at defaults. Preserve and
report those current resolved bounds first; decide separately whether to leave any gap/overlap or
intentionally make the new metre-authored interface contiguous.
The L19 density/mesh evidence supports LOD extraction as the direct cause of the measured lower-ground
ring steps. A shared explicit ceiling surface is the right approach for seals/caps, but not sufficient
for those upward-facing ground ledges. Step 5 therefore exposes the SurfaceWorld ground profile to a
generic explicit-surface/transition contract and remains subject to the protected LOD2 approval.
## Output and worktree status
No source, manifest, generator, mesher, or build input was changed. No build or world run was made.
Thus no new W12 hash claim is needed for this documentation-only round. The L19 reference hashes
remain the expected equality gates for later source changes:
- SurfaceWorld whole view: `c10697a8f48380c7 / 4197fc1072f0ff58 / 7b3e616ec9459851 / c879e35592bf33e5`
- FloatingIslands whole view: `00bc3607a7839854 / 4baa66127c2b0892 / e11ef05e851a1517 / 1278bc4b1fffb869`
The pre-existing untracked `Standalone/Research/WorldAssemblerM3/Linux18/exports/` directory was
left untouched. No commit, push, or stash was made.
Loaded 100 of 194 files, more files were not shown because too many files have changed in this diff. Show more