fix #435 (part 1): delete 17 probes that outlived their closed investigations
Each of these was temporary apparatus added to chase one bug, and each was supposed to be deleted in the commit that fixed it. Fourteen closed issues later they were still here: #337's support/wire-mesh trio, #171's sticky timeline, #119's viewer and entity dumps, #113's phantom probe, and a dozen more. 3,493 lines removed; the client now reads 144 environment variables instead of 161, and 47 temporary probes remain instead of 64. This is not only tidying. Every probe leaves a branch on its hot path when unset, several re-read the environment per call rather than caching, and the volume buries the diagnostics that are actually load-bearing. It is also a headless correctness matter: HeadlessStaticStateAudit reflects over PhysicsDiagnostics' flags to refuse a multi-session host when any is set, and cannot see probes that live outside that owner. Four files went entirely — WalkMissDiagnostic.cs, CollisionMeshWireframe.cs and two test files whose only subject was a deleted probe. TransitionTypes.SetContactPlane also sheds its CallerMemberName / CallerLineNumber parameters, which existed solely for #337's cpSrc= attribution and carried the instruction to strip them with the probe family; no call site passed them, so no behavior changes. F2's collision overlay survives and reverts to its proxy-cylinder form, which is what removing the ACDREAM_WIRE_MESH upgrade means. LaunchOptionsDocumentationTests earned its keep here: it refused the deletion until docs/launch-options.md moved the 17 rows into Retired and the frozen direct-read counts came down (PhysicsEngine.cs to zero, TransitionTypes.cs 3 to 2). The documentation could not drift during a cleanup this wide. The 14 probes that name no owning issue are deliberately NOT deleted. Nothing records when they became safe to remove, and guessing is how a future investigation loses apparatus it needed; #435 stays open for their attribution. Full hermetic suite 15,321 passed / 0 failed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
05bfe8d162
commit
0c5057c9ff
34 changed files with 57 additions and 3495 deletions
|
|
@ -780,21 +780,6 @@ public sealed partial class WbDrawDispatcher : IDisposable
|
|||
private readonly HashSet<ulong> _missRequested = new();
|
||||
private readonly HashSet<ulong> _missLogged = new();
|
||||
|
||||
// #119 decisive probe (2026-06-11): ACDREAM_DUMP_ENTITY one-shot entity
|
||||
// dump. Keyed by entity Id; the stored signature re-emits the header line
|
||||
// whenever (MeshRefs count, cache batch count, zero-translation count,
|
||||
// culled) changes — e.g. the Tier-1 populate landing one frame after the
|
||||
// first slow-path draw. The full per-part listing prints only on first
|
||||
// sight. Inert (one Count==0 check per new entity) when the env var is
|
||||
// unset. Render-thread only.
|
||||
private readonly Dictionary<uint, (int MeshRefCount, int CacheBatches, int ZeroT, bool Culled)> _entityDumpSig = new();
|
||||
|
||||
// Rate limiter for [dump-entity] WALK-REJECT lines: a rejected entity
|
||||
// re-tests every frame; emit the first rejection per entity then every
|
||||
// 300th (~5 s at 60 fps). Static because WalkEntitiesInto is static;
|
||||
// render-thread only like the walk itself.
|
||||
private static readonly Dictionary<uint, int> _walkRejectCounts = new();
|
||||
|
||||
// CPU + GPU timing for [WB-DIAG] under ACDREAM_WB_DIAG=1. The GPU samples
|
||||
// are written by the RHI arm's SampleRhiTimers (WbDrawDispatcher.Rhi.cs)
|
||||
// from the device's own timer pool; the raw-GL query-object ring that used
|
||||
|
|
@ -1200,7 +1185,6 @@ public sealed partial class WbDrawDispatcher : IDisposable
|
|||
if (!cellInVis)
|
||||
{
|
||||
if (shellScoped) result.BuildingShellAnchorReject++;
|
||||
MaybeEmitWalkRejectDump(entity, "visibleCellIds-miss");
|
||||
if (isCellEntity && RenderingDiagnostics.ProbeIndoorCullEnabled
|
||||
&& indoorProbeState!.ShouldEmit(cellProbeId))
|
||||
{
|
||||
|
|
@ -1226,7 +1210,6 @@ public sealed partial class WbDrawDispatcher : IDisposable
|
|||
|
||||
if (!aabbVisible)
|
||||
{
|
||||
MaybeEmitWalkRejectDump(entity, "frustum");
|
||||
if (isCellEntity && RenderingDiagnostics.ProbeIndoorCullEnabled
|
||||
&& indoorProbeState!.ShouldEmit(cellProbeId))
|
||||
{
|
||||
|
|
@ -1324,117 +1307,6 @@ public sealed partial class WbDrawDispatcher : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #119 decisive probe: rate-limited <c>[dump-entity] WALK-REJECT</c> line
|
||||
/// for an <c>ACDREAM_DUMP_ENTITY</c>-targeted entity that the walk filtered
|
||||
/// out (visibleCellIds gate / per-entity frustum). Absence of any DRAW dump
|
||||
/// plus presence of these lines attributes "entity exists but never reaches
|
||||
/// the draw loop" to the specific gate. Inert when the target set is empty.
|
||||
/// </summary>
|
||||
private static void MaybeEmitWalkRejectDump(WorldEntity entity, string reason)
|
||||
{
|
||||
var targets = RenderingDiagnostics.DumpEntitySourceIds;
|
||||
if (targets.Count == 0 || !targets.Contains(entity.SourceGfxObjOrSetupId)) return;
|
||||
_walkRejectCounts.TryGetValue(entity.Id, out int n);
|
||||
_walkRejectCounts[entity.Id] = n + 1;
|
||||
if (n % 300 != 0) return;
|
||||
Console.WriteLine(
|
||||
$"[dump-entity] WALK-REJECT id=0x{entity.Id:X8} src=0x{entity.SourceGfxObjOrSetupId:X8} " +
|
||||
$"reason={reason} parentCell=0x{(entity.ParentCellId ?? 0u):X8} " +
|
||||
$"pos=({entity.Position.X:F2},{entity.Position.Y:F2},{entity.Position.Z:F2}) n={n + 1}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #119 decisive probe: per-entity state dump at draw time for
|
||||
/// <c>ACDREAM_DUMP_ENTITY</c>-targeted entities. First sight prints a
|
||||
/// header + every MeshRef's GfxObj id, part-transform translation, and
|
||||
/// loaded flag; afterwards a compact header re-emits only when the
|
||||
/// (meshRefs, cacheBatches, zeroTranslations, culled) signature changes.
|
||||
/// Discriminates H-A (hydration-time MeshRef corruption: translations
|
||||
/// collapsed to ~zero / missing parts) from H-B (Tier-1 cache holding a
|
||||
/// partial or stale batch set) from H-C (both healthy ⇒ draw-side compose).
|
||||
/// </summary>
|
||||
private void MaybeEmitEntityDump(
|
||||
in RenderInstanceCandidate entity,
|
||||
uint landblockId,
|
||||
bool culled,
|
||||
IReadOnlyList<RenderInstanceTuple> tuples)
|
||||
{
|
||||
var targets = RenderingDiagnostics.DumpEntitySourceIds;
|
||||
if (targets.Count == 0 || !targets.Contains(entity.SourceId))
|
||||
return;
|
||||
|
||||
int zeroT = 0;
|
||||
int refsCount = 0;
|
||||
float tzMin = float.MaxValue, tzMax = float.MinValue;
|
||||
for (int i = 0; i < tuples.Count; i++)
|
||||
{
|
||||
RenderInstanceTuple tuple = tuples[i];
|
||||
if (tuple.Candidate.LocalEntityId != entity.LocalEntityId
|
||||
|| tuple.Candidate.TupleLandblockId
|
||||
!= entity.TupleLandblockId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
refsCount++;
|
||||
Vector3 t = tuple.MeshRef.PartTransform.Translation;
|
||||
if (t.LengthSquared() < 1e-9f) zeroT++;
|
||||
if (t.Z < tzMin) tzMin = t.Z;
|
||||
if (t.Z > tzMax) tzMax = t.Z;
|
||||
}
|
||||
|
||||
int cacheBatches = -1;
|
||||
int restZero = 0;
|
||||
float rzMin = float.MaxValue, rzMax = float.MinValue;
|
||||
if (_cache.TryGet(entity.Id, landblockId, out var cacheEntry))
|
||||
{
|
||||
cacheBatches = cacheEntry!.Batches.Length;
|
||||
foreach (var b in cacheEntry.Batches)
|
||||
{
|
||||
var t = b.RestPose.Translation;
|
||||
if (t.LengthSquared() < 1e-9f) restZero++;
|
||||
if (t.Z < rzMin) rzMin = t.Z;
|
||||
if (t.Z > rzMax) rzMax = t.Z;
|
||||
}
|
||||
}
|
||||
|
||||
var sig = (refsCount, cacheBatches, zeroT, culled);
|
||||
bool first = !_entityDumpSig.TryGetValue(entity.Id, out var prev);
|
||||
if (!first && prev == sig) return;
|
||||
_entityDumpSig[entity.Id] = sig;
|
||||
|
||||
string cacheStr = cacheBatches < 0
|
||||
? (_tier1CacheDisabled ? "disabled" : "miss")
|
||||
: $"hit:{cacheBatches} restZero={restZero} restZ=[{rzMin:F2}..{rzMax:F2}]";
|
||||
Console.WriteLine(
|
||||
$"[dump-entity] DRAW{(first ? "" : "-CHANGED")} id=0x{entity.Id:X8} src=0x{entity.SourceId:X8} " +
|
||||
$"lb=0x{landblockId:X8} cell=0x{entity.ParentCellId:X8} " +
|
||||
$"pos=({entity.Position.X:F2},{entity.Position.Y:F2},{entity.Position.Z:F2}) scale={entity.Scale:F2} " +
|
||||
$"meshRefs={refsCount} tZero={zeroT} tZ=[{tzMin:F2}..{tzMax:F2}] cache={cacheStr} culled={culled}");
|
||||
|
||||
if (first)
|
||||
{
|
||||
for (int i = 0; i < tuples.Count; i++)
|
||||
{
|
||||
RenderInstanceTuple tuple = tuples[i];
|
||||
if (tuple.Candidate.LocalEntityId
|
||||
!= entity.LocalEntityId
|
||||
|| tuple.Candidate.TupleLandblockId
|
||||
!= entity.TupleLandblockId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
MeshRef mr = tuple.MeshRef;
|
||||
var t = mr.PartTransform.Translation;
|
||||
bool loaded = _meshAdapter.TryGetRenderData(mr.GfxObjId) is not null;
|
||||
Console.WriteLine(
|
||||
$"[dump-entity] part[{tuple.MeshRefIndex:D2}] gfx=0x{mr.GfxObjId:X8} t=({t.X:F3},{t.Y:F3},{t.Z:F3}) loaded={loaded}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(
|
||||
ICamera camera,
|
||||
IEnumerable<(uint LandblockId, Vector3 AabbMin, Vector3 AabbMax,
|
||||
|
|
@ -1651,15 +1523,6 @@ public sealed partial class WbDrawDispatcher : IDisposable
|
|||
? new Vector2(lighting.Luminosity, lighting.Diffuse)
|
||||
: new Vector2(0f, 1f);
|
||||
|
||||
// #119 decisive probe: one-shot dump (+ change re-emission) for
|
||||
// ACDREAM_DUMP_ENTITY-targeted entities. Before the culled-continue
|
||||
// so a routed-out entity still reports its state.
|
||||
MaybeEmitEntityDump(
|
||||
in entity,
|
||||
cacheLb,
|
||||
_currentEntityCulled,
|
||||
_candidateTupleScratch);
|
||||
|
||||
// #176 seam-draw probe: any entity parented to a target cell reports
|
||||
// its position + light set (a floor-coincident static/plate would be
|
||||
// the z-fight's second draw; the player entity is the positive
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue