AbilitySystem.PredictionKey.DepChainBehavior

AbilitySystem.PredictionKey.DepChainBehavior

#Overview

name: AbilitySystem.PredictionKey.DepChainBehavior

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

It is referenced in 3 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of AbilitySystem.PredictionKey.DepChainBehavior is to control how dependency key chains are handled in the Gameplay Ability System’s prediction mechanism. This setting variable is crucial for managing the behavior of prediction keys in networked gameplay scenarios.

This setting variable is primarily used by the Gameplay Abilities module, which is a part of the Unreal Engine’s Gameplay Ability System. It’s specifically utilized within the prediction and networking components of this system.

The value of this variable is set through a console variable (CVar) named “AbilitySystem.PredictionKey.DepChainBehavior”. It’s initialized with a default value of 0 but can be changed at runtime.

The associated variable CVarDependentChainBehaviorValue directly interacts with AbilitySystem.PredictionKey.DepChainBehavior. They share the same value, with CVarDependentChainBehaviorValue being the actual integer storage for the CVar.

Developers must be aware that this variable uses a bitmask to control different aspects of the dependency chain behavior:

The best practices when using this variable include:

  1. Understanding the implications of each bitmask value on the prediction system.
  2. Consider using the value 3 (0x1 | 0x2) for the most logically correct behavior, as mentioned in the comments.
  3. Be cautious when changing this value, as it can significantly affect how prediction keys are processed in networked gameplay.

Regarding the associated variable CVarDependentChainBehaviorValue:

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Private/GameplayPrediction.cpp:29

Scope (from outer to inner):

file
namespace    UE::AbilitySystem::Private

Source code excerpt:

	// 0 (no bitmask) is legacy behavior.  Logically, (0x1 | 0x2) = 3 is the correct value. The long-term fix will be a value of 3.
	int32 CVarDependentChainBehaviorValue = 0;
	FAutoConsoleVariableRef CVarDependentChainBehavior(TEXT("AbilitySystem.PredictionKey.DepChainBehavior"), CVarDependentChainBehaviorValue,
		TEXT("How do we handle dependency key chains? Bitmask: 0 = Old Accept/Rejected Implies Newer Accepted/Rejected. 0x1 = Newer Accepted also implies Older Accepted. 0x2 = Old Accepted Does NOT imply Newer Accepted"));

	// Prior to UE5.4.2, we used to allow Server Initiated Replication Keys to be sent to the client as 'acknowledged' but that hardly makes sense.
	// Unfortunately, it also causes key hash collisions since there is limited space based on the key value.
	int32 CVarReplicateServerKeysAsAcknowledgedValue = 0;
	FAutoConsoleVariableRef CVarReplicateServerKeysAsAcknowledged(TEXT("AbilitySystem.PredictionKey.RepServerKeysAsAcknowledged"), CVarReplicateServerKeysAsAcknowledgedValue,

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Private/GameplayPrediction.cpp:28

Scope (from outer to inner):

file
namespace    UE::AbilitySystem::Private

Source code excerpt:

	// How should we deal with dependent keys (in a chain)?  Prior to UE5.5, old keys implied new keys.  We introduced some new functionality (explained in the help text).
	// 0 (no bitmask) is legacy behavior.  Logically, (0x1 | 0x2) = 3 is the correct value. The long-term fix will be a value of 3.
	int32 CVarDependentChainBehaviorValue = 0;
	FAutoConsoleVariableRef CVarDependentChainBehavior(TEXT("AbilitySystem.PredictionKey.DepChainBehavior"), CVarDependentChainBehaviorValue,
		TEXT("How do we handle dependency key chains? Bitmask: 0 = Old Accept/Rejected Implies Newer Accepted/Rejected. 0x1 = Newer Accepted also implies Older Accepted. 0x2 = Old Accepted Does NOT imply Newer Accepted"));

	// Prior to UE5.4.2, we used to allow Server Initiated Replication Keys to be sent to the client as 'acknowledged' but that hardly makes sense.
	// Unfortunately, it also causes key hash collisions since there is limited space based on the key value.
	int32 CVarReplicateServerKeysAsAcknowledgedValue = 0;
	FAutoConsoleVariableRef CVarReplicateServerKeysAsAcknowledged(TEXT("AbilitySystem.PredictionKey.RepServerKeysAsAcknowledged"), CVarReplicateServerKeysAsAcknowledgedValue,

#Loc: <Workspace>/Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Private/GameplayPrediction.cpp:343

Scope (from outer to inner):

file
function     void FPredictionKeyDelegates::AddDependency

Source code excerpt:

	//	This allows a FPredictionKey to _not_ be sent to the server, yet be acknowledged as long as a newer dependent key was sent & acknowledged.
	//	This is logically correct and newly introduced behavior.
	if ((UE::AbilitySystem::Private::CVarDependentChainBehaviorValue & 1) != 0)
	{
		NewCaughtUpDelegate(ThisKey).BindStatic(&FPredictionKeyDelegates::CatchUpTo, DependsOn);
	}

	// 2. If we receive an earlier key in the chain of dependencies, then the later ones should also be acknowledged. 
	//	This is unintuitive, but it's possible to create FPredictionKeys that are never sent to the server.
	//	This is the case with FScopedServerAbilityRPCBatcher.  It sends only the BaseKey but needs to notify dependents.
	//	This isn't logically correct, so we're introducing a way to disable this legacy functionality once Engine fixes are finished.
	if ((UE::AbilitySystem::Private::CVarDependentChainBehaviorValue & 2) == 0)
	{
		NewCaughtUpDelegate(DependsOn).BindStatic(&FPredictionKeyDelegates::CatchUpTo, ThisKey);
	}
	
}