# Unreal Core integration report — round 1 Date: 2026-10-08 Branch: `unreal/core-integration` ## Result Goals 1 and 2 are complete in BuildHost. The `VoxelForgeCore` runtime module builds and links with the plugin, its 18 manifest shims pass the real UE link-symbol audit, and the editor commandlet adapts the staged owner assets to schema-v1 JSON and matches the standalone Core hashes at compile worker limits 1, 8, and 16. The `AVoxelWorld` runtime route is not implemented. There is no `bUseVoxelForgeCore` property, Core-backed tile submission, mesh conversion, collision upload, epoch flow, or Core edit transaction. No owner hand-off switch is ready to flip. The existing plugin generation route remains the active route. ## Files and architecture - `Source/VoxelForgeCore/VoxelForgeCore.Build.cs` defines the runtime module. It validates the canonical manifest and shim inventory, uses C++20/precise FP with no PCH or unity, and exposes only `Standalone/Core/include` publicly. - `Source/VoxelForgeCore/Private/Manifest/` contains one include shim for each of the 18 rows in `Standalone/Core/core_sources.txt`. Canonical source files remain under `Standalone/`. - `Source/VoxelForgeCore/Private/ModuleEntry/` supplies the Unreal module entry and the isolated include of the engine `CoreMinimal.h`. - `VoxelForge.Build.cs` and `VoxelForgeEditor.Build.cs` depend on `VoxelForgeCore`. - `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` defines the empty standalone export macro and the UBT module export macro. No Core generation logic changed in this round. - `Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp` serializes the owner assets on the game thread, sorts map/set members and JSON object keys, parses the emitted JSON through `ResolvedWorldSnapshot::FromJson`, and validates full clipmap tile hashes. Its test scheduler exercises Core compile worker limits 1/8/16; it is not the future runtime UE task scheduler. ## BuildHost evidence `Tools/BuildVoxelForgeCoreHost.ps1` stages plugin source and copied owner assets only under `Saved/BuildHost/HostProject`. The final UBT run completed successfully: - `UnrealEditor-VoxelForgeCore.dll` and `UnrealEditor-VoxelForge.dll` linked in UnrealEditor Win64 Development. - All 18 expected Core shim objects were found and audited. - `CheckCoreSymbols.ps1` reported `CORE_LINK_SAFETY_PASS`: 83,843 `dumpbin` symbol lines checked against 399 copied Unreal-style type names, with no conflicts. - Five staged asset copies matched their source SHA-256 values: | Asset | SHA-256 | |---|---| | `DA_Settings` | `5D2977F57E75A63B6B73499CD6E0AA7FBBF3718CE7F70318107BF922F0819AB7` | | `DA_Strate1` | `CDA1F985E589F28CA6E93A068FECC3CA92487E4AD5700F2C301C4B563E40E5F9` | | `DA_Strate2` | `02F56A18CED991BAF93DFB2F69438152275E8353B5E279C1CB7DD6E079E352E2` | | `DA_Strate3` | `F47437F8D156C608AA06E40C5B76716ED4A19FA0F057688E7FECC04DC976428C` | | `DA_Strate4` | `279570AE3CBA7B3507269C8209A7C931EEB7A15CC3241CE07B50120996B1C656` | The final logs are `Saved/BuildHost/UBT-CoreIntegration.log` and `Saved/BuildHost/VoxelForgeCore_ue_link_safety.log`. ## Headless adapter evidence `Tools/TestVoxelForgeCoreAdapterHost.ps1` launches the isolated BuildHost Unreal commandlet at Normal priority. It sampled about 4.30 GiB private memory, below the 8 GiB limit. The generated JSON is retained at `Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreAdapterValidation/Output/owner_world.json`; the commandlet log is beside it under `Logs/CoreAdapterValidation.log`. For Core compile worker limits 1, 8, and 16, the validator then generated and hashed the 2,226 desired tiles serially. Each pass matched: | Hash | Expected / actual | |---|---| | Density | `0xdb2991c73215af4c` | | Mesh | `0x8236c5edd7fc8e4f` | | Payload | `0x4c48fa75a543d58e` | | Topology | `0xbea22e76b34a4dfc` | | Passage walkability | `5,642 / 5,642` | The adapter first parses the unmodified asset-derived export. The test then reparses a validation copy with the standalone CPU benchmark view settings `clip_radius=3` and `max_clip_level=8`. The final export itself retains the asset values. ## Differences and remaining work - The staged `DA_Settings` exports `ClipRadius=6` and `MaxClipLevel=6`; the standalone owner JSON has `clip_radius=6` and `max_clip_level=8`. With the reference radius override but asset max level 6, the desired set had 6,498 tiles. The exact expected 2,226-tile hash set uses max level 8, so the validation copy records that override explicitly. - Core schema and mesh output use 25 cm per voxel. The existing plugin Runtime defines `VOXEL_SIZE=12.5 cm`. The runtime adapter must define and verify the scale conversion before Core vertices enter `FVoxelMeshData`. - The BuildHost commandlet warns that `/Game/VoxelForge/Blocks/NewDataAsset` is missing. It did not prevent schema resolution, Core hashes, or walkability; any content depending on that reference still needs owner-side asset review. - Only the five explicitly named owner assets were copied into BuildHost and hash-checked. No owner editor was opened, and no owner project build or asset write was performed. - Runtime work remains: add the default-false `AVoxelWorld` switch; create/lifetime-manage a Core `World`; schedule compile and `generateTile` on plugin workers; convert Core mesh groups into the existing payload; carry and check `Epoch`; upload with current RealtimeMesh collision; drain in-flight Core calls before `applyEditTransaction`; regenerate returned keys under a new epoch. - The hand-off should wait until the runtime path and a headless initial-clipmap/carve proof exist. ## Failed runs, retries, and crashes No run exceeded the 15-minute limit. No process returned `0xC0000142`, so no automatic retry was used. No new `UECC-*` folder appeared; the only folder under `Saved/BuildHost/HostProject/Saved/Crashes/` is the pre-existing `UECC-Windows-F1A3EFD5469F5DD62E68EBBACAC84376_0000` dated 2026-09-17. The run history, including corrected failures, is: | Run | Outcome | |---|---| | Early UBT validation/build attempts 1–7 | Failed in sequence on a shim-preamble regex, stale staged Build.cs, duplicated UHT source tree, missing API export/incorrect CoreMinimal and forwarding-header paths, malformed macro quoting, canonical C4456/C4668 warnings-as-errors, and editor-only `FFilePath` compat fields. Each was corrected; no source `Binaries/`, `Intermediate/`, or generated header was edited. | | Initial successful BuildHost UBT runs | Passed after defining the module export macro, isolating the actual engine CoreMinimal include, and setting `WITH_EDITORONLY_DATA=0`. They established module links and the first symbol audit. | | Adapter commandlet: first launch | Failed the commandlet's output-path guard because `-out` was outside the staged plugin `Saved` directory. The path was moved under BuildHost. | | Adapter commandlet: DDC path | Exited 3 with a fatal error because the DDC path exceeded Unreal's 119-character limit. The staged DDC was moved to the shorter `Saved/BuildHost/VFCoreAdapterDDC`; no new UECC folder appeared. | | Adapter commandlet: scale | Failed schema resolution with `voxel_size_cm=12.5`; the adapter was corrected to emit Core's standalone 25 cm scale. | | Adapter commandlet: clip bounds | The original radius 6 exceeded the validation compiler's 160-million-node bound. The harness now applies the documented radius 3 override to a copy only. | | Adapter commandlet: hash comparison | Generated 6,498 tiles and walkability 5,642/5,642, but hashes differed because the staged asset max level is 6 and the standalone reference is 8. The validation copy now applies max level 8. | | UBT/commandlet wrapper status | Unreal logged successful results, but two `Start-Process` handles exposed empty exit-code fields; one commandlet fallback also looked for a marker absent from the abslog. The scripts now require UBT's `Result: Succeeded` or the commandlet's `result 0` plus exact parity markers. Final UBT and adapter harness runs passed. | | PowerShell helper checks | Two intermediate parser attempts failed while adding the UBT fallback; one parser check exposed a multiline `-and` in the commandlet fallback; a separate parser invocation also hit nested-shell variable expansion. These affected no Unreal run; the scripts were corrected and parsed successfully before final execution. | | Staged standalone viewer build | The first launch failed before compilation because Start-Process split a path containing spaces. The corrected BuildHost run compiled the Core library and passed its symbol audit, then the viewer link failed with 12 unresolved `VoxelForgeGpuFarViewer` symbols: `Standalone/Build.ps1` does not link the `GpuFieldPort.cpp` implementation still referenced by `StandaloneViewer.cpp`. No canonical standalone build file was edited. | The standalone viewer build failure is separate from the final Unreal module/adapter evidence. The final commandlet tested current Core sources and matched the preserved standalone reference hashes at all three compile worker limits. ## Owner hand-off There is nothing to flip yet. Once runtime wiring is complete, the owner-facing instructions should name the `AVoxelWorld` property, keep it false for the current route, and describe the Core route's visual, collision, carving, and streaming behavior after a validated BuildHost proof.