#119 decisive probe: ACDREAM_DUMP_ENTITY one-shot entity dump (H-A/H-B/H-C discriminator)
The broken-state log (user-session-capture2.log) shows meshMissing=0 / entSeen==entDrawn WHILE broken stairs are on screen - the staircase is DRAWN WRONG, not missing. This probe discriminates the three live hypotheses in ONE launch (handoff 2026-06-11 s4): - HYDRATE dump (GameWindow.BuildInteriorEntitiesForStreaming): per-part placement-frame translations + dropped-part accounting at the MOMENT MeshRefs are constructed. H-A (SetupMesh.Flatten identity fallback / silent gfx-null part drops under degraded dat reads) shows here as zero translations or built<43. - DRAW dump (WbDrawDispatcher, first tuple per entity): live MeshRefs translation summary + per-part loaded flags + Tier-1 classification cache state (batch count + RestPose translation summary), re-emitted compactly on signature change. H-B (partial/stale cached batch set) shows as correct translations + odd batch count. - WALK-REJECT lines (rate-limited): attributes 'entity never reaches the draw loop' to the specific gate (visibleCellIds/frustum). - Correct everything -> H-C (draw-side compose), instrument next. Targets: ACDREAM_DUMP_ENTITY=0x020003F2,0x020005D8 (the 43-part spiral staircase Setup + the wall barrels; H-A predicts the user's 'barrel' IS the collapsed staircase). Probe is inert when the env var is unset. Parser in RenderingDiagnostics (diagnostic-owner pattern) + 5 unit tests. Suites: App 242+1skip / Core 1427+2skip / UI 420 / Net 294. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d82f070b88
commit
3cf6bcc219
4 changed files with 246 additions and 2 deletions
|
|
@ -5610,6 +5610,15 @@ public sealed class GameWindow : IDisposable
|
|||
// Phase 2d: static objects inside the EnvCell.
|
||||
foreach (var stab in envCell.StaticObjects)
|
||||
{
|
||||
// #119 decisive probe: HYDRATE-side dump for ACDREAM_DUMP_ENTITY-
|
||||
// targeted stabs. This is the MOMENT MeshRefs are constructed —
|
||||
// a degraded dat read here (setup null / placement frames short /
|
||||
// part GfxObj null) permanently corrupts the entity (H-A), and
|
||||
// nothing downstream ever rebuilds it. Inert when the set is empty.
|
||||
bool dumpStab = AcDream.Core.Rendering.RenderingDiagnostics
|
||||
.DumpEntitySourceIds.Contains(stab.Id);
|
||||
int dumpSetupParts = -1, dumpPlacementFrames = -1, dumpFlattened = -1, dumpDropped = 0;
|
||||
|
||||
var meshRefs = new List<AcDream.Core.World.MeshRef>();
|
||||
if ((stab.Id & 0xFF000000u) == 0x01000000u)
|
||||
{
|
||||
|
|
@ -5620,6 +5629,10 @@ public sealed class GameWindow : IDisposable
|
|||
_ = AcDream.Core.Meshing.GfxObjMesh.Build(gfx, _dats);
|
||||
meshRefs.Add(new AcDream.Core.World.MeshRef(stab.Id, System.Numerics.Matrix4x4.Identity));
|
||||
}
|
||||
else if (dumpStab)
|
||||
{
|
||||
Console.WriteLine($"[dump-entity] HYDRATE src=0x{stab.Id:X8} cell=0x{envCellId:X8} GFXOBJ-NULL -> entity dropped");
|
||||
}
|
||||
}
|
||||
else if ((stab.Id & 0xFF000000u) == 0x02000000u)
|
||||
{
|
||||
|
|
@ -5628,18 +5641,39 @@ public sealed class GameWindow : IDisposable
|
|||
{
|
||||
_physicsDataCache.CacheSetup(stab.Id, setup);
|
||||
var flat = AcDream.Core.Meshing.SetupMesh.Flatten(setup);
|
||||
if (dumpStab)
|
||||
{
|
||||
dumpSetupParts = setup.Parts.Count;
|
||||
dumpPlacementFrames = setup.PlacementFrames.Count;
|
||||
dumpFlattened = flat.Count;
|
||||
}
|
||||
foreach (var mr in flat)
|
||||
{
|
||||
var gfx = _dats.Get<DatReaderWriter.DBObjs.GfxObj>(mr.GfxObjId);
|
||||
if (gfx is null) continue;
|
||||
if (gfx is null)
|
||||
{
|
||||
dumpDropped++;
|
||||
if (dumpStab)
|
||||
Console.WriteLine($"[dump-entity] HYDRATE src=0x{stab.Id:X8} cell=0x{envCellId:X8} part gfx=0x{mr.GfxObjId:X8} GFXOBJ-NULL -> part dropped");
|
||||
continue;
|
||||
}
|
||||
_physicsDataCache.CacheGfxObj(mr.GfxObjId, gfx);
|
||||
_ = AcDream.Core.Meshing.GfxObjMesh.Build(gfx, _dats);
|
||||
meshRefs.Add(mr);
|
||||
}
|
||||
}
|
||||
else if (dumpStab)
|
||||
{
|
||||
Console.WriteLine($"[dump-entity] HYDRATE src=0x{stab.Id:X8} cell=0x{envCellId:X8} SETUP-NULL -> entity dropped");
|
||||
}
|
||||
}
|
||||
|
||||
if (meshRefs.Count == 0) continue;
|
||||
if (meshRefs.Count == 0)
|
||||
{
|
||||
if (dumpStab)
|
||||
Console.WriteLine($"[dump-entity] HYDRATE src=0x{stab.Id:X8} cell=0x{envCellId:X8} meshRefs=0 -> entity dropped");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Stabs inside EnvCells are already in landblock-local coordinates
|
||||
// (same space as LandBlockInfo.Objects stabs). Adding cellOrigin would
|
||||
|
|
@ -5656,6 +5690,21 @@ public sealed class GameWindow : IDisposable
|
|||
MeshRefs = meshRefs,
|
||||
ParentCellId = envCellId,
|
||||
};
|
||||
|
||||
if (dumpStab)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"[dump-entity] HYDRATE src=0x{stab.Id:X8} cell=0x{envCellId:X8} entId=0x{hydrated.Id:X8} " +
|
||||
$"setupParts={dumpSetupParts} placementFrames={dumpPlacementFrames} flattened={dumpFlattened} " +
|
||||
$"built={meshRefs.Count} dropped={dumpDropped} " +
|
||||
$"pos=({worldPos.X:F2},{worldPos.Y:F2},{worldPos.Z:F2})");
|
||||
for (int i = 0; i < meshRefs.Count; i++)
|
||||
{
|
||||
var t = meshRefs[i].PartTransform.Translation;
|
||||
Console.WriteLine($"[dump-entity] hyd-part[{i:D2}] gfx=0x{meshRefs[i].GfxObjId:X8} t=({t.X:F3},{t.Y:F3},{t.Z:F3})");
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(hydrated);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue