Download

AI - Dynamic Behavior Tree Problem

Hello

I’m using slightly modified task RunBehaviorDynamic, which does take BehaviorTreeAsset from custom variable on AI Controller instead of being specified on task itself.
Unfortunately sometimes depending on a setup of subtrees, game crashes.
I can’t make exact repro, with some setups of subtrees it never/very rarely throws an error, while in others it does every few mins.

Behavior Tree Setup Overview

This is overview of main behavior tree which have dynamic subtree slots for different behavior types

Example subtree 1 that gets injected into SUBREE GAMEPLAY task

Example subtree 2 that gets injected into SUBREE GAMEPLAY task

Crash usualy happens when dynamic behavior tree is switched to another one.
Flow of changing dynamic behavior looks like that:

  1. Null out ActiveSubtree bb key to interrupt currently running dynamic subtree
  2. Put new behavior tree in custom variable (PendingActiveSubtree)
  3. Put value of PendingActiveSubtree to bb key ActiveSubtree
  4. Change in bb key ActiveSubtree forces new behavior to be activated though decorator observing it
Crash Callstack

UE4Editor_AIModule!UBTNode::GetNodeMemory<FBTCompositeMemory>() [D:\Build++UE4\Sync\Engine\Source\Runtime\AIModule\Classes\BehaviorTree\BTNode.h:291]
UE4Editor_AIModule!UBTCompositeNode::FindChildToExecute() [D:\Build++UE4\Sync\Engine\Source\Runtime\AIModule\Private\BehaviorTree\BTCompositeNode.cpp:38]
UE4Editor_AIModule!UBehaviorTreeComponent::ProcessExecutionRequest() [D:\Build++UE4\Sync\Engine\Source\Runtime\AIModule\Private\BehaviorTree\BehaviorTreeComponent.cpp:1648]
UE4Editor_AIModule!UBehaviorTreeComponent::TickComponent() [D:\Build++UE4\Sync\Engine\Source\Runtime\AIModule\Private\BehaviorTree\BehaviorTreeComponent.cpp:1358]
UE4Editor_Engine!FActorComponentTickFunction::ExecuteTickHelper<<lambda_865f1c8123559010106a353ada1cfb7d> >() [D:\Build++UE4\Sync\Engine\Source\Runtime\Engine\Classes\GameFramework\Actor.h:3573]
UE4Editor_Engine!FActorComponentTickFunction::ExecuteTick() [D:\Build++UE4\Sync\Engine\Source\Runtime\Engine\Private\Components\ActorComponent.cpp:1014]
UE4Editor_Engine!FTickFunctionTask::DoTask() [D:\Build++UE4\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:284]
UE4Editor_Engine!TGraphTask<FTickFunctionTask>::ExecuteTask() [D:\Build++UE4\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:886]
UE4Editor_Core!FNamedTaskThread::ProcessTasksNamedThread() [D:\Build++UE4\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:709]
UE4Editor_Core!FNamedTaskThread::ProcessTasksUntilIdle() [D:\Build++UE4\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:612]
UE4Editor_Core!FTaskGraphImplementation::ProcessThreadUntilIdle() [D:\Build++UE4\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:1464]
UE4Editor_Engine!FTickTaskSequencer::ReleaseTickGroup() [D:\Build++UE4\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:581]
UE4Editor_Engine!FTickTaskManager::RunTickGroup() [D:\Build++UE4\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:1578]
UE4Editor_Engine!UWorld::RunTickGroup() [D:\Build++UE4\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:782]
UE4Editor_Engine!UWorld::Tick() [D:\Build++UE4\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:1474]
UE4Editor_UnrealEd!UEditorEngine::Tick() [D:\Build++UE4\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1720]
UE4Editor_UnrealEd!UUnrealEdEngine::Tick() [D:\Build++UE4\Sync\Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp:426]
UE4Editor!FEngineLoop::Tick() [D:\Build++UE4\Sync\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:4836]
UE4Editor!GuardedMain() [D:\Build++UE4\Sync\Engine\Source\Runtime\Launch\Private\Launch.cpp:169]
UE4Editor!GuardedMainWrapper() [D:\Build++UE4\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:137]
UE4Editor!WinMain() [D:\Build++UE4\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:268]
UE4Editor!__scrt_common_main_seh() [d:\agent_work\5\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32

Crash In Code

Caused by trying to get element from InstanceStack while it became empty

Logs from Visual Logger in moment of crash

If anyone has an idea what could be causing it, let me know.
Thanks!

Edit: Stopping Behavior Tree in 3rd image from Visual Logger is caused by AI getting stunned,
and most likely this is source of the problem, when AI agent changes dynamic subtree and StopLogic is called on its BehaviorTreeComponent.
Because when I disabled stopping logic at all, then I couldn’t generate the crash.
Yet I didn’t find exact repro steps for this and still can’t figure out why would it crash in such circumstances.