# AI and Behavior Trees

AI setup uses `execute_python` for Blueprint assets and `write_file` + `live_coding_compile` for C++ classes.

## Asset Creation (BT_, BB_)

To create Behavior Tree and Blackboard assets via Python:

1. Use `query_ue_api` to discover the correct Factory class for `BehaviorTree` and `BlackboardData`
2. Use `dir()` on the factory and asset tools objects to find creation and save methods
3. Always check if the asset already exists before creating
4. Save the asset after creation

The same discovery workflow applies to linking a Blackboard to a Behavior Tree and setting AIController on a character Blueprint — use `query_ue_api` and `dir()` to find the correct properties and methods at runtime.

## C++ AIController setup
```cpp
// AMyAIController.h
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "MyAIController.generated.h"

UCLASS()
class AMyAIController : public AAIController
{
    GENERATED_BODY()

public:
    UPROPERTY(EditDefaultsOnly, Category = "AI")
    UBehaviorTree* BehaviorTreeAsset;

protected:
    virtual void OnPossess(APawn* InPawn) override;
};

// AMyAIController.cpp
#include "MyAIController.h"
#include "BehaviorTree/BehaviorTree.h"
#include "BehaviorTree/BlackboardComponent.h"

void AMyAIController::OnPossess(APawn* InPawn)
{
    Super::OnPossess(InPawn);
    if (BehaviorTreeAsset)
    {
        RunBehaviorTree(BehaviorTreeAsset);
    }
}
```

## C++ BTTaskNode (custom task)
```cpp
// UBTTask_FindPatrolPoint.h
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/BTTaskNode.h"
#include "BTTask_FindPatrolPoint.generated.h"

UCLASS()
class UBTTask_FindPatrolPoint : public UBTTaskNode
{
    GENERATED_BODY()

public:
    UBTTask_FindPatrolPoint();
    virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;

    UPROPERTY(EditAnywhere, Category = "Blackboard")
    FBlackboardKeySelector PatrolPointKey;
};

// UBTTask_FindPatrolPoint.cpp
#include "BTTask_FindPatrolPoint.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "AIController.h"
#include "NavigationSystem.h"

UBTTask_FindPatrolPoint::UBTTask_FindPatrolPoint()
{
    NodeName = "Find Patrol Point";
}

EBTNodeResult::Type UBTTask_FindPatrolPoint::ExecuteTask(
    UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
    AAIController* AICon = OwnerComp.GetAIOwner();
    if (!AICon || !AICon->GetPawn()) return EBTNodeResult::Failed;

    FNavLocation Result;
    UNavigationSystemV1* NavSys = UNavigationSystemV1::GetCurrent(GetWorld());
    if (NavSys && NavSys->GetRandomReachablePointInRadius(
        AICon->GetPawn()->GetActorLocation(), 1500.f, Result))
    {
        OwnerComp.GetBlackboardComponent()->SetValueAsVector(
            PatrolPointKey.SelectedKeyName, Result.Location);
        return EBTNodeResult::Succeeded;
    }
    return EBTNodeResult::Failed;
}
```

## Common built-in BT nodes

Discover available nodes: `query_ue_api('BTTask')`, `query_ue_api('BTDecorator')`, `query_ue_api('BTService')`.

- **BTTask_MoveTo** -- move AI to blackboard location/actor
- **BTTask_Wait** -- pause for duration
- **BTTask_PlayAnimation** -- play anim montage
- **BTDecorator_Blackboard** -- check blackboard value condition
- **BTDecorator_IsAtLocation** -- check if near target
- **BTService_DefaultFocus** -- keep looking at target

## EQS (Environment Query System)
EQS finds locations/actors based on scored tests:
- Create EQS Query asset in editor or via Python
- Run from BT with `BTTask_RunEQSQuery`
- Common generators: `PointsInGrid`, `PointsOnCircle`, `ActorsOfClass`
- Common tests: `Distance`, `Trace`, `Dot`, `PathLength`

## StateTree (modern alternative)
StateTree is UE5's newer AI framework -- data-driven state machines:
- More visual, less code than Behavior Trees
- Better for complex state logic with conditions and transitions
- Uses `UStateTreeComponent` on the AI-controlled actor
- Consider StateTree for new projects; BT is still valid for existing workflows

## Setting AIController on a character Blueprint

To assign an AIController class and configure auto-possession on a character Blueprint via Python:

1. Use `query_ue_api` to discover how to load Blueprint assets and access their generated class and CDO
2. Use `dir()` on the CDO to find `ai_controller_class` and `auto_possess_ai` properties
3. Compile and save after changes

## Build.cs dependencies
```csharp
PublicDependencyModuleNames.AddRange(new string[] {
    "AIModule",
    "GameplayTasks",
    "NavigationSystem"
});
```

## Naming conventions
- BT_ prefix for Behavior Trees: BT_EnemyAI, BT_GuardPatrol
- BB_ prefix for Blackboards: BB_EnemyAI, BB_Guard
- BTTask_ prefix for custom tasks: BTTask_FindPatrolPoint
- BTDecorator_ prefix: BTDecorator_HasAmmo
- BTService_ prefix: BTService_UpdateTarget

## Related modules
- For StateTree (modern alternative) -> see **statetree** knowledge module for full C++ tasks, conditions, transitions
- For GAS integration with AI -> see **gas** knowledge module

## CRITICAL RULES
- ALWAYS add "AIModule" and "GameplayTasks" to Build.cs
- ALWAYS call Super::OnPossess in AIController
- ALWAYS link Blackboard to BehaviorTree before running
- RunBehaviorTree() must be called after possession (in OnPossess, not constructor)
- BTTaskNode::ExecuteTask must return Succeeded, Failed, or InProgress
- For InProgress tasks, call FinishLatentTask() when complete
