Modding:Entity Behavior taskai

From Vintage Story Wiki

This server side entity behavior runs one or more tasks for the entity. The tasks are assigned through the aitasks property as part of applying the behavior to the entity.

Tasks are either active (aka executing or running) or inactive. Each task is assigned a slot, in the range 0 to 7. Multiple tasks are often assigned to the same slot, but only one task can be active per slot.

Tasks are assigned a priority. The behavior will run the highest priority task that is able to run for the slot. When there are multiple tasks with the same priority, the task's order in the list is used as a tie-breaker, where entries earlier in the list are preferred.

Sometimes a higher priority task is initially unable to run, but later is able to run, which causes the current active task to be cancelled and replaced with the higher priority task. When considering whether to cancel an active task, its cancel priority is considered instead of its regular priority. Setting the cancel priority high allows an otherwise low priority task to run to completion once it starts.

For example, consider the following two tasks inside locust.json.

  server: {
    behaviors: [
...
      {
        code: "taskai",
        aitasks: [
          {
            code: "meleeattack",
            entityCodes: ["player"],
            priority: 3,
...
          },
...
          {
            code: "seekentity",
            entityCodes: ["player"],
            priority: 1.5,
...
          },
...
        ]
      }
    ],
...
  },

The locust has the meleeattack at priority 3. Since the slot was not specified, it defaults to slot 0. seekentity has priority 1.5 (and cancel priority 1.5) on slot 0. Initially when the player is not in range, meleeattack is unable to run, because its ShouldExecute method returns false when the target entity is out of melee attack range. So the seekentity task is run first, even though it is lower priority. After the seekentity task gets the locust within range of the player, the meleeattack task is able to run. So the seekentity task is canceled and replaced with meleeattack, because they share the same slot. After the attack, meleeattack enters cooldown and becomes inactive. So the seekentity task resumes.

Debugging

Ram with the seekfoodandeat task active at priority 1.35

Turning on entitydebuginfo puts a text box above each entity. The text box shows the active tasks (along with their priority and cancel priority), emotional state, and currently running animations.

Entity debug info has to be turned on on both the server (with /entity debug 1) and client side (with .clientconfig showentitydebuginfo 1). With just the server side, the server sends the extra debug information to the client, but the client does not display it. With just the client side, it will display the active animations, but it will not get the task status from the server.

AiTaskBase properties

All vanilla AI tasks inherit from AiTaskBase. As such, all those AI tasks support the following properties defined in AiTaskBase. Some tasks also inherit from AiTaskBaseTargetable, which defines additional properties.

slot: (integer, default 0)
The slot that this mod runs in. Out of all of the tasks assigned the same slot, only one can be active at a time. The inactive tasks still do a little processing on every tick to consider whether they should become active.; priority: (float, default 0) : The priority for starting this task compared to the other tasks assigned to the same slot.
priorityForCancel: (float, default 0)
This task's priority when considering canceling it to run a different task. Often a low priority task is given a higher priorityForCancel value so that the task starts at low priority but runs to completion after it starts.
id: (string, default "")
This is rarely used and typically as the default for most tasks. Other entity behaviors or tasks can read this field to find a specific task to inspect or modify. The bellalarm task will not start unless a task with the id "listen" is active. Typically other behaviors and tasks will search for tasks by type. However, in the bellalarm case, the bell entity has two idle type tasks. So one is given the id "listen" to differentiate it.
animation: (string)
Animation to play on the entity while the task executes. The animation is stopped when the task finishes, unless the animation is "attack" or "idle", in which case it plays to completion. The animation can either match an AnimationMetaData code from the entity properties, or it can be the name of an animation from the entity's shape file.
animationSpeed: (float, default 1)
Playback speed of the animation. If the animation refers to a AnimationMetaData code from the entity properties, then this field overrides the playback speed only if it is set (the default is not applied to AnimationMetaDatas). If the animation instead directly refers to an animation code from the entity shape file, and an explicit speed was not given, then the default playback speed of 1 is applied.
sound: (asset location)
Sound to play while the task is running.
soundRange: (float, default 16)
How many blocks away the sound can be heard.
soundStartMs: (int, default 0)
Wait this many milliseconds after the task starts before playing the sound.
soundRepeatMs: (int, default 0)
If this is non-zero, then repeat the sound this long after starting the previous sound. It is possible to repeat the sound before the previous one finished.
finishSound: (asset location)
Sound to play when the task finishes execution.

AiTaskBase partial compliance properties

In the code, these properties are parsed by AiTaskBase. So they can be attached to any AI task that inherits from that, which is all of them. However, only a few of the tasks actually comply with the value parsed for these properties. So the properties are described here, and also included in the per-task lists for the tasks that comply with the properties.

mincooldown: (int, default 0)
lower bound on the randomly selected cooldown time. See the description at maxcooldown
maxcooldown: (int, default 0)
upper bound on the randomly selected cooldown time. The cooldown means to wait at least this many milliseconds before starting the task again, relative to the last time the task started or finished (whichever is more recent).
initialmincooldown: (int, default mincooldown)
lower bound for the warmup time.
initialmaxcooldown: (int, default maxcooldown)
upper bound for randomly selecting the warmup time. The warmup time is the delay between creating the entity and the first time the task may execute. Tasks honor the warmup time if and only if they honor the cooldown time. Most tasks do not honor the warmup time.
mincooldownHours: (double, default 0)
same concept as mincooldown, but in in-game hours.
maxcooldownHours: (double, default 0)
same concept as maxcooldown, but in in-game hours.
whenSwimming: (bool?, default null)
If null, then the task can be run whether or not the entity is swimming. If true, then only run the task if the entity is swimming. If false, then only run the task if the entity is not swimming.
whenInEmotionState: (string, default null)
If non-null, then only run the task when the entity's emotional state matches the specified value.
whenNotInEmotionState: (string, default null)
If non-null, then only run the task when the entity's emotional state is different from the specified value.

All Tasks

Task Name Explanation Example entities Properties
bellalarm
butterflychase
butterflyfeedonflowers
butterflyflee
butterflyrest
butterflywander
cometoowner
eidolonmeleeattack
eidolonslam
fishmovefast
fishoutofwater
fleeentity

whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes

flycircle
flyswoopattack

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes

getoutofwater
gotoentity
idle

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState

jealousmeleeattack Gets jealous of other guards for the same guarded entity, and deals damage if they are in melee attack range.
  • locust-*-hacked
  • mechhelper

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes
tamingGenerations
damageTier
damageType
knockbackStrength
attackAngleRangeDeg
attackDurationMs
damagePlayerAtMs
minDist
minVerDist

jealousseekentity Gets jealous of other guards for the same guarded entity. It targets and approaches them.
  • locust-*-hacked
  • mechhelper

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes
leapAtTarget
leapAnimation
leapChance
leapHeightMul
moveSpeed
extraTargetDistance
seekingRange
belowTempSeekingRange
belowTempThreshold
maxFollowTime
alarmHerd
retaliateAttacks
executionChance
searchWaitMs

lookaround

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown

lookatentity

friendlyTarget
triggerEmotionState
skipEntityCodes
entityCodes

meleeattack Deals damage to target entities within melee attack range of the attacker
  • wolf

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes
tamingGenerations
damageTier
damageType
knockbackStrength
attackAngleRangeDeg
attackDurationMs
damagePlayerAtMs
minDist
minVerDist

meleeattacktargetingentity Deals damage to target entities within melee attack range of the attacker, but only if they are targeting the guarded entity (owner of the guard entity).
  • locust-*-hacked
  • mechhelper

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes
tamingGenerations
damageTier
damageType
knockbackStrength
attackAngleRangeDeg
attackDurationMs
damagePlayerAtMs
minDist
minVerDist

seekblockandlay

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
mincooldownHours
maxcooldownHours
whenSwimming
whenInEmotionState
whenNotInEmotionState

seekentity Locks onto a target entity and approaches it. Also handles retreat.
  • wolf

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes
leapAtTarget
leapAnimation
leapChance
leapHeightMul
moveSpeed
extraTargetDistance
seekingRange
belowTempSeekingRange
belowTempThreshold
maxFollowTime
alarmHerd
retaliateAttacks
executionChance
searchWaitMs

seekfoodandeat

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
mincooldownHours
maxcooldownHours
whenSwimming
whenInEmotionState
whenNotInEmotionState

seektargetingentity Targets and approaches other entities that are targeting the guarded entity (owner of the guard entity).
  • locust-*-hacked
  • mechhelper

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
whenSwimming
whenInEmotionState
whenNotInEmotionState
friendlyTarget
retaliateAttacks
triggerEmotionState
skipEntityCodes
entityCodes
leapAtTarget
leapAnimation
leapChance
leapHeightMul
moveSpeed
extraTargetDistance
seekingRange
belowTempSeekingRange
belowTempThreshold
maxFollowTime
alarmHerd
retaliateAttacks
executionChance
searchWaitMs

stayclosetoentity
stayclosetoguardedentity
throwatentity
useinventory

mincooldown
maxcooldown
initialmincooldown
initialmaxcooldown
mincooldownHours
maxcooldownHours
whenSwimming
whenInEmotionState
whenNotInEmotionState

wander


Content Modding
Basics Content Mods Developing a Content Mod Packaging & Release
Tutorials
Concepts Modding Concepts Modinfo Variants Domains Patching Remapping World Properties
Moddable Assets
Uncategorized
Icon Sign.png

Wondering where some links have gone?
The modding navbox is going through some changes! Check out Navigation Box Updates for more info and help finding specific pages.

Modding
Modding Introduction Getting Started Theme Pack
Content Modding Content Mods Developing a Content Mod Basic Tutorials Intermediate Tutorials Advanced Tutorials Content Mod Concepts
Code Modding Code Mods Setting up your Development Environment
Property Overview ItemEntityEntity BehaviorsBlockBlock BehaviorsBlock ClassesBlock EntitiesBlock Entity BehaviorsCollectible BehaviorsWorld properties
Workflows & Infrastructure Modding Efficiency TipsMod-engine compatibilityMod ExtensibilityVS Engine
Additional Resources Community Resources Modding API Updates Programming Languages List of server commandsList of client commandsClient startup parametersServer startup parameters
Example ModsAPI DocsGitHub Repository