docs(assembler): Sol 6.1 review of the L20 strate/units design
Verdict: direction right; preserve today's bounds as compatibility data but reject overlaps in new layouts; approve the LOD2 boundary fix with a precise affected region; one director-owned vertical partition (strate interior / shared bedrock band / explicit void); bedrock = solid volume + explicit LOD-stable surface; first step = versioned resolved-layout snapshot + validator, no output change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
This commit is contained in:
1 parent
6f9c7bd652
commit
5d5447dc32
1 file changed
+233
@@ -0,0 +1,233 @@
|
|||||||
|
# Sol 6.1 (medium) read-only review of the L20 design — 2026-10-20
|
||||||
|
|
||||||
|
Requested by the owner. Prompt: `Saved/Linux/claude/sol-l20-review.md` (copied below the answer). Session `01a1582c-547a-7701-9d9e-35239b7f0a26`, 68,458 tokens, sandbox read-only.
|
||||||
|
|
||||||
|
**The direction is right. Preserve today’s world during conversion, but treat inconsistent bounds as compatibility data, not valid new layout. Allow the SurfaceWorld LOD2 boundary fix, with a precisely defined affected region and unchanged density.**
|
||||||
|
|
||||||
|
L20 needs a stronger bedrock model and an earlier ownership contract. Adding floor bedrock everywhere is also a deliberate geometry change: current FloatingIslands v3 explicitly omits its lower seal.
|
||||||
|
|
||||||
|
I only read files; I did not build, run, or modify anything.
|
||||||
|
|
||||||
|
**1. The two decisions**
|
||||||
|
|
||||||
|
**Decision 1: preserve first, repair separately.** L17 demonstrates why: unifying the chunk scale removed the approved SurfaceWorld ground and moved the world ([Linux17/REPORT.md:168](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux17/REPORT.md:168)).
|
||||||
|
|
||||||
|
The mismatch is real. SurfaceWorld uses slot chunks directly as 32 Core voxels; FloatingIslands applies the owner/Core ratio ([VoxelForgeCoreAdapter.cpp:290](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:290), [VoxelForgeCoreAdapter.cpp:464](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:464)).
|
||||||
|
|
||||||
|
However, preserve **effective behavior**, not just converted endpoints. Dispatch itself uses different conversions: SurfaceWorld divides Z by 32, while FloatingIslands uses the owner/Core scale ([ShapeWorldInternal.h:2130](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:2130), [ShapeWorldInternal.h:2158](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:2158)). An apparent interval between bounds therefore does not prove that interval currently generates air.
|
||||||
|
|
||||||
|
Keep historical overlaps and ambiguities in a versioned compatibility snapshot. **Reject overlaps in newly authored layouts.** Otherwise preservation becomes permanent acceptance of the bug.
|
||||||
|
|
||||||
|
**Decision 2: approve the change in principle.** L19 measured actual lower-ground extraction differences, not ceiling triangles: up to 1.50 m and 7.73 m ([Linux19/REPORT.md:9](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux19/REPORT.md:9)). An explicit ceiling cannot fix these.
|
||||||
|
|
||||||
|
Define the affected tiles from the observed surface and transition support, including halos—not merely distance from a nominal strate plane. Preserve exact queries and unaffected near-player geometry. Validate against the same physical surface so the audit cannot “improve” by pairing different surfaces or hiding terrain.
|
||||||
|
|
||||||
|
Metre authoring and default 25 cm voxels are sound. Fixed 32³ tiles mean physical tile width still follows voxel size; if Jahni wants fixed physical streaming regions, introduce those separately from internal tiles.
|
||||||
|
|
||||||
|
**2. A concrete strate structure**
|
||||||
|
|
||||||
|
Use one immutable, versioned director output. Distinguish a strate’s **generator interior** from the bedrock separating interiors. This makes thickness and ownership unambiguous.
|
||||||
|
|
||||||
|
```text
|
||||||
|
ResolvedWorld
|
||||||
|
schemaVersion, evaluatorVersion, seed, worldIdentity
|
||||||
|
physicalUnit = fixed integer unit independent of voxel size
|
||||||
|
strates[] // ordered downward
|
||||||
|
verticalSegments[] // exact partition of declared world extent
|
||||||
|
interfaces[]
|
||||||
|
passages[]
|
||||||
|
|
||||||
|
Strate
|
||||||
|
stableId // persisted; independent of array position
|
||||||
|
order
|
||||||
|
bottomM, topM // generator interior: [bottomM, topM)
|
||||||
|
voxelSizeM = 0.25
|
||||||
|
latticeOriginM
|
||||||
|
generatorKind
|
||||||
|
recipeId, recipeVersion, resolvedRecipe, seedKey
|
||||||
|
floorBandId, ceilingBandId
|
||||||
|
interfaceAboveId, interfaceBelowId
|
||||||
|
|
||||||
|
VerticalSegment
|
||||||
|
stableId, bottomM, topM
|
||||||
|
kind = StrateInterior | Bedrock | VoidGap
|
||||||
|
ownerId
|
||||||
|
|
||||||
|
BedrockBand
|
||||||
|
stableId, bottomM, topM
|
||||||
|
thicknessM = topM - bottomM
|
||||||
|
volumeMaterialId
|
||||||
|
upperFaceMaterialId, lowerFaceMaterialId
|
||||||
|
digPolicy = Diggable | Protected | Restricted
|
||||||
|
allowedPassageIds[]
|
||||||
|
surfaceDescriptorIds[]
|
||||||
|
|
||||||
|
Interface
|
||||||
|
stableId, upperStrateId, lowerStrateId
|
||||||
|
orderedSegmentIds[] // bedrock, optional void, further bedrock
|
||||||
|
passagePlacementRecipe
|
||||||
|
resolvedPassageIds[]
|
||||||
|
|
||||||
|
Passage
|
||||||
|
stableId, interfaceId
|
||||||
|
physical tunnel shape, aperture boundaries
|
||||||
|
upper/lower endpoints, landing/support geometry
|
||||||
|
crossedBandIds[], clearance, carvePermission
|
||||||
|
```
|
||||||
|
|
||||||
|
Author in metres; serialize canonical fixed physical units with explicit rounding. The resolved fields above are produced once, not independently editable copies.
|
||||||
|
|
||||||
|
For a shared slab, the upper strate’s floor and lower strate’s ceiling reference **the same band**. Its thickness and digging policy cannot disagree between sides. Separate skins with a void between them require three explicit segments.
|
||||||
|
|
||||||
|
I recommend ordinary inter-strate bedrock remain diggable, preserving the established player-dug descent behavior ([ARCHITECTURE.md:472](/home/jahni/VoxelM/Plugins/VoxelForge/ARCHITECTURE.md:472)). Protection should be an explicit band policy.
|
||||||
|
|
||||||
|
The invariants are:
|
||||||
|
|
||||||
|
- Unique stable IDs; explicit order; finite bounds; positive interior height and bedrock thickness.
|
||||||
|
- Every physical height within the declared stack belongs to exactly one segment. No overlaps or implicit gaps.
|
||||||
|
- Every strate has floor and ceiling bedrock, including terminal strates.
|
||||||
|
- Interiors remain closed except through registered passages or authorized player-created apertures.
|
||||||
|
- A void gap lies between closed skins. A freely open connection requires an explicit aperture, potentially covering the whole interface.
|
||||||
|
- Passages cross every intervening band and provide usable entrances, exits, and support.
|
||||||
|
- All generators, proofs, streaming, meshing, collision, and material queries consume this snapshot. None reconstruct boundaries from chunk indices.
|
||||||
|
|
||||||
|
Keep legacy recipe seed keys frozen during migration. Switching randomness from strate index to stable ID must be versioned separately to avoid changing the world.
|
||||||
|
|
||||||
|
**3. Bedrock should be both volume and explicit geometry**
|
||||||
|
|
||||||
|
Use an authoritative solid volume for density, digging, collision queries, and conservative proofs, plus explicit boundary surfaces for reliable extraction. Both representations derive from the same band and aperture descriptors.
|
||||||
|
|
||||||
|
Density alone cannot guarantee a thin band survives coarse sampling. Conversely, a visual plane alone supplies no solid interior and can disagree with collision or digging.
|
||||||
|
|
||||||
|
Current code illustrates the mismatch: the upper seal fills inward over its thickness, while fallback ceiling vertices are placed at `Bounds.TopZ` ([VoxelDensityPrimitives.h:44](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Public/VoxelDensityPrimitives.h:44), [FarShellsInternal.h:1238](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/FarShellsInternal.h:1238)). The new contract must distinguish the band’s outer boundary from its room-facing surface.
|
||||||
|
|
||||||
|
For a ceiling above an interior, its lower face is at `topM`; for a floor below an interior, its upper face is at `bottomM`. Thickness extends away from the interior.
|
||||||
|
|
||||||
|
The mesher should own each exposed face once, suppress overlapping ordinary extraction, and use shared edge anchors across LODs. Passage mouths need explicit clipping and wall geometry; corner sampling alone can miss a small aperture.
|
||||||
|
|
||||||
|
Authorized edits must modify both density and surface extraction. Protected bands require explicit edit masking. Generated passages carve after bedrock composition, consistent with today’s passage ordering ([VoxelDensityPrimitives.h:86](/home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Public/VoxelDensityPrimitives.h:86)).
|
||||||
|
|
||||||
|
Collision uses the same geometry semantics at a gameplay resolution independent of camera LOD. Peers reproduce bands and generated passages from the versioned plan; only player edits need synchronization.
|
||||||
|
|
||||||
|
Cost stays local: cheap band queries and flat faces generally, extra refinement around openings and edited areas.
|
||||||
|
|
||||||
|
**4. What I would change in L20**
|
||||||
|
|
||||||
|
My top three risks are:
|
||||||
|
|
||||||
|
1. **Migrating bounds without migrating dispatch.** Today’s “resolved” bounds still consult the manager and branch by generator ([ShapeWorldInternal.h:67](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:67)). Snapshot ownership, fallback behavior, and recipe anchors together.
|
||||||
|
2. **Changing gameplay under structural cleanup.** FloatingIslands v3 applies only an upper seal ([ShapeWorldInternal.h:2192](/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:2192)). Restoring a floor changes visibility and descent. Require a new layout version; do not silently reintroduce the removed floor.
|
||||||
|
3. **Maintaining conflicting density, mesh, and collision boundaries.** Explicit surfaces must be authoritative constraints derived from bands, rather than another repair overlay.
|
||||||
|
|
||||||
|
Reorder the migration to: compatibility snapshot → canonical ownership and bedrock schema → minimal shared boundary composition → targeted LOD transition prototype → metre authoring and generator adapters. Keep the broad generator/helper refactor incremental. Mixed resolutions remain last.
|
||||||
|
|
||||||
|
**5. Smallest first implementation**
|
||||||
|
|
||||||
|
Implement a **versioned resolved-layout snapshot and validator**, populated by the existing director/adapter. Record actual physical bounds, recipe/cap anchors, voxel sizes, current floor/ceiling behavior, and dispatch provenance. Flag incompatible intervals explicitly. Leave evaluation unchanged.
|
||||||
|
|
||||||
|
Its acceptance test should require:
|
||||||
|
|
||||||
|
- Exact preservation of existing resolved anchors and recipe values, including routes and cap profiles.
|
||||||
|
- Boundary probes immediately below, at, and above every endpoint, comparing actual old dispatch with the snapshot’s recorded behavior.
|
||||||
|
- Deterministic identity across worker counts and serialization round trips.
|
||||||
|
- Rejection of overlapping or uncovered new layouts.
|
||||||
|
- Existing SurfaceWorld density and geometry hashes unchanged; L19 ceiling coverage unchanged.
|
||||||
|
|
||||||
|
This delivers inspectable strate structure first. Enforcing new floors and repairing ledges then become separate, measurable world changes.
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
# VoxelForge — design review (Sol, read-only): strate structure, bedrock and the L20 decisions
|
||||||
|
|
||||||
|
You are reviewing a design for VoxelForge, a voxel terrain plugin for a multiplayer Unreal Engine
|
||||||
|
game, with its generation done in a C++ Core library. The game is underground: the world is a
|
||||||
|
vertical stack of **strates** (layers). Each strate has its own generator type:
|
||||||
|
- SurfaceWorld: an enclosed surface-like heightfield world;
|
||||||
|
- FloatingIslands;
|
||||||
|
- caves, and future types.
|
||||||
|
|
||||||
|
Players travel between strates through passages. Every machine generates the same terrain from a
|
||||||
|
seed. Only player edits cross the network.
|
||||||
|
|
||||||
|
**This is a read-only review.** Read files, but don't build, run, edit or create anything. The
|
||||||
|
owner pays for this review, so be efficient: read what you need, and keep the answer focused and
|
||||||
|
concrete.
|
||||||
|
|
||||||
|
## Read first
|
||||||
|
|
||||||
|
- `/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/DESIGN_STRATA_UNITS_AND_LAYERS.md`: the design
|
||||||
|
under review (round L20).
|
||||||
|
- `/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux20/REPORT.md`
|
||||||
|
- For the bugs that motivated it: `.../Linux17/REPORT.md`, `.../Linux18/REPORT.md` and
|
||||||
|
`.../Linux19/REPORT.md`, in the same folder. Each has an "Orchestrator review" section at the end.
|
||||||
|
- Code, as needed:
|
||||||
|
- `Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp` (plan building: SurfaceWorld vs
|
||||||
|
FloatingIslands chunk conversion);
|
||||||
|
- `Source/VoxelForge/Private/VoxelStrateManager.cpp` and `Source/VoxelForge/Public/VoxelStrateTypes.h`
|
||||||
|
(strate slots and params);
|
||||||
|
- `Standalone/Core/src/ShapeWorldInternal.h` (`FResolvedStratumBounds`, `GetResolvedStratumBounds`);
|
||||||
|
- `Standalone/Core/src/FarShellsInternal.h` (`AppendStratumBoundaryCeilings`);
|
||||||
|
- `Source/VoxelForge/Public/VoxelDensityPrimitives.h` (boundary seals);
|
||||||
|
- `CLAUDE.md`, and `ARCHITECTURE.md` (§8) for the hard rules.
|
||||||
|
|
||||||
|
## The owner's direction
|
||||||
|
|
||||||
|
The owner is Jahni. Quotes:
|
||||||
|
- "Everything should use a parameter like on the strate, saying which voxel size it is, by default
|
||||||
|
25 for everyone, same for island."
|
||||||
|
- "Our system should be in different categories: the director/orchestrator, the generators (all
|
||||||
|
using the same kind of format, helper functions … from a shared library like noise functions) and
|
||||||
|
the mesher; the generators are dictated by our current strate parameters."
|
||||||
|
- "The voxel size shouldn't dictate the size of a chunk … wouldn't it be better to have like Unreal
|
||||||
|
unit distance, and have x voxels fill it?"
|
||||||
|
- "Any strate should have a ceiling, since we're underground."
|
||||||
|
- "The ceiling height is decided by the strate parameter, it's not something unique to sky island."
|
||||||
|
- Now: **"we need proper strate structure, knowing where each starts etc."**, including the strate
|
||||||
|
**bedrocks (ceiling and floor)**.
|
||||||
|
|
||||||
|
## What I (the orchestrator) recommended, which he wants judged
|
||||||
|
|
||||||
|
1. **Layout is authored in metres;** each strate has a voxel size (default 25 cm); internal tiles
|
||||||
|
stay 32³ voxels. Units cost nothing at run time, while the voxel count does.
|
||||||
|
2. **Decision 1 (preservation):** when converting today's chunk-based strate parameters to metres,
|
||||||
|
keep every strate exactly where it currently is in the generated world, including any gap or
|
||||||
|
overlap that the current 8 m (SurfaceWorld) vs 4 m (FloatingIslands) per-chunk mismatch creates.
|
||||||
|
Report those gaps and overlaps, then tune in metres. The alternative is to force them to meet
|
||||||
|
during the migration.
|
||||||
|
3. **Decision 2:** allow step 5 of the migration (an explicit, LOD-stable interface surface) to
|
||||||
|
change SurfaceWorld LOD2 output near strate boundaries, to fix the owner's "ledges" (cross-LOD
|
||||||
|
ring steps of up to 1.5 m and 7.7 m at the FloatingIslands/SurfaceWorld interface). Near-player
|
||||||
|
terrain away from boundaries must stay identical.
|
||||||
|
|
||||||
|
## Questions (answer each)
|
||||||
|
|
||||||
|
1. **Are the two decisions and the direction right?** Say where you'd decide differently, and why.
|
||||||
|
Is preserving today's possibly-inconsistent bounds the right first step, or does it entrench a
|
||||||
|
bug? Is there a better migration order?
|
||||||
|
2. **Propose a proper strate structure.** A concrete data model the director owns. For each strate:
|
||||||
|
- its stable ID and order;
|
||||||
|
- top and bottom in metres;
|
||||||
|
- **floor bedrock and ceiling bedrock:** thickness in metres, material, whether players can dig
|
||||||
|
through, and how passages pierce them;
|
||||||
|
- its voxel size;
|
||||||
|
- its generator and recipe;
|
||||||
|
- its interfaces to the strate above and below: solid bedrock band, open void, passage
|
||||||
|
placement.
|
||||||
|
|
||||||
|
Define the invariants: no overlaps; every metre owned by exactly one strate or one explicit
|
||||||
|
bedrock/gap band; ceiling and floor always closed, except at passages; contiguous or explicit
|
||||||
|
gaps. Show how "where each strate starts and ends" becomes a single source of truth that every
|
||||||
|
generator and the mesher read, never re-derive.
|
||||||
|
3. **Bedrock as geometry.** Should a ceiling or floor be a density band (a seal), an explicit
|
||||||
|
surface the mesher knows about, or both? Weigh LOD stability (the ledge problem: thin seals
|
||||||
|
extract at different heights per LOD), collision, player digging, multiplayer determinism, and
|
||||||
|
cost. Give a recommendation.
|
||||||
|
4. **What in the L20 design would you change, cut, or reorder?** Name the top 3 risks.
|
||||||
|
5. **The smallest first implementation step** that delivers the strate structure without moving the
|
||||||
|
approved SurfaceWorld world, and its acceptance test.
|
||||||
|
|
||||||
|
## Answer format
|
||||||
|
|
||||||
|
Plain English. The owner reads it, so lead with your verdicts in a few lines, then the details.
|
||||||
|
Around 1,500 words at most, plus the data-model sketch. Cite file:line where you rely on code.
|
||||||
Reference in new issue
Block a user