refactor(runtime): own per-session physics simulation

Move the sole PhysicsEngine, production cache, collision admissions, canonical bodies and hosts, remote components, ordinary/remote worksets, simulation, cell commits, and shadow synchronization under RuntimeEntityObjectLifetime. Keep App as the prepared-asset, animation-input, and render-projection adapter while preserving the named-retail update and collision order.

Add exact-incarnation, object-clock, callback-reentrancy, GUID-reuse, two-runtime isolation, source ownership, collision publication, and graphical projection coverage. Release build and the complete 8,588-test solution pass.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-26 13:39:57 +02:00
parent 0dc3bfdeff
commit 7e6033d0ad
39 changed files with 3685 additions and 1722 deletions

View file

@ -105,7 +105,7 @@ public sealed class ProjectileControllerTests
LiveEntityRecord record = fixture.Spawn(instance: 1);
WorldEntity entity = record.WorldEntity!;
Assert.Null(record.AnimationRuntime);
var remote = new AcDream.App.Physics.RemoteMotion();
var remote = new AcDream.Runtime.Physics.RemoteMotion();
RemotePhysicsBodyInitializer.Initialize(remote.Body, record);
remote.Body.Position = entity.Position;
remote.Body.Orientation = entity.Rotation;
@ -124,7 +124,7 @@ public sealed class ProjectileControllerTests
isMovingTo: false,
currentBodyPosition: remote.Body.Position);
var updater = new RemotePhysicsUpdater(
fixture.Engine,
fixture.Live.Physics,
(_, _) => (0.48f, 1.835f),
(_, _, _, _) => { });
@ -685,7 +685,7 @@ public sealed class ProjectileControllerTests
LiveEntityRecord record = fixture.Spawn(instance: 1);
Assert.True(fixture.Controller.TryBind(record, ProjectileSetup(), 1.0));
PhysicsBody body = record.PhysicsBody!;
fixture.Live.SetRemoteMotionRuntime(Guid, new AcDream.App.Physics.RemoteMotion(body));
fixture.Live.SetRemoteMotionRuntime(Guid, new AcDream.Runtime.Physics.RemoteMotion(body));
record.FinalPhysicsState = PhysicsStateFlags.ReportCollisions;
Assert.True(fixture.Controller.ApplyAuthoritativeState(
record, record.FinalPhysicsState, 2.0, 1, 1));
@ -709,7 +709,7 @@ public sealed class ProjectileControllerTests
Assert.True(fixture.Controller.TryBind(record, ProjectileSetup(), 1.0));
PhysicsBody body = record.PhysicsBody!;
Vector3 position = body.Position;
fixture.Live.SetRemoteMotionRuntime(Guid, new AcDream.App.Physics.RemoteMotion(body));
fixture.Live.SetRemoteMotionRuntime(Guid, new AcDream.Runtime.Physics.RemoteMotion(body));
record.FinalPhysicsState = PhysicsStateFlags.ReportCollisions;
Assert.True(fixture.Controller.ApplyAuthoritativeState(
@ -948,7 +948,7 @@ public sealed class ProjectileControllerTests
var fixture = new Fixture();
LiveEntityRecord record = fixture.Spawn(instance: 1);
record.FinalPhysicsState = PhysicsStateFlags.ReportCollisions;
var remote = new AcDream.App.Physics.RemoteMotion();
var remote = new AcDream.Runtime.Physics.RemoteMotion();
RemotePhysicsBodyInitializer.Initialize(remote.Body, record);
fixture.Live.SetRemoteMotionRuntime(Guid, remote);
@ -1000,7 +1000,7 @@ public sealed class ProjectileControllerTests
var fixture = new Fixture();
LiveEntityRecord record = fixture.Spawn(instance: 1);
record.FinalPhysicsState = PhysicsStateFlags.ReportCollisions;
var remote = new AcDream.App.Physics.RemoteMotion();
var remote = new AcDream.Runtime.Physics.RemoteMotion();
RemotePhysicsBodyInitializer.Initialize(remote.Body, record);
fixture.Live.SetRemoteMotionRuntime(Guid, remote);
@ -1072,7 +1072,7 @@ public sealed class ProjectileControllerTests
seedCellId: startCell,
isStatic: false);
record.FinalPhysicsState = PhysicsStateFlags.ReportCollisions;
var remote = new AcDream.App.Physics.RemoteMotion();
var remote = new AcDream.Runtime.Physics.RemoteMotion();
RemotePhysicsBodyInitializer.Initialize(remote.Body, record);
Assert.Equal(new Vector3(40f, 0f, 0f), remote.Body.Velocity);
Assert.Equal(new Vector3(0f, 0f, 2f), remote.Body.Omega);
@ -1138,7 +1138,7 @@ public sealed class ProjectileControllerTests
velocity: new Vector3(float.NaN, 0f, 0f));
WorldEntity entity = record.WorldEntity!;
record.FinalPhysicsState = PhysicsStateFlags.ReportCollisions;
var remote = new AcDream.App.Physics.RemoteMotion();
var remote = new AcDream.Runtime.Physics.RemoteMotion();
RemotePhysicsBodyInitializer.Initialize(remote.Body, record);
remote.Body.Position = entity.Position;
remote.Body.Orientation = entity.Rotation;
@ -1164,7 +1164,7 @@ public sealed class ProjectileControllerTests
LiveEntityRecord record = fixture.Spawn(instance: 1);
WorldEntity entity = record.WorldEntity!;
record.FinalPhysicsState = PhysicsStateFlags.ReportCollisions;
var remote = new AcDream.App.Physics.RemoteMotion();
var remote = new AcDream.Runtime.Physics.RemoteMotion();
RemotePhysicsBodyInitializer.Initialize(remote.Body, record);
remote.Body.Position = entity.Position;
remote.Body.Orientation = entity.Rotation;
@ -1188,7 +1188,7 @@ public sealed class ProjectileControllerTests
LiveEntityRecord record = fixture.Spawn(instance: 1);
Assert.True(fixture.Controller.TryBind(record, ProjectileSetup(), 1.0));
PhysicsBody body = record.PhysicsBody!;
var remote = new AcDream.App.Physics.RemoteMotion(body);
var remote = new AcDream.Runtime.Physics.RemoteMotion(body);
fixture.Live.SetRemoteMotionRuntime(Guid, remote);
fixture.Live.RebucketLiveEntity(Guid, CellB);
@ -1200,7 +1200,7 @@ public sealed class ProjectileControllerTests
Assert.Same(body, record.RemoteMotionRuntime!.Body);
Assert.Same(body, record.ProjectileRuntime!.Body);
var replacement = new AcDream.App.Physics.RemoteMotion(body);
var replacement = new AcDream.Runtime.Physics.RemoteMotion(body);
fixture.Live.SetRemoteMotionRuntime(Guid, replacement);
remote.CellId = CellB;
Assert.Equal(CellA, record.FullCellId);