p.NetCorrectionLifetime
p.NetCorrectionLifetime
#Overview
name: p.NetCorrectionLifetime
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
How long a visualized network correction persists.\nTime in seconds each visualized network correction persists.
It is referenced in 10
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of p.NetCorrectionLifetime is to control the duration of visualized network corrections in Unreal Engine’s character movement and physics replication systems. It is primarily used for debugging and visualization purposes.
This setting variable is utilized by the following Unreal Engine subsystems and modules:
- Character Movement Component
- Physics Replication System
The value of this variable is set using an FAutoConsoleVariableRef in the CharacterMovementCVars namespace. It is initialized with a default value of 4.0 seconds.
The associated variable NetCorrectionLifetime interacts directly with p.NetCorrectionLifetime, sharing the same value. This variable is used throughout the code to determine the lifetime of debug visualizations.
Developers should be aware of the following when using this variable:
- It is only active in non-shipping builds (DEBUG or DEVELOPMENT).
- It affects the duration of debug visualizations for network corrections, which can be useful for identifying and diagnosing network-related movement issues.
- Changing this value will impact the visibility duration of debug drawings in the game world.
Best practices when using this variable include:
- Adjust the value as needed during development to better visualize and debug network corrections.
- Keep in mind that longer durations may clutter the debug visualization, while shorter durations might make it harder to spot issues.
- Use in conjunction with other debugging tools and console variables to get a comprehensive view of character movement and physics replication behavior.
Regarding the associated variable NetCorrectionLifetime:
The purpose of NetCorrectionLifetime is to provide a convenient way to access the p.NetCorrectionLifetime value within the code. It is used in various functions to set the lifetime of debug drawings and visualizations related to network corrections.
This variable is used in multiple locations within the CharacterMovementComponent and PhysicsReplication systems to control the duration of debug visualizations. It directly reflects the value set by p.NetCorrectionLifetime.
Developers should be aware that changes to p.NetCorrectionLifetime will affect all uses of NetCorrectionLifetime throughout the code. When working with this variable, ensure that the visualizations remain useful for debugging purposes without becoming overly intrusive or persistent.
#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:344
Scope (from outer to inner):
file
namespace CharacterMovementCVars
Source code excerpt:
float NetCorrectionLifetime = 4.f;
FAutoConsoleVariableRef CVarNetCorrectionLifetime(
TEXT("p.NetCorrectionLifetime"),
NetCorrectionLifetime,
TEXT("How long a visualized network correction persists.\n")
TEXT("Time in seconds each visualized network correction persists."),
ECVF_Cheat);
#endif // !UE_BUILD_SHIPPING
#Associated Variable and Callsites
This variable is associated with another variable named NetCorrectionLifetime
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:342
Scope (from outer to inner):
file
namespace CharacterMovementCVars
Source code excerpt:
ECVF_Cheat);
float NetCorrectionLifetime = 4.f;
FAutoConsoleVariableRef CVarNetCorrectionLifetime(
TEXT("p.NetCorrectionLifetime"),
NetCorrectionLifetime,
TEXT("How long a visualized network correction persists.\n")
TEXT("Time in seconds each visualized network correction persists."),
ECVF_Cheat);
#endif // !UE_BUILD_SHIPPING
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:10020
Scope (from outer to inner):
file
function void UCharacterMovementComponent::ServerMoveHandleClientError
Source code excerpt:
UE_LOG(LogNetPlayerMovement, Warning, TEXT("*** Server: Error for %s at Time=%.3f is %3.3f LocDiff(%s) ClientLoc(%s) ServerLoc(%s) Base: %s Bone: %s Accel(%s) Velocity(%s)"),
*GetNameSafe(CharacterOwner), ClientTimeStamp, LocDiff.Size(), *LocDiff.ToString(), *ClientLoc.ToString(), *UpdatedComponent->GetComponentLocation().ToString(), *BaseString, *ServerData->PendingAdjustment.NewBaseBoneName.ToString(), *Accel.ToString(), *Velocity.ToString());
const float DebugLifetime = CharacterMovementCVars::NetCorrectionLifetime;
DrawDebugCapsule(GetWorld(), UpdatedComponent->GetComponentLocation(), CharacterOwner->GetSimpleCollisionHalfHeight(), CharacterOwner->GetSimpleCollisionRadius(), FQuat::Identity, FColor(100, 255, 100), false, DebugLifetime);
DrawDebugCapsule(GetWorld(), ClientLoc , CharacterOwner->GetSimpleCollisionHalfHeight(), CharacterOwner->GetSimpleCollisionRadius(), FQuat::Identity, FColor(255, 100, 100), false, DebugLifetime);
}
#endif
ServerData->LastUpdateTime = GetWorld()->TimeSeconds;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/CharacterMovementComponent.cpp:10896
Scope (from outer to inner):
file
function void UCharacterMovementComponent::OnClientCorrectionReceived
Source code excerpt:
UE_LOG(LogNetPlayerMovement, Warning, TEXT("*** Client: Error for %s at Time=%.3f is %3.3f LocDiff(%s) ClientLoc(%s) ServerLoc(%s) NewBase: %s NewBone: %s ClientVel(%s) ServerVel(%s) SavedMoves %d"),
*GetNameSafe(CharacterOwner), TimeStamp, LocDiff.Size(), *LocDiff.ToString(), *ClientLocAtCorrectedMove.ToString(), *NewLocation.ToString(), *NewBaseString, *NewBaseBoneName.ToString(), *Velocity.ToString(), *NewVelocity.ToString(), ClientData.SavedMoves.Num());
const float DebugLifetime = CharacterMovementCVars::NetCorrectionLifetime;
if (!LocDiff.IsNearlyZero())
{
// When server corrects us to a new location, draw red at location where client thought they were, green where the server corrected us to
DrawDebugCapsule(GetWorld(), ClientLocAtCorrectedMove, CharacterOwner->GetSimpleCollisionHalfHeight(), CharacterOwner->GetSimpleCollisionRadius(), FQuat::Identity, FColor(255, 100, 100), false, DebugLifetime);
DrawDebugCapsule(GetWorld(), NewLocation, CharacterOwner->GetSimpleCollisionHalfHeight(), CharacterOwner->GetSimpleCollisionRadius(), FQuat::Identity, FColor(100, 255, 100), false, DebugLifetime);
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsReplication.cpp:21
Scope (from outer to inner):
file
namespace CharacterMovementCVars
Source code excerpt:
{
extern int32 NetShowCorrections;
extern float NetCorrectionLifetime;
int32 SkipPhysicsReplication = 0;
static FAutoConsoleVariableRef CVarSkipPhysicsReplication(TEXT("p.SkipPhysicsReplication"), SkipPhysicsReplication, TEXT(""));
float NetPingExtrapolation = -1.0f;
static FAutoConsoleVariableRef CVarNetPingExtrapolation(TEXT("p.NetPingExtrapolation"), NetPingExtrapolation, TEXT(""));
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsReplication.cpp:724
Scope (from outer to inner):
file
function bool FPhysicsReplication::ApplyRigidBodyState
Source code excerpt:
{
FColor Color = FColor::White;
DrawDebugDirectionalArrow(OwningWorld, CurrentState.Position, TargetPos, 5.0f, Color, true, CharacterMovementCVars::NetCorrectionLifetime, 0, 1.5f);
DrawDebugFloatHistory(*OwningWorld, PhysicsTarget.ErrorHistory, CurrentState.Position + FVector(0.0f, 0.0f, 100.0f), FVector2D(100.0f, 50.0f), FColor::White, false, 0, -1);
}
}
#endif
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsReplication.cpp:989
Scope (from outer to inner):
file
function void FPhysicsReplicationAsync::UpdateAsyncTarget
Source code excerpt:
{
const FVector Offset = FVector(0.0f, 0.0f, 50.0f);
Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(Input.TargetState.Position + Offset, FVector(15.0f, 15.0f, 15.0f), Input.TargetState.Quaternion, FColor::MakeRandomSeededColor(Input.ServerFrame), false, CharacterMovementCVars::NetCorrectionLifetime, 0, 1.0f);
}
#endif
// Cache the position we received this target at, Predictive Interpolation will alter the target state but use this as the source position for reconciliation.
Target->PrevPosTarget = Input.TargetState.Position;
Target->PrevRotTarget = Input.TargetState.Quaternion;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsReplication.cpp:1463
Scope (from outer to inner):
file
function bool FPhysicsReplicationAsync::PredictiveInterpolation
Source code excerpt:
const FVector StartPos = Target.TargetState.Position + Offset;
const int32 SizeMultiplier = FMath::Clamp(Target.TickCount, -4, 30);
Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(StartPos, FVector(5.0f + SizeMultiplier * 0.75f, 5.0f + SizeMultiplier * 0.75f, 5.0f + SizeMultiplier * 0.75f), Target.TargetState.Quaternion, FColor::MakeRandomSeededColor(Target.ServerFrame), false, CharacterMovementCVars::NetCorrectionLifetime, 0, 1.0f);
}
#endif
const bool bIsSleeping = Handle->IsSleeping();
const bool bCanSimulate = Handle->IsDynamic() || bIsSleeping;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsReplication.cpp:1817
Scope (from outer to inner):
file
function bool FPhysicsReplicationAsync::ResimulationReplication
Source code excerpt:
const FColor DebugColor = FLinearColor::LerpUsingHSV(FLinearColor::Green, FLinearColor::Red, ColorLerp).ToFColor(false);
Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(Target.TargetState.Position, FVector(BoxSize, BoxSize, BoxSize), Target.TargetState.Quaternion, FColor::Orange, true, CharacterMovementCVars::NetCorrectionLifetime, 0, 1.0f);
Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(PastState.GetX(), FVector(6, 6, 6), PastState.GetR(), DebugColor, true, CharacterMovementCVars::NetCorrectionLifetime, 0, 1.0f);
Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow(PastState.GetX(), Target.TargetState.Position, 5.0f, FColor::MakeRandomSeededColor(LocalFrame), true, CharacterMovementCVars::NetCorrectionLifetime, 0, 0.5f);
}
#endif
if (LocalFrame > RewindData->GetBlockedResimFrame())
{
if (ShouldTriggerResim && Target.TickCount == 0)
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsEngine/PhysicsReplication.cpp:1874
Scope (from outer to inner):
file
function bool FPhysicsReplicationAsync::ResimulationReplication
Source code excerpt:
if (PhysicsReplicationCVars::ResimulationCVars::bDrawDebug)
{
Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow(Handle->GetX(), CorrectedX, 5.0f, FColor::MakeRandomSeededColor(LocalFrame), true, CharacterMovementCVars::NetCorrectionLifetime, 0, 0.5f);
}
#endif
// Apply correction to position and rotation
RigidsSolver->GetEvolution()->ApplyParticleTransformCorrection(Handle, CorrectedX, CorrectedR, PhysicsReplicationCVars::ResimulationCVars::bRuntimeCorrectConnectedBodies);
}