Our team has been encountering a crash when trying to change levels in PIE using Seamless Travel. We’re hitting an assert in UActorDescContainerInstance::UnregisterDelegates() followed immediately by a crash.
Here’s what I’ve been able to figure out from debugging so far:
1) Container is nullptr because UActorDescContainerInstance::Uninitialize() is being called twice for the same instance
2) We’ve tried adding a null check to just bypass the second uninitialize call. This makes us hit a different assert later on in World Partition code and results in an infinite load:
3) This behavior seems to be related to a LevelInstance using “Level Behavior”=“Standalone”. Switching “Level Behavior” to “Embedded” makes this crash disappear but this isn’t an option for us as we had to set this particular level instance to “Standalone” to work around some other issues.
4) The issue only occurs when running with “Net Mode”=“Play as Client”. I assume this is due to there being two instances of the levels for both the Client and Server. The issue does not occur with “Play Standalone”
Would appreciate any guidance on how to fix or work around this issue. Thanks in advance!
I think I found a fix for this problem. CL31765603 is moving the place where UActorDescContainerInstance::Uninitialize is called and it should prevent the double call you are seeing.
Thanks for reaching out. I tried integrating the change and it does seem to fix the crash but similar to the local fix I’d tried, it results in still hitting that assert in WorldPartition::BeingDestroy(). It seems like there’s an underlying issue here at a higher level than just UActorDescContainerInstance.
Here’s the call stack for that assert if that can help:
> UnrealEditor-Engine.dll!UWorldPartition::BeginDestroy() Line 1564 C++ UnrealEditor-CoreUObject.dll!UObject::ConditionalBeginDestroy() Line 1214 C++ UnrealEditor-CoreUObject.dll!UnhashUnreachableObjects(bool bUseTimeLimit, double TimeLimit) Line 5949 C++ UnrealEditor-CoreUObject.dll!UE::GC::PostCollectGarbageImpl<1>(EObjectFlags KeepFlags) Line 5575 C++ UnrealEditor-CoreUObject.dll!UE::GC::FReachabilityAnalysisState::PerformReachabilityAnalysisAndConditionallyPurgeGarbage(bool bReachabilityUsingTimeLimit) Line 5771 C++ [Inline Frame] UnrealEditor-CoreUObject.dll!UE::GC::CollectGarbageInternal(EObjectFlags) Line 5342 C++ UnrealEditor-CoreUObject.dll!CollectGarbage(EObjectFlags KeepFlags, bool bPerformFullPurge) Line 6007 C++ UnrealEditor-Engine.dll!FSeamlessTravelHandler::Tick() Line 7982 C++ UnrealEditor-Engine.dll!UEngine::TickWorldTravel(FWorldContext & Context, float DeltaSeconds) Line 14816 C++ UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1989 C++ UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 550 C++ UnrealEditor.exe!FEngineLoop::Tick() Line 5921 C++ [Inline Frame] UnrealEditor.exe!EngineTick() Line 61 C++ UnrealEditor.exe!GuardedMain(const wchar_t * CmdLine) Line 180 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]
We are reproducing the same assert in the Main stream. We are actively trying to understand what it happening. It does appear to be a bug as the Client’s version of the Level Instance is getting GC’ed before the Client’s world is meant to be destroyed. It also looks like running past the assert is resulting in memory corruption that set the allocator in an infinite loop.
We have found a workaround for the problem. You have to turn on the Network Emulation. This will change the order of some operations and will prevent the assert from being hit.
[Image Removed]
We are still debugging to find a fix when Network Emulation is not being used.
I tried out this workaround on my side and can confirm it fixes the issue for me as well. We’re looking into whether we can turn this on for the project globally, but at the very least we can use this workaround to get people who have been running into this unstuck.
Update after doing some additional tests, we’re ok applying these changes on our side. We were previously using network emulation but on client only. We switched to “Everyone” and reduced the latency values so the total latency would be similar and the crash went away.