Manifest imported into UVoxelSettings (hash 8933693d9560ba9f), folded into the season content hash only when Core is on. BuildHost: W1/W8/W16 stable, 2553 surface tiles match standalone, 432 LOD transitions, collision on all 36 expected tiles. Matched timing 96.8 s native vs 197.3 s bridge (2.04x). Collision support tiles wait for Core region admission. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
485 lines
44 KiB
Markdown
485 lines
44 KiB
Markdown
# Unreal Core integration report — rounds 2–4
|
||
|
||
Date: 2026-10-08
|
||
Branch: `unreal/core-integration`
|
||
|
||
The initial sections preserve the round-2 integration baseline. Round 3 records the owner's first
|
||
visual review; the round-4 addendum below supersedes its SurfaceWorld status and adds the requested
|
||
strate coverage evidence.
|
||
|
||
## Result
|
||
|
||
The Unreal route remains verified in BuildHost: an `AVoxelWorld` with Core mode enabled matches
|
||
standalone Core tile-by-tile, checks expected collision bodies, streams an entering/leaving anchor
|
||
tile, applies a carve transaction, and travels to a layout containing SurfaceWorld. The round-4
|
||
coverage matrix also found that SurfaceWorld density is exact through a temporary copied-legacy
|
||
evaluator in Core. Other generator archetypes and boundary transitions remain approximate or absent;
|
||
the full owner requirement is not complete. Goal 3 still has only a narrow legacy-generator baseline
|
||
pass, not an actor-level switch-off A/B comparison.
|
||
|
||
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. Round 4 changed canonical Core source and the standalone
|
||
JSON reader; no .uasset or owner project file was touched.
|
||
|
||
## 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`, mesh `0x747c531b4499a9a6`, payload `0x5d38ea99f9c2cad0`, topology
|
||
`0xd9974b32dc47fc8d`.
|
||
- 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=318` is the actor's global no-body bookkeeping
|
||
count, not the expected-box count.
|
||
- Anchor: moving the `CollisionOnly` anchor from Core tile `(20,0,0)` to `(21,0,0)` requests one
|
||
entering tile and releases one leaving tile. `FullVisual` follows 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 to `0x633f3488c0800734`; 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.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/VoxelForge/Private/VoxelForgeCoreAdapter.cpp` and
|
||
`Source/VoxelForge/Public/VoxelForgeCoreAssetAdapter.h` serialize resolved assets into schema-v1
|
||
values without passing UObjects to Core workers.
|
||
- `Source/VoxelForge/Private/VoxelWorld.cpp` and `Public/VoxelWorld.h` contain the opt-in route,
|
||
Unreal task scheduler, Core tile-key/scale bridge, MPSC/epoch handling, anchor integration, and
|
||
transaction edits. `VoxelForgeExploreCommandlet.cpp` contains 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.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.
|
||
|
||
## Owner hand-off and known limits
|
||
|
||
- The staged `DA_Settings` exports `ClipRadius=6` and `MaxClipLevel=6`; the standalone owner JSON
|
||
has `clip_radius=6` and `max_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 `AVoxelWorld` actor 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 in `VoxelForge.Build.cs`, the Core/RealtimeMesh
|
||
bridge in `VoxelWorld.cpp`, and the editor-only commandlet code. No owner-editor build was run.
|
||
- The commandlet warns that `/Game/VoxelForge/Blocks/NewDataAsset` is missing. `/Game` is 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. `CollisionOnly` anchor movement is asserted;
|
||
`FullVisual` uses 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-mode `GetBiomeAtWorldLocation` now 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.cpp` and
|
||
`Tools/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:
|
||
|
||
1. 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.
|
||
2. Continue into the normal cave room and look down: the entry should not continue as a deep shaft.
|
||
3. 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.
|
||
4. 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.
|
||
|
||
## Round 4 — strate coverage and SurfaceWorld bridge (2026-10-08)
|
||
|
||
### Status
|
||
|
||
SurfaceWorld now has an exact-density compatibility route inside Core. Surface lattice hashes match
|
||
the owner reference at full resolution and at the tested coarse LODs. The bridge calls the copied
|
||
legacy generator for SurfaceWorld samples, including its resolved biome field and terrain operations,
|
||
then applies Core edit brushes. It is deterministic in the BuildHost W1/W8/W16 matrix. This is not a
|
||
native Core SurfaceWorld implementation, and the matched viewer captures still show a mesh/presentation
|
||
difference. The bridge also makes Core surface tile generation about as expensive as the owner field.
|
||
|
||
The reader now retains the serialized slab, maze, shaft, and floating-island parameter structs.
|
||
Parsing those values does not mean their terrain evaluators are implemented in Core.
|
||
|
||
### Generator archetype probes
|
||
|
||
Each probe has its own JSON under
|
||
[the probe directory](Research/OwnerShapeWorld/core_strate_coverage/probes/). The viewer comparison
|
||
uses 16 LOD0 tiles per row, except where the SurfaceWorld row also reports an explicit cross-LOD run.
|
||
“Changed” counts lattice samples whose density sign differs; the old/Core hashes catch magnitude
|
||
differences even when that count is zero. Capture links are matched owner-field/Core frames, reduced
|
||
to 640×400 JPEGs under 300 KB each.
|
||
|
||
| Generator type | Core result | Owner/Core numeric evidence | Matched capture pair |
|
||
|---|---|---|---|
|
||
| TunnelNetwork | **Approximate.** Core extracts room/tunnel primitives and passage chains, but not the complete owner density stack. | At the owner viewer start, 686,000 LOD0 samples: 2.167784% sign changes; symmetric sampled surface distance 1.0149 m mean / 5.1468 m max; 388 unmatched samples. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_0_TunnelNetwork.viewerstart.compare.stdout.log) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_0_TunnelNetwork_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_0_TunnelNetwork_core_small.jpg) |
|
||
| FlatPlain | **Native slab field missing; generic extracted cave geometry is only an approximation.** The legacy view has its slab/column structure while Core shows a cave-like passage. | 686,000 LOD0 samples: 1.284548% sign changes; 0.4040 m mean / 1.1567 m max surface distance. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_1_FlatPlain.compare.stdout.log) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_1_FlatPlain_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_1_FlatPlain_core_small.jpg) |
|
||
| CrystalChamber | **Native slab and crystal-ceiling field missing; generic cave geometry is only an approximation.** | 686,000 LOD0 samples: 1.284548% sign changes; 0.4040 m mean / 1.1567 m max surface distance. The fixture uses the authored crystal type and its slab parameters. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_2_CrystalChamber.compare.stdout.log) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_2_CrystalChamber_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_2_CrystalChamber_core_small.jpg) |
|
||
| Maze | **Native maze lattice and corridor field missing.** Core's room/tunnel extraction is a poor approximation in this view. | 686,000 LOD0 samples: 13.337026% sign changes; 1.0784 m mean / 5.9201 m max; 3,067 unmatched samples. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_3_Maze.compare.stdout.log) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_3_Maze_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_3_Maze_core_small.jpg) |
|
||
| SurfaceWorld | **Exact density through the temporary legacy route; mesh/presentation remains approximate.** | At the surface crossing, 686,000 LOD0 samples have identical hashes and zero sign changes; sampled surface distance is 0.0767 m mean / 1.0117 m max. At the matched viewer camera, LOD2 also has identical hashes across 109,744 samples; mean surface distance 0.1737 m, max 5.264 m, 63 unmatched samples. LOD0–LOD3 hashes matched in the matched-camera matrix. [LOD0 log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_4_SurfaceWorld.compare.stdout.log) · [cross-LOD logs](Research/OwnerShapeWorld/core_strate_coverage/probes/) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_4_SurfaceWorld_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_4_SurfaceWorld_core_small.jpg) |
|
||
| VerticalShafts | **Native shaft/ledge field missing.** The current Core shape is not a shaft approximation at the probe. | 686,000 LOD0 samples: 6.071137% sign changes; legacy had 3,970 sampled surface vertices while Core had none in those tiles. A center probe changed 2.368222% of signs. The walkability audit also failed 18,122/18,570 passage samples. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_5_VerticalShafts.compare.stdout.log) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_5_VerticalShafts_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_5_VerticalShafts_core_small.jpg) |
|
||
| FloatingIslands | **Native island SDF missing.** Core generates generic cave geometry instead of suspended islands. | 686,000 LOD0 samples: 95.751458% sign changes; 1.4638 m mean / 5.9236 m max surface distance. The center probe changed 100% of signs. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_6_FloatingIslands.compare.stdout.log) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_6_FloatingIslands_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_6_FloatingIslands_core_small.jpg) |
|
||
| Underwater | **Cave shape approximate; water presentation missing.** Core carries no water plane/material in its mesh payload. | At a surface-field sample point, 686,000 LOD0 samples: 8.116472% sign changes; 1.1988 m mean / 5.8131 m max surface distance, with 115 unmatched samples. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/type_7_Underwater.samplepoint.compare.stdout.log) | [Owner](Research/OwnerShapeWorld/core_strate_coverage/type_7_Underwater_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/type_7_Underwater_core_small.jpg) |
|
||
|
||
These numbers come from different authored fields and camera regions, so the percentages are evidence
|
||
for each probe, not a normalized cross-type score.
|
||
|
||
### Passage types and styles
|
||
|
||
The four authored styles map to four legacy passage types in VoxelStrateManager: Straight →
|
||
SlopedTunnel, Worm → CrackCrevice, Spiral → SpiralDescent, and Cascading → CascadingDrops.
|
||
VerticalShaft is the separate open-surface entry, not a selectable FStratePassageConfig style.
|
||
Core reads the manager-generated control-point chain, radii, and floor profile, then rebuilds tapered
|
||
capsules. That preserves the broad path but not the full passage density modifier.
|
||
|
||
| Passage type | Style / source | Numeric evidence, 16 LOD0 tiles | Walkability audit | Capture pair |
|
||
|---|---|---|---|---|
|
||
| SlopedTunnel | Straight | 1.585569% sign changes; 0.4532 m mean / 1.2473 m max. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/style_0_Straight.compare.stdout.log) | PASS, 5,642/5,642 | [Owner](Research/OwnerShapeWorld/core_strate_coverage/style_0_Straight_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/style_0_Straight_core_small.jpg) |
|
||
| VerticalShaft | Open-surface entry | 12.102187% sign changes; 0.9802 m mean / 5.3772 m max. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/vertical_shaft_entry.compare.stdout.log) | PASS, 5,642/5,642 | [Owner](Research/OwnerShapeWorld/core_strate_coverage/passage_type_VerticalShaft_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/passage_type_VerticalShaft_core_small.jpg) |
|
||
| SpiralDescent | Spiral | 1.905539% sign changes; 0.4692 m mean / 2.1429 m max. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/style_2_Spiral.compare.stdout.log) | PASS, 1,545/1,545 | [Owner](Research/OwnerShapeWorld/core_strate_coverage/style_2_Spiral_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/style_2_Spiral_core_small.jpg) |
|
||
| CascadingDrops | Cascading | 1.884840% sign changes; 0.4879 m mean / 2.2203 m max. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/style_3_Cascading.compare.stdout.log) | **FAIL, 365/1,495 solid centerline samples** | [Owner](Research/OwnerShapeWorld/core_strate_coverage/style_3_Cascading_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/style_3_Cascading_core_small.jpg) |
|
||
| CrackCrevice | Worm | 1.793440% sign changes; 0.4680 m mean / 2.1420 m max. [Log](Research/OwnerShapeWorld/core_strate_coverage/probes/style_1_Worm.compare.stdout.log) | **FAIL, 109/1,490 solid centerline samples** | [Owner](Research/OwnerShapeWorld/core_strate_coverage/style_1_Worm_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/style_1_Worm_core_small.jpg) |
|
||
|
||
The non-walkable Worm and Cascading probes violate the requested entrance-to-exit walkability
|
||
invariant. Those styles need correction before the Core route can claim passage coverage.
|
||
|
||
### Strate transitions
|
||
|
||
All three transition fixtures were compared at the generated passage crossing near the strata
|
||
boundary (16 LOD0 tiles, 514,500 lattice samples each). Owner hashes change per transition, while Core
|
||
returns the same hash, 0x7f9999008f887de6, for Gradient, Hard, and Interleaved. The Core representation
|
||
therefore does not yet reproduce the transition field. The Core mesh remains an approximate control-
|
||
point passage through the boundary.
|
||
|
||
| Transition | Sign changes | Mean / max surface distance | Capture pair |
|
||
|---|---:|---:|---|
|
||
| Gradient | 1.186395% | 0.4302 m / 2.0185 m | [Owner](Research/OwnerShapeWorld/core_strate_coverage/transition_0_Gradient_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/transition_0_Gradient_core_small.jpg) |
|
||
| Hard | 1.170262% | 0.4302 m / 2.0383 m | [Owner](Research/OwnerShapeWorld/core_strate_coverage/transition_1_Hard_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/transition_1_Hard_core_small.jpg) |
|
||
| Interleaved | 1.301846% | 0.4622 m / 2.5725 m | [Owner](Research/OwnerShapeWorld/core_strate_coverage/transition_2_Interleaved_legacy_small.jpg) / [Core](Research/OwnerShapeWorld/core_strate_coverage/transition_2_Interleaved_core_small.jpg) |
|
||
|
||
The captures were taken at the passage crossing, not in the solid-only boundary camera used by the
|
||
first probe attempt. Numeric logs are in the probe directory.
|
||
|
||
### Other terrain-changing strate inputs and implementation route
|
||
|
||
The legacy generator also reads world seed and strate bounds; FStrateGenerationParams (worm, room,
|
||
tunnel, cave warp, floor, and detail fields); the archetype structs FSlabGenerationParams,
|
||
FMazeGenerationParams, FSurfaceGenerationParams, FVerticalShaftParams, and FFloatingIslandParams;
|
||
disturbances; weighted/probabilistic terrain-operation stacks; biome definitions and biome-map
|
||
parameters; transition type/blend width; passage style/configuration and generated floor profiles;
|
||
and water-level and render-side water/biome presentation data. The round-4 reader carries the typed
|
||
parameter and operation assets into the standalone snapshot. SurfaceWorld's legacy fallback consumes
|
||
its full density-side stack. The shape-only path still does not evaluate all of those inputs for the
|
||
other archetypes.
|
||
|
||
Recommended next route, ordered by observed visual gap: implement native FloatingIslands, then native
|
||
VerticalShafts and Maze, then native FlatPlain/CrystalChamber slab fields; keep the passage chain native
|
||
but fix Worm/Cascading walkability; implement transition blending in the Core layer field; add
|
||
Underwater's water plane as a separate render payload. Keep the current TunnelNetwork primitive route
|
||
and refine its density operators. A copied-legacy evaluator is a valid temporary bridge where exact
|
||
density is the priority, but the SurfaceWorld timing below shows its cost. A density fallback alone
|
||
cannot create render-side water, biome materials, decorations, or atmosphere.
|
||
|
||
### SurfaceWorld performance and BuildHost verification
|
||
|
||
The matched-camera CPU viewer used 1,294 tiles through LOD8. Owner legacy generation took 23.914 s
|
||
wall / 188.705 worker-seconds; Core with the SurfaceWorld bridge took 23.085 s / 180.562 worker-
|
||
seconds. The prior Step29 Core viewer without the bridge took 0.785 s / 2.538 worker-seconds for the
|
||
same tile count, but it omitted the surface. This is not a controlled per-sample microbenchmark; it
|
||
shows the bridge costs approximately the legacy field route for the complete view. Captures and logs
|
||
are under core_strate_coverage.
|
||
|
||
BuildHost was rebuilt and the actor test passed with a SurfaceWorld strate. The initial W1/W8/W16
|
||
hashes are stable: density 0xccd5858289627767, mesh 0x33c4f191ee318a40, payload
|
||
0xd487ed030c6622cd, topology 0xf5f6262021a780a0. At the surface actor position, all 2,553 expected
|
||
visual tiles matched standalone; 640 fine tiles compiled, 3,588 neighbour faces and 448 LOD
|
||
transitions were checked, and the biome query returned Biome_Surface_Plain (index 2). Surface hashes:
|
||
density 0xb80442b34787eb4e, mesh 0xfecc9327337abbfb, payload 0xca57a4e295ce0602, topology
|
||
0x7f187a07e5c19f7f. The extra loaded count (3,288) includes support/stale keys; visual keys remain
|
||
complete. Full log: [CoreWorldValidation.stdout.log](../Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/CoreWorldValidation.stdout.log).
|
||
|
||
The UBT host build passed. The actor test took 12m59s and peaked at 3,042,344,960 private bytes
|
||
(about 2.83 GiB), below the 15-minute / 8-GiB limits. No 0xC0000142 retry occurred. The only crash
|
||
folder under BuildHost is the pre-existing UECC-Windows-F1A3EFD5469F5DD62E68EBBACAC84376_0000;
|
||
there was no new crash.
|
||
|
||
### Round-4 failed attempts and retries
|
||
|
||
| Attempt | Outcome |
|
||
|---|---|
|
||
| Surface numeric probe at viewer z = −1,024 m | Wrong vertical slice for the standalone JSON's SurfaceWorld strate; no surface triangles. Corrected to the terrain crossing near z = −400 m and matched capture camera z = −340 m. |
|
||
| First style matrix | The fixture changed nested asset PassageConfig while the reader consumes the duplicated top-level passage_config. All four probes therefore stayed Straight. Regenerated each fixture with both copies updated and reran. |
|
||
| Vertical-shaft probe invocation | Exit 2 because the loop named a JSON file that had not been generated. Reran against the original layout, which contains the open-surface VerticalShaft entry. |
|
||
| First LOD matrix invocation | Exit 2 because PowerShell split a computed area argument and the viewer treated surface_lod0 as a data path. Reran with explicit argument strings; LOD0–LOD3 hashes matched. |
|
||
| Step30 viewer build | The script printed that vswhere.exe was unavailable, then used the installed compiler toolchain; Core compile, symbol audit, and viewer link passed. |
|
||
|
||
No round-4 run crashed or needed a retry. No build/test step exceeded 15 minutes. Switch-off remains the
|
||
legacy route. After the owner rebuild, recheck the SurfaceWorld shoreline, hills, and biome transitions
|
||
at the matched camera after fine tiles settle; also recheck the opening-room floor. The captures show
|
||
the exact-density bridge improves the surface field, but water/presentation and the other missing
|
||
archetypes are still open work.
|
||
|
||
### Round-5 native SurfaceWorld delivery
|
||
|
||
Round 4 above is historical. The native manifest route now supersedes the temporary legacy density
|
||
bridge for a reviewed `SurfaceWorld` when `AVoxelWorld::bUseVoxelForgeCore` is enabled. Existing Core
|
||
cave generation remains supported when there is no world-assembly manifest. With the switch off,
|
||
legacy generation and the existing season identity hash remain on the old path.
|
||
|
||
The editor `UVoxelSettings` asset now has a `SourceWorldAssemblyManifestJson` picker and
|
||
`ImportWorldAssemblyManifestJson` button. Import stores canonical JSON plus the verified Core content
|
||
hash in the settings asset. `GetCurrentSeasonContentHash()` combines that hash only while Core is
|
||
active. Core adapter initialization checks the manifest seed against the resolved layout and
|
||
requires exact, unique `SurfaceWorld` slot index/top/bottom matches. The test passes the reviewed
|
||
JSON to BuildHost through `-coreworldassembly`; it does not edit an asset. Manifest, recipe and plan
|
||
hashes were `8933693d9560ba9f`, `c37de78b759c0a4c` and `1ca84619c8600ee5`.
|
||
|
||
The final BuildHost commandlet passed the W1/W8/W16 matrix, cave initial streaming, anchor movement,
|
||
carving, lower-surface travel and native SurfaceWorld travel. At `(37,165,-2011)` Core voxels, all
|
||
2,553 expected visual tile hashes matched standalone Core. Coverage checked 573 local tiles, 3,438
|
||
neighbour faces and 432 LOD transitions across two regions. The collision gate checked 125 expected
|
||
near tiles: 36 non-empty tiles had cooked bodies; 89 expected-empty tiles correctly had none. Native
|
||
SurfaceWorld hashes were density `56ccc76575aa5f5f`, mesh `f3aeb31de1f967c1`, payload
|
||
`95cb4781a1be4b73`, topology `26ac366d430599bd`. The BuildHost path uses Unreal mesh upload and
|
||
Chaos collision cooking; standalone checks field and mesh output only.
|
||
|
||
The narrow switch-off check is source-level, not a second runtime actor session: Core remains
|
||
default-off; the legacy `UpdateChunksAroundPosition` branch is retained; Core-only manifest
|
||
initialization and collision admission are guarded by the switch; and the legacy hash returns before
|
||
reading optional manifest data when disabled. This does not claim a full flag-off runtime replay.
|
||
|
||
In the same BuildHost session, 2,553 identical keys were generated with hashes on. Native
|
||
`Heightfield2D` vs the legacy bridge took 0.015903 vs 0.012752 s for region compilation and
|
||
96.800984 vs 197.333401 s for summed tile generation; compile plus tiles was 96.816887 vs 197.346153
|
||
s (2.038× speedup). This is serial headless tile generation, not rendered frame time. The ~1.57 s
|
||
full-view aim remains unmet: the last full 529-tile LOD8 stream measured 4.446 s, 2.83× the aim.
|
||
No full-view viewer benchmark ran in round 5.
|
||
|
||
The existing downscaled native/owner cliff overlook pair was inspected. The sharp ridge peaks remain
|
||
attached to the highland surface with no detached shard trail, so the field/mesh was not altered;
|
||
their appearance is left for the owner to judge in-game. Handoff instructions and actor-local camera
|
||
targets for the surface, coast, cliff, route and cap are in
|
||
[`ASSEMBLER_M1_REPORT.md`](ASSEMBLER_M1_REPORT.md). Likely project compile touchpoints are
|
||
`VoxelSettings.h/.cpp`, `VoxelForgeCoreAdapter.cpp`, `VoxelWorld.cpp` and
|
||
`VoxelForgeExploreCommandlet.cpp`.
|
||
|
||
Round-5 BuildHost run ledger: the first UBT compile failed to link non-exported settings methods;
|
||
exporting them made the retry pass. Actor attempt 1 found a surface support-tile hash mismatch;
|
||
attempt 2 reproduced it and exposed collision work starting before region admission. Actor attempt 3
|
||
failed the legacy biome-query assertion because the native surface does not provide that legacy
|
||
decorator query; it was replaced with direct native heightfield sampling. After the collision-admission
|
||
fix, the actor test passed. The final rerun after gating the manifest hash on the Core switch also
|
||
passed in 9m20s with 3,880,357,888 bytes peak sampled private memory (3.61 GiB). No `0xC0000142`
|
||
retry or new UECC folder occurred. The owner's project was not opened or built and no `.uasset` was
|
||
edited.
|