ai_controller 
Vars | |
| able_to_run | TRUE if we're able to run, FALSE if we aren't Should not be set manually, override get_able_to_run() instead Make sure you hook update_able_to_run() in setup_able_to_run() to whatever parameters changing that you added Otherwise we will not pay attention to them changing |
|---|---|
| active_execution_index | Execution index of the leaf node currently returning BT_RUNNING. 0 = nothing active. |
| ai_movement | Reference to the movement datum we use. Is a type on initialize but becomes a ref afterwards. |
| ai_status | Current status of AI (OFF/ON) |
| ai_traits | Bitfield of traits for this AI to handle extra behavior |
| behavior_nodes | The root of our tree, which will contain |
| behavior_tree_json | Repo-relative path to the .bt.json source file for this controller (e.g. "code/datums/ai/basic_mobs/cleanbot.bt.json"). initialize_behavior_tree() derives the compiled path from this and loads the BT tree at runtime. |
| blackboard | This is a list of variables the AI uses and can be mutated by actions. |
| bt_execution_log | Draining log of all leaf execution indices that fired since the last bt_viewer poll. Null when no viewer is attached. |
| cancelled_during_tick | Set to TRUE by cancel_current_plan() when it fires mid-tick. Checked by composites to abort the current tick loop early, preventing running_child_index from being re-established after a reset. Cleared at the start of SelectBehaviors(). |
| consecutive_pathing_attempts | Tracks recent pathing attempts, if we fail too many in a row we fail our current plans. |
| continue_processing_when_client | Can the AI remain in control if there is a client? |
| forced_off | Set by force_ai_off() when an outside system deliberately disables this AI. While TRUE, get_expected_ai_status() always returns AI_STATUS_OFF, so status recalculations (stat changes, z changes, client login/logout) cannot re-enable us. Cleared via clear_forced_off(). |
| interesting_dist | What distance should we be checking for interesting things when considering idling/deidling? Defaults to AI_DEFAULT_INTERESTING_DIST |
| last_bt_tick | world.time of our last SelectBehaviors() tick from SSai_controllers. Used to derive the real seconds_per_tick under load; 0 means no tick since the last status change, so the first tick falls back to the subsystem wait. |
| max_target_distance | distance to give up on target |
| movement_delay | Delay between movements. This is on the controller so we can keep the movement datum singleton |
| our_cells | our current cell grid |
| override_slots | assoc list of override_id -> /datum/bt_node/subtree for runtime subtree replacement. Populated by finalize_tree() when subtrees with override_id are found. Null until then. |
| paused_until | AI paused time |
| pawn | The atom this controller is controlling |
| polling_observers | Decorators in polling mode (observer_abort set, no signal registered). Iterated after each SelectBehaviors tick so their condition is re-evaluated even when skipped by composite resume logic. |
Procs | |
| PossessPawn | Proc to move from one pawn to another, this will destroy the target's existing controller. |
| SelectBehaviors | This is where you decide what actions are taken by the AI. |
| TryPossessPawn | Abstract proc for initializing the pawn to the new controller |
| UnpossessPawn | Proc for deinitializing the pawn to the old controller |
| _substitute_bindings | Recursively walks a descriptor list, replacing "$name" strings with their bound values. |
| _substitute_bindings_in_list | Substitutes bindings inside a descriptor value list, preserving assoc entries |
| add_blackboard_key | Adds the passed "thing" to the associated key |
| add_blackboard_key_assoc | Adds the value to the inner list at key with the inner key set to "thing" Throws an error if the key is not a list already, intended only for use with lists |
| add_blackboard_key_assoc_lazylist | Similar to [proc/add_blackboard_key_assoc], assuming key is intended to be a lazylist (so it will create a list) More dangerous / easier to override values, only use when you want to use a lazylist |
| add_blackboard_key_lazylist | Adds the passed "thing" to the associated key, assuming key is intended to be a lazylist (so it will create a list) More dangerous / easier to override values, only use when you want to use a lazylist |
| ai_can_interact | Can this pawn interact with objects? |
| ai_interact | Interact with objects |
| apply_bindings_to_descriptor | Merges call-site binding overrides with the subtree's declared defaults, then substitutes all $name placeholders in the descriptor tree. Returns a new descriptor with BT_DESC_BINDINGS stripped and placeholders resolved. |
| blackboard_key_exists | Returns true if we have a blackboard key with the provided key and it is not qdeleting |
| build_node_from_descriptor | Recursively builds a BT node tree from a descriptor list. BT_DESC_TYPE and BT_DESC_CHILDREN are consumed internally; all other keys are written as vars onto the node. String values starting with "/" are resolved via text2path so typepath args (e.g. "/datum/ai_movement/basic_avoidance") arrive as actual types. If you put / in a string then yeah that might cause issues, should probably fix that later! |
| can_reach_target | Returns TRUE if the pawn can path to the target. minimum_distance is how close the path must get (0 = onto/adjacent to the target's turf); searches pass it from their own acquire_target leaf. |
| change_ai_movement_type | Overrides the current ai_movement of this controller with a new one |
| clear_blackboard_key | Clears the passed key, resetting it to null |
| clear_forced_off | Undoes force_ai_off() and recalculates what status we should be in. |
| disable_evlogging | Unregister the evlog event added event, as we're no longer updating track info |
| enable_evlogging | Register for an event being added so we can update track info |
| finalize_tree | Walks the resolved tree to set owning_controller and parent_node on all nodes, populates override_slots, and assigns pre-order execution indices. Called after initialize_behavior_tree() and after set_behavior_tree_override() installs or removes an override node. |
| force_ai_off | Deliberately disables this AI until clear_forced_off() is called. Unlike a bare set_ai_status(AI_STATUS_OFF), this survives status recalculations from stat changes, z-level changes, client login/logout and the like. |
| get_able_to_run | Returns TRUE if the ai controller can actually run at the moment, FALSE otherwise |
| get_access | Use this proc to define how your controller defines what access the pawn has for the sake of pathfinding. Return the access list you want to use |
| get_active_ai_status | Classifies an active AI controller into a priority tier. Returns AI_STATUS_ON for controllers on station/shuttle territory, with a nearby client, Returns AI_STATUS_ON_LOW for other active controllers unless they have ALWAYS_HIGH_PRIORITY. else its AI_STATUS_OFF |
| get_expected_ai_status | Gets the AI status we expect the AI controller to be on at this current moment. Returns AI_STATUS_OFF if it has been forced off, is inhabited by a Client and shouldn't be, is dead and cannot act while dead, or is sleeping for performance (off-station with no nearby client and not flagged RUN_WHILE_UNWATCHED; client arrival wakes these automatically). Otherwise returns AI_STATUS_ON or AI_STATUS_ON_LOW, see get_active_ai_status(). |
| has_nearby_client | Returns TRUE if a living mob with a client is in one of our tracked spatial grid cells |
| initialize_behavior_tree | Builds the per-controller BT node tree from behavior_nodes typepaths or descriptors, then finalizes it. |
| insert_blackboard_key | Similar to [proc/add_blackboard_key], but performs an insertion rather than an add Throws an error if the key is not a list already, intended only for use with lists |
| insert_blackboard_key_lazylist | Similar to [proc/insert_blackboard_key_lazylist], but performs an insertion / or rather than an add |
| load_tree_from_json | Loads and decodes a compiled BT JSON file into a node tree. |
| note_unreachable_target | Called when a target was found but couldn't be reached. Base no-op; override to record the target (e.g. add it to an ignore list). |
| on_changed_z_level | Called when the AI controller pawn changes z levels, we check if there's any clients on the new one and wake up the AI if there is. |
| on_evlog_event_added | Called whenever an event is logged for this controller. Attaches a snapshot of current behaviors and blackboard state to the event via track_info. |
| on_pawn_evlogging_disabled | When the pawn gets DF_EVLOGGING disabled, propagate it to this controller too. |
| on_pawn_evlogging_enabled | When the pawn gets DF_EVLOGGING, propagate it to this controller too. |
| on_stat_changed | Turn the controller on or off based on if you're alive, we only register to this if the flag is present so don't need to check again |
| override_blackboard_key | Helper to force a key to be a certain thing no matter what's already there |
| post_blackboard_key_set | Called after we set a blackboard key, forwards signal information. |
| recalculate_idle | Check if mob should go into idle/low-priority (from spatial cells) |
| remove_from_blackboard_lazylist_key | removes a tracked object from a lazylist |
| remove_thing_from_blackboard_key | Remove the passed thing from the associated blackboard key |
| replace_behavior_nodes | Completely replaces the behavior_nodes with a new set based on argument provided. |
| reset_ai_status | Sets the AI on or off based on current conditions, call to reset after you've manually disabled it somewhere |
| reset_bt_tick_states | Call reset tick state on every node in the tree. |
| resolve_node_children | Resolves the children/child of a composite or decorator node, creating configured instances. Safe to call on any node type; non-composite/non-decorator nodes are a no-op. |
| set_ai_status | This proc handles changing ai status and updates the planning subsystem list. |
| set_behavior_tree_override | Installs or removes a runtime override on the subtree slot registered with the given id. |
| set_blackboard_key | Sets the key to the passed "thing". |
| set_blackboard_key_assoc | Sets the key at index thing to the passed value |
| set_blackboard_key_assoc_lazylist | Similar to [proc/set_blackboard_key_assoc] but operates under the assumption the key is a lazylist (so it will create a list) More dangerous / easier to override values, only use when you want to use a lazylist |
| sig_remove_from_blackboard | Signal proc to go through every key and remove the datum from all keys it finds |
Var Details
able_to_run 
TRUE if we're able to run, FALSE if we aren't Should not be set manually, override get_able_to_run() instead Make sure you hook update_able_to_run() in setup_able_to_run() to whatever parameters changing that you added Otherwise we will not pay attention to them changing
active_execution_index 
Execution index of the leaf node currently returning BT_RUNNING. 0 = nothing active.
ai_movement 
Reference to the movement datum we use. Is a type on initialize but becomes a ref afterwards.
ai_status 
Current status of AI (OFF/ON)
ai_traits 
Bitfield of traits for this AI to handle extra behavior
behavior_nodes 
The root of our tree, which will contain
behavior_tree_json 
Repo-relative path to the .bt.json source file for this controller (e.g. "code/datums/ai/basic_mobs/cleanbot.bt.json"). initialize_behavior_tree() derives the compiled path from this and loads the BT tree at runtime.
blackboard 
This is a list of variables the AI uses and can be mutated by actions.
When an action is performed you pass this list and any relevant keys for the variables it can mutate.
DO NOT set values in the blackboard directly, and especially not if you're adding a datum reference to this! Use the setters, this is important for reference handing.
bt_execution_log 
Draining log of all leaf execution indices that fired since the last bt_viewer poll. Null when no viewer is attached.
cancelled_during_tick 
Set to TRUE by cancel_current_plan() when it fires mid-tick. Checked by composites to abort the current tick loop early, preventing running_child_index from being re-established after a reset. Cleared at the start of SelectBehaviors().
consecutive_pathing_attempts 
Tracks recent pathing attempts, if we fail too many in a row we fail our current plans.
continue_processing_when_client 
Can the AI remain in control if there is a client?
forced_off 
Set by force_ai_off() when an outside system deliberately disables this AI. While TRUE, get_expected_ai_status() always returns AI_STATUS_OFF, so status recalculations (stat changes, z changes, client login/logout) cannot re-enable us. Cleared via clear_forced_off().
interesting_dist 
What distance should we be checking for interesting things when considering idling/deidling? Defaults to AI_DEFAULT_INTERESTING_DIST
last_bt_tick 
world.time of our last SelectBehaviors() tick from SSai_controllers. Used to derive the real seconds_per_tick under load; 0 means no tick since the last status change, so the first tick falls back to the subsystem wait.
max_target_distance 
distance to give up on target
movement_delay 
Delay between movements. This is on the controller so we can keep the movement datum singleton
our_cells 
our current cell grid
override_slots 
assoc list of override_id -> /datum/bt_node/subtree for runtime subtree replacement. Populated by finalize_tree() when subtrees with override_id are found. Null until then.
paused_until 
AI paused time
pawn 
The atom this controller is controlling
polling_observers 
Decorators in polling mode (observer_abort set, no signal registered). Iterated after each SelectBehaviors tick so their condition is re-evaluated even when skipped by composite resume logic.
Proc Details
PossessPawn
Proc to move from one pawn to another, this will destroy the target's existing controller.
SelectBehaviors
This is where you decide what actions are taken by the AI.
TryPossessPawn
Abstract proc for initializing the pawn to the new controller
UnpossessPawn
Proc for deinitializing the pawn to the old controller
_substitute_bindings
Recursively walks a descriptor list, replacing "$name" strings with their bound values.
_substitute_bindings_in_list
Substitutes bindings inside a descriptor value list, preserving assoc entries
add_blackboard_key
Adds the passed "thing" to the associated key
Works with lists or numbers, but not lazylists.
- key - A blackboard key
- thing - a value to set the blackboard key to.
add_blackboard_key_assoc
Adds the value to the inner list at key with the inner key set to "thing" Throws an error if the key is not a list already, intended only for use with lists
- key - A blackboard key, with its value set to a list
- thing - a value which becomes the inner list value's key
- value - what to set the inner list's value to
add_blackboard_key_assoc_lazylist
Similar to [proc/add_blackboard_key_assoc], assuming key is intended to be a lazylist (so it will create a list) More dangerous / easier to override values, only use when you want to use a lazylist
- key - A blackboard key, with its value set to a list
- thing - a value which becomes the inner list value's key
- value - what to set the inner list's value to
add_blackboard_key_lazylist
Adds the passed "thing" to the associated key, assuming key is intended to be a lazylist (so it will create a list) More dangerous / easier to override values, only use when you want to use a lazylist
- key - A blackboard key
- thing - a value to set the blackboard key to.
ai_can_interact
Can this pawn interact with objects?
ai_interact
Interact with objects
apply_bindings_to_descriptor
Merges call-site binding overrides with the subtree's declared defaults, then substitutes all $name placeholders in the descriptor tree. Returns a new descriptor with BT_DESC_BINDINGS stripped and placeholders resolved.
blackboard_key_exists
Returns true if we have a blackboard key with the provided key and it is not qdeleting
build_node_from_descriptor
Recursively builds a BT node tree from a descriptor list. BT_DESC_TYPE and BT_DESC_CHILDREN are consumed internally; all other keys are written as vars onto the node. String values starting with "/" are resolved via text2path so typepath args (e.g. "/datum/ai_movement/basic_avoidance") arrive as actual types. If you put / in a string then yeah that might cause issues, should probably fix that later!
can_reach_target
Returns TRUE if the pawn can path to the target. minimum_distance is how close the path must get (0 = onto/adjacent to the target's turf); searches pass it from their own acquire_target leaf.
change_ai_movement_type
Overrides the current ai_movement of this controller with a new one
clear_blackboard_key
Clears the passed key, resetting it to null
Not intended for use with list keys - use [proc/remove_thing_from_blackboard_key] if you are removing a value from a list at a key
- key - A blackboard key
clear_forced_off
Undoes force_ai_off() and recalculates what status we should be in.
disable_evlogging
Unregister the evlog event added event, as we're no longer updating track info
enable_evlogging
Register for an event being added so we can update track info
finalize_tree
Walks the resolved tree to set owning_controller and parent_node on all nodes, populates override_slots, and assigns pre-order execution indices. Called after initialize_behavior_tree() and after set_behavior_tree_override() installs or removes an override node.
force_ai_off
Deliberately disables this AI until clear_forced_off() is called. Unlike a bare set_ai_status(AI_STATUS_OFF), this survives status recalculations from stat changes, z-level changes, client login/logout and the like.
get_able_to_run
Returns TRUE if the ai controller can actually run at the moment, FALSE otherwise
get_access
Use this proc to define how your controller defines what access the pawn has for the sake of pathfinding. Return the access list you want to use
get_active_ai_status
Classifies an active AI controller into a priority tier. Returns AI_STATUS_ON for controllers on station/shuttle territory, with a nearby client, Returns AI_STATUS_ON_LOW for other active controllers unless they have ALWAYS_HIGH_PRIORITY. else its AI_STATUS_OFF
get_expected_ai_status
Gets the AI status we expect the AI controller to be on at this current moment. Returns AI_STATUS_OFF if it has been forced off, is inhabited by a Client and shouldn't be, is dead and cannot act while dead, or is sleeping for performance (off-station with no nearby client and not flagged RUN_WHILE_UNWATCHED; client arrival wakes these automatically). Otherwise returns AI_STATUS_ON or AI_STATUS_ON_LOW, see get_active_ai_status().
has_nearby_client
Returns TRUE if a living mob with a client is in one of our tracked spatial grid cells
initialize_behavior_tree
Builds the per-controller BT node tree from behavior_nodes typepaths or descriptors, then finalizes it.
insert_blackboard_key
Similar to [proc/add_blackboard_key], but performs an insertion rather than an add Throws an error if the key is not a list already, intended only for use with lists
- key - A blackboard key, with its value set to a list
- thing - a value to set the blackboard key to.
insert_blackboard_key_lazylist
Similar to [proc/insert_blackboard_key_lazylist], but performs an insertion / or rather than an add
- key - A blackboard key
- thing - a value to set the blackboard key to.
load_tree_from_json
Loads and decodes a compiled BT JSON file into a node tree.
note_unreachable_target
Called when a target was found but couldn't be reached. Base no-op; override to record the target (e.g. add it to an ignore list).
on_changed_z_level
Called when the AI controller pawn changes z levels, we check if there's any clients on the new one and wake up the AI if there is.
on_evlog_event_added
Called whenever an event is logged for this controller. Attaches a snapshot of current behaviors and blackboard state to the event via track_info.
on_pawn_evlogging_disabled
When the pawn gets DF_EVLOGGING disabled, propagate it to this controller too.
on_pawn_evlogging_enabled
When the pawn gets DF_EVLOGGING, propagate it to this controller too.
on_stat_changed
Turn the controller on or off based on if you're alive, we only register to this if the flag is present so don't need to check again
override_blackboard_key
Helper to force a key to be a certain thing no matter what's already there
Useful for if you're overriding a list with a new list entirely, as otherwise it would throw a runtime error from trying to override a list
Not necessary to use if you aren't dealing with lists, as set_blackboard_key will clear the existing value in that case already, but may be useful for clarity.
- key - A blackboard key
- thing - a value to set the blackboard key to.
post_blackboard_key_set
Called after we set a blackboard key, forwards signal information.
recalculate_idle
Check if mob should go into idle/low-priority (from spatial cells)
remove_from_blackboard_lazylist_key
removes a tracked object from a lazylist
remove_thing_from_blackboard_key
Remove the passed thing from the associated blackboard key
Intended for use with lists, if you're just clearing a reference from a key use [proc/clear_blackboard_key]
- key - A blackboard key
- thing - a value to set the blackboard key to.
replace_behavior_nodes
Completely replaces the behavior_nodes with a new set based on argument provided.
reset_ai_status
Sets the AI on or off based on current conditions, call to reset after you've manually disabled it somewhere
reset_bt_tick_states
Call reset tick state on every node in the tree.
resolve_node_children
Resolves the children/child of a composite or decorator node, creating configured instances. Safe to call on any node type; non-composite/non-decorator nodes are a no-op.
set_ai_status
This proc handles changing ai status and updates the planning subsystem list.
set_behavior_tree_override
Installs or removes a runtime override on the subtree slot registered with the given id.
id - The ID for this slot override_subtree - actual subtree we're setting
set_blackboard_key
Sets the key to the passed "thing".
- key - A blackboard key
- thing - a value to set the blackboard key to.
- track_datum - whether we should track this ref for deletion, this should always be TRUE unless you really know wtf you're doing
set_blackboard_key_assoc
Sets the key at index thing to the passed value
Assumes the key value is already a list, if not throws an error.
- key - A blackboard key, with its value set to a list
- thing - a value which becomes the inner list value's key
- value - what to set the inner list's value to
set_blackboard_key_assoc_lazylist
Similar to [proc/set_blackboard_key_assoc] but operates under the assumption the key is a lazylist (so it will create a list) More dangerous / easier to override values, only use when you want to use a lazylist
- key - A blackboard key, with its value set to a list
- thing - a value which becomes the inner list value's key
- value - what to set the inner list's value to
sig_remove_from_blackboard
Signal proc to go through every key and remove the datum from all keys it finds