API Documentation/Modifying AI behaviors
This tutorial will show you how to modify the AI of an entity.
AI parts
The AI of an entity is not a vast body, but splitted into several parts. With this API, you are in charge of adding and removing these parts. To ensure that you don't have to deal with native server code, the API introduces wrapper classes for many of the AI behaviors.
There are two categories containing all AI behaviors. The first one is the pathfinding, the other the targeting system. These systems are working independently (mutex bits and priorities of one system do not affect the other system).
Quote:Be aware that manually added actions like moveTo() or target() will override any of these AI behaviors.
Pathfinding system
The pathfinding behaviors will make an entity move or look at specific locations, or describe the way an entity attacks its target.
All pathfinding behaviors extend the base class AIBehavior. Currently, these pathfinding behaviors can be used:
AIBehavior | notes | what it does | mutex bits |
---|---|---|---|
AIAttackMelee | attack type: | the entity attacks its target with a melee attack and will constantly run to it. | 0,1 |
AIAttackRanged | attack type: only available for Skeleton, Snowman, Witch, Wither | the entity will use ranged attacks (depending on the entity type) and move to its target until it is in range. | 0,1 |
AIFleeSun | only available for Creatures | when the entity is burning and standing in the sun, it will search for a water or shadow place | 0 |
AIFloat | the entity will swim in water, prevents drowning | 2 | |
AILookAtEntity | the entity will look at another entity when the distance between them is not too large | 1 | |
AIRandomLookaround | the entity will curiously look around | 0,1 | |
AIRandomStroll | only available for Creatures | the entity will curiously move around | 0 |
AIRestrictSun | only available for Creatures. Passive | the entity stays out of the sun |
Quote:Be aware that you have to keep the default behaviors or add at least one behavior that describes how an entity's attack will look like to ensure that your entity will attack its target when you order it to. Otherwise, the entity will not move to nor attack its target.
Targeting system
The targeting behaviors describe which other entities an entity will try to follow or attack.
All targeting behaviors extend the base class AITargetBehavior. Currently, these targeting behaviors can be used:
AITargetBehavior | what it does | mutex bits |
---|---|---|
AITargetHurtBy | if the entity is getting attacked by another entity, it will attack its attacker back | 0 |
AITargetNearest | the entity is going to attack the nearest suitable target within range | 0 |
Quote:You don't have to add any of the targeting behaviors. If you order an entity to attack by using
controlledEntity.getActions().target(LivingEntity yourTarget), it will work without previosly having added any custom targeting behaviors. These behaviors are just in case you want your entity to automatically attack without your explicit order.
The priority system and mutex bits
The order of which behaviors are executed is determined by the order you add them to the entity. You can create every behavior by using a constructor and providing a priority. This priority affects which behavior will be executed when there are incompatibilities. Incompatibilities between behaviors are occuring when the parallel execution of both would lead to "stupid" behavior. For example, when one behavior says "hey, let's stroll around curiously" and the other "follow your target to attack it!". As you can see, not both can be handled at the same time. To realize this, for all behaviors exist so-called mutex bits (as listed in the tables above). If two behaviors have at least one mutex bit in common, they are incompatible. The priority you provided will now decide which one will be executed first - the behavior with the lower priority will be executed, the one with the higher priority will have to wait!
Quote from Infosystem:To ensure you (and the server too!) are not getting cofused, you should add the behaviors with the lowest priority first and the behaviors with the highest priorities last.
If you don't specify a priority or pass a priority <= 0, the actually highest priority +1 will be used. You may specify the same priority for several behaviors.
Managing AI behaviors
The ControllableMobAI interface gives you verious methods to control the AI of an entity.
Creating AI behaviors
All non-abstract classes extending AIBehavior have different constructors you may use. Depending on the arguments you want to provide, you can select any of them.
Example:
AITargetNearest behavior = new AITargetNearest(4, 80.0F, true, 100)
will create a behavior with the priority 4 that lets your entity search for attackable targets in a radius of 80 blocks. The third parameter will force the entity to ignore invulnerability. The fourth parameter will ensure that the entity has eye contact to its target (value greater 0) and will cause the entity to lose its target when there is no eye contact for more than 5 seconds (20 server ticks ~ 1 second)
Adding a behavior
Simply use
AIPart aiPart = controlledEntity.getAI().addBehavior(behavior);
to add the behavior to your entity. However, there are some facts you have to pay attention to:
- do not add a behavior twice or more times to the same entity
- keep a reference to the returned AIPart in memory if you wish to remove the behavior it later
State monitoring
Use AIPart.getState() to monitor the state of a certain behavior.
The ControllableMobAI interface provides several other methods to get and check for currently attached behaviors, like ControllableMobAI.hasBehavior()
Unattaching / reattaching an AI part
You can use
aiPart.unattach();
to remove the underlying behavior from your entity.
Using this method it is not possible to remove default behaviors (behaviors, that were automatically added to the entity before you made it controllable). You can either clear all behaviors, or remove behaviors of a certain type by
controlledEntity.getAI().remove(aiType);
You can use
aiPart.reattach();
to add the behavior again later on.
Clearing behaviors
Use
controlledEntity.getAI().clear();
to remove every default and manually added behavior. As a result, the entity will not automatically move or attack anywhere or anything. Manually added actions like moveTo() or target() are unaffected.
Restoring behaviors
Use
controlledEntity.getAI().reset();
to restore all default behaviors. It is unimportant how often you added custom behaviors or cleared all behaviors, this method will restore the default behaviors, no more and no less, at any time. As a result all custom behaviors are removed and the entity behaves naturally.
You adjusted the AI for your needs? Great, maybe you should continue and perform actions with your entity!