- Export commandlet writes the live Core adapter's world_assembly + resolved layout pair; the headless owner path imports that pair (manifest/layout equal, layout_chunk_width_q validated). owner_world.json re-exported from the owner's staged assets on the Linux host. - Adapter SW route: Core clearance/radius floors, 0.5 m support search, outward-facing tie-break; passage mouth/mid radius floors match Core (36/24 owner voxels). - FI in Unreal now uses the legacy (compiled analytic) generator unless a plan is imported: the auto native-FI plan failed the passage audit on the owner plan (1843 blocked samples, 945 open-air violations). Owner decides whether native FI returns. - In-engine spawn traces per strate (3 each): SW GenerateTile 42.7 worker-s vs 20.1 headless for equal tile counts; LOD0 p95 45-169 ms in UE. - Fast tier green; all three passages pass on the shared plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
8.1 KiB
Linux 70: Unreal and headless plan parity
Result
The strict Unreal export and the headless import now resolve the same Core manifest and layout:
manifest_equal=True, layout_equal=True, manifest hash bcc0d0d33ea39435, layout identity
resolved-layout-v3-fnv64:0589300eb07dfe06, and layout_chunk_width_q=8192. The headless log reports
source=owner_export/unreal_core_adapter. Slot bounds are 0: top 0 / bottom -63,
1: -64 / -93, 2: -94 / -109, and 3: -110 / -125.
The exact-plan passage audit passes all three interfaces, with natural=3/3 and zero route-binding
failures. The fast tier also passes (268.4 s), including peer determinism and the new four-strate
plan stage. The new floating-islands style-2 output is pinned in
Standalone/Tools/verify/hash-baselines/owner-hash-floating-islands-style2-v214.log; the historical
L68 baseline was left intact.
Divergences and fixes
-
Export and manifest. The pre-L70 owner JSON had no root resolved Core manifest/layout pair. Its inactive
settings_asset.WorldAssemblyManifestJsonalso lackedlayout_chunk_width_qand carried an FI plan with top/bottom-16/-79, while the live FI slot is-64/-93.bUseWorldAssemblyManifestOverrideis false, so Unreal did not consume that stale string; the headless fallback instead made its own plan. The export commandlet now writesworld_assembly,core_world_assembly_json, andresolved_layout_jsonfrom the live Unreal Core adapter. The headless owner path imports that pair and validates width and live slot bounds. The embedded legacy string remains inactive; use the root pair. -
Slots, passage inputs, and route. The four live slot bounds and authored passage configs agree after export. Before unification, the independently resolved SurfaceWorld upper mouth differed: headless fallback
[0,0,-383938]versus Unreal[8192,16384,-381197]in Q units. Unreal's candidate search had weaker clearance and support constraints and a different tie choice. The adapter now uses the Core clearance/radius floors, checks route support, and prefers the outward-facing candidate; the Core radial phase override was removed. The composed route support deck and root taper were corrected, and the imported-plan passage audit now samples the serialized Core route. The final canonical routes and passage configs compare equal. -
Generators and FI dispatch. Recipes in the resolved layout are
SurfaceWorld.Heightfield2Dv2,FloatingIslands.ClusterFieldv0,legacy.TunnelNetwork, andlegacy.VerticalShafts. The owner currently has no native FI plan:bUseWorldAssemblyManifestOverride=falseleavesbImportedOverride=false, so the adapter'sType == FloatingIslands && bImportedOverridebranch does not build one.NativeFloatingIslandDensityAtthen has no boundIslandPlanand the FI slot usescompiled-analytic/FloatingIslands. This is the same default FI dispatch on both sides of the final plan. -
The L69 solid sample. R37's notes place
(-43.0,-34.5,-448.5) mon the lower inclusive boundary of the wider compiled region. L68's smaller compile queriedEvaluateFast; L69's wider compile read the packed rock bit, and the same point was solid in both L69 headless and Unreal runs. The source of that historical packed bit is still unidentified. L70's exact-plan composed density audit passes all three interfaces; that does not identify the old bit's density contributor. The route-planner difference was real, but R37 did not find it sufficient to explain that sample.
Re-export on Windows
Set the three paths for the owner's machine, then run this PowerShell command. It overwrites
Standalone\data\owner_world.json with the live four-strate export and its canonical plan pair.
$UE = 'C:\Path\To\UnrealEngine'
$VFHost = 'C:\Path\To\VFHost'
$VoxelForge = Join-Path $VFHost 'Plugins\VoxelForge'
& "$UE\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" "$VFHost\VFHost.uproject" `
-run=VoxelForgeExplore -nullrhi -unattended -nop4 -nosplash -NoSound `
-NoZenAutoLaunch -notraceserver -nocrashreports -DDC-ForceMemoryCache `
-settingsref=/Game/VoxelForge/DA_Settings.DA_Settings -modes=export `
-gameconfig=1 -standaloneworldexport=1 -ownerfourstrateplan=1 `
"-out=$VoxelForge\Standalone\data" `
"-abslog=$VoxelForge\Saved\Linux\l70\owner-export.log"
Spawn traces
Three Unreal traces per strate completed. The table uses Unreal medians; walkable is the 9/9
walkable-gate time, LOD0 is the 512-tile ring time, full is spawn to initial_set_ready, and
worker is the sum of tile worker_task_s. Headless values are one run at the same arrival;
worker sums WorldAssemblerLODWorker.worker_sum_s.
| Strate | Walkable UE | LOD0 UE | Headless first / neighborhood | Full UE / headless (tiles) | Worker UE / headless (s) | UE LOD0 p50 / p95 (ms) | UE GenerateTile / mesh copy / RMC (s) |
|---|---|---|---|---|---|---|---|
| 0 SurfaceWorld | 0.833 s | 2.063 s | 0.406 / 0.556 s | 7.039 / 2.057 s (2850 / 2850) | 42.912 / 20.064 | 0.924 / 125.243 | 42.688 / 0.035 / 0.190 |
| 1 FloatingIslands | 1.813 s | 3.200 s | 0.377 / 0.660 s | 6.642 / 5.493 s (2249 / 2249) | 48.219 / 61.516 | 16.819 / 168.878 | 47.968 / 0.037 / 0.214 |
| 2 TunnelNetwork | 0.361 s | 2.684 s | 0.393 / 0.547 s | 5.626 / 4.634 s (2233 / 2233) | 37.894 / 50.868 | 8.188 / 166.935 | 37.655 / 0.035 / 0.203 |
| 3 VerticalShafts | 0.379 s | 1.191 s | 0.400 / 0.413 s | 3.651 / 2.258 s (2329 / 2329) | 16.425 / 22.227 | 2.323 / 44.996 | 16.217 / 0.033 / 0.178 |
The full-set wall gaps exceed 30% at strates 0 (+242%) and 3 (+62%); the worker-sum gap exceeds
30% only at strate 0 (+114%). Unreal ran with streaming_background_worker_cap=1, an eight-slot
effective queue, startup apply boost, and the live asset clip settings (radius 6, max clip 6;
observed levels 0–8). The headless table used 12 workers, radius 3, max clip 8, max level 8. Its
tile counts match Unreal at every LOD for these arrivals, but these are not identical runtime
settings. The explicit headless radius-6/max-clip-6 run hit the 160-million-node shape safety
bound at 17,689 desired tiles before generation. Unreal's full-set milestone also includes its
tile scheduling and delivery path, while headless whole_view_ready is the direct pipeline
milestone. Strate 3's higher wall time with 26% fewer worker-seconds suggests readiness/scheduling
overhead. Strate 0's worker excess is in GenerateTile itself (42.688 s versus 20.064 s for the
headless worker sum); plan and per-LOD tile counts do not explain it, and this trace does not
isolate the remaining runtime cost.
Native FI experiment
I temporarily removed the && bImportedOverride gate, rebuilt, and exported the auto-native FI
plan (hash 303f3d266dc40a7c). Dispatch changed to FloatingIslands-native; the 2249-tile
whole-view density/mesh/payload/topology hash changed from off
c1e5e72f879b0327/2c3994301a77a14e/1e3c8f74f439e4ff/ba850f95f0b889c8 to
on 11042f19685926d1/56c6d3d46d8ed3b1/d81e70785c858145/7e608c8cb9027a70 (one run each).
The on-plan audit failed: 2/3 interfaces
passed, the FI route had 1843 blocked samples, and open-air had 945 violations. Leave native FI
off for the owner.
Build and failed runs
Linux UBT succeeded with the final native-FI-off code. Source/ files for the Windows build are
Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp and
Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp. The build completed before the
timing series; no Unreal build ran during timing. Every process was taskset-limited and capped at
6 GiB; UE used RSS and headless used address space. No run exceeded 30 minutes; each valid Unreal
trace took about 53 s.
- Initial UE trace attempts inherited an address-space cap and failed during UE startup/mapping; switching the trace driver to the RSS cap produced all 12 valid traces.
- The radius-6 headless comparison stopped at the 160-million-node bound noted above.
- A diagnostic passage-audit run with extra max-clip/output flags threw
std::bad_alloc; the bounded rerun without those diagnostic flags passed all three interfaces. - The one-line native-FI experiment intentionally failed the passage audit as described above.
No commit, push, or stash was made.