Skip to content

BehaviorTrees

Behavior trees are logic trees that determine how a entity make decisions.

Tree Nodes

The 3 basic nodes are: - Leaf Node - Sequence Node - Select Node

Leaf Node

This is an action, it contains a function that do or check something. It returns a Success or Failure, aka true or false.

E.g. HasEnemy node: If EnemyClass property exist, returns Success else Failure.

function treePackage.HasEnemy(logic, npcClass: NpcClass)
    local targetHandler: NpcTargetHandler = npcClass:GetComponent("TargetHandler");
    return targetHandler.EnemyClass ~= nil and logic.Success or logic.Failure;
end

FireGun node: Point gun at target and fire primary.

Sequence Node

This is a logic node, it is usually a parent of a bunch of nodes which creates a logic flow chart.

Think of the Sequence Node as a "Until false/failure" flow.

For example: HealSequence node is a sequence node that sequentially process its child nodes until it fails. The IsLowHealth, HasHealItem and UseHealItem are leaf nodes.

HealSequence = {"And"; "IsLowHealth"; "HasHealItem"; "UseHealItem"};
flowchart LR
    A{{HealSequence}}
    A --> B>IsLowHealth]
    B --> C>HasHealItem]
    C --> D>UseHealItem]

If a leaf node fails, the sequence stops, otherwise, it continues to the next leaf node.

Select Node

This is a logic node, it is usually a parent of a bunch of nodes, think of the Select Node as a "Until true/success" flow.

For example: IdleSelect node is a select node that process its child nodes until it returns true. Usually combined with SequenceNode to make a comprehensive logic flow. The HealSelfSequence, HealNearbySequence, IdleTasksSequence, PatrolSequence nodes are sequence nodes.

IdleSelect={"Or"; "HealSelfSequence"; "HealNearbySequence"; "IdleTasksSequence"; "PatrolSequence";};
flowchart LR
    A[[IdleSelect]]
    A --> B{{HealSelfSequence}}
    B --> C{{HealNearbySequence}}
    C --> D{{IdleTasksSequence}}
    D --> E{{PatrolSequence}}

Here it goes one by one from HealSelfSequence and process it to see if it succeeds, if not it continues to HealNearbySequence, IdleTasksSequence and then PatrolSequence


Bandit's HasEnemySequence

A useful example. This sequence node handles what happens when a Bandit has an enemy assigned.

HasEnemySequence={"And"; "HasEnemy"; "FleeSelect"; "FightSelect";};
flowchart LR
    A{{HasEnemySequence}}
    A-->B>HasEnemy]
    B-->C[[FleeSelect]]
    C-->D[[FightSelect]]

Which process as a sequence node (Until false): 1. HasEnemy: If success (true) proceeds to FleeSelect, otherwise sequence stops. 2. FleeSelect: Does the FleeSelect behavior tree until success true, otherwise proceeds to FightSelect. 3. FightSelect: Does the FightSelect behavior tree.

![[BanditDefaultTree.luau]]