mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Attempt #2 to fix the timing bugs. CurTime increases again, and all the unit tests pass this time.
This resolves https://github.com/space-wizards/space-station-14/issues/1560. Special thanks to PJB's prediction unit tests.
This commit is contained in:
@@ -117,6 +117,8 @@ namespace Robust.Client
|
||||
_entityManager.Startup();
|
||||
_mapManager.Startup();
|
||||
|
||||
_timing.ResetSimTime();
|
||||
_timing.Paused = false;
|
||||
PlayerJoinedServer?.Invoke(this, new PlayerEventArgs(session));
|
||||
}
|
||||
|
||||
@@ -190,7 +192,7 @@ namespace Robust.Client
|
||||
private void HandleSetTickRate(MsgSetTickRate message)
|
||||
{
|
||||
_timing.TickRate = message.NewTickRate;
|
||||
Logger.InfoS("client", $"Tickrate changed to: {message.NewTickRate}");
|
||||
Logger.InfoS("client", $"Tickrate changed to: {message.NewTickRate} on tick {_timing.CurTick}");
|
||||
}
|
||||
|
||||
private void OnLocalStatusChanged(object? obj, StatusEventArgs eventArgs)
|
||||
|
||||
@@ -268,6 +268,7 @@ namespace Robust.Client
|
||||
{
|
||||
_clyde.ProcessInput(frameEventArgs);
|
||||
_networkManager.ProcessPackets();
|
||||
_taskManager.ProcessPendingTasks(); // tasks like connect
|
||||
}
|
||||
|
||||
private void Tick(FrameEventArgs frameEventArgs)
|
||||
|
||||
@@ -400,11 +400,14 @@ namespace Robust.Server
|
||||
|
||||
_uptimeStopwatch.Start();
|
||||
|
||||
_mainLoop.Input += (sender, args) => Input(args);
|
||||
|
||||
_mainLoop.Tick += (sender, args) => Update(args);
|
||||
|
||||
_mainLoop.Update += (sender, args) => { ServerUpTime.Set(_uptimeStopwatch.Elapsed.TotalSeconds); };
|
||||
|
||||
// set GameLoop.Running to false to return from this function.
|
||||
_time.Paused = false;
|
||||
_mainLoop.Run();
|
||||
|
||||
_time.InSimulation = true;
|
||||
@@ -454,6 +457,8 @@ namespace Robust.Server
|
||||
{
|
||||
var b = (byte) i;
|
||||
_time.TickRate = b;
|
||||
|
||||
Logger.InfoS("game", $"Tickrate changed to: {b} on tick {_time.CurTick}");
|
||||
SendTickRateUpdateToClients(b);
|
||||
});
|
||||
|
||||
@@ -511,15 +516,20 @@ namespace Robust.Server
|
||||
return bps;
|
||||
}
|
||||
|
||||
private void Input(FrameEventArgs args)
|
||||
{
|
||||
_systemConsole.Update();
|
||||
|
||||
_network.ProcessPackets();
|
||||
_taskManager.ProcessPendingTasks();
|
||||
}
|
||||
|
||||
private void Update(FrameEventArgs frameEventArgs)
|
||||
{
|
||||
ServerCurTick.Set(_time.CurTick.Value);
|
||||
ServerCurTime.Set(_time.CurTime.TotalSeconds);
|
||||
|
||||
UpdateTitle();
|
||||
_systemConsole.Update();
|
||||
|
||||
_network.ProcessPackets();
|
||||
|
||||
_modLoader.BroadcastUpdate(ModUpdateLevel.PreEngine, frameEventArgs);
|
||||
|
||||
|
||||
@@ -136,5 +136,10 @@ namespace Robust.Shared.Interfaces.Timing
|
||||
string TickStamp => $"{CurTick}, predFirst: {IsFirstTimePredicted}, tickRem: {TickRemainder.TotalSeconds}, sim: {InSimulation}";
|
||||
|
||||
static string TickStampStatic => IoCManager.Resolve<IGameTiming>().TickStamp;
|
||||
|
||||
/// <summary>
|
||||
/// Resets the simulation time. This should be called on round restarts.
|
||||
/// </summary>
|
||||
void ResetSimTime();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Robust.Shared.Timing
|
||||
// does nothing if timer is already running
|
||||
_realTimer.Start();
|
||||
|
||||
Paused = false;
|
||||
Paused = true;
|
||||
TickRate = NumFrames;
|
||||
}
|
||||
|
||||
@@ -60,8 +60,17 @@ namespace Robust.Shared.Timing
|
||||
{
|
||||
get
|
||||
{
|
||||
// last tickrate change epoch
|
||||
var (time, lastTimeTick) = _cachedCurTimeInfo;
|
||||
|
||||
// add our current time to it.
|
||||
// the server never rewinds time, and the client never rewinds time outside of prediction.
|
||||
// the only way this assert should fail is if the TickRate is changed inside prediction, which should never happen.
|
||||
//DebugTools.Assert(CurTick >= lastTimeTick);
|
||||
//TODO: turns out prediction leaves CurTick at the last predicted tick, and not at the last processed server tick
|
||||
//so time gets rewound when processing events like TickRate.
|
||||
time += TickPeriod * (CurTick.Value - lastTimeTick.Value);
|
||||
|
||||
if (!InSimulation) // rendering can draw frames between ticks
|
||||
{
|
||||
DebugTools.Assert(0 <= (time + TickRemainder).TotalSeconds);
|
||||
@@ -191,8 +200,7 @@ namespace Robust.Shared.Timing
|
||||
}
|
||||
|
||||
// Calculate and store the current time value, based on the current tick rate.
|
||||
// Call this whenever you want an updated value for CurTime, or when
|
||||
// you change the TickRate
|
||||
// Call this whenever you change the TickRate.
|
||||
private void CacheCurTime()
|
||||
{
|
||||
var (cachedTime, lastTimeTick) = _cachedCurTimeInfo;
|
||||
@@ -217,6 +225,17 @@ namespace Robust.Shared.Timing
|
||||
_lastRealTime = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the simulation time.
|
||||
/// </summary>
|
||||
public void ResetSimTime()
|
||||
{
|
||||
_cachedCurTimeInfo = (TimeSpan.Zero, GameTick.First);;
|
||||
CurTick = GameTick.First;
|
||||
TickRemainder = TimeSpan.Zero;
|
||||
Paused = true;
|
||||
}
|
||||
|
||||
public bool IsFirstTimePredicted { get; private set; } = true;
|
||||
|
||||
public void StartPastPrediction()
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Robust.UnitTesting.Shared.Timing
|
||||
var newStopwatch = new Mock<IStopwatch>();
|
||||
newStopwatch.SetupGet(p => p.Elapsed).Returns(elapsedVal);
|
||||
var gameTiming = GameTimingFactory(newStopwatch.Object);
|
||||
gameTiming.Paused = false;
|
||||
var loop = new GameLoop(gameTiming);
|
||||
|
||||
var callCount = 0;
|
||||
|
||||
@@ -162,6 +162,7 @@ namespace Robust.UnitTesting.Shared.Timing
|
||||
newStopwatch.SetupGet(p => p.Elapsed).Returns(() => elapsedVal);
|
||||
var gameTiming = GameTimingFactory(newStopwatch.Object);
|
||||
gameTiming.InSimulation = false;
|
||||
gameTiming.Paused = false; // paused timing returns 0 frame time.
|
||||
gameTiming.StartFrame(); // changes last time from 0 to 3
|
||||
|
||||
// Act
|
||||
|
||||
Reference in New Issue
Block a user