net.PartialBunchReliableThreshold
net.PartialBunchReliableThreshold
#Overview
name: net.PartialBunchReliableThreshold
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
If a bunch is broken up into this many partial bunches are more, we will send it reliable even if the original bunch was not reliable. Partial bunches are atonmic and must all make it over to be used
It is referenced in 4
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of net.PartialBunchReliableThreshold is to control the reliability of network packet transmission in Unreal Engine’s networking system. It determines when to switch from unreliable to reliable transmission for partial bunches of data.
This setting variable is primarily used by the networking subsystem of Unreal Engine, specifically in the data channel and replication modules.
The value of this variable is set through the console variable system. It’s initialized with a default value of 8 and can be modified at runtime.
GCVarNetPartialBunchReliableThreshold is the associated variable that directly interacts with net.PartialBunchReliableThreshold. They share the same value and are used interchangeably in the code.
Developers must be aware that:
- This variable affects network performance and reliability.
- Setting it too low might unnecessarily increase network traffic and overhead.
- Setting it too high might result in data loss if partial bunches fail to transmit.
Best practices when using this variable include:
- Carefully consider the trade-off between reliability and performance when adjusting this value.
- Monitor network performance and adjust as needed based on your game’s specific requirements.
- Test thoroughly with different values to find the optimal setting for your game.
Regarding GCVarNetPartialBunchReliableThreshold: This is the internal C++ variable that stores the value of net.PartialBunchReliableThreshold. It’s used in the actual logic of the networking code to determine when to switch to reliable transmission. The same considerations and best practices apply to this variable as they do to net.PartialBunchReliableThreshold, as they are essentially the same thing, just accessed in different ways (console variable vs. C++ variable).
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DataChannel.cpp:85
Scope: file
Source code excerpt:
int32 GCVarNetPartialBunchReliableThreshold = 8;
FAutoConsoleVariableRef CVarNetPartialBunchReliableThreshold(
TEXT("net.PartialBunchReliableThreshold"),
GCVarNetPartialBunchReliableThreshold,
TEXT("If a bunch is broken up into this many partial bunches are more, we will send it reliable even if the original bunch was not reliable. Partial bunches are atonmic and must all make it over to be used"));
int32 GSkipReplicatorForDestructionInfos = 1;
FAutoConsoleVariableRef CVarNetSkipReplicatorForDestructionInfos(
TEXT("net.SkipReplicatorForDestructionInfos"),
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/Net/RepLayout.h:1142
Scope: file
Source code excerpt:
* alongside with other sent properties.
*
* When "net.PartialBunchReliableThreshold" is non-zero and property data bunches are split into partial bunches above
* the threshold, we will not generate a history item. Instead, we will rely on the reliable bunch framework for resends
* and replication of the Object will be completely paused until the property bunches are acknowledged.
* However, this will not affect other history items since they are still unreliable.
*/
class FRepLayout : public FGCObject, public TSharedFromThis<FRepLayout>
{
private:
friend struct FRepStateStaticBuffer;
friend class UPackageMapClient;
friend class FNetSerializeCB;
friend struct FCustomDeltaPropertyIterator;
FRepLayout();
public:
virtual ~FRepLayout();
/** Creates a new FRepLayout for the given class. */
ENGINE_API static TSharedPtr<FRepLayout> CreateFromClass(UClass* InObjectClass, const UNetConnection* ServerConnection = nullptr, const ECreateRepLayoutFlags Flags = ECreateRepLayoutFlags::None);
/** Creates a new FRepLayout for the given struct. */
ENGINE_API static TSharedPtr<FRepLayout> CreateFromStruct(UStruct * InStruct, const UNetConnection* ServerConnection = nullptr, const ECreateRepLayoutFlags Flags = ECreateRepLayoutFlags::None);
/** Creates a new FRepLayout for the given function. */
static TSharedPtr<FRepLayout> CreateFromFunction(UFunction* InFunction, const UNetConnection* ServerConnection = nullptr, const ECreateRepLayoutFlags Flags = ECreateRepLayoutFlags::None);
/**
* Creates and initialize a new Shadow Buffer.
*
* Shadow Data / Shadow States are used to cache property data so that the Object's state can be
* compared between frames to see if any properties have changed. They are also used on clients
* to keep track of RepNotify state.
*
* This includes:
* - Allocating memory for all Properties in the class.
* - Constructing instances of each Property.
* - Copying the values of the Properties from given object.
*
* @param Source Memory buffer storing object property data.
*/
FRepStateStaticBuffer CreateShadowBuffer(const FConstRepObjectDataBuffer Source) const;
/**
* Creates and initializes a new FReplicationChangelistMgr.
*
* @param InObject The Object that is being managed.
* @param CreateFlags Flags modifying how the manager is created.
*/
TSharedPtr<FReplicationChangelistMgr> CreateReplicationChangelistMgr(const UObject* InObject, const ECreateReplicationChangelistMgrFlags CreateFlags) const;
/**
* Creates and initializes a new FRepState.
*
* This includes:
* - Initializing the ShadowData.
* - Associating and validating the appropriate ChangedPropertyTracker.
* - Building initial ConditionMap.
*
* @param RepState The RepState to initialize.
* @param Class The class of the object represented by the input memory.
* @param Src Memory buffer storing object property data.
* @param InRepChangedPropertyTracker The PropertyTracker we want to associate with the RepState.
*
* @return A new RepState.
* Note, maybe a a FRepStateBase or FRepStateSending based on parameters.
*/
TUniquePtr<FRepState> CreateRepState(
const FConstRepObjectDataBuffer Source,
TSharedPtr<FRepChangedPropertyTracker>& InRepChangedPropertyTracker,
ECreateRepStateFlags Flags) const;
UE_DEPRECATED(5.1, "No longer used, trackers are initialized by the replication subsystem.")
void InitChangedTracker(FRepChangedPropertyTracker * ChangedTracker) const;
/**
* Writes out any changed properties for an Object into the given data buffer,
* and does book keeping for the RepState of the object.
*
* Note, this does not compare properties or send them on the wire, it's only used
* to serialize properties.
*
* @param RepState RepState for the object.
* This is expected to be valid.
* @param RepChangelistState RepChangelistState for the object.
* @param Data Pointer to memory where property data is stored.
* @param ObjectClass Class of the object.
* @param Writer Writer used to store / write out the replicated properties.
* @param RepFlags Flags used for replication.
*/
bool ReplicateProperties(
FSendingRepState* RESTRICT RepState,
#Associated Variable and Callsites
This variable is associated with another variable named GCVarNetPartialBunchReliableThreshold
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DataChannel.cpp:83
Scope: file
Source code excerpt:
TEXT("Time threshold for processing queued bunches during instant replays. If it takes longer than this in a single frame, wait until the next frame to continue processing queued bunches. For unlimited time, set to 0."));
int32 GCVarNetPartialBunchReliableThreshold = 8;
FAutoConsoleVariableRef CVarNetPartialBunchReliableThreshold(
TEXT("net.PartialBunchReliableThreshold"),
GCVarNetPartialBunchReliableThreshold,
TEXT("If a bunch is broken up into this many partial bunches are more, we will send it reliable even if the original bunch was not reliable. Partial bunches are atonmic and must all make it over to be used"));
int32 GSkipReplicatorForDestructionInfos = 1;
FAutoConsoleVariableRef CVarNetSkipReplicatorForDestructionInfos(
TEXT("net.SkipReplicatorForDestructionInfos"),
GSkipReplicatorForDestructionInfos,
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DataChannel.cpp:1326
Scope (from outer to inner):
file
function FPacketIdRange UChannel::SendBunch
Source code excerpt:
const bool bOverflowsReliable = (NumOutRec + OutgoingBunches.Num() >= RELIABLE_BUFFER + Bunch->bClose);
if ((GCVarNetPartialBunchReliableThreshold > 0) && (OutgoingBunches.Num() >= GCVarNetPartialBunchReliableThreshold) && !Connection->IsInternalAck())
{
if (!bOverflowsReliable)
{
UE_LOG(LogNetPartialBunch, Log, TEXT(" OutgoingBunches.Num (%d) exceeds reliable threashold (%d). Making bunches reliable. Property replication will be paused on this channel until these are ACK'd."), OutgoingBunches.Num(), GCVarNetPartialBunchReliableThreshold);
Bunch->bReliable = true;
bPausedUntilReliableACK = true;
}
else
{
// The threshold was hit, but making these reliable would overflow the reliable buffer. This is a problem: there is just too much data.
UE_LOG(LogNetPartialBunch, Warning, TEXT(" OutgoingBunches.Num (%d) exceeds reliable threashold (%d) but this would overflow the reliable buffer! Consider sending less stuff. Channel: %s"), OutgoingBunches.Num(), GCVarNetPartialBunchReliableThreshold, *Describe());
}
}
if (Bunch->bReliable && bOverflowsReliable)
{
UE_LOG(LogNetPartialBunch, Warning, TEXT("SendBunch: Reliable partial bunch overflows reliable buffer! %s"), *Describe() );