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