Compare commits

..
Author SHA1 Message Date
Fr0zkaandClaude Opus 5.5 3b71d35eba experiment: LivingPlane repeatable + standalone UE runtime module (L164)
Readback barrier fix (GL_TEXTURE_UPDATE_BARRIER_BIT before glGetTexImage); check_repeatability.py compares full-field
checksums across query/capture settings - Intel GPU PASS (3b9d45905c7aafff), llvmpipe PASS, mismatch control fails.
New runtime module VoxelForgeLivingPlane (separate from generation): RDG global shader (Shaders/LivingPlane.usf),
ping-pong RGBA32F render targets, actor with WPO plane and object inputs, no CPU readback. Compiles in Linux UE 5.7.
Windows build: Source/VoxelForgeLivingPlane/*, Shaders/LivingPlane.usf, VoxelForge.uplugin. Setup: UE-SETUP.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-11-02 11:10:43 +01:00
Fr0zkaandClaude Opus 5.5 e1d87eed26 experiment: LivingPlane readable + alive mode (L163)
RGBA32F displacement/velocity/imprint field; rolling base relief, grazing light, elevation colours, 7.5 cm contours,
follow camera; scenes: roll, rest and wobble, lift-off, second sphere; alive mode = travelling swells + viscoelastic
imprint. Intel ADL GT2: ~0.17 ms/step at 512^2. Open: run-to-run difference with queries on/off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-11-02 10:55:32 +01:00
Fr0zkaandClaude Opus 5.5 5b15595e4a experiment: LivingPlane - GPU wave-equation height field reacting to a moving sphere (L162)
Standalone EGL/OpenGL 4.3 compute runner (runtime GLSL, no shader compiler needed), ping-pong height/velocity field,
damped wave + foundation spring + Gaussian sphere push + optional breathing, vertex-displaced render to PNG.
Independent of generation. Intel ADL GT2: ~0.08 ms/step at 512^2, ~0.29 ms/step at 1024^2 (wall-time difference).
.gitignore now allows Experiments/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-11-02 10:35:37 +01:00
Fr0zkaandClaude Opus 5.5 eb47d72258 research: R47 liminal/dreamcore style and mapping to Core (text only; images kept local)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-11-01 04:11:52 +01:00
250 changed files with 2867 additions and 22514 deletions

No files matched your search

+8
View File
@@ -9,12 +9,20 @@
!/Source/
!/Source/**
# Plugin runtime shader source.
!/Shaders/
!/Shaders/**
# Portable CPU generator and D3D11 viewer.
!/Standalone/
!/Standalone/**
/Standalone/Build/
/Standalone/bin/
# Research and prototype experiments.
!/Experiments/
!/Experiments/**
# The guarded single-entry test harness is source, not generated output.
!/Tools/
!/Tools/**
+4 -43
View File
@@ -2299,55 +2299,16 @@ results; the code path is not promoted to legacy Maze/VerticalShafts generation.
rooms, or tunnels. The Unreal adapter preserves the established passage planner, then resolves
authored stamps and cavern graph records, then finalizes the layout. Stable names are required and
are scoped by strate in Core; landmarks may target a stamp, room, or tunnel by that stable name.
Core profile heightfields are restricted to SurfaceWorld. Native caves require the TunnelNetwork,
Underwater, or VerticalShafts archetype; native lattice requires Maze or VerticalShafts. Core
recipe/version fields enter the resolved layout identity when selected. An imported manifest cannot
be mixed with a per-strate profiled heightfield.
Core profile heightfields are restricted to SurfaceWorld. Native caves require the TunnelNetwork or
Underwater archetype; native lattice requires Maze or VerticalShafts. Core recipe/version fields
enter the resolved layout identity when selected. An imported manifest cannot be mixed with a
per-strate profiled heightfield.
The checked-out Core API contains stamp vocabularies V1, V2, and V3. Unreal uses V1 for the original
stamp kinds and V3 for monolith/platform motifs, then combines and strictly validates the result.
Research17 names V2, but the source API and motif vocabulary require V3; source was followed.
Research27 water remains out of scope for U1.
### 8.56 Native Vertical Shafts graph field — World Assembler M3 L139
Vertical Shafts uses the same `PlanResolvedCavernNetworkV1` and `Core.Caves.PrimitiveField` as
Tunnel Network. There is no separate shaft planner. The existing room/tunnel shapes do not express
a capped bore spanning the strate height, so the shared cave field gains a shaft-cylinder record
kind; resolved records then add access tunnels, shaft cross-connects, and internal ledges.
`Core.Lattice.PrimitiveField` is not used: its L58 VerticalShafts route read as a corkscrew, so it
does not satisfy this archetype's open-shaft identity.
The basal owner strate has an arrival mouth from passage 2–3 and deliberately has no departure
mouth. Here the primordial law's route is the arrival mouth to a walkable terminal landing above the
bedrock seal. The shared planner extends its walk-only spine to that terminal with the same grade
limit used for a two-mouth cave; it does not invent a second passage. Route landings and connectors
are built as part of the graph. Shaft bores and their ledges are a separate exploration tier: an
open vertical drop or a climb between ledges is not walk-only traversal. Climb and mine remain
reporting tiers; they never relax the walk-only guarantee.
`FVerticalShaftParams` mapping:
| Field | Core behavior |
|---|---|
| `ShaftSpacing` | Planner room spacing, converting owner voxels to integer micrometres. |
| `ShaftDensity` | `roomDensityQ16`; seeds shaft placement, with the route's initial shaft guaranteed when nonzero. |
| `ShaftMinRadius`, `ShaftMaxRadius` | Minimum and maximum shaft radii. |
| `CrossConnectChance` | `tunnelDensityQ16` for cross-shaft links; generic cave branches are disabled in shaft mode. |
| `ConnectorRadius` | Fixed minimum/maximum radius for access and connector bores. |
| `LedgeSpacing`, `LedgeDepth` | Shaft shelf spacing and intrusion depth; zero spacing disables ledges, while zero depth leaves them nonintrusive. |
| `SurfaceRoughness` | Shaft-wall roughness amplitude. Frequency is derived as `max(0.5 m, 4 owner voxels)` because the legacy params have no frequency field. |
| `BoundarySealThickness`, `BaseDensity` | Continue to feed the resolved top and basal boundary bands through `sealAndDensity`, not the planner settings. |
L139 increments `WorldAssemblyEvaluatorVersion` to 237 and extends the versioned cavern graph
vocabulary for shaft cylinders. The fast-tier dispatch report binds S3 to
`Core.Caves.PrimitiveField` / `Caves-native`. The 16-seed composed acceptance gate is not green:
seed 2 fails the passage-shell audit at the incoming mouth. Three geometry variants failed that
same gate, so the remaining issue is recorded for a new design premise rather than another local
patch. L139 does not claim promoted shaft generation; its L80 run is recorded as characterization
of the current worktree. See
[`Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md).
The shared VoxelForge custom asset version is 2: version 1 records the tunnel-floor slope migration;
version 2 adds load-time conversion for inter-strate gap, strate height, and transition width. The
saved strate-layout width is used, currently 8 m. Old packages are converted in memory and marked
+1 -15
View File
@@ -174,7 +174,7 @@ remains `0`, and lateral regions remain gated off.
| `../../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` / `../../Standalone/Core/src/ResolvedLayoutInternal.h` | `ResolvedLayoutSnapshotV3`: physical layout-chunk width, versioned micrometre intervals, owned ceiling/content/bedrock bands, honored transition settings, deterministic per-column transition bands, 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.42, §8.46. |
| `ResolvedLayoutStratePassageCapabilitiesV1::{hasNativeCaveField,hasNativeLatticeField}`, `IsNativeLatticeFieldStratum`, `HasNativeGraphField` | `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` / `Standalone/Core/src/ResolvedLayoutInternal.h` | Explicit per-strate native graph capability; `Core.Lattice.PrimitiveField` remains Maze/VerticalShafts recipe version 1, and `Core.Caves.PrimitiveField` also accepts VerticalShafts in L139. Lattice seeds include world seed, strate, recipe version and stable feature ID; explicit polyline records keep their endpoints and receive conservative bounds. §8.54, §8.56. |
| `ResolvedLayoutStratePassageCapabilitiesV1::{hasNativeCaveField,hasNativeLatticeField}`, `IsNativeLatticeFieldStratum`, `HasNativeGraphField` | `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` / `Standalone/Core/src/ResolvedLayoutInternal.h` | Explicit per-strate native graph capability; `Core.Lattice.PrimitiveField` is restricted to Maze/VerticalShafts recipe version 1. Lattice seeds include world seed, strate, recipe version and stable feature ID; explicit polyline records keep their endpoints and receive conservative bounds. §8.54. |
| `FCavernRuntimeFeature::FSegmentNode`, `ApplyResolvedNativeCavesField`, `ClassifyNativeCaveFieldBox` | `Standalone/Core/src/ShapeWorldInternal.h` | A deterministic nested segment BVH accelerates native graph distance and conservative interval evaluation; the outer graph BVH still supplies tile candidates and protects `isTileShapeFree`. The 0.4 m feature-union width is separate from the floor fillet width. §8.54. |
| `../../Standalone/Core/src/FloatingIslandsInternal.h` | Canonical standalone/Core floating-island planner, geometry-versioned field, manifest serializer, influence bounds, capsule-route checks, and thickness audit. |
| `ApplyOwnerFourStratePlan` | `Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp` | BuildHost-only transient fixed-slot plan from the four staged owner strate assets; leaves the authored settings and strate packages untouched. |
@@ -1352,20 +1352,6 @@ tunnel-slope version in `VoxelStrateDefinition.cpp`, plus the standalone `VoxelF
in `VoxelForgeExploreCommandlet.cpp`. `GetStrateForChunk` still receives layout-chunk Z, not a Core
tile index. See `Standalone/Research/WorldAssemblerM3/Unreal1/REPORT.md` for BuildHost evidence.
### 3.38 Native Vertical Shafts graph field — World Assembler M3 L139
| Symbol | Canonical file | Role |
|---|---|---|
| `ResolvedCavernPlannerSettingsV1::verticalShaftMode`, basal terminal route planning | `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`, `Standalone/Core/src/ResolvedLayoutInternal.h` | Extends shared `PlanResolvedCavernNetworkV1` for an arrival-only basal strate; its walk-only spine terminates at a landing above bedrock. Shaft mode disables generic branches and uses dedicated shaft nodes. |
| `ResolvedCavernRoomV1::shapeKind=1`, `ApplyResolvedNativeCavesField` | `Standalone/Core/src/ShapeWorldInternal.h` | Evaluates capped vertical shaft cylinders with shelves alongside shared access and cross-connect tunnels. Uses `Core.Caves.PrimitiveField`, not the L58 lattice spiral. |
| VerticalShafts settings mapping | `Standalone/Source/WorldAssemblyPrototype.h` | Maps the 11 legacy params into shared spacing, room density/radii, bore radius, cross-connect density, ledges, roughness, and existing boundary seal/density bands. |
| `IsNativeCaveFieldStratum`, S3 binding and `FCavesFieldAdapter` | `Standalone/Core/src/ShapeWorldInternal.h`, `Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp` | Reports `VerticalShafts` as `Core.Caves.PrimitiveField` v1 / `Caves-native`; leaves the legacy generator archetype identity intact. |
| `RunL139SeedSweep.py`, `RunL139Determinism.py`, `RunL139Captures.py`, `RunL139WholeLayerCapture.py`, `RunL139FinalTiming.py` | `Standalone/Research/WorldAssemblerM3/Linux139/` | Reproducible composed 16-seed audit, Clang/GCC W1/W8/W12 identity check, five before/after eye-height views plus density-cutaway and plan-projection outside views, and L80 characterization. The seed-2 passage-shell failure blocks promotion. |
See ARCHITECTURE §8.56 and
[`Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md)
for the planner semantics, field mapping, audit result, captures, and outstanding shell failure.
## 4. The density pipeline (most-edited hot path)
### 4.1 `GetDensityWithParams` (TunnelNetwork) — VoxelGenerator.cpp:3749
+10 -11
View File
@@ -1,18 +1,18 @@
# VoxelForge current state
As of 2026-11-01. L139 is being developed on `wip/l134-cave-planner`. Current-state claims below point to their code or measured report; L139's Vertical Shafts implementation has not passed composed acceptance and is not promoted.
As of 2026-10-31. L131 is on `assembler/world` as `8107196`; this L132 worktree is on `wip/l132-dispatch-truth`, starting at `ebae71b`. Current-state claims below point to their code or measured report.
## What ships today
- **Core:** evaluator version **237** in the L139 worktree. Unreal's `AVoxelWorld::bUseVoxelForgeCore` remains opt-in and defaults to `false`; the legacy generator remains the default runtime path. [Core version](Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h), [runtime switch](Source/VoxelForge/Public/VoxelWorld.h), [L139 report](Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md).
- **Verified owner4 generator dispatch:** S0 SurfaceWorld binds `SurfaceWorld-native`; S1 FloatingIslands remains `compiled-analytic/FloatingIslands`; S2 TunnelNetwork binds `Core.Caves.PrimitiveField`; and the L139 fast-tier report binds S3 VerticalShafts to `Core.Caves.PrimitiveField` / `Caves-native`. This proves dispatch, not the full shaft gate: the composed 16-seed sweep fails the passage-shell audit at seed 2. [Dispatch](Standalone/Core/src/ShapeWorldInternal.h), [adapter recipe checks](Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h), [L139 report](Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md).
- **Core:** evaluator version **227**. Unreal's `AVoxelWorld::bUseVoxelForgeCore` is opt-in and defaults to `false`; the legacy generator remains the default runtime path. [Core version](Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h), [runtime switch](Source/VoxelForge/Public/VoxelWorld.h), [L130 report](Standalone/Research/WorldAssemblerM3/Linux130/REPORT.md).
- **Verified owner4 generator dispatch (L132):** SW binds `SurfaceWorld-native` because the owner export contains a matching `SurfaceWorld.Heightfield2D` v2 plan. FI binds `compiled-analytic/FloatingIslands` because its `FloatingIslands.ClusterField` v0 layout has no matching native island plan. TN and VS bind `compiled-analytic/TunnelNetwork` and `compiled-analytic/VerticalShafts`; their legacy recipe IDs provide neither a `NativeCaves`/`NativeLattice` graph recipe nor native field capability. The L132 fast-tier report prints the binding and generated tile-center share at each owner strate. [Dispatch](Standalone/Core/src/ShapeWorldInternal.h), [adapter recipe checks](Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h), [L132 report](Standalone/Research/WorldAssemblerM3/Linux132/REPORT.md).
- **Passages:** continuous smooth swept tubes with a continuous floor profile. L125 stamps conservative route slabs and outside sentinels into the tile cache; exact route geometry is still evaluated. All 21,425 route samples passed the open-air walk check; the nine-station floor probe's maximum root offset was 7.884 mm. L130 sets the shared influence reach to **1.0533 m** (0.75 m shell + 0.21 m relief + 0.50 m smooth-max support / 6 + 0.01 m margin), converted once from metres to Core voxels for the proof, feature, fallback, and off-grid bounds. [L125](Standalone/Research/WorldAssemblerM3/Linux125/REPORT.md), [L130](Standalone/Research/WorldAssemblerM3/Linux130/REPORT.md).
- **Streaming:** arrival uses a bounded startup apply burst: `voxel.StreamingStartupApplyBoost=1` by default, up to 24 visible meshes or 14 ms per frame for at most 30 seconds, until the initial desired set and walkable ring are ready. `voxel.StreamingFarApplySupplement=1` is also default-on: after the normal visible apply cap, at most one far result applies when under half the apply-time budget; it is inactive during the startup burst. Dynamic near reserve defaults on; coarse-first remains off; the legacy pending-result cap defaults off. The far-apply lane is Unreal-only. [CVar source](Source/VoxelForge/Private/VoxelWorld.cpp), [L121 report](Standalone/Research/WorldAssemblerM3/Linux121/REPORT.md), [architecture](ARCHITECTURE.md).
- **Determinism:** the L139 Vertical Shafts plan and field match across Clang/GCC at W1/W8/W12 (six cases); L131's unchanged-output comparison still covers the earlier owner4 SW/FI/TN/VS views and canonical owner4/owner2 recipe matrix. Windows determinism is unverified. [L139 checks](Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md), [L131 checks](Standalone/Research/WorldAssemblerM3/Linux131/REPORT.md), [canonical hashes](Standalone/Tools/verify/baselines/owner-hash/canonical/).
- **Determinism:** proven on Linux with Clang and GCC at W1/W8/W12. L131's unchanged-output comparison covers owner4's SW/FI/TN/VS views in 24 compiler/worker cases; the canonical owner4/owner2 recipe matrix also passes. Windows determinism is unverified. [L131 checks](Standalone/Research/WorldAssemblerM3/Linux131/REPORT.md), [v227 canonical hashes](Standalone/Tools/verify/baselines/owner-hash/canonical/).
## Current performance references
Headless medians in seconds, five interleaved L80-style measurements per version in each cell. Near-ready means the complete LOD0–2 set; whole-view is the full requested view. Values below are the latest complete L131 measurements; L139 characterization is in the [L139 report](Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md) and [timing summary](Saved/Linux/l139/timing/summary.json). The paired pre-cleanup comparison is in the [L131 report](Standalone/Research/WorldAssemblerM3/Linux131/REPORT.md) and [timing summary](Saved/Linux/l131/timing/summary.json).
Headless medians in seconds, five interleaved L80-style measurements per version in each cell. Near-ready means the complete LOD0–2 set; whole-view is the full requested view. Values below are the edited L131 binary; the paired pre-cleanup comparison is in the [L131 report](Standalone/Research/WorldAssemblerM3/Linux131/REPORT.md) and [timing summary](Saved/Linux/l131/timing/summary.json).
| Stratum | Near-ready W8 / W12 | Whole-view W8 / W12 |
|---|---:|---:|
@@ -28,18 +28,17 @@ The latest recorded Linux Unreal start-to-LOD0–2 values are L127's one run per
## Open gaps
- Multiplayer world lifecycle is unfinished: seed/layout replication, authoritative modification RPCs, and serialized diff replay for late join are still open. See [ARCHITECTURE §9.5 and §9.7](ARCHITECTURE.md).
- L139 Vertical Shafts is not accepted: the composed audit's seed 2 fails the incoming passage shell after three geometry variants failed that same gate. L80 characterization and the Linux host build passed, but neither changes the composed acceptance result. See [L139 report](Standalone/Research/WorldAssemblerM3/Linux139/REPORT.md).
- Determinism has not been verified on Windows. Linux Clang/GCC agreement does not establish MSVC agreement.
- NullRHI measures residency and apply timing, not the first presented pixel or rendered enclosure. L127 also found four low-contrast views among 23 otherwise verified captures. [L121](Standalone/Research/WorldAssemblerM3/Linux121/REPORT.md), [L127](Standalone/Research/WorldAssemblerM3/Linux127/REPORT.md).
- UE startup/movement numbers above predate L130's v227 reach change; there is no L130/L131 UE movement comparison.
## How to verify
- Build standalone Clang or GCC with [`Standalone/BuildLinux.sh`](Standalone/BuildLinux.sh), for example `bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=l139-clang --fp-contract=off --jobs=4`. The script pins CPUs 0–11 and applies `prlimit --as=6442450944` itself.
- Fast tier: `python3 Standalone/Tools/verify/verify.py fast --out Saved/Linux/l139 --overall-timeout 1740`. It includes the four-strate owner density-dispatch report; per-run logs and the summary stay under `Saved/Linux/l139`.
- The L139 v237 canonical Surface World and Floating Islands owner-hash baselines are in `Standalone/Tools/verify/baselines/owner-hash/canonical/`; both values match v236. L131 also provides reproducible pre-cleanup identity matrices for owner4 tile hashes and owner4/owner2 canonical hashes under `Standalone/Research/WorldAssemblerM3/Linux131/`.
- Timing follows L80: quiet machine, no overlapping build, one warm-up per version, five interleaved runs per stratum and worker count, W8/W12. The L139 run recorded the L137 A/A noise floor of ±1%. Each headless run uses `taskset -c 0-11`, `prlimit --as=6442450944`, and a 1,740 s timeout. See [`RunL139FinalTiming.py`](Standalone/Research/WorldAssemblerM3/Linux139/RunL139FinalTiming.py).
- Linux host build: `/home/jahni/UnrealEngine/Engine/Build/BatchFiles/Linux/Build.sh VFHostEditor Linux Development -Project=/home/jahni/VFHost/VFHost.uproject -NoUBA -MaxParallelActions=4 -Log=/home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l139/ubt.log`. Run Unreal without `prlimit`.
- Build standalone Clang or GCC with [`Standalone/BuildLinux.sh`](Standalone/BuildLinux.sh), for example `bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=l132-clang --fp-contract=off --jobs=4`. The script pins CPUs 0–11 and applies `prlimit --as=6442450944` itself.
- Fast tier: `python3 Standalone/Tools/verify/verify.py fast --out Saved/Linux/l132 --overall-timeout 1740`. It includes the L132 four-pose owner density-dispatch report; per-run logs and the summary stay under `Saved/Linux/l132`.
- Canonical output baselines are the v227 files in `Standalone/Tools/verify/baselines/owner-hash/canonical/`. L131 also provides reproducible pre-cleanup identity matrices for owner4 tile hashes and owner4/owner2 canonical hashes under `Standalone/Research/WorldAssemblerM3/Linux131/`.
- Timing follows L80: quiet machine, no overlapping build, one warm-up per version, five interleaved runs per stratum and worker count, W8/W12. Each headless run uses `taskset -c 0-11`, `prlimit --as=6442450944`, and a 1,740 s timeout. See [`RunL131Timing.py`](Standalone/Research/WorldAssemblerM3/Linux131/RunL131Timing.py).
- Linux host build: `/home/jahni/UnrealEngine/Engine/Build/BatchFiles/Linux/Build.sh VFHostEditor Linux Development -Project=/home/jahni/VFHost/VFHost.uproject -NoUBA -MaxParallelActions=4 -Log=/home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l131/ubt.log`. Run Unreal without `prlimit`.
## Closed experiments
File diff suppressed because it is too large. Load diff
+201
View File
@@ -0,0 +1,201 @@
# L162 — Living Plane
The EGL/OpenGL 4.3 runner builds and passes its llvmpipe correctness and frame checks. The sandbox has no accessible DRM render node, so it did not run or report Intel GPU performance. The runner refuses `--device=gpu` here instead of falling back to software.
## Implementation
`LivingPlane.cpp` runs a ping-pong `RG32F` height/velocity field through a runtime-compiled GLSL compute shader. The damped wave update includes a weak foundation spring, a Gaussian sphere push, and an optional slow breathing force. The spring is needed because a persistent local push otherwise accelerates the zero-frequency height mode and sinks the whole plane. The sphere moves across the plane, stops, and bobs. A vertex-displaced mesh and lit sphere render to an EGL pbuffer-backed framebuffer and save as PNGs.
The timestep is selected from the largest 2D grid eigenfrequency:
`dt = 1.30 / sqrt(8*c*c/(dx*dx) + foundationStiffness)`
The resulting spectral step ratio is 1.30, below the explicit update's 2.0 stability limit. The runner warms the compute kernel for eight unmeasured dispatches, then records one `GL_TIME_ELAPSED` query per requested simulation step in `timing.json`.
The first-step equation audit also caught a GL state error during bring-up: frame rendering left the graphics program active before the next compute dispatch. `Dispatch` now binds the compute program before every step, so the audit fails if a frame silently stops simulation.
Device selection enumerates EGL devices and uses `EGL_EXT_platform_device` for an accessible Intel render node first. On this host, the known integrated device is Intel on `renderD128`. Automatic mode falls back to a surfaceless Mesa context with `LIBGL_ALWAYS_SOFTWARE=1`; explicit GPU mode fails when no accessible hardware node is present. EGL does not expose Vulkan's integrated/discrete enum, so Intel vendor/render-node identity is the selection heuristic.
The Unreal handoff is in [UNREAL-MAPPING.md](UNREAL-MAPPING.md). It keeps the prototype render-only and describes the density mapping if the surface later needs to affect voxel queries. No Unreal `Source/` files changed.
## Measurements and checks
- Built with `Experiments/LivingPlane/build.sh` using the installed EGL, desktop GL, and libpng development files; no shader compiler or package install was needed.
- Final llvmpipe run: 128² field, 360 steps, `dt=9.56814 ms`, spectral ratio 1.30. The first-step equation audit and finite-field/dynamics audit passed. Final field range was −0.139533 m to +0.0366704 m. It wrote 16 128×128 PNGs and a JSON file containing 360 per-step query samples. The frames were inspected; the moving sphere and wake are visible.
- Auto-selection smoke check: 32², 12 steps; selected llvmpipe and passed both audits. Breathing smoke check: 64², 180 steps with `--breathing=on`; passed both audits.
- Negative device-selection control: `--device=gpu` returned an error because the sandbox has no accessible EGL DRM render node.
- Existing fast verification tier passed: 278.9 seconds, ending in `SUMMARY PASS`. Its build and logs are under `Saved/Linux/l162/verify/` and `Saved/Linux/l162/`.
- The llvmpipe `GL_TIME_ELAPSED` samples are preserved in JSON but are software-driver query values, not GPU timings. The requested hardware timing pass remains to be run outside the sandbox.
- No Unreal build was run; no Unreal `Source/` files changed.
## Intel GPU pass
Run these from the plugin root as `jahni`. The frame run writes 512×512 PNGs to `Saved/Linux/l162/gpu-frames-512/`; the two timing runs write `timing.json` with one GPU query per step and skip PNG capture. They still read the field for the first-step and final-state correctness audits.
Before the timing runs, check `uptime` and run them on a quiet machine (load below about 1.5, with no other build active).
```sh
uptime
taskset -c 0-11 prlimit --as=6442450944 -- timeout 1740s ./Saved/Linux/l162/living-plane --device=gpu --size=512 --steps=1800 --capture-every=12 --out=Saved/Linux/l162/gpu-frames-512
taskset -c 0-11 prlimit --as=6442450944 -- timeout 1740s ./Saved/Linux/l162/living-plane --device=gpu --size=512 --steps=1800 --capture-every=0 --out=Saved/Linux/l162/gpu-timing-512
taskset -c 0-11 prlimit --as=6442450944 -- timeout 1740s ./Saved/Linux/l162/living-plane --device=gpu --size=1024 --steps=1800 --capture-every=0 --out=Saved/Linux/l162/gpu-timing-1024
```
Encode the captured sequence as MP4 with:
```sh
ffmpeg -y -framerate 30 -i Saved/Linux/l162/gpu-frames-512/frame_%06d.png -c:v libx264 -pix_fmt yuv420p Saved/Linux/l162/living-plane-512.mp4
```
## Files and remaining risk
The only changed file outside `Experiments/LivingPlane/` is `.gitignore`, which now allows `Experiments/` and its contents. GPU timings and Intel render-node selection remain unverified until the commands above run on the host outside this sandbox.
## Intel GPU pass (run by the orchestrator outside the sandbox, 2026-11-02)
- The device was selected correctly: `Mesa Intel(R) Graphics (ADL GT2)`, OpenGL 4.6, `/dev/dri/renderD128`. 512²,
1,800 steps, 151 frames; the equation audit passes. MP4: `Saved/Linux/l162/living-plane-512.mp4` (local).
- **The `GL_TIME_ELAPSED` per-dispatch values (~0.0001 ms) are not credible** for 262k cells, so they aren't
reported as timings.
- Wall-time difference between 1,800 and 200 steps, divided by the 1,600 steps (start-up cancels out; this includes
submission, so it's an upper bound): **0.080 ms/step at 512²** and **0.292 ms/step at 1024²**.
- Visual read: the effect is very subtle in the current render (a slight dip under the sphere, faint rings). It needs
a larger push amplitude, grazing light or height colouring, and a closer camera to read.
## L163 — readable, living plane
The plane now reads as rolling terrain, and the objects leave visible troughs and wakes. `alive` adds travelling
breathing and a viscoelastic imprint that remains after lift-off. The simulation still runs in one GPU dispatch per
step; CPU work only supplies the two object states.
`LivingPlane.cpp` now keeps the dynamic displacement, velocity, and imprint in an `RGBA32F` ping-pong field. The
surface shader adds broad static terrain relief, calculates normals from relief plus displacement, and uses grazing
light, elevation colours, slope tint, and 7.5 cm contour bands. The camera follows the first sphere at a closer angle.
The wake scene rolls the first sphere, pauses and wobbles it, lifts it, then sends a second sphere through the wake.
The alive scene runs that same sequence with low-frequency travelling swells and a decaying contact imprint. Its
defaults are breathing strength 4.8 m/s², imprint capture 0.15 m/s, recovery time 6 s, and maximum imprint depth
0.34 m. These values have command-line overrides.
The timer query check found no early read or reuse in L162: it allocated a unique query per step, called `glFinish`,
then read every result. The saved Intel/Mesa 25.0.7 samples are 0 or 52 ns for most dispatches (512² median 0,
p95 52 ns; largest sample 17.552 µs), which cannot be a credible per-dispatch cost. The old usage did not reuse
query objects, so lifetime is not the cause; the saved data point to Intel/Mesa's timer-query reporting or timing
scope, but the sandbox cannot isolate which. L163 uses a 64-query ring, reads each query before reusing its slot,
checks availability after `glFinish`, and records `GL_QUERY_COUNTER_BITS`. On llvmpipe the availability check passed
with 64 counter bits and zero waits. The Intel query result still needs the GPU diagnostic command below.
### Measurements and checks
- llvmpipe wake: 128², 600 steps (`dt=9.56814 ms`, 5.741 s simulation window), 151 frames at 30 fps. First-step
equation audit and timer-query lifetime check passed; final displacement range was −0.177488 m to +0.104854 m.
- llvmpipe alive: same grid, steps, and window; equation audit and timer-query lifetime check passed. Final
displacement range was −0.200437 m to +0.115904 m, with a −0.111667 m stored imprint.
- llvmpipe cost: 512², 1,800 steps, `--queries=off`, no frame capture: **0.767473 ms/step** in one timed
simulation-loop window. `timing.json` includes dispatch submission, the step-0 equation readback, and final
`glFinish`, but excludes setup and frame capture. This is a software-renderer measurement, not the Intel GPU cost.
- Both five-second llvmpipe previews are in `Saved/Linux/l163/llvmpipe-wake.mp4` and
`Saved/Linux/l163/llvmpipe-alive.mp4`. They are 128² review previews; use the GPU commands below for the owner
videos.
- Equation-audit negative control: a temporary copy with its expected first-step height forced to zero exited FAIL
at actual −0.0488777 m. The final source passes that same check.
- The fast verification tier passed in 278.5 s. Build and logs are under `Saved/Linux/l163/verify/`.
- No Unreal `Source/` files changed and no Unreal build ran.
### Intel GPU run
Run from the plugin root as `jahni`. First build the runner. For timed runs, check `uptime` and keep the machine
quiet. The wall-time field is valid only when `--capture-every=0`; use `--queries=off` for the step-cost measurement.
```sh
bash Experiments/LivingPlane/build.sh
uptime
taskset -c 0-11 prlimit --as=6442450944 -- timeout 1740s ./Saved/Linux/l163/living-plane --device=gpu --scene=wake --size=512 --steps=2400 --capture-every=16 --queries=off --out=Saved/Linux/l163/gpu-wake-512
taskset -c 0-11 prlimit --as=6442450944 -- timeout 1740s ./Saved/Linux/l163/living-plane --device=gpu --scene=alive --size=512 --steps=2400 --capture-every=16 --queries=off --out=Saved/Linux/l163/gpu-alive-512
ffmpeg -y -framerate 30 -i Saved/Linux/l163/gpu-wake-512/frame_%06d.png -c:v libx264 -pix_fmt yuv420p Saved/Linux/l163/living-plane-wake-512.mp4
ffmpeg -y -framerate 30 -i Saved/Linux/l163/gpu-alive-512/frame_%06d.png -c:v libx264 -pix_fmt yuv420p Saved/Linux/l163/living-plane-alive-512.mp4
taskset -c 0-11 prlimit --as=6442450944 -- timeout 1740s ./Saved/Linux/l163/living-plane --device=gpu --scene=alive --size=512 --steps=1800 --capture-every=0 --queries=off --out=Saved/Linux/l163/gpu-timing-512
taskset -c 0-11 prlimit --as=6442450944 -- timeout 1740s ./Saved/Linux/l163/living-plane --device=gpu --scene=alive --size=512 --steps=1800 --capture-every=0 --queries=on --out=Saved/Linux/l163/gpu-query-check-512
```
`gpu-timing-512/timing.json` reports the 512² batch wall time per step, including dispatch submission and completion.
`gpu-query-check-512/timing.json` contains query counter bits, waits before slot reuse, availability status, and raw
per-step query samples. The sandbox has no accessible Intel DRM node, so the current Intel step cost and new query
diagnostic remain unmeasured here.
### L163 Intel GPU pass (run by the orchestrator, 2026-11-02)
- Intel ADL GT2 (Mesa 25.0.7, `renderD128`): wake and alive scenes, 512², 2,400 steps, 151 frames each; equation
audits PASS. Videos (local): `Saved/Linux/l163/living-plane-wake-512.mp4`, `living-plane-alive-512.mp4`.
- Step cost, alive scene, 512², 1,800 steps, no capture: **0.172 ms/step** with queries off, 0.152 ms/step with
queries on (batch wall time per step).
- The Intel `GL_TIME_ELAPSED` median is still 0 with 64 counter bits and the ring/availability checks passing. That
looks like a Mesa/Intel reporting issue; use wall time.
- **Open issue:** the same scene with the same steps gave different final fields (min −0.637 m with queries off vs
−0.327 m with queries on). Something depends on more than the step index (e.g. wall-clock time); investigate.
## L164 — repeatable field readback and UE runtime actor
**Result:** the repeatability check passes on llvmpipe, and the new `VoxelForgeLivingPlane` runtime module compiles
in the Linux UE 5.7 host. The surface actor is independent of VoxelForge generation and sends no field readback to
the CPU.
### Repeatability finding
`uTime` is `Step * dt`, and `GetBodiesAt` receives that same value. Neither the object schedule nor the breathing
force uses wall time or a rendered-frame counter. Every compute step already issued an image-access barrier before
the next ping-pong image read. The defect was on the diagnostic side: the step-zero and final `glGetTexImage`
readbacks followed shader image writes without `GL_TEXTURE_UPDATE_BARRIER_BIT`. The Khronos OpenGL specification
requires that barrier for `GetTexImage` to observe earlier shader writes ([§7.12](https://registry.khronos.org/OpenGL/specs/gl/glspec44.compatibility.pdf)). Query/capture pacing could therefore affect the reported field values without changing any simulation input. The barrier is now issued before both readbacks.
`check_repeatability.py` runs the same 512² alive scene for 1,800 steps twice: queries off with no captures, then
queries on with captures every 900 steps. The checksum covers every final RGBA32F field value using canonical
little-endian float bytes.
- llvmpipe, queries off/capture off: field range −0.637382 m to +0.109308 m; checksum
`1ba08f5dafc01f82`.
- llvmpipe, queries on/capture every 900: the same range and checksum; equation and timer-query audits pass; three
frames written.
- Negative control: changing one saved checksum made the comparison exit 1 with `FAIL field checksum mismatch`.
- The llvmpipe runs were each one 1,800-step simulation-loop window. Logs and JSON are under
`Saved/Linux/l164/repeatability/`.
The Intel run is not available in this sandbox. The owner should repeat the checksum comparison on the GPU to
confirm that the missing transfer-readback barrier accounts for the earlier Intel min mismatch:
```sh
python3 Experiments/LivingPlane/check_repeatability.py --device=gpu --out=Saved/Linux/l164/gpu-repeatability
```
### Unreal implementation and checks
The plugin descriptor adds a separate `VoxelForgeLivingPlane` runtime module. Its RDG global shader is in
`Shaders/LivingPlane.usf`; module startup maps `/Plugin/VoxelForgeLivingPlane` to the plugin shader directory. The
actor owns two UAV-capable RGBA32F render targets, advances them at the stable fixed step, and supplies the current
texture to a movable plane mesh material. Its Blueprint/C++ object input includes world position, radius, velocity,
base push, and active state. The CPU converts those values to plane-local metres and uploads uniforms; it does not
read the field back. The ignore rules now include `Shaders/` so that the shader ships in the worktree diff.
`Experiments/LivingPlane/UE-SETUP.md` gives level setup, the full material graph, and object driving steps.
- Linux UE 5.7 `VFHostEditor Linux Development`: **PASS**, final incremental build compiled
`VoxelForgeLivingPlaneActor.cpp` and linked `libUnrealEditor-VoxelForgeLivingPlane.so`. Command used
`-NoUBA -MaxParallelActions=4`, `taskset -c 0-11`, and no `prlimit`. Log:
`Saved/Linux/l164/ue-build-final.log`. The initial attempt exposed an incorrect RDG texture registration overload;
it had already compiled `VoxelForgeLivingPlaneModule.cpp` and the generated module code. The corrected final
build passed.
- The host `PluginDeps/VoxelForge/Source` and `.uplugin` links were temporarily pointed at this worktree for the
build and restored to `/home/jahni/VoxelM/Plugins/VoxelForge` afterward. The temporary shader link was removed.
- Standalone build, final repeatability comparison, checksum-mismatch negative control, plugin JSON parse, and
`git diff --check` passed.
- Not run: fast generation verification (generation sources are untouched), Intel GPU checksum comparison, or a UE
editor render/shader-runtime check. The Linux UBT build verifies C++ and module integration, not first-use shader
compilation or material appearance.
New Unreal source and shader files for the owner's Windows build:
- `Source/VoxelForgeLivingPlane/VoxelForgeLivingPlane.Build.cs`
- `Source/VoxelForgeLivingPlane/Public/VoxelForgeLivingPlaneActor.h`
- `Source/VoxelForgeLivingPlane/Private/VoxelForgeLivingPlaneActor.cpp`
- `Source/VoxelForgeLivingPlane/Private/VoxelForgeLivingPlaneModule.cpp`
- `Shaders/LivingPlane.usf`
No VoxelForge generation module files changed. Remaining risks are the Intel checksum confirmation and first-use UE
shader/material rendering, which require the owner's GPU/editor run.
+55
View File
@@ -0,0 +1,55 @@
# Living Plane in Unreal Engine 5.7
`VoxelForgeLivingPlane` is a separate runtime module. It does not call the VoxelForge terrain generators and it does not read the simulated texture back to the CPU. The actor owns two transient `RGBA32f` render targets and advances them with an RDG compute pass. The CPU sends object state and fixed-step uniforms only.
## Add it to a level
1. Enable the VoxelForge plugin and restart the editor so the `VoxelForgeLivingPlane` runtime module and its shader mapping load.
2. Create a material named `M_LivingPlane` using the graph below.
3. Place `VoxelForgeLivingPlaneActor` in the level. Assign `M_LivingPlane` to **Plane Material**.
4. Keep the actor on the world XY plane with unit actor scale. `Plane Length Meters` controls the mesh width and simulation width; the built-in plane mesh is scaled to that size.
5. The actor creates and clears its two GPU state targets on `BeginPlay`. The mesh has collision disabled; this surface is render-only and does not change VoxelForge density or collision queries.
## Material graph
Use a Surface, Opaque material. The actor binds these parameters on its dynamic material instance:
- `LivingField`: Texture Object Parameter. The texture is the current RGBA32f simulation state; **R** is displacement in metres.
- `PlaneLengthMeters`: Scalar Parameter.
- `FieldSize`: Scalar Parameter, equal to the render target width and height.
For World Position Offset:
1. Read `LivingField` at `TextureCoordinate[0]` with a Texture Sample.
2. Multiply its **R** output by `100` to convert metres to Unreal centimetres.
3. Append `(0, 0)` to that value, making `(0, 0, heightCm)`, and connect it to **World Position Offset**.
For the displaced normal, sample the height at four UV offsets using the same texture object:
- Left/right UV: `TexCoord + (-1/FieldSize, 0)` and `TexCoord + (1/FieldSize, 0)`.
- Down/up UV: `TexCoord + (0, -1/FieldSize)` and `TexCoord + (0, 1/FieldSize)`.
- `dHdx = (Right.R - Left.R) * FieldSize / (2 * PlaneLengthMeters)`.
- `dHdy = (Up.R - Down.R) * FieldSize / (2 * PlaneLengthMeters)`.
- Make and normalize the tangent-space vector `(-dHdx, -dHdy, 1)`, then connect it to **Normal**.
The built-in plane's U/V tangent directions align with local X/Y. Use a neutral base colour and roughness around `0.7` to start. The graph assumes a horizontal plane; add a local-to-world transform if the plane needs arbitrary rotation.
## Drive objects
`ObjectInputs` has two slots. Each `FVFLivingPlaneObjectInput` contains world position in centimetres, world velocity in centimetres per second, radius in centimetres, base push acceleration in metres per second squared, and an active flag. Blueprint can use **Set Object State** or set the array entry; C++ can call the same method. Set the object's center about one radius above the plane while it contacts it, and mark the slot inactive after lift-off.
The compute shader uses the radius to scale the Gaussian contact footprint. The original wave equation keeps the L163 wave speed, damping, foundation spring, travelling breathing force, and recovering imprint. The base push acceleration supplies the object force; lateral speed adds `0.25 m/s²` per `1 m/s`, and downward speed adds `0.5 m/s²` per `1 m/s`. Upward velocity does not add force. Object positions and velocities are transformed into the plane's local frame and converted from centimetres to metres before upload.
Each step uses `dt = 1.30 / sqrt(8*c*c/(dx*dx) + foundationStiffness)`, with `dx = PlaneLengthMeters / FieldSize`. Simulation time passed to breathing is the fixed step index times `dt`. Game-thread delta time only determines how many fixed steps are queued; no GPU field data is read back in the normal path.
## Build files
The owner's Windows build needs every added source and shader file:
- `Source/VoxelForgeLivingPlane/VoxelForgeLivingPlane.Build.cs`
- `Source/VoxelForgeLivingPlane/Public/VoxelForgeLivingPlaneActor.h`
- `Source/VoxelForgeLivingPlane/Private/VoxelForgeLivingPlaneActor.cpp`
- `Source/VoxelForgeLivingPlane/Private/VoxelForgeLivingPlaneModule.cpp`
- `Shaders/LivingPlane.usf`
The `VoxelForge.uplugin` runtime-module entry must ship with them.
+33
View File
@@ -0,0 +1,33 @@
# Unreal mapping note
The prototype stores height, vertical velocity, a recovering imprint, and a spare
channel in a pair of `RGBA32F` textures. A world-owned Unreal component can keep
equivalent transient render graph textures and advance them with a compute pass. It
should own simulation time and clear or restore its buffers when the world is recreated.
The sphere path becomes a world-space interaction event: position, contact radius,
and impulse strength are supplied to the compute pass. For multiplayer or deterministic
replay, replicate the compact events and simulation tick, or record the resulting field;
do not assume that independent GPU floating-point runs will produce byte-identical
textures.
The rendered top surface can remain a render-only displaced mesh. If it must participate
in voxel collision or queries, its height must also reach the density evaluator. For a
height `h(x,y)`, the plugin's density convention is negative inside solid and positive
in air, so the plane's signed density is `z - h(x,y)`. Keep this calculation in metres
until the existing voxel/Core boundary converts with the active voxel size (25 cm by
default); do not mix metre distances and voxel counts in the wave solver.
The current sample is an isolated visual field. Wiring this into `AVoxelWorld` would
need an explicit owner for simulation lifetime, collision/update cadence, save/load,
and the replication policy before it could affect shipped terrain.
## L164 render-only Unreal implementation
`Source/VoxelForgeLivingPlane/` now implements this render-only path as a separate
runtime module. `AVoxelForgeLivingPlaneActor` owns two UAV-capable RGBA32F render
targets, advances the wave, breathing, and imprint equations with an RDG global shader,
and binds the current texture to its plane material. Blueprint/C++ supplies object
position, radius, velocity, push, and active state. The actor does not call the
generation modules and does not read the field back. Level setup and the material graph
are in [UE-SETUP.md](UE-SETUP.md).
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PLUGIN_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd)"
OUTPUT_DIR="${PLUGIN_ROOT}/Saved/Linux/l164"
CXX="${CXX:-g++}"
command -v "${CXX}" >/dev/null || { echo "C++ compiler not found: ${CXX}" >&2; exit 2; }
pkg-config --exists egl gl libpng || {
echo "EGL, desktop OpenGL, and libpng development files are required" >&2
exit 2
}
mkdir -p "${OUTPUT_DIR}"
read -r -a GRAPHICS_FLAGS <<<"$(pkg-config --cflags --libs egl gl libpng)"
taskset -c 0-11 prlimit --as=6442450944 -- \
"${CXX}" -std=c++20 -O2 -g -Wall -Wextra -Wpedantic \
"${SCRIPT_DIR}/LivingPlane.cpp" -o "${OUTPUT_DIR}/living-plane" \
"${GRAPHICS_FLAGS[@]}"
echo "built ${OUTPUT_DIR}/living-plane"
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env python3
"""Compare final field checksums across different query and capture settings."""
from __future__ import annotations
import argparse
import json
import pathlib
import shutil
import subprocess
import sys
PLUGIN_ROOT = pathlib.Path(__file__).resolve().parents[2]
def read_checksum(path: pathlib.Path) -> str:
try:
with path.open(encoding="utf-8") as source:
result = json.load(source)
except (OSError, json.JSONDecodeError) as error:
raise RuntimeError(f"could not read {path}: {error}") from error
checksum = result.get("field_checksum_fnv1a64")
if not isinstance(checksum, str) or len(checksum) != 16:
raise RuntimeError(f"{path} has no 16-digit field checksum")
return checksum
def compare(left: pathlib.Path, right: pathlib.Path) -> bool:
left_checksum = read_checksum(left)
right_checksum = read_checksum(right)
if left_checksum != right_checksum:
print(
"FAIL field checksum mismatch: "
f"{left}={left_checksum}, {right}={right_checksum}",
file=sys.stderr,
)
return False
print(f"PASS field checksum matches: {left_checksum}")
return True
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--binary",
type=pathlib.Path,
default=PLUGIN_ROOT / "Saved/Linux/l164/living-plane",
)
parser.add_argument(
"--out",
type=pathlib.Path,
default=PLUGIN_ROOT / "Saved/Linux/l164/repeatability",
)
parser.add_argument("--device", choices=("auto", "cpu", "gpu"), default="cpu")
parser.add_argument("--size", type=int, default=512)
parser.add_argument("--steps", type=int, default=1800)
parser.add_argument(
"--compare-only",
nargs=2,
type=pathlib.Path,
metavar=("LEFT_JSON", "RIGHT_JSON"),
help="compare existing timing.json files; used to exercise the failure path",
)
options = parser.parse_args()
if options.compare_only:
return 0 if compare(*options.compare_only) else 1
if not options.binary.is_file():
parser.error(f"binary not found: {options.binary}; run Experiments/LivingPlane/build.sh")
options.out.mkdir(parents=True, exist_ok=True)
off_dir = options.out / "queries-off_capture-off"
on_dir = options.out / "queries-on_capture-every-900"
for directory in (off_dir, on_dir):
if directory.exists():
shutil.rmtree(directory)
common = [
f"--device={options.device}",
"--scene=alive",
f"--size={options.size}",
f"--steps={options.steps}",
]
runs = (
("--capture-every=0", "--queries=off", off_dir),
("--capture-every=900", "--queries=on", on_dir),
)
for capture, queries, output in runs:
command = [
"taskset",
"-c",
"0-11",
"prlimit",
"--as=6442450944",
"--",
"timeout",
"1740s",
str(options.binary.resolve()),
*common,
capture,
queries,
f"--out={output}",
]
print("RUN " + " ".join(command), flush=True)
log_path = options.out / f"{output.name}.log"
with log_path.open("w", encoding="utf-8") as log_file:
try:
subprocess.run(
command,
cwd=PLUGIN_ROOT,
check=True,
stdout=log_file,
stderr=subprocess.STDOUT,
)
except subprocess.CalledProcessError:
print(log_path.read_text(encoding="utf-8"), file=sys.stderr)
raise
print(log_path.read_text(encoding="utf-8").rstrip())
left = off_dir / "timing.json"
right = on_dir / "timing.json"
return 0 if compare(left, right) else 1
if __name__ == "__main__":
try:
raise SystemExit(main())
except (OSError, RuntimeError, subprocess.CalledProcessError) as error:
print(f"FAIL repeatability check: {error}", file=sys.stderr)
raise SystemExit(1)
+85
View File
@@ -0,0 +1,85 @@
Texture2D<float4> SourceState;
RWTexture2D<float4> TargetState;
int2 GridSize;
float Dt;
float Dx;
float PlaneLength;
float WaveSpeed;
float Damping;
float FoundationStiffness;
float TimeSeconds;
float2 BreathingSettings;
float4 ImprintSettings;
float4 ObjectPositionRadius[2];
float4 ObjectVelocityPush[2];
[numthreads(8, 8, 1)]
void MainCS(uint3 DispatchThreadId : SV_DispatchThreadID)
{
int2 Pixel = int2(DispatchThreadId.xy);
if (Pixel.x >= GridSize.x || Pixel.y >= GridSize.y)
{
return;
}
int2 Lo = int2(0, 0);
int2 Hi = GridSize - 1;
float4 State = SourceState.Load(int3(Pixel, 0));
float Height = State.r;
float Velocity = State.g;
float Imprint = State.b;
float Left = SourceState.Load(int3(max(Pixel + int2(-1, 0), Lo), 0)).r;
float Right = SourceState.Load(int3(min(Pixel + int2(1, 0), Hi), 0)).r;
float Down = SourceState.Load(int3(max(Pixel + int2(0, -1), Lo), 0)).r;
float Up = SourceState.Load(int3(min(Pixel + int2(0, 1), Hi), 0)).r;
float Laplacian = (Left + Right + Down + Up - 4.0 * Height) / max(Dx * Dx, 1.0e-8);
float2 World = (float2(Pixel) + 0.5) * Dx - PlaneLength * 0.5;
float Interaction = 0.0;
float Contact = 0.0;
for (int ObjectIndex = 0; ObjectIndex < 2; ++ObjectIndex)
{
float4 PositionRadius = ObjectPositionRadius[ObjectIndex];
if (PositionRadius.w <= 0.0)
{
continue;
}
float4 VelocityPush = ObjectVelocityPush[ObjectIndex];
float Radius = PositionRadius.w;
float Sigma = max(Radius * (0.58 / 0.43), Dx);
float2 Offset = World - PositionRadius.xy;
float Weight = exp(-dot(Offset, Offset) / max(2.0 * Sigma * Sigma, 1.0e-8));
float HeightAboveContact = max(PositionRadius.z - Radius, 0.0);
float ContactHeight = 1.0 - smoothstep(0.0, max(Radius, Dx), HeightAboveContact);
float ImpactSpeed = length(VelocityPush.xy) * 0.25 + max(-VelocityPush.z, 0.0) * 0.5;
float Push = max(VelocityPush.w, 0.0) + ImpactSpeed;
Interaction -= Push * Weight * ContactHeight;
if (Push > 0.0)
{
Contact = max(Contact, Weight * ContactHeight);
}
}
float Breathing = 0.0;
if (BreathingSettings.x != 0.0)
{
float Swell = sin(World.x * 0.48 - TimeSeconds * 0.22)
* cos(World.y * 0.42 + TimeSeconds * 0.16);
Breathing = BreathingSettings.y * Swell * sin(TimeSeconds * 0.48);
}
float NextImprint = Imprint;
if (ImprintSettings.x != 0.0)
{
NextImprint = clamp(Imprint * exp(-Dt / max(ImprintSettings.z, 1.0e-4))
- Contact * ImprintSettings.y * Dt, -ImprintSettings.w, 0.0);
}
float FoundationTarget = ImprintSettings.x != 0.0 ? Imprint : 0.0;
float Acceleration = WaveSpeed * WaveSpeed * Laplacian
- FoundationStiffness * (Height - FoundationTarget) + Interaction + Breathing;
float NextVelocity = (Velocity + Acceleration * Dt) * exp(-Damping * Dt);
float NextHeight = Height + NextVelocity * Dt;
TargetState[Pixel] = float4(NextHeight, NextVelocity, NextImprint, 0.0);
}
@@ -144,15 +144,13 @@ bool ConfigureCoreGeometryStratum(const FStrateSlot& Slot, ECaveGeneratorType Ge
return true;
case EVoxelForgeCoreGeneratorRecipe::NativeCaves:
if (GeneratorType != ECaveGeneratorType::TunnelNetwork
&& GeneratorType != ECaveGeneratorType::Underwater
&& GeneratorType != ECaveGeneratorType::VerticalShafts)
&& GeneratorType != ECaveGeneratorType::Underwater)
{
OutError = FString::Printf(TEXT("Strate %d selects NativeCaves but its generator archetype is not TunnelNetwork/Underwater/VerticalShafts."),
OutError = FString::Printf(TEXT("Strate %d selects NativeCaves but its generator archetype is not TunnelNetwork/Underwater."),
Slot.StrateIndex);
return false;
}
Item.generatorKind = GeneratorType == ECaveGeneratorType::VerticalShafts
? "VerticalShafts" : "Caves";
Item.generatorKind = "Caves";
Item.recipeId = "Core.Caves.PrimitiveField";
Item.recipeVersion = 1;
Item.boundDispatchPath = "Core native cave graph uses resolved room and tunnel records";
@@ -0,0 +1,303 @@
#include "VoxelForgeLivingPlaneActor.h"
#include "Engine/TextureRenderTarget2D.h"
#include "Engine/TextureRenderTarget.h"
#include "Engine/StaticMesh.h"
#include "Engine/World.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Materials/MaterialInterface.h"
#include "RenderGraphBuilder.h"
#include "RenderGraphUtils.h"
#include "RHICommandList.h"
#include "RHIResources.h"
#include "DataDrivenShaderPlatformInfo.h"
#include "GlobalShader.h"
#include "ShaderParameterStruct.h"
#include "UObject/ConstructorHelpers.h"
#include "Components/StaticMeshComponent.h"
namespace
{
constexpr int32 LivingPlaneThreadGroupSize = 8;
struct FLivingPlaneStepInput
{
FVector4f ObjectPositionRadius[2] = {FVector4f(0, 0, 0, -1), FVector4f(0, 0, 0, -1)};
FVector4f ObjectVelocityPush[2] = {FVector4f(0, 0, 0, 0), FVector4f(0, 0, 0, 0)};
float TimeSeconds = 0.0f;
};
class FVFLivingPlaneStepCS final : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FVFLivingPlaneStepCS);
SHADER_USE_PARAMETER_STRUCT(FVFLivingPlaneStepCS, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER(FIntPoint, GridSize)
SHADER_PARAMETER(float, Dt)
SHADER_PARAMETER(float, Dx)
SHADER_PARAMETER(float, PlaneLength)
SHADER_PARAMETER(float, WaveSpeed)
SHADER_PARAMETER(float, Damping)
SHADER_PARAMETER(float, FoundationStiffness)
SHADER_PARAMETER(float, TimeSeconds)
SHADER_PARAMETER(FVector2f, BreathingSettings)
SHADER_PARAMETER(FVector4f, ImprintSettings)
SHADER_PARAMETER_ARRAY(FVector4f, ObjectPositionRadius, [2])
SHADER_PARAMETER_ARRAY(FVector4f, ObjectVelocityPush, [2])
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D<float4>, SourceState)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, TargetState)
END_SHADER_PARAMETER_STRUCT()
public:
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
}
};
IMPLEMENT_GLOBAL_SHADER(FVFLivingPlaneStepCS,
"/Plugin/VoxelForgeLivingPlane/LivingPlane.usf", "MainCS", SF_Compute)
UTextureRenderTarget2D* CreateFieldTarget(UObject* Outer, int32 Size, FName Name)
{
UTextureRenderTarget2D* Target = NewObject<UTextureRenderTarget2D>(Outer, Name, RF_Transient);
Target->RenderTargetFormat = RTF_RGBA32f;
Target->bCanCreateUAV = true;
Target->bAutoGenerateMips = false;
Target->ClearColor = FLinearColor::Transparent;
Target->Filter = TF_Bilinear;
Target->AddressX = TA_Clamp;
Target->AddressY = TA_Clamp;
Target->InitAutoFormat(Size, Size);
Target->UpdateResourceImmediate(true);
return Target;
}
}
AVoxelForgeLivingPlaneActor::AVoxelForgeLivingPlaneActor()
{
PrimaryActorTick.bCanEverTick = true;
PlaneMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("LivingPlaneMesh"));
SetRootComponent(PlaneMesh);
PlaneMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
PlaneMesh->SetMobility(EComponentMobility::Movable);
static ConstructorHelpers::FObjectFinder<UStaticMesh> PlaneAsset(
TEXT("/Engine/BasicShapes/Plane.Plane"));
if (PlaneAsset.Succeeded())
{
PlaneMesh->SetStaticMesh(PlaneAsset.Object);
}
ObjectInputs.SetNum(2);
}
void AVoxelForgeLivingPlaneActor::OnConstruction(const FTransform& Transform)
{
Super::OnConstruction(Transform);
if (PlaneMesh)
{
// /Engine/BasicShapes/Plane is 100 cm square; one Unreal scale unit
// therefore corresponds to one metre of authored plane length.
PlaneMesh->SetRelativeScale3D(FVector(PlaneLengthMeters, PlaneLengthMeters, 1.0));
}
}
float AVoxelForgeLivingPlaneActor::GetStableStepSeconds() const
{
const float Dx = PlaneLengthMeters / static_cast<float>(FMath::Max(GridSize, 16));
const float EigenFrequencySquared = 8.0f * WaveSpeedMetersPerSecond * WaveSpeedMetersPerSecond
/ FMath::Max(Dx * Dx, 1.0e-8f) + FoundationStiffnessPerSecondSquared;
return 1.30f / FMath::Sqrt(FMath::Max(EigenFrequencySquared, 1.0e-8f));
}
void AVoxelForgeLivingPlaneActor::BeginPlay()
{
Super::BeginPlay();
GridSize = FMath::Clamp(GridSize, 16, 2048);
PlaneLengthMeters = FMath::Max(PlaneLengthMeters, 1.0f);
FixedStepSeconds = GetStableStepSeconds();
CreateFieldTargets();
if (PlaneMaterial && PlaneMesh)
{
DynamicPlaneMaterial = PlaneMesh->CreateDynamicMaterialInstance(0, PlaneMaterial);
if (DynamicPlaneMaterial)
{
DynamicPlaneMaterial->SetScalarParameterValue(TEXT("PlaneLengthMeters"), PlaneLengthMeters);
DynamicPlaneMaterial->SetScalarParameterValue(TEXT("FieldSize"), static_cast<float>(GridSize));
}
}
UpdateMaterialField();
}
void AVoxelForgeLivingPlaneActor::CreateFieldTargets()
{
FieldTargets[0] = CreateFieldTarget(this, GridSize, TEXT("LivingPlaneStateA"));
FieldTargets[1] = CreateFieldTarget(this, GridSize, TEXT("LivingPlaneStateB"));
CurrentFieldIndex = 0;
SimulationStepCount = 0;
SimulationAccumulatorSeconds = 0.0;
}
void AVoxelForgeLivingPlaneActor::SetObjectState(int32 ObjectIndex,
const FVFLivingPlaneObjectInput& State)
{
if (!ObjectInputs.IsValidIndex(ObjectIndex) || ObjectIndex >= 2)
{
return;
}
ObjectInputs[ObjectIndex] = State;
}
void AVoxelForgeLivingPlaneActor::ResetSimulation()
{
if (!IsInGameThread() || !FieldTargets[0] || !FieldTargets[1])
{
return;
}
CreateFieldTargets();
FixedStepSeconds = GetStableStepSeconds();
UpdateMaterialField();
}
void AVoxelForgeLivingPlaneActor::UpdateMaterialField()
{
if (DynamicPlaneMaterial && FieldTargets[CurrentFieldIndex])
{
DynamicPlaneMaterial->SetTextureParameterValue(TEXT("LivingField"), FieldTargets[CurrentFieldIndex]);
}
}
void AVoxelForgeLivingPlaneActor::EnqueueSimulationSteps(int32 NumSteps)
{
if (NumSteps <= 0 || !FieldTargets[0] || !FieldTargets[1])
{
return;
}
FTextureRenderTargetResource* ResourceA = FieldTargets[0]->GameThread_GetRenderTargetResource();
FTextureRenderTargetResource* ResourceB = FieldTargets[1]->GameThread_GetRenderTargetResource();
if (!ResourceA || !ResourceB)
{
return;
}
TArray<FLivingPlaneStepInput> Steps;
Steps.Reserve(NumSteps);
const FTransform PlaneTransform = GetActorTransform();
for (int32 Step = 0; Step < NumSteps; ++Step)
{
FLivingPlaneStepInput& Input = Steps.AddDefaulted_GetRef();
Input.TimeSeconds = static_cast<float>(SimulationStepCount + Step) * FixedStepSeconds;
for (int32 ObjectIndex = 0; ObjectIndex < 2; ++ObjectIndex)
{
if (!ObjectInputs.IsValidIndex(ObjectIndex) || !ObjectInputs[ObjectIndex].bActive)
{
continue;
}
const FVFLivingPlaneObjectInput& Object = ObjectInputs[ObjectIndex];
const FVector LocalPosition = PlaneTransform.InverseTransformPosition(Object.WorldPositionCm);
const FVector LocalVelocity = PlaneTransform.InverseTransformVector(Object.WorldVelocityCmPerSecond);
const float RadiusMeters = FMath::Max(Object.RadiusCm * 0.01f, 0.001f);
Input.ObjectPositionRadius[ObjectIndex] = FVector4f(
static_cast<float>(LocalPosition.X * 0.01),
static_cast<float>(LocalPosition.Y * 0.01),
static_cast<float>(LocalPosition.Z * 0.01),
RadiusMeters);
Input.ObjectVelocityPush[ObjectIndex] = FVector4f(
static_cast<float>(LocalVelocity.X * 0.01),
static_cast<float>(LocalVelocity.Y * 0.01),
static_cast<float>(LocalVelocity.Z * 0.01),
FMath::Max(Object.PushAccelerationMetersPerSecondSquared, 0.0f));
}
}
const int32 Resolution = GridSize;
const int32 InitialFieldIndex = CurrentFieldIndex;
const float Dt = static_cast<float>(FixedStepSeconds);
const float Dx = PlaneLengthMeters / static_cast<float>(Resolution);
const float PlaneLength = PlaneLengthMeters;
const float WaveSpeed = WaveSpeedMetersPerSecond;
const float Damping = DampingPerSecond;
const float Foundation = FoundationStiffnessPerSecondSquared;
const float BreathingStrength = bEnableBreathing ? BreathingStrengthMetersPerSecondSquared : 0.0f;
const FVector2f BreathingSettings(bEnableBreathing ? 1.0f : 0.0f, BreathingStrength);
const FVector4f ImprintSettings(bEnableImprint ? 1.0f : 0.0f,
ImprintCaptureMetersPerSecond, FMath::Max(ImprintRecoverySeconds, 1.0e-4f),
FMath::Max(ImprintMaxDepthMeters, 0.0f));
ENQUEUE_RENDER_COMMAND(VoxelForgeLivingPlaneStep)(
[ResourceA, ResourceB, Steps = MoveTemp(Steps), InitialFieldIndex, Resolution, Dt, Dx, PlaneLength,
WaveSpeed, Damping, Foundation, BreathingSettings, ImprintSettings]
(FRHICommandListImmediate& RHICmdList) mutable
{
FRDGBuilder GraphBuilder(RHICmdList, RDG_EVENT_NAME("VoxelForgeLivingPlane"));
FRDGTextureRef Fields[2] = {
RegisterExternalTexture(GraphBuilder, ResourceA->GetRenderTargetTexture().GetReference(), TEXT("LivingPlaneStateA")),
RegisterExternalTexture(GraphBuilder, ResourceB->GetRenderTargetTexture().GetReference(), TEXT("LivingPlaneStateB"))};
TShaderMapRef<FVFLivingPlaneStepCS> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
int32 CurrentIndex = InitialFieldIndex;
for (const FLivingPlaneStepInput& StepInput : Steps)
{
const int32 TargetIndex = 1 - CurrentIndex;
FVFLivingPlaneStepCS::FParameters* PassParameters =
GraphBuilder.AllocParameters<FVFLivingPlaneStepCS::FParameters>();
PassParameters->GridSize = FIntPoint(Resolution, Resolution);
PassParameters->Dt = Dt;
PassParameters->Dx = Dx;
PassParameters->PlaneLength = PlaneLength;
PassParameters->WaveSpeed = WaveSpeed;
PassParameters->Damping = Damping;
PassParameters->FoundationStiffness = Foundation;
PassParameters->TimeSeconds = StepInput.TimeSeconds;
PassParameters->BreathingSettings = BreathingSettings;
PassParameters->ImprintSettings = ImprintSettings;
for (int32 ObjectIndex = 0; ObjectIndex < 2; ++ObjectIndex)
{
PassParameters->ObjectPositionRadius[ObjectIndex] = StepInput.ObjectPositionRadius[ObjectIndex];
PassParameters->ObjectVelocityPush[ObjectIndex] = StepInput.ObjectVelocityPush[ObjectIndex];
}
PassParameters->SourceState = GraphBuilder.CreateSRV(Fields[CurrentIndex]);
PassParameters->TargetState = GraphBuilder.CreateUAV(Fields[TargetIndex]);
FComputeShaderUtils::AddPass(GraphBuilder,
RDG_EVENT_NAME("LivingPlaneStep"),
ComputeShader, PassParameters,
FIntVector(FMath::DivideAndRoundUp(Resolution, LivingPlaneThreadGroupSize),
FMath::DivideAndRoundUp(Resolution, LivingPlaneThreadGroupSize), 1));
CurrentIndex = TargetIndex;
}
GraphBuilder.Execute();
});
CurrentFieldIndex = (InitialFieldIndex + NumSteps) & 1;
SimulationStepCount += NumSteps;
UpdateMaterialField();
}
void AVoxelForgeLivingPlaneActor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (FixedStepSeconds <= 0.0 || !FieldTargets[0] || !FieldTargets[1])
{
return;
}
SimulationAccumulatorSeconds += FMath::Max(static_cast<double>(DeltaSeconds), 0.0);
const int32 StepsToRun = FMath::Min(
static_cast<int32>(SimulationAccumulatorSeconds / FixedStepSeconds), 32);
if (StepsToRun > 0)
{
SimulationAccumulatorSeconds -= StepsToRun * FixedStepSeconds;
EnqueueSimulationSteps(StepsToRun);
}
}
void AVoxelForgeLivingPlaneActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
DynamicPlaneMaterial = nullptr;
FieldTargets[0] = nullptr;
FieldTargets[1] = nullptr;
}
@@ -0,0 +1,25 @@
#include "Modules/ModuleManager.h"
#include "Interfaces/IPluginManager.h"
#include "Misc/Paths.h"
#include "ShaderCore.h"
class FVoxelForgeLivingPlaneModule final : public IModuleInterface
{
public:
virtual void StartupModule() override
{
const TSharedPtr<IPlugin> Plugin = IPluginManager::Get().FindPlugin(TEXT("VoxelForge"));
if (!Plugin.IsValid())
{
UE_LOG(LogTemp, Error, TEXT("VoxelForgeLivingPlane could not find its owning plugin."));
return;
}
AddShaderSourceDirectoryMapping(
TEXT("/Plugin/VoxelForgeLivingPlane"),
FPaths::Combine(Plugin->GetBaseDir(), TEXT("Shaders")));
}
};
IMPLEMENT_MODULE(FVoxelForgeLivingPlaneModule, VoxelForgeLivingPlane)
@@ -0,0 +1,114 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "VoxelForgeLivingPlaneActor.generated.h"
class UMaterialInterface;
class UMaterialInstanceDynamic;
class UStaticMeshComponent;
class UTextureRenderTarget2D;
USTRUCT(BlueprintType)
struct FVFLivingPlaneObjectInput
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Object")
FVector WorldPositionCm = FVector(0.0, 0.0, 43.0);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Object")
FVector WorldVelocityCmPerSecond = FVector::ZeroVector;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Object", meta=(ClampMin="0.1"))
float RadiusCm = 43.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Object", meta=(ClampMin="0.0"))
float PushAccelerationMetersPerSecondSquared = 36.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Object")
bool bActive = false;
};
/** A render-only, GPU-stepped heightfield plane. Object state is uploaded; the field is never read back. */
UCLASS(BlueprintType, Blueprintable)
class VOXELFORGELIVINGPLANE_API AVoxelForgeLivingPlaneActor : public AActor
{
GENERATED_BODY()
public:
AVoxelForgeLivingPlaneActor();
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
virtual void OnConstruction(const FTransform& Transform) override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
UFUNCTION(BlueprintCallable, Category="Living Plane|Object")
void SetObjectState(int32 ObjectIndex, const FVFLivingPlaneObjectInput& State);
UFUNCTION(BlueprintCallable, Category="Living Plane")
void ResetSimulation();
UFUNCTION(BlueprintPure, Category="Living Plane")
int64 GetSimulationStepCount() const { return SimulationStepCount; }
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Living Plane")
TObjectPtr<UStaticMeshComponent> PlaneMesh;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Living Plane|Rendering")
TObjectPtr<UMaterialInterface> PlaneMaterial;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Simulation", meta=(ClampMin="16", ClampMax="2048"))
int32 GridSize = 256;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Simulation", meta=(ClampMin="1.0", ClampMax="100.0"))
float PlaneLengthMeters = 12.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Simulation", meta=(ClampMin="0.0"))
float WaveSpeedMetersPerSecond = 4.5f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Simulation", meta=(ClampMin="0.0"))
float DampingPerSecond = 1.35f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Simulation", meta=(ClampMin="0.0"))
float FoundationStiffnessPerSecondSquared = 28.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Simulation")
bool bEnableBreathing = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Simulation", meta=(ClampMin="0.0", ClampMax="30.0"))
float BreathingStrengthMetersPerSecondSquared = 4.8f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Imprint")
bool bEnableImprint = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Imprint", meta=(ClampMin="0.0", ClampMax="1.0"))
float ImprintCaptureMetersPerSecond = 0.15f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Imprint", meta=(ClampMin="0.1", ClampMax="60.0"))
float ImprintRecoverySeconds = 6.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Imprint", meta=(ClampMin="0.0", ClampMax="1.0"))
float ImprintMaxDepthMeters = 0.34f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Living Plane|Object")
TArray<FVFLivingPlaneObjectInput> ObjectInputs;
private:
void CreateFieldTargets();
void EnqueueSimulationSteps(int32 NumSteps);
void UpdateMaterialField();
float GetStableStepSeconds() const;
UPROPERTY(Transient)
TObjectPtr<UTextureRenderTarget2D> FieldTargets[2];
UPROPERTY(Transient)
TObjectPtr<UMaterialInstanceDynamic> DynamicPlaneMaterial;
int32 CurrentFieldIndex = 0;
int64 SimulationStepCount = 0;
double SimulationAccumulatorSeconds = 0.0;
double FixedStepSeconds = 0.0;
};
@@ -0,0 +1,28 @@
using UnrealBuildTool;
public class VoxelForgeLivingPlane : ModuleRules
{
public VoxelForgeLivingPlane(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
if (Target.Platform == UnrealTargetPlatform.Linux)
{
bUseUnity = false;
}
PublicDependencyModuleNames.AddRange(new string[]
{
"Core",
"CoreUObject",
"Engine"
});
PrivateDependencyModuleNames.AddRange(new string[]
{
"Projects",
"RenderCore",
"RHI"
});
}
}
@@ -119,48 +119,6 @@ namespace VoxelForgeCore::PassageSpline
return std::lerp(plannedFloor,receivingFloor,blend);
}
inline void BlendEndpointFloorToRoute(std::span<const FPoint> controls,
std::vector<double>& floorProfile,std::size_t endpoint,
std::span<const std::array<double,3>> receivingRoute,double unitsPerMetre,
double playerCenterAboveFloorMetres=1.13,double maximumGradeDegrees=12.0)
{
if(controls.size()!=floorProfile.size()||endpoint>=floorProfile.size()
||receivingRoute.empty()||!(unitsPerMetre>0.0)
||!(maximumGradeDegrees>0.0&&maximumGradeDegrees<45.0))return;
const double maximumGrade=std::tan(maximumGradeDegrees
*3.14159265358979323846/180.0);
const double routeReach=controls[endpoint][3]/unitsPerMetre+0.5;
constexpr double MouthProfileBlendDistanceMetres=10.0;
double routeHeight=0.0,routeDistanceSquared=0.0;
if(!ClosestRouteHeightAtXY(receivingRoute,controls[endpoint][0],
controls[endpoint][1],routeHeight,routeDistanceSquared)
||routeDistanceSquared>std::pow(routeReach*unitsPerMetre,2.0))return;
floorProfile[endpoint]=routeHeight
-playerCenterAboveFloorMetres*unitsPerMetre;
double pathDistance=0.0;
for(std::size_t step=1;step<controls.size();++step)
{
if(endpoint>0&&step>endpoint)break;
const std::size_t index=endpoint==0?step:endpoint-step;
const std::size_t previous=endpoint==0?index-1:index+1;
const double dx=(controls[index][0]-controls[previous][0])/unitsPerMetre;
const double dy=(controls[index][1]-controls[previous][1])/unitsPerMetre;
const double horizontal=std::hypot(dx,dy);
pathDistance+=horizontal;
double localRouteHeight=0.0,localRouteDistanceSquared=0.0;
const bool followsRoute=pathDistance<=MouthProfileBlendDistanceMetres
&&ClosestRouteHeightAtXY(receivingRoute,
controls[index][0],controls[index][1],localRouteHeight,localRouteDistanceSquared)
&&localRouteDistanceSquared<=std::pow(routeReach*unitsPerMetre,2.0);
double target=floorProfile[index];
if(followsRoute)
target=localRouteHeight-playerCenterAboveFloorMetres*unitsPerMetre;
const double maximumStep=maximumGrade*horizontal*unitsPerMetre;
floorProfile[index]=std::clamp(target,
floorProfile[previous]-maximumStep,floorProfile[previous]+maximumStep);
}
}
inline std::vector<FSegment> BuildSegments(std::span<const FPoint> controls,
std::size_t spanCount,double spacingMetres,double unitsPerMetre=1.0,
std::span<const double> plannedFloorProfile={},
@@ -138,9 +138,6 @@ namespace VoxelForgeCore
bool passageComposerProfiled = false;
std::uint64_t passageTileFeatureCount = 0;
std::uint64_t passageTileRouteSegmentCandidates = 0;
std::uint64_t nativeCaveFieldSamples = 0;
std::uint64_t cavernRoomCandidates = 0;
std::uint64_t cavernEdgeCandidates = 0;
std::uint64_t resolvedBoundaryBandQueries = 0;
std::uint64_t passageComposerQueries = 0;
std::uint64_t passageIterations = 0;
@@ -499,20 +496,8 @@ namespace VoxelForgeCore
// continuous floor while relaxing the spline chord tolerance and bounding shell work.
// Version 226 unifies the passage influence reach in metres and converts it to core
// voxels for every broadphase and proof bound. Version 227 uses the exact smooth-max
// support width/6 when deriving that reach. Version 228 composes deterministic cave
// graphs from fixed passage mouths and the owner Tunnel Network settings. Version 229
// budgets cave floor support; 230 records a shared backbone floor profile and joint cap;
// 231 carries passage tangents and floor slopes through cave portal lead-ins and keeps
// floor backing local to the walk footprint, with depth measured along the floor normal;
// 233 bounds passage ring jitter to the authored placement disk; 234 aligns route mouth
// anchors with capsule foot height and carries support through the SurfaceWorld mouth;
// 235 plans the cave backbone as a sampled curve with both passage mouth tangents and
// preserves open cave lanes through passage shell overlaps; 236 binds passage mouths to
// the planned graph route, preserves its walk corridor through shell overlaps, and keeps
// boundary-blended host rock from widening the authored passage wall.
// v238 plans one resolved passage spline with explicit landing chambers.
// v239 plans their floor planes as the passage's continuous floor profile.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 239;
// support width/6 when deriving that reach.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 227;
enum class FieldChannel : std::uint32_t
{
@@ -907,8 +892,6 @@ namespace VoxelForgeCore
inline constexpr std::uint32_t ResolvedLayoutStampVocabularyVersionV2 = 2;
inline constexpr std::uint32_t ResolvedLayoutStampVocabularyVersionV3 = 3;
inline constexpr std::uint32_t ResolvedLayoutCavernGraphVocabularyVersionV1 = 1;
inline constexpr std::uint32_t ResolvedLayoutCavernGraphVocabularyVersionV2 = 2;
inline constexpr std::uint32_t ResolvedLayoutCavernGraphVocabularyVersionV3 = 3;
inline constexpr std::uint32_t ResolvedLayoutOreVeinVocabularyVersionV1 = 1;
enum class ResolvedLayoutValidationModeV3 : std::uint8_t { compatibility, strict };
@@ -970,18 +953,9 @@ namespace VoxelForgeCore
{
std::string stableId;
std::int32_t strateIndex = -1;
// 0 = floor-backed room; 1 = a true vertical cylindrical shaft. The
// shaft form is part of the shared cave graph so other recipes can reuse
// the same graph, indexing, interval and density machinery.
std::uint8_t shapeKind = 0;
std::array<std::int64_t, 3> centerMicrometres{};
std::array<std::int64_t, 3> halfExtentsMicrometres{};
std::int64_t floorMicrometres = 0;
// Optional shared backbone profile reference. The room floor plane is
// floorMicrometres plus this Q16 XY gradient from centerMicrometres.
std::string floorProfileStableId;
std::int64_t floorProfileDistanceMicrometres = -1;
std::array<std::int32_t, 2> floorGradientQ16{};
std::int64_t smoothWidthMicrometres = 0;
// Optional feature-to-feature union width. Zero preserves the historical
// behavior where smoothWidthMicrometres also controls the graph union.
@@ -989,11 +963,6 @@ namespace VoxelForgeCore
std::int64_t irregularityAmplitudeMicrometres = 0;
std::int64_t irregularityWavelengthMicrometres = 0;
std::uint64_t irregularitySeed = 0;
// Used only by shapeKind=1. floorMicrometres is the shaft top; the
// bottom is center.z - halfExtents.z. Ledges face one cardinal side.
std::int64_t ledgeSpacingMicrometres = 0;
std::int64_t ledgeDepthMicrometres = 0;
std::uint8_t ledgeSide = 0;
std::array<std::int64_t, 3> boundsMinimumMicrometres{};
std::array<std::int64_t, 3> boundsMaximumMicrometres{};
};
@@ -1006,11 +975,6 @@ namespace VoxelForgeCore
std::int32_t strateIndex = -1;
// A single cubic Bezier in XY. Its four Z values are the cubic floor profile.
std::array<std::array<std::int64_t, 3>, 4> controlPointsMicrometres{};
// Edges with the same profile ID are adjacent pieces of one shared h(s).
// Distances are signed along that profile, so a terminal edge may be reversed.
std::string floorProfileStableId;
std::int64_t floorProfileStartDistanceMicrometres = -1;
std::int64_t floorProfileEndDistanceMicrometres = -1;
// Resolve-time, error-bounded approximation of the cubic centerline. Each
// consecutive pair is a physical segment used by the native cave field.
std::vector<std::array<std::int64_t, 3>> polylineMicrometres;
@@ -1027,43 +991,6 @@ namespace VoxelForgeCore
std::array<std::int64_t, 3> boundsMaximumMicrometres{};
};
// Inputs to the reusable, plan-time cave graph composer. All distances are
// integer micrometres and unit-interval values are Q16 so the resolved graph
// does not depend on worker count or floating-point random distributions.
struct ResolvedCavernPlannerSettingsV1
{
std::int64_t roomSpacingMicrometres = 16000000;
std::int64_t minimumRoomRadiusMicrometres = 2000000;
std::int64_t maximumRoomRadiusMicrometres = 5000000;
std::int64_t destinationRadiusMicrometres = 6000000;
// Solid floor backing below the planned edge floor, preserved after graph
// unions and passage composition. This is separate from bore height.
std::int64_t floorSupportDepthMicrometres = 750000;
std::int64_t minimumTunnelRadiusMicrometres = 750000;
std::int64_t maximumTunnelRadiusMicrometres = 1000000;
std::int64_t maximumTunnelLengthMicrometres = 45000000;
std::int64_t tunnelWarpMicrometres = 0;
std::int64_t caveWarpMicrometres = 0;
std::int64_t smoothWidthMicrometres = 500000;
std::int64_t irregularityAmplitudeMicrometres = 0;
std::int64_t irregularityWavelengthMicrometres = 0;
std::int32_t roomDensityQ16 = 22938;
std::int32_t tunnelDensityQ16 = 26214;
std::int32_t roomShapeVarietyQ16 = 32768;
std::int32_t roomHeightRatioQ16 = 55706;
std::int32_t roomFloorCutMinimumQ16 = 45875;
std::int32_t roomFloorCutMaximumQ16 = 58982;
std::int32_t tunnelHorizontalBiasQ16 = 32768;
std::int32_t originRoomMaximumConnections = 4;
bool tunnelsFlowTowardOrigin = true;
// Vertical Shafts uses this same planner and graph field. It binds its
// incoming passage and resolves a bedrock terminal when no departure
// mouth exists, then adds shaft records beside the walk-only backbone.
bool verticalShaftMode = false;
std::int64_t ledgeSpacingMicrometres = 8000000;
std::int64_t ledgeDepthMicrometres = 1000000;
};
// Immutable material-only deposits. The capsule and its conservative bounds are in
// micrometres; bounds include irregularity and the blend envelope.
struct ResolvedLayoutOreVeinRequestV1
@@ -1168,8 +1095,7 @@ namespace VoxelForgeCore
inline bool IsNativeCaveFieldStratum(const ResolvedLayoutStratumV2& stratum) noexcept
{
return (stratum.generatorKind=="Caves"||stratum.generatorKind=="TunnelNetwork"
||stratum.generatorKind=="VerticalShafts")
return stratum.generatorKind=="Caves"
&&stratum.recipeId=="Core.Caves.PrimitiveField"
&&stratum.recipeVersion==1;
}
@@ -1210,16 +1136,6 @@ namespace VoxelForgeCore
std::int64_t radiusSubvoxels = 0;
};
struct ResolvedLayoutPassageLandingChamberV1
{
// The chamber floor plane passes through this point. Gradient is dz/dx,
// dz/dy in Q16 so the chamber continues the passage's authored h(s) grade.
std::array<std::int64_t, 3> floorCenterSubvoxels{};
std::array<std::int64_t, 2> floorGradientQ16{};
std::int64_t radiusSubvoxels = 0;
std::int64_t clearHeightSubvoxels = 0;
};
struct ResolvedLayoutPassageV1
{
std::string stableId;
@@ -1234,12 +1150,6 @@ namespace VoxelForgeCore
std::int64_t midRadiusSubvoxels = 0;
// Derived from the mouth binding; the main descent is monotone through this point.
std::size_t lowerMouthControlIndex = 0;
ResolvedLayoutPassageLandingChamberV1 upperLandingChamber;
ResolvedLayoutPassageLandingChamberV1 lowerLandingChamber;
// When true, each control point's position.z - radius is the planned
// floor h(s), and both chamber planes continue that same endpoint profile.
// False preserves older resolved snapshots' runtime floor composition.
bool floorProfileIncludesLandingChambers = false;
std::vector<ResolvedLayoutPassagePointV1> controlPoints;
};
@@ -1346,17 +1256,6 @@ namespace VoxelForgeCore
std::span<const ResolvedCavernRoomV1> rooms,
std::span<const ResolvedCavernEdgeV1> edges,
std::string& error);
// Build a deterministic, walkable room-and-tunnel graph between the two
// passage mouths that terminate in strateIndex. Compound rooms are emitted
// as overlapping room primitives; the route is planned below a 15 degree
// walking grade and every corridor carries a 4.5 m vertical clearance.
VFCORE_API bool PlanResolvedCavernNetworkV1(
const ResolvedLayoutSnapshotV3& layout, std::int32_t seed,
std::int32_t strateIndex,
const ResolvedCavernPlannerSettingsV1& settings,
std::vector<ResolvedCavernRoomV1>& rooms,
std::vector<ResolvedCavernEdgeV1>& edges,
std::string& error);
VFCORE_API bool ResolveResolvedLayoutOreVeinsV1(
ResolvedLayoutSnapshotV3& layout, std::int32_t seed,
std::span<const ResolvedLayoutOreVeinRequestV1> requests,
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,33 +0,0 @@
# Design49 — flat landing pad at tunnel ends (owner idea, reviewed 2026-11-02)
Owner: "the end of the tunnel should be flat; flatten the arrival with a fade-out that blends to the surrounding
density; a cheap stamp applied at arrival, no matter what's there."
A read-only design review (Claude Opus 5.5, medium effort) of `wip/l134-cave-planner` recommends a **clamp, not a
lerp**. Each tunnel end gets a level disc at the tunnel's end floor P. Out to a blend radius, the native ground is
squeezed between two gentle cones (12°) starting at P: a lower one that fills solid, an upper one that carves air.
Inside the disc the floor is exactly flat; outside it, the slope is never steeper than max(cone, native), with no
overhang or cliff. The full note is in the session transcript; key points:
- **Placement:** the last step of `ApplyResolvedStrateComposition`, after the passage composer, on both the native and
non-native branches. The fill is masked by the tube-only distance (bore stays open). It replaces the landing-chamber
box, shell and floor-shell special cases that caused L152–L156.
- **Formula** (metres; ×cos α for 1-Lipschitz). d = max(0, r−R), t = tan α.
- Fill: `Lo = P − t·d`, `F = max(z−Lo, (Lo−Ds)−z, r−(R+B))`.
- Air: `Hi = P + t·d`, `A = min(z−Hi, (Hi+H)−z, (R+B)−r)`.
- Result: `c = max(min(native, max(F, −tubeDist)), A)`.
- Hard min/max inside R; smooth-min width ramps 0 → 0.5 m over the first metre outside it.
- Why not lerp: native density saturates at about ±4.125 voxels (`DetailSupremum`), so a lerp makes cliffs and
films.
- **Parameters:** α = 12°, R = max(mouthRadius + 1 m, 3 m), B = min(8 m, |Δh_ring|/t + 1 m), H = 3 m, Ds = 1.25 m.
- **Planner:**
- P = h(end), with h′ = 0 over the last R.
- Sample the edge ring; move P into the feasible band or take the next deterministic site.
- Rewrite route heights inside R+B to the clamped ground.
- Content-band check including P−tB−Ds and P+tB+H.
- **Bounds:** the pad influence box goes into the proof bounds, the fallback overlap test, the **tile feature
bounds** (critical: the composer early-returns on an empty route list) and the proof-miss sampler.
- **Audits:** new `LandingPadAudit` (flatness ±2 cm, support, headroom, 36 radial blend transects ≤ 15° with one
crossing) plus negative controls (pad off, 2% tilt, B halved, bore mask removed).
- **Risks:** caves under pads (connectivity), low ceilings, shaft footprints, island edges and their air gap, liminal
decks; off-route edges on non-heightfield layers are a metric only.
@@ -1,26 +0,0 @@
# Linux134 — Tunnel Network cave planner
`TunnelNetwork` dispatches native `Core.Caves.PrimitiveField` v1. Seed 0 is strict-valid: 30 compound rooms, 72 room primitives, 31 edges, 3 branches, and a destination chamber. Its 27-point backbone spans 400.620 m horizontally with a 59.021 m floor change and an 8.381° maximum grade.
Design 4 gives backbone rooms and edges one continuous floor profile `h(s)`. Edge curves follow that profile; each room primitive is placed at its own profiled floor. Side branches keep independent flat floors. Overlap backing is capped at the lower floor. This removes the descending-joint capsule blockage. The incoming passage remains fully open: 21,425/21,425 samples.
The final-source fast tier passes in 370.8 s, including owner passage, shell, floor, ripple and negative-control audits. The default composed route audit passes: 0 blocked, 0 unsupported, 0 grade failures across 51,975 cave-route capsule samples; blocked-route controls detect their controls. The tile seam audit also passes (4 pairs, 4,900 shared samples, 0 mismatches).
Seed 2's cave route passes independently (0 blocked, 0 unsupported, 0 grade failures), but its full composed audit still fails at `passage/1-2/0`: 22 unsupported samples, first at `(15.153, 5.830, -754.680) m`. Seed 1's cave route has 24 blocked samples at the arrival mouth, beginning near `(8.380, -12.618, -864.420) m` on `passage/2-3/0`. Explicit seeds 0 and 3 produce no sweepable route candidates. The default seed is the only fully green composed audit among these runs.
Clang and GCC W1/W8/W12 match all 13 pipeline hash lines at the cave camera; each route audit passes. Seven legacy/planner cutaway pairs cover the arrival room, two backbone rooms, two tunnels, destination chamber, and departure room. All planner views render; several legacy cutaways show sparse geometry. Review them in `Saved/Linux/l134/captures/COMPARE.html`.
L80 timing used five interleaved samples per binary at W8/W12. Values below are the planner median change versus `assembler/world`; each cell is whole-view ready / LOD0–2 ready.
| Strate | W8 | W12 |
|---|---:|---:|
| 0 | -0.70% / +1.52% | +0.97% / +3.50% |
| 1 | +3.81% / +8.38% | +2.41% / +6.19% |
| 2 | +3.38% / +12.90% | +3.98% / +10.26% |
| 3 | +7.97% / +13.54% | +1.93% / +7.67% |
The VFHost Linux Development build succeeds with `-NoUBA -MaxParallelActions=4`. Final Clang/GCC source stamp: `f3b69ea0ce186c855643702a88e0d0732c81c18ec93c17d1824c25210e6408a3`. Canonical owner hashes are pinned at v230.
Logs and timing data are under `Saved/Linux/l134`; the timing summary is `timing/v230-summary.json`, the final fast log is `verify-fast-final-source.log`, and the host build log is `ubt.log`.
The separate legacy `--audit-native-caves` signature check still fails its mouth offset (it expects 1.00 m; the route contract is 1.13 m) and ripple span (1.8878 m against its 1.25 m cap). Its center-air, floor-solid, and shell probes pass; the composed owner route audit above is green.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

@@ -1 +0,0 @@
{"schema_version":3,"world_identity":"owner-world/seed/0","owner_voxel_size_um":125000,"core_voxel_size_um":250000,"strate_layout_chunk_size_um":8000000,"strate_layout_chunk_width_subvoxels":8192,"strates":[{"stable_id":"owner-world/seed/0/strate/0/generator/SurfaceWorld","order":0,"strate_index":0,"generator_kind":"SurfaceWorld","recipe_id":"SurfaceWorld.Heightfield2D","recipe_version":2,"interior_bottom_um":-504000000,"interior_top_um":8000000,"voxel_size_um":250000,"lattice_origin_um":[0,0,0],"ceiling":{"kind":"ceiling","bottom_um":7500000,"top_um":8000000,"present":true,"diggable":true,"protected":false,"solid_density_q16":524288,"behaviour":"solid ceiling from strate BoundarySealThickness; breakable by default","density_side":"interior-facing lower surface","cap_path":"shared resolved-layout density band"},"content":{"kind":"content","bottom_um":-503500000,"top_um":7500000,"present":true,"diggable":true,"protected":false,"solid_density_q16":65536,"behaviour":"resolved generator interior","density_side":"none","cap_path":"none"},"bedrock":{"kind":"bedrock","bottom_um":-504000000,"top_um":-503500000,"present":true,"diggable":true,"protected":false,"solid_density_q16":524288,"behaviour":"solid bedrock floor from strate BoundarySealThickness; breakable by default","density_side":"interior-facing upper surface","cap_path":"shared resolved-layout density band"},"transition_mode":"Gradient","transition_blend_chunks":1,"transition_width_um":8000000,"transition_warp_amplitude_um":0,"transition_interpenetration_um":2000000,"transition_honoured_in_core":true,"transition_falls_back_to_hard":false,"transition_dispatch_path":"shared composition moves both band faces together with the smooth declared-width transition field","bound_dispatch_path":"BuildSurfaceStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV3","query_dispatch_path":"NativeSurfaceDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV3","manager_lookup":"UVoxelStrateManager::GetGeneratorTypeForChunk; transition is controlled by upper strate","manager_chunk_width_um":8000000,"dispatch_chunk_width_um":8000000,"anchors":[{"kind":"cap_profile","stable_id":"biome/4097","units":"1/256 Core voxel","values":[-18022,0,64000,1536,0]},{"kind":"route_point","stable_id":"route/0","units":"1/256 Core voxel","values":[8192,24576,-381223,1024]},{"kind":"route_point","stable_id":"route/1","units":"1/256 Core voxel","values":[8192,24320,-381254,1024]},{"kind":"route_point","stable_id":"route/2","units":"1/256 Core voxel","values":[8192,24064,-381284,1024]},{"kind":"route_point","stable_id":"route/3","units":"1/256 Core voxel","values":[8192,23808,-381302,1024]},{"kind":"route_point","stable_id":"route/4","units":"1/256 Core voxel","values":[8192,23552,-381304,1024]},{"kind":"route_point","stable_id":"route/5","units":"1/256 Core voxel","values":[8192,23296,-381291,1024]},{"kind":"route_point","stable_id":"route/6","units":"1/256 Core voxel","values":[8192,23040,-381270,1024]},{"kind":"route_point","stable_id":"route/7","units":"1/256 Core voxel","values":[8192,22784,-381242,1024]},{"kind":"route_point","stable_id":"route/8","units":"1/256 Core voxel","values":[8192,22528,-381218,1024]},{"kind":"route_point","stable_id":"route/9","units":"1/256 Core voxel","values":[8192,22272,-381192,1024]},{"kind":"route_point","stable_id":"route/10","units":"1/256 Core voxel","values":[8192,22016,-381161,1024]},{"kind":"route_point","stable_id":"route/11","units":"1/256 Core voxel","values":[8192,21760,-381118,1024]},{"kind":"route_point","stable_id":"route/12","units":"1/256 Core voxel","values":[8192,21504,-381122,1024]},{"kind":"route_point","stable_id":"route/13","units":"1/256 Core voxel","values":[8192,21248,-381155,1024]},{"kind":"route_point","stable_id":"route/14","units":"1/256 Core voxel","values":[8192,20992,-381183,1024]},{"kind":"route_point","stable_id":"route/15","units":"1/256 Core voxel","values":[8192,20736,-381207,1024]},{"kind":"route_point","stable_id":"route/16","units":"1/256 Core voxel","values":[8192,20480,-381219,1024]},{"kind":"route_point","stable_id":"route/17","units":"1/256 Core voxel","values":[8192,20224,-381220,1024]},{"kind":"route_point","stable_id":"route/18","units":"1/256 Core voxel","values":[8192,19968,-381202,1024]},{"kind":"route_point","stable_id":"route/19","units":"1/256 Core voxel","values":[8192,19712,-381167,1024]},{"kind":"route_point","stable_id":"route/20","units":"1/256 Core voxel","values":[8192,19456,-381130,1024]},{"kind":"route_point","stable_id":"route/21","units":"1/256 Core voxel","values":[8192,19200,-381101,1024]},{"kind":"route_point","stable_id":"route/22","units":"1/256 Core voxel","values":[8192,18944,-381072,1024]},{"kind":"route_point","stable_id":"route/23","units":"1/256 Core voxel","values":[8192,18688,-381092,1024]},{"kind":"route_point","stable_id":"route/24","units":"1/256 Core voxel","values":[8192,18432,-381149,1024]},{"kind":"route_point","stable_id"Line truncated
@@ -1 +0,0 @@
{"schema_version":3,"world_identity":"owner-world/seed/0","owner_voxel_size_um":125000,"core_voxel_size_um":250000,"strate_layout_chunk_size_um":8000000,"strate_layout_chunk_width_subvoxels":8192,"strates":[{"stable_id":"owner-world/seed/0/strate/0/generator/SurfaceWorld","order":0,"strate_index":0,"generator_kind":"SurfaceWorld","recipe_id":"SurfaceWorld.Heightfield2D","recipe_version":2,"interior_bottom_um":-504000000,"interior_top_um":8000000,"voxel_size_um":250000,"lattice_origin_um":[0,0,0],"ceiling":{"kind":"ceiling","bottom_um":7500000,"top_um":8000000,"present":true,"diggable":true,"protected":false,"solid_density_q16":524288,"behaviour":"solid ceiling from strate BoundarySealThickness; breakable by default","density_side":"interior-facing lower surface","cap_path":"shared resolved-layout density band"},"content":{"kind":"content","bottom_um":-503500000,"top_um":7500000,"present":true,"diggable":true,"protected":false,"solid_density_q16":65536,"behaviour":"resolved generator interior","density_side":"none","cap_path":"none"},"bedrock":{"kind":"bedrock","bottom_um":-504000000,"top_um":-503500000,"present":true,"diggable":true,"protected":false,"solid_density_q16":524288,"behaviour":"solid bedrock floor from strate BoundarySealThickness; breakable by default","density_side":"interior-facing upper surface","cap_path":"shared resolved-layout density band"},"transition_mode":"Gradient","transition_blend_chunks":1,"transition_width_um":8000000,"transition_warp_amplitude_um":0,"transition_interpenetration_um":2000000,"transition_honoured_in_core":true,"transition_falls_back_to_hard":false,"transition_dispatch_path":"shared composition moves both band faces together with the smooth declared-width transition field","bound_dispatch_path":"BuildSurfaceStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV3","query_dispatch_path":"NativeSurfaceDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV3","manager_lookup":"UVoxelStrateManager::GetGeneratorTypeForChunk; transition is controlled by upper strate","manager_chunk_width_um":8000000,"dispatch_chunk_width_um":8000000,"anchors":[{"kind":"cap_profile","stable_id":"biome/4097","units":"1/256 Core voxel","values":[-18022,0,64000,1536,0]},{"kind":"route_point","stable_id":"route/0","units":"1/256 Core voxel","values":[8192,24576,-381223,1024]},{"kind":"route_point","stable_id":"route/1","units":"1/256 Core voxel","values":[8192,24320,-381254,1024]},{"kind":"route_point","stable_id":"route/2","units":"1/256 Core voxel","values":[8192,24064,-381284,1024]},{"kind":"route_point","stable_id":"route/3","units":"1/256 Core voxel","values":[8192,23808,-381302,1024]},{"kind":"route_point","stable_id":"route/4","units":"1/256 Core voxel","values":[8192,23552,-381304,1024]},{"kind":"route_point","stable_id":"route/5","units":"1/256 Core voxel","values":[8192,23296,-381291,1024]},{"kind":"route_point","stable_id":"route/6","units":"1/256 Core voxel","values":[8192,23040,-381270,1024]},{"kind":"route_point","stable_id":"route/7","units":"1/256 Core voxel","values":[8192,22784,-381242,1024]},{"kind":"route_point","stable_id":"route/8","units":"1/256 Core voxel","values":[8192,22528,-381218,1024]},{"kind":"route_point","stable_id":"route/9","units":"1/256 Core voxel","values":[8192,22272,-381192,1024]},{"kind":"route_point","stable_id":"route/10","units":"1/256 Core voxel","values":[8192,22016,-381161,1024]},{"kind":"route_point","stable_id":"route/11","units":"1/256 Core voxel","values":[8192,21760,-381118,1024]},{"kind":"route_point","stable_id":"route/12","units":"1/256 Core voxel","values":[8192,21504,-381122,1024]},{"kind":"route_point","stable_id":"route/13","units":"1/256 Core voxel","values":[8192,21248,-381155,1024]},{"kind":"route_point","stable_id":"route/14","units":"1/256 Core voxel","values":[8192,20992,-381183,1024]},{"kind":"route_point","stable_id":"route/15","units":"1/256 Core voxel","values":[8192,20736,-381207,1024]},{"kind":"route_point","stable_id":"route/16","units":"1/256 Core voxel","values":[8192,20480,-381219,1024]},{"kind":"route_point","stable_id":"route/17","units":"1/256 Core voxel","values":[8192,20224,-381220,1024]},{"kind":"route_point","stable_id":"route/18","units":"1/256 Core voxel","values":[8192,19968,-381202,1024]},{"kind":"route_point","stable_id":"route/19","units":"1/256 Core voxel","values":[8192,19712,-381167,1024]},{"kind":"route_point","stable_id":"route/20","units":"1/256 Core voxel","values":[8192,19456,-381130,1024]},{"kind":"route_point","stable_id":"route/21","units":"1/256 Core voxel","values":[8192,19200,-381101,1024]},{"kind":"route_point","stable_id":"route/22","units":"1/256 Core voxel","values":[8192,18944,-381072,1024]},{"kind":"route_point","stable_id":"route/23","units":"1/256 Core voxel","values":[8192,18688,-381092,1024]},{"kind":"route_point","stable_id":"route/24","units":"1/256 Core voxel","values":[8192,18432,-381149,1024]},{"kind":"route_point","stable_id"Line truncated
@@ -1 +0,0 @@
{"schema_version":3,"world_identity":"owner-world/seed/0","owner_voxel_size_um":125000,"core_voxel_size_um":250000,"strate_layout_chunk_size_um":8000000,"strate_layout_chunk_width_subvoxels":8192,"strates":[{"stable_id":"owner-world/seed/0/strate/0/generator/SurfaceWorld","order":0,"strate_index":0,"generator_kind":"SurfaceWorld","recipe_id":"SurfaceWorld.Heightfield2D","recipe_version":2,"interior_bottom_um":-504000000,"interior_top_um":8000000,"voxel_size_um":250000,"lattice_origin_um":[0,0,0],"ceiling":{"kind":"ceiling","bottom_um":7500000,"top_um":8000000,"present":true,"diggable":true,"protected":false,"solid_density_q16":524288,"behaviour":"solid ceiling from strate BoundarySealThickness; breakable by default","density_side":"interior-facing lower surface","cap_path":"shared resolved-layout density band"},"content":{"kind":"content","bottom_um":-503500000,"top_um":7500000,"present":true,"diggable":true,"protected":false,"solid_density_q16":65536,"behaviour":"resolved generator interior","density_side":"none","cap_path":"none"},"bedrock":{"kind":"bedrock","bottom_um":-504000000,"top_um":-503500000,"present":true,"diggable":true,"protected":false,"solid_density_q16":524288,"behaviour":"solid bedrock floor from strate BoundarySealThickness; breakable by default","density_side":"interior-facing upper surface","cap_path":"shared resolved-layout density band"},"transition_mode":"Gradient","transition_blend_chunks":1,"transition_width_um":8000000,"transition_warp_amplitude_um":0,"transition_interpenetration_um":2000000,"transition_honoured_in_core":true,"transition_falls_back_to_hard":false,"transition_dispatch_path":"shared composition moves both band faces together with the smooth declared-width transition field","bound_dispatch_path":"BuildSurfaceStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV3","query_dispatch_path":"NativeSurfaceDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV3","manager_lookup":"UVoxelStrateManager::GetGeneratorTypeForChunk; transition is controlled by upper strate","manager_chunk_width_um":8000000,"dispatch_chunk_width_um":8000000,"anchors":[{"kind":"cap_profile","stable_id":"biome/4097","units":"1/256 Core voxel","values":[-18022,0,64000,1536,0]},{"kind":"route_point","stable_id":"route/0","units":"1/256 Core voxel","values":[8192,24576,-381223,1024]},{"kind":"route_point","stable_id":"route/1","units":"1/256 Core voxel","values":[8192,24320,-381254,1024]},{"kind":"route_point","stable_id":"route/2","units":"1/256 Core voxel","values":[8192,24064,-381284,1024]},{"kind":"route_point","stable_id":"route/3","units":"1/256 Core voxel","values":[8192,23808,-381302,1024]},{"kind":"route_point","stable_id":"route/4","units":"1/256 Core voxel","values":[8192,23552,-381304,1024]},{"kind":"route_point","stable_id":"route/5","units":"1/256 Core voxel","values":[8192,23296,-381291,1024]},{"kind":"route_point","stable_id":"route/6","units":"1/256 Core voxel","values":[8192,23040,-381270,1024]},{"kind":"route_point","stable_id":"route/7","units":"1/256 Core voxel","values":[8192,22784,-381242,1024]},{"kind":"route_point","stable_id":"route/8","units":"1/256 Core voxel","values":[8192,22528,-381218,1024]},{"kind":"route_point","stable_id":"route/9","units":"1/256 Core voxel","values":[8192,22272,-381192,1024]},{"kind":"route_point","stable_id":"route/10","units":"1/256 Core voxel","values":[8192,22016,-381161,1024]},{"kind":"route_point","stable_id":"route/11","units":"1/256 Core voxel","values":[8192,21760,-381118,1024]},{"kind":"route_point","stable_id":"route/12","units":"1/256 Core voxel","values":[8192,21504,-381122,1024]},{"kind":"route_point","stable_id":"route/13","units":"1/256 Core voxel","values":[8192,21248,-381155,1024]},{"kind":"route_point","stable_id":"route/14","units":"1/256 Core voxel","values":[8192,20992,-381183,1024]},{"kind":"route_point","stable_id":"route/15","units":"1/256 Core voxel","values":[8192,20736,-381207,1024]},{"kind":"route_point","stable_id":"route/16","units":"1/256 Core voxel","values":[8192,20480,-381219,1024]},{"kind":"route_point","stable_id":"route/17","units":"1/256 Core voxel","values":[8192,20224,-381220,1024]},{"kind":"route_point","stable_id":"route/18","units":"1/256 Core voxel","values":[8192,19968,-381202,1024]},{"kind":"route_point","stable_id":"route/19","units":"1/256 Core voxel","values":[8192,19712,-381167,1024]},{"kind":"route_point","stable_id":"route/20","units":"1/256 Core voxel","values":[8192,19456,-381130,1024]},{"kind":"route_point","stable_id":"route/21","units":"1/256 Core voxel","values":[8192,19200,-381101,1024]},{"kind":"route_point","stable_id":"route/22","units":"1/256 Core voxel","values":[8192,18944,-381072,1024]},{"kind":"route_point","stable_id":"route/23","units":"1/256 Core voxel","values":[8192,18688,-381092,1024]},{"kind":"route_point","stable_id":"route/24","units":"1/256 Core voxel","values":[8192,18432,-381149,1024]},{"kind":"route_point","stable_id"Line truncated
@@ -1,32 +0,0 @@
# Linux135 — Tunnel Network planner
Source v236 (`8dc4294ce0250a591ee4515471c3c547e796ffa4346ab44f0ae1740bbc3797f5`) on `wip/l134-cave-planner`.
## Route audits
Seeds 0–15 pass the composed passage, seam, shell, naturalness, mouth-profile, ripple, and blocked-route controls (16/16). The negative control still detects all three blocked routes. No audit threshold changed.
The mouth joint now takes its floor/profile from the resolved mouth geometry and carries that shared profile into the planner's first and last edges. This fixes seed 1's blocked arrival and seed 2's unsupported arrival. For seeds 0 and 3, the first 648 regular route candidates exceeded the grade bound; the bounded deterministic fallback finds a route. “No sweepable route candidates” was a planner search miss, not an empty cave.
## Cost
L80 medians are near-ready / whole-view percent deltas. The serialized 144-run matrix started at load 0.81 / 98.4% CPU idle. Each cell gives `assembler/world` first, then exact L134 (`a3c8e36`).
| Layer | W8 | W12 |
|---|---:|---:|
| 0 | +3.88 / +0.27%; +1.79 / -0.21% | +8.22 / +4.09%; +3.89 / +2.49% |
| 1 | +8.82 / +4.96%; +4.14 / +1.71% | +11.83 / +5.35%; +4.10 / +2.09% |
| 2 | +13.33 / +3.77%; +2.34 / -0.09% | +12.56 / +5.20%; +1.40 / +0.61% |
| 3 | +13.65 / +3.99%; -0.25 / +0.44% | +12.71 / +5.14%; +2.97 / +2.12% |
The two speed changes were bounded cave AABBs with a 1 mm float guard, and normalized edge-BVH bounds with one normalization per sample. This improves on L134, but misses the `assembler/world` target: near-ready remains 3.88–13.65% slower. Layers 1–3 overlap the native cave volume and spend time on roughly 4.95–5.76 million near-LOD cave samples per view; layer 0 has none at LOD0–3 and is still up 3.88% at W8, showing some generic composer/classification cost as well.
Planning is about 3.75–4.19 ms per view (cavern planning 0.46–0.49 ms). At LOD0–3, room/edge candidates average 0.39/0.23 per composer tile on layer 1, 0.47/0.27 on layer 2, and 0.06/0.04 on layer 3. Tile proofs skip work at LOD0–3; measured cave views have no tile skips at LOD4–8. The reported 180–320 ns density-call estimate includes all shape fields, not cave-only time. Profile: `Saved/Linux/l135/profile-summary-speed2.json`.
## Gates and pictures
Fast tier passes in 301.7 s. Clang and GCC each match 13 hash lines at W1/W8/W12. Route seams and the negative controls pass; canonical baselines are v236. The post-timing VFHost Linux Development build succeeds: 27/27 actions, 77.70 s, using `-NoUBA -MaxParallelActions=4`.
The seven-view gallery has four planner views at the planned floor plus 1.6 m and three legacy views at legacy coordinates. Open `captures/COMPARE.html`; camera coordinates and renderer settings are in `captures/capture-index.json`.
Sweep: `Saved/Linux/l135/optimized-seed-sweep.json`. Timing: `Saved/Linux/l135/timing/summary.json`. Determinism: `Saved/Linux/l135/determinism-summary.json`. Host build log: `Saved/Linux/l135/ubt-l135-console.log`.
@@ -1,171 +0,0 @@
#!/usr/bin/env python3
"""Capture eye-height planner interiors and legacy interiors at legacy coordinates."""
from __future__ import annotations
import json
import math
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Standalone/Research/WorldAssemblerM3/Linux135/captures"
SAVED = ROOT / "Saved/Linux/l135"
DATA = ROOT / "Standalone/data/owner_world.json"
LAYOUT = SAVED / "capture-default-layout.json"
HEADLESS = SAVED / "bin/VoxelForgeCoreHeadless-clang-l135"
RENDERER = SAVED / "bin/VoxelForgeOffscreenCapture-clang-l135"
STAMP = "8dc4294ce0250a591ee4515471c3c547e796ffa4346ab44f0ae1740bbc3797f5"
EYE_METRES = 1.6
def run(command: list[str], log_path: Path) -> None:
wrapped = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", *command]
with log_path.open("w", encoding="utf-8") as log:
result = subprocess.run(wrapped, cwd=ROOT, stdout=log,
stderr=subprocess.STDOUT, timeout=1740,
check=False)
if result.returncode:
raise SystemExit(f"command failed ({result.returncode}): {log_path}")
def xyz(value: list[int] | list[float]) -> tuple[float, float, float]:
return tuple(component / 1_000_000.0 for component in value) # type: ignore[return-value]
def yaw_to(dx: float, dy: float) -> float:
# The renderer's yaw zero points along +Y (Forward = sin(yaw), cos(yaw), 0).
return math.degrees(math.atan2(dx, dy))
def camera_arg(camera: tuple[float, float, float], yaw: float) -> str:
return ",".join(f"{part:.9f}" for part in (*camera, yaw, 0.0))
def make_view(name: str, recipe: str, camera: tuple[float, float, float],
yaw: float) -> dict[str, object]:
OUT.mkdir(parents=True, exist_ok=True)
mesh = SAVED / f"capture-{name}.vfmesh"
image = OUT / f"{name}.png"
mesh_log = SAVED / f"capture-{name}-mesh.log"
render_log = SAVED / f"capture-{name}-render.log"
command = [str(HEADLESS), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=8",
"--clip-radius=1", "--max-clip-level=0", "--max-level=0",
f"--camera={camera_arg(camera, yaw)}", f"--mesh-export={mesh}",
"--capture-skip-walkability", "--force-generate",
"--render-distance-chunks=0"]
# The checked-in fixture is already seed 0. Keeping its Unreal-resolved owner
# plan avoids rebuilding the broad SurfaceWorld spawn search for each camera.
if recipe == "legacy-tunnel-network":
command.append("--legacy-tunnel-network")
else:
command.append("--recipe=surface-world")
run(command, mesh_log)
render_command = [str(RENDERER), str(mesh), str(image), "--size=1600x900",
"--shade=readable", "--height-tint=on", "--headlamp=off"]
run(render_command, render_log)
mesh_output = mesh_log.read_text(encoding="utf-8", errors="replace")
render_output = render_log.read_text(encoding="utf-8", errors="replace")
if STAMP not in mesh_output or STAMP not in render_output:
raise SystemExit(f"source stamp mismatch for {name}")
if "status=PASS" not in render_output:
raise SystemExit(f"render failed for {name}")
return {"name": name, "recipe": recipe, "camera_m": list(camera),
"yaw_deg": yaw,
"camera_height_basis": "floor + player eye offset" if recipe == "surface-world"
else ("legacy room floor + player eye offset" if name.endswith("room")
else "near the legacy tunnel centerline"),
"eye_offset_m": EYE_METRES
if recipe == "surface-world" or name.endswith("room") else None,
"mesh": str(mesh.relative_to(ROOT)), "image": str(image.relative_to(ROOT)),
"mesh_log": str(mesh_log.relative_to(ROOT)),
"render_log": str(render_log.relative_to(ROOT))}
def main() -> int:
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
rooms = {room["stable_id"]: room for room in layout["cavern_rooms"]}
edges = {edge["stable_id"]: edge for edge in layout["cavern_edges"]}
views: list[dict[str, object]] = []
arrival = rooms["tunnel-network/strate-2/room-0/primitive-0"]
room1 = rooms["tunnel-network/strate-2/room-1/primitive-0"]
arrival_center = xyz(arrival["center_um"])
arrival_floor = arrival["floor_um"] / 1_000_000.0
views.append(make_view("planner-arrival-room", "surface-world",
(arrival_center[0], arrival_center[1], arrival_floor + EYE_METRES),
yaw_to(room1["center_um"][0] - arrival["center_um"][0],
room1["center_um"][1] - arrival["center_um"][1])))
tunnel = edges["tunnel-network/strate-2/route-edge-1"]["polyline_um"]
tunnel_start, tunnel_end = xyz(tunnel[0]), xyz(tunnel[-1])
tunnel_floor = tunnel[1][2] / 1_000_000.0
views.append(make_view("planner-tunnel", "surface-world",
((tunnel_start[0] + tunnel_end[0]) * 0.5,
(tunnel_start[1] + tunnel_end[1]) * 0.5,
tunnel_floor + EYE_METRES),
yaw_to(tunnel_end[0] - tunnel_start[0], tunnel_end[1] - tunnel_start[1])))
compound = rooms["tunnel-network/strate-2/room-19/primitive-0"]
compound_center = xyz(compound["center_um"])
compound_next = rooms["tunnel-network/strate-2/room-20/primitive-0"]
views.append(make_view("planner-compound-room", "surface-world",
(compound_center[0], compound_center[1],
compound["floor_um"] / 1_000_000.0 + EYE_METRES),
yaw_to(compound_next["center_um"][0] - compound["center_um"][0],
compound_next["center_um"][1] - compound["center_um"][1])))
destination = rooms["tunnel-network/strate-2/room-33/primitive-0"]
destination_center = xyz(destination["center_um"])
upstream = rooms["tunnel-network/strate-2/room-32/primitive-0"]
views.append(make_view("planner-destination-chamber", "surface-world",
(destination_center[0], destination_center[1],
destination["floor_um"] / 1_000_000.0 + EYE_METRES),
yaw_to(upstream["center_um"][0] - destination["center_um"][0],
upstream["center_um"][1] - destination["center_um"][1])))
# The compiled legacy network has a deterministic origin chamber at (0, 0).
# Its room floor is hash-rolled from the owner fixture; these are legacy world
# coordinates, independent of the native planner's passage route.
legacy_origin_floor = -819.9169921875
legacy_origin_eye = legacy_origin_floor + EYE_METRES
legacy_neighbor = (39.327854, 5.115777, -797.724731)
views.append(make_view("legacy-origin-room", "legacy-tunnel-network",
(0.0, 0.0, legacy_origin_eye), yaw_to(legacy_neighbor[0], legacy_neighbor[1])))
# Hash-selected (cell 1,0) is the origin graph's nearest connected room. Its
# cut-plane floor estimate is -801.0 m before the authored local relief.
legacy_neighbor_floor = -800.9986572265625
legacy_neighbor_eye = legacy_neighbor_floor + EYE_METRES
views.append(make_view("legacy-connected-room", "legacy-tunnel-network",
(legacy_neighbor[0], legacy_neighbor[1], legacy_neighbor_eye),
yaw_to(-legacy_neighbor[0], -legacy_neighbor[1])))
legacy_tunnel_mid = (legacy_neighbor[0] * 0.5, legacy_neighbor[1] * 0.5,
(-812.0 + legacy_neighbor[2]) * 0.5)
views.append(make_view("legacy-origin-tunnel", "legacy-tunnel-network",
legacy_tunnel_mid, yaw_to(legacy_neighbor[0], legacy_neighbor[1])))
manifest = {"source_stamp": STAMP, "seed": 0,
"renderer": "readable, height tint on, headlamp off; 1600x900",
"views": views}
(OUT / "capture-index.json").write_text(
json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
cards = "\n".join(
f'<figure><a href="{Path(str(view["image"])).name}">'
f'<img src="{Path(str(view["image"])).name}" alt="{view["name"]}"></a>'
f'<figcaption>{view["name"]}</figcaption></figure>' for view in views)
(OUT / "COMPARE.html").write_text(
"<!doctype html><meta charset=\"utf-8\"><title>L135 interior views</title>\n"
"<style>body{font:16px sans-serif;background:#202329;color:#eee;margin:24px}"
"h1{font-size:22px}section{display:grid;grid-template-columns:repeat(auto-fit,minmax(420px,1fr));gap:18px}"
"figure{margin:0}img{width:100%;height:auto;display:block}figcaption{padding:6px 0}</style>\n"
"<h1>Planner and legacy interiors, seed 0</h1><section>\n"
+ cards + "\n</section>\n", encoding="utf-8")
print(f"[L135CaptureSummary] views={len(views)} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,79 +0,0 @@
#!/usr/bin/env python3
"""Check Clang/GCC cave-path pipeline hashes at 1, 8, and 12 workers."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l135"
DATA = ROOT / "Standalone/data/regression/owner_world_2strate_l61.json"
BINARIES = {
"clang": OUT / "bin/VoxelForgeCoreHeadless-clang-l135",
"gcc": OUT / "bin/VoxelForgeCoreHeadless-gcc-l135",
}
CAMERA = "-4.688214,38.662384,-505.781342,-28.446,0"
HASH_RE = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|MaterialHash|LODHash|ExactQueryHash)\].*$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing L135 determinism binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
rows = []
baseline: tuple[str, ...] | None = None
stamp: str | None = None
for compiler, binary in BINARIES.items():
for workers in (1, 8, 12):
label = f"determinism-{compiler}-w{workers}"
log = OUT / f"{label}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=0",
"--max-level=0", f"--camera={CAMERA}", "--stream-hash-tiles",
"--force-generate", "--recipe=surface-world", "--render-distance-chunks=0",
"--landmark-chamber-demo", "--ore-veins-demo"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
found_stamp = STAMP_RE.search(content)
hashes = tuple(HASH_RE.findall(content))
passed = result.returncode == 0 and found_stamp is not None and len(hashes) >= 4
if found_stamp is not None:
if stamp is None:
stamp = found_stamp.group(1)
passed &= stamp == found_stamp.group(1)
if baseline is None and passed:
baseline = hashes
elif baseline is not None:
passed &= hashes == baseline
row = {"compiler": compiler, "workers": workers,
"exit": result.returncode, "stamp": found_stamp.group(1)
if found_stamp else None,
"hash_lines": len(hashes), "hashes_match_first": hashes == baseline,
"passed": bool(passed), "elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
rows.append(row)
print("[L135DeterminismRun] " + json.dumps(row, sort_keys=True), flush=True)
if not passed:
(OUT / "determinism-summary.json").write_text(json.dumps(
{"status": "FAIL", "runs": rows}, indent=2) + "\n")
raise SystemExit(f"determinism mismatch; see {log}")
summary = {"status": "PASS", "stamp": stamp, "runs": rows}
(OUT / "determinism-summary.json").write_text(
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print(f"[L135DeterminismSummary] runs={len(rows)} stamp={stamp} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,115 +0,0 @@
#!/usr/bin/env python3
"""Collect final-stamp cave, candidate, proof, and startup counters by stratum."""
from __future__ import annotations
import json
import re
import subprocess
import time
from collections import defaultdict
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l135"
BIN = OUT / "bin/VoxelForgeCoreHeadless-clang-l135"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "8dc4294ce0250a591ee4515471c3c547e796ffa4346ab44f0ae1740bbc3797f5"
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
PLAN_RE = re.compile(r"^\[WorldAssemblerPlanTiming\] total_ms=([0-9.]+) status=([^ ]+)$", re.M)
CAVE_RE = re.compile(r"^\[CavernPlannerV1\].* plan_ms=([0-9.]+) status=([^ ]+)$", re.M)
TILE_RE = re.compile(r"^\[WorldAssemblerTilePipeline\] (.*)$", re.M)
CLASS_RE = re.compile(r"^\[WorldAssemblerLODClassification\] (.*)$", re.M)
COMPOSER_RE = re.compile(r"^\[PassageComposerTile\] (.*)$", re.M)
FIELDS_RE = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
def fields(line: str) -> dict[str, str]:
return dict(FIELDS_RE.findall(line))
def main() -> int:
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L135 profile binary or owner fixture")
rows = []
for strate, xyz in CAMERAS.items():
camera = ",".join(f"{value:.12f}" for value in xyz) + ",0,0"
log = OUT / f"profile-final-speed2-s{strate}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=8",
"--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--profile-passage-composer",
"--stream-scheduler-policy=3"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
found_stamp = STAMP_RE.search(content)
if result.returncode or found_stamp is None or found_stamp.group(1) != STAMP:
raise SystemExit(f"final-stamp profile failed: {log}, exit={result.returncode}")
plan, cave = PLAN_RE.search(content), CAVE_RE.search(content)
tile = TILE_RE.search(content)
if plan is None or cave is None or tile is None:
raise SystemExit(f"profile counters missing: {log}")
aggregate = defaultdict(lambda: defaultdict(int))
for match in CLASS_RE.finditer(content):
v = fields(match.group(1)); lod = int(v["lod"])
for key in ("tiles", "tile_skips", "density_point_calls", "field_eval_sample_points",
"proof_air_cells", "proof_solid_cells"):
aggregate[lod][key] = int(v.get(key, "0"))
aggregate[lod]["field_eval_ms_est"] = float(v.get("field_eval_ms_est", "0"))
for match in COMPOSER_RE.finditer(content):
v = fields(match.group(1)); lod = int(v["key"].split("lod", 1)[1].rstrip(")"))
aggregate[lod]["composer_tiles"] += 1
for key in ("samples", "native_cave_samples", "room_candidates", "edge_candidates",
"features", "route_candidates", "passage_iterations"):
aggregate[lod][key] += int(v.get(key, "0"))
aggregate[lod]["composer_worker_ms"] += float(v.get("worker_ms", "0"))
for lod, values in aggregate.items():
calls = values.get("density_point_calls", 0)
values["field_eval_ns_per_density_call_est"] = round(
values.get("field_eval_ms_est", 0.0) * 1.0e6 / calls, 1) if calls else None
composer_tiles = values.get("composer_tiles", 0)
values["room_candidates_per_composer_tile"] = round(
values.get("room_candidates", 0) / composer_tiles, 3) if composer_tiles else None
values["edge_candidates_per_composer_tile"] = round(
values.get("edge_candidates", 0) / composer_tiles, 3) if composer_tiles else None
tile_fields = fields(tile.group(1))
tile_summary = {}
for key, value in tile_fields.items():
try:
tile_summary[key] = int(value)
except ValueError:
try:
tile_summary[key] = float(value)
except ValueError:
continue
row = {"strate": strate, "source_stamp": found_stamp.group(1),
"world_assembler_plan_ms": float(plan.group(1)),
"cavern_planner_ms": float(cave.group(1)),
"tile_pipeline": tile_summary,
"lod": {str(k): dict(v) for k, v in sorted(aggregate.items())},
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
rows.append(row)
print("[L135ProfileRun] " + json.dumps(row, sort_keys=True), flush=True)
summary = {"status": "PASS", "source_stamp": STAMP, "strata": rows,
"field_eval_ns_per_density_call_note":
"Estimate includes all shape-field density calls at this view, not native-cave-exclusive time.",
"tile_skip_note":
"tile_pipeline.whole_tile_skips and lod.tile_skips are aggregate classifiers; they are not cave-only attribution."}
(OUT / "profile-summary-speed2.json").write_text(
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print("[L135ProfileSummary] strata=4 status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,70 +0,0 @@
#!/usr/bin/env python3
"""Run the L135 composed cave-passage and tile-seam audits for fixed seeds."""
from __future__ import annotations
import json
import re
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l135"
BIN = OUT / "bin/VoxelForgeCoreHeadless-clang-l135"
DATA = ROOT / "Standalone/data/owner_world.json"
REQUIRED = {
"passage": re.compile(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", re.M),
"seams": re.compile(r"^\[PassageTileSeamAudit\].*status=PASS$", re.M),
"shell": re.compile(r"^\[PassageShellAuditSummary\].*status=PASS$", re.M),
"naturalness": re.compile(r"^\[PassageNaturalnessSummary\].*status=PASS$", re.M),
"mouth_profile": re.compile(r"^\[PassageMouthProfileSummary\].*status=PASS$", re.M),
"ripple": re.compile(r"^\[PassageRippleAuditSummary\].*status=PASS$", re.M),
"route_negative_control": re.compile(
r"^\[TunnelNetworkBlockedRouteControl\].*expected=FAIL status=PASS$", re.M),
}
def main() -> int:
seeds = [int(value) for value in sys.argv[1:]] or list(range(16))
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L135 headless binary or owner fixture")
results = []
for seed in seeds:
log = OUT / f"optimized-seed{seed}.log"
layout = OUT / f"optimized-seed{seed}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=0",
"--force-generate", f"--seed={seed}", "--recipe=surface-world",
"--audit-resolved-layout-passages", "--audit-passage-tile-seams",
f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
checks = {name: bool(pattern.search(content)) for name, pattern in REQUIRED.items()}
blocked_controls = re.findall(
r"^\[ResolvedPassageBlockedControl\].*detected=true$", content, re.M)
checks["three_blocked_controls"] = len(blocked_controls) == 3
passed = result.returncode == 0 and all(checks.values())
row = {"seed": seed, "exit": result.returncode, "passed": passed,
"checks": checks, "blocked_controls": len(blocked_controls),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
results.append(row)
print("[L135SeedSweep] " + json.dumps(row, sort_keys=True), flush=True)
if not passed:
raise SystemExit(f"seed {seed} failed a composed audit; see {log}")
summary = {"seeds": seeds, "passed": len(results), "failed": 0,
"results": results}
(OUT / "optimized-seed-sweep.json").write_text(
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print(f"[L135SeedSweepSummary] passed={len(results)}/{len(seeds)} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,133 +0,0 @@
#!/usr/bin/env python3
"""Five interleaved L80 timings against assembler/world and the L134 revision."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l135/timing"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang",
"a3c8e36-v230": ROOT / "Saved/Linux/l134/bin/VoxelForgeCoreHeadless-l134-clang",
"l135-v236": ROOT / "Saved/Linux/l135/bin/VoxelForgeCoreHeadless-clang-l135",
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
PIPELINE_RE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS_RE = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR_RE = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
PLAN_RE = re.compile(r"^\[WorldAssemblerPlanTiming\] total_ms=([0-9.]+) status=([^ ]+)$", re.M)
CAVE_RE = re.compile(r"^\[CavernPlannerV1\].* plan_ms=([0-9.]+) status=([^ ]+)$", re.M)
def run(strate: int, workers: int, version: str, phase: str,
replicate: int) -> dict:
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}-l135"
log = OUT / f"{label}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARIES[version]), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=8",
"--max-level=8", f"--camera={camera}", "--profile-lod-work",
"--stream-scheduler-policy=3"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near = PIPELINE_RE.search(content), NEAR_RE.search(content)
if result.returncode or pipeline is None or near is None:
raise RuntimeError(f"timing run failed: {log}; exit={result.returncode}")
fields = dict(FIELDS_RE.findall(pipeline.group(1)))
plan, cave = PLAN_RE.search(content), CAVE_RE.search(content)
row = {"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate,
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"plan_ms": float(plan.group(1)) if plan else None,
"cave_plan_ms": float(cave.group(1)) if cave else None,
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
print("[L135TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing L135 timing input")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L135TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 0.9 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows = []
for strate in range(4):
for workers in (8, 12):
for version in BINARIES:
rows.append(run(strate, workers, version, "warmup", 0))
for replicate in range(1, 6):
order = tuple(BINARIES) if replicate % 2 else tuple(reversed(BINARIES))
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
measured = [row for row in rows if row["phase"] == "measured"]
summary = []
for strate in range(4):
for workers in (8, 12):
item = {"strate": strate, "workers": workers,
"replicates_per_version": 5}
medians = {}
for version in BINARIES:
group = [row for row in measured if row["strate"] == strate
and row["workers"] == workers and row["version"] == version]
medians[version] = {}
for key in ("lod02_ready_s", "whole_view_ready_s"):
values = [row[key] for row in group]
medians[version][key] = statistics.median(values)
item[f"{version}_{key}_values"] = values
item[f"{version}_{key}_median"] = medians[version][key]
for baseline in ("assembler-world", "a3c8e36-v230"):
for key in ("lod02_ready_s", "whole_view_ready_s"):
item[f"vs_{baseline}_{key}_delta_pct"] = round(
100.0 * (medians["l135-v236"][key]
/ medians[baseline][key] - 1.0), 2)
summary.append(item)
(OUT / "summary.json").write_text(json.dumps(
{"runs": rows, "summary": summary}, indent=2) + "\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,11 +0,0 @@
<!doctype html><meta charset="utf-8"><title>L135 interior views</title>
<style>body{font:16px sans-serif;background:#202329;color:#eee;margin:24px}h1{font-size:22px}section{display:grid;grid-template-columns:repeat(auto-fit,minmax(420px,1fr));gap:18px}figure{margin:0}img{width:100%;height:auto;display:block}figcaption{padding:6px 0}</style>
<h1>Planner and legacy interiors, seed 0</h1><section>
<figure><a href="planner-arrival-room.png"><img src="planner-arrival-room.png" alt="planner-arrival-room"></a><figcaption>planner-arrival-room</figcaption></figure>
<figure><a href="planner-tunnel.png"><img src="planner-tunnel.png" alt="planner-tunnel"></a><figcaption>planner-tunnel</figcaption></figure>
<figure><a href="planner-compound-room.png"><img src="planner-compound-room.png" alt="planner-compound-room"></a><figcaption>planner-compound-room</figcaption></figure>
<figure><a href="planner-destination-chamber.png"><img src="planner-destination-chamber.png" alt="planner-destination-chamber"></a><figcaption>planner-destination-chamber</figcaption></figure>
<figure><a href="legacy-origin-room.png"><img src="legacy-origin-room.png" alt="legacy-origin-room"></a><figcaption>legacy-origin-room</figcaption></figure>
<figure><a href="legacy-connected-room.png"><img src="legacy-connected-room.png" alt="legacy-connected-room"></a><figcaption>legacy-connected-room</figcaption></figure>
<figure><a href="legacy-origin-tunnel.png"><img src="legacy-origin-tunnel.png" alt="legacy-origin-tunnel"></a><figcaption>legacy-origin-tunnel</figcaption></figure>
</section>
@@ -1,119 +0,0 @@
{
"source_stamp": "8dc4294ce0250a591ee4515471c3c547e796ffa4346ab44f0ae1740bbc3797f5",
"seed": 0,
"renderer": "readable, height tint on, headlamp off; 1600x900",
"views": [
{
"name": "planner-arrival-room",
"recipe": "surface-world",
"camera_m": [
35.593114,
-21.55801,
-755.864011
],
"yaw_deg": 114.47628370565772,
"camera_height_basis": "floor + player eye offset",
"eye_offset_m": 1.6,
"mesh": "Saved/Linux/l135/capture-planner-arrival-room.vfmesh",
"image": "Standalone/Research/WorldAssemblerM3/Linux135/captures/planner-arrival-room.png",
"mesh_log": "Saved/Linux/l135/capture-planner-arrival-room-mesh.log",
"render_log": "Saved/Linux/l135/capture-planner-arrival-room-render.log"
},
{
"name": "planner-tunnel",
"recipe": "surface-world",
"camera_m": [
42.874177,
-24.8725425,
-757.112565
],
"yaw_deg": 114.47628370565774,
"camera_height_basis": "floor + player eye offset",
"eye_offset_m": 1.6,
"mesh": "Saved/Linux/l135/capture-planner-tunnel.vfmesh",
"image": "Standalone/Research/WorldAssemblerM3/Linux135/captures/planner-tunnel.png",
"mesh_log": "Saved/Linux/l135/capture-planner-tunnel-mesh.log",
"render_log": "Saved/Linux/l135/capture-planner-tunnel-render.log"
},
{
"name": "planner-compound-room",
"recipe": "surface-world",
"camera_m": [
-39.519627,
-52.685596,
-785.85419
],
"yaw_deg": -74.782578137959,
"camera_height_basis": "floor + player eye offset",
"eye_offset_m": 1.6,
"mesh": "Saved/Linux/l135/capture-planner-compound-room.vfmesh",
"image": "Standalone/Research/WorldAssemblerM3/Linux135/captures/planner-compound-room.png",
"mesh_log": "Saved/Linux/l135/capture-planner-compound-room-mesh.log",
"render_log": "Saved/Linux/l135/capture-planner-compound-room-render.log"
},
{
"name": "planner-destination-chamber",
"recipe": "surface-world",
"camera_m": [
-28.634259,
-4.85816,
-810.5142579999999
],
"yaw_deg": -89.33032962272898,
"camera_height_basis": "floor + player eye offset",
"eye_offset_m": 1.6,
"mesh": "Saved/Linux/l135/capture-planner-destination-chamber.vfmesh",
"image": "Standalone/Research/WorldAssemblerM3/Linux135/captures/planner-destination-chamber.png",
"mesh_log": "Saved/Linux/l135/capture-planner-destination-chamber-mesh.log",
"render_log": "Saved/Linux/l135/capture-planner-destination-chamber-render.log"
},
{
"name": "legacy-origin-room",
"recipe": "legacy-tunnel-network",
"camera_m": [
0.0,
0.0,
-818.3169921875
],
"yaw_deg": 82.58856646117444,
"camera_height_basis": "legacy room floor + player eye offset",
"eye_offset_m": 1.6,
"mesh": "Saved/Linux/l135/capture-legacy-origin-room.vfmesh",
"image": "Standalone/Research/WorldAssemblerM3/Linux135/captures/legacy-origin-room.png",
"mesh_log": "Saved/Linux/l135/capture-legacy-origin-room-mesh.log",
"render_log": "Saved/Linux/l135/capture-legacy-origin-room-render.log"
},
{
"name": "legacy-connected-room",
"recipe": "legacy-tunnel-network",
"camera_m": [
39.327854,
5.115777,
-799.3986572265625
],
"yaw_deg": -97.41143353882556,
"camera_height_basis": "legacy room floor + player eye offset",
"eye_offset_m": 1.6,
"mesh": "Saved/Linux/l135/capture-legacy-connected-room.vfmesh",
"image": "Standalone/Research/WorldAssemblerM3/Linux135/captures/legacy-connected-room.png",
"mesh_log": "Saved/Linux/l135/capture-legacy-connected-room-mesh.log",
"render_log": "Saved/Linux/l135/capture-legacy-connected-room-render.log"
},
{
"name": "legacy-origin-tunnel",
"recipe": "legacy-tunnel-network",
"camera_m": [
19.663927,
2.5578885,
-804.8623655
],
"yaw_deg": 82.58856646117444,
"camera_height_basis": "near the legacy tunnel centerline",
"eye_offset_m": null,
"mesh": "Saved/Linux/l135/capture-legacy-origin-tunnel.vfmesh",
"image": "Standalone/Research/WorldAssemblerM3/Linux135/captures/legacy-origin-tunnel.png",
"mesh_log": "Saved/Linux/l135/capture-legacy-origin-tunnel-mesh.log",
"render_log": "Saved/Linux/l135/capture-legacy-origin-tunnel-render.log"
}
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

@@ -1,33 +0,0 @@
# Linux136 — cave planner speed
Source stamp `ebe6b32a7cd96c5aa69c6dc64ae6b9c6ff4bc18bc484efc5148611c48723c28f` (v239; v236 is commit `2d89023`).
## Findings
The tile query now keeps sorted passage IDs with route candidates, so the composer skips unrelated routes. A route-free tile returns before per-sample coordinate and scale math. Native cave evaluation also returns the exact host-rock value when its conservative tile feature list is empty. These paths preserve v236 output; no version bump was needed.
The LOD0–2 census shows the shared composer does substantial work outside Tunnel Network. Surface World has zero native cave samples at LOD0–3, yet near-ready passage visits are 19.61M on both `assembler/world` and v236. The route-ID path reduces that count to 3.20M, but cumulative near-ready composer worker time stays around 3.5 s (3.42 s baseline, 3.51 s v236, 3.52 s v239). Whole-view classification worker time is 584 ms / 641 ms / 623 ms. Planning is about 4 ms. This rules out cave evaluation and planning as the Surface World regression, but the census does not isolate mouth-profile checks from the other shared composer/classifier work.
Floating Islands and Vertical Shafts have unrelated-route churn: v236 adds 7.79M and 8.43M passage visits over baseline. v239 brings those totals to 7.89M and 2.54M, and reduces composer worker time by about 9% and 8% versus v236. Tunnel Network falls from 34.63M visits in v236 to 7.47M; its composer worker time returns to baseline. The views still process about 4.7–5.4M native cave samples. The attempted LOD4–8 cave tile proofs produced no skips: every cave-view tile at those LODs remained unclassified.
## L80 timing
Five interleaved measured runs per version and cell, one warmup per version. The pre-run gate was load 0.74 and 99.3% CPU idle. Cells show near-ready and whole-view median deltas versus `assembler/world`, in W8/W12 order; the last column shows near-ready deltas versus v236.
| Stratum | Near-ready Δ | Whole-view Δ | Near-ready Δ vs v236 |
|---|---:|---:|---:|
| Surface World (0) | +4.29% / +5.78% | +2.45% / −0.17% | +0.52% / −1.99% |
| Floating Islands (1) | +8.88% / +5.48% | +1.31% / −0.48% | −2.40% / −4.29% |
| Tunnel Network (2) | +8.23% / +8.26% | +0.35% / +0.88% | −3.51% / −3.97% |
| Vertical Shafts (3) | +13.29% / +6.36% | +1.26% / −1.97% | −4.22% / −3.81% |
v239 improves on v236 in seven of eight near-ready cells, but misses the requested ≤+3% target in all eight cells versus `assembler/world`. Whole-view deltas stay within +2.45%/−1.97%.
## Gates
- Fast tier: PASS, 289.9 s.
- Composed passage, seam, shell, mouth, ripple, naturalness, and blocked-route audits: 16/16 seeds PASS.
- Clang and GCC at W1/W8/W12: all six runs match 13 hash lines.
- Linux VFHostEditor Development: PASS, 5/5 actions in 41.33 s with `-NoUBA -MaxParallelActions=4`; no `prlimit`.
Timing, census, seed, determinism, and build logs are under `Saved/Linux/l136/`. The completed timing matrix is `Saved/Linux/l136/timing/summary.json`; the interrupted partial matrix is excluded. No commit or push was made.
@@ -1,113 +0,0 @@
#!/usr/bin/env python3
"""Compare assembler/world and v236 composer/classifier phase counters."""
from __future__ import annotations
import json
import re
import subprocess
import time
from collections import defaultdict
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l136/census"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang",
"v236": ROOT / "Saved/Linux/l135/bin/VoxelForgeCoreHeadless-clang-l135",
"v239": ROOT / "Saved/Linux/l136/bin/VoxelForgeCoreHeadless-l136-clang",
}
STAMPS = {
"assembler-world": "8b3e7bfb4cde2b408ab940925eab973d8375d6b719774d6f72f64ee72b526c35",
"v236": "8dc4294ce0250a591ee4515471c3c547e796ffa4346ab44f0ae1740bbc3797f5",
"v239": "ebe6b32a7cd96c5aa69c6dc64ae6b9c6ff4bc18bc484efc5148611c48723c28f",
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
def field(line: str) -> dict[str, str]:
return dict(FIELDS.findall(line))
def run(strate: int, version: str) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
log = OUT / f"{version}-s{strate}.log"
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARIES[version]), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--profile-passage-composer",
"--stream-scheduler-policy=3"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp_match = re.search(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", content, re.M)
if result.returncode or stamp_match is None or stamp_match.group(1) != STAMPS[version]:
raise SystemExit(f"census failed/stamp mismatch: {log}, exit={result.returncode}, stamp={stamp_match}")
lod: dict[int, dict] = defaultdict(lambda: defaultdict(float))
for line in content.splitlines():
if line.startswith("[WorldAssemblerLODClassification] "):
values = field(line)
target = lod[int(values["lod"])]
for name in ("tiles", "all_air", "all_solid", "mixed", "unclassified",
"tile_skips", "density_point_calls", "field_eval_sample_points",
"proof_air_cells", "proof_solid_cells"):
target[name] = int(values.get(name, "0"))
target["field_eval_ms_est"] = float(values.get("field_eval_ms_est", "0"))
elif line.startswith("[PassageComposerTile] "):
values = field(line)
level = int(re.search(r"lod(\d+)\)", values["key"]).group(1))
target = lod[level]
target["composer_tiles"] += 1
for name in ("samples", "field_calls", "native_cave_samples", "native_field_calls",
"room_candidates", "edge_candidates", "features", "route_candidates",
"passage_iterations", "carve_segment_visits"):
target[name] += int(values.get(name, "0"))
target["composer_worker_ms"] += float(values.get("worker_ms", "0"))
plan = re.search(r"^\[WorldAssemblerPlanTiming\] total_ms=([0-9.]+)", content, re.M)
cave = re.search(r"^\[CavernPlannerV1\].* plan_ms=([0-9.]+)", content, re.M)
pipeline = re.search(r"^\[WorldAssemblerTilePipeline\] (.*)$", content, re.M)
pipeline_fields = field(pipeline.group(1)) if pipeline else {}
result_row = {
"strate": strate, "version": version, "source_stamp": stamp_match.group(1),
"plan_ms": float(plan.group(1)) if plan else None,
"cave_plan_ms": float(cave.group(1)) if cave else None,
"tile_pipeline": {key: (float(value) if "." in value else int(value))
for key, value in pipeline_fields.items()
if re.fullmatch(r"-?\d+(?:\.\d+)?", value)},
"lod": {str(key): dict(values) for key, values in sorted(lod.items())},
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)),
}
print("[L136CensusRun] " + json.dumps(result_row, sort_keys=True), flush=True)
return result_row
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing census fixture or binary")
rows = []
for strate in range(4):
for version in BINARIES:
rows.append(run(strate, version))
(OUT / "runs-partial.json").write_text(json.dumps(rows, indent=2) + "\n")
summary = {"status": "PASS", "rows": rows,
"notes": [
"classifier milliseconds and composer worker milliseconds are cumulative counters, not exclusive wall time",
"assembler/world predates native cave field counters; field sample fields are only comparable where emitted",
]}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,75 +0,0 @@
#!/usr/bin/env python3
"""Check exact-stamp Clang/GCC cave-path hashes at 1, 8, and 12 workers."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l136/determinism"
DATA = ROOT / "Standalone/data/regression/owner_world_2strate_l61.json"
BINARIES = {
"clang": ROOT / "Saved/Linux/l136/fast/bin/VoxelForgeCoreHeadless-fast-clang",
"gcc": ROOT / "Saved/Linux/l136/fast/bin/VoxelForgeCoreHeadless-fast-gcc",
}
STAMP = "ebe6b32a7cd96c5aa69c6dc64ae6b9c6ff4bc18bc484efc5148611c48723c28f"
CAMERA = "-4.688214,38.662384,-505.781342,-28.446,0"
HASH_RE = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|MaterialHash|LODHash|ExactQueryHash)\].*$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing L136 determinism binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
rows = []
baseline: tuple[str, ...] | None = None
for compiler, binary in BINARIES.items():
for workers in (1, 8, 12):
label = f"determinism-{compiler}-w{workers}"
log = OUT / f"{label}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=0",
"--max-level=0", f"--camera={CAMERA}", "--stream-hash-tiles",
"--force-generate", "--recipe=surface-world", "--render-distance-chunks=0",
"--landmark-chamber-demo", "--ore-veins-demo"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
found_stamp = STAMP_RE.search(content)
hashes = tuple(HASH_RE.findall(content))
passed = (result.returncode == 0 and found_stamp is not None
and found_stamp.group(1) == STAMP and len(hashes) >= 4)
if baseline is None and passed:
baseline = hashes
elif baseline is not None:
passed &= hashes == baseline
row = {"compiler": compiler, "workers": workers,
"exit": result.returncode, "stamp": found_stamp.group(1)
if found_stamp else None,
"hash_lines": len(hashes), "hashes_match_first": hashes == baseline,
"passed": bool(passed), "elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
rows.append(row)
print("[L136DeterminismRun] " + json.dumps(row, sort_keys=True), flush=True)
if not passed:
(OUT / "summary.json").write_text(json.dumps(
{"status": "FAIL", "stamp": STAMP, "runs": rows}, indent=2) + "\n")
raise SystemExit(f"determinism mismatch; see {log}")
(OUT / "summary.json").write_text(json.dumps(
{"status": "PASS", "stamp": STAMP, "runs": rows}, indent=2) + "\n")
print(f"[L136DeterminismSummary] runs={len(rows)} stamp={STAMP} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,75 +0,0 @@
#!/usr/bin/env python3
"""Run the v239 composed cave-passage and tile-seam audits for fixed seeds."""
from __future__ import annotations
import json
import re
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l136/seeds"
BIN = ROOT / "Saved/Linux/l136/bin/VoxelForgeCoreHeadless-l136-clang"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "ebe6b32a7cd96c5aa69c6dc64ae6b9c6ff4bc18bc484efc5148611c48723c28f"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
REQUIRED = {
"passage": re.compile(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", re.M),
"seams": re.compile(r"^\[PassageTileSeamAudit\].*status=PASS$", re.M),
"shell": re.compile(r"^\[PassageShellAuditSummary\].*status=PASS$", re.M),
"naturalness": re.compile(r"^\[PassageNaturalnessSummary\].*status=PASS$", re.M),
"mouth_profile": re.compile(r"^\[PassageMouthProfileSummary\].*status=PASS$", re.M),
"ripple": re.compile(r"^\[PassageRippleAuditSummary\].*status=PASS$", re.M),
"route_negative_control": re.compile(
r"^\[TunnelNetworkBlockedRouteControl\].*expected=FAIL status=PASS$", re.M),
}
def main() -> int:
seeds = [int(value) for value in sys.argv[1:]] or list(range(16))
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L136 headless binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
results = []
for seed in seeds:
log = OUT / f"seed{seed}.log"
layout = OUT / f"seed{seed}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=0",
"--force-generate", f"--seed={seed}", "--recipe=surface-world",
"--audit-resolved-layout-passages", "--audit-passage-tile-seams",
f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
found_stamp = STAMP_RE.search(content)
checks = {name: bool(pattern.search(content)) for name, pattern in REQUIRED.items()}
checks["source_stamp"] = found_stamp is not None and found_stamp.group(1) == STAMP
blocked_controls = re.findall(
r"^\[ResolvedPassageBlockedControl\].*detected=true$", content, re.M)
checks["three_blocked_controls"] = len(blocked_controls) == 3
passed = result.returncode == 0 and all(checks.values())
row = {"seed": seed, "exit": result.returncode, "passed": passed,
"checks": checks, "blocked_controls": len(blocked_controls),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
results.append(row)
print("[L136SeedSweep] " + json.dumps(row, sort_keys=True), flush=True)
(OUT / "runs-partial.json").write_text(json.dumps(results, indent=2) + "\n")
if not passed:
raise SystemExit(f"seed {seed} failed a composed audit; see {log}")
summary = {"source_stamp": STAMP, "seeds": seeds, "passed": len(results),
"failed": 0, "results": results}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
print(f"[L136SeedSweepSummary] passed={len(results)}/{len(seeds)} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,136 +0,0 @@
#!/usr/bin/env python3
"""Five interleaved L80 timings for assembler/world, v236, and v239."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l136/timing"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": (ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang",
"8b3e7bfb4cde2b408ab940925eab973d8375d6b719774d6f72f64ee72b526c35"),
"v236": (ROOT / "Saved/Linux/l135/bin/VoxelForgeCoreHeadless-clang-l135",
"8dc4294ce0250a591ee4515471c3c547e796ffa4346ab44f0ae1740bbc3797f5"),
"v239": (ROOT / "Saved/Linux/l136/bin/VoxelForgeCoreHeadless-l136-clang",
"ebe6b32a7cd96c5aa69c6dc64ae6b9c6ff4bc18bc484efc5148611c48723c28f"),
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
PIPELINE_RE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS_RE = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR_RE = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
PLAN_RE = re.compile(r"^\[WorldAssemblerPlanTiming\] total_ms=([0-9.]+) status=([^ ]+)$", re.M)
CAVE_RE = re.compile(r"^\[CavernPlannerV1\].* plan_ms=([0-9.]+) status=([^ ]+)$", re.M)
def run(strate: int, workers: int, version: str, phase: str,
replicate: int) -> dict:
binary, expected_stamp = BINARIES[version]
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--stream-scheduler-policy=3"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near, stamp = (PIPELINE_RE.search(content), NEAR_RE.search(content),
STAMP_RE.search(content))
if (result.returncode or pipeline is None or near is None or stamp is None
or stamp.group(1) != expected_stamp):
raise SystemExit(f"L80 timing failed/stamp mismatch: {log}; exit={result.returncode}")
fields = dict(FIELDS_RE.findall(pipeline.group(1)))
plan, cave = PLAN_RE.search(content), CAVE_RE.search(content)
row = {"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "source_stamp": stamp.group(1),
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"plan_ms": float(plan.group(1)) if plan else None,
"cave_plan_ms": float(cave.group(1)) if cave else None,
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
print("[L136TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def main() -> int:
if any(not path.is_file() for path, _ in BINARIES.values()) or not DATA.is_file():
raise SystemExit("missing L136 timing input")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L136TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 0.9 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows = []
for strate in range(4):
for workers in (8, 12):
for version in BINARIES:
run(strate, workers, version, "warmup", 0)
for replicate in range(1, 6):
order = tuple(BINARIES) if replicate % 2 else tuple(reversed(BINARIES))
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(json.dumps(rows, indent=2) + "\n")
measured = [row for row in rows if row["phase"] == "measured"]
summary = []
for strate in range(4):
for workers in (8, 12):
item = {"strate": strate, "workers": workers, "replicates_per_version": 5}
medians = {}
for version in BINARIES:
group = [row for row in measured if row["strate"] == strate
and row["workers"] == workers and row["version"] == version]
medians[version] = {}
for key in ("lod02_ready_s", "whole_view_ready_s"):
values = [row[key] for row in group]
medians[version][key] = statistics.median(values)
item[f"{version}_{key}_values"] = values
item[f"{version}_{key}_median"] = medians[version][key]
for baseline in ("assembler-world", "v236"):
for key in ("lod02_ready_s", "whole_view_ready_s"):
item[f"v239_vs_{baseline}_{key}_delta_pct"] = round(
100.0 * (medians["v239"][key] / medians[baseline][key] - 1.0), 2)
summary.append(item)
(OUT / "summary.json").write_text(json.dumps(
{"runs": rows, "summary": summary}, indent=2) + "\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,120 +0,0 @@
#!/usr/bin/env python3
"""Symbolize L137 L77 samples and compare inclusive worker functions."""
from __future__ import annotations
import csv
import json
import re
import subprocess
from collections import Counter
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/profile"
BINARIES = {
"assembler-world": ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-base",
"head": ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-head",
}
SAMPLE_RE = re.compile(
r"^\[L77Sample\] pc=(0x\w+) lod=(\d+) stage=(\S+) route=(\S+) "
r"phase=(\S+) halo=(\d+) weight=(\d+)$", re.M)
def samples(version: str) -> tuple[list[dict], set[str]]:
rows, pcs = [], set()
for replicate in (1, 2, 3):
path = OUT / f"sw-{version}-r{replicate}.log"
for pc, lod, stage, route, phase, halo, weight in SAMPLE_RE.findall(
path.read_text(encoding="utf-8", errors="replace")):
lod_value = int(lod)
if not 0 <= lod_value <= 8:
continue
pcs.add(pc)
rows.append({"version": version, "replicate": replicate,
"pc": pc, "lod": lod_value, "stage": stage,
"route": route, "phase": phase, "halo": int(halo),
"weight": int(weight)})
return rows, pcs
def symbolize(version: str, pcs: set[str]) -> dict[str, str]:
command = ["llvm-symbolizer-19", "--demangle", "--inlines", "--output-style=JSON",
f"--obj={BINARIES[version]}"]
result = subprocess.run(command, input="\n".join(sorted(pcs)) + "\n",
capture_output=True, text=True, check=True)
decoder = json.JSONDecoder()
offset, output = 0, {}
while offset < len(result.stdout):
while offset < len(result.stdout) and result.stdout[offset].isspace():
offset += 1
if offset == len(result.stdout):
break
item, offset = decoder.raw_decode(result.stdout, offset)
frames = item.get("Symbol", [])
output[item["Address"]] = (
frames[0].get("FunctionName", "?") if frames else "?")
if output.keys() != pcs:
raise RuntimeError(f"{version}: symbolizer resolved {len(output)}/{len(pcs)} PCs")
return output
def main() -> int:
totals: dict[str, Counter] = {}
lod_totals: dict[str, Counter] = {}
detail_rows = []
for version in BINARIES:
rows, pcs = samples(version)
symbols = symbolize(version, pcs)
totals[version] = Counter()
lod_totals[version] = Counter()
for row in rows:
function = symbols[row["pc"]]
weight = row["weight"]
totals[version][function] += weight
lod_totals[version][row["lod"]] += weight
detail_rows.append({**row, "function": function})
total_by_version = {key: sum(counter.values()) for key, counter in totals.items()}
functions = set(totals["assembler-world"]) | set(totals["head"])
result = []
for function in functions:
base_ticks = totals["assembler-world"][function]
head_ticks = totals["head"][function]
base_pct = 100.0 * base_ticks / total_by_version["assembler-world"]
head_pct = 100.0 * head_ticks / total_by_version["head"]
result.append({
"function": function,
"assembler_world_ticks": base_ticks,
"assembler_world_share_pct": round(base_pct, 3),
"head_ticks": head_ticks,
"head_share_pct": round(head_pct, 3),
"share_delta_pp": round(head_pct - base_pct, 3),
})
result.sort(key=lambda row: abs(row["share_delta_pp"]), reverse=True)
with (OUT / "function-diff.csv").open("w", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=list(result[0]))
writer.writeheader()
writer.writerows(result)
with (OUT / "symbolized-samples.csv").open(
"w", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=list(detail_rows[0]))
writer.writeheader()
writer.writerows(detail_rows)
summary = {
"scope": "worker samples LOD0-8, all LODs included; lod=255 main-thread samples excluded",
"runs_per_version": 3,
"weighted_ticks": total_by_version,
"lod_weighted_ticks": {version: dict(sorted(values.items()))
for version, values in lod_totals.items()},
"function_diff": result,
}
(OUT / "function-diff.json").write_text(
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print("[L137ProfileDiff] " + json.dumps({
"scope": summary["scope"], "weighted_ticks": total_by_version,
"lod_weighted_ticks": summary["lod_weighted_ticks"],
"largest_share_deltas": result[:20]}, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,26 +0,0 @@
# Linux137 report
## Measurement
Two `assembler/world` binaries had identical SHA-256. On Surface World, their L80 near-ready medians differed by +0.52% at W8 and −0.59% at W12. The no-op v228 control differed by −0.37% and −0.05%; its stream hashes matched v227. Use ±1% as the median noise floor. Individual paired controls varied by up to about 2.5% (3.6% for one no-op pair).
The three-run L77 profile sampled LOD 0–8 with no lost samples. Function share changes, `HEAD` versus `assembler/world`: `CachedColumn` +0.93 pp, shared column `TryRead` +0.58 pp, `prepareSweptTubeBase` +0.38 pp, and `sweptSample` +0.17 pp. `ApplyResolvedStratePassageCarves` fell by 0.97 pp and `FindBoundStratumForManagerZ` by 0.39 pp. The profile points more toward column-cache work and the sweep lookup than mouth-profile work; it does not isolate one cause for every world.
Changes retained: removed the unused `floorShellSignedDistance` sample field; removed per-lookup shared-pointer refcounting and batched diagnostic counters per query scope.
## L80 near-ready medians
Each delta is candidate versus `assembler/world`; the A/A median noise floor is ±1%.
| World | W8 delta | W12 delta |
|---|---:|---:|
| Surface World | +3.58% (±1%) | +2.90% (±1%) |
| Floating Islands | +0.19% (±1%) | +2.20% (±1%) |
| Tunnel Network | −3.60% (±1%) | +6.84% (±1%) |
| Vertical Shafts | +4.31% (±1%) | +3.96% (±1%) |
The requested targets are not met except Floating Islands W8 and Tunnel Network W8. Whole-view medians were within −8.39% to +0.27% of baseline.
## Verification
Fast tier passed (273 checks); the composed sweep passed 16/16 seeds with seams and blocked controls; Clang/GCC W1/W8/W12 matched all 13 hashes. Linux UE host build passed with `-NoUBA -MaxParallelActions=4` and no `prlimit`. Output audits stayed green, so version and baselines were left unchanged. No commit, push, or stash.
@@ -1,140 +0,0 @@
#!/usr/bin/env python3
"""L80 Surface World A/A and no-op evaluator-version control timings."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/timing/aa"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"aa_a": ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-a",
"aa_b": ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-b",
"v228": ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-v228",
}
CAMERA = "8.000000000000,16.000000000000,-372.262695312500,0,0"
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def run(workers: int, version: str, phase: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
label = f"sw-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARIES[version]), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=8",
"--max-level=8", f"--camera={CAMERA}", "--profile-lod-work",
"--stream-scheduler-policy=3",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near, stamp = PIPELINE.search(content), NEAR.search(content), STAMP.search(content)
if result.returncode or pipeline is None or near is None or stamp is None:
raise SystemExit(f"L80 run failed or trace missing: {log}; exit={result.returncode}")
fields = dict(FIELDS.findall(pipeline.group(1)))
row = {
"strate": 0, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "source_stamp": stamp.group(1),
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(fields["whole_tiles"].split("/")[0]),
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)),
}
print("[L137AARun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def main() -> int:
missing = [str(path) for path in [DATA, *BINARIES.values()] if not path.is_file()]
if missing:
raise SystemExit("missing L137 A/A input: " + ", ".join(missing))
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L137AAGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 0.9 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows = []
versions = tuple(BINARIES)
for workers in (8, 12):
for version in versions:
run(workers, version, "warmup", 0)
orders = (versions, ("v228", "aa_b", "aa_a"),
("aa_b", "aa_a", "v228"), ("aa_a", "v228", "aa_b"),
("v228", "aa_a", "aa_b"))
for replicate, order in enumerate(orders, 1):
for version in order:
rows.append(run(workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
summary = []
for workers in (8, 12):
group = [row for row in rows if row["workers"] == workers]
medians = {
version: {
key: statistics.median(row[key] for row in group
if row["version"] == version)
for key in ("lod02_ready_s", "whole_view_ready_s")
}
for version in versions
}
item = {"strate": 0, "workers": workers, "replicates_per_version": 5,
"medians": medians}
for metric in ("lod02_ready_s", "whole_view_ready_s"):
for lhs, rhs in (("aa_b", "aa_a"), ("v228", "aa_a")):
item[f"{lhs}_vs_{rhs}_{metric}_delta_pct"] = round(
100.0 * (medians[lhs][metric] / medians[rhs][metric] - 1.0), 3)
paired = []
for replicate in range(1, 6):
values = {row["version"]: row[metric] for row in group
if row["phase"] == "measured" and row["replicate"] == replicate}
paired.append({"replicate": replicate,
"aa_b_vs_aa_a_pct": round(
100.0 * (values["aa_b"] / values["aa_a"] - 1.0), 3),
"v228_vs_aa_a_pct": round(
100.0 * (values["v228"] / values["aa_a"] - 1.0), 3)})
item[f"{metric}_paired_deltas_pct"] = paired
summary.append(item)
(OUT / "summary.json").write_text(
json.dumps({"runs": rows, "summary": summary}, indent=2) + "\n",
encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,74 +0,0 @@
#!/usr/bin/env python3
"""Compare L137 Clang/GCC composed hashes at W1, W8, and W12."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/determinism"
DATA = ROOT / "Standalone/data/regression/owner_world_2strate_l61.json"
BINARIES = {
"clang": ROOT / "Saved/Linux/l137/fast/bin/VoxelForgeCoreHeadless-fast-clang",
"gcc": ROOT / "Saved/Linux/l137/fast/bin/VoxelForgeCoreHeadless-fast-gcc",
}
STAMP = "dcf2ffa55fd6d62b3c7faf76229c3b99c635868dc1b694fc6e8f39e738775a4e"
CAMERA = "-4.688214,38.662384,-505.781342,-28.446,0"
HASH_RE = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|MaterialHash|LODHash|ExactQueryHash)\].*$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing L137 determinism binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
rows = []
baseline: tuple[str, ...] | None = None
for compiler, binary in BINARIES.items():
for workers in (1, 8, 12):
label = f"determinism-{compiler}-w{workers}"
log = OUT / f"{label}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=0",
"--max-level=0", f"--camera={CAMERA}", "--stream-hash-tiles",
"--force-generate", "--recipe=surface-world", "--render-distance-chunks=0",
"--landmark-chamber-demo", "--ore-veins-demo"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
hashes = tuple(HASH_RE.findall(content))
passed = (result.returncode == 0 and stamp is not None
and stamp.group(1) == STAMP and len(hashes) >= 4)
if baseline is None and passed:
baseline = hashes
elif baseline is not None:
passed &= hashes == baseline
row = {"compiler": compiler, "workers": workers, "exit": result.returncode,
"stamp": stamp.group(1) if stamp else None, "hash_lines": len(hashes),
"hashes_match_first": hashes == baseline, "passed": bool(passed),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
rows.append(row)
print("[L137DeterminismRun] " + json.dumps(row, sort_keys=True), flush=True)
if not passed:
(OUT / "summary.json").write_text(json.dumps(
{"status": "FAIL", "stamp": STAMP, "runs": rows}, indent=2) + "\n")
raise SystemExit(f"determinism mismatch; see {log}")
(OUT / "summary.json").write_text(json.dumps(
{"status": "PASS", "stamp": STAMP, "runs": rows}, indent=2) + "\n")
print(f"[L137DeterminismSummary] runs={len(rows)} stamp={STAMP} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,146 +0,0 @@
#!/usr/bin/env python3
"""Five interleaved L80 timings for assembler/world and the L137 candidate."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/timing/final"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": (
ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-a",
"4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621"),
"l137": (
ROOT / "Saved/Linux/l137/fast/bin/VoxelForgeCoreHeadless-fast-clang",
"dcf2ffa55fd6d62b3c7faf76229c3b99c635868dc1b694fc6e8f39e738775a4e"),
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
binary, expected_stamp = BINARIES[version]
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--stream-scheduler-policy=3",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near, stamp = PIPELINE.search(content), NEAR.search(content), STAMP.search(content)
if (result.returncode or pipeline is None or near is None or stamp is None
or stamp.group(1) != expected_stamp):
raise SystemExit(f"L80 timing failed or stamp mismatch: {log}; exit={result.returncode}")
fields = dict(FIELDS.findall(pipeline.group(1)))
row = {
"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "source_stamp": stamp.group(1),
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(fields["whole_tiles"].split("/")[0]),
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)),
}
print("[L137FinalTimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def main() -> int:
if any(not path.is_file() for path in [DATA, *(entry[0] for entry in BINARIES.values())]):
raise SystemExit("missing L137 timing input")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L137FinalTimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 0.9 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows = []
for strate in range(4):
for workers in (8, 12):
for version in BINARIES:
run(strate, workers, version, "warmup", 0)
for replicate in range(1, 6):
order = tuple(BINARIES) if replicate % 2 else tuple(reversed(BINARIES))
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
measured = [row for row in rows if row["phase"] == "measured"]
summary = []
for strate in range(4):
for workers in (8, 12):
group = [row for row in measured
if row["strate"] == strate and row["workers"] == workers]
entry = {"strate": strate, "workers": workers, "replicates_per_version": 5}
medians = {}
for version in BINARIES:
version_rows = [row for row in group if row["version"] == version]
medians[version] = {
key: statistics.median(row[key] for row in version_rows)
for key in ("lod02_ready_s", "whole_view_ready_s")}
for key in medians[version]:
entry[f"{version}_{key}_values"] = [row[key] for row in version_rows]
entry[f"{version}_{key}_median"] = medians[version][key]
for key in ("lod02_ready_s", "whole_view_ready_s"):
entry[f"l137_vs_assembler-world_{key}_delta_pct"] = round(
100.0 * (medians["l137"][key]
/ medians["assembler-world"][key] - 1.0), 2)
entry[f"{key}_paired_deltas_pct"] = [
round(100.0 * (next(row[key] for row in group
if row["version"] == "l137" and row["replicate"] == replicate)
/ next(row[key] for row in group
if row["version"] == "assembler-world"
and row["replicate"] == replicate) - 1.0), 3)
for replicate in range(1, 6)]
summary.append(entry)
(OUT / "summary.json").write_text(json.dumps(
{"runs": rows, "summary": summary}, indent=2) + "\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,84 +0,0 @@
#!/usr/bin/env python3
"""All-LOD inclusive L77 samples for assembler/world and L137 HEAD."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/profile"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-base",
"head": ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-head",
}
STAMPS = {
"assembler-world": "4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621",
"head": "dcf2ffa55fd6d62b3c7faf76229c3b99c635868dc1b694fc6e8f39e738775a4e",
}
CAMERA = "8.000000000000,16.000000000000,-372.262695312500,0,0"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
SAMPLER_RE = re.compile(r"^\[L77Sampler\] action=stop (.*)$", re.M)
SAMPLE_RE = re.compile(
r"^\[L77Sample\] pc=(0x\w+) lod=(\d+) stage=(\S+) route=(\S+) "
r"phase=(\S+) halo=(\d+) weight=(\d+)$", re.M)
def run(version: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
log = OUT / f"sw-{version}-r{replicate}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARIES[version]), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={CAMERA}", "--profile-lod-work", "--stream-scheduler-policy=3",
"--linux77-profile",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp, sampler = STAMP_RE.search(content), SAMPLER_RE.search(content)
samples = SAMPLE_RE.findall(content)
if (result.returncode or stamp is None or sampler is None
or stamp.group(1) != STAMPS[version] or "status=PASS" not in sampler.group(1)):
raise SystemExit(f"L77 profile failed or stamp mismatch: {log}; exit={result.returncode}")
sam = dict(re.findall(r"([a-zA-Z0-9_]+)=([^ ]+)", sampler.group(1)))
lods = sorted({int(row[1]) for row in samples})
row = {
"world": "Surface World", "version": version, "replicate": replicate,
"source_stamp": stamp.group(1), "workers": 8, "lods_sampled": lods,
"stored_samples": len(samples), "expanded_ticks": int(sam["expanded_ticks"]),
"lost": int(sam["lost"]), "timer_threads": int(sam["timer_threads"]),
"profiled_thread_cpu_s": float(sam["profiled_thread_cpu_s"]),
"handler_cpu_ms": float(sam["handler_cpu_ms"]),
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)),
}
print("[L137ProfileRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
missing = [str(path) for path in [DATA, *BINARIES.values()] if not path.is_file()]
if missing:
raise SystemExit("missing L137 profile input: " + ", ".join(missing))
rows = []
for replicate, order in enumerate((
("assembler-world", "head"), ("head", "assembler-world"),
("assembler-world", "head")), 1):
for version in order:
rows.append(run(version, replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
(OUT / "runs.json").write_text(json.dumps(rows, indent=2) + "\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,73 +0,0 @@
#!/usr/bin/env python3
"""Run the L137 composed passage and tile-seam audits for seeds 0 through 15."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/seeds"
BIN = ROOT / "Saved/Linux/l137/fast/bin/VoxelForgeCoreHeadless-fast-clang"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "dcf2ffa55fd6d62b3c7faf76229c3b99c635868dc1b694fc6e8f39e738775a4e"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
REQUIRED = {
"passage": re.compile(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", re.M),
"seams": re.compile(r"^\[PassageTileSeamAudit\].*status=PASS$", re.M),
"shell": re.compile(r"^\[PassageShellAuditSummary\].*status=PASS$", re.M),
"naturalness": re.compile(r"^\[PassageNaturalnessSummary\].*status=PASS$", re.M),
"mouth_profile": re.compile(r"^\[PassageMouthProfileSummary\].*status=PASS$", re.M),
"ripple": re.compile(r"^\[PassageRippleAuditSummary\].*status=PASS$", re.M),
"route_negative_control": re.compile(
r"^\[TunnelNetworkBlockedRouteControl\].*expected=FAIL status=PASS$", re.M),
}
def main() -> int:
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L137 fast binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
results = []
for seed in range(16):
log = OUT / f"seed{seed}.log"
layout = OUT / f"seed{seed}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=0",
"--force-generate", f"--seed={seed}", "--recipe=surface-world",
"--audit-resolved-layout-passages", "--audit-passage-tile-seams",
f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
found_stamp = STAMP_RE.search(content)
checks = {name: bool(pattern.search(content)) for name, pattern in REQUIRED.items()}
checks["source_stamp"] = found_stamp is not None and found_stamp.group(1) == STAMP
blocked = re.findall(r"^\[ResolvedPassageBlockedControl\].*detected=true$",
content, re.M)
checks["three_blocked_controls"] = len(blocked) == 3
passed = result.returncode == 0 and all(checks.values())
row = {"seed": seed, "exit": result.returncode, "passed": passed,
"checks": checks, "blocked_controls": len(blocked),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
results.append(row)
print("[L137SeedSweep] " + json.dumps(row, sort_keys=True), flush=True)
(OUT / "runs-partial.json").write_text(json.dumps(results, indent=2) + "\n")
if not passed:
raise SystemExit(f"seed {seed} failed composed audits; see {log}")
summary = {"source_stamp": STAMP, "seeds": list(range(16)),
"passed": len(results), "failed": 0, "results": results}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
print("[L137SeedSweepSummary] passed=16/16 status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,60 +0,0 @@
#!/usr/bin/env python3
"""Compare rendered Surface World hashes for v227 and the no-op v228 bump."""
from __future__ import annotations
import json
import re
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/output-check"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"v227": ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-a",
"v228": ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-v228",
}
CAMERA = "8.000000000000,16.000000000000,-372.262695312500,0,0"
HASHES = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|MaterialHash|LODHash|ExactQueryHash)\].*$",
re.M)
def run(version: str) -> tuple[list[str], str]:
OUT.mkdir(parents=True, exist_ok=True)
log = OUT / f"surface-world-{version}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARIES[version]), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={CAMERA}", "--recipe=surface-world", "--stream-hash",
"--stream-scheduler-policy=3",
]
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
hashes = HASHES.findall(content)
if result.returncode or len(hashes) < 4:
raise SystemExit(f"hash run failed: {version}; exit={result.returncode}; log={log}")
return hashes, str(log.relative_to(ROOT))
def main() -> int:
rows = []
for version in BINARIES:
hashes, log = run(version)
rows.append({"version": version, "hashes": hashes, "log": log})
match = rows[0]["hashes"] == rows[1]["hashes"]
summary = {"output_hashes_match": match, "rows": rows}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
print("[L137VersionOutput] " + json.dumps({
"output_hashes_match": match,
"hash_lines": len(rows[0]["hashes"]),
"v227": rows[0]["hashes"], "v228": rows[1]["hashes"]}, sort_keys=True))
return 0 if match else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,103 +0,0 @@
#!/usr/bin/env python3
"""Summarize per-tile cache counters from the five L137 paired timing runs."""
from __future__ import annotations
import json
import re
import statistics
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
SOURCE = ROOT / "Saved/Linux/l137/timing/final-design1"
OUT = ROOT / "Saved/Linux/l138/prechange/column-cache-counts.json"
STAMPS = {
"assembler-world": "4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621",
"l137": "7913d019d968de2dbaea2282b90fa8ff41b53f996c022e9e6fed92712cb40ecf",
}
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
METRICS = (
"column_point_calls", "column_local_hits", "column_local_misses",
"column_conflict_misses", "column_shared_hits", "column_formula_evaluations",
)
def read_run(strate: int, workers: int, version: str, replicate: int) -> dict:
path = SOURCE / f"s{strate}-w{workers}-{version}-measured{replicate}.log"
if not path.is_file():
raise SystemExit(f"missing pre-change L137 run: {path}")
text = path.read_text(encoding="utf-8", errors="replace")
stamp = re.search(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", text, re.M)
if stamp is None or stamp.group(1) != STAMPS[version]:
raise SystemExit(f"unexpected source stamp in {path}")
rows = {}
for line in text.splitlines():
if not line.startswith("[WorldAssemblerLODCostDetail] "):
continue
fields = dict(FIELDS.findall(line))
rows[int(fields["lod"])] = fields
if set(rows) != set(range(9)):
raise SystemExit(f"incomplete LOD counters in {path}: {sorted(rows)}")
return {"path": str(path.relative_to(ROOT)), "rows": rows}
def summarize(runs: list[dict], lods: range) -> dict:
per_run = []
for run in runs:
selected = [run["rows"][lod] for lod in lods]
tile_count = sum(int(row["tiles"]) for row in selected)
per_run.append({
"tiles": tile_count,
**{metric: sum(int(row[metric]) for row in selected) / tile_count
for metric in METRICS},
})
return {
"tiles_per_run": statistics.mean(row["tiles"] for row in per_run),
"mean_per_tile": {
metric: statistics.mean(row[metric] for row in per_run)
for metric in METRICS
},
"run_range_per_tile": {
metric: [min(row[metric] for row in per_run),
max(row[metric] for row in per_run)]
for metric in METRICS
},
}
def main() -> int:
result = {
"source": "five measured L137 L80 runs per version, worker count, and stratum",
"pre_change_stamps": STAMPS,
"cells": [],
}
for strate in range(4):
for workers in (8, 12):
versions = {
version: [read_run(strate, workers, version, replicate)
for replicate in range(1, 6)]
for version in STAMPS
}
item = {"strate": strate, "workers": workers}
for window, lods in (("near_lod0_2", range(3)), ("whole_lod0_8", range(9))):
item[window] = {
version: summarize(runs, lods)
for version, runs in versions.items()
}
item[window]["candidate_minus_baseline_per_tile"] = {
metric: (item[window]["l137"]["mean_per_tile"][metric]
- item[window]["assembler-world"]["mean_per_tile"][metric])
for metric in METRICS
}
item["logs"] = {
version: [run["path"] for run in runs]
for version, runs in versions.items()
}
result["cells"].append(item)
OUT.parent.mkdir(parents=True, exist_ok=True)
OUT.write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8")
print(f"[L138PrechangeCacheCounts] cells={len(result['cells'])} output={OUT.relative_to(ROOT)}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,49 +0,0 @@
# Linux138 — final cave planner speed pass
Source stamp: `9aade4e6cb33e86c36b89440644d9ef5d440288fb6ff0af03af128291c95f93f`.
## Result
The suspected column-cache regression is not present in the measured counters. Calls and formula evaluations per tile match `assembler/world`; the small miss deltas change sign between W8 and W12. The L77 `CachedColumn` and shared `TryRead` increases were normalized sample-share changes, not evidence of more cache calls.
I removed repeated route identity checks and added a fast path for prepared sweep samples that are stamped outside all passage influence. The path preserves the sample's flat distance in the union and skips wall/floor shell work whose bounds are positive. The speed bar is still missed on several near-ready cells, especially Vertical Shafts. No version bump or baseline update was needed: output audits remained green.
## Before-change cache census
Means per near-ready LOD0–2 tile, averaged across the five measured L137 L80 runs per worker count. Each cell is `assembler/world / L137 candidate`.
| Stratum / workers | Point calls | Local hits | Local misses | Shared hits | Formula evaluations |
|---|---:|---:|---:|---:|---:|
| Surface World / W8 | 6529.395 / 6529.396 | 5712.251 / 5720.303 | 817.144 / 809.092 | 570.207 / 562.158 | 246.937 / 246.934 |
| Surface World / W12 | 6529.395 / 6529.396 | 5642.386 / 5641.558 | 887.009 / 887.838 | 639.976 / 640.851 | 247.033 / 246.987 |
Floating Islands, Tunnel Network, and Vertical Shafts had zero generic heightfield column calls and cache hits/misses per near-ready tile in both binaries. Floating Islands' separate local/shared cache counters were also zero in its profiled LOD0–2 tiles. The shared `TryRead` path is reached on local misses: W8 had about 8 fewer misses per tile on the candidate, while W12 had 0.83 more. Cache code, key, and window are unchanged versus `assembler/world` in `WorldAssemblerInternal.h`, `SharedColumnCache.h`, and `FloatingIslandsInternal.h`.
L77 reports each function's share of sampled worker ticks. A higher share can result when other work takes a smaller share; it is not a cache-call counter. The before-change census is in `Saved/Linux/l138/prechange/column-cache-counts.json`; the separate Floating Islands counters are in `Saved/Linux/l138/prechange/island-cache/summary.json`.
## Change and timing
`ShapeWorldInternal.h` now reuses the already-computed Tunnel Network stratum predicate in the passage loop. For a swept sample with no exact contribution, it adds the same flat outside distance to the union, then skips relief, mouth, wall, and shell calculations. The influence bound is 1.053 m (0.75 m shell + 0.21 m relief + 0.083 m corner support + 0.01 m guard); the stamped sentinel is one subvoxel beyond it.
Final L80 used one warm-up and five interleaved runs per binary, at W8/W12 across all four strata. The quiet-host gate passed at load 1.34 and 98.9% CPU idle. Deltas are candidate medians versus `assembler/world`; the L137 A/A noise floor is ±1%.
| Stratum | Near-ready W8 / W12 | Whole-view W8 / W12 |
|---|---:|---:|
| Surface World | +0.34% / +1.72% | −0.48% / −0.93% |
| Floating Islands | −4.34% / +2.87% | −3.11% / −1.50% |
| Tunnel Network | −2.54% / +2.86% | −3.96% / −1.73% |
| Vertical Shafts | +4.66% / +3.25% | −1.73% / −2.06% |
Only Surface World W8 is within ±1% near-ready. The per-LOD worker totals show LOD2 down 24–39% on Floating Islands, Tunnel Network, and Vertical Shafts, but Vertical Shafts LOD0/1 are up 5–22%; that remaining work keeps its near-ready medians outside the bar. Tunnel Network W8 is the closest of its two near-ready cells.
## Checks
- Fast tier: PASS, 273 checks, 286.0 s.
- Composed sweep: PASS, 16/16 seeds, with passage, seam, shell, mouth-profile, naturalness, ripple, and blocked-route controls.
- Clang/GCC W1/W8/W12: PASS, all 13 determinism hash lines match.
- Linux `VFHostEditor` Development: PASS, 5 actions, 38.19 s with `-NoUBA -MaxParallelActions=4`; no `prlimit`.
- The full verification tier and Windows UE build were not run. No Unreal `Source/` files changed.
The first fast-tier invocation used the verifier's default `l42` output directory and refused its stale binary. I reran it with `--out Saved/Linux/l138`; the final-source run passed.
Build, fast-tier, seed, determinism, cache-census, and timing logs are under `Saved/Linux/l138/`; the final timing matrix is `Saved/Linux/l138/timing/summary.json`. Changes are uncommitted.
@@ -1,74 +0,0 @@
#!/usr/bin/env python3
"""Compare L138 Clang/GCC composed hashes at W1, W8, and W12."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l138/determinism"
DATA = ROOT / "Standalone/data/regression/owner_world_2strate_l61.json"
BINARIES = {
"clang": ROOT / "Saved/Linux/l138/bin/VoxelForgeCoreHeadless-l138-clang",
"gcc": ROOT / "Saved/Linux/l138/bin/VoxelForgeCoreHeadless-l138-gcc",
}
STAMP = "9aade4e6cb33e86c36b89440644d9ef5d440288fb6ff0af03af128291c95f93f"
CAMERA = "-4.688214,38.662384,-505.781342,-28.446,0"
HASH_RE = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|MaterialHash|LODHash|ExactQueryHash)\].*$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing L138 determinism binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
rows = []
reference: tuple[str, ...] | None = None
for compiler, binary in BINARIES.items():
for workers in (1, 8, 12):
name = f"determinism-{compiler}-w{workers}"
log = OUT / f"{name}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=0",
"--max-level=0", f"--camera={CAMERA}", "--stream-hash-tiles",
"--force-generate", "--recipe=surface-world", "--render-distance-chunks=0",
"--landmark-chamber-demo", "--ore-veins-demo"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
hashes = tuple(HASH_RE.findall(content))
passed = (proc.returncode == 0 and stamp is not None
and stamp.group(1) == STAMP and len(hashes) >= 4)
if reference is None and passed:
reference = hashes
elif reference is not None:
passed = passed and hashes == reference
row = {"compiler": compiler, "workers": workers, "exit": proc.returncode,
"stamp": stamp.group(1) if stamp else None, "hash_lines": len(hashes),
"hashes_match_first": hashes == reference, "passed": bool(passed),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
rows.append(row)
print("[L138DeterminismRun] " + json.dumps(row, sort_keys=True), flush=True)
if not passed:
(OUT / "summary.json").write_text(json.dumps(
{"status": "FAIL", "stamp": STAMP, "runs": rows}, indent=2) + "\n")
raise SystemExit(f"determinism mismatch; see {log}")
(OUT / "summary.json").write_text(json.dumps(
{"status": "PASS", "stamp": STAMP, "runs": rows}, indent=2) + "\n")
print(f"[L138DeterminismSummary] runs={len(rows)} stamp={STAMP} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,151 +0,0 @@
#!/usr/bin/env python3
"""Run five interleaved L80 timings for assembler/world and the L138 candidate."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l138/timing"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": (
ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-a",
"4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621"),
"l138": (
ROOT / "Saved/Linux/l138/bin/VoxelForgeCoreHeadless-l138-clang",
"9aade4e6cb33e86c36b89440644d9ef5d440288fb6ff0af03af128291c95f93f"),
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
binary, expected_stamp = BINARIES[version]
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--stream-scheduler-policy=3",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near, stamp = PIPELINE.search(content), NEAR.search(content), STAMP.search(content)
if (proc.returncode or pipeline is None or near is None or stamp is None
or stamp.group(1) != expected_stamp):
raise SystemExit(f"L80 timing failed or stamp mismatch: {log}; exit={proc.returncode}")
fields = dict(FIELDS.findall(pipeline.group(1)))
row = {
"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "source_stamp": stamp.group(1),
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(fields["whole_tiles"].split("/")[0]),
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)),
}
print("[L138FinalTimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def main() -> int:
if any(not path.is_file() for path in [DATA, *(entry[0] for entry in BINARIES.values())]):
raise SystemExit("missing L138 timing input")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L138FinalTimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 1.5 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows = []
for strate in range(4):
for workers in (8, 12):
for version in BINARIES:
run(strate, workers, version, "warmup", 0)
for replicate in range(1, 6):
order = tuple(BINARIES) if replicate % 2 else tuple(reversed(BINARIES))
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
measured = [row for row in rows if row["phase"] == "measured"]
summary = []
for strate in range(4):
for workers in (8, 12):
group = [row for row in measured
if row["strate"] == strate and row["workers"] == workers]
entry = {"strate": strate, "workers": workers, "replicates_per_version": 5}
medians = {
version: {
key: statistics.median(row[key] for row in group
if row["version"] == version)
for key in ("lod02_ready_s", "whole_view_ready_s")
}
for version in BINARIES
}
entry["medians"] = medians
for key in ("lod02_ready_s", "whole_view_ready_s"):
entry[f"l138_vs_assembler-world_{key}_delta_pct"] = round(
100.0 * (medians["l138"][key] / medians["assembler-world"][key] - 1.0), 2)
entry[f"{key}_paired_deltas_pct"] = [
round(100.0 * (
next(row[key] for row in group
if row["version"] == "l138" and row["replicate"] == replicate)
/ next(row[key] for row in group
if row["version"] == "assembler-world"
and row["replicate"] == replicate) - 1.0), 3)
for replicate in range(1, 6)
]
summary.append(entry)
(OUT / "summary.json").write_text(json.dumps({
"a_a_noise_floor_pct": 1.0,
"timing_protocol": "one warmup per binary, five interleaved runs, W8/W12, all four strata",
"runs": rows,
"summary": summary,
}, indent=2) + "\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,80 +0,0 @@
#!/usr/bin/env python3
"""Count pre-change Floating Islands cache calls from L137 binaries."""
from __future__ import annotations
import json
import re
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l138/prechange/island-cache"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": (
ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-base",
"4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621"),
"l137": (
ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-head",
"dcf2ffa55fd6d62b3c7faf76229c3b99c635868dc1b694fc6e8f39e738775a4e"),
}
CAMERAS = {
1: (25.8369140625, 3.19921875, -737.0),
}
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
TILE = re.compile(r"^\[CpuTileStages\] key=\([^)]*,lod(\d+)\).*", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
CACHE_FIELDS = (
"fi_local_hit", "fi_local_miss", "fi_local_conflicts",
"fi_shared_hit", "fi_shared_miss", "fi_shared_computes",
"fi_shared_conflicts",
)
def main() -> int:
OUT.mkdir(parents=True, exist_ok=True)
rows = []
for workers in (8, 12):
for version, (binary, expected_stamp) in BINARIES.items():
camera = ",".join(f"{value:.12f}" for value in CAMERAS[1]) + ",0,0"
log = OUT / f"s1-w{workers}-{version}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=8",
"--max-level=8", f"--camera={camera}", "--profile-lod-work",
"--profile-passage-composer", "--stream-scheduler-policy=3",
]
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
text = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP.search(text)
if proc.returncode or not stamp or stamp.group(1) != expected_stamp:
raise SystemExit(f"pre-change cache census failed: {log}")
tiles = []
for line in text.splitlines():
match = TILE.match(line)
if not match or int(match.group(1)) > 2:
continue
fields = dict(FIELDS.findall(line))
tiles.append({key: int(fields.get(key, "0")) for key in CACHE_FIELDS})
if not tiles:
raise SystemExit(f"no LOD0-2 tile-cache counters in {log}")
total = {key: sum(tile[key] for tile in tiles) for key in CACHE_FIELDS}
row = {
"strate": 1, "workers": workers, "version": version,
"source_stamp": stamp.group(1), "tiles": len(tiles),
"totals": total,
"per_tile": {key: value / len(tiles) for key, value in total.items()},
"logs": str(log.relative_to(ROOT)),
}
rows.append(row)
print("[L138PrechangeIslandCache] " + json.dumps(row, sort_keys=True), flush=True)
(OUT / "summary.json").write_text(json.dumps(rows, indent=2) + "\n")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,73 +0,0 @@
#!/usr/bin/env python3
"""Run the 16-seed composed passage and seam audits on the L138 candidate."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l138/seeds"
BIN = ROOT / "Saved/Linux/l138/bin/VoxelForgeCoreHeadless-l138-clang"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "9aade4e6cb33e86c36b89440644d9ef5d440288fb6ff0af03af128291c95f93f"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
REQUIRED = {
"passage": re.compile(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", re.M),
"seams": re.compile(r"^\[PassageTileSeamAudit\].*status=PASS$", re.M),
"shell": re.compile(r"^\[PassageShellAuditSummary\].*status=PASS$", re.M),
"naturalness": re.compile(r"^\[PassageNaturalnessSummary\].*status=PASS$", re.M),
"mouth_profile": re.compile(r"^\[PassageMouthProfileSummary\].*status=PASS$", re.M),
"ripple": re.compile(r"^\[PassageRippleAuditSummary\].*status=PASS$", re.M),
"route_negative_control": re.compile(
r"^\[TunnelNetworkBlockedRouteControl\].*expected=FAIL status=PASS$", re.M),
}
def main() -> int:
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L138 Clang binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
results = []
for seed in range(16):
log = OUT / f"seed{seed}.log"
layout = OUT / f"seed{seed}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=0",
"--force-generate", f"--seed={seed}", "--recipe=surface-world",
"--audit-resolved-layout-passages", "--audit-passage-tile-seams",
f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
checks = {name: bool(pattern.search(content)) for name, pattern in REQUIRED.items()}
checks["source_stamp"] = stamp is not None and stamp.group(1) == STAMP
blocked = re.findall(r"^\[ResolvedPassageBlockedControl\].*detected=true$",
content, re.M)
checks["three_blocked_controls"] = len(blocked) == 3
passed = proc.returncode == 0 and all(checks.values())
row = {"seed": seed, "exit": proc.returncode, "passed": passed,
"checks": checks, "blocked_controls": len(blocked),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
results.append(row)
print("[L138SeedSweep] " + json.dumps(row, sort_keys=True), flush=True)
(OUT / "runs-partial.json").write_text(json.dumps(results, indent=2) + "\n")
if not passed:
raise SystemExit(f"seed {seed} failed composed audits; see {log}")
summary = {"source_stamp": STAMP, "seeds": list(range(16)),
"passed": len(results), "failed": 0, "results": results}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
print("[L138SeedSweepSummary] passed=16/16 status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,92 +0,0 @@
# Linux139 — Vertical Shafts on the Core planner
## Result
S3 now reports `Core.Caves.PrimitiveField` / `Caves-native`, using the shared Tunnel Network
planner. The composed acceptance gate is not green: **15/16 seeds pass; seed 2 fails the passage
shell and tile seam checks at the arrival from passage 2–3.** This worktree is not promoted as an
accepted Vertical Shafts generator.
The basal primordial route law means arrival passage 2–3 to a walkable terminal landing above the
bedrock seal. There is no departure mouth at the bottom of the owner world. The shared planner
builds that walk-only spine, its access tunnels, and landings within the existing grade contract.
The full-height open shafts and their ledges are an exploration tier: a drop or climb is not
walk-only traversal, and climb or mine access stays in the reporting tiers. `Core.Lattice` was not
used because L58's VerticalShafts lattice route looked like a corkscrew, not an open shaft.
## Plan and parameter mapping
`PlanResolvedCavernNetworkV1` is reused without a planner fork. `Core.Caves.PrimitiveField` is the
shared evaluator, extended with `shapeKind=1`: the existing room/tunnel shapes do not represent a
capped, full-height vertical bore, and the L58 lattice route was a corkscrew. Shaft records use
that cylinder primitive with ledges, short access bores, and cross-shaft links. Generic cave
branches are disabled in shaft mode.
| `FVerticalShaftParams` field(s) | Core setting |
|---|---|
| `ShaftSpacing` | Shared planner room spacing; owner voxels convert to integer micrometres. |
| `ShaftDensity` | `roomDensityQ16`, controlling shaft placement; a nonzero setting guarantees the route's initial shaft. |
| `ShaftMinRadius`, `ShaftMaxRadius` | Minimum and maximum shaft radii. |
| `CrossConnectChance` | `tunnelDensityQ16` for links between shafts. |
| `ConnectorRadius` | Equal minimum/maximum radius for access and connector bores. |
| `LedgeSpacing`, `LedgeDepth` | Vertical shelf interval and intrusion; zero spacing disables shelves and zero depth makes them nonintrusive. |
| `SurfaceRoughness` | Roughness amplitude; frequency derives as `max(0.5 m, 4 owner voxels)` because no frequency field exists. |
| `BoundarySealThickness`, `BaseDensity` | Existing resolved top/basal boundary bands via `sealAndDensity`, outside planner settings. |
## Measurements
The final source stamp was `b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1`.
The composed sweep covered seeds 0–15 with one run per seed (reported process time 320.485 s in
total; individual runs 10.296–34.015 s). Seeds 0, 1, and 3–15 passed passages, route, seams, shell,
and blocked-route controls. Seed 2's route grades/support, naturalness, mouth profile, ripple,
dispatch, and negative controls passed; its composed passage, seam, and shell summaries failed.
The shell audit reported eight `wall_missing` samples on `passage/2-3/0`, at route stations
489.627–490.321 m. The final log records positive native density at those samples and negative
wall-shell margins. See `Saved/Linux/l139/seeds/seed2-final.log` and
`Saved/Linux/l139/seeds/summary.json`.
Three geometry variants were tried against this same shell gate: starting passage clearance at
12 m, adding a guarded cubic lateral bow, and starting clearance at 8 m. The first and third still
failed wall checks; the bow failed floor checks. Per the three-failure stop rule, these were
discarded. The final binary retains the successful Q16 endpoint-normalization correction needed
for seed 1 and no seed-2 geometry patch.
L80 ran after the seed sweep. The host gate was **load 1.31, CPU idle 99.4%**. It used one warm-up
per build and stratum/worker cell, then five interleaved measured runs for each of three builds at
W8 and W12 across all four strata: 120 measured runs total. Comparisons use `fa4417a`,
`assembler/world`, and the L139 binary; the established L137 A/A noise floor is ±1% ([A/A report](../Linux137/REPORT.md)).
Times are medians in seconds; deltas are L139 relative to each comparison build. Paired values in
each cell are W8 / W12.
| Stratum | LOD0–2 L139 | Δ vs `fa4417a` | Δ vs `assembler/world` | Whole-view L139 | Δ vs `fa4417a` | Δ vs `assembler/world` |
|---|---:|---:|---:|---:|---:|---:|
| S0 Surface World | 0.838 / 0.886 | +1.71% / +3.97% | +2.92% / +5.06% | 1.862 / 1.804 | +2.42% / +1.63% | −0.11% / −0.33% |
| S1 Floating Islands | 1.036 / 1.038 | +4.72% / +4.61% | +2.09% / +5.35% | 1.842 / 1.830 | +0.11% / +1.16% | −6.73% / −1.24% |
| S2 Tunnel Network | 1.105 / 1.078 | +2.44% / +3.07% | +3.57% / +7.57% | 1.876 / 1.808 | −1.11% / +0.00% | −4.33% / −1.15% |
| S3 Vertical Shafts | 0.899 / 0.884 | −3.81% / −0.94% | −0.95% / +2.00% | 1.706 / 1.657 | −6.57% / −2.53% | −6.21% / −4.77% |
Whole-view medians are numerically lower than `assembler/world` in all eight cells; the S0 W8 and
W12 differences are within the ±1% noise floor. Seven of eight LOD0–2 cells are slower than
`assembler/world`; the remaining cell is within the noise floor. This is characterization of an
unaccepted build, not a promotion claim. Raw runs and medians are in
`Saved/Linux/l139/timing/summary.json`.
## Checks and captures
- Fast tier: **PASS**, 284.0 s; the S3 dispatch line is `VerticalShafts` → `Core.Caves.PrimitiveField` v1 / `Caves-native` / `FCavesFieldAdapter`.
- Clang and GCC determinism: **PASS**, W1/W8/W12 (six cases), 13 hash lines and resolved-layout identity matched. Both compilers built the final source stamp above.
- Canonical v237 baselines added for Surface World and Floating Islands; both match their v236 values.
- Five eye-height views were captured before and after: arrival mouth, shaft access landing, looking down, looking up from a ledge, and basal terminal landing. All five L139 views pass the existing quality threshold. Two L138 baseline views fail it: the old layer has no shaft at the selected site, so the down-shaft view is flat, and the upward view is low contrast. The threshold was not relaxed. Images and camera details are in `captures/`.
- The outside views are `captures/after-whole-layer-density-cutaway.jpg` (coarse LOD density-mesh slice at y=−5 m) and `captures/after-whole-layer-side-elevation.svg` (resolved-plan projection that labels the walk route and all 53 shaft primitives). The cutaway passes the unchanged image-quality threshold; its plan companion makes the full shaft layout clearer.
- Linux `VFHostEditor` Development build: **PASS**, 27 actions, 72.58 s, run after timing with `-NoUBA -MaxParallelActions=4` and no `prlimit`. It emitted three pre-existing deprecated RealtimeMesh API warnings from `VoxelWorld.cpp`; that file was not changed.
- `git diff --check` and Python bytecode compilation of the L139 runners passed. Windows build and Windows determinism were not run.
Logs and source-stamped binaries are under `Saved/Linux/l139/`. The only changed Unreal `Source/`
file is `Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp`.
## Remaining risk
The passage shell and seam break at the incoming mouth on seed 2 remain unresolved. The local
clearance/heading premise failed three geometry attempts; a new route-to-mouth design premise is
needed before another geometry change. Walk-only connectivity stays guaranteed by construction;
vertical drops, climbs, and mine access remain reporting tiers.
@@ -1,278 +0,0 @@
#!/usr/bin/env python3
"""Capture comparable player-height views of the L138 and L139 owner shaft layer."""
from __future__ import annotations
import json
import math
import os
from pathlib import Path
import re
import subprocess
import sys
import time
ROOT = Path(__file__).resolve().parents[4]
DATA = ROOT / "Standalone/data/owner_world.json"
LAYOUT = ROOT / "Saved/Linux/l139/seeds/seed0.json"
OUT = ROOT / "Saved/Linux/l139/captures"
ARTIFACTS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux139/captures"
LIMIT = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--"]
VERSIONS = {
"before-l138": {
"headless": ROOT / "Saved/Linux/l138/bin/VoxelForgeCoreHeadless-l138-clang",
"renderer": ROOT / "Saved/Linux/l138/bin/VoxelForgeOffscreenCapture-l138-clang",
"stamp": "9aade4e6cb33e86c36b89440644d9ef5d440288fb6ff0af03af128291c95f93f",
},
"after-l139": {
"headless": ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-clang",
"renderer": ROOT / "Saved/Linux/l139/bin/VoxelForgeOffscreenCapture-l139-clang",
"stamp": "b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1",
},
}
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]{64})$", re.M)
def fmt(values: tuple[float, ...]) -> str:
return ",".join(f"{value:.6f}" for value in values)
def angles(camera: tuple[float, float, float],
target: tuple[float, float, float]) -> tuple[float, float]:
dx, dy, dz = (target[i] - camera[i] for i in range(3))
return math.degrees(math.atan2(dx, dy)), math.degrees(
math.atan2(dz, math.hypot(dx, dy)))
def stamped_run(name: str, command: list[str], log: Path, expected: str,
env: dict[str, str]) -> str:
binary = Path(command[0])
probe = subprocess.run([*LIMIT, "timeout", "15s", str(binary), "--print-source-stamp"],
cwd=ROOT, env=env, text=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, check=False, timeout=20)
match = STAMP_RE.search(probe.stdout or "")
if probe.returncode != 0 or not match or match.group(1) != expected:
raise RuntimeError(f"{name}: executable stamp mismatch for {binary}")
log.parent.mkdir(parents=True, exist_ok=True)
started = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run([*LIMIT, "timeout", "1740s", *map(str, command)],
cwd=ROOT, env=env, stdout=stream, stderr=subprocess.STDOUT,
timeout=1745, check=False)
output = log.read_text(encoding="utf-8", errors="replace")
emitted = STAMP_RE.search(output)
if (result.returncode != 0 or not emitted or emitted.group(1) != expected):
raise RuntimeError(f"{name}: process failed or source changed; see {log}")
print(f"[L139CaptureRun] step={name} elapsed_s={time.monotonic()-started:.1f} "
f"log={log.relative_to(ROOT)}", flush=True)
return output
def point_um(values: list[int]) -> tuple[float, float, float]:
return tuple(value / 1_000_000.0 for value in values)
def make_views(layout: dict) -> list[dict]:
edges = {row["stable_id"]: row for row in layout["cavern_edges"]}
rooms = {row["stable_id"]: row for row in layout["cavern_rooms"]}
shaft = rooms["vertical-shafts/strate-3/shaft-0/primitive-0"]
access = edges["vertical-shafts/strate-3/shaft-access-0"]["polyline_um"]
arrival = edges["vertical-shafts/strate-3/route-edge-0"]["polyline_um"]
basal = rooms["vertical-shafts/strate-3/basal-landing/primitive-0"]
center = point_um(shaft["center_um"])
half = point_um(shaft["half_extents_um"])
shaft_top = center[2] + half[2]
shaft_bottom = center[2] - half[2]
route_a, route_b = point_um(arrival[0]), point_um(arrival[1])
tx, ty = route_b[0] - route_a[0], route_b[1] - route_a[1]
tlen = max(1.0e-9, math.hypot(tx, ty))
tangent = (tx / tlen, ty / tlen)
mouth_camera = (route_a[0] - tangent[0] * 2.0,
route_a[1] - tangent[1] * 2.0, route_a[2] + 1.45)
mouth_target = (route_a[0] + tangent[0] * 8.0,
route_a[1] + tangent[1] * 8.0, route_a[2] + 1.45)
access_a, access_b = point_um(access[0]), point_um(access[-1])
access_camera = (access_a[0], access_a[1], access_a[2] + 1.45)
access_target = (access_b[0], access_b[1], access_b[2] + 1.45)
shaft_lip_camera = (access_b[0], access_b[1], access_b[2] + 1.45)
basal_center = point_um(basal["center_um"])
basal_camera = (basal_center[0], basal_center[1], basal["floor_um"] / 1.0e6 + 1.45)
basal_target = (basal_center[0] + tangent[0] * 8.0,
basal_center[1] + tangent[1] * 8.0, basal_camera[2])
ledge_z = shaft_top - 12 * (shaft["ledge_spacing_um"] / 1.0e6)
return [
{"name": "arrival-mouth", "camera": mouth_camera, "target": mouth_target,
"focus": (route_a[0], route_a[1], route_a[2] + 1.4, 12.0),
"note": "player eye at the passage arrival, looking into the connected layer"},
{"name": "landing-at-shaft-access", "camera": access_camera,
"target": access_target,
"focus": (center[0], center[1], access_a[2], 14.0),
"note": "walkable route landing and short shaft access tunnel"},
{"name": "looking-down-shaft", "camera": shaft_lip_camera,
"target": (center[0], center[1], shaft_top - 30.0),
"focus": (center[0], center[1], shaft_top - 25.0, 14.0),
"fov": 35.0,
"note": "player eye at the upper access landing, looking down the open shaft"},
{"name": "looking-up-from-ledge", "camera": (center[0], center[1], ledge_z + 1.45),
"target": (center[0], center[1], shaft_top - 2.0),
"focus": (center[0], center[1], shaft_top - 22.0, 20.0),
"note": "player eye at an internal ledge, looking up; reaching this ledge is a climb tier"},
{"name": "basal-terminal-landing", "camera": basal_camera,
"target": basal_target,
"focus": (basal_center[0], basal_center[1], basal_center[2], 16.0),
"note": "walkable terminal landing above the basal seal"},
]
def write_overview(layout: dict, destination: Path) -> None:
shafts = [room for room in layout["cavern_rooms"] if room.get("shape_kind") == 1]
route_edges = sorted((edge for edge in layout["cavern_edges"]
if edge["stable_id"].startswith("vertical-shafts/strate-3/route-edge-")),
key=lambda edge: int(edge["stable_id"].rsplit("-", 1)[1]))
if not shafts or not route_edges:
raise ValueError("overview needs the resolved shaft primitives and walk route")
points = [point_um(row) for edge in route_edges for row in edge["polyline_um"]]
shaft_x_bounds = [(point_um(room["center_um"])[0]
-room["half_extents_um"][0]/1e6,
point_um(room["center_um"])[0]+room["half_extents_um"][0]/1e6)
for room in shafts]
x_min = min(min(bounds[0] for bounds in shaft_x_bounds),
min(row[0] for row in points))
x_max = max(x + room["half_extents_um"][0] / 1e6
for room in shafts for x in [point_um(room["center_um"])[0]])
x_max = max(x_max, max(row[0] for row in points))
z_min = min(point_um(room["center_um"])[2] - room["half_extents_um"][2] / 1e6
for room in shafts)
z_max = max(point_um(room["center_um"])[2] + room["half_extents_um"][2] / 1e6
for room in shafts)
z_min = min(z_min, min(row[2] for row in points))
z_max = max(z_max, max(row[2] for row in points))
width, height, margin = 1800.0, 760.0, 72.0
sx = (width - 2 * margin) / max(1.0, x_max - x_min)
sz = (height - 2 * margin) / max(1.0, z_max - z_min)
scale = min(sx, sz)
x_offset = margin + ((width - 2 * margin) - (x_max - x_min) * scale) * 0.5
z_offset = margin + ((height - 2 * margin) - (z_max - z_min) * scale) * 0.5
def xy(x: float, z: float) -> tuple[float, float]:
return x_offset + (x - x_min) * scale, height - (z_offset + (z - z_min) * scale)
route_xy = [xy(p[0], p[2]) for p in points]
route = " ".join(("M" if i == 0 else "L") + f"{x:.2f},{y:.2f}"
for i, (x, y) in enumerate(route_xy))
cylinders = []
for room in shafts:
x, _y, z = point_um(room["center_um"])
radius = room["half_extents_um"][0] / 1e6
half_z = room["half_extents_um"][2] / 1e6
left, top = xy(x - radius, z + half_z)
right, bottom = xy(x + radius, z - half_z)
cylinders.append(f'<rect x="{left:.2f}" y="{top:.2f}" width="{max(1.2,right-left):.2f}" '
f'height="{bottom-top:.2f}" rx="{min(7.0,(right-left)/2):.2f}" '
'fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/>')
rx0, ry0 = xy(x_min, 0.0)
rx1, ry1 = xy(x_max, 0.0)
svg = f'''<svg xmlns="http://www.w3.org/2000/svg" width="1800" height="760" viewBox="0 0 1800 760">
<rect width="1800" height="760" fill="#07111a"/>
<text x="72" y="42" fill="#edf6fb" font-family="sans-serif" font-size="24">Vertical Shafts — whole-layer side elevation</text>
<text x="72" y="64" fill="#9bb5c5" font-family="sans-serif" font-size="13">Resolved plan • seed 0 • strate 3 • vertical axis and route shown in metres • Y projected out</text>
<line x1="{rx0:.1f}" y1="{ry0:.1f}" x2="{rx1:.1f}" y2="{ry1:.1f}" stroke="#315060" stroke-dasharray="5 8"/>
{''.join(cylinders)}
<path d="{route}" fill="none" stroke="#f4bf68" stroke-width="3.0" stroke-linecap="round" stroke-linejoin="round"/>
<text x="82" y="716" fill="#f4bf68" font-family="sans-serif" font-size="15">walk-only graded spine and landings</text>
<rect x="416" y="704" width="15" height="15" fill="#93dded" fill-opacity="0.65" stroke="#42b8d1"/>
<text x="440" y="716" fill="#b8dce5" font-family="sans-serif" font-size="15">open vertical shaft primitives (53)</text>
<text x="1718" y="716" fill="#9bb5c5" text-anchor="end" font-family="sans-serif" font-size="12">Plan projection, not a density mesh</text>
</svg>'''
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_text(svg, encoding="utf-8")
def main() -> int:
if not DATA.is_file() or not LAYOUT.is_file():
raise SystemExit("missing owner fixture or passing seed-0 resolved layout")
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
views = make_views(layout)
OUT.mkdir(parents=True, exist_ok=True)
ARTIFACTS.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(OUT / "xdg-cache")
quality = ROOT / "Standalone/Tools/verify/capture_quality.py"
manifest = []
quality_failures = []
for version, config in VERSIONS.items():
phase = "before" if version.startswith("before") else "after"
for view in views:
name = view["name"]
camera, target = view["camera"], view["target"]
yaw, pitch = angles(camera, target)
mesh_dir = OUT / "meshes" / phase
mesh_dir.mkdir(parents=True, exist_ok=True)
mesh = mesh_dir / f"{name}.vfmesh"
capture_layout = mesh_dir / f"{name}-layout.json"
export_log = OUT / f"{phase}-{name}-export.log"
export = [config["headless"], DATA, "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=12",
"--clip-radius=6", "--max-clip-level=0", "--max-level=0",
"--force-generate", "--seed=0", "--recipe=surface-world",
"--render-distance-chunks=0", f"--camera={fmt((*camera,yaw,pitch))}",
f"--resolved-layout-output={capture_layout}", f"--mesh-export={mesh}"]
stamped_run(f"{phase}-{name}-export", list(map(str, export)), export_log,
config["stamp"], env)
if not mesh.is_file() or mesh.stat().st_size == 0:
raise RuntimeError(f"{phase}-{name}: empty mesh export")
png = OUT / f"{phase}-{name}.png"
jpg = ARTIFACTS / f"{phase}-{name}.jpg"
fov = float(view.get("fov", 78.0))
render = [config["renderer"], mesh, png, "--size=1280x720",
f"--fov-deg={fov:.1f}", f"--camera-m={fmt(camera)}", f"--yaw-deg={yaw:.6f}",
f"--pitch-deg={pitch:.6f}", "--tile-skirts=off", "--shade=readable",
"--headlamp=on", "--height-tint=on", "--height-center-m=-950",
"--height-range-m=60", "--tile-edges=off",
f"--focus-region={fmt(view['focus'])}"]
stamped_run(f"{phase}-{name}-render", list(map(str, render)),
OUT / f"{phase}-{name}-render.log", config["stamp"], env)
jpeg = ["ffmpeg", "-nostdin", "-hide_banner", "-loglevel", "error", "-y",
"-i", png, "-frames:v", "1", "-q:v", "4", jpg]
subprocess.run([*LIMIT, "timeout", "120s", *map(str, jpeg)], cwd=ROOT,
env=env, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT,
timeout=125)
check = subprocess.run([*LIMIT, "timeout", "120s", sys.executable,
quality, jpg], cwd=ROOT, env=env, text=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, check=False, timeout=125)
quality_ok = check.returncode == 0 and "status=PASS" in check.stdout
quality_result = (check.stdout.strip().splitlines()[-1]
if check.stdout.strip() else f"quality command exit={check.returncode}")
if not quality_ok:
quality_failures.append(f"{phase}-{name}")
manifest.append({"phase": phase, "view": name, "file": str(jpg.relative_to(ROOT)),
"bytes": jpg.stat().st_size, "camera_m": camera, "target_m": target,
"yaw_deg": yaw, "pitch_deg": pitch, "fov_deg": fov,
"note": view["note"],
"quality_status": "PASS" if quality_ok else "FAIL",
"quality": quality_result})
print(f"[L139Capture] phase={phase} view={name} file={jpg.relative_to(ROOT)} "
f"bytes={jpg.stat().st_size} quality={'PASS' if quality_ok else 'FAIL'}",
flush=True)
overview = ARTIFACTS / "after-whole-layer-side-elevation.svg"
write_overview(layout, overview)
manifest.append({"phase": "after", "view": "whole-layer-side-elevation",
"file": str(overview.relative_to(ROOT)), "shafts": sum(
room.get("shape_kind") == 1 for room in layout["cavern_rooms"]),
"walk_route_edges": len([edge for edge in layout["cavern_edges"]
if edge["stable_id"].startswith("vertical-shafts/strate-3/route-edge-")]),
"note": "resolved-plan side projection; not a density-mesh capture"})
(ARTIFACTS / "manifest.json").write_text(json.dumps(manifest, indent=2) + "\n",
encoding="utf-8")
status = "PASS" if not quality_failures else "FAIL"
print(f"[L139CaptureSummary] spot_views={len(views)} comparisons={len(views)*2} "
f"whole_layer_projection=1 quality_failures={len(quality_failures)} "
f"status={status}", flush=True)
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as error:
print(f"[L139CaptureFailure] {error}", file=sys.stderr, flush=True)
raise SystemExit(1)
@@ -1,86 +0,0 @@
#!/usr/bin/env python3
"""Compare composed owner hashes and resolved graph identity at W1/W8/W12."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l139/determinism"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1"
BINARIES = {
"clang": ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-clang",
"gcc": ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-gcc",
}
CAMERA = "-20.062500,-5.068359,-900.353516,0,0"
HASH_RE = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|MaterialHash|LODHash|ExactQueryHash)\].*$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing L139 determinism binary or composed owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
rows = []
reference_hashes: tuple[str, ...] | None = None
reference_layout_identity: str | None = None
for compiler, binary in BINARIES.items():
for workers in (1, 8, 12):
name = f"determinism-{compiler}-w{workers}"
log, layout = OUT / f"{name}.log", OUT / f"{name}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=0",
f"--camera={CAMERA}", "--stream-hash", "--force-generate", "--seed=0",
"--recipe=surface-world", "--render-distance-chunks=0",
"--density-dispatch-report", f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
hashes = tuple(HASH_RE.findall(content))
current_layout = json.loads(layout.read_text(encoding="utf-8"))
stable_identity = current_layout.get("stable_identity")
dispatch_ok = bool(re.search(
r"^\[DensityDispatch\] strate=3 generator=VerticalShafts "
r"recipe=Core\.Caves\.PrimitiveField version=1 "
r"bound_path=Caves-native adapter=FCavesFieldAdapter$", content, re.M))
passed = (proc.returncode == 0 and stamp is not None and stamp.group(1) == STAMP
and len(hashes) >= 4 and dispatch_ok and bool(stable_identity))
if reference_hashes is None and passed:
reference_hashes = hashes
reference_layout_identity = stable_identity
else:
passed = (passed and hashes == reference_hashes
and stable_identity == reference_layout_identity)
row = {"compiler": compiler, "workers": workers, "exit": proc.returncode,
"stamp": stamp.group(1) if stamp else None, "hash_lines": len(hashes),
"hashes_match_first": hashes == reference_hashes,
"layout_identity": stable_identity,
"layout_matches_first": stable_identity == reference_layout_identity,
"shaft_dispatch": dispatch_ok, "passed": bool(passed),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
rows.append(row)
print("[L139DeterminismRun] " + json.dumps(row, sort_keys=True), flush=True)
(OUT / "runs-partial.json").write_text(json.dumps(rows, indent=2) + "\n")
if not passed:
raise SystemExit(f"composed owner determinism mismatch; see {log}")
(OUT / "summary.json").write_text(json.dumps({"status": "PASS", "stamp": STAMP,
"layout_identity": reference_layout_identity, "runs": rows}, indent=2) + "\n")
print(f"[L139DeterminismSummary] runs={len(rows)} source_stamp={STAMP} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,167 +0,0 @@
#!/usr/bin/env python3
"""Run interleaved L80 timings for L139, fa4417a, and assembler/world."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l139/timing"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": (
ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-a",
"4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621"),
"fa4417a": (
ROOT / "Saved/Linux/l138/bin/VoxelForgeCoreHeadless-l138-clang",
"9aade4e6cb33e86c36b89440644d9ef5d440288fb6ff0af03af128291c95f93f"),
"l139": (
ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-clang",
"b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1"),
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
binary, expected_stamp = BINARIES[version]
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--stream-scheduler-policy=3",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near, stamp = PIPELINE.search(content), NEAR.search(content), STAMP.search(content)
if (proc.returncode or pipeline is None or near is None or stamp is None
or stamp.group(1) != expected_stamp):
raise SystemExit(f"L80 timing failed or stamp mismatch: {log}; exit={proc.returncode}")
fields = dict(FIELDS.findall(pipeline.group(1)))
row = {
"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "source_stamp": stamp.group(1),
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(fields["whole_tiles"].split("/")[0]),
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)),
}
print("[L139FinalTimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def main() -> int:
if any(not path.is_file() for path in [DATA, *(entry[0] for entry in BINARIES.values())]):
raise SystemExit("missing L139 timing input")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L139FinalTimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 1.5 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows = []
for strate in range(4):
for workers in (8, 12):
for version in BINARIES:
run(strate, workers, version, "warmup", 0)
for replicate in range(1, 6):
order = tuple(BINARIES)
order = order[replicate % 3:] + order[:replicate % 3]
if replicate % 2 == 0:
order = tuple(reversed(order))
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
measured = [row for row in rows if row["phase"] == "measured"]
summary = []
for strate in range(4):
for workers in (8, 12):
group = [row for row in measured
if row["strate"] == strate and row["workers"] == workers]
medians = {
version: {
key: statistics.median(row[key] for row in group
if row["version"] == version)
for key in ("lod02_ready_s", "whole_view_ready_s")
}
for version in BINARIES
}
entry = {"strate": strate, "workers": workers,
"replicates_per_version": 5, "medians": medians}
for key in ("lod02_ready_s", "whole_view_ready_s"):
for baseline in ("fa4417a", "assembler-world"):
entry[f"l139_vs_{baseline}_{key}_delta_pct"] = round(
100.0 * (medians["l139"][key] / medians[baseline][key] - 1.0), 2)
entry[f"l139_vs_fa4417a_{key}_paired_deltas_pct"] = [
round(100.0 * (
next(row[key] for row in group
if row["version"] == "l139" and row["replicate"] == replicate)
/ next(row[key] for row in group
if row["version"] == "fa4417a" and row["replicate"] == replicate)
- 1.0), 3) for replicate in range(1, 6)]
entry[f"l139_vs_assembler-world_{key}_paired_deltas_pct"] = [
round(100.0 * (
next(row[key] for row in group
if row["version"] == "l139" and row["replicate"] == replicate)
/ next(row[key] for row in group
if row["version"] == "assembler-world"
and row["replicate"] == replicate) - 1.0), 3)
for replicate in range(1, 6)]
summary.append(entry)
(OUT / "summary.json").write_text(json.dumps({
"a_a_noise_floor_pct": 1.0,
"fa4417a_commit": "fa4417a",
"timing_protocol": (
"one warmup per binary, five interleaved runs, W8/W12, all four owner layers"),
"runs": rows,
"summary": summary,
}, indent=2) + "\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,107 +0,0 @@
#!/usr/bin/env python3
"""Audit the composed owner world, including the basal Vertical Shafts route."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l139/seeds"
BIN = ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-clang"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
REQUIRED = {
"passages": re.compile(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", re.M),
"route": re.compile(
r"^\[ResolvedStrateRouteAudit\] strate=3 .*unsupported=0 grade_failures=0 .*status=PASS$",
re.M),
"seams": re.compile(r"^\[PassageTileSeamAudit\].*status=PASS$", re.M),
"shell": re.compile(r"^\[PassageShellAuditSummary\].*status=PASS$", re.M),
"naturalness": re.compile(r"^\[PassageNaturalnessSummary\].*status=PASS$", re.M),
"mouth_profile": re.compile(r"^\[PassageMouthProfileSummary\].*status=PASS$", re.M),
"ripple": re.compile(r"^\[PassageRippleAuditSummary\].*status=PASS$", re.M),
"shaft_dispatch": re.compile(
r"^\[DensityDispatch\] strate=3 generator=VerticalShafts "
r"recipe=Core\.Caves\.PrimitiveField version=1 "
r"bound_path=Caves-native adapter=FCavesFieldAdapter$", re.M),
"shaft_blocked_route": re.compile(
r"^\[VerticalShaftsBlockedRouteControl\].*expected=FAIL status=PASS$", re.M),
}
def main() -> int:
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L139 Clang binary or composed owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
results = []
partial = OUT / "runs-partial.json"
if partial.is_file():
for prior in json.loads(partial.read_text(encoding="utf-8")):
seed = len(results)
if prior.get("seed") != seed:
break
log = ROOT / prior.get("log", "")
layout = ROOT / prior.get("layout", "")
if not log.is_file() or not layout.is_file():
break
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
checks = {name: bool(pattern.search(content))
for name, pattern in REQUIRED.items()}
checks["source_stamp"] = stamp is not None and stamp.group(1) == STAMP
checks["blocked_passage_controls"] = len(re.findall(
r"^\[ResolvedPassageBlockedControl\].*detected=true$", content, re.M)) == 3
checks["passage_count"] = len(re.findall(
r"^\[ResolvedPassageAudit\].*walkability=PASS$", content, re.M)) == 3
passed = prior.get("exit") == 0 and all(checks.values())
if checks != prior.get("checks") or passed != prior.get("passed"):
break
results.append(prior)
print(f"[L139SeedSweepResume] reused={len(results)} source_stamp={STAMP}",
flush=True)
for seed in range(len(results), 16):
log = OUT / f"seed{seed}.log"
layout = OUT / f"seed{seed}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=8", "--clip-radius=3",
"--max-clip-level=8", "--max-level=0", "--force-generate", f"--seed={seed}",
"--recipe=surface-world", "--density-dispatch-report",
"--audit-resolved-layout-passages", "--audit-passage-tile-seams",
f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
checks = {name: bool(pattern.search(content)) for name, pattern in REQUIRED.items()}
checks["source_stamp"] = stamp is not None and stamp.group(1) == STAMP
checks["blocked_passage_controls"] = len(re.findall(
r"^\[ResolvedPassageBlockedControl\].*detected=true$", content, re.M)) == 3
checks["passage_count"] = len(re.findall(
r"^\[ResolvedPassageAudit\].*walkability=PASS$", content, re.M)) == 3
passed = proc.returncode == 0 and all(checks.values())
row = {"seed": seed, "exit": proc.returncode, "passed": passed,
"checks": checks, "elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
results.append(row)
print("[L139SeedSweep] " + json.dumps(row, sort_keys=True), flush=True)
partial.write_text(json.dumps(results, indent=2) + "\n")
passed_count = sum(row["passed"] for row in results)
failed_count = len(results) - passed_count
summary = {"source_stamp": STAMP, "seeds": list(range(len(results))),
"passed": passed_count, "failed": failed_count, "results": results}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
print(f"[L139SeedSweepSummary] passed={passed_count}/16 failed={failed_count} "
f"status={'PASS' if len(results)==16 and failed_count==0 else 'FAIL'}")
return 0 if len(results) == 16 and failed_count == 0 else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,110 +0,0 @@
#!/usr/bin/env python3
"""Render a coarse whole-strate cutaway from the L139 density mesh."""
from __future__ import annotations
import json
import os
from pathlib import Path
import re
import subprocess
import sys
import time
ROOT = Path(__file__).resolve().parents[4]
DATA = ROOT / "Standalone/data/owner_world.json"
BIN = ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-clang"
RENDERER = ROOT / "Saved/Linux/l139/bin/VoxelForgeOffscreenCapture-l139-clang"
OUT = ROOT / "Saved/Linux/l139/captures"
ARTIFACTS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux139/captures"
STAMP = "b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]{64})$", re.M)
LIMIT = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--"]
SLICE_Y = -5.0
CAMERA = (-450.0, SLICE_Y - 100.0, -950.0)
YAW, PITCH, FOV = 0.0, 0.0, 70.0
def stamped_run(label: str, command: list[str], log: Path, env: dict[str, str]) -> str:
probe = subprocess.run([*LIMIT, "timeout", "15s", str(command[0]), "--print-source-stamp"],
cwd=ROOT, env=env, text=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, check=False, timeout=20)
match = STAMP_RE.search(probe.stdout or "")
if probe.returncode != 0 or not match or match.group(1) != STAMP:
raise RuntimeError(f"{label}: source stamp mismatch")
log.parent.mkdir(parents=True, exist_ok=True)
started = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run([*LIMIT, "timeout", "1740s", *map(str, command)],
cwd=ROOT, env=env, stdout=stream, stderr=subprocess.STDOUT,
timeout=1745, check=False)
content = log.read_text(encoding="utf-8", errors="replace")
emitted = STAMP_RE.search(content)
if result.returncode != 0 or not emitted or emitted.group(1) != STAMP:
raise RuntimeError(f"{label}: process failed or source changed; see {log}")
print(f"[L139WholeLayerCapture] step={label} elapsed_s={time.monotonic()-started:.1f} "
f"log={log.relative_to(ROOT)}", flush=True)
return content
def main() -> int:
if not DATA.is_file() or not BIN.is_file() or not RENDERER.is_file():
raise SystemExit("missing owner fixture or final L139 capture binaries")
OUT.mkdir(parents=True, exist_ok=True)
ARTIFACTS.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(OUT / "xdg-cache")
stem = "whole-layer-density-cutaway"
mesh = OUT / f"{stem}.vfmesh"
layout = OUT / f"{stem}-layout.json"
camera_text = ",".join(f"{value:.6f}" for value in (*CAMERA, YAW, PITCH))
export = [BIN, DATA, "--world-assembler-prototype", "--stream-benchmark",
"--stream-pipeline", "--workers=12", "--clip-radius=3", "--max-clip-level=8",
"--max-level=8", "--force-generate", "--seed=0", "--recipe=surface-world",
"--render-distance-chunks=0", "--capture-skip-walkability", "--density-dispatch-report",
f"--camera={camera_text}", f"--resolved-layout-output={layout}", f"--mesh-export={mesh}"]
content = stamped_run("export", export, OUT / f"{stem}-export.log", env)
dispatch = re.search(
r"^\[DensityDispatch\] strate=3 generator=VerticalShafts "
r"recipe=Core\.Caves\.PrimitiveField version=1 "
r"bound_path=Caves-native adapter=FCavesFieldAdapter$", content, re.M)
if not dispatch or not mesh.is_file() or mesh.stat().st_size == 0:
raise RuntimeError("coarse density export is empty or lacks native shaft dispatch")
png = OUT / f"{stem}.png"
jpg = ARTIFACTS / "after-whole-layer-density-cutaway.jpg"
render = [RENDERER, mesh, png, "--size=2200x320", f"--fov-deg={FOV:.1f}",
"--camera-m=" + ",".join(f"{value:.6f}" for value in CAMERA),
f"--yaw-deg={YAW:.6f}", f"--pitch-deg={PITCH:.6f}",
f"--clip-plane=0,-1,0,{SLICE_Y:.6f}", "--tile-skirts=off", "--shade=readable",
"--headlamp=on", "--height-tint=off", "--height-center-m=-950",
"--height-range-m=80", "--tile-edges=off"]
stamped_run("render", render, OUT / f"{stem}-render.log", env)
subprocess.run([*LIMIT, "timeout", "120s", "ffmpeg", "-nostdin", "-hide_banner",
"-loglevel", "error", "-y", "-i", png, "-frames:v", "1", "-q:v", "3", jpg],
cwd=ROOT, env=env, check=True, stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT, timeout=125)
quality = subprocess.run([*LIMIT, "timeout", "120s", sys.executable,
ROOT / "Standalone/Tools/verify/capture_quality.py", jpg], cwd=ROOT, env=env,
text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
check=False, timeout=125)
quality_line = quality.stdout.strip().splitlines()[-1] if quality.stdout.strip() else ""
ok = quality.returncode == 0 and "status=PASS" in quality_line
manifest_path = ARTIFACTS / "manifest.json"
manifest = json.loads(manifest_path.read_text(encoding="utf-8")) if manifest_path.is_file() else []
manifest = [row for row in manifest if row.get("view") != "whole-layer-density-cutaway"]
manifest.append({"phase": "after", "view": "whole-layer-density-cutaway",
"file": str(jpg.relative_to(ROOT)), "bytes": jpg.stat().st_size,
"camera_m": CAMERA, "target_m": (-450.0, SLICE_Y, -950.0),
"yaw_deg": YAW, "pitch_deg": PITCH, "fov_deg": FOV,
"clip_plane": [0.0, -1.0, 0.0, SLICE_Y],
"note": "outside side cutaway through the coarse LOD density mesh across the whole Vertical Shafts strate at y=-5 m",
"quality_status": "PASS" if ok else "FAIL", "quality": quality_line})
manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
print(f"[L139WholeLayerCaptureSummary] file={jpg.relative_to(ROOT)} "
f"quality={'PASS' if ok else 'FAIL'} {quality_line}", flush=True)
return 0 if ok else 1
if __name__ == "__main__":
raise SystemExit(main())
Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

@@ -1,12 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1800" height="760" viewBox="0 0 1800 760">
<rect width="1800" height="760" fill="#07111a"/>
<text x="72" y="42" fill="#edf6fb" font-family="sans-serif" font-size="24">Vertical Shafts — whole-layer side elevation</text>
<text x="72" y="64" fill="#9bb5c5" font-family="sans-serif" font-size="13">Resolved plan • seed 0 • strate 3 • vertical axis and route shown in metres • Y projected out</text>
<line x1="72.0" y1="-1440.6" x2="1728.0" y2="-1440.6" stroke="#315060" stroke-dasharray="5 8"/>
<rect x="1707.84" y="284.18" width="4.65" height="191.65" rx="2.33" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1667.56" y="288.45" width="5.72" height="187.37" rx="2.86" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1245.04" y="344.01" width="6.24" height="131.81" rx="3.12" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1206.94" y="349.61" width="5.68" height="126.22" rx="2.84" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1188.40" y="352.41" width="4.37" height="123.41" rx="2.18" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1168.07" y="355.22" width="6.64" height="120.60" rx="3.32" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1130.81" y="360.85" width="4.40" height="114.97" rx="2.20" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1092.31" y="366.48" width="4.62" height="109.35" rx="2.31" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1072.90" y="369.29" width="5.04" height="106.54" rx="2.52" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1053.43" y="372.09" width="5.61" height="103.74" rx="2.80" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1034.94" y="374.88" width="4.20" height="100.94" rx="2.10" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1015.20" y="377.67" width="5.28" height="98.16" rx="2.64" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1648.28" y="290.59" width="5.89" height="185.23" rx="2.95" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="995.75" y="380.44" width="5.81" height="95.38" rx="2.90" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="976.77" y="383.20" width="5.37" height="92.62" rx="2.68" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="938.19" y="388.67" width="5.75" height="87.15" rx="2.88" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="918.75" y="391.38" width="6.25" height="84.44" rx="3.13" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="896.89" y="394.44" width="6.22" height="81.38" rx="3.11" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="880.62" y="396.74" width="5.74" height="79.09" rx="2.87" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="862.36" y="399.38" width="3.87" height="76.45" rx="1.94" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="842.60" y="401.99" width="5.01" height="73.83" rx="2.50" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="804.64" y="407.14" width="4.16" height="68.69" rx="2.08" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="785.14" y="409.66" width="4.77" height="66.16" rx="2.39" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1629.77" y="292.79" width="4.53" height="183.04" rx="2.26" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="765.24" y="412.16" width="6.18" height="63.67" rx="3.09" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="746.73" y="414.61" width="4.82" height="61.21" rx="2.41" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="727.40" y="417.04" width="5.08" height="58.79" rx="2.54" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="707.91" y="419.42" width="5.68" height="56.41" rx="2.84" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="669.16" y="424.06" width="6.41" height="51.77" rx="3.20" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="650.97" y="426.31" width="4.40" height="49.51" rx="2.20" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="593.65" y="432.79" width="3.89" height="43.04" rx="1.94" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="573.84" y="434.85" width="5.11" height="40.98" rx="2.56" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="478.04" y="444.31" width="4.78" height="31.52" rx="2.39" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="440.09" y="447.66" width="3.90" height="28.16" rx="1.95" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="1590.94" y="297.31" width="5.40" height="178.52" rx="2.70" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rect x="420.88" y="449.24" width="3.93" height="26.58" rx="1.97" fill="#93dded" fill-opacity="0.45" stroke="#42b8d1" stroke-width="1.2"/><rLine truncated
<path d="M1728.00,290.01 L1716.48,291.19 L1716.48,291.19 L1710.17,291.85 L1710.17,291.85 L1689.61,294.04 L1689.61,294.04 L1670.42,296.13 L1670.42,296.13 L1651.23,298.27 L1651.23,298.27 L1632.03,300.46 L1632.03,300.46 L1612.84,302.70 L1612.84,302.70 L1593.65,304.98 L1593.65,304.98 L1574.45,307.31 L1574.45,307.31 L1555.26,309.68 L1555.26,309.68 L1536.07,312.09 L1536.07,312.09 L1516.87,314.53 L1516.87,314.53 L1497.68,317.01 L1497.68,317.01 L1478.49,319.53 L1478.49,319.53 L1459.29,322.07 L1459.29,322.07 L1440.10,324.65 L1440.10,324.65 L1420.91,327.26 L1420.91,327.26 L1401.71,329.89 L1401.71,329.89 L1382.52,332.55 L1382.52,332.55 L1363.33,335.23 L1363.33,335.23 L1344.13,337.93 L1344.13,337.93 L1324.94,340.65 L1324.94,340.65 L1305.74,343.39 L1305.74,343.39 L1286.55,346.14 L1286.55,346.14 L1267.36,348.91 L1267.36,348.91 L1248.16,351.69 L1248.16,351.69 L1228.97,354.48 L1228.97,354.48 L1209.78,357.28 L1209.78,357.28 L1190.58,360.09 L1190.58,360.09 L1171.39,362.90 L1171.39,362.90 L1152.20,365.71 L1152.20,365.71 L1133.00,368.53 L1133.00,368.53 L1113.81,371.34 L1113.81,371.34 L1094.62,374.16 L1094.62,374.16 L1075.42,376.97 L1075.42,376.97 L1056.23,379.77 L1056.23,379.77 L1037.04,382.56 L1037.04,382.56 L1017.84,385.35 L1017.84,385.35 L998.65,388.12 L998.65,388.12 L979.46,390.88 L979.46,390.88 L960.26,393.62 L960.26,393.62 L941.07,396.35 L941.07,396.35 L921.88,399.06 L921.88,399.06 L902.68,401.75 L902.68,401.75 L900.00,402.12 L900.00,402.12 L883.49,404.41 L883.49,404.41 L864.30,407.05 L864.30,407.05 L845.10,409.67 L845.10,409.67 L825.91,412.26 L825.91,412.26 L806.72,414.82 L806.72,414.82 L787.52,417.34 L787.52,417.34 L768.33,419.83 L768.33,419.83 L749.14,422.29 L749.14,422.29 L729.94,424.71 L729.94,424.71 L710.75,427.09 L710.75,427.09 L691.56,429.44 L691.56,429.44 L672.36,431.73 L672.36,431.73 L653.17,433.99 L653.17,433.99 L633.98,436.20 L633.98,436.20 L614.78,438.36 L614.78,438.36 L595.59,440.47 L595.59,440.47 L576.39,442.53 L576.39,442.53 L557.20,444.53 L557.20,444.53 L538.01,446.48 L538.01,446.48 L518.81,448.37 L518.81,448.37 L499.62,450.21 L499.62,450.21 L480.43,451.98 L480.43,451.98 L461.23,453.69 L461.23,453.69 L442.04,455.34 L442.04,455.34 L422.85,456.92 L422.85,456.92 L403.65,458.43 L403.65,458.43 L384.46,459.88 L384.46,459.88 L365.27,461.25 L365.27,461.25 L346.07,462.55 L346.07,462.55 L326.88,463.77 L326.88,463.77 L307.69,464.91 L307.69,464.91 L288.49,465.98 L288.49,465.98 L269.30,466.97 L269.30,466.97 L250.11,467.87 L250.11,467.87 L230.91,468.69 L230.91,468.69 L211.72,469.42 L211.72,469.42 L192.53,470.06 L192.53,470.06 L173.33,470.62 L173.33,470.62 L154.14,471.08 L154.14,471.08 L134.95,471.45 L134.95,471.45 L115.75,471.73 L115.75,471.73 L96.56,471.90 L96.56,471.90 L89.83,471.94 L89.83,471.94 L83.52,471.97 L83.52,471.97 L77.37,471.98 L77.37,471.98 L72.00,471.99" fill="none" stroke="#f4bf68" stroke-width="3.0" stroke-linecap="round" stroke-linejoin="round"/>
<text x="82" y="716" fill="#f4bf68" font-family="sans-serif" font-size="15">walk-only graded spine and landings</text>
<rect x="416" y="704" width="15" height="15" fill="#93dded" fill-opacity="0.65" stroke="#42b8d1"/>
<text x="440" y="716" fill="#b8dce5" font-family="sans-serif" font-size="15">open vertical shaft primitives (53)</text>
<text x="1718" y="716" fill="#9bb5c5" text-anchor="end" font-family="sans-serif" font-size="12">Plan projection, not a density mesh</text>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

@@ -1,258 +0,0 @@
[
{
"phase": "before",
"view": "arrival-mouth",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/before-arrival-mouth.jpg",
"bytes": 21788,
"camera_m": [
-20.0625,
-5.068359,
-900.237499
],
"target_m": [
-30.0625,
-5.068359,
-900.237499
],
"yaw_deg": -90.0,
"pitch_deg": 0.0,
"fov_deg": 78.0,
"note": "player eye at the passage arrival, looking into the connected layer",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/before-arrival-mouth.jpg pixels=921600 mean_luma=110.102 stddev_luma=3.380 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "before",
"view": "landing-at-shaft-access",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/before-landing-at-shaft-access.jpg",
"bytes": 15114,
"camera_m": [
-31.354577,
-5.068359,
-901.1982009999999
],
"target_m": [
-31.354577,
-9.889916,
-901.1982009999999
],
"yaw_deg": 180.0,
"pitch_deg": 0.0,
"fov_deg": 78.0,
"note": "walkable route landing and short shaft access tunnel",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/before-landing-at-shaft-access.jpg pixels=921600 mean_luma=110.563 stddev_luma=3.056 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "before",
"view": "looking-down-shaft",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/before-looking-down-shaft.jpg",
"bytes": 11005,
"camera_m": [
-31.354577,
-9.889916,
-901.1982009999999
],
"target_m": [
-31.354577,
-10.852462,
-928.6482010000001
],
"yaw_deg": 180.0,
"pitch_deg": -87.99172181188044,
"fov_deg": 35.0,
"note": "player eye at the upper access landing, looking down the open shaft",
"quality_status": "FAIL",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/before-looking-down-shaft.jpg pixels=921600 mean_luma=112.000 stddev_luma=0.000 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=FAIL"
},
{
"phase": "before",
"view": "looking-up-from-ledge",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/before-looking-up-from-ledge.jpg",
"bytes": 15507,
"camera_m": [
-31.354577,
-10.852462,
-945.198201
],
"target_m": [
-31.354577,
-10.852462,
-900.6482010000001
],
"yaw_deg": 0.0,
"pitch_deg": 90.0,
"fov_deg": 78.0,
"note": "player eye at an internal ledge, looking up; reaching this ledge is a climb tier",
"quality_status": "FAIL",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/before-looking-up-from-ledge.jpg pixels=921600 mean_luma=111.693 stddev_luma=1.515 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=FAIL"
},
{
"phase": "before",
"view": "basal-terminal-landing",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/before-basal-terminal-landing.jpg",
"bytes": 13933,
"camera_m": [
-884.858259,
-5.068359,
-995.05
],
"target_m": [
-892.858259,
-5.068359,
-995.05
],
"yaw_deg": -90.0,
"pitch_deg": 0.0,
"fov_deg": 78.0,
"note": "walkable terminal landing above the basal seal",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/before-basal-terminal-landing.jpg pixels=921600 mean_luma=108.996 stddev_luma=6.932 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "after",
"view": "arrival-mouth",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/after-arrival-mouth.jpg",
"bytes": 19044,
"camera_m": [
-20.0625,
-5.068359,
-900.237499
],
"target_m": [
-30.0625,
-5.068359,
-900.237499
],
"yaw_deg": -90.0,
"pitch_deg": 0.0,
"fov_deg": 78.0,
"note": "player eye at the passage arrival, looking into the connected layer",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/after-arrival-mouth.jpg pixels=921600 mean_luma=125.004 stddev_luma=16.734 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "after",
"view": "landing-at-shaft-access",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/after-landing-at-shaft-access.jpg",
"bytes": 15595,
"camera_m": [
-31.354577,
-5.068359,
-901.1982009999999
],
"target_m": [
-31.354577,
-9.889916,
-901.1982009999999
],
"yaw_deg": 180.0,
"pitch_deg": 0.0,
"fov_deg": 78.0,
"note": "walkable route landing and short shaft access tunnel",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/after-landing-at-shaft-access.jpg pixels=921600 mean_luma=117.622 stddev_luma=14.149 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "after",
"view": "looking-down-shaft",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/after-looking-down-shaft.jpg",
"bytes": 24396,
"camera_m": [
-31.354577,
-9.889916,
-901.1982009999999
],
"target_m": [
-31.354577,
-10.852462,
-928.6482010000001
],
"yaw_deg": 180.0,
"pitch_deg": -87.99172181188044,
"fov_deg": 35.0,
"note": "player eye at the upper access landing, looking down the open shaft",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/after-looking-down-shaft.jpg pixels=921600 mean_luma=112.365 stddev_luma=3.113 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "after",
"view": "looking-up-from-ledge",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/after-looking-up-from-ledge.jpg",
"bytes": 23172,
"camera_m": [
-31.354577,
-10.852462,
-945.198201
],
"target_m": [
-31.354577,
-10.852462,
-900.6482010000001
],
"yaw_deg": 0.0,
"pitch_deg": 90.0,
"fov_deg": 78.0,
"note": "player eye at an internal ledge, looking up; reaching this ledge is a climb tier",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/after-looking-up-from-ledge.jpg pixels=921600 mean_luma=111.549 stddev_luma=2.538 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "after",
"view": "basal-terminal-landing",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/after-basal-terminal-landing.jpg",
"bytes": 12527,
"camera_m": [
-884.858259,
-5.068359,
-995.05
],
"target_m": [
-892.858259,
-5.068359,
-995.05
],
"yaw_deg": -90.0,
"pitch_deg": 0.0,
"fov_deg": 78.0,
"note": "walkable terminal landing above the basal seal",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/after-basal-terminal-landing.jpg pixels=921600 mean_luma=125.238 stddev_luma=3.555 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"phase": "after",
"view": "whole-layer-side-elevation",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/after-whole-layer-side-elevation.svg",
"shafts": 53,
"walk_route_edges": 91,
"note": "resolved-plan side projection; not a density-mesh capture"
},
{
"phase": "after",
"view": "whole-layer-density-cutaway",
"file": "Standalone/Research/WorldAssemblerM3/Linux139/captures/after-whole-layer-density-cutaway.jpg",
"bytes": 20280,
"camera_m": [
-450.0,
-105.0,
-950.0
],
"target_m": [
-450.0,
-5.0,
-950.0
],
"yaw_deg": 0.0,
"pitch_deg": 0.0,
"fov_deg": 70.0,
"clip_plane": [
0.0,
-1.0,
0.0,
-5.0
],
"note": "outside side cutaway through the coarse LOD density mesh across the whole Vertical Shafts strate at the denser shaft row",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux139/captures/after-whole-layer-density-cutaway.jpg pixels=704000 mean_luma=113.286 stddev_luma=3.364 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
}
]
@@ -1,34 +0,0 @@
# L140 — Floating Islands planned around passages
**Not accepted: 0/16 composed seeds passed.** The new Core recipe reaches native S1 dispatch and meets its dedicated route, passage-clearance, and mouth-support checks on seeds 0 and 10. Seed 10 still has one blocked capsule in the composed owner route; both seeds fail the unchanged passage-ripple gate. Fourteen seeds cannot produce a corridor-aware plan.
## Change
Core evaluator version is 239 and Floating Islands geometry version is 10. The owner adapter resolves the fixed passage layout first, then plans nine native islands and a walk route around the 0–1 arrival and 1–2 departure tubes. The plan records route and island anchors in the resolved layout. The clearance check reserves the 1.053 m passage influence reach plus the 0.880 m capsule half-height and checks five support probes at each mouth. Shape composition preserves native landing support and passage shell distance for this recipe. Direct legacy recipe fixtures retain their earlier attach-before-layout order.
S1 binds to `FloatingIslands-native` in the explicit Core owner mode. `bUseVoxelForgeCore` remains opt-in; the fast-tier default owner pose still reports the legacy analytic S1 path.
## Composed sweep
The final-source Clang run covered seeds 0–15. Results and per-seed logs are in [`summary.json`](../../../../Saved/Linux/l140/seeds/summary.json) and `Saved/Linux/l140/seeds/` (source stamp `6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da`).
- **Seed 0:** the planner tried 11 detours; its 94.5 m route has 1.47 m conservative tube clearance. Native route audit: 128 points, 0 blocked capsule samples, 0 unsupported points, 0 grade failures. Passage check: 5,325 tube samples, 0 island conflicts, 676,275 route checks, 0 route conflicts, arrival and departure support 5/5, 2.824 m minimum excess clearance. The composed S1 route and seams pass. Ripple is 1/3: wall ripple is 6.85 cm on 0–1 and 7.10 cm on 1–2 against the unchanged 3.50 cm limit.
- **Seed 10:** the native route and passage checks pass, with 5/5 mouth support and 0 isolated route conflicts. The composed S1 capsule audit finds one blocked sample at `(-6.246, -28.615, -737.982) m`, inside the resolved 0–1 passage; composed density is `-0.002062` while native island density is `+1.730469`. Ripple is again 1/3 (6.22 cm on 0–1 and 7.19 cm on 1–2). Seams and negative controls pass.
- **Seeds 1, 2, 7, 8, 9, 12, 13, 15:** no candidate clears the tubes; best conservative clearances range from −5.994 m to −0.406 m. **Seeds 3, 5, 6, 14:** candidates clear the tubes but the supported island profile cannot reach both fixed mouth heights. **Seeds 4 and 11:** candidate islands escape the sealed vertical layout.
The dedicated gate is therefore 0/16. No geometry variant was attempted after these results. The repeated 0–1/1–2 ripple failure is also consistent with L67's closed authored-radius experiment: it measured 7.27 cm on 1–2 against the same 3.50 cm limit ([L67 report](../../Linux67/REPORT.md)).
## Other checks
- **Fast tier:** PASS, 287.8 s; negative controls and existing worker-hash checks passed. It continues to verify the default legacy S1 dispatch.
- **Determinism:** PASS, six runs (Clang/GCC × W1/W8/W12). All produced the same 512-tile density, mesh, payload, topology, material, and exact-query hashes, with layout identity `resolved-layout-v3-fnv64:08da20d55ff6820f`. Native recipe hash: `0b6a23bc73a3b867`. See the [baseline](baselines/native-owner-fi-seed0.json) and [`summary.json`](../../../../Saved/Linux/l140/determinism/summary.json).
- **Captures:** ten before/after JPEGs passed the existing image-quality gate. The [manifest](captures/manifest.json) records eye-height arrival, island edge, route between islands, departure, and wide silhouette views for both versions. See [before](captures/before-arrival-mouth.jpg), [before edge](captures/before-island-edge.jpg), [before route](captures/before-walk-between-islands.jpg), [before departure](captures/before-departure-mouth.jpg), [before wide](captures/before-wide-silhouette.jpg); [after](captures/after-arrival-mouth.jpg), [after edge](captures/after-island-edge.jpg), [after route](captures/after-walk-between-islands.jpg), [after departure](captures/after-departure-mouth.jpg), [after wide](captures/after-wide-silhouette.jpg).
- **Linux VFHostEditor:** PASS in 73.58 s. Build log: [`ubt.log`](../../../../Saved/Linux/l140/ubt.log).
- **L80 timing:** not completed. The machine gate passed (load 0.97, 2-second CPU idle 98.5%), but the candidate warm-up could not construct native S1 around the checked-in Unreal-exported passage layout: 0 detours, best clearance −3.509 m. No measured L80 pairs were recorded; the ±1% A/A floor remains the L137 reference. A separate 30-second setup probe with a regenerated seed-0 owner plan timed out during passage-route planning, so I did not run a mismatched or incomplete timing matrix.
- `git diff --check`: PASS.
## Remaining issues
The fixed exported owner layout and many generated seeds leave no route-clear island arrangement. On seed 10, the native-only clearance check also misses a collision that the final composed owner route catches. Ripple remains above the existing limit on both upper passages. Native S1 is still opt-in and is not promoted by this round.
Changed Unreal source: [`VoxelForgeCoreAdapter.cpp`](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp). Windows compilation remains for the owner.
@@ -1,224 +0,0 @@
#!/usr/bin/env python3
"""Capture comparable player-height and wide views of owner S1 before and after L140."""
from __future__ import annotations
import json
import argparse
import math
import os
import re
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
DATA = ROOT / "Standalone/data/owner_world.json"
LAYOUT = ROOT / "Saved/Linux/l140/seeds/seed0-composed-layout.json"
OUT = ROOT / "Saved/Linux/l140/captures"
ARTIFACTS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux140/captures"
LIMIT = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--"]
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]{64})$", re.M)
VERSIONS = {
"before-head": {
"headless": ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-clang",
"renderer": ROOT / "Saved/Linux/l139/bin/VoxelForgeOffscreenCapture-l139-clang",
"stamp": "b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1",
"native": False,
},
"after-l140": {
"headless": ROOT / "Saved/Linux/l140/bin/VoxelForgeCoreHeadless-l140-clang",
"renderer": ROOT / "Saved/Linux/l140/bin/VoxelForgeOffscreenCapture-l140-clang",
"stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"native": True,
},
}
def fmt(values: tuple[float, ...]) -> str:
return ",".join(f"{value:.6f}" for value in values)
def angles(camera: tuple[float, float, float], target: tuple[float, float, float]) -> tuple[float, float]:
dx, dy, dz = (target[i] - camera[i] for i in range(3))
return math.degrees(math.atan2(dx, dy)), math.degrees(math.atan2(dz, math.hypot(dx, dy)))
def stamped_run(name: str, command: list[str], log: Path, expected: str,
env: dict[str, str]) -> str:
binary = Path(command[0])
probe = subprocess.run([*LIMIT, "timeout", "15s", str(binary), "--print-source-stamp"],
cwd=ROOT, env=env, text=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, check=False, timeout=20)
match = STAMP_RE.search(probe.stdout or "")
if probe.returncode != 0 or not match or match.group(1) != expected:
raise RuntimeError(f"{name}: executable stamp mismatch for {binary}")
log.parent.mkdir(parents=True, exist_ok=True)
started = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run([*LIMIT, "timeout", "1740s", *map(str, command)],
cwd=ROOT, env=env, stdout=stream, stderr=subprocess.STDOUT,
timeout=1745, check=False)
output = log.read_text(encoding="utf-8", errors="replace")
emitted = STAMP_RE.search(output)
if result.returncode != 0 or not emitted or emitted.group(1) != expected:
raise RuntimeError(f"{name}: process failed or source changed; see {log}")
print(f"[L140CaptureRun] step={name} elapsed_s={time.monotonic()-started:.1f} "
f"log={log.relative_to(ROOT)}", flush=True)
return output
def qpoint(values: list[int], scale_m: float) -> tuple[float, float, float]:
return tuple(value * scale_m for value in values[:3])
def make_views(layout: dict) -> list[dict[str, object]]:
scale_m = layout["core_voxel_size_um"] / 1_000_000.0 / 256.0
strate = next(row for row in layout["strates"] if row["strate_index"] == 1)
anchors = strate["anchors"]
route = [qpoint(row["values"], scale_m) for row in anchors if row["kind"] == "route_point"]
islands = [row for row in anchors if row["kind"] == "island_anchor"]
if len(route) < 8 or len(islands) < 5:
raise ValueError("seed-0 resolved layout lacks a complete S1 route or island chain")
def tangent(index: int) -> tuple[float, float]:
a, b = route[max(0, index - 1)], route[min(len(route) - 1, index + 1)]
dx, dy = b[0] - a[0], b[1] - a[1]
length = max(1e-9, math.hypot(dx, dy))
return dx / length, dy / length
def eye(point: tuple[float, float, float]) -> tuple[float, float, float]:
return point[0], point[1], point[2] + 1.45
i = len(route) // 3
tx, ty = tangent(i)
arrival_t = tangent(0)
departure_t = tangent(len(route) - 1)
arrival, departure = route[0], route[-1]
arrival_camera = eye((arrival[0] - 2.5 * arrival_t[0], arrival[1] - 2.5 * arrival_t[1], arrival[2]))
arrival_target = eye((arrival[0] + 8.0 * arrival_t[0], arrival[1] + 8.0 * arrival_t[1], arrival[2]))
departure_camera = eye((departure[0] - 2.5 * departure_t[0], departure[1] - 2.5 * departure_t[1], departure[2]))
departure_target = eye((departure[0] + 8.0 * departure_t[0], departure[1] + 8.0 * departure_t[1], departure[2]))
edge_point = route[i]
edge_camera = eye((edge_point[0] + 6.0 * ty, edge_point[1] - 6.0 * tx, edge_point[2]))
edge_target = (edge_point[0] + 4.0 * tx, edge_point[1] + 4.0 * ty, edge_point[2] + 0.35)
centers = [qpoint(row["values"], scale_m) for row in islands]
middle_index = len(route) // 2
midpoint = route[middle_index]
mid_t = tangent(middle_index)
walk_camera = eye((midpoint[0] - 2.0 * mid_t[0], midpoint[1] - 2.0 * mid_t[1], midpoint[2]))
next_island_index = min(len(centers) - 1, 5)
next_island_top = centers[next_island_index][2] + islands[next_island_index]["values"][4] * scale_m
walk_target = (centers[next_island_index][0], centers[next_island_index][1], next_island_top + 0.5)
walk_focus = tuple((centers[4][axis] + centers[5][axis]) * 0.5 for axis in range(3)) + (18.0,)
cx = sum(p[0] for p in centers) / len(centers)
cy = sum(p[1] for p in centers) / len(centers)
cz = sum(p[2] + row["values"][4] * scale_m for p, row in zip(centers, islands)) / len(centers)
wide_camera = (cx, cy + 23.0, cz + 10.0)
wide_target = (cx, cy, cz)
return [
{"name": "arrival-mouth", "camera": arrival_camera, "target": arrival_target,
"focus": (*arrival, 14.0), "note": "player eye at the fixed 0-1 arrival mouth"},
{"name": "island-edge", "camera": edge_camera, "target": edge_target,
"focus": (*edge_point, 18.0), "note": "player eye beside the route on an island edge"},
{"name": "walk-between-islands", "camera": walk_camera, "target": walk_target,
"focus": walk_focus, "note": "player eye looking from one route landing toward the next island"},
{"name": "departure-mouth", "camera": departure_camera, "target": departure_target,
"focus": (*departure, 14.0), "note": "player eye approaching the fixed 1-2 departure mouth"},
{"name": "wide-silhouette", "camera": wide_camera, "target": wide_target,
"focus": (cx, cy, cz, 48.0), "fov": 72.0,
"note": "wide side view showing the island chain silhouette"},
]
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--views", nargs="*", default=None,
help="optional view names to rerender in both phases")
args = parser.parse_args()
if not DATA.is_file() or not LAYOUT.is_file():
raise SystemExit("missing owner fixture or final seed-0 resolved layout")
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
views = make_views(layout)
if args.views:
unknown = set(args.views) - {str(view["name"]) for view in views}
if unknown:
raise SystemExit(f"unknown capture views: {sorted(unknown)}")
views = [view for view in views if view["name"] in set(args.views)]
OUT.mkdir(parents=True, exist_ok=True)
ARTIFACTS.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(OUT / "xdg-cache")
quality = ROOT / "Standalone/Tools/verify/capture_quality.py"
manifest: list[dict[str, object]] = []
old_manifest_path = ARTIFACTS / "manifest.json"
existing = json.loads(old_manifest_path.read_text(encoding="utf-8")) \
if old_manifest_path.is_file() else {"captures": []}
rerendered = {str(view["name"]) for view in views}
for row in existing.get("captures", []):
if row.get("view") not in rerendered:
manifest.append(row)
for version, config in VERSIONS.items():
phase = "before" if version.startswith("before") else "after"
for view in views:
name = str(view["name"])
camera, target = view["camera"], view["target"]
assert isinstance(camera, tuple) and isinstance(target, tuple)
yaw, pitch = angles(camera, target)
mesh_dir = OUT / "meshes" / phase
mesh_dir.mkdir(parents=True, exist_ok=True)
mesh = mesh_dir / f"{name}.vfmesh"
capture_layout = mesh_dir / f"{name}-layout.json"
flags = ["--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=12", "--clip-radius=6", "--max-clip-level=0", "--max-level=0",
"--force-generate", "--seed=0", "--recipe=surface-world",
"--render-distance-chunks=0", f"--camera={fmt((*camera,yaw,pitch))}",
f"--resolved-layout-output={capture_layout}", f"--mesh-export={mesh}"]
if config["native"]:
flags.extend(["--native-owner-fi", "--density-dispatch-report"])
export = [config["headless"], DATA, *flags]
stamped_run(f"{phase}-{name}-export", list(map(str, export)),
OUT / f"{phase}-{name}-export.log", config["stamp"], env)
if not mesh.is_file() or mesh.stat().st_size == 0:
raise RuntimeError(f"{phase}-{name}: empty mesh export")
png = OUT / f"{phase}-{name}.png"
jpg = ARTIFACTS / f"{phase}-{name}.jpg"
focus = view["focus"]
assert isinstance(focus, tuple)
fov = float(view.get("fov", 78.0))
render = [config["renderer"], mesh, png, "--size=1280x720",
f"--fov-deg={fov:.1f}", f"--camera-m={fmt(camera)}", f"--yaw-deg={yaw:.6f}",
f"--pitch-deg={pitch:.6f}", "--tile-skirts=off", "--shade=readable",
"--headlamp=on", "--height-tint=on", "--height-center-m=-740",
"--height-range-m=70", "--tile-edges=off", f"--focus-region={fmt(focus)}"]
stamped_run(f"{phase}-{name}-render", list(map(str, render)),
OUT / f"{phase}-{name}-render.log", config["stamp"], env)
subprocess.run([*LIMIT, "timeout", "120s", "ffmpeg", "-nostdin", "-hide_banner",
"-loglevel", "error", "-y", "-i", png, "-frames:v", "1", "-q:v", "4", jpg],
cwd=ROOT, env=env, check=True, stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT, timeout=125)
check = subprocess.run([*LIMIT, "timeout", "120s", sys.executable,
quality, jpg], cwd=ROOT, env=env, text=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, check=False, timeout=125)
result = check.stdout.strip().splitlines()[-1] if check.stdout.strip() else f"exit={check.returncode}"
ok = check.returncode == 0 and "status=PASS" in check.stdout
manifest.append({"phase": phase, "view": name, "file": str(jpg.relative_to(ROOT)),
"bytes": jpg.stat().st_size, "camera_m": camera, "target_m": target,
"yaw_deg": yaw, "pitch_deg": pitch, "fov_deg": fov,
"note": view["note"], "quality_status": "PASS" if ok else "FAIL", "quality": result})
print(f"[L140Capture] phase={phase} view={name} file={jpg.relative_to(ROOT)} "
f"quality={'PASS' if ok else 'FAIL'} {result}", flush=True)
manifest.sort(key=lambda row: (str(row["phase"]), str(row["view"])))
summary = {"seed": 0, "source_stamp": VERSIONS["after-l140"]["stamp"],
"before_stamp": VERSIONS["before-head"]["stamp"], "views_per_phase": 5,
"all_quality_pass": all(row["quality_status"] == "PASS" for row in manifest),
"captures": manifest}
(ARTIFACTS / "manifest.json").write_text(json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print(f"[L140CaptureSummary] views_per_phase={len(views)} captures={len(manifest)} "
f"all_quality_pass={summary['all_quality_pass']}", flush=True)
return 0 if summary["all_quality_pass"] else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,100 +0,0 @@
#!/usr/bin/env python3
"""Check native Floating Islands owner identity and hashes at W1/W8/W12."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l140/determinism"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da"
BINARIES = {
"clang": ROOT / "Saved/Linux/l140/bin/VoxelForgeCoreHeadless-l140-clang",
"gcc": ROOT / "Saved/Linux/l140/bin/VoxelForgeCoreHeadless-l140-gcc",
}
CAMERA = "25.836914,3.199219,-737.000000,0,0"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
HASH_RE = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|MaterialHash|LODHash|ExactQueryHash)\].*$",
re.M)
NATIVE_FI = re.compile(
r"^\[DensityDispatch\] strate=1 generator=FloatingIslands "
r"recipe=FloatingIslands\.ClusterField version=10 "
r"bound_path=FloatingIslands-native adapter=FFloatingIslandFieldAdapter$", re.M)
FI_RECIPE_HASH = re.compile(r"^\[FloatingIslandWorldAssembly\].*recipe_hash=([0-9a-f]+) status=PASS$", re.M)
FI_CLEARANCE = re.compile(r"^\[FloatingIslandPassageClearance\].*status=PASS$", re.M)
FI_ROUTE_AUDIT = re.compile(r"^\[FloatingIslandRouteAudit\].*status=PASS$", re.M)
def main() -> int:
if not DATA.is_file() or any(not path.is_file() for path in BINARIES.values()):
raise SystemExit("missing L140 Clang/GCC determinism binary or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
rows: list[dict[str, object]] = []
reference_hashes: list[str] | None = None
reference_identity: str | None = None
for compiler, binary in BINARIES.items():
for workers in (1, 8, 12):
name = f"native-owner-fi-{compiler}-w{workers}"
log, layout = OUT / f"{name}.log", OUT / f"{name}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=0",
f"--camera={CAMERA}", "--stream-hash", "--force-generate", "--seed=0",
"--recipe=surface-world", "--native-owner-fi", "--render-distance-chunks=0",
"--density-dispatch-report", f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
hashes = HASH_RE.findall(content)
current_layout = json.loads(layout.read_text(encoding="utf-8")) if layout.is_file() else {}
identity = current_layout.get("stable_identity")
native_ok = bool(NATIVE_FI.search(content))
plan_ok = ("[FloatingIslandRouteAudit]" in content
and "[FloatingIslandPassageClearance]" in content)
recipe_hash = FI_RECIPE_HASH.search(content)
clearance = FI_CLEARANCE.search(content)
route_audit = FI_ROUTE_AUDIT.search(content)
passed = (proc.returncode == 0 and stamp is not None and stamp.group(1) == STAMP
and len(hashes) >= 4 and native_ok and plan_ok and recipe_hash is not None
and clearance is not None and route_audit is not None and bool(identity))
if reference_hashes is None and passed:
reference_hashes, reference_identity = hashes, identity
else:
passed = passed and hashes == reference_hashes and identity == reference_identity
row = {"compiler": compiler, "workers": workers, "exit": proc.returncode,
"source_stamp": stamp.group(1) if stamp else None, "hash_lines": hashes,
"layout_identity": identity, "native_fi_dispatch": native_ok,
"native_plan_audits": plan_ok, "floating_island_recipe_hash":
recipe_hash.group(1) if recipe_hash else None,
"passage_clearance_line": clearance.group(0) if clearance else None,
"route_audit_line": route_audit.group(0) if route_audit else None,
"passed": bool(passed),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
rows.append(row)
print("[L140DeterminismRun] " + json.dumps(row, sort_keys=True), flush=True)
(OUT / "runs-partial.json").write_text(json.dumps(rows, indent=2) + "\n")
if not passed:
(OUT / "summary.json").write_text(json.dumps({"status": "FAIL", "runs": rows}, indent=2) + "\n")
raise SystemExit(f"native owner determinism mismatch; see {log}")
summary = {"status": "PASS", "source_stamp": STAMP,
"layout_identity": reference_identity, "runs": rows}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
(ROOT / "Standalone/Research/WorldAssemblerM3/Linux140/baselines").mkdir(parents=True, exist_ok=True)
(ROOT / "Standalone/Research/WorldAssemblerM3/Linux140/baselines/native-owner-fi-seed0.json").write_text(
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print(f"[L140DeterminismSummary] runs={len(rows)} source_stamp={STAMP} status=PASS")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,111 +0,0 @@
#!/usr/bin/env python3
"""Run the composed L140 owner gates for all requested seeds."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l140/seeds"
BIN = ROOT / "Saved/Linux/l140/bin/VoxelForgeCoreHeadless-l140-clang"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
CHECKS = {
"native_dispatch": re.compile(
r"^\[DensityDispatch\] strate=1 generator=FloatingIslands "
r"recipe=FloatingIslands\.ClusterField version=10 "
r"bound_path=FloatingIslands-native adapter=FFloatingIslandFieldAdapter$", re.M),
"island_route": re.compile(r"^\[FloatingIslandRouteAudit\].*status=PASS$", re.M),
"passage_clearance": re.compile(r"^\[FloatingIslandPassageClearance\].*status=PASS$", re.M),
"strate1_route": re.compile(
r"^\[ResolvedStrateRouteAudit\] strate=1 .*blocked=0 .*unsupported=0 "
r"grade_failures=0 mouth_binding=PASS status=PASS$", re.M),
"route_summary": re.compile(
r"^\[ResolvedPassageAuditSummary\].*route_walkable=4 .*route_bindings=4 "
r"route_binding_failures=0 .*blocked_controls=3/3", re.M),
"passages": re.compile(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", re.M),
"shell": re.compile(r"^\[PassageShellAuditSummary\].*status=PASS$", re.M),
"naturalness": re.compile(r"^\[PassageNaturalnessSummary\].*status=PASS$", re.M),
"mouth_profile": re.compile(r"^\[PassageMouthProfileSummary\].*status=PASS$", re.M),
"ripple": re.compile(r"^\[PassageRippleAuditSummary\].*status=PASS$", re.M),
}
def run(seed: int, label: str, seams_only: bool) -> tuple[int, str, float]:
log = OUT / f"seed{seed}-{label}.log"
layout = OUT / f"seed{seed}-{label}-layout.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=8", "--clip-radius=3",
"--max-clip-level=8", "--max-level=0", "--force-generate", f"--seed={seed}",
"--recipe=surface-world", "--native-owner-fi", "--density-dispatch-report"]
command.append("--audit-passage-tile-seams" if seams_only else "--audit-resolved-layout-passages")
if not seams_only:
command.append("--audit-passage-tile-seams")
command.append(f"--resolved-layout-output={layout}")
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
return proc.returncode, str(log.relative_to(ROOT)), round(time.monotonic() - started, 3)
def main() -> int:
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L140 Clang binary or composed owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
results = []
for seed in range(16):
exit_code, log_name, elapsed = run(seed, "composed", False)
content = (ROOT / log_name).read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
checks = {name: bool(pattern.search(content)) for name, pattern in CHECKS.items()}
checks["source_stamp"] = stamp is not None and stamp.group(1) == STAMP
checks["blocked_controls"] = len(re.findall(
r"^\[ResolvedPassageBlockedControl\].*detected=true$", content, re.M)) == 3
checks["negative_controls"] = (
"[ResolvedLayoutValidatorControls] rejected=10/10 status=PASS" in content
and len(re.findall(r"^\[PassageNaturalnessNegativeControl\].*detected=true$",
content, re.M)) == 1
and len(re.findall(r"^\[PassageMouthProfileNegativeControl\].*detected=true$",
content, re.M)) == 1
and len(re.findall(r"^\[PassageFloorStepNegativeControl\].*detected=true$",
content, re.M)) == 3
and "synthetic_spheres_negative_control=DETECTED" in content
and "floor_beaded_negative_control=DETECTED" in content)
seam_match = re.search(r"^\[PassageTileSeamAudit\].*status=(PASS|FAIL)$", content, re.M)
seam_exit = exit_code
seam_log = log_name
seam_elapsed = 0.0
if seam_match is None:
seam_exit, seam_log, seam_elapsed = run(seed, "seams", True)
seam_content = (ROOT / seam_log).read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(seam_content)
checks["source_stamp"] &= stamp is not None and stamp.group(1) == STAMP
seam_match = re.search(
r"^\[PassageTileSeamAudit\].*status=(PASS|FAIL)$", seam_content, re.M)
content += "\n" + seam_content
checks["seams"] = seam_match is not None and seam_match.group(1) == "PASS"
all_gates = all(checks.values()) and exit_code == 0 and seam_exit == 0
row = {"seed": seed, "exit": exit_code, "seam_exit": seam_exit,
"passed": all_gates, "checks": checks,
"elapsed_s": elapsed + seam_elapsed, "log": log_name, "seam_log": seam_log}
results.append(row)
print("[L140SeedSweep] " + json.dumps(row, sort_keys=True), flush=True)
(OUT / "runs-partial.json").write_text(json.dumps(results, indent=2) + "\n")
passed = sum(row["passed"] for row in results)
summary = {"source_stamp": STAMP, "seeds": list(range(16)),
"passed": passed, "failed": 16 - passed, "results": results}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
print(f"[L140SeedSweepSummary] passed={passed}/16 failed={16-passed} status={'PASS' if passed==16 else 'FAIL'}",
flush=True)
return 0 if passed == 16 else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,153 +0,0 @@
#!/usr/bin/env python3
"""L80 timing: native L140 vs L139 HEAD and assembler/world, all owner strata."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l140/timing"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": (
ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-a",
"4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621"),
"head": (
ROOT / "Saved/Linux/l139/bin/VoxelForgeCoreHeadless-l139-clang",
"b8603b6cb3975ca0f9669759e4e2464561c557fdb7aa6836acef123ecf0b99d1"),
"l140-native-fi": (
ROOT / "Saved/Linux/l140/bin/VoxelForgeCoreHeadless-l140-clang",
"6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da"),
}
CAMERAS = {
# The camera override also selects the owner SurfaceWorld departure mouth.
# Hold XY to the seed-0 native-FI valid mouth so every layer/version shares one layout.
0: (25.8369140625, 3.19921875, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (25.8369140625, 3.19921875, -753.3740234375),
3: (25.8369140625, 3.19921875, -900.353515625),
}
PIPELINE_RE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS_RE = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR_RE = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]{64})$", re.M)
L140_AA_FLOOR_PCT = 1.0 # L137's same-binary A/A median control.
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict[str, object]:
binary, expected_stamp = BINARIES[version]
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--stream-scheduler-policy=3",
"--recipe=surface-world"]
if version == "l140-native-fi":
command.append("--native-owner-fi")
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near, stamp = PIPELINE_RE.search(content), NEAR_RE.search(content), STAMP_RE.search(content)
if (proc.returncode or pipeline is None or near is None or stamp is None
or stamp.group(1) != expected_stamp):
raise SystemExit(f"L80 run failed or stamp mismatch: {log}; exit={proc.returncode}")
if version == "l140-native-fi" and not re.search(
r"^\[FloatingIslandWorldAssembly\].*dispatch=FloatingIslands-native .*status=PASS$",
content, re.M):
raise SystemExit(f"candidate timing did not bind native FloatingIslands: {log}")
fields = dict(FIELDS_RE.findall(pipeline.group(1)))
row = {"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "source_stamp": stamp.group(1),
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(fields["whole_tiles"].split("/")[0]),
"wall_s": round(time.monotonic() - started, 3), "log": str(log.relative_to(ROOT))}
print("[L140TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
if any(not path.is_file() for path, _ in BINARIES.values()) or not DATA.is_file():
raise SystemExit("missing L80 timing binaries or owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L140TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 1.5 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows: list[dict[str, object]] = []
for strate in range(4):
for workers in (8, 12):
for version in BINARIES:
run(strate, workers, version, "warmup", 0)
for replicate in range(1, 6):
order = tuple(BINARIES)
order = order[replicate % len(order):] + order[:replicate % len(order)]
if replicate % 2 == 0:
order = tuple(reversed(order))
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(json.dumps(rows, indent=2) + "\n")
measured = [row for row in rows if row["phase"] == "measured"]
summary = []
for strate in range(4):
for workers in (8, 12):
group = [row for row in measured if row["strate"] == strate and row["workers"] == workers]
medians = {version: {key: statistics.median(
row[key] for row in group if row["version"] == version)
for key in ("lod02_ready_s", "whole_view_ready_s")} for version in BINARIES}
entry: dict[str, object] = {"strate": strate, "workers": workers,
"replicates_per_version": 5, "medians": medians}
for key in ("lod02_ready_s", "whole_view_ready_s"):
for baseline in ("head", "assembler-world"):
entry[f"l140_vs_{baseline}_{key}_delta_pct"] = round(
100.0 * (medians["l140-native-fi"][key] / medians[baseline][key] - 1.0), 2)
entry[f"l140_vs_{baseline}_{key}_paired_deltas_pct"] = [round(100.0 * (
next(row[key] for row in group if row["version"] == "l140-native-fi"
and row["replicate"] == replicate)
/ next(row[key] for row in group if row["version"] == baseline
and row["replicate"] == replicate) - 1.0), 3)
for replicate in range(1, 6)]
summary.append(entry)
result = {"a_a_noise_floor_pct": L140_AA_FLOOR_PCT,
"a_a_reference": "L137 same-binary median control; assembler/world source stamp",
"timing_protocol": "quiet machine; one warm-up per binary per cell; five interleaved measured runs; W8/W12; all four owner layers",
"machine": {"load_1m": load_1m, "cpu_idle_2s_pct": idle},
"source_stamps": {name: stamp for name, (_path, stamp) in BINARIES.items()},
"runs": rows, "summary": summary}
(OUT / "summary.json").write_text(json.dumps(result, indent=2) + "\n")
print(f"[L140TimingSummary] measured_runs={len(measured)} warmups=24 aa_floor_pct=1.0 status=PASS",
flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,201 +0,0 @@
{
"status": "PASS",
"source_stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"layout_identity": "resolved-layout-v3-fnv64:08da20d55ff6820f",
"runs": [
{
"compiler": "clang",
"workers": 1,
"exit": 0,
"source_stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"hash_lines": [
"[PipelineFullDetailHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineWholeViewHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineMaterialHash] tiles=512 material=0xc3cb5fcccf78f4ee",
"[PipelineLODHash] lod=0 tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineLODHash] lod=1 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=2 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=3 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=4 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=5 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=6 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=7 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=8 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineExactQueryHash] probes=9 density=0x74eac0457ddc2026 unclamped=0x74eac0457ddc2026 detail=0xefcba20c0c70c415 collision=0xdd5b083a1fa82cc7 path=direct-Core-queries"
],
"layout_identity": "resolved-layout-v3-fnv64:08da20d55ff6820f",
"native_fi_dispatch": true,
"native_plan_audits": true,
"passed": true,
"elapsed_s": 101.92,
"log": "Saved/Linux/l140/determinism/native-owner-fi-clang-w1.log",
"layout": "Saved/Linux/l140/determinism/native-owner-fi-clang-w1.json",
"floating_island_recipe_hash": "0b6a23bc73a3b867",
"passage_clearance_line": "[FloatingIslandPassageClearance] strate=1 tube_samples=5325 island_blocked=0 route_checks=676275 route_blocked=0 arrival_support=5/5 departure_support=5/5 clearance_excess_m=2.824 portal_exclusion_m=13.0 influence_reach_m=1.053 capsule_bound_m=0.880 status=PASS",
"route_audit_line": "[FloatingIslandRouteAudit] points=128 centers=911 capsule_samples=247792 blocked=0 support_samples=6961 unsupported=0 grade_failures=0 status=PASS"
},
{
"compiler": "clang",
"workers": 8,
"exit": 0,
"source_stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"hash_lines": [
"[PipelineFullDetailHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineWholeViewHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineMaterialHash] tiles=512 material=0xc3cb5fcccf78f4ee",
"[PipelineLODHash] lod=0 tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineLODHash] lod=1 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=2 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=3 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=4 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=5 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=6 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=7 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=8 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineExactQueryHash] probes=9 density=0x74eac0457ddc2026 unclamped=0x74eac0457ddc2026 detail=0xefcba20c0c70c415 collision=0xdd5b083a1fa82cc7 path=direct-Core-queries"
],
"layout_identity": "resolved-layout-v3-fnv64:08da20d55ff6820f",
"native_fi_dispatch": true,
"native_plan_audits": true,
"passed": true,
"elapsed_s": 68.892,
"log": "Saved/Linux/l140/determinism/native-owner-fi-clang-w8.log",
"layout": "Saved/Linux/l140/determinism/native-owner-fi-clang-w8.json",
"floating_island_recipe_hash": "0b6a23bc73a3b867",
"passage_clearance_line": "[FloatingIslandPassageClearance] strate=1 tube_samples=5325 island_blocked=0 route_checks=676275 route_blocked=0 arrival_support=5/5 departure_support=5/5 clearance_excess_m=2.824 portal_exclusion_m=13.0 influence_reach_m=1.053 capsule_bound_m=0.880 status=PASS",
"route_audit_line": "[FloatingIslandRouteAudit] points=128 centers=911 capsule_samples=247792 blocked=0 support_samples=6961 unsupported=0 grade_failures=0 status=PASS"
},
{
"compiler": "clang",
"workers": 12,
"exit": 0,
"source_stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"hash_lines": [
"[PipelineFullDetailHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineWholeViewHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineMaterialHash] tiles=512 material=0xc3cb5fcccf78f4ee",
"[PipelineLODHash] lod=0 tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineLODHash] lod=1 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=2 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=3 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=4 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=5 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=6 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=7 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=8 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineExactQueryHash] probes=9 density=0x74eac0457ddc2026 unclamped=0x74eac0457ddc2026 detail=0xefcba20c0c70c415 collision=0xdd5b083a1fa82cc7 path=direct-Core-queries"
],
"layout_identity": "resolved-layout-v3-fnv64:08da20d55ff6820f",
"native_fi_dispatch": true,
"native_plan_audits": true,
"passed": true,
"elapsed_s": 68.96,
"log": "Saved/Linux/l140/determinism/native-owner-fi-clang-w12.log",
"layout": "Saved/Linux/l140/determinism/native-owner-fi-clang-w12.json",
"floating_island_recipe_hash": "0b6a23bc73a3b867",
"passage_clearance_line": "[FloatingIslandPassageClearance] strate=1 tube_samples=5325 island_blocked=0 route_checks=676275 route_blocked=0 arrival_support=5/5 departure_support=5/5 clearance_excess_m=2.824 portal_exclusion_m=13.0 influence_reach_m=1.053 capsule_bound_m=0.880 status=PASS",
"route_audit_line": "[FloatingIslandRouteAudit] points=128 centers=911 capsule_samples=247792 blocked=0 support_samples=6961 unsupported=0 grade_failures=0 status=PASS"
},
{
"compiler": "gcc",
"workers": 1,
"exit": 0,
"source_stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"hash_lines": [
"[PipelineFullDetailHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineWholeViewHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineMaterialHash] tiles=512 material=0xc3cb5fcccf78f4ee",
"[PipelineLODHash] lod=0 tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineLODHash] lod=1 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=2 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=3 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=4 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=5 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=6 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=7 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=8 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineExactQueryHash] probes=9 density=0x74eac0457ddc2026 unclamped=0x74eac0457ddc2026 detail=0xefcba20c0c70c415 collision=0xdd5b083a1fa82cc7 path=direct-Core-queries"
],
"layout_identity": "resolved-layout-v3-fnv64:08da20d55ff6820f",
"native_fi_dispatch": true,
"native_plan_audits": true,
"passed": true,
"elapsed_s": 100.676,
"log": "Saved/Linux/l140/determinism/native-owner-fi-gcc-w1.log",
"layout": "Saved/Linux/l140/determinism/native-owner-fi-gcc-w1.json",
"floating_island_recipe_hash": "0b6a23bc73a3b867",
"passage_clearance_line": "[FloatingIslandPassageClearance] strate=1 tube_samples=5325 island_blocked=0 route_checks=676275 route_blocked=0 arrival_support=5/5 departure_support=5/5 clearance_excess_m=2.824 portal_exclusion_m=13.0 influence_reach_m=1.053 capsule_bound_m=0.880 status=PASS",
"route_audit_line": "[FloatingIslandRouteAudit] points=128 centers=911 capsule_samples=247792 blocked=0 support_samples=6961 unsupported=0 grade_failures=0 status=PASS"
},
{
"compiler": "gcc",
"workers": 8,
"exit": 0,
"source_stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"hash_lines": [
"[PipelineFullDetailHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineWholeViewHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineMaterialHash] tiles=512 material=0xc3cb5fcccf78f4ee",
"[PipelineLODHash] lod=0 tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineLODHash] lod=1 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=2 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=3 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=4 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=5 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=6 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=7 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=8 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineExactQueryHash] probes=9 density=0x74eac0457ddc2026 unclamped=0x74eac0457ddc2026 detail=0xefcba20c0c70c415 collision=0xdd5b083a1fa82cc7 path=direct-Core-queries"
],
"layout_identity": "resolved-layout-v3-fnv64:08da20d55ff6820f",
"native_fi_dispatch": true,
"native_plan_audits": true,
"passed": true,
"elapsed_s": 70.398,
"log": "Saved/Linux/l140/determinism/native-owner-fi-gcc-w8.log",
"layout": "Saved/Linux/l140/determinism/native-owner-fi-gcc-w8.json",
"floating_island_recipe_hash": "0b6a23bc73a3b867",
"passage_clearance_line": "[FloatingIslandPassageClearance] strate=1 tube_samples=5325 island_blocked=0 route_checks=676275 route_blocked=0 arrival_support=5/5 departure_support=5/5 clearance_excess_m=2.824 portal_exclusion_m=13.0 influence_reach_m=1.053 capsule_bound_m=0.880 status=PASS",
"route_audit_line": "[FloatingIslandRouteAudit] points=128 centers=911 capsule_samples=247792 blocked=0 support_samples=6961 unsupported=0 grade_failures=0 status=PASS"
},
{
"compiler": "gcc",
"workers": 12,
"exit": 0,
"source_stamp": "6205e6c180ef32c41792dc3e0d8bf443a96df41974f40334af4bf3a157ab88da",
"hash_lines": [
"[PipelineFullDetailHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineWholeViewHash] tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineMaterialHash] tiles=512 material=0xc3cb5fcccf78f4ee",
"[PipelineLODHash] lod=0 tiles=512 density=0xe10ac12305f1dbc0 mesh=0x822e56e8f5bfa6f0 payload=0x0be1f08906997251 topology=0x650bbeb9e554d390",
"[PipelineLODHash] lod=1 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=2 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=3 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=4 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=5 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=6 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=7 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineLODHash] lod=8 tiles=0 density=0xcbf29ce484222325 mesh=0xcbf29ce484222325 payload=0xcbf29ce484222325 topology=0xcbf29ce484222325",
"[PipelineExactQueryHash] probes=9 density=0x74eac0457ddc2026 unclamped=0x74eac0457ddc2026 detail=0xefcba20c0c70c415 collision=0xdd5b083a1fa82cc7 path=direct-Core-queries"
],
"layout_identity": "resolved-layout-v3-fnv64:08da20d55ff6820f",
"native_fi_dispatch": true,
"native_plan_audits": true,
"passed": true,
"elapsed_s": 69.061,
"log": "Saved/Linux/l140/determinism/native-owner-fi-gcc-w12.log",
"layout": "Saved/Linux/l140/determinism/native-owner-fi-gcc-w12.json",
"floating_island_recipe_hash": "0b6a23bc73a3b867",
"passage_clearance_line": "[FloatingIslandPassageClearance] strate=1 tube_samples=5325 island_blocked=0 route_checks=676275 route_blocked=0 arrival_support=5/5 departure_support=5/5 clearance_excess_m=2.824 portal_exclusion_m=13.0 influence_reach_m=1.053 capsule_bound_m=0.880 status=PASS",
"route_audit_line": "[FloatingIslandRouteAudit] points=128 centers=911 capsule_samples=247792 blocked=0 support_samples=6961 unsupported=0 grade_failures=0 status=PASS"
}
],
"world_assembly_evaluator_version": 239,
"floating_island_geometry_version": 10,
"native_dispatch": "FloatingIslands-native",
"route_and_clearance_baseline": {
"route_audit": "[FloatingIslandRouteAudit] points=128 centers=... status=PASS",
"passage_clearance": "[FloatingIslandPassageClearance] strate=1 tube_samples=5325 island_blocked=0 route_checks=676275 route_blocked=0 arrival_support=5/5 departure_support=5/5 clearance_excess_m=2.824 portal_exclusion_m=13.0 influence_reach_m=1.053 capsule_bound_m=0.880 status=PASS",
"note": "The six identical hash/layout rows are the concrete baselines; route point counts differ by seed only in other sweep cases."
}
}
Loaded 100 of 250 files, more files were not shown because too many files have changed in this diff. Show more