MaxMoveDeltaTime
MaxMoveDeltaTime
#Overview
name: MaxMoveDeltaTime
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 11
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of MaxMoveDeltaTime is to set the maximum time delta for character movement updates in Unreal Engine’s networking system. It is primarily used in the character movement component to control the frequency and granularity of movement updates sent between the client and server.
This setting variable is mainly used by the Character Movement Component and the Game Network Manager subsystems of Unreal Engine. It’s a crucial part of the networking and movement replication system.
The value of this variable is typically set in the AGameNetworkManager class, which is a global configuration. However, it can be modified per actor if needed, as seen in the FNetworkPredictionData_Client_Character and FNetworkPredictionData_Server_Character classes.
MaxMoveDeltaTime interacts with several other variables, including:
- ClientNetSendMoveDeltaTime
- MaxClientSmoothingDeltaTime
- MAXCLIENTUPDATEINTERVAL
Developers must be aware that:
- MaxMoveDeltaTime should be less than or equal to MAXCLIENTUPDATEINTERVAL to prevent server interference with large move deltas.
- It affects both client and server-side prediction and smoothing of character movement.
- It’s used to clamp the delta time for movement updates, which can impact the precision and frequency of movement replication.
Best practices when using this variable include:
- Ensure it’s set to a value that balances network performance with movement accuracy.
- Consider the relationship between MaxMoveDeltaTime and other related variables like MaxClientSmoothingDeltaTime.
- Monitor its impact on network traffic and adjust as needed based on your game’s specific requirements.
- Be cautious when modifying it per actor, as it could lead to inconsistencies in movement replication across different characters.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseGame.ini:31, section: [/Script/Engine.GameNetworkManager]
- INI Section:
/Script/Engine.GameNetworkManager
- Raw value:
0.125f
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/GameFramework/CharacterMovementComponent.h:3123
Scope (from outer to inner):
file
class class FNetworkPredictionData_Client_Character : public FNetworkPredictionData_Client, protected FNoncopyable
Source code excerpt:
/**
* Max delta time for a given move, in real seconds
* Based off of AGameNetworkManager::MaxMoveDeltaTime config setting, but can be modified per actor
* if needed.
* This value is mirrored in FNetworkPredictionData_Server, which is what server logic runs off of.
* Client needs to know this in order to not send move deltas that are going to get clamped anyway (meaning
* they'll be rejected/corrected).
* Note: This was previously named MaxResponseTime, but has been renamed to reflect what it does more accurately
*/
float MaxMoveDeltaTime;
/** Values used for visualization and debugging of simulated net corrections */
FVector LastSmoothLocation;
FVector LastServerLocation;
float SimulatedDebugDrawTime;
/** Array of replay samples that we use to interpolate between to get smooth location/rotation/velocity/ect */
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/GameFramework/CharacterMovementComponent.h:3192
Scope (from outer to inner):
file
class class FNetworkPredictionData_Server_Character : public FNetworkPredictionData_Server, protected FNoncopyable
Source code excerpt:
/**
* Max delta time for a given move, in real seconds
* Based off of AGameNetworkManager::MaxMoveDeltaTime config setting, but can be modified per actor
* if needed.
* Note: This was previously named MaxResponseTime, but has been renamed to reflect what it does more accurately
*/
float MaxMoveDeltaTime;
/** Force client update on the next ServerMoveHandleClientError() call. */
uint32 bForceClientUpdate:1;
/** Accumulated timestamp difference between autonomous client and server for tracking long-term trends */
float LifetimeRawTimeDiscrepancy;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/GameFramework/GameNetworkManager.h:141
Scope (from outer to inner):
file
class class AGameNetworkManager : public AInfo
Source code excerpt:
float ServerForcedUpdateHitchCooldown;
/** MaxMoveDeltaTime is the default maximum time delta of CharacterMovement ServerMoves. Should be less than or equal to MAXCLIENTUPDATEINTERVAL, otherwise server will interfere by forcing position updates. */
UPROPERTY(GlobalConfig)
float MaxMoveDeltaTime;
/** MaxClientSmoothingDeltaTime is the maximum delta time between server updates that clients are allowed to smooth between for position interpolation. This was previously (2 * MaxMoveDeltaTime). */
UPROPERTY(GlobalConfig)
float MaxClientSmoothingDeltaTime;
/**
* ClientNetSendMoveDeltaTime is the default minimum time delta of CharacterMovement client moves to the server. When updates occur more frequently, they may be combined to save bandwidth.
* This value is not used when player count is over ClientNetSendMoveThrottleOverPlayerCount or player net speed is <= ClientNetSendMoveThrottleAtNetSpeed (see ClientNetSendMoveDeltaTimeThrottled).
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:8521
Scope (from outer to inner):
file
function float FNetworkPredictionData_Client_Character::UpdateTimeStampAndDeltaTime
Source code excerpt:
}
return FMath::Min(ClientDeltaTime, MaxMoveDeltaTime * CharacterOwner.GetActorTimeDilation());
}
void UCharacterMovementComponent::ReplicateMoveToServer(float DeltaTime, const FVector& NewAcceleration)
{
SCOPE_CYCLE_COUNTER(STAT_CharacterMovementReplicateMoveToServer);
check(CharacterOwner != NULL);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:8585
Scope (from outer to inner):
file
function void UCharacterMovementComponent::ReplicateMoveToServer
Source code excerpt:
if (const FSavedMove_Character* PendingMove = ClientData->PendingMove.Get())
{
if (PendingMove->CanCombineWith(NewMovePtr, CharacterOwner, ClientData->MaxMoveDeltaTime * CharacterOwner->GetActorTimeDilation(*MyWorld)))
{
SCOPE_CYCLE_COUNTER(STAT_CharacterMovementCombineNetMove);
// Only combine and move back to the start location if we don't move back in to a spot that would make us collide with something new.
const FVector OldStartLocation = PendingMove->GetRevertedLocation();
const bool bAttachedToObject = (NewMovePtr->StartAttachParent != nullptr);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:11822
Scope (from outer to inner):
file
function FNetworkPredictionData_Client_Character::FNetworkPredictionData_Client_Character
Source code excerpt:
, SmoothNetUpdateTime(0.f)
, SmoothNetUpdateRotationTime(0.f)
, MaxMoveDeltaTime(0.125f)
, LastSmoothLocation(FVector::ZeroVector)
, LastServerLocation(FVector::ZeroVector)
, SimulatedDebugDrawTime(0.0f)
, DebugForcedPacketLossTimerStart(0.0f)
{
MaxSmoothNetUpdateDist = ClientMovement.NetworkMaxSmoothUpdateDistance;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:11838
Scope (from outer to inner):
file
function FNetworkPredictionData_Client_Character::FNetworkPredictionData_Client_Character
Source code excerpt:
if (GameNetworkManager)
{
MaxMoveDeltaTime = GameNetworkManager->MaxMoveDeltaTime;
MaxClientSmoothingDeltaTime = FMath::Max(GameNetworkManager->MaxClientSmoothingDeltaTime, MaxMoveDeltaTime * 2.0f);
}
if (ClientMovement.GetOwnerRole() == ROLE_AutonomousProxy)
{
SavedMoves.Reserve(MaxSavedMoveCount);
FreeMoves.Reserve(MaxFreeMoveCount);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:12007
Scope (from outer to inner):
file
function FNetworkPredictionData_Server_Character::FNetworkPredictionData_Server_Character
Source code excerpt:
, LastUpdateTime(0.f)
, ServerTimeStampLastServerMove(0.f)
, MaxMoveDeltaTime(0.125f)
, bForceClientUpdate(false)
, LifetimeRawTimeDiscrepancy(0.f)
, TimeDiscrepancy(0.f)
, bResolvingTimeDiscrepancy(false)
, TimeDiscrepancyResolutionMoveDeltaOverride(0.f)
, TimeDiscrepancyAccumulatedClientDeltasSinceLastServerTick(0.f)
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:12019
Scope (from outer to inner):
file
function FNetworkPredictionData_Server_Character::FNetworkPredictionData_Server_Character
Source code excerpt:
if (GameNetworkManager)
{
MaxMoveDeltaTime = GameNetworkManager->MaxMoveDeltaTime;
if (GameNetworkManager->MaxMoveDeltaTime > GameNetworkManager->MAXCLIENTUPDATEINTERVAL)
{
UE_LOG(LogNetPlayerMovement, Warning, TEXT("GameNetworkManager::MaxMoveDeltaTime (%f) is greater than GameNetworkManager::MAXCLIENTUPDATEINTERVAL (%f)! Server will interfere with move deltas that large!"), GameNetworkManager->MaxMoveDeltaTime, GameNetworkManager->MAXCLIENTUPDATEINTERVAL);
}
}
const UWorld* World = ServerMovement.GetWorld();
if (World)
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:12056
Scope (from outer to inner):
file
function float FNetworkPredictionData_Server_Character::GetBaseServerMoveDeltaTime
Source code excerpt:
float FNetworkPredictionData_Server_Character::GetBaseServerMoveDeltaTime(float ClientTimeStamp, float ActorTimeDilation) const
{
const float DeltaTime = FMath::Min(MaxMoveDeltaTime * ActorTimeDilation, ClientTimeStamp - CurrentClientTimeStamp);
return DeltaTime;
}
FSavedMove_Character::FSavedMove_Character()
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameNetworkManager.cpp:31
Scope (from outer to inner):
file
function AGameNetworkManager::AGameNetworkManager
Source code excerpt:
ServerForcedUpdateHitchThreshold = 0.150f;
ServerForcedUpdateHitchCooldown = 0.100f;
MaxMoveDeltaTime = 0.125f;
MaxClientSmoothingDeltaTime = 0.50f;
ClientNetSendMoveDeltaTime = 0.0166f;
ClientNetSendMoveDeltaTimeThrottled = 0.0222f;
ClientNetSendMoveDeltaTimeStationary = 0.0166f;
ClientNetSendMoveThrottleAtNetSpeed = 10000;
ClientNetSendMoveThrottleOverPlayerCount = 10;