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:
1 parent
29ca99af7f
commit
075e58187e
7 files changed
+2069
-118
No files matched your search
+30
-33
@@ -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)
|
||||
|
||||
|
||||
Reference in new issue
Block a user