docs(architecture): drop the sheet ring, fix content/water to match code
- §8.10 render-distance paragraph: remove the F18 far "sheet" ring description (GenerateSheetMesh, SheetHole*, sheet re-queue). The ring is plain level-MaxClipLevel MC tiles; bFarSheetRing/FarSheetSpanLevels are documented as unused settings the runtime always passes as false. All other §8.10 invariants are kept; the budgeted-teardown note now says what UnloadTile does today (park the component), not ClearChunk. - Fix the claim that GetLODForChunk/LODToStep/IsChunkInRange/ GetStrateChunkZBounds and the ViewDistance settings are dead (the first three are gone, the last two are used); only the ceiling settings are. - §8.5: decoration results are BuildId-guarded region builds applied by ApplyRegion (no ReadyResults/DecoEpoch/ApplyDecoResult); water is one player-following plane (UpdateWater), not per-tile planes; palette tags are per-grid EntryBiome; FStrateSetPiece no longer "coming" (folded into landmarks); drop the dead ContentMaxLevel/MaxLODLevel notes. - §9.3: anchors fold in after the player clipmap (no sheet ring). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01URDGLsu7c4nunqNFPJEFPU
This commit is contained in:
1 file changed
+36
-45
+36
-45
@@ -291,9 +291,11 @@ when close (separate HISMs → crossing the near boundary never touches the far
|
|||||||
(per grid, sharing ONE `MaxConcurrentDecorationTasks` budget — each throttles against the other's in-flight count):
|
(per grid, sharing ONE `MaxConcurrentDecorationTasks` budget — each throttles against the other's in-flight count):
|
||||||
snapshot the update's decoration palette (built once on the GAME thread — biome, see below) then fire an async `UE::Tasks` march
|
snapshot the update's decoration palette (built once on the GAME thread — biome, see below) then fire an async `UE::Tasks` march
|
||||||
(`BuildCellSpawns`, `BackgroundNormal`, capped at `MaxConcurrentDecorationTasks` in flight via `InFlightCells`).
|
(`BuildCellSpawns`, `BackgroundNormal`, capped at `MaxConcurrentDecorationTasks` in flight via `InFlightCells`).
|
||||||
**(3)** `ProcessDecoResults`: drain finished tasks' results (`Mpsc` queue → `ReadyResults`), epoch-guarded
|
**(3)** `ProcessDecoResults`: drain finished cell marches (`DecoResults`, `Mpsc`) and fold each into its
|
||||||
(`DecoEpoch`, bumped on clear/strate-change so stale in-flight results are discarded) + range-checked, and
|
grid's region build (`MergeCellResult`; a result whose build is gone or whose `BuildId` no longer matches —
|
||||||
**apply (spawn) budgeted** (`MaxDecorationCellsPerFrame` — the only game-thread cost, SpawnActor/AddInstance).
|
region cleared + re-marched — is discarded), then **apply completed regions budgeted**
|
||||||
|
(`MaxDecorationCellsPerFrame` regions/frame via `ApplyRegion` — the only game-thread cost; a region that left
|
||||||
|
range while it marched is dropped unbuilt).
|
||||||
`BuildCellSpawns` (worker) finds each column's surface point(s) and rolls the entries there (shared
|
`BuildCellSpawns` (worker) finds each column's surface point(s) and rolls the entries there (shared
|
||||||
`PlaceAtCrossing`). Candidate columns are **snapped to INTEGER voxel XY** (integer jitter) so the generator's
|
`PlaceAtCrossing`). Candidate columns are **snapped to INTEGER voxel XY** (integer jitter) so the generator's
|
||||||
surface-column cache (T1.a, §8.10) applies — FRACTIONAL XY bypasses it and recomputes the noise-heavy
|
surface-column cache (T1.a, §8.10) applies — FRACTIONAL XY bypasses it and recomputes the noise-heavy
|
||||||
@@ -321,7 +323,7 @@ result's `Entries` snapshot. `DecorationMaxCrossingsPerColumn` caps cave columns
|
|||||||
task count before UObject teardown (tasks read the Generator); `BeginDestroy` is the backstop. **Determinism:**
|
task count before UObject teardown (tasks read the Generator); `BeginDestroy` is the backstop. **Determinism:**
|
||||||
pure hash of (cell, column, crossing, entry, seed) + the density surface snap. **Decorations exist ONLY in
|
pure hash of (cell, column, crossing, entry, seed) + the density surface snap. **Decorations exist ONLY in
|
||||||
the player's current strate** (march is strate-bounded) → a strate change wipes + rebuilds them, and there
|
the player's current strate** (march is strate-bounded) → a strate change wipes + rebuilds them, and there
|
||||||
is **no cross-strate light bleed to cull** (the old `SetActiveStrate` light-culling pass is SUBSUMED — gone).
|
is **no cross-strate light bleed to cull**.
|
||||||
**Render paths:** `ActorClass` → real actors (lights/logic, pricey game-thread spawn); `InstancedMesh` → HISM
|
**Render paths:** `ActorClass` → real actors (lights/logic, pricey game-thread spawn); `InstancedMesh` → HISM
|
||||||
(no tick/actor/collision, emissive glows far), per-cell-per-entry. **Per-entry HISM tuning for dense groundcover**
|
(no tick/actor/collision, emissive glows far), per-cell-per-entry. **Per-entry HISM tuning for dense groundcover**
|
||||||
(`FStrateDecoration`, only the InstancedMesh path): `CullDistance` (cm; 0 = no cull — the lever that makes dense
|
(`FStrateDecoration`, only the InstancedMesh path): `CullDistance` (cm; 0 = no cull — the lever that makes dense
|
||||||
@@ -332,8 +334,8 @@ grass affordable: placed thickly, drawn only near → GPU cost bounded by area-w
|
|||||||
`MinSlopeAngle` (lower companion to Max — band a prop onto a tilt range, e.g. 30..70 = slopes only),
|
`MinSlopeAngle` (lower companion to Max — band a prop onto a tilt range, e.g. 30..70 = slopes only),
|
||||||
`bWallExcludeOverhangs` (wall-only-upright: drop normals with N.Z < 0 so downward overhangs don't take wall props).
|
`bWallExcludeOverhangs` (wall-only-upright: drop normals with N.Z < 0 so downward overhangs don't take wall props).
|
||||||
**Shared vocabulary (2026-07-06):** these gates + spawn/transform/render fields now live on `FPlacementProfile`
|
**Shared vocabulary (2026-07-06):** these gates + spawn/transform/render fields now live on `FPlacementProfile`
|
||||||
(embedded as `Profile` on `FStrateDecoration`, `FStrateLandmark`, and the coming `FStrateSetPiece`), so all three
|
(embedded as `Profile` on `FStrateDecoration` and `FStrateLandmark`), so both scatter primitives are
|
||||||
scatter primitives are authored identically. Rotation unified to `RotationOffset` (fixed) + `RandomRotation`
|
authored identically. Rotation unified to `RotationOffset` (fixed) + `RandomRotation`
|
||||||
(per-axis hash-random) — decoration's ctor defaults `RandomRotation.Yaw = 360` (full random heading, replacing the
|
(per-axis hash-random) — decoration's ctor defaults `RandomRotation.Yaw = 360` (full random heading, replacing the
|
||||||
old `bRandomYaw`/`MinYaw`/`MaxYaw`; banded yaw = offset + a smaller random range). Distribution is unchanged; the
|
old `bRandomYaw`/`MinYaw`/`MaxYaw`; banded yaw = offset + a smaller random range). Distribution is unchanged; the
|
||||||
exact per-instance yaw values reshuffle once (different hash mix).
|
exact per-instance yaw values reshuffle once (different hash mix).
|
||||||
@@ -345,7 +347,7 @@ SampleMoisture / SampleBiomeAt) on demand, so it's deterministic + worker-safe (
|
|||||||
strate's already-resolved `FBiomeContext`, so no re-resolve). Opt-in per entry (empty list = zero cost);
|
strate's already-resolved `FBiomeContext`, so no re-resolve). Opt-in per entry (empty list = zero cost);
|
||||||
wired into both the deco worker (`BuildCellSpawns`) and landmark placement (`SpawnLandmarkInstance`). This
|
wired into both the deco worker (`BuildCellSpawns`) and landmark placement (`SpawnLandmarkInstance`). This
|
||||||
is the shared core of the coming quest `FindFeature` locator (same predicate, run as an outward search) and
|
is the shared core of the coming quest `FindFeature` locator (same predicate, run as an outward search) and
|
||||||
the anchor gate for `FStrateSetPiece`. The BP bridge `AVoxelWorld::GetVoxelSurfaceHeightAt` exposes the
|
the landmark anchor gate. The BP bridge `AVoxelWorld::GetVoxelSurfaceHeightAt` exposes the
|
||||||
trace-free deterministic ground/ceiling height so authored ruin/set-piece Blueprints self-arrange on the
|
trace-free deterministic ground/ceiling height so authored ruin/set-piece Blueprints self-arrange on the
|
||||||
real surface before it meshes. Next types (water-edge band, relief-peak local-max, slope) are additive.
|
real surface before it meshes. Next types (water-edge band, relief-peak local-max, slope) are additive.
|
||||||
**F7 COMPANIONS (relational decoration, `FDecoCompanion`):** each `FStrateDecoration` may list `Companions`
|
**F7 COMPANIONS (relational decoration, `FDecoCompanion`):** each `FStrateDecoration` may list `Companions`
|
||||||
@@ -397,12 +399,12 @@ Static-mobility HISM re-caches its proxy — fine for player-paced digging.) Not
|
|||||||
grass on a freshly-exposed ledge / regrowth after fill-back — both self-correct on the next natural re-stream. **Freeze note:** a huge set-piece mesh hitches on register (game-thread proxy/distance-field build —
|
grass on a freshly-exposed ledge / regrowth after fill-back — both self-correct on the next natural re-stream. **Freeze note:** a huge set-piece mesh hitches on register (game-thread proxy/distance-field build —
|
||||||
NOT async-fixable; the spawn is game-thread by engine rule; the asset is a hard ref so already resident) →
|
NOT async-fixable; the spawn is game-thread by engine rule; the asset is a hard ref so already resident) →
|
||||||
mitigate ASSET-side (Nanite on the mesh, bake distance fields), optionally budget spawns across frames.
|
mitigate ASSET-side (Nanite on the mesh, bake distance fields), optionally budget spawns across frames.
|
||||||
`ApplyDecoResult` buckets spawns per entry and builds each HISM with ONE batched `AddInstances`
|
`ApplyRegion` buckets a region's spawns per mesh (all its cells merged) and builds each HISM with ONE batched
|
||||||
(single cluster-tree build, set cull/shadow BEFORE `RegisterComponent`) — the game-thread hitch-killer for dense cells.
|
`AddInstances` (single cluster-tree build, set cull/shadow BEFORE `RegisterComponent`) — the game-thread
|
||||||
|
hitch-killer for dense cells.
|
||||||
**Per-entry tier (`StreamTier`, default Far)** picks NearGrid or FarGrid; radius + column spacing are PER-GRID
|
**Per-entry tier (`StreamTier`, default Far)** picks NearGrid or FarGrid; radius + column spacing are PER-GRID
|
||||||
settings, never per-entry (a per-entry radius would re-introduce the in-place re-stream flicker — see the two-grid
|
settings, never per-entry (a per-entry radius would re-introduce the in-place re-stream flicker — see the two-grid
|
||||||
rationale above). This REPLACES the vestigial `MaxLODLevel`; the dead `DecorationActorRadiusChunks` setting is
|
rationale above). `CullDistance` still bounds GPU draw on top (orthogonal to which grid
|
||||||
repurposed as `DecorationNearRadiusChunks`. `CullDistance` still bounds GPU draw on top (orthogonal to which grid
|
|
||||||
streams the entry). **No LOD area-density compensation** (placement is per real
|
streams the entry). **No LOD area-density compensation** (placement is per real
|
||||||
surface point, density-stable with distance). **SpawnDensity semantics CHANGED** vs the old vertex scatter: it
|
surface point, density-stable with distance). **SpawnDensity semantics CHANGED** vs the old vertex scatter: it
|
||||||
rolls per column surface-point (not per mesh vertex) → expect a one-time density re-tune. **Settings
|
rolls per column surface-point (not per mesh vertex) → expect a one-time density re-tune. **Settings
|
||||||
@@ -436,22 +438,21 @@ null entry = "evaluated, nothing placed" so it isn't retried). Deterministic (ha
|
|||||||
Strate-bounded (wiped on strate change, like decorations). This is the real home for "rare prop at all
|
Strate-bounded (wiped on strate change, like decorations). This is the real home for "rare prop at all
|
||||||
distances" — the job the decoration FarGrid could approximate at moderate range but not at extreme radius.
|
distances" — the job the decoration FarGrid could approximate at moderate range but not at extreme radius.
|
||||||
|
|
||||||
**(B) WATER — tile-driven, level-0 only (continuous plane, never pops).** `PopulateTileWater(tile)` in
|
**(B) WATER — ONE strate-global ocean plane that follows the player (`UpdateWater`, from `Tick`).** A single
|
||||||
`ApplyMeshToTile` (level-0 tiles), `ClearTileWater(tile)` in `UnloadTile`. One scaled engine plane
|
scaled engine plane (`/Engine/BasicShapes/Plane`, no collision, no shadow) snapped to a coarse cell around the
|
||||||
(`/Engine/BasicShapes/Plane`) per water-surface chunk (per-chunk-Z plane logic assumes a single chunk's
|
player, so it only repositions when the player crosses a cell; terrain pokes through it, so it reads as water at
|
||||||
vertical span — hence level-0 only), keyed `TMap<FIntVector, UStaticMeshComponent*>` (reflected UPROPERTY).
|
every LOD and to the horizon with no per-tile gaps (one draw). Water Z: `bHasWater` + `WaterLevelRelative` →
|
||||||
Water Z: `bHasWater` + `WaterLevelRelative` → `StrateManager::GetWaterLevelWorldZForChunk`. Biome
|
`StrateManager::GetWaterLevelWorldZForChunk` (no water in the current strate ⇒ plane hidden). Material:
|
||||||
`WaterMaterial` overrides `UVoxelStrateDefinition::WaterMaterial` (level stays strate-global).
|
`UVoxelStrateDefinition::WaterMaterial`.
|
||||||
|
|
||||||
`ClearAll`/`SetSeed` on `ChangeSeed`/regenerate clears both subsystems (decorations re-stream on the next
|
`ClearAll`/`SetSeed` on `ChangeSeed`/regenerate clears both subsystems (decorations re-stream on the next
|
||||||
Tick via the INT_MIN sentinels). **Per-biome content (§8.14):** decorations resolve the dominant biome **PER COLUMN** on the worker
|
Tick via the INT_MIN sentinels). **Per-biome content (§8.14):** decorations resolve the dominant biome **PER COLUMN** on the worker
|
||||||
(`ResolveBiomeSampleAt` via the strate's `FBiomeContext`, box-cached → one rebuild per chunk footprint). The
|
(`ResolveBiomeSampleAt` via the strate's `FBiomeContext`, box-cached → one rebuild per chunk footprint). The
|
||||||
update builds ONE flat decoration palette (every biome's list concatenated; `CurrentEntryBiome[i]` tags entry
|
update builds ONE flat decoration palette per grid (every biome's list concatenated; `EntryBiome[i]` tags entry
|
||||||
`i` with its context-biome index, -1 = strate fallback), and `PlaceAtCrossing` rolls only the entries the
|
`i` with its context-biome index, -1 = strate fallback), and `PlaceAtCrossing` rolls only the entries the
|
||||||
column's biome owns. This replaced the old per-CELL `GetDominantBiomeAt` (one biome for a whole 8 m cell →
|
column's biome owns. Borders follow the warped-Voronoi field at column resolution, no straight lines (a
|
||||||
axis-aligned border snapping); borders now follow the warped-Voronoi field at column resolution, no straight
|
per-CELL biome would snap borders to the 8 m cell grid). `Initialize` also takes `UVoxelSettings*` (for the
|
||||||
lines. Water still uses the chunk-centre `GetDominantBiomeAt` for its material. `Initialize` now also takes
|
grid tunables).
|
||||||
`UVoxelSettings*` (for the grid tunables). `ContentMaxLevel` is now legacy/dead for decorations.
|
|
||||||
|
|
||||||
### 8.6 Atmosphere — `VoxelAtmosphereManager.h/.cpp` (NEW)
|
### 8.6 Atmosphere — `VoxelAtmosphereManager.h/.cpp` (NEW)
|
||||||
`UVoxelAtmosphereManager` (owned by `AVoxelWorld`, gated by `bManageAtmosphere`).
|
`UVoxelAtmosphereManager` (owned by `AVoxelWorld`, gated by `bManageAtmosphere`).
|
||||||
@@ -764,28 +765,19 @@ driven by `EditorBrush*` props.
|
|||||||
inside a strate band), then the OUTERMOST shell keeps generating tiles outward until it covers
|
inside a strate band), then the OUTERMOST shell keeps generating tiles outward until it covers
|
||||||
the requested distance (`VF_OuterShell`, shared by `BuildDesiredTiles` and `IsTileInClipRange`
|
the requested distance (`VF_OuterShell`, shared by `BuildDesiredTiles` and `IsTileInClipRange`
|
||||||
so the cull sees the same horizon; the ring's dz sweep is pre-clamped to the vertical strate
|
so the cull sees the same horizon; the ring's dz sweep is pre-clamped to the vertical strate
|
||||||
band). As MC tiles the ring cost grows with (distance/2^MaxClipLevel)² — which is why the ring
|
band). The ring is made of level-MaxClipLevel MC tiles, so its cost grows with
|
||||||
defaults to **F18 SHEETS** (`bFarSheetRing`): in an open strate the far field is exactly two
|
(distance/2^MaxClipLevel)². The far "sheet" ring (heightfield tiles past `MaxClipLevel`) was
|
||||||
heightfields (TerrainZ + CeilSurf, per-column oracle), so the ring streams tiles at level
|
dropped by the owner's decision: `bFarSheetRing` / `FarSheetSpanLevels` stay in `UVoxelSettings`
|
||||||
`MaxClipLevel + FarSheetSpanLevels` (one sheet = 2^span MC footprints per axis → 4-16× fewer
|
only so saved assets load, and the runtime (`VF_OuterShell`, `BuildDesiredTiles`) always passes
|
||||||
components) meshed by `GenerateSheetMesh` as two displaced grids — ground polygroup 0 / cap
|
`bFarSheetRing = false` to the selector (`VoxelClipmapDesiredTiles`, whose automation tests still
|
||||||
polygroup 1, tags true by construction, same materials/UVs/F6 masks, ~3-6× cheaper gen per
|
exercise the sheet branch).
|
||||||
area than band-cut MC. **XY hole**: a partially-covered sheet renders its whole footprint, so
|
(A "step cap" variant — raising CoarseTileCells per level so far levels keep a fine Step — was
|
||||||
the MC-covered box around the player (level-MaxClipLevel box, shrunk 1 tile for a seam-overlap
|
tried and rejected 2026-07-06.)
|
||||||
ring) is CUT out of the sheet at cell granularity (`SheetHole*Vox`, passed to
|
|
||||||
`GenerateSheetMesh`); when the player crosses a MaxClipLevel tile the hole moves and the
|
|
||||||
overlapping sheets re-queue via `BandRemeshQueue` — the shrink means the newly-cut area's MC
|
|
||||||
tiles were already desired one crossing earlier (loaded before uncovered). Sheet tiles take
|
|
||||||
the strate from the BAND (mid chunk): band unarmed
|
|
||||||
(inter-strate gap) ⇒ empty ring until landing; non-open strates ⇒ empty sheets (their far
|
|
||||||
ring was enclosed rock anyway); carved features (passages/spine/chasms/diff) don't show at
|
|
||||||
sheet distance — the MC shells keep them near. (A "step cap" variant — raising CoarseTileCells
|
|
||||||
per level so far levels keep a fine Step — was tried and rejected 2026-07-06.)
|
|
||||||
Trade-offs accepted: other strates simply don't render at far LOD (they're sealed/enclosed —
|
Trade-offs accepted: other strates simply don't render at far LOD (they're sealed/enclosed —
|
||||||
invisible except through passage mouths, which read as dark holes); passage tubes crossing the gap
|
invisible except through passage mouths, which read as dark holes); passage tubes crossing the gap
|
||||||
are cut at coarse levels only (near levels mesh full).
|
are cut at coarse levels only (near levels mesh full).
|
||||||
`GetLODForChunk` / `LODToStep` / `IsChunkInRange` / `GetStrateChunkZBounds` and the
|
The ceiling settings `CeilingViewMultiplier` / `CeilingBandChunks` are unused (left in place for
|
||||||
ViewDistance/LOD/strate-Z/ceiling settings are now DEAD/unused (left in place).
|
saved assets).
|
||||||
- **SKIRTS — LOD-seam crack filler** (`GenerateMesh`, after the cell loop; `VoxelSettings::bGenerateSkirts`
|
- **SKIRTS — LOD-seam crack filler** (`GenerateMesh`, after the cell loop; `VoxelSettings::bGenerateSkirts`
|
||||||
+ `SkirtCells`, wired onto the mesher at setup). Neighbouring shells mesh at different resolutions so
|
+ `SkirtCells`, wired onto the mesher at setup). Neighbouring shells mesh at different resolutions so
|
||||||
their iso-surfaces don't meet along the shared face → a thin see-through crack. After meshing, every
|
their iso-surfaces don't meet along the shared face → a thin see-through crack. After meshing, every
|
||||||
@@ -818,9 +810,8 @@ driven by `EditorBrush*` props.
|
|||||||
drain; `VoxelSettings::MaxUnloadsPerFrame`): the cull APPROVES removals (strict load-before-unload) but
|
drain; `VoxelSettings::MaxUnloadsPerFrame`): the cull APPROVES removals (strict load-before-unload) but
|
||||||
doesn't destroy in place — it queues them. `ProcessUnloadQueue` runs at most `MaxUnloadsPerFrame`
|
doesn't destroy in place — it queues them. `ProcessUnloadQueue` runs at most `MaxUnloadsPerFrame`
|
||||||
`UnloadTile`s/frame (scaled up to 4× with backlog, capped so a huge backlog can't re-spike). WHY: a
|
`UnloadTile`s/frame (scaled up to 4× with backlog, capped so a huge backlog can't re-spike). WHY: a
|
||||||
fast traversal culls a whole shell's worth of tiles in ONE frame, and each `UnloadTile` does
|
fast traversal culls a whole shell's worth of tiles in ONE frame, and each `UnloadTile` strips and
|
||||||
`DestroyComponent` + (level 0) `ContentManager::ClearChunk` → `Destroy()` of every decoration actor —
|
parks its component (T2.c pool) — an unbudgeted burst = a game-thread spike ("stuff torn down behind you" at speed). Mesh APPLIES were
|
||||||
an unbudgeted burst = a game-thread spike ("stuff torn down behind you" at speed). Mesh APPLIES were
|
|
||||||
already budgeted; this matches it for DESTROYS. Re-desired tiles are cancelled out of the queue (still
|
already budgeted; this matches it for DESTROYS. Re-desired tiles are cancelled out of the queue (still
|
||||||
loaded → no reload). `PendingUnload` is cleared in `RegenerateAllChunks`/`EndPlay` (tiles already gone).
|
loaded → no reload). `PendingUnload` is cleared in `RegenerateAllChunks`/`EndPlay` (tiles already gone).
|
||||||
- **Collision only at LEVEL 0** (`ApplyMeshToTile`): `UpdateSectionConfig(..., Tile.Level==0)`. Far tiles
|
- **Collision only at LEVEL 0** (`ApplyMeshToTile`): `UpdateSectionConfig(..., Tile.Level==0)`. Far tiles
|
||||||
@@ -1117,7 +1108,7 @@ pending).** `AVoxelWorld::RegisterStreamingAnchor(Actor, Policy, RadiusChunks)`
|
|||||||
(BlueprintCallable) add an actor to `StreamingAnchors`. `UpdateChunksAroundPosition` prunes dead anchors +
|
(BlueprintCallable) add an actor to `StreamingAnchors`. `UpdateChunksAroundPosition` prunes dead anchors +
|
||||||
detects chunk crossings (rebuilds the desired set when any anchor crosses a level-0 boundary — same cadence
|
detects chunk crossings (rebuilds the desired set when any anchor crosses a level-0 boundary — same cadence
|
||||||
as player movement, coalesced into one rebuild). `AddAnchorDesiredTiles` (inside `BuildDesiredTiles`, after
|
as player movement, coalesced into one rebuild). `AddAnchorDesiredTiles` (inside `BuildDesiredTiles`, after
|
||||||
the player clipmap + sheet ring) folds each anchor's Chebyshev box of **level-0** tiles into the SAME
|
the player clipmap) folds each anchor's Chebyshev box of **level-0** tiles into the SAME
|
||||||
`DesiredStamped`/`DesiredSorted` set (deduped vs the clipmap by stamp) → the existing delta cull releases an
|
`DesiredStamped`/`DesiredSorted` set (deduped vs the clipmap by stamp) → the existing delta cull releases an
|
||||||
anchor's tiles automatically when it moves away / unregisters. Zero cost when no anchors (empty loop). The box
|
anchor's tiles automatically when it moves away / unregisters. Zero cost when no anchors (empty loop). The box
|
||||||
defaults to a THIN shape (its chunk + 1 horizontal ring + 1 chunk below for ground safety, nothing above —
|
defaults to a THIN shape (its chunk + 1 horizontal ring + 1 chunk below for ground safety, nothing above —
|
||||||
|
|||||||
Reference in new issue
Block a user