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

126 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
```powershell
$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.