fix(correctness): cold-audit fixes -- tile-cache determinism bug, cache identities, lifetimes
Correctness round on AUDIT-COLD-2026-09-14.md (Codex; key fixes reviewed by me). #7 (determinism, introduced by the tile-cache work): the refetch guard in GetDensityAt now rebuilds on `bTileCacheContext != CP_UsesTileCacheWindow` or when the worker-local stack/core were moved into a cache entry (`CP_ActiveTunnelDensityCache != nullptr`). A cache miss can no longer evaluate a moved-from, empty operator stack. Test (VoxelForgeCorrectnessRoundTest): the pre-fix binary CRASHED in the context-switch case (negative control); the fixed binary passes with 0/5 coarse and fine mismatches, and warm vs fresh origin-tile meshes are identical. Also fixed, each with a focused test that passes: - #3/#8: worker diff/surface/biome caches carry owner/layer identity (no cross-world reuse); #9: the shaft key gains LedgeSpacing/LedgeDepth and the island key BoundarySealThickness; #14: clearing passages bumps PassagesVersion; #21: HasAnyModInChunkRange is proportional to the queried range (the sealed-rock proof calls it per candidate). - #1: the density-volume fill thread is paused/drained with generation; #2: each content manager joins its own decoration tasks before destruction; #15: non-finite/invalid modification geometry is rejected; #20: zero-width transition blend is guarded at runtime. - Also #4-#6, #10-#13, #16-#18, #22. #19 is valid C++20 and unchanged. Verified: canonical export b3e5f4c3..9b377; capability 20,830 / 10,909; fresh trace 841/841 identical, 0 origin-column mismatches; static mesher calls 18,078,130. Performance: two pairs disagree in sign, and the means are final -2.5% static / -0.8% moving; no repeatable regression. Known and NOT caused by this round: ClassifyTileSoundness and PassageLandsInOpenSpace were already failing (15/17 in the grouped suite). Queued for investigation. Ledger: first determinism launch hit the DDC fatal (crash folder 57DB6ADC, 23:21); the retry exited 1 on the two known failures; one malformed multi-test launch was inconclusive; one malformed trace launch was stopped; one launch with an unquoted project path found no test and its retry passed. Everything else passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TaFdXhTdYMkW1xrV6ApT6Y
This commit is contained in:
1 parent
39c306b524
commit
8879045627
14 files changed
+1365
-139
No files matched your search
@@ -120,6 +120,11 @@ public:
|
||||
* future rebuild — this patches the LIVE instances. Returns how many were removed. Game-thread. */
|
||||
int32 RemoveDecorationsInSphere(const FVector& WorldCenter, float WorldRadius);
|
||||
|
||||
/** Invalidate decoration regions after a terrain edit. Existing regions and in-flight builds are
|
||||
* discarded together, so an old worker result cannot resurrect pre-edit content; the next update
|
||||
* rebuilds the desired cells from the edited density field. Game-thread. */
|
||||
void InvalidateDecorationBuilds();
|
||||
|
||||
/** Destroy all spawned content (decorations + water). Regenerate / season reset. Bumps the deco
|
||||
* epoch so any in-flight march tasks' results are discarded. */
|
||||
void ClearAll();
|
||||
@@ -179,6 +184,9 @@ private:
|
||||
FPlacementProfile Profile; // representative profile (mesh + HISM render tuning: cull/shadow) —
|
||||
// may be a decoration entry's OR a companion's (F7).
|
||||
TArray<FTransform> Xforms;
|
||||
int32 SourceEntryIdx = INT32_MAX;
|
||||
int32 SourceCompanionIdx = INT32_MAX;
|
||||
int32 SourceSubIdx = INT32_MAX;
|
||||
};
|
||||
// A non-instanced actor placement, spawned when the region is applied.
|
||||
struct FRegionActorSpawn
|
||||
@@ -287,6 +295,7 @@ private:
|
||||
void ClearAllDecorations();
|
||||
void DrainDecoResults(); // discard every queued march result
|
||||
static void ResetGridBuildState(FDecoGrid& G); // drop builds/queues (loaded regions untouched)
|
||||
void JoinDecorationTasks(); // real per-manager lifetime join
|
||||
// Region size in cells, clamped (>=1). Cell↔region math lives in file-static helpers in the .cpp.
|
||||
int32 RegionSize() const;
|
||||
|
||||
@@ -353,10 +362,18 @@ private:
|
||||
|
||||
// Set in BeginDestroy; worker tasks check it before touching us.
|
||||
std::atomic<bool> bShuttingDown{false};
|
||||
// Per-manager task count. A process-global count would make one world's shutdown wait on
|
||||
// another world's decoration work and cannot prove this manager's UObject is safe to tear down.
|
||||
std::atomic<int32> ActiveDecorationTasks{0};
|
||||
|
||||
// Streaming state. INT_MIN sentinels force a full rebuild on the first update / after ClearAll.
|
||||
FIntPoint LastDecoCell = FIntPoint(INT32_MIN, INT32_MIN);
|
||||
int32 LastStrateIndex = INT32_MIN;
|
||||
int32 LastNearRadius = INT32_MIN;
|
||||
int32 LastFarRadius = INT32_MIN;
|
||||
int32 LastNearSpacing = INT32_MIN;
|
||||
int32 LastFarSpacing = INT32_MIN;
|
||||
int32 LastRegionSize = INT32_MIN;
|
||||
|
||||
// Shared strate context for the current update (recomputed each UpdateDecorations; the launch step
|
||||
// copies the PODs into each task). Same for both grids — a strate is a horizontal slab.
|
||||
|
||||
Reference in new issue
Block a user