wip(unreal): AVoxelWorld Core mode -- streaming, collision and carving through VoxelForgeCore

Luna, integration round 2 (BuildHost only): AVoxelWorld::bUseVoxelForgeCore (default
false) routes desired tiles, generation, upload/collision and carving through Core.
Core-only CoreClipRadius=3 / CoreMaxClipLevel=8 (owner's asset untouched); 25 cm Core
voxels in every cm<->voxel conversion; legacy brush sizes scaled to keep physical size;
UE-task JobScheduler, epoch-checked Mpsc results, existing RMC upload + collision cook;
carving via sequenced applyEditTransaction. Switch off: BuildDesiredTiles takes the old
path unchanged.
BuildHost proof (actor commandlet, staged copies of the owner's assets): all 2,226
initial tiles hash-match standalone Core; collision bodies as expected; anchor move
requests 1 / releases 1 tile; carved tile hash matches standalone; peak ~2.68 GiB.
Legacy CrossPlatformDigest automation: 115,000 samples pass (wrapper flagged an
analytics write outside isolation).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-08 20:33:46 +02:00
1 parent 29ca99af7f
commit 075e58187e
7 files changed
+2069 -118

No files matched your search

+30 -33
View File
@@ -1065,42 +1065,39 @@ timings are intentionally diagnostic metadata and do not affect world or image c
viewer remains a separate display-only consumer: it must load this OBJ/manifest and never evaluate
density or generate geometry.
### 8.17 Standalone Core in Unreal — integration round 1
**Status (2026-10-08):** the `VoxelForgeCore` runtime module and manifest shims build and link in the
isolated BuildHost. The editor commandlet can adapt the owner's copied settings/strate assets into
schema-v1 JSON, resolve it through `ResolvedWorldSnapshot::FromJson`, and reproduce the standalone
hashes at compile worker limits 1, 8, and 16. This has not yet changed the `AVoxelWorld` generation
route. There is no `bUseVoxelForgeCore` property, and no world should be switched yet.
### 8.17 Standalone Core in Unreal — integration round 2
**Status (2026-10-08):** `AVoxelWorld::bUseVoxelForgeCore` now selects a Core runtime route and is
false by default. Core mode has independent `CoreClipRadius=3` and `CoreMaxClipLevel=8` properties;
it does not read or write the older clip properties or owner assets. BuildHost UBT and the Core link
symbol audit pass. A headless BuildHost actor proof matches all initial tile hashes against standalone
Core, checks collision readiness against the expected non-empty level-0 tiles, moves a streaming
anchor, and applies a transaction edit. The current-plugin switch-off baseline is the narrow
`VoxelForge.Determinism.CrossPlatformDigest`; it passes but does not spawn an actor with the switch
false, so it is a legacy-generator baseline rather than an actor-level A/B proof.
The commandlet adapter is game-thread-only: it resolves UObjects and soft references, writes stable
property/map/set order, and emits values rather than UObject pointers. It writes the standalone
schema scale of 25 cm per voxel. The plugin's existing Runtime generator still defines
`VOXEL_SIZE=12.5 cm`, so a Core mesh-to-`FVoxelMeshData` bridge must define the coordinate/scale
conversion before runtime use. The staged `DA_Settings` also says `MaxClipLevel=6`, while the
standalone owner JSON says 8; hash validation keeps the authored JSON unchanged and applies the
reference harness view (`clip_radius=3`, `max_clip_level=8`) only to its validation copy.
The game-thread asset adapter emits the immutable schema-v1 input and resolves it through
`ResolvedWorldSnapshot::FromJson`; Core workers receive no UObjects. The Core route asks
`World::desiredTiles` and `prioritizeTiles`, compiles and generates through Unreal tasks, and carries
the generation `Epoch` through MPSC results. The shared payload builder, RealtimeMesh upload, and
collision cook remain the final path. Workers observe `bShuttingDown`, and `EndPlay` drains active
tasks. Preserve §8.10 streaming, cancellation, epoch, collision-handoff, and per-frame-budget rules.
The intended side-by-side runtime route is:
Core `Vec3d` positions and tile keys are in voxel space, one voxel is 25 cm, and Core mesh vertex
positions are already in centimetres. The bridge copies those mesh positions directly; player,
anchor, query, and edit inputs convert world centimetres using the Core scale. High-level brushes
that historically express dimensions in the plugin's 12.5 cm voxels scale radius, extent, and falloff
by 12.5/25 to preserve physical dimensions. The low-level `ApplyModification` path expects active
voxel units. Tile keys remain Core keys; only legacy material lookup maps Core tile spans into the
existing strate chunk layout.
1. Add `bUseVoxelForgeCore=false` to `AVoxelWorld`. The false branch must retain the existing field,
mesher, output, streaming, and collision behavior.
2. On the game thread, adapt owner assets to an immutable schema-v1 snapshot. Keep UObjects out of
Core and worker data.
3. On the Core branch, ask `World::desiredTiles` and `prioritizeTiles` for the target set/order;
compile the initial field using a `JobScheduler` backed by Unreal's task system. The plugin still
owns work admission, worker lifetime, cancellation, `bShuttingDown`, and the generation `Epoch`.
4. Run `generateTile` on the plugin workers, explicitly reconcile Core centimetre positions with
the Runtime voxel scale, then copy mesh arrays/groups into `FVoxelMeshData`. Let the existing
`BuildTileStreamSet` → MPSC result → epoch check → RealtimeMesh upload/collision-cook path consume
the result.
5. For carving, drain Core calls on the current `World`, call `applyEditTransaction` with an
authority sequence and ordered brushes, bump the epoch, and regenerate its returned desired tiles.
Keep the current plugin behavior when the switch is false.
The module-link and asset-adapter evidence, including the settings mismatch and incomplete runtime
work, is recorded in [`Standalone/UNREAL_INTEGRATION_REPORT.md`](Standalone/UNREAL_INTEGRATION_REPORT.md).
Keep every §8.10 streaming, cancellation, epoch, collision-handoff, and per-frame-budget invariant
when implementing this route; Core does not own those systems.
Carving drains in-flight Core calls, applies an increasing-sequence `applyEditTransaction`, advances
the epoch, and regenerates the returned affected keys. This leaves a transaction boundary for later
replication; no transport is implemented. Existing streaming anchors are included in Core desired
tiles; the BuildHost shift check covers `CollisionOnly`. `FullVisual` is wired through the same
anchor reconciliation but has not had an independent headless assertion. The owner-editor visual
and physical play check remains the hand-off step. See
[`Standalone/UNREAL_INTEGRATION_REPORT.md`](Standalone/UNREAL_INTEGRATION_REPORT.md) for evidence,
known limits, and instructions.
## 9. Multiplayer model (listen-server first, dedicated-friendly)