diff --git a/tests/AcDream.Core.Tests/Rendering/Issue93TownNetworkFountainRoomLightInspectionTests.cs b/tests/AcDream.Core.Tests/Rendering/Issue93TownNetworkFountainRoomLightInspectionTests.cs
index 4dc7f889..aa7e1159 100644
--- a/tests/AcDream.Core.Tests/Rendering/Issue93TownNetworkFountainRoomLightInspectionTests.cs
+++ b/tests/AcDream.Core.Tests/Rendering/Issue93TownNetworkFountainRoomLightInspectionTests.cs
@@ -134,4 +134,53 @@ public class Issue93TownNetworkFountainRoomLightInspectionTests
_out.WriteLine($" meshRefs survivor count = {survivors} (markerSkipped={markerSkipped} gfxNull={gfxNull}) " +
$"=> GameWindow.cs:7324 would {(survivors == 0 ? "DROP" : "KEEP")} this entity");
}
+
+ ///
+ /// Follow-up (same session, 2026-07-09): user confirmed lighting improved but
+ /// reported missing candle flames + fountain water particles. Hypothesis tested:
+ /// same mesh-empty hydration-gate class as the light fix, just for
+ /// Setup.DefaultScript instead of Setup.Lights (GpuWorldState.cs:221 fires
+ /// ambient particle scripts from DefaultScript.DataId per hydrated entity — the
+ /// SAME lb.Entities list EntityHydrationRules.ShouldKeepEntity gates).
+ /// REFUTED — do not re-chase this specific mechanism for #79/#93's particle
+ /// residual. The fountain (0x02000AA3) has a SURVIVING mesh part (1/1) AND a
+ /// real DefaultScript (0x33000B21, almost certainly the water spray) — never
+ /// dropped by the gate, mesh or no. The "16 ring objects" guess (0x02001967) was
+ /// WRONG: real mesh, DefaultScript==0 — not candles, no script at all. Filed as
+ /// its own issue (missing ambient particles) — the remaining suspects are
+ /// downstream of hydration entirely: does EntityScriptActivator/
+ /// PhysicsScriptRunner actually fire DefaultScript=0x33000B21 for dat-hydrated
+ /// (ServerGuid==0) entities at runtime, does that script resolve to a real
+ /// PhysicsScriptTable entry, and does the resulting emitter reach the particle
+ /// renderer. NOT investigated further this session — separate root cause,
+ /// separate fix.
+ ///
+ [Theory]
+ [InlineData(0x02000AA3u)] // the fountain itself (cell 0x00070144 center)
+ [InlineData(0x02001967u)] // the 16 ring objects around the fountain (candles?)
+ [InlineData(0x020018C5u)] // the other cell-center static
+ public void FountainAndCandleSetup_DefaultScriptAndMeshSurvivorCount_Dump(uint setupId)
+ {
+ var datDir = ResolveDatDir();
+ if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
+ using var dats = new DatCollection(datDir, DatAccessType.Read);
+
+ var setup = dats.Get(setupId);
+ Assert.NotNull(setup);
+
+ _out.WriteLine($"=== Setup 0x{setupId:X8}: Parts={setup!.Parts.Count} DefaultScript.DataId=0x{setup.DefaultScript.DataId:X8} Lights={setup.Lights.Count} ===");
+
+ var flat = AcDream.Core.Meshing.SetupMesh.Flatten(setup);
+ int survivors = 0;
+ foreach (var mr in flat)
+ {
+ if (AcDream.Core.Meshing.GfxObjDegradeResolver.IsRuntimeHiddenMarker(dats, mr.GfxObjId)) continue;
+ if (dats.Get(mr.GfxObjId) is null) continue;
+ survivors++;
+ }
+ bool wouldBeKeptByCurrentFix = AcDream.Core.Meshing.EntityHydrationRules.ShouldKeepEntity(survivors, setup.Lights.Count);
+ _out.WriteLine($" flattened={flat.Count} meshSurvivors={survivors} " +
+ $"hasDefaultScript={setup.DefaultScript.DataId != 0} " +
+ $"=> current ShouldKeepEntity(mesh,lights) = {wouldBeKeptByCurrentFix}");
+ }
}