feat(physics): port retail complete object frame pipeline
Restore the named-retail object update order across local, remote, static, projectile, animation, shadow, teleport, and effect lifetimes. Separate authoritative root commits from spatial rebucketing, preserve per-owner hook/FIFO ordering, and remove update-path allocations with exact lifecycle and residency gates. Add deterministic conformance, adversarial lifetime, GUID-reuse, pending-cell, quaternion, timestamp, and allocation coverage. Release build is warning-free and all 6,446 tests pass with five intentional skips; retail, architecture, and adversarial reviews are clean. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
31a0889f08
commit
f961d70023
77 changed files with 12513 additions and 1871 deletions
|
|
@ -50,7 +50,10 @@ public sealed class RetailLocalPlayerFrameControllerTests
|
|||
},
|
||||
() => calls.Add("spatial"));
|
||||
|
||||
live.Tick(1f / 60f);
|
||||
// CPhysicsObj::update_object admits manager time only after the strict
|
||||
// minimum quantum. Use one admitted object tick; the test's concern is
|
||||
// the network barrier, not render-fragment accumulation.
|
||||
live.Tick(PhysicsBody.MaxQuantum);
|
||||
Assert.True(local.TryGetPresentationAfterNetwork(out var presentation));
|
||||
|
||||
Assert.Equal(
|
||||
|
|
@ -150,6 +153,119 @@ public sealed class RetailLocalPlayerFrameControllerTests
|
|||
Assert.Equal(controller.Position, positionSeenByTargetManager);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FrozenObject_IsPresentedWithoutPhysicsInputOrOutboundState()
|
||||
{
|
||||
PlayerMovementController controller = CreateController();
|
||||
Vector3 initial = controller.Position;
|
||||
int inputCaptures = 0;
|
||||
int projections = 0;
|
||||
int preNetwork = 0;
|
||||
int postNetwork = 0;
|
||||
var local = new RetailLocalPlayerFrameController(
|
||||
canPresentPlayer: () => true,
|
||||
getController: () => controller,
|
||||
captureInput: () =>
|
||||
{
|
||||
inputCaptures++;
|
||||
return new MovementInput(Forward: true);
|
||||
},
|
||||
resolveLocalEntityId: () => 7u,
|
||||
handleTargeting: () => throw new InvalidOperationException(
|
||||
"Frozen object advanced its manager tail."),
|
||||
isHidden: () => false,
|
||||
project: (_, _, _) => projections++,
|
||||
sendPreNetwork: (_, _, _) => preNetwork++,
|
||||
sendPostNetwork: (_, _) => postNetwork++,
|
||||
objectClockDisposition: () =>
|
||||
RetailObjectClockDisposition.Suspend);
|
||||
|
||||
local.AdvanceBeforeNetwork(PhysicsBody.MaxQuantum);
|
||||
local.RunPostNetworkCommandPhase();
|
||||
Assert.True(local.TryGetPresentationAfterNetwork(out var presentation));
|
||||
|
||||
Assert.Equal(initial, controller.Position);
|
||||
Assert.Equal(PhysicsBody.MaxQuantum, controller.SimTimeSeconds);
|
||||
Assert.Equal(0, inputCaptures);
|
||||
Assert.Equal(2, projections);
|
||||
Assert.Equal(0, preNetwork);
|
||||
Assert.Equal(0, postNetwork);
|
||||
Assert.False(presentation.AdvancedBeforeNetwork);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HiddenPoseIsDirtyOnlyWhenACompleteObjectQuantumRuns()
|
||||
{
|
||||
PlayerMovementController controller = CreateController();
|
||||
var local = new RetailLocalPlayerFrameController(
|
||||
canPresentPlayer: () => true,
|
||||
getController: () => controller,
|
||||
captureInput: () => new MovementInput(),
|
||||
resolveLocalEntityId: () => 7u,
|
||||
handleTargeting: () => { },
|
||||
isHidden: () => true,
|
||||
project: (_, _, _) => { },
|
||||
sendPreNetwork: (_, _, _) => { },
|
||||
sendPostNetwork: (_, _) => { });
|
||||
|
||||
local.AdvanceBeforeNetwork(PhysicsBody.MaxQuantum);
|
||||
Assert.True(local.HiddenPartPoseDirty);
|
||||
|
||||
local.AdvanceBeforeNetwork(PhysicsBody.MinQuantum / 2f);
|
||||
Assert.False(local.HiddenPartPoseDirty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidElapsed_PublishesSnapshotWithoutInputOrNetworkCallbacks()
|
||||
{
|
||||
PlayerMovementController controller = CreateController();
|
||||
int inputCaptures = 0;
|
||||
int targeting = 0;
|
||||
int projections = 0;
|
||||
int preNetwork = 0;
|
||||
int postNetwork = 0;
|
||||
var local = new RetailLocalPlayerFrameController(
|
||||
canPresentPlayer: () => true,
|
||||
getController: () => controller,
|
||||
captureInput: () =>
|
||||
{
|
||||
inputCaptures++;
|
||||
return new MovementInput(Forward: true);
|
||||
},
|
||||
resolveLocalEntityId: () => 7u,
|
||||
handleTargeting: () => targeting++,
|
||||
isHidden: () => false,
|
||||
project: (_, _, _) => projections++,
|
||||
sendPreNetwork: (_, _, _) => preNetwork++,
|
||||
sendPostNetwork: (_, _) => postNetwork++);
|
||||
float initialTime = controller.SimTimeSeconds;
|
||||
Vector3 initialPosition = controller.Position;
|
||||
|
||||
foreach (float elapsed in new[]
|
||||
{
|
||||
float.NaN,
|
||||
float.PositiveInfinity,
|
||||
float.NegativeInfinity,
|
||||
-1f,
|
||||
0f,
|
||||
})
|
||||
{
|
||||
local.AdvanceBeforeNetwork(elapsed);
|
||||
local.RunPostNetworkCommandPhase();
|
||||
Assert.True(local.TryGetPresentationAfterNetwork(out var frame));
|
||||
Assert.False(frame.AdvancedBeforeNetwork);
|
||||
Assert.False(local.HiddenPartPoseDirty);
|
||||
}
|
||||
|
||||
Assert.Equal(initialTime, controller.SimTimeSeconds);
|
||||
Assert.Equal(initialPosition, controller.Position);
|
||||
Assert.Equal(0, inputCaptures);
|
||||
Assert.Equal(0, targeting);
|
||||
Assert.Equal(0, preNetwork);
|
||||
Assert.Equal(0, postNetwork);
|
||||
Assert.Equal(10, projections);
|
||||
}
|
||||
|
||||
private static PlayerMovementController CreateController()
|
||||
{
|
||||
var engine = new PhysicsEngine();
|
||||
|
|
@ -167,8 +283,10 @@ public sealed class RetailLocalPlayerFrameControllerTests
|
|||
worldOffsetX: 0f,
|
||||
worldOffsetY: 0f);
|
||||
|
||||
var controller = new PlayerMovementController(engine);
|
||||
var clock = new RetailObjectQuantumClock();
|
||||
var controller = new PlayerMovementController(engine, clock);
|
||||
controller.SetPosition(new Vector3(96f, 96f, 50f), 0x0001u);
|
||||
Assert.True(clock.IsActive);
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue