feat(streaming): shadow-publish flat collision assets

Carry one immutable prepared collision closure with each accepted near-tier generation and install graph plus flat views through the same retained publication receipt. Apply the same strict package-only rule to live entities, add exact sampled graph-authoritative comparison artifacts and lifecycle counters, and prove cancellation, demotion, rehydrate, revisit, teardown, reconnect, and the nine-stop route with 14,064 zero-mismatch samples.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-25 16:38:54 +02:00
parent f7ff9f4eea
commit d9446030e6
32 changed files with 2777 additions and 92 deletions

View file

@ -30,7 +30,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
private readonly RuntimeOptions _options;
private readonly IDatReaderWriter _dats;
private readonly LiveEntityRuntime _runtime;
private readonly PhysicsDataCache _physicsData;
private readonly LiveCollisionAssetPublisher _collisionAssets;
private readonly IAnimationLoader _animationLoader;
private readonly EntitySpawnAdapter _spawnAdapter;
private readonly TextureCache _textures;
@ -62,7 +62,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
RuntimeOptions options,
IDatReaderWriter dats,
LiveEntityRuntime runtime,
PhysicsDataCache physicsData,
LiveCollisionAssetPublisher collisionAssets,
IAnimationLoader animationLoader,
EntitySpawnAdapter spawnAdapter,
TextureCache textures,
@ -82,7 +82,8 @@ internal sealed class DatLiveEntityProjectionMaterializer
_options = options ?? throw new ArgumentNullException(nameof(options));
_dats = dats ?? throw new ArgumentNullException(nameof(dats));
_runtime = runtime ?? throw new ArgumentNullException(nameof(runtime));
_physicsData = physicsData ?? throw new ArgumentNullException(nameof(physicsData));
_collisionAssets = collisionAssets ??
throw new ArgumentNullException(nameof(collisionAssets));
_animationLoader = animationLoader ?? throw new ArgumentNullException(nameof(animationLoader));
_spawnAdapter = spawnAdapter ?? throw new ArgumentNullException(nameof(spawnAdapter));
_textures = textures ?? throw new ArgumentNullException(nameof(textures));
@ -172,7 +173,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
Setup? setup = _dats.Get<Setup>(canonicalSpawn.SetupTableId.Value);
if (setup is not null)
_physicsData.CacheSetup(canonicalSpawn.SetupTableId.Value, setup);
_collisionAssets.CacheSetup(canonicalSpawn.SetupTableId.Value, setup);
if (setup is null)
{
_missingSetup++;
@ -282,7 +283,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
continue;
}
_physicsData.CacheGfxObj(part.GfxObjId, gfx);
_collisionAssets.CacheGfxObj(part.GfxObjId, gfx);
if (dumpClothing)
{
var subMeshes = GfxObjMesh.Build(gfx, _dats);
@ -430,7 +431,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
}
if (slotZeroGfx is not null)
_physicsData.CacheGfxObj(slotZeroId, slotZeroGfx);
_collisionAssets.CacheGfxObj(slotZeroId, slotZeroGfx);
return slotZeroId;
}
@ -512,7 +513,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
}
continue;
}
_physicsData.CacheGfxObj(parts[partIndex].GfxObjId, gfx);
_collisionAssets.CacheGfxObj(parts[partIndex].GfxObjId, gfx);
Dictionary<uint, uint>? resolved = null;
foreach (var surfaceQid in gfx.Surfaces)