A high UWorld::Tick DeltaSeconds (i.e. GameThread hitch) results in a high UNetDriver::TickFlush DeltaSeconds. This DeltaSeconds can high (many seconds) if the hitch is long. This value then affects NetDriver's scheduling of an actor's next update via
ActorInfo->NextUpdateTime = World->TimeSeconds + UpdateDelayRandomStream.FRand() * ServerTickTime + NextUpdateDelta;
where the value for ServerTickTime == DeltaSeconds.
This issue was reported by a user when showing a loading screen configured to let the engine tick, but did not reset the tick measurement. That is an issue originating in MoviePlayer and will be ticketed separately. However, since server hitches can occur for any other reason I believe this logic for calculating NextUpdateTime should be reconsidered not to use measured DeltaSeconds, but either use expected DeltaSeconds from the target frame rate or cap the value off at a maximum.
void UMyIpNetDriver::TickFlush(float DeltaSeconds) { if (DeltaSeconds > 5.0f) { UE_LOG(LogTemp, Error, TEXT("AAA | Long NetDriver tick delta seconds: %.2f"), DeltaSeconds); } Super::TickFlush(DeltaSeconds); if (UWorld* MyWorld = GetWorld()) { const float WorldTime = MyWorld->GetTimeSeconds(); for (const TSharedPtr<FNetworkObjectInfo>& ObjectInfo : GetNetworkObjectList().GetActiveObjects()) { FNetworkObjectInfo* ActorInfo = ObjectInfo.Get(); if (ActorInfo->NextUpdateTime > WorldTime + 5.0f) { UE_LOG(LogTemp, Error, TEXT("AAA | Actor '%s' NextUpdateTime = %.2f seconds into the future!"), *ActorInfo->Actor->GetPathName(), ActorInfo->NextUpdateTime - WorldTime); } } } }
[/Script/Engine.Engine] !NetDriverDefinitions=ClearArray +NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/NetDriverTick53R.MyIpNetDriver",DriverClassNameFallback="OnlineSubsystem.IpNetDriver")
void AMyPlayerController::ManuallyTriggerHitch()
{
UE_LOG(LogTemp, Display, TEXT("Triggering 10 second hitch!"));
FPlatformProcess::Sleep(10.f);
}
Observe: After the hitch, NetDriver has scheduled actor's next update far into the future. This is because measured DeltaSeconds passed into TickFlush directly becomes the high 'ServerTickTIme' value in ServerReplicateActors_BuildConsiderList:
ActorInfo->NextUpdateTime = World->TimeSeconds + UpdateDelayRandomStream.FRand() * ServerTickTime + NextUpdateDelta; // ServerTickTime will be same as hitch time
Expected: A server GameThread hitch should not cause actor's next net update to be scheduled far into the future. It should be capped somehow to expected DeltaSeconds.
UnrealEditor-Engine.dll!UNetDriver::ServerReplicateActors_BuildConsiderList(TArray<FNetworkObjectInfo *,TSizedDefaultAllocator<32>> & OutConsiderList, const float ServerTickTime) Line 4340 C++
UnrealEditor-Engine.dll!UNetDriver::ServerReplicateActors(float DeltaSeconds) Line 5278 C++
UnrealEditor-Engine.dll!UNetDriver::TickFlush(float DeltaSeconds) Line 955 C++
UnrealEditor-NetDriverTick53R.dll!UMyIpNetDriver::TickFlush(float DeltaSeconds) Line 9 C++
UnrealEditor-Engine.dll!UNetDriver::InternalTickFlush(float DeltaSeconds) Line 1603 C++
[Inline Frame] UnrealEditor-Engine.dll!Invoke(void(UNetDriver::*)(float)) Line 66 C++
[Inline Frame] UnrealEditor-Engine.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(UNetDriver::*)(float) &) Line 311 C++
UnrealEditor-Engine.dll!TBaseUObjectMethodDelegateInstance<0,UNetDriver,void __cdecl(float),FDefaultDelegateUserPolicy>::ExecuteIfSafe(float <Params_0>) Line 667 C++
[Inline Frame] UnrealEditor-Engine.dll!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast(float) Line 254 C++
UnrealEditor-Engine.dll!TMulticastDelegate<void __cdecl(float),FDefaultDelegateUserPolicy>::Broadcast(float <Params_0>) Line 956 C++
> UnrealEditor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1675 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1924 C++
UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 531 C++
UnrealEditor.exe!FEngineLoop::Tick() Line 5825 C++
[Inline Frame] UnrealEditor.exe!EngineTick() Line 61 C++
UnrealEditor.exe!GuardedMain(const wchar_t * CmdLine) Line 188 C++
UnrealEditor.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 247 C++
UnrealEditor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 298 C++
[External Code]
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-207161 in the post.
0 |
Component | UE - Networking |
---|---|
Affects Versions | 5.1, 5.2, 5.3 |
Target Fix | 5.6 |
Created | Feb 16, 2024 |
---|---|
Updated | Oct 25, 2024 |