Skip to content

Commit

Permalink
Add smoothing to catchup frames
Browse files Browse the repository at this point in the history
  • Loading branch information
adammitchelldev committed Jan 14, 2021
1 parent fba46e6 commit 804d292
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 12 deletions.
18 changes: 8 additions & 10 deletions OpenRA.Game/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static class Game
public const int NewNetcodeNetTickScale = 1; // Net tick every world frame
public const int Timestep = 40;
public const int TimestepJankThreshold = 250; // Don't catch up for delays larger than 250ms

public const double NetCatchupFactor = 0.25;
public static InstalledMods Mods { get; private set; }
public static ExternalMods ExternalMods { get; private set; }

Expand Down Expand Up @@ -600,10 +600,11 @@ static void InnerLogicTick(OrderManager orderManager)
worldTimestep = Timestep;
else if (world.IsLoadingGameSave)
worldTimestep = 1;
else if (orderManager.IsCatchingUp)
worldTimestep = Timestep / 4;
else if (orderManager.CatchUpFrames > 0)
worldTimestep = (int)Math.Floor(world.Timestep / (1.0 + NetCatchupFactor * orderManager.CatchUpFrames)); // Smooth catchup
else
worldTimestep = world.Timestep;

var worldTickDelta = tick - orderManager.LastTickTime;
if (worldTimestep == 0 || worldTickDelta < worldTimestep)
{
Expand Down Expand Up @@ -804,12 +805,9 @@ static void Loop()
var maxFramerate = Settings.Graphics.CapFramerate ? Settings.Graphics.MaxFramerate.Clamp(1, 1000) : 1000;
var renderInterval = 1000 / maxFramerate;

// Halve framerate and double logic when catching up
if (OrderManager.IsCatchingUp)
{
logicInterval /= 4;
renderInterval *= 2;
}
// TODO: limit rendering if we are taking too long to catch up
if (OrderManager.CatchUpFrames > 0)
logicInterval = (int)Math.Floor(logicInterval / (1.0 + NetCatchupFactor * OrderManager.CatchUpFrames));

// Tick as fast as possible while restoring game saves, capping rendering at 5 FPS
if (OrderManager.World != null && OrderManager.World.IsLoadingGameSave)
Expand Down Expand Up @@ -837,7 +835,7 @@ static void Loop()
LogicTick();

// Force at least one render per tick during regular gameplay
if (!OrderManager.IsCatchingUp && OrderManager.World != null && !OrderManager.World.IsLoadingGameSave && !OrderManager.World.IsReplay)
if (!(OrderManager.CatchUpFrames > 0) && OrderManager.World != null && !OrderManager.World.IsLoadingGameSave && !OrderManager.World.IsReplay)
renderBeforeNextTick = true;
}

Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Game/Network/OrderManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public sealed class OrderManager : IDisposable
public bool ShouldUseCatchUp;
public int OrderLatency; // Set during lobby by a "SyncInfo" packet, see UnitOrders
public int NextOrderFrame;
public bool IsCatchingUp { get; private set; }
public int CatchUpFrames { get; private set; }

public long LastTickTime = Game.RunTime;

Expand Down Expand Up @@ -201,7 +201,7 @@ void CompensateForLatency()
if (catchUpNetFrames < 0)
catchUpNetFrames = 0;

IsCatchingUp = ShouldUseCatchUp && catchUpNetFrames > 0;
CatchUpFrames = ShouldUseCatchUp ? catchUpNetFrames : 0;

if (LastSlowDownRequestTick + 5 < NetFrameNumber && (catchUpNetFrames > 5))
{
Expand Down

0 comments on commit 804d292

Please sign in to comment.