feat: wire SurfaceWorld (biome-less) + fix a column-memo perf trap
All six checks green, 9399 samples inside the overhang window. The single-entry column memo was correct only if the caller walks a Z column before changing XY, which the mesher does not promise. Iterating X first within a Z slice would miss on every voxel and re-run the whole height stack per voxel, cliff resamples included — an order of magnitude on the plugin's most expensive archetype. The tests could not have caught it: they sample random XY, where a one-entry memo and a 256-entry one behave identically. Only reading the access pattern finds this. Replaced with a direct-mapped 256-entry thread_local table hashed on the XY bit patterns, full key compared on hit, so a collision costs a recompute and never returns the wrong column. Wiring: UsesOperatorStackForChunk returns true for SurfaceWorld only when the strate has no biomes. The original blends heights toward the neighbouring biome across the border band; the stack evaluates one param set, so a biome strate would get a hard seam at every border rather than a subtle shift. The guard sits beside the archetype list so "can this strate take the stack?" stays one question in one place, and GetDensityAt keeps a defensive CP_BiomeCtx check that falls back if the two disagree. UNVERIFIED: not compiled. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4dc55b1af3
commit
f7ed9407bf
4 files changed
+107
-6
No files matched your search
@@ -574,6 +574,22 @@ bool UVoxelStrateManager::UsesOperatorStackForChunk(const FIntVector& ChunkCoord
|
||||
case ECaveGeneratorType::Maze: return true; // Phase 1
|
||||
case ECaveGeneratorType::FlatPlain: // Phase 2 — les deux partagent
|
||||
case ECaveGeneratorType::CrystalChamber: return true; // UNE seule pile (BuildSlabStack)
|
||||
|
||||
case ECaveGeneratorType::SurfaceWorld:
|
||||
// ⚠️ PORTÉ, MAIS PAS AVEC LES BIOMES. `BuildSurfaceStack` évalue UN jeu de params ; le
|
||||
// chemin d'origine évalue le biome dominant puis interpole les HAUTEURS vers le voisin
|
||||
// dans la bande de frontière (le combiner `Mask`, prototype de la Phase 3 — §5). Sans lui,
|
||||
// une strate à biomes perdrait ses transitions : pas un décalage subtil, une couture nette
|
||||
// à chaque frontière de biome.
|
||||
//
|
||||
// Donc la garde est ici, dans la MÊME fonction que la liste des archétypes portés, plutôt
|
||||
// que dispersée dans `GetDensityAt` : « cette strate peut-elle prendre la pile ? » reste
|
||||
// une seule question, posée à un seul endroit.
|
||||
// Ported, but NOT with biomes: the stack evaluates ONE param set, while the original blends
|
||||
// heights toward the neighbouring biome. Without the Mask combiner a biome strate would lose
|
||||
// its transitions — a hard seam at every biome border, not a subtle shift.
|
||||
return Def->Biomes.Num() == 0;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user