diag(render): tripwires on every silent dat-miss path (white-walls attribution, #105)

The intermittent white-cottage-walls failure has NEVER produced a log line:
every dat-read failure on the walls-relevant paths exits silently, and the
failed result is cached for the session (mesh batches build once). Today it
reproduced on a probe-free launch with a 35-line, zero-error log — so the
prior heavy-probes-starve-the-dat-reader framing is not the whole story.

Tripwires (print ONLY on anomaly; zero cost healthy; keep until #105 closes):
- [dat-miss]  DatDatabaseWrapper.TryGet — a miss for an id whose BTree entry
  EXISTS (re-probed under the same lock); legit not-found fallbacks stay quiet.
- [tex-miss]  TextureCache.DecodeFromDats x3 — render-thread decode fell back
  to magenta (Surface / SurfaceTexture / RenderSurface miss).
- [cell-miss] GameWindow interior hydration x2 — EnvCell or Environment read
  returned null, so a cell''s WALLS are silently never registered while its
  statics still draw (the exact observed geometry signature).

Color discriminates the layer on the next occurrence: magenta = TextureCache;
see-through + [tex-skip]/[dat-miss] = mesh build; see-through + [cell-miss] =
hydration; broken with NO tripwire output = GL-side upload/residency.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-09 21:28:32 +02:00
parent 8fadf770fe
commit 7433b704fb
3 changed files with 39 additions and 1 deletions

View file

@ -5471,13 +5471,28 @@ public sealed class GameWindow : IDisposable
{
uint envCellId = firstCellId + offset;
var envCell = _dats.Get<DatReaderWriter.DBObjs.EnvCell>(envCellId);
if (envCell is null) continue;
if (envCell is null)
{
// TEMP diagnostic (dat-race investigation 2026-06-09, strip with fix):
// every id in [0x0100, 0x0100+NumCells) is derived from LandBlockInfo and
// MUST exist in the cell dat — a null here is always a read anomaly.
Console.WriteLine($"[cell-miss] EnvCell 0x{envCellId:X8} null during interior hydration (NumCells={lbInfo.NumCells})");
continue;
}
// Phase 7.1: build and register room geometry for this EnvCell.
DatReaderWriter.Types.CellStruct? cellStruct = null;
if (envCell.EnvironmentId != 0)
{
var environment = _dats.Get<DatReaderWriter.DBObjs.Environment>(0x0D000000u | envCell.EnvironmentId);
if (environment is null)
{
// TEMP diagnostic (dat-race investigation 2026-06-09, strip with fix):
// a null Environment means this cell's WALLS are silently never
// registered while its static objects still draw — the exact
// white-walls geometry signature.
Console.WriteLine($"[cell-miss] Environment 0x{0x0D000000u | envCell.EnvironmentId:X8} null for EnvCell 0x{envCellId:X8} -> walls not registered");
}
if (environment is not null
&& environment.Cells.TryGetValue(envCell.CellStructure, out cellStruct))
{