diff --git a/tests/AcDream.Core.Tests/Conformance/Issue113DoorVanishDiagnosticTests.cs b/tests/AcDream.Core.Tests/Conformance/Issue113DoorVanishDiagnosticTests.cs
index f698b0b0..78420fa2 100644
--- a/tests/AcDream.Core.Tests/Conformance/Issue113DoorVanishDiagnosticTests.cs
+++ b/tests/AcDream.Core.Tests/Conformance/Issue113DoorVanishDiagnosticTests.cs
@@ -181,6 +181,56 @@ public sealed class Issue113DoorVanishDiagnosticTests
return n.LengthSquared() < 1e-10f ? Vector3.Zero : Vector3.Normalize(n);
}
+ ///
+ /// Phase A confirmation: retail's building/cell mesh pass skips surface
+ /// batches whose CSurface type has neither Base1Image (0x2) nor
+ /// Base1ClipMap (0x4) — the skipNoTexture rule (D3DPolyRender inner draw
+ /// 0x0059d4a0; default skipNoTexture=1). Prediction: the hall's phantom
+ /// stair-ramp portal-fill polys {0,1} reference SOLID (untextured)
+ /// surfaces while cottage door/window fills reference TEXTURED surfaces —
+ /// which is exactly why retail shows doors but not the ramp.
+ ///
+ [Fact]
+ public void DumpPortalFillSurfaceTypes()
+ {
+ var datDir = ConformanceDats.ResolveDatDir();
+ if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; }
+ using var dats = new DatCollection(datDir, DatAccessType.Read);
+
+ foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u, 0x0100082Eu, 0x01000C17u })
+ {
+ var gfx = dats.Get(mid);
+ if (gfx?.DrawingBSP?.Root is null) continue;
+
+ var walked = new HashSet();
+ void Walk(DatReaderWriter.Types.DrawingBSPNode? n)
+ {
+ if (n is null) return;
+ if (n.Polygons is not null) foreach (var pid in n.Polygons) walked.Add((ushort)pid);
+ Walk(n.PosNode); Walk(n.NegNode);
+ }
+ Walk(gfx.DrawingBSP.Root);
+ var portalFills = gfx.Polygons.Keys.Where(k => !walked.Contains(k)).OrderBy(k => k).ToList();
+
+ _out.WriteLine($"=== model 0x{mid:X8}: {portalFills.Count} portal-fill polys; Surfaces list has {gfx.Surfaces.Count} entries ===");
+ foreach (var pid in portalFills)
+ {
+ var poly = gfx.Polygons[pid];
+ string Describe(short surfIdx)
+ {
+ if (surfIdx < 0 || surfIdx >= gfx.Surfaces.Count) return $"idx{surfIdx}=OOB";
+ uint sid = gfx.Surfaces[surfIdx];
+ var surf = dats.Get(sid);
+ if (surf is null) return $"0x{sid:X8}=MISSING";
+ bool textured = surf.Type.HasFlag(DatReaderWriter.Enums.SurfaceType.Base1Image)
+ || surf.Type.HasFlag(DatReaderWriter.Enums.SurfaceType.Base1ClipMap);
+ return $"0x{sid:X8} type={surf.Type} -> {(textured ? "TEXTURED (drawn)" : "SOLID (skipNoTexture SKIPS on building/cell pass)")}";
+ }
+ _out.WriteLine($" poly {pid,3}: sides={poly.SidesType} stip={poly.Stippling} pos[{Describe(poly.PosSurface)}] neg[{Describe(poly.NegSurface)}]");
+ }
+ }
+ }
+
///
/// Control group: the two #113 models (hall + cottage) whose orphans ARE
/// the phantom geometry, for type-model comparison against the door.