feat(world): the XY edge seal -- the fourth structural invariant
VF_ApplyBoundarySeal was purely VERTICAL: it sealed each strate's ceiling
and floor and there was no horizontal equivalent, because until the depths
were bounded the world had no sides. The GDD now says "bounded, but
gigantic", so a player who walked far enough reached unterminated
generation running off into nothing.
Built as a FORCING op, appended automatically and not author-omittable, so
an invented strate cannot forget its own edge. Because a forcing op proves
AllSolid in its band, the outer shell also becomes free to skip in tile
classification -- correctness and a perf win from one change.
order spine -> vertical seal -> passage carving -> XY EDGE SEAL
-> disturbances -> diff
A near-rim passage may pierce a vertical seal; the XY seal runs after and
wins. A passage must never punch a hole through the world's edge.
ClassifyBox/ForcedMarginOverBox proved via the closest AABB radius with a
one-voxel margin: 8 boxes proved, 1 tile proved, 600 voxels brute-forced,
0 violations. FXYEdgeSealOp is IsXYPure. Max rim discontinuity .187 against
a 1.0 threshold -- a ramp, not a cylinder wall.
⚠️ WorldRadiusVoxels DEFAULTS TO 0, and that is deliberate. Codex flagged
that DA_Settings and BP_VoxelSettings predate the property and so do not
serialize it -- they inherit the C++ default silently. A default of 8192
would have walled in every existing world on next editor open with nothing
in the asset to explain it. 0 is a bitwise no-op (45 interior comparisons
against the unbounded path prove it). The GDD's intended ~8192 is a value
to set in the asset, deliberately, once. Documented at the declaration.
Codex found four spec errors, three of them mine: VF_ApplyBoundarySeal
lives in VoxelDensityPrimitives.h not VoxelCaveMorphology; the asset
default trap above; and my "density increases through the band" wording
contradicts the MC sign convention (solid is more NEGATIVE) -- the test
measures increasing solidness.
Build clean, 21 succeeded / 0 failed, run and verified by me.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJiTcTSDNkKBtnNdiBtdaU
This commit is contained in:
1 parent
44938f3f98
commit
9d2324879d
19 files changed
+1006
-126
No files matched your search
@@ -179,6 +179,28 @@ public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel|Clipmap", meta = (ClampMin = "0", ClampMax = "3"))
|
||||
int32 LODOctaveDrop = 0;
|
||||
|
||||
//==========================================================================
|
||||
// WORLD BOUNDS (bounded gigantic world in actor-space XY)
|
||||
//==========================================================================
|
||||
// Radius (voxels) of the bounded world in XY, measured from actor-space (0,0).
|
||||
// 0 = unbounded (legacy behaviour, no edge seal).
|
||||
//
|
||||
// ⚠️ DEFAULTS TO 0 ON PURPOSE, and it is not the value the GDD wants.
|
||||
// Existing DA_Settings / BP_VoxelSettings assets predate this property, so they do NOT serialize
|
||||
// it — they silently inherit whatever C++ default is written here. A non-zero default would
|
||||
// therefore wall in every existing world the next time the editor opens, with nothing in the
|
||||
// asset to show why. The GDD calls for "bounded, but gigantic": ~8192 voxels (2.05 km) is the
|
||||
// intended production value. SET IT IN THE ASSET, deliberately, once.
|
||||
//
|
||||
// FR : 0 par défaut EXPRÈS — les assets existants n'ont pas cette propriété et héritent
|
||||
// silencieusement de la valeur C++. La valeur de production visée (~8192) se règle dans l'asset.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel|World Bounds", meta = (ClampMin = "0.0"))
|
||||
float WorldRadiusVoxels = 0.0f;
|
||||
|
||||
// Solid ramp thickness at the radial world edge, in voxels.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel|World Bounds", meta = (ClampMin = "0.0"))
|
||||
float EdgeSealThickness = 64.0f;
|
||||
|
||||
//=========================================================================
|
||||
// CONTENT — distance-based decoration grid (no LOD pop)
|
||||
//=========================================================================
|
||||
|
||||
Reference in new issue
Block a user