feat(headless): complete deterministic bot command parity

This commit is contained in:
Erik 2026-07-27 08:23:36 +02:00
parent 7e8acb74dd
commit 38e83640d9
37 changed files with 2805 additions and 295 deletions

View file

@ -518,6 +518,52 @@ public sealed class RuntimePhysicsStateTests
Assert.Equal(record.FullCellId, snapshot.FullCellId);
}
[Fact]
public void RemoteVelocityStalenessUsesInjectedRuntimeClock()
{
var time = new ManualTimeProvider(
DateTimeOffset.UnixEpoch.AddSeconds(100d));
using var lifetime = new RuntimeEntityObjectLifetime(
timeProvider: time);
RuntimeEntityRecord record =
lifetime.Entities.AddActive(Spawn(0x70000025u, 1));
var remote = new RemoteMotion
{
HasServerVelocity = true,
LastServerPosTime = 99d,
ServerVelocity = Vector3.UnitX,
};
remote.Body.Position = new Vector3(10f, 20f, 5f);
remote.Body.TransientState = TransientStateFlags.Active
| TransientStateFlags.Contact
| TransientStateFlags.OnWalkable;
lifetime.Physics.SetRemoteMotion(record, remote);
lifetime.Physics.AcknowledgeSpatialProjection(record, spatial: true);
var updater = new RuntimeRemotePhysicsUpdater(lifetime.Physics);
Vector3? cycle = null;
Assert.True(updater.Tick(
record,
remote,
objectScale: 1f,
sequencer: null,
dt: 0.1f,
objectClockEpoch: record.ObjectClockEpoch,
new MotionDeltaFrame
{
Orientation = Quaternion.Identity,
},
radius: 0.48f,
height: 1.835f,
liveCenterX: 1,
liveCenterY: 1,
applyStaleVelocityCycle: value => cycle = value));
Assert.False(remote.HasServerVelocity);
Assert.Equal(Vector3.Zero, remote.ServerVelocity);
Assert.Equal(Vector3.Zero, cycle);
}
[Fact]
public void PhysicsBodyAcquisitionIsCanonicalAndRejectsGuidReuse()
{
@ -551,6 +597,12 @@ public sealed class RuntimePhysicsStateTests
Assert.False(stale.PhysicsBodyAcquisitionInProgress);
}
private sealed class ManualTimeProvider(DateTimeOffset utcNow)
: TimeProvider
{
public override DateTimeOffset GetUtcNow() => utcNow;
}
[Fact]
public void PhysicsHostIdentityAndLookupBelongToExactRuntimeIncarnation()
{