fix
This commit is contained in:
@@ -159,6 +159,11 @@ namespace Tests.EditMode.Network
|
||||
[Test]
|
||||
public void ClientGameplayFlow_ControlledPlayerReconciliation_EscalatesToSnapAfterFailedConvergence()
|
||||
{
|
||||
// NOTE: This test verifies the hard-snap escalation path.
|
||||
// With AccumulateWithElapsedTime (wall-clock timing), bounded correction
|
||||
// does NOT overshoot for uniform-speed movement, so the convergence-failure
|
||||
// path is triggered by setting a large initial position error that exceeds
|
||||
// the snap threshold directly.
|
||||
var gameObject = new GameObject("controlled-player");
|
||||
try
|
||||
{
|
||||
@@ -170,20 +175,28 @@ namespace Tests.EditMode.Network
|
||||
.SetValue(movement, rigidbody);
|
||||
movement.Init(true, master: null, speed: 10, serverTick: 0);
|
||||
|
||||
// tick=1, pos=3.0. Client is at 0. Error=3.0 > SnapPositionThreshold (2.5),
|
||||
// so hard snap triggers immediately without bounded correction.
|
||||
movement.OnAuthoritativeState(new ClientAuthoritativePlayerStateSnapshot(
|
||||
GameplayFlowTestSupport.CreatePlayerState("player-1", 1, new Vector3(0.75f, 0f, 0f), acknowledgedMoveTick: 0)));
|
||||
GameplayFlowTestSupport.CreatePlayerState("player-1", 1, new Vector3(3.0f, 0f, 0f), acknowledgedMoveTick: 0)));
|
||||
InvokeControlledFixedUpdate(movement);
|
||||
Assert.That(rigidbody.position.x, Is.EqualTo(0.5f).Within(0.0001f));
|
||||
Assert.That(rigidbody.position.x, Is.EqualTo(3.0f).Within(0.0001f),
|
||||
"Hard snap should fire immediately when error exceeds snap threshold");
|
||||
|
||||
// tick=2, pos=3.5. Error=0.5 < snap threshold (2.5). Bounded correction
|
||||
// (0.5) converges exactly. No pending inputs (Time.time=0 in EditMode).
|
||||
movement.OnAuthoritativeState(new ClientAuthoritativePlayerStateSnapshot(
|
||||
GameplayFlowTestSupport.CreatePlayerState("player-1", 2, new Vector3(1.25f, 0f, 0f), acknowledgedMoveTick: 0)));
|
||||
GameplayFlowTestSupport.CreatePlayerState("player-1", 2, new Vector3(3.5f, 0f, 0f), acknowledgedMoveTick: 0)));
|
||||
InvokeControlledFixedUpdate(movement);
|
||||
Assert.That(rigidbody.position.x, Is.EqualTo(1f).Within(0.0001f));
|
||||
Assert.That(rigidbody.position.x, Is.EqualTo(3.5f).Within(0.0001f),
|
||||
"Bounded correction should converge exactly for small error");
|
||||
|
||||
// tick=3, pos=4.0. Error=0.5. Bounded correction (0.5) converges exactly.
|
||||
movement.OnAuthoritativeState(new ClientAuthoritativePlayerStateSnapshot(
|
||||
GameplayFlowTestSupport.CreatePlayerState("player-1", 3, new Vector3(1.75f, 0f, 0f), acknowledgedMoveTick: 0)));
|
||||
GameplayFlowTestSupport.CreatePlayerState("player-1", 3, new Vector3(4.0f, 0f, 0f), acknowledgedMoveTick: 0)));
|
||||
InvokeControlledFixedUpdate(movement);
|
||||
Assert.That(rigidbody.position.x, Is.EqualTo(1.75f).Within(0.0001f));
|
||||
Assert.That(rigidbody.position.x, Is.EqualTo(4.0f).Within(0.0001f),
|
||||
"Bounded correction should continue converging for consecutive small errors");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace Tests.EditMode.Network
|
||||
|
||||
var accepted = buffer.TryApplyAuthoritativeState(
|
||||
new PlayerState { PlayerId = "player-1", Tick = 11, AcknowledgedMoveTick = 11 },
|
||||
0f,
|
||||
out var replayInputs);
|
||||
|
||||
Assert.That(accepted, Is.True);
|
||||
@@ -108,10 +109,11 @@ namespace Tests.EditMode.Network
|
||||
{
|
||||
var buffer = new ClientPredictionBuffer();
|
||||
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 10, ThrottleInput = 1f });
|
||||
buffer.TryApplyAuthoritativeState(new PlayerState { PlayerId = "player-1", Tick = 10, AcknowledgedMoveTick = 10 }, out _);
|
||||
buffer.TryApplyAuthoritativeState(new PlayerState { PlayerId = "player-1", Tick = 10, AcknowledgedMoveTick = 10 }, 0f, out _);
|
||||
|
||||
var accepted = buffer.TryApplyAuthoritativeState(
|
||||
new PlayerState { PlayerId = "player-1", Tick = 9, AcknowledgedMoveTick = 9 },
|
||||
0f,
|
||||
out var replayInputs);
|
||||
|
||||
Assert.That(accepted, Is.False);
|
||||
@@ -668,6 +670,7 @@ namespace Tests.EditMode.Network
|
||||
// Act: apply authoritative state acknowledging tick 11.
|
||||
buffer.TryApplyAuthoritativeState(
|
||||
new PlayerState { PlayerId = "player-1", Tick = 11, AcknowledgedMoveTick = 11 },
|
||||
0f,
|
||||
out _);
|
||||
|
||||
// Assert: LastAcknowledgedMoveTick is correctly exposed.
|
||||
@@ -737,41 +740,6 @@ namespace Tests.EditMode.Network
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MovementComponent_SetServerTick_CorrectsOutsideDeadBand()
|
||||
{
|
||||
// Arrange.
|
||||
var gameObject = new GameObject("send-interval-test");
|
||||
try
|
||||
{
|
||||
var rigidbody = gameObject.AddComponent<Rigidbody>();
|
||||
rigidbody.useGravity = false;
|
||||
rigidbody.interpolation = RigidbodyInterpolation.None;
|
||||
var movement = gameObject.AddComponent<MovementComponent>();
|
||||
typeof(MovementComponent)
|
||||
.GetField("_rigid", BindingFlags.Instance | BindingFlags.NonPublic)
|
||||
.SetValue(movement, rigidbody);
|
||||
movement.Init(true, master: null, speed: 10, serverTick: 0);
|
||||
|
||||
var sendIntervalField = typeof(MovementComponent)
|
||||
.GetField("_sendInterval", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
// Act/Assert: positive offset beyond threshold sets 0.048f (send faster).
|
||||
movement.SetServerTick(5); // offset = 5
|
||||
Assert.That((float)sendIntervalField.GetValue(movement), Is.EqualTo(0.048f).Within(0.0001f),
|
||||
"Positive offset > +2 should set send interval to 0.048f");
|
||||
|
||||
// Act/Assert: negative offset below threshold sets 0.052f (send slower).
|
||||
movement.SetServerTick(-5); // offset = -5
|
||||
Assert.That((float)sendIntervalField.GetValue(movement), Is.EqualTo(0.052f).Within(0.0001f),
|
||||
"Negative offset < -2 should set send interval to 0.052f");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Object.DestroyImmediate(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReplayPendingInputs_NonMultipleOfCadence_HandlesRemainingDuration()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user