using AcDream.Core.Physics; using DatReaderWriter; using DatReaderWriter.DBObjs; using DatReaderWriter.Options; namespace AcDream.Content.Tests; /// /// AP-22 reachability proof. The deleted Setup-radius collision fallback fired /// only for a Setup with no CylSphere, no Sphere, and a nonzero summary /// Radius. This sweeps every Setup in the installed client_portal.dat and /// asserts no such Setup exists, so the deletion cannot remove collision from /// any real object. /// public sealed class InstalledSetupCollisionReachabilityTests { // Positive controls. These are EXTERNAL constants, measured on 2026-08-06 // by an independent raw client_portal.dat parse (B-tree directory walk + // Setup record decode) that validated itself by byte accounting: all // 5,935 records consumed with an exact residual tail of // 20 + 48 * numLights and zero unexplained bytes. // // They are deliberately NOT derived from FlatCollisionAssetBuilder. A // broken enumeration, a wrong dat path, or a silently-empty flatten all // satisfy the negative claim vacuously and are caught only here. private const int ExpectedSetups = 5935; private const int ExpectedWithCylinder = 678; private const int ExpectedSphereOnlyNoCylinder = 3605; private const int ExpectedWithoutAnyPrimitive = 1652; private const int ExpectedWithSummaryRadius = 4282; [Fact] public void InstalledSetups_NeverReachTheDeletedRadiusFallback() { string? datDir = ContentConformanceDats.ResolveDatDir(); if (datDir is null) return; using var dats = new DatCollection(datDir, DatAccessType.Read); int total = 0; int withCylinder = 0; int sphereOnly = 0; int withoutPrimitive = 0; int withRadius = 0; var fallbackReachable = new List(); var fallbackReachableWideGuard = new List(); foreach (uint id in dats.GetAllIdsOfType()) { if (!dats.Portal.TryGet(id, out Setup? setup) || setup is null) { continue; } FlatSetupCollision flat = FlatCollisionAssetBuilder.FlattenSetup(setup); total++; bool hasCylinder = flat.Cylinders.Length > 0; bool hasSphere = flat.Spheres.Length > 0; if (hasCylinder) withCylinder++; else if (hasSphere) sphereOnly++; else withoutPrimitive++; if (flat.Radius > 0.0001f) withRadius++; // BOTH guard variants the deleted copies used — they are not the // same predicate. Site 1 (LiveEntityCollisionBuilder) tested // `Radius > 0.0001f`; sites 2 and 3 (LandblockPhysicsPublisher, // LandblockPhysicsContentBuilder — the headless-reachable one) // tested the strictly wider `Radius > 0f`. Corrected 2026-08-06 at // the AP-22 architecture review, which measured that the two // genuinely differ over the installed DAT by exactly one Setup: // 0x02001657, whose radius is the denormal 1.3e-39. Asserting only // the narrow guard would have claimed coverage of two deletions it // never evaluated. if (!hasCylinder && !hasSphere && flat.Radius > 0.0001f) fallbackReachable.Add(id); if (!hasCylinder && !hasSphere && flat.Radius > 0f) fallbackReachableWideGuard.Add(id); } // (b) Positive controls first: if the enumeration is broken, fail here // rather than passing (a) for the wrong reason. Assert.Equal(ExpectedSetups, total); Assert.Equal(ExpectedWithCylinder, withCylinder); Assert.Equal(ExpectedSphereOnlyNoCylinder, sphereOnly); Assert.Equal(ExpectedWithoutAnyPrimitive, withoutPrimitive); Assert.Equal(ExpectedWithSummaryRadius, withRadius); // (a) The negative claim the deletion rests on. Assert.Empty(fallbackReachable); // The wider guard sites 2 and 3 actually used. Zero here is what makes // the headless-reachable deletion safe; the narrow guard above does // not evaluate it. Assert.Empty(fallbackReachableWideGuard); } }