AI Systems
BehaviorTree and Blackboard verbs: bt-list, bt-add-node, bt-add-decorator, bb-add-key, and more.
Part of the BlueprintAIAssistant AI Reference.
Verbs for reading and editing BehaviorTree assets and their associated BlackboardData. BehaviorTrees define AI decision logic as composites (Selector, Sequence), tasks (MoveTo, Wait), decorators, and services. BlackboardData assets hold the key definitions that BT nodes read and write at runtime.
All verbs return JSON. On success: "success": true. On failure:
"success": false with "error", "errorCode", "suggestion", and
"details" fields.
Global optional flags: -compile, -save, -timing.
Table of Contents#
BehaviorTree (5 verbs)
- bt-list: List the node tree structure
- bt-add-node: Add a task or composite node
- bt-add-decorator: Add a decorator to a node
- bt-add-service: Add a service to a node
- bt-set-property: Set a property on a BT node
Blackboard (3 verbs) 6. bb-list-keys: List all keys in a BlackboardData asset 7. bb-add-key: Add a key to a BlackboardData asset 8. bb-remove-key: Remove a key from a BlackboardData asset
BehaviorTree verbs#
bt-list#
List the node tree structure of a BehaviorTree asset. Returns composites, tasks, decorators, and services in a hierarchical tree.
Category: Read
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BehaviorTree asset path (e.g., /Game/AI/BT_EnemyMain) |
Examples:
# List the full tree structure
-verb=bt-list -asset=/Game/AI/BT_EnemyMain
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-list","args":{"asset":"/Game/AI/BT_EnemyMain"}}'
Output:
{
"success": true,
"asset": "/Game/AI/BT_EnemyMain",
"root": {
"index": 0,
"type": "Selector",
"decorators": [],
"services": [],
"children": [
{
"index": 1,
"type": "Sequence",
"decorators": [
{"type": "BTDecorator_Blackboard", "key": "TargetActor"}
],
"services": [
{"type": "BTService_BlackboardBase"}
],
"children": [
{"index": 2, "type": "BTTask_MoveTo"},
{"index": 3, "type": "BTTask_Wait"}
]
}
]
}
}
bt-add-node#
Add a task or composite node to a BehaviorTree.
Category: Write
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BehaviorTree asset path |
-type= |
Yes | Node type. Composites: Selector, Sequence, SimpleParallel. Tasks: MoveTo, Wait, RunBehavior, RunEQS, or any custom class name (e.g., BTTask_MyCustomTask) |
-parent= |
No | Parent composite index (defaults to 0 = root). Use indices from bt-list output |
-index= |
No | Insertion index within the parent's children. Omit to append at the end |
Examples:
# Add a Sequence under the root Selector
-verb=bt-add-node -asset=/Game/AI/BT_EnemyMain -type=Sequence -parent=0
# Add a MoveTo task under composite index 1
-verb=bt-add-node -asset=/Game/AI/BT_EnemyMain -type=MoveTo -parent=1 -save
# Add a Wait task at a specific child position
-verb=bt-add-node -asset=/Game/AI/BT_EnemyMain -type=Wait -parent=1 -index=0 -save
# Add a custom task class
-verb=bt-add-node -asset=/Game/AI/BT_EnemyMain -type=BTTask_FindCover -parent=1 -save
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-add-node","args":{"asset":"/Game/AI/BT_EnemyMain","type":"Sequence","parent":"0"}}'
Output:
{
"success": true,
"action": "created",
"node": {
"index": 4,
"type": "BTComposite_Sequence",
"parentIndex": 0
}
}
bt-add-decorator#
Add a decorator to a BehaviorTree node. Decorators are conditions or modifiers attached to a composite's child slot.
Category: Write
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BehaviorTree asset path |
-node= |
Yes | Composite index to decorate (from bt-list output) |
-childIndex= |
Yes | Which child slot to decorate (0-based) |
-type= |
Yes | Decorator type: Blackboard, ConeCheck, Cooldown, ForceSuccess, Loop, or any custom class name (e.g., BTDecorator_MyCondition) |
Examples:
# Add a Blackboard decorator checking a key
-verb=bt-add-decorator -asset=/Game/AI/BT_EnemyMain -node=0 -childIndex=0 -type=Blackboard -save
# Add a Cooldown decorator
-verb=bt-add-decorator -asset=/Game/AI/BT_EnemyMain -node=1 -childIndex=1 -type=Cooldown -save
# Add a custom decorator
-verb=bt-add-decorator -asset=/Game/AI/BT_EnemyMain -node=0 -childIndex=0 -type=BTDecorator_IsInCombat -save
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-add-decorator","args":{"asset":"/Game/AI/BT_EnemyMain","node":"0","childIndex":"0","type":"Blackboard"}}'
Output:
{
"success": true,
"action": "created",
"decorator": {
"type": "BTDecorator_Blackboard",
"nodeIndex": 0,
"childIndex": 0
}
}
bt-add-service#
Add a service to a BehaviorTree composite node. Services run periodically while their composite is active (e.g., updating the blackboard with perception data).
Category: Write
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BehaviorTree asset path |
-node= |
Yes | Composite index to attach the service to |
-type= |
Yes | Service type: BlackboardBase, DefaultFocus, or any custom class name (e.g., BTService_UpdateCombatInfo) |
Examples:
# Add a BlackboardBase service to the root
-verb=bt-add-service -asset=/Game/AI/BT_EnemyMain -node=0 -type=BlackboardBase -save
# Add a DefaultFocus service
-verb=bt-add-service -asset=/Game/AI/BT_EnemyMain -node=1 -type=DefaultFocus -save
# Add a custom service
-verb=bt-add-service -asset=/Game/AI/BT_EnemyMain -node=0 -type=BTService_UpdateThreat -save
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-add-service","args":{"asset":"/Game/AI/BT_EnemyMain","node":"0","type":"BlackboardBase"}}'
Output:
{
"success": true,
"action": "created",
"service": {
"type": "BTService_BlackboardBase",
"nodeIndex": 0
}
}
bt-set-property#
Set a property on a BehaviorTree node via UE reflection. Supports dot notation
for nested properties (e.g., BlackboardKey.SelectedKeyName).
Category: Write
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BehaviorTree asset path |
-node= |
Yes | Composite index or root |
-property= |
Yes | Property name. Supports dot notation for nested properties |
-value= |
Yes | Value as string (parsed by UE property import) |
Examples:
# Set the WaitTime on a Wait task
-verb=bt-set-property -asset=/Game/AI/BT_EnemyMain -node=3 -property=WaitTime -value=2.5 -save
# Set the Blackboard key on a decorator (dot notation)
-verb=bt-set-property -asset=/Game/AI/BT_EnemyMain -node=1 -property=BlackboardKey.SelectedKeyName -value=TargetActor -save
# Set AcceptableRadius on a MoveTo task
-verb=bt-set-property -asset=/Game/AI/BT_EnemyMain -node=2 -property=AcceptableRadius -value=150.0 -save
# Set a boolean property
-verb=bt-set-property -asset=/Game/AI/BT_EnemyMain -node=2 -property=bAllowStrafe -value=true -save
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-set-property","args":{"asset":"/Game/AI/BT_EnemyMain","node":"3","property":"WaitTime","value":"2.5"}}'
Output:
{
"success": true,
"node": 3,
"property": "WaitTime",
"oldValue": "5.0",
"newValue": "2.5"
}
Blackboard verbs#
bb-list-keys#
List all keys defined in a BlackboardData asset, including their types and any base class constraints.
Category: Read
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BlackboardData asset path (e.g., /Game/AI/BB_EnemyData) |
Examples:
-verb=bb-list-keys -asset=/Game/AI/BB_EnemyData
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bb-list-keys","args":{"asset":"/Game/AI/BB_EnemyData"}}'
Output:
{
"success": true,
"asset": "/Game/AI/BB_EnemyData",
"keys": [
{"name": "TargetActor", "type": "Object", "baseClass": "Actor"},
{"name": "TargetLocation", "type": "Vector"},
{"name": "HasLineOfSight", "type": "Bool"},
{"name": "DistanceToTarget", "type": "Float"}
]
}
bb-add-key#
Add a key to a BlackboardData asset. Idempotent: if a key with the same name already exists, the verb succeeds without modifying it.
Category: Write
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BlackboardData asset path |
-name= |
Yes | Key name |
-type= |
Yes | Key type: Bool, Float, Int, String, Name, Object, Class, Enum, Vector, Rotator |
-baseClass= |
No | Base class constraint for Object key type (e.g., Actor, Pawn). Ignored for non-Object types |
Examples:
# Add a simple boolean key
-verb=bb-add-key -asset=/Game/AI/BB_EnemyData -name=IsAggressive -type=Bool -save
# Add an object key constrained to Actor
-verb=bb-add-key -asset=/Game/AI/BB_EnemyData -name=PatrolTarget -type=Object -baseClass=Actor -save
# Add a vector key for a location
-verb=bb-add-key -asset=/Game/AI/BB_EnemyData -name=LastKnownLocation -type=Vector -save
# Add a float key
-verb=bb-add-key -asset=/Game/AI/BB_EnemyData -name=AggroRadius -type=Float -save
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bb-add-key","args":{"asset":"/Game/AI/BB_EnemyData","name":"PatrolTarget","type":"Object","baseClass":"Actor"}}'
Output:
{
"success": true,
"action": "created",
"key": {
"name": "PatrolTarget",
"type": "Object",
"baseClass": "Actor"
}
}
Output (already exists):
{
"success": true,
"action": "already_exists",
"key": {
"name": "PatrolTarget",
"type": "Object",
"baseClass": "Actor"
}
}
bb-remove-key#
Remove a key from a BlackboardData asset. Idempotent: if the key does not exist, the verb succeeds without error.
Category: Write
Args:
| Arg | Required | Description |
|---|---|---|
-asset= |
Yes | BlackboardData asset path |
-name= |
Yes | Key name to remove |
Examples:
-verb=bb-remove-key -asset=/Game/AI/BB_EnemyData -name=OldUnusedKey -save
HTTP:
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bb-remove-key","args":{"asset":"/Game/AI/BB_EnemyData","name":"OldUnusedKey"}}'
Output:
{
"success": true,
"action": "removed",
"key": "OldUnusedKey"
}
Common AI Workflows#
Workflow 1: Set up a new AI from scratch#
Create a Blackboard with keys, then build a BehaviorTree that uses them.
Step 1: Create the Blackboard keys (batch):
curl -X POST http://localhost:7850/baa/v1/batch \
-H "Content-Type: application/json" \
-d '{
"defaultAsset": "/Game/AI/BB_PatrolGuard",
"operations": [
{"verb": "bb-add-key", "args": {"name": "TargetActor", "type": "Object", "baseClass": "Actor"}},
{"verb": "bb-add-key", "args": {"name": "PatrolLocation", "type": "Vector"}},
{"verb": "bb-add-key", "args": {"name": "HasLineOfSight", "type": "Bool"}},
{"verb": "bb-add-key", "args": {"name": "DistanceToTarget", "type": "Float"}}
],
"save": true
}'
Step 2: Build the BehaviorTree structure (batch):
curl -X POST http://localhost:7850/baa/v1/batch \
-H "Content-Type: application/json" \
-d '{
"defaultAsset": "/Game/AI/BT_PatrolGuard",
"operations": [
{"verb": "bt-add-node", "args": {"type": "Sequence", "parent": "0"}},
{"verb": "bt-add-node", "args": {"type": "MoveTo", "parent": "$1"}},
{"verb": "bt-add-node", "args": {"type": "Wait", "parent": "$1"}},
{"verb": "bt-set-property", "args": {"node": "$3", "property": "WaitTime", "value": "3.0"}},
{"verb": "bt-add-decorator", "args": {"node": "0", "childIndex": "0", "type": "Blackboard"}},
{"verb": "bt-set-property", "args": {"node": "$5", "property": "BlackboardKey.SelectedKeyName", "value": "HasLineOfSight"}}
],
"save": true
}'
Workflow 2: Inspect and modify an existing BehaviorTree#
Read the tree, find the node you need, then change its properties.
# Step 1: List the tree to find node indices
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-list","args":{"asset":"/Game/AI/BT_EnemyMain"}}'
# Step 2: Change the MoveTo acceptable radius (suppose it is at index 2)
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-set-property","args":{"asset":"/Game/AI/BT_EnemyMain","node":"2","property":"AcceptableRadius","value":"200.0"}}'
# Step 3: Add a Cooldown decorator to prevent re-entry
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-add-decorator","args":{"asset":"/Game/AI/BT_EnemyMain","node":"0","childIndex":"0","type":"Cooldown"}}'
# Step 4: Save
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"save","args":{"asset":"/Game/AI/BT_EnemyMain"}}'
Workflow 3: Add a new Blackboard key and wire it into the tree#
# Add a new key to the Blackboard
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bb-add-key","args":{"asset":"/Game/AI/BB_EnemyData","name":"CoverLocation","type":"Vector"}}'
# Add a service that updates the key (custom service class)
curl -X POST http://localhost:7850/baa/v1/execute \
-H "Content-Type: application/json" \
-d '{"verb":"bt-add-service","args":{"asset":"/Game/AI/BT_EnemyMain","node":"0","type":"BTService_FindCover"}}'
# Add a Blackboard decorator that checks the key
curl -X POST http://localhost:7850/baa/v1/batch \
-H "Content-Type: application/json" \
-d '{
"defaultAsset": "/Game/AI/BT_EnemyMain",
"operations": [
{"verb": "bt-add-node", "args": {"type": "Sequence", "parent": "0"}},
{"verb": "bt-add-decorator", "args": {"node": "0", "childIndex": "$1", "type": "Blackboard"}},
{"verb": "bt-add-node", "args": {"type": "MoveTo", "parent": "$1"}}
],
"save": true
}'
Workflow 4: Commandlet invocation (no HTTP server)#
When the editor and BAAServer are not running, use the one-shot commandlet:
# List a BehaviorTree
"C:\Unreal\UE571Source\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" \
"C:\Unreal\ProjectLeyline\CombatDemo\CombatDemo.uproject" \
-run=BlueprintAIAssistant \
-verb=bt-list \
-asset=/Game/AI/BT_EnemyMain \
-nullrhi -nosplash -nosound -unattended
# Add a Blackboard key and save
"C:\Unreal\UE571Source\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" \
"C:\Unreal\ProjectLeyline\CombatDemo\CombatDemo.uproject" \
-run=BlueprintAIAssistant \
-verb=bb-add-key \
-asset=/Game/AI/BB_EnemyData \
-name=AlertLevel -type=Float \
-save \
-nullrhi -nosplash -nosound -unattended
Error Codes#
Errors relevant to BehaviorTree and Blackboard verbs:
| Code | Description |
|---|---|
| ASSET_NOT_FOUND | Asset path does not exist or could not be loaded |
| INVALID_ARGS | Missing or malformed required arguments |
| NODE_NOT_FOUND | Node index not found in the BehaviorTree |
| PROPERTY_NOT_FOUND | Property name not found on the BT node class |
| SAVE_ERROR | Package save to disk failed |
All error responses include:
"error": human-readable message"errorCode": one of the codes above"suggestion": actionable fix hint"details": structured data when applicable
Tips#
- Always
bt-listfirst. Before modifying a BehaviorTree, list its structure to get current node indices. Indices can shift when nodes are added or removed. - Use batch for multi-step operations. Each commandlet launch takes 30-60 seconds. Batching avoids repeated startup costs.
- Dot notation for nested properties. Many BT node properties are nested
structs (e.g.,
BlackboardKey.SelectedKeyName). Use dot notation to reach them. - Custom classes must be loaded. When using a custom class name (e.g.,
BTTask_FindCover), the module containing that class must be loaded by the engine. If the class is in a game module, it loads automatically. If it is in a plugin, ensure the plugin is enabled. - Blackboard keys are idempotent.
bb-add-keyandbb-remove-keyare safe to call multiple times. They succeed silently if the key already exists or is already absent.