docs(#79/#93): dat-truth check refutes the mesh-gate theory for missing fountain/candle particles
Same-session follow-up: user confirmed the light-carrier hydration fix worked, then reported missing candle flames + fountain water particles. Tested whether it's the same root cause (a mesh-empty Setup dropped by EntityHydrationRules before its Setup.DefaultScript — the ambient particle script GpuWorldState.cs:221 fires — is ever read). Refuted: the fountain (0x02000AA3) has a surviving mesh part and a real DefaultScript (0x33000B21), never dropped by the gate. The guessed "candle" objects (0x02001967, ring of 16 around the fountain) have real mesh and no DefaultScript at all — not candles. Separate root cause; filed as its own issue rather than chased further this session. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
9ebb206086
commit
f6b054b7d7
1 changed files with 49 additions and 0 deletions
|
|
@ -134,4 +134,53 @@ public class Issue93TownNetworkFountainRoomLightInspectionTests
|
||||||
_out.WriteLine($" meshRefs survivor count = {survivors} (markerSkipped={markerSkipped} gfxNull={gfxNull}) " +
|
_out.WriteLine($" meshRefs survivor count = {survivors} (markerSkipped={markerSkipped} gfxNull={gfxNull}) " +
|
||||||
$"=> GameWindow.cs:7324 would {(survivors == 0 ? "DROP" : "KEEP")} this entity");
|
$"=> GameWindow.cs:7324 would {(survivors == 0 ? "DROP" : "KEEP")} this entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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).
|
||||||
|
/// <b>REFUTED — do not re-chase this specific mechanism for #79/#93's particle
|
||||||
|
/// residual.</b> 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.
|
||||||
|
/// </summary>
|
||||||
|
[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<Setup>(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<GfxObj>(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}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue