Files
VoxelForge/Standalone/Research/WorldAssemblerM3/Research17/REPORT.md
T

7.2 KiB
Raw Blame History

VoxelForge Research 17 — Unreal landmarks and cavern graphs

Add an optional CoreGeometry block to the existing per-strate UVoxelStrateDefinition asset. It is already the strate’s content bag and a UPrimaryDataAsset; a separate asset adds references and loading work, while a recipe flag is too coarse to describe authored atoms. Epic’s Data Assets documentation

The block can hold stamp requests and cavern room/edge inputs. Give every atom an explicit stable string ID, and author distances in metres. Convert once to integer micrometres at the adapter boundary, following R8’s unit and versioning plan. UE defaults to centimetres, and unit metadata is editor-facing, so the adapter must use the field’s actual stored unit. UE units, property metadata

Keep FStrateLandmark as the presentation and streaming entry. Add an optional reference from landmarks—and, when needed, decorations—to a Core stable ID. The existing landmark instances are keyed by lattice cell and entry index, so those keys cannot identify a fixed Core feature across systems. See FStrateLandmark and LandmarkInstances.

Adapter flow and runtime lookup

AttachValidatedWorldAssembly builds the layout at line 1045 and plans passages at lines 1259–1265. Gather the authored requests from each resolved slot, then call ResolveResolvedLayoutStampsV2 and ResolveResolvedCavernGraphV1 after passage planning and before Layout.finalize at line 1268. The demo uses that resolver order. The adapter already writes the resulting layout JSON at lines 1273–1274; ResolvedLayoutSnapshotV3 already contains the stamp and graph records.

Namespace IDs with the strate and feature name: the stamp resolver requires unique non-empty IDs and derives placement randomness from seed, strate, and ID. It performs bounded deterministic placement from a preferred anchor. The graph resolver, however, currently derives seeds and bounds and validates authored room centers and edge control points; it does not plan graph routes or choose their positions.

The runtime snapshot parser already reads resolved_layout_json into ResolvedWorldSnapshot, whose resolvedLayout() accessor is available before the snapshot is moved into the Core world. AVoxelWorld::InitializeVoxelForgeCoreWorld is the handoff point. Cache or expose that layout there, then extend UVoxelContentManager::Initialize to retain it. Today the manager parses the world assembly manifest only.

Build a non-reflected runtime TMap<FString, FCoreResolvedAnchor> from the layout’s stable IDs to local positions and bounds. Actor, light, and decoration placement can then resolve the same ID. For example, a light reads the chamber center, while a set-piece references the dais stamp and can surface-find at that XY. Transform the resulting local position through the world actor transform.

Useful UE types are USTRUCT(BlueprintType) and UPROPERTY for authored records; FString, TArray, an enum, and explicit metre-valued fields for authoring; and a plain C++ TMap, FTransform, and shared immutable runtime snapshot for lookup. Keep Core’s std::string, std::vector, and resolver types out of reflected properties. UE struct reflection, reflection and UHT

Determinism, multiplayer, and risks

Stamp and graph seeds are deterministic from the same world seed, strate, and stable ID. Peers with matching authored assets, resolver versions, and seed do not need the generated records replicated. Keep terrain edits in the existing diff layer. Include the resolved layout’s stableIdentity in the multiplayer/content identity: GetCurrentSeasonContentHash currently appends the assembly content hash, while the resolved layout is a separate payload. Gameplay actors still need normal server authority and replication; deterministic client-local spawning suits cosmetic props. UE property replication

UHT must parse the new reflected structs and fields; use UE-supported property types and avoid exposing Core C++ types through UPROPERTY. The strate asset already registers a custom version in VoxelStrateDefinition.cpp. Extend that version if a migration is needed; keep existing chunk/voxel fields’ meaning unchanged. Additive optional fields can default empty. Epic documents the GUID-based custom-version pattern and object-level Serialize migration path. Asset versioning

Ordered implementation plan

  1. Core-only portability gate: compile the existing Core target and resolver API independently. Compilable on Linux: yes; this does not validate the Unreal adapter.
  2. Add reflected authored atom structs and the optional per-strate property, with explicit stable IDs and metre semantics. Compilable on Linux: no; requires UHT.
  3. Map authored atoms to Core requests in AttachValidatedWorldAssembly; invoke the stamp and graph resolvers before layout finalization. Compilable on Linux: no; Unreal adapter.
  4. Cache/expose the parsed resolved layout and add stable-ID lookup for presentation placement. Compilable on Linux: no; Unreal runtime.
  5. Add content-hash coverage for stableIdentity, then run UHT/UBT and review asset migration/resave behavior in the owner’s Windows editor. Compilable on Linux: no; the adapter and UHT require the Unreal build environment.

Question for the owner

Should cavern room centers and edge control points be authored in metres for the current graph resolver, or must Core place the graph from stable IDs? The current resolver supports authored points and deterministic irregularity, but does not generate the graph route.

Read-only review only; no source edits, builds, or tests were made.