Added dynamic tic stabilization
Attempts to balance periods of rough traffic by putting in an artificial delay, smoothing playback but further increasing input delay. This can be disabled with net_ticbalance.
This commit is contained in:
parent
54f1f5ad9d
commit
0e23b900bb
3 changed files with 65 additions and 3 deletions
|
|
@ -11,6 +11,7 @@ enum ENetConstants
|
|||
BACKUPTICS = 35 * 5, // Remember up to 5 seconds of data.
|
||||
MAXTICDUP = 3,
|
||||
MAXSENDTICS = 35 * 1, // Only send up to 1 second of data at a time.
|
||||
STABILITYTICS = 12,
|
||||
LOCALCMDTICS = (BACKUPTICS * MAXTICDUP),
|
||||
MAX_MSGLEN = 14000,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -116,6 +116,14 @@ int LastSentConsistency = 0; // Last consistency we sent out. If < CurrentC
|
|||
int CurrentConsistency = 0; // Last consistency we generated.
|
||||
FClientNetState ClientStates[MAXPLAYERS] = {};
|
||||
|
||||
// Try and stabilize uneven connections by checking for spikes in available
|
||||
// sequences. If they're found, try and average out a buffer to prioritize
|
||||
// making the experience smoother over very stop and go heavy.
|
||||
static int StabilityBuffer = 0;
|
||||
static int PrevAvailableDiff = 0;
|
||||
static size_t CurStabilityTic = 0u;
|
||||
static int StabilityTics[STABILITYTICS] = {};
|
||||
|
||||
// If we're sending a packet to ourselves, store it here instead. This is the simplest way to execute
|
||||
// playback as it means in the world running code itself all player commands are built the exact same way
|
||||
// instead of having to rely on pulling from the correct local buffers. It also ensures all commands are
|
||||
|
|
@ -157,7 +165,7 @@ extern bool advancedemo;
|
|||
CVAR(Bool, vid_dontdowait, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, vid_lowerinbackground, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
CVAR(Bool, net_ticbalance, false, CVAR_SERVERINFO | CVAR_NOSAVE) // Currently deprecated, but may be brought back later.
|
||||
CVAR(Bool, net_ticbalance, true, CVAR_SERVERINFO | CVAR_NOSAVE)
|
||||
CVAR(Bool, net_extratic, false, CVAR_SERVERINFO | CVAR_NOSAVE)
|
||||
CVAR(Bool, net_limitsaves, true, CVAR_SERVERINFO | CVAR_NOSAVE)
|
||||
CVAR(Bool, net_repeatableactioncooldown, true, CVAR_SERVERINFO | CVAR_NOSAVE)
|
||||
|
|
@ -395,6 +403,9 @@ void Net_ClearBuffers()
|
|||
LastEnterTic = LastGameUpdate = EnterTic;
|
||||
gametic = ClientTic = 0;
|
||||
SkipCommandTimer = SkipCommandAmount = CommandsAhead = 0;
|
||||
StabilityBuffer = PrevAvailableDiff = 0;
|
||||
CurStabilityTic = 0u;
|
||||
memset(StabilityTics, 0, sizeof(StabilityTics));
|
||||
NetEvents.ResetStream();
|
||||
|
||||
CutsceneReady = 0u;
|
||||
|
|
@ -502,6 +513,9 @@ void Net_ResetCommands(bool midTic)
|
|||
bCommandsReset = midTic;
|
||||
++CurrentLobbyID;
|
||||
SkipCommandTimer = SkipCommandAmount = CommandsAhead = 0;
|
||||
StabilityBuffer = PrevAvailableDiff = 0;
|
||||
CurStabilityTic = 0u;
|
||||
memset(StabilityTics, 0, sizeof(StabilityTics));
|
||||
|
||||
int tic = gametic / TicDup;
|
||||
if (midTic)
|
||||
|
|
@ -1292,6 +1306,7 @@ static bool Net_UpdateStatus()
|
|||
|
||||
if (updated)
|
||||
{
|
||||
lowestDiff -= StabilityBuffer;
|
||||
if (lowestDiff > 0)
|
||||
{
|
||||
if (SkipCommandTimer++ > TICRATE / 2)
|
||||
|
|
@ -2090,6 +2105,47 @@ static bool ShouldStabilizeTick()
|
|||
&& gameaction != ga_worlddone && gameaction != ga_completed && gameaction != ga_screenshot && gameaction != ga_fullconsole;
|
||||
}
|
||||
|
||||
// If the connection has been unstable then let the game lag behind for a little bit
|
||||
// while we wait for it to stabilize, otherwise everything will appear to jitter around.
|
||||
static void CalculateNetStabilityBuffer(int diff)
|
||||
{
|
||||
if (!netgame || demoplayback)
|
||||
{
|
||||
StabilityBuffer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (diff < 0)
|
||||
diff = 0;
|
||||
|
||||
if (!(gametic % TicDup))
|
||||
{
|
||||
StabilityTics[CurStabilityTic++ % STABILITYTICS] = diff > PrevAvailableDiff ? diff : 0;
|
||||
PrevAvailableDiff = diff;
|
||||
}
|
||||
|
||||
// If we're not balancing latency, just give an extra tic for padding
|
||||
// and nothing else.
|
||||
if (!net_ticbalance)
|
||||
{
|
||||
StabilityBuffer = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
double total = 0.0;
|
||||
int unstableCount = 0;
|
||||
for (int t : StabilityTics)
|
||||
{
|
||||
if (t > 0)
|
||||
{
|
||||
++unstableCount;
|
||||
total += t;
|
||||
}
|
||||
}
|
||||
|
||||
StabilityBuffer = unstableCount > 0 ? static_cast<int>(ceil(total / unstableCount)) : 0;
|
||||
}
|
||||
|
||||
//
|
||||
// TryRunTics
|
||||
//
|
||||
|
|
@ -2148,8 +2204,12 @@ void TryRunTics()
|
|||
// If the amount of tics to run is falling behind the amount of available tics,
|
||||
// speed the playsim up a bit to help catch up.
|
||||
int runTics = min<int>(totalTics, availableTics);
|
||||
if (totalTics > 0 && totalTics < availableTics && !singletics)
|
||||
++runTics;
|
||||
if (!singletics && totalTics > 0)
|
||||
{
|
||||
CalculateNetStabilityBuffer(availableTics - totalTics);
|
||||
if (totalTics < availableTics - StabilityBuffer)
|
||||
++runTics;
|
||||
}
|
||||
|
||||
// Test player prediction code in singleplayer
|
||||
// by running the gametic behind the ClientTic
|
||||
|
|
|
|||
|
|
@ -2440,6 +2440,7 @@ OptionMenu NetworkOptions protected
|
|||
StaticText " "
|
||||
StaticText "$NETMNU_HOSTOPTIONS", 1
|
||||
Option "$NETMNU_EXTRATICS", "net_extratic", "OnOff"
|
||||
Option "$NETMNU_BALANCETICS", "net_ticbalance", "OnOff"
|
||||
Option "$NETMNU_LIMITCONVO", "net_limitconversations", "OnOff"
|
||||
Option "$NETMNU_REPEATCOOLDOWN", "net_repeatableactioncooldown", "OnOff"
|
||||
Option "$NETMNU_DISABLEPAUSE", "net_disablepause", "PauseTypes"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue