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:

Developers must be aware that:

  1. MaxMoveDeltaTime should be less than or equal to MAXCLIENTUPDATEINTERVAL to prevent server interference with large move deltas.
  2. It affects both client and server-side prediction and smoothing of character movement.
  3. 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:

  1. Ensure it’s set to a value that balances network performance with movement accuracy.
  2. Consider the relationship between MaxMoveDeltaTime and other related variables like MaxClientSmoothingDeltaTime.
  3. Monitor its impact on network traffic and adjust as needed based on your game’s specific requirements.
  4. 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]

#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;