p.NetPackedMovementMaxBits

p.NetPackedMovementMaxBits

#Overview

name: p.NetPackedMovementMaxBits

This variable is created as a Console Variable (cvar).

It is referenced in 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of p.NetPackedMovementMaxBits is to set a limit on the number of bits allowed in each packed movement Remote Procedure Call (RPC) in Unreal Engine’s networking system. This setting is primarily used for the character movement component and serves as a protection mechanism against potential bad data that could cause the server to allocate excessive memory.

This setting variable is primarily used in the Unreal Engine’s character movement system, specifically within the CharacterMovementComponent. It’s part of the Engine module and is crucial for network-related operations involving character movement.

The value of this variable is set using an FAutoConsoleVariableRef, which allows it to be modified at runtime through console commands. The default value is set to 4096 bits.

The associated variable NetPackedMovementMaxBits directly interacts with p.NetPackedMovementMaxBits. They share the same value and are used interchangeably in the code.

Developers must be aware that this variable acts as a safeguard against potential network exploits or errors. If the number of bits in a packed movement RPC exceeds this limit, the move will be dropped to prevent potential server issues.

Best practices when using this variable include:

  1. Monitoring its value in production to ensure it’s set appropriately for your game’s needs.
  2. Being cautious when increasing this value, as it directly affects memory allocation on the server.
  3. Using it in conjunction with proper error handling and logging in network-related code.

Regarding the associated variable NetPackedMovementMaxBits:

The purpose of NetPackedMovementMaxBits is identical to p.NetPackedMovementMaxBits. It’s used internally within the CharacterMovementComponent to enforce the bit limit for packed movement RPCs.

This variable is used in several key functions within the CharacterMovementComponent, including NetSerialize, ServerMovePacked_ServerReceive, and MoveResponsePacked_ClientReceive. In these functions, it’s used to validate incoming network data and prevent potential issues with excessive memory allocation.

The value of NetPackedMovementMaxBits is set directly from p.NetPackedMovementMaxBits through the FAutoConsoleVariableRef mechanism.

Developers should be aware that modifying NetPackedMovementMaxBits directly is not recommended. Instead, they should use the console variable p.NetPackedMovementMaxBits to adjust this value if needed.

Best practices for NetPackedMovementMaxBits include:

  1. Treating it as a read-only variable in most scenarios.
  2. Using it for comparisons in network-related functions to ensure data integrity.
  3. Considering its value when designing and optimizing network movement systems for characters.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:116

Scope (from outer to inner):

file
namespace    CharacterMovementCVars

Source code excerpt:

	static int32 NetPackedMovementMaxBits = 4096;
	FAutoConsoleVariableRef CVarNetPackedMovementMaxBits(
		TEXT("p.NetPackedMovementMaxBits"),
		NetPackedMovementMaxBits,
		TEXT("Max number of bits allowed in each packed movement RPC. Used to protect against bad data causing the server to allocate too much memory.\n"),
		ECVF_Default);

	// Listen server smoothing
	static int32 NetEnableListenServerSmoothing = 1;

#Associated Variable and Callsites

This variable is associated with another variable named NetPackedMovementMaxBits. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:114

Scope (from outer to inner):

file
namespace    CharacterMovementCVars

Source code excerpt:

		ECVF_Default);

	static int32 NetPackedMovementMaxBits = 4096;
	FAutoConsoleVariableRef CVarNetPackedMovementMaxBits(
		TEXT("p.NetPackedMovementMaxBits"),
		NetPackedMovementMaxBits,
		TEXT("Max number of bits allowed in each packed movement RPC. Used to protect against bad data causing the server to allocate too much memory.\n"),
		ECVF_Default);

	// Listen server smoothing
	static int32 NetEnableListenServerSmoothing = 1;
	FAutoConsoleVariableRef CVarNetEnableListenServerSmoothing(

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:9313

Scope (from outer to inner):

file
function     bool FCharacterNetworkSerializationPackedBits::NetSerialize

Source code excerpt:

	Ar.SerializeIntPacked(NumBits);

	if (NumBits > static_cast<uint32>(CharacterMovementCVars::NetPackedMovementMaxBits))
	{
		// Protect against bad data that could cause server to allocate way too much memory.
		UE_LOG(LogNetPlayerMovement, Error, TEXT("FCharacterNetworkSerializationPackedBits::NetSerialize: Dropping move due to NumBits (%d) exceeding allowable limit (%d). See NetPackedMovementMaxBits."), NumBits, CharacterMovementCVars::NetPackedMovementMaxBits);
		return false;
	}

	if (Ar.IsLoading())
	{
		DataBits.Init(0, NumBits);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:9475

Scope (from outer to inner):

file
function     void UCharacterMovementComponent::ServerMovePacked_ServerReceive

Source code excerpt:


	const int32 NumBits = PackedBits.DataBits.Num();
	if (NumBits > CharacterMovementCVars::NetPackedMovementMaxBits)
	{
		// Protect against bad data that could cause server to allocate way too much memory.
		UE_LOG(LogNetPlayerMovement, Error, TEXT("ServerMovePacked_ServerReceive (%s): Dropping move due to NumBits (%d) exceeding allowable limit (%d). See NetPackedMovementMaxBits."), *GetNameSafe(GetOwner()), NumBits, CharacterMovementCVars::NetPackedMovementMaxBits);
		return;
	}

	// Reuse bit reader to avoid allocating memory each time.
	ServerMoveBitReader.SetData((uint8*)PackedBits.DataBits.GetData(), NumBits);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:10327

Scope (from outer to inner):

file
function     void UCharacterMovementComponent::MoveResponsePacked_ClientReceive

Source code excerpt:


	const int32 NumBits = PackedBits.DataBits.Num();
	if (!ensureMsgf(NumBits <= CharacterMovementCVars::NetPackedMovementMaxBits, TEXT("MoveResponsePacked_ClientReceive: NumBits (%d) exceeds CharacterMovementCVars::NetPackedMovementMaxBits (%d)"), NumBits, CharacterMovementCVars::NetPackedMovementMaxBits))
	{
		// Protect against bad data that could cause client to allocate way too much memory.
		devCode(UE_LOG(LogNetPlayerMovement, Error, TEXT("MoveResponsePacked_ClientReceive: NumBits (%d) exceeds allowable limit!"), NumBits));
		return;
	}