Chaos physics crashes while trying to execute AsyncPhysicsTick over an actor that was unloaded by Word Partition

Hi!

I’m using World Partition, and when I travel far enough, my game / editor crashes when Chaos is trying to Tick on actor unloaded from memory.
Removing the actor solved the issue.

This looks like a bug. But I heard no one else complaining about this.

I’m on 5.1.1

There are painful things I could try, but I thought about asking for help here first.

Any help / ideas?
Thanks!

Call stack:

> UnrealEditor-Engine.dll!FAsyncPhysicsTickCallback::OnPreSimulate_Internal() Line 125 C++
[Inline Frame] UnrealEditor-Chaos.dll!Chaos::ISimCallbackObject::PreSimulate_Internal() Line 65 C++
UnrealEditor-Chaos.dll!Chaos::FPhysicsSolverBase::ApplyCallbacks_Internal() Line 462 C++
UnrealEditor-Chaos.dll!Chaos::FPhysicsSolverFrozenGTPreSimCallbacks::GTPreSimCallbacks() Line 118 C++
[Inline Frame] UnrealEditor-Chaos.dll!Chaos::FPhysicsSolverFrozenGTPreSimCallbacks::DoTask(ENamedThreads::Type) Line 106 C++
UnrealEditor-Chaos.dll!TGraphTaskChaos::FPhysicsSolverFrozenGTPreSimCallbacks::ExecuteTask(TArray<FBaseGraphTask *,TSizedDefaultAllocator<32>> & NewTasks, ENamedThreads::Type CurrentThread, bool bDeleteOnCompletion) Line 1348 C++
[Inline Frame] UnrealEditor-Core.dll!FBaseGraphTask::Execute(TArray<FBaseGraphTask *,TSizedDefaultAllocator<32>> & CurrentThread, ENamedThreads::Type) Line 950 C++
UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread(int QueueIndex, bool bAllowStall) Line 760 C++
UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksUntilQuit(int QueueIndex) Line 649 C++
[Inline Frame] UnrealEditor-Core.dll!FTaskGraphCompatibilityImplementation::ProcessThreadUntilRequestReturn(ENamedThreads::Type CurrentThread) Line 2149 C++
UnrealEditor-Core.dll!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete(const TArray<TRefCountPtr,TSizedInlineAllocator<4,32,TSizedDefaultAllocator<32>>> & Tasks, ENamedThreads::Type CurrentThreadIfKnown) Line 2203 C++
UnrealEditor-Engine.dll!FTickTaskSequencer::ReleaseTickGroup(ETickingGroup WorldTickGroup, bool bBlockTillComplete) Line 565 C++
UnrealEditor-Engine.dll!FTickTaskManager::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 1592 C++
UnrealEditor-Engine.dll!UWorld::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 794 C++
UnrealEditor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1559 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1890 C++
UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 517 C++
UnrealEditor-Win64-DebugGame.exe!FEngineLoop::Tick() Line 5369 C++
[Inline Frame] UnrealEditor-Win64-DebugGame.exe!EngineTick() Line 66 C++
UnrealEditor-Win64-DebugGame.exe!GuardedMain(const wchar_t * CmdLine) Line 202 C++
UnrealEditor-Win64-DebugGame.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 233 C++
UnrealEditor-Win64-DebugGame.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 282 C++


The issue does not happen in any other level.

So there’s something wrong with mine.
I tried removing EVERYTHING (lanscape, folliage, level blueprint logic, etc) from my level and this still happens. It happens with a trivial actor with just a PrintString node in the AsyncPhysicsTick.

But my level it’s a big openworld so I really can’t just start over.

The actor actually get’s unloaded fine, but if I go farther away, then the issue happens (like it gets re-added for some reason to the list of physic actors).

I’ll investigate into what it takes to migrate everything into a new level. But if anyone has a better idea about what could be wrong or a workaround / fix (maybe there’s a level cleanup I can do or… ).

After 20+ hours, I think it’s a bug with async actors with world streaming enabled. Happens in 5.1 and 5.2.
I just reported the bug to Epic.
JIC someone else suffers the same, I’ll post the issue if they create it.

1 Like

Is no one using level streaming with async physics? I find weird that no one else reported this or even replied.
It will be of great help to me if I hear from someone that either uses it and works, or it doesn’t and has a different setup (maybe implemented their own async loop, etc)

BTW no news about the bug I reported :frowning:

I am seeing the exact same thing now, I brought my streaming distance way in and boom!
Do you have a link to the bug?

I turned off Async Physics so I could get some work done. edit: That didn’t work, it still trys to tick any actor that is an AsyncPhysicsTickActors.

I set these actors to Is Spatialy Loaded = False, there was a fix in 5.1.1 that stopped these actors from crashing upon destruction, but it looks like that fix ins’t helping you out in this case!? :sob:

I have a similar issue. I am using UE5.2 and World Composition. When I have the flag “Async Physics Tick Enabled” = true the game crashes 100% of the time as soon a level is unloaded containing such an actor.

Just reading this. I don’t. I reported the issue, but I didn’t get any feedback so I suspect the just didn’t raised it as a bug. It seems critical, I reported it very neatly and it can be reproduced in 30 seconds.

yeap, that’s the bug. It just doesn’t work.

spatially loaded = false does prevent the bug (iirc) but then that’s the same as not having the world partitioned.

Sadly, this is still happening in 5.3.

JIC someone from Epic can see this → Steps to reproduce (takes 30 secs):

  1. Create new prject (blueprint it’s fine)
  2. Make sure world streaming is enabled
  3. Create new blueprint x
  4. Add asynch physics tick with a print "X" node
  5. Run console command gc.CollectGarbageEveryFrame 1
  6. Add x actor to the level
  7. Run Simulate while looking at the actor (print X should appear on screen)
  8. Zoom out → Crash
  9. The bug does not happen if async physics tick or world streaming are disabled.

Again if someone knows a good workaround for this it would be much appreciated. Maybe reimplementing async physics using some kind to timing logic over the regular Event Tick?

I’m still puzzled about this not being a huge issue. I figured there would be plenty of big / open world projects with async physics that should be impacted by this problem.

JIC Someone else runs into this, I made it work. This is my - humble -fix:
You can either implement this in a base BP + C++ actor (AsyncPhysicsWorldPartitionedActor.h or similar) and or just add three nodes to your existing actors and two methods on a C++ function library.
First add this two functions in C++. I added them in a library but you can add them in your base actor (Just replace “actor” by “this”):

CPP_LosBlueprintFunctionLibrary.h:

UFUNCTION(BlueprintCallable, Category = "AsyncPhysics", meta = (DisplayName = "UnregisterAsyncPhysicsActor"))
static void UnregisterAsyncPhysicsActor(AActor* actor);

UFUNCTION(BlueprintCallable, Category = "AsyncPhysics", meta = (DisplayName = "RegisterAsyncPhysicsActor"))
static void RegisterAsyncPhysicsActor(AActor* actor);

CPP_LosBlueprintFunctionLibrary.cpp

void UCPP_LosBlueprintFunctionLibrary::UnregisterAsyncPhysicsActor(AActor* actor)
{
    if (FPhysScene_Chaos* Scene = static_cast<FPhysScene_Chaos*>(actor->GetWorld()->GetPhysicsScene()))
    {
        Scene->UnregisterAsyncPhysicsTickActor(actor);
    }
}

void UCPP_LosBlueprintFunctionLibrary::RegisterAsyncPhysicsActor(AActor* actor)
{
    if (FPhysScene_Chaos* Scene = static_cast<FPhysScene_Chaos*>(actor->GetWorld()->GetPhysicsScene()))
    {
        Scene->RegisterAsyncPhysicsTickActor(actor);
    }
}

Then just add this to your async physics actor begin and end nodes, and you should be fine.

2 Likes

Hey there. Just making sure that if you still need this, check the solution at the end!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.