Files
VoxelForge/Standalone/Research/WorldAssemblerM3/Linux70/REPORT.md
T
Fr0zkaandClaude Opus 5.5 bd68aee1ca parity: Unreal and headless resolve the same four-strate plan (L70, v214)
- 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
2026-10-27 06:22:48 +01:00

8.1 KiB
Raw Blame History

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.WorldAssemblyManifestJson also lacked layout_chunk_width_q and carried an FI plan with top/bottom -16/-79, while the live FI slot is -64/-93. bUseWorldAssemblyManifestOverride is false, so Unreal did not consume that stale string; the headless fallback instead made its own plan. The export commandlet now writes world_assembly, core_world_assembly_json, and resolved_layout_json from 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.Heightfield2D v2, FloatingIslands.ClusterField v0, legacy.TunnelNetwork, and legacy.VerticalShafts. The owner currently has no native FI plan: bUseWorldAssemblyManifestOverride=false leaves bImportedOverride=false, so the adapter's Type == FloatingIslands && bImportedOverride branch does not build one. NativeFloatingIslandDensityAt then has no bound IslandPlan and the FI slot uses compiled-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) m on the lower inclusive boundary of the wider compiled region. L68's smaller compile queried EvaluateFast; 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.