Luna, integration round 3, from the owner's four in-game screenshots: - Capsule rings at the opening and the shaft continuing through the cave room were Core world defects: the synthetic bore is removed and the opening gets a finite origin room and floor (solid below). New world version, W1/W8/W16 identical: density a8bcb72d41092503, mesh 90f29ba15e24579f, payload 82c6b489e7bb7fd7, topology 7b99448a1f844f2c. - B-side landing and surface: headless coverage found no missing tiles or LOD-transition gaps (960 / 640 fine tiles compiled after travel); best explained by Core's missing SurfaceWorld representation. Null-RHI cannot rule out a presentation-only issue. - Core mode GetBiomeAtWorldLocation now answers (e.g. Biome_Surface_Plain); biome terrain itself is not generated yet (proposal: native Core SurfaceWorld evaluator). Owner checked the Step29 viewer himself: the surface strate type is absent there too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
24 KiB
Unreal Core integration report — rounds 2–3
Date: 2026-10-08
Branch: unreal/core-integration
The initial sections preserve the round-2 integration baseline. The round-3 addendum records the owner's visual findings and current status, superseding earlier statements where indicated.
Result
Goals 1 and 2 now pass in BuildHost: an AVoxelWorld with Core mode enabled matches standalone Core
tile-by-tile, checks expected collision bodies, streams an entering/leaving anchor tile, and applies a
carve transaction whose affected tile hashes match standalone Core. Goal 3 has a narrow legacy
generator baseline pass; it does not instantiate an actor with Core disabled, so that result is not
an actor-level A/B comparison. The owner can now try the opt-in switch in their editor after building
the plugin.
Core remains opt-in (bUseVoxelForgeCore=false by default). Core mode owns separate clip settings
(radius 3, max level 8), uses 25 cm Core voxels and Core tile keys, and routes mesh payloads through
the existing RealtimeMesh/collision path. No Core canonical source or owner asset was edited.
Headless AVoxelWorld evidence
Tools/TestVoxelForgeCoreWorldHost.ps1 stages the current plugin and the five copied owner world
assets into BuildHost, builds the Unreal modules, and runs
VoxelForgeExplore -coreworldtest=1. The commandlet resolves the staged settings/strate data and
spawns a transient AVoxelWorld with Core mode enabled.
- Initial desired set: 2,226 tiles. Density, mesh, payload, topology, triangle, empty-tile and
per-tile hashes match the standalone Core reference. Aggregate hashes are density
0xd528cf02858dd01d, mesh0x747c531b4499a9a6, payload0x5d38ea99f9c2cad0, topology0xd9974b32dc47fc8d. - Collision: the expected set is 125 level-0 tiles (a 5×5×5 box); all expected non-empty tiles have
cooked bodies (58), and all 67 expected empty tiles are explicitly checked as no-body. The final
log reports
collision_ready=58;collision_no_body=318is the actor's global no-body bookkeeping count, not the expected-box count. - Anchor: moving the
CollisionOnlyanchor from Core tile(20,0,0)to(21,0,0)requests one entering tile and releases one leaving tile.FullVisualfollows the same reconciliation path but has no independent assertion in this harness. - Carve: sequence 1, digest
0xa1d628d0de1a6824, four affected keys. The carved LOD0 tile(-1,-1,-1)hashes to0x633f3488c0800734; every affected tile is compared to standalone Core after applying the same transaction. - Peak process memory: 2,881,925,120 bytes (approximately 2.68 GiB), below the 8 GiB cap. The run completed in seconds, below the 15-minute stop limit.
The mesh bridge copies Core vertex positions directly: the Core API returns vertices in centimetres.
Inputs to Core (player/anchor/query/edit positions and brush dimensions) use 25 cm voxel conversion;
high-level brush radii/extents/falloff that came from legacy 12.5 cm voxel units are multiplied by
12.5/25 to preserve their physical size. ApplyModification low-level callers supply active Core
voxel units.
Switch-off baseline
The selected narrow existing test was
VoxelForge.Determinism.CrossPlatformDigest, run from Tools/VoxelForgeTest.ps1 against the staged
BuildHost plugin. Unreal's automation result passed with exit 0: 115,000 legacy samples, shape digest
0xB9F6E034156BDB7A, field digest 0x212DA316FBBA4401, 86,901 solid, 28,099 air, and zero NaNs.
The wrapper marked its overall run failed because Unreal wrote analytics files under
C:\Users\Jahni\AppData\Local\UnrealEngine\common\analytics despite the isolated user-data path
and bSendUsageData=false. This was an incidental external profile write; I did not alter or remove
it. The raw automation result is a legacy baseline, not a direct assertion that an actor with
bUseVoxelForgeCore=false is byte-for-byte unchanged.
Files and architecture
Source/VoxelForgeCore/VoxelForgeCore.Build.csdefines the runtime module. It validates the canonical manifest and shim inventory, uses C++20/precise FP with no PCH or unity, and exposes onlyStandalone/Core/includepublicly.Source/VoxelForgeCore/Private/Manifest/contains one include shim for each of the 18 rows inStandalone/Core/core_sources.txt. Canonical source files remain underStandalone/.Source/VoxelForgeCore/Private/ModuleEntry/supplies the Unreal module entry and the isolated include of the engineCoreMinimal.h.VoxelForge.Build.csandVoxelForgeEditor.Build.csdepend onVoxelForgeCore.Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.hdefines the empty standalone export macro and the UBT module export macro. No Core generation logic changed in this round.Source/VoxelForge/Private/VoxelForgeCoreAdapter.cppandSource/VoxelForge/Public/VoxelForgeCoreAssetAdapter.hserialize resolved assets into schema-v1 values without passing UObjects to Core workers.Source/VoxelForge/Private/VoxelWorld.cppandPublic/VoxelWorld.hcontain the opt-in route, Unreal task scheduler, Core tile-key/scale bridge, MPSC/epoch handling, anchor integration, and transaction edits.VoxelForgeExploreCommandlet.cppcontains the BuildHost actor proof.- The commandlet adapter's compile scheduler still exercises the standalone compiler at worker limits 1/8/16; the runtime scheduler is the separate Unreal-task implementation above.
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.dllandUnrealEditor-VoxelForge.dlllinked in UnrealEditor Win64 Development.- All 18 expected Core shim objects were found and audited.
CheckCoreSymbols.ps1reportedCORE_LINK_SAFETY_PASS: 83,843dumpbinsymbol 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.
Owner hand-off and known limits
- The staged
DA_SettingsexportsClipRadius=6andMaxClipLevel=6; the standalone owner JSON hasclip_radius=6andmax_clip_level=8. Runtime Core mode intentionally does not read the old asset clip values; its own defaults are radius 3 and max level 8. The adapter parity test preserves the source export and applies those reference view values only to a separate validation copy. - In the owner's Unreal editor, select the
AVoxelWorldactor and enable Voxel World | Core | Use VoxelForge Core in Details. Leave Core Clip Radius = 3 and Core Max Clip Level = 8 for the first check. Save the level only if the owner wants to keep the actor setting. With the world running, expect Core terrain to stream around the player, solid LOD0 terrain to block movement, and the existing carve entry points to create a deterministic hole. Disable the switch to return to the legacy route. - BuildHost UBT compiled the current runtime and editor modules. If the owner's editor reports a
compile error, the likely integration seams to inspect first are the new reflected properties in
VoxelWorld.h(UHT), the Core module dependency inVoxelForge.Build.cs, the Core/RealtimeMesh bridge inVoxelWorld.cpp, and the editor-only commandlet code. No owner-editor build was run. - The commandlet warns that
/Game/VoxelForge/Blocks/NewDataAssetis missing./Gameis project content, and this asset is not part of the plugin; the staged copied content also lacks that package. It did not prevent schema resolution, hash checks, or walkability. The owner should verify whether that reference is stale or whether the asset needs restoring in project Content. - At the end of round 2, Core mode's legacy biome query returned empty because Core exposed no biome
query API. Round 3 adds a Core-mode query through the copied owner biome evaluator; it does not add
biome terrain or decorations to the Core field.
CollisionOnlyanchor movement is asserted;FullVisualuses the same reconciliation path but was not independently checked. BuildHost runs with null rendering, so the test proves generated payload and collision state, not a human visual review of the result. - Only the five explicitly named world assets were copied and SHA-checked. No owner editor was opened, and no owner project build or asset write was performed.
Failed runs, retries, and crashes
No build or test exceeded the 15-minute limit. No process returned 0xC0000142, so no automatic
retry was used. One new UECC-Windows-7B23387E4235BCFEDE42BC9D637E41CB_0000 was written under
Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/User/Saved/Crashes/;
its fatal log records duplicate WorldSettings creation in the transient actor-test world. The
requested Saved/BuildHost/HostProject/Saved/Crashes/ contains only the older 2026-09-17
UECC-Windows-F1A3EFD5469F5DD62E68EBBACAC84376_0000.
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. |
| Core actor commandlet: world creation | Unreal aborted on duplicate WorldSettings creation in the transient validation level. The UECC folder above contains the fatal log. World creation was changed to use the engine initialization values; the passing actor run no longer hits this fatal. |
| Core actor commandlet: lifecycle attempts | One run was manually stopped after BeginPlay did not run; another had no desired tiles after roughly 15,000 manual ticks. The harness was corrected to initialize actors for play, supply a transient game instance/context and GameMode, and advance GFrameCounter. Both were stopped well before 15 minutes and produced no crash. |
| Core actor commandlet: UBT | One quick compile failed with C2027 for incomplete AWorldSettings; adding GameFramework/WorldSettings.h fixed it. |
| Core world host final run | Passed after the lifecycle fixes and again after correcting high-level brush dimensions from 12.5 cm to 25 cm Core units. The pre-correction carve run also passed parity but affected 8 tiles; the final scale-correct run affects 4 and is the reported result. |
RunVoxelForgeAutomationR2.ps1 switch-off attempt |
Failed before launching Unreal because the expected Saved/VoxelForgeHarnessCommon.ps1 helper was absent. The later direct VoxelForgeTest.ps1 automation run executed the selected test and produced the analytics-write wrapper failure documented above. |
| Switch-off automation wrapper | Unreal automation itself passed VoxelForge.Determinism.CrossPlatformDigest with exit 0; the wrapper returned failure for the external common\analytics write. No retry was attempted and no crash was reported. |
The standalone viewer build failure is separate from Unreal integration. The final adapter and actor passes match preserved standalone reference hashes; the Core worker-limit 1/8/16 adapter proof also retains the original passage walkability result.
Handoff status
The owner can now try the switch described above. BuildHost proves Core tile parity, expected collision-body bookkeeping, anchor entering/leaving, and transaction-based carving. The remaining validation is the owner's editor compile and an in-game visual/walkability/carve check; the narrow switch-off automation is not an actor-level legacy-route assertion.
Round 3 — owner visual report, classification, and fixes (2026-10-08)
The owner had already built the plugin in his own game and confirmed that the Core toggle worked and
performance looked fine. I compared the four small images in Standalone/owner_shots/unreal_core_r2/
with owner-field and shape-world viewer modes at the B and surface locations, checked the owner's
BuildOriginLandingGeometry/passage definitions, and extended the BuildHost actor proof to inspect
desired keys, hashes, meshes, and LOD faces. Viewer comparisons were captured before the geometry
correction; the final test recompiled the corrected field in BuildHost.
| Reported defect | Standalone and layout evidence | Unreal Core headless evidence | Classification and outcome |
|---|---|---|---|
| 1. Capsule rings at the city/surface opening | Owner passage is a short entry into a finite origin room. Core shape-world instead added a segmented 256-voxel bore; owner-field mode has no such continuation. | Room center +4.125 (air); floor below center and side -4.125 (solid); above floor center and side +4.125 (air). |
(ii) Core world defect, also visible in shape-world. Fixed. Removed the synthetic bore and added the finite room/floor. |
| 2. Bore continues through a normal cave room | Owner layout ends the entry at the room; no shaft continues through it or into the lower seal. The same Core bore passed through it. | 32 voxels below the room floor samples -4.125 (solid). |
(ii) Core world defect, also visible in shape-world. Fixed. |
| 3. B-side landing has jagged/sawtooth edges | At B, owner-field and shape-world fields differ: Core shows a smooth cavern/floor while owner reference has the authored landing/terrain form. The landing is in the lower biome/SurfaceWorld portion of the layout. | All expected 2,553 visual keys load and match standalone hashes. B travel compiled 960 fine tiles; 3,438 neighbour faces checked, including 432 LOD-transition faces; no expected visual key is missing. | (iii) Missing Core SurfaceWorld/biome representation is best supported. The suspected missing-neighbour/LOD coverage fault is absent at the tested pose. Null-render headless testing cannot rule out a final RMC presentation artifact; owner should recheck after rebuild. |
| 4a. Surface strate is not surfacy | Shape-world viewer lacks the owner's biome-composed SurfaceWorld; owner-field mode shows rolling biome terrain. The owner separately confirmed the surface strate type is absent in his viewer. | Core query reports Biome_Surface_Plain, index 2, but geometry remains the Core shape field. |
(iii) Missing Core feature: biome terrain. Not implemented this round. Cheap biome query is implemented. |
| 4b. Coarse shapes may not page detail | Hypothesis: travel failed to trigger fine compilation. Standalone Core uses the same clipmap policy. | Surface travel compiled 640 fine tiles. Visual set and tile hashes match standalone; 3,588 neighbour faces checked, including 448 LOD-transition faces, with no missing expected visual key. | (i) Unreal paging bug not reproduced. StartPendingCoreRegionCompile paged detail at the tested location. Extra loaded keys included collision-only/stale support; validator filters these and proves the exact visual set. |
Changes and hashes
Standalone/Core/src/ShapeWorldInternal.h: add the owner-layout finite origin room/floor per strate, remove the synthetic long surface-entry bore, and ignore invalid/default passage landing descriptors that made tiny false landings.Source/VoxelForge/Private/VoxelWorld.cpp: Core-modeGetBiomeAtWorldLocationnow calls the copied owner biome evaluator using its authored 12.5 cm query scale. Core terrain still uses 25 cm voxels; the exception is local to this legacy biome query.Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cppandTools/TestVoxelForgeCoreWorldHost.ps1: probe the room/floor, W1/W8/W16 determinism, travel to B and surface, exact visual keys/hashes, LOD face coverage, fine compilation, and biome result.
The corrected world intentionally changes the four aggregate hashes. W1/W8/W16 initial clipmap results are identical:
| Hash | New value | R2 value |
|---|---|---|
| Density | 0xa8bcb72d41092503 |
0xdb2991c73215af4c |
| Mesh | 0x90f29ba15e24579f |
0x8236c5edd7fc8e4f |
| Payload | 0x82c6b489e7bb7fd7 |
0x4c48fa75a543d58e |
| Topology | 0x7b99448a1f844f2c |
0xbea22e76b34a4dfc |
B travel hashes: density 0x02ffd603879b7fdc, mesh 0xde3bfc6069854070, payload
0x14f98868de7986c5, topology 0xdf960f8a26aafdc0. Surface travel hashes: density
0x7f878c0933972c7f, mesh 0x18d63306f5215f10, payload 0x18b6e682e2a17505, topology
0xe89da4150dc053c9. At surface desired=2553, while actor loaded=3334 includes support/stale
keys during the move. The validator filters collision-only support, then proves every expected visual
key and hash; it does not claim support-set quiescence.
Biome design proposal
Recommended direction: add a deterministic SurfaceWorld evaluator to the Core shape-world model,
fed by resolved biome definitions, surface-generation parameters, and fixed-order noise. Keep biome
identity/blend selection in the immutable worker snapshot and add per-column height/biome caching so
mesh samples reuse height work. This makes the surface, biome query, and decoration inputs one pure
field. The port is medium-to-large work. Uncached per-sample biome/noise could slow detail tiles;
column caching bounds the added cost. Determinism is straightforward to preserve with fixed coordinate
hashing/math and worker-count hash tests.
Routing only SurfaceWorld strates through the copied legacy UVoxelGenerator in Core is a smaller
compatibility bridge with higher immediate visual fidelity. It likely costs about the legacy field
evaluation per sample, duplicates a second field implementation, and inherits legacy float/platform
behavior. It should be checked across worker counts and platforms. A better staged design is an
explicit strate-evaluator interface: use the port long-term and allow the copied evaluator as a
temporary per-strate fallback when exact behavior is needed earlier. This round implemented the cheap
biome query only; a full biome surface port did not fit alongside the geometry and streaming checks.
BuildHost outcome and run ledger
Tools/BuildVoxelForgeCoreHost.ps1 and Tools/TestVoxelForgeCoreWorldHost.ps1 -TimeoutSeconds 900
passed. The actor test reported streaming=1 collision=1 anchor_move=1 carve=1; peak commandlet
private memory was 2,997,526,528 bytes (about 2.8 GiB). No step exceeded 15 minutes, no 0xC0000142
retry occurred, and no new UECC folder appeared. The requested Saved/BuildHost/HostProject/Saved/Crashes/
contained only its prior crash folder.
| Round-3 attempt | Outcome |
|---|---|
| First standalone viewer capture invocation | Failed because an owner-data path with spaces was passed in the wrong form. Corrected auto-discovery invocation produced all four Core/owner B/surface captures with exit 0. |
Standalone/Build.ps1 -Target All |
Core library built and symbol audit passed; viewer link failed on 12 unresolved VoxelForgeGpuFarViewer symbols because the script omits GpuFieldPort.cpp. Canonical build files were left unchanged. |
| First expanded surface actor test | Manually stopped after repeated collision-only region compiles prevented the overly broad settled-state condition from completing. Narrowed the test to expected visual keys/hashes; final run passed. No new UECC. |
| Origin-room sign assertion | Failed quickly because expected signs were reversed. Core uses positive=air and negative=solid; corrected assertion passed. |
| Intermediate commandlet builds | One failed on non-exported GetEffectiveOriginSpineRadius; another used protected OriginSpineRadius. Harness now computes effective radius from settings/season data. Later UBT builds passed. |
| Final UBT and Core world test | Passed W1/W8/W16 hashes, origin floor, B/surface coverage and paging, biome query, anchor movement, collision, and carve markers. |
After the owner's rebuild, with Use VoxelForge Core enabled, inspect these exact places:
- At the city/surface opening, confirm one short entry reaches a finite rounded room without capsule rings; stand on the floor and confirm it is flat and walkable.
- Continue into the normal cave room and look down: the entry should not continue as a deep shaft.
- Walk through the A→B landing to the B side. Check whether jagged edges/sky gaps remain after nearby tiles settle. Headless key and LOD coverage is complete; a remaining artifact needs a screenshot from this same view to isolate final mesh presentation.
- Travel to the surface strate. Wait for coarse-to-fine transition and confirm nearby detail appears.
The biome query identifies
Biome_Surface_Plain, but biome-driven surface geometry is still missing, so the broad surface terrain should not yet be judged as fixed.
Switch-off continues through the legacy generator. The owner rebuild/editor review is the remaining visual check.