From 24de2841d9eae7023584ff0885a1de0326fa37d1 Mon Sep 17 00:00:00 2001 From: "CTHULHU\\Ben" Date: Sat, 24 Aug 2024 19:42:11 -0400 Subject: [PATCH 1/6] get a more accurate local time by using half the RTT. --- .../Runtime/Timing/NetworkTimeSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs index 4dbd85a046..d6354a450a 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs @@ -248,7 +248,7 @@ public void Sync(double serverTimeSec, double rttSec) var timeDif = serverTimeSec - m_TimeSec; m_DesiredServerTimeOffset = timeDif - ServerBufferSec; - m_DesiredLocalTimeOffset = timeDif + rttSec + LocalBufferSec; + m_DesiredLocalTimeOffset = timeDif + (rttSec * 0.5d) + LocalBufferSec; } } } From b9a9da86c9b7233ba68c8eac7cf2276dd47d6121 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 15 Jan 2025 13:56:36 -0600 Subject: [PATCH 2/6] update adding change log entry. --- com.unity.netcode.gameobjects/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index f05ecff6a7..aa7da36ee1 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -18,6 +18,8 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Changed +- Changed the `NetworkTimeSystem.Sync` method to use half RTT to calcule the desired local time offset as opposed to the full RTT. + ## [1.12.0] - 2024-11-19 ### Added From 4945e3d226ca61ee21a95a5f7e5d3f11788f4bd9 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 15 Jan 2025 14:03:01 -0600 Subject: [PATCH 3/6] updarte adding PR number to entry. --- com.unity.netcode.gameobjects/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index aa7da36ee1..dcd384061b 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -18,7 +18,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Changed -- Changed the `NetworkTimeSystem.Sync` method to use half RTT to calcule the desired local time offset as opposed to the full RTT. +- Changed the `NetworkTimeSystem.Sync` method to use half RTT to calculate the desired local time offset as opposed to the full RTT. (#3206) ## [1.12.0] - 2024-11-19 From 07575a58483b74dbe2c7500f3f9c97bdc43824d1 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 15 Jan 2025 18:45:25 -0600 Subject: [PATCH 4/6] test Adjusting ClientNetworkTimeSystemTests to account for half RTT adjustment applied in this PR. --- .../Timing/ClientNetworkTimeSystemTests.cs | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs index 8913ebc74a..b3d8f6612d 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs @@ -18,15 +18,16 @@ public class ClientNetworkTimeSystemTests public void StableRttTest() { double receivedServerTime = 2; - - var timeSystem = new NetworkTimeSystem(0.05d, 0.05d, 0.1d); + var baseRtt = 0.1f; + var halfRtt = 0.05f; + var timeSystem = new NetworkTimeSystem(0.05d, 0.05d, baseRtt); timeSystem.Reset(receivedServerTime, 0.15); var tickSystem = new NetworkTickSystem(60, timeSystem.LocalTime, timeSystem.ServerTime); Assert.True(timeSystem.LocalTime > 2); - var steps = TimingTestHelper.GetRandomTimeSteps(100f, 0.01f, 0.1f, 42); - var rttSteps = TimingTestHelper.GetRandomTimeSteps(1000f, 0.095f, 0.105f, 42); // 10ms jitter + var steps = TimingTestHelper.GetRandomTimeSteps(100f, 0.01f, baseRtt, 42); + var rttSteps = TimingTestHelper.GetRandomTimeSteps(1000f, baseRtt - 0.05f, baseRtt + 0.05f, 42); // 10ms jitter // run for a while so that we reach regular RTT offset TimingTestHelper.ApplySteps(timeSystem, tickSystem, steps, delegate (int step) @@ -37,10 +38,11 @@ public void StableRttTest() }); // check how we close we are to target time. - var expectedRtt = 0.1d; - var offsetToTarget = (timeSystem.LocalTime - timeSystem.ServerTime) - expectedRtt - timeSystem.ServerBufferSec - timeSystem.LocalBufferSec; + var offsetToTarget = (timeSystem.LocalTime - timeSystem.ServerTime) - halfRtt - timeSystem.ServerBufferSec - timeSystem.LocalBufferSec; Debug.Log($"offset to target time after running for a while: {offsetToTarget}"); - Assert.IsTrue(Math.Abs(offsetToTarget) < k_AcceptableRttOffset); + + // server speedup/slowdowns should not be affected by RTT + Assert.True(Math.Abs(offsetToTarget) < k_AcceptableRttOffset, $"Expected offset time to be less than {k_AcceptableRttOffset}ms but it was {offsetToTarget}!"); // run again, test that we never need to speed up or slow down under stable RTT TimingTestHelper.ApplySteps(timeSystem, tickSystem, steps, delegate (int step) @@ -51,9 +53,10 @@ public void StableRttTest() }); // check again to ensure we are still close to the target - var newOffsetToTarget = (timeSystem.LocalTime - timeSystem.ServerTime) - expectedRtt - timeSystem.ServerBufferSec - timeSystem.LocalBufferSec; + var newOffsetToTarget = (timeSystem.LocalTime - timeSystem.ServerTime) - halfRtt - timeSystem.ServerBufferSec - timeSystem.LocalBufferSec; Debug.Log($"offset to target time after running longer: {newOffsetToTarget}"); - Assert.IsTrue(Math.Abs(newOffsetToTarget) < k_AcceptableRttOffset); + // server speedup/slowdowns should not be affected by RTT + Assert.True(Math.Abs(offsetToTarget) < k_AcceptableRttOffset, $"Expected offset time to be less than {k_AcceptableRttOffset}ms but it was {offsetToTarget}!"); // difference between first and second offset should be minimal var dif = offsetToTarget - newOffsetToTarget; @@ -67,13 +70,14 @@ public void StableRttTest() public void RttCatchupSlowdownTest() { double receivedServerTime = 2; - - var timeSystem = new NetworkTimeSystem(0.05d, 0.05d, 0.1d); + var baseRtt = 0.1f; + var halfRtt = 0.05f; + var timeSystem = new NetworkTimeSystem(0.05d, 0.05d, baseRtt); timeSystem.Reset(receivedServerTime, 0.15); var tickSystem = new NetworkTickSystem(60, timeSystem.LocalTime, timeSystem.ServerTime); - var steps = TimingTestHelper.GetRandomTimeSteps(100f, 0.01f, 0.1f, 42); - var rttSteps = TimingTestHelper.GetRandomTimeSteps(1000f, 0.095f, 0.105f, 42); // 10ms jitter + var steps = TimingTestHelper.GetRandomTimeSteps(100f, 0.01f, baseRtt, 42); + var rttSteps = TimingTestHelper.GetRandomTimeSteps(1000f, baseRtt - 0.05f, baseRtt + 0.05f, 42); // 10ms jitter // run for a while so that we reach regular RTT offset TimingTestHelper.ApplySteps(timeSystem, tickSystem, steps, delegate (int step) @@ -102,11 +106,14 @@ public void RttCatchupSlowdownTest() // speed up of 0.1f expected Debug.Log($"Total local speed up time catch up: {totalLocalSpeedUpTime}"); - Assert.True(Math.Abs(totalLocalSpeedUpTime - 0.1) < k_AcceptableRttOffset); - Assert.True(Math.Abs(totalServerSpeedUpTime) < k_AcceptableRttOffset); // server speedup/slowdowns should not be affected by RTT + var expectedSpeedUpTime = Math.Abs(totalLocalSpeedUpTime - halfRtt); + var expectedServerSpeedUpTime = Math.Abs(totalServerSpeedUpTime); + Assert.True(expectedSpeedUpTime < k_AcceptableRttOffset, $"Expected local speed up time to be less than {k_AcceptableRttOffset}ms but it was {expectedSpeedUpTime}!"); + // server speedup/slowdowns should not be affected by RTT + Assert.True(Math.Abs(totalServerSpeedUpTime) < k_AcceptableRttOffset, $"Expected server speed up time to be less than {k_AcceptableRttOffset}ms but it was {expectedServerSpeedUpTime}!"); - // run again with RTT ~100ms and see whether we slow down by -0.1f + // run again with RTT ~100ms and see whether we slow down by -halfRtt unscaledLocalTime = timeSystem.LocalTime; unscaledServerTime = timeSystem.ServerTime; @@ -121,13 +128,13 @@ public void RttCatchupSlowdownTest() totalLocalSpeedUpTime = timeSystem.LocalTime - unscaledLocalTime; totalServerSpeedUpTime = timeSystem.ServerTime - unscaledServerTime; - - // slow down of 0.1f expected + // slow down of half halfRtt expected Debug.Log($"Total local speed up time slow down: {totalLocalSpeedUpTime}"); - Assert.True(Math.Abs(totalLocalSpeedUpTime + 0.1) < k_AcceptableRttOffset); - Assert.True(Math.Abs(totalServerSpeedUpTime) < k_AcceptableRttOffset); // server speedup/slowdowns should not be affected by RTT - - + expectedSpeedUpTime = Math.Abs(totalLocalSpeedUpTime + halfRtt); + expectedServerSpeedUpTime = Math.Abs(totalServerSpeedUpTime); + Assert.True(expectedSpeedUpTime < k_AcceptableRttOffset, $"Expected local speed up time to be less than {k_AcceptableRttOffset}ms but it was {expectedSpeedUpTime}!"); + // server speedup/slowdowns should not be affected by RTT + Assert.True(Math.Abs(totalServerSpeedUpTime) < k_AcceptableRttOffset, $"Expected server speed up time to be less than {k_AcceptableRttOffset}ms but it was {expectedServerSpeedUpTime}!"); } /// @@ -172,8 +179,8 @@ public void ResetTest() receivedServerTime += steps[step]; timeSystem.Sync(receivedServerTime, rttSteps2[step]); - // after hard reset time should stay close to rtt - var expectedRtt = 0.5d; + // after hard reset time should stay close to half rtt + var expectedRtt = 0.25d; Assert.IsTrue(Math.Abs((timeSystem.LocalTime - timeSystem.ServerTime) - expectedRtt - timeSystem.ServerBufferSec - timeSystem.LocalBufferSec) < k_AcceptableRttOffset); }); From a04a177e9c95696e8944616e9ab5244f16e936fa Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 15 Jan 2025 18:48:53 -0600 Subject: [PATCH 5/6] style Adding a comment about the change --- .../Runtime/Timing/NetworkTimeSystem.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs index d6354a450a..41327dbcd2 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs @@ -248,6 +248,8 @@ public void Sync(double serverTimeSec, double rttSec) var timeDif = serverTimeSec - m_TimeSec; m_DesiredServerTimeOffset = timeDif - ServerBufferSec; + // We adjust our desired local time offset to be half RTT since the delivery of + // the TimeSyncMessage should only take half of the RTT time (legacy was using 1 full RTT) m_DesiredLocalTimeOffset = timeDif + (rttSec * 0.5d) + LocalBufferSec; } } From 5f12a968f57e4b4f6d630291343b4308c19527c0 Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Sun, 19 Jan 2025 10:56:24 -0600 Subject: [PATCH 6/6] style removing whitespace after comment --- .../Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs index b3d8f6612d..1b74014b9b 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs @@ -27,7 +27,7 @@ public void StableRttTest() Assert.True(timeSystem.LocalTime > 2); var steps = TimingTestHelper.GetRandomTimeSteps(100f, 0.01f, baseRtt, 42); - var rttSteps = TimingTestHelper.GetRandomTimeSteps(1000f, baseRtt - 0.05f, baseRtt + 0.05f, 42); // 10ms jitter + var rttSteps = TimingTestHelper.GetRandomTimeSteps(1000f, baseRtt - 0.05f, baseRtt + 0.05f, 42); // 10ms jitter // run for a while so that we reach regular RTT offset TimingTestHelper.ApplySteps(timeSystem, tickSystem, steps, delegate (int step)