From 871ca190af3676c3931e6ea71be52e6adcd1d25e Mon Sep 17 00:00:00 2001 From: Fr0zka Date: Mon, 17 Aug 2026 01:22:12 +0200 Subject: [PATCH] fix(classify): use the public GetStrateChunkZBounds; the index accessor is protected VoxelGenerator.cpp(2796): C2248 -- FindSlotIndexForChunkZ is protected. I claimed it was public "verified" in the previous commit. The grep printed the declaration line, not the access specifier above it. Same shape as the partial read that produced a false accusation earlier today. GetStrateChunkZBounds is public (VoxelStrateManager.h:177), returns false for exactly the no-slot case, and ClassifyTile already calls it three times for the same question. Wrapped in a VF_ChunkZHasSlot lambda so the condition reads as the predicate it is. No accessor promoted, no API widened. Co-Authored-By: Claude Opus 5 --- OPSTACK-PROGRESS.md | 15 +++++++++++++++ Source/VoxelForge/Private/VoxelGenerator.cpp | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/OPSTACK-PROGRESS.md b/OPSTACK-PROGRESS.md index c138f69..90892a7 100644 --- a/OPSTACK-PROGRESS.md +++ b/OPSTACK-PROGRESS.md @@ -4402,3 +4402,18 @@ flight, and it is a class of tile T1.d has never once been able to prove. Compile-risk spots: `FindSlotIndexForChunkZ` is public (`VoxelStrateManager.h:351`, verified); `FStrateDisturbanceParams` is already used later in the same function; the new `else if` sits before the surface `else`, so `Slots[MemoSlotIdx]` is never dereferenced for the new category. + +## 2026-08-16 (t) — build break: `FindSlotIndexForChunkZ` is protected, not public + +`VoxelGenerator.cpp(2796): C2248 — cannot access protected member`. + +I wrote "`FindSlotIndexForChunkZ` is public (`VoxelStrateManager.h:351`, verified)" in the previous +entry. **It is `protected`.** The grep I called verification printed the declaration line and not the +access specifier above it — I checked that the symbol existed and reported it as checked for +something else. Exactly the "assert a negative from a partial read" mistake made earlier today with +the test fixture, in the same shape. + +**Fixed without widening the API:** `GetStrateChunkZBounds` is `public:` (line 177), returns false +for precisely the no-slot case, and this same function already calls it three times for the same +question. A small `VF_ChunkZHasSlot` lambda wraps it so the `else if` reads as the predicate it is. +No accessor promoted, no new surface. diff --git a/Source/VoxelForge/Private/VoxelGenerator.cpp b/Source/VoxelForge/Private/VoxelGenerator.cpp index 76e1d8d..37227b1 100644 --- a/Source/VoxelForge/Private/VoxelGenerator.cpp +++ b/Source/VoxelForge/Private/VoxelGenerator.cpp @@ -2762,8 +2762,16 @@ EVoxelTileClass UVoxelGenerator::ClassifyTile(const FIntVector& OriginVoxels, in bool bAnyNonCave = false; // gap ou SurfaceWorld dans la même tuile ⇒ on abandonne int32 MemoChunkZ = INT32_MAX; - int32 MemoCat = -1; // 0 = gap, 1 = surface, 2 = cave (pile d'opérateurs) + int32 MemoCat = -1; // 0 = gap, 1 = surface, 2 = cave (pile), 3 = hors layout int32 MemoSlotIdx = -1; + + // « Ce chunk Z appartient-il à une strate ? » sous forme publique : `FindSlotIndexForChunkZ` + // est `protected`, `GetStrateChunkZBounds` rend false pour exactement le même cas. + auto VF_ChunkZHasSlot = [&](int32 Z) -> bool + { + int32 UnusedTopCZ = 0, UnusedBotCZ = 0; + return StrateManager->GetStrateChunkZBounds(Z, UnusedTopCZ, UnusedBotCZ); + }; for (int32 g = -1; g <= GridDim; ++g) { const int32 Zi = OriginVoxels.Z + g * Step; @@ -2793,7 +2801,12 @@ EVoxelTileClass UVoxelGenerator::ClassifyTile(const FIntVector& OriginVoxels, in // // Out-of-layout is a CONSTANT AIR field, not a cave archetype. Every tile touching the // open air above the world was being routed into the cave branch and bailing there. - else if (StrateManager->FindSlotIndexForChunkZ(ChunkZ) < 0) + // `GetStrateChunkZBounds` (PUBLIC) rend false exactement quand `FindSlotIndexForChunkZ` + // rend -1 — ce dernier est `protected`, et cette fonction l'utilise déjà deux fois pour + // la même question. Pas de nouvelle surface d'API pour un prédicat qui existe. + // GetStrateChunkZBounds is the public form of "has a layout slot"; the index accessor + // is protected and this function already uses the bounds call twice for the same test. + else if (!VF_ChunkZHasSlot(ChunkZ)) { MemoCat = 3; bAnyNonCave = true; // n'entre JAMAIS dans la branche de cave