Animal Tasks - UQcsse3200/2024-studio-1 GitHub Wiki
Overview
The Task system is a collection of AI behaviour components designed to create realistic and dynamic animal behaviours in our game. These tasks are built on top of the AI Task System, which allows for priority-based task execution and seamless switching between different behaviours based on which has the highest priority. Each task specifies its priority using static variables.
To configure these tasks for each animal, see NPC Configuration.
Tasks
Tasks are units of behaviour that NPCs can execute. Each task defines what the NPC does when the task is active and specifies a priority to determine when it should be executed. All tasks default to a priority of -1 when not active, however WanderTask
and StraightWanderTask
always have a constant priority of 1, making them the fallback tasks. The other tasks return their INACTIVE_PRIORITY
when inactive and that conditions to be activated are met.
WanderTask
NPC wanders around within a specified range from its starting position.
- Configuration:
wanderRadius
: The radius within which the NPC wanders.waitTime
: Time to wait between movements.wanderSpeed
: Speed at which the NPC moves while wandering.
public class WanderTask extends DefaultTask implements PriorityTask {
private static final int PRIORITY = 1;
// ...
}
StraightWanderTask
NPC moves in a straight line in a random direction. On collision, it changes direction randomly. It is not compatible with WanderTask
.
- Configuration:
wanderSpeed
: Speed at which the NPC moves.
public class StraightWanderTask extends DefaultTask implements PriorityTask {
private static final int PRIORITY = 1;
// ...
}
FollowTask
NPC follows the player or another target entity within a specified range.
- Configuration:
followRadius
: The radius within which the NPC follows the target.waitTime
: Time to wait between movements.followSpeed
: Speed at which the NPC moves while following.
public class FollowTask extends DefaultTask implements PriorityTask {
private static final int PRIORITY = 1;
// ...
}
ChaseTask
NPC chases a target entity when within a viewDistance
until it gets too far away (chaseDistance
) or loses line of sight.
- Configuration:
viewDistance
: Distance within which the NPC can see the target.chaseDistance
: Maximum distance the NPC will chase the target.chaseSpeed
: Speed at which the NPC chases the target.maxTime
: Maximum time the NPC will continue to chase.
public class ChaseTask extends DefaultTask implements PriorityTask {
private static final int PRIORITY = 4;
// ...
}
ChargeTask
NPC charges towards a target's current position. It can overshoot the target based on a distance multiplier and stops when colliding with entities or obstacles. It gives the task manager its inactive priority, when the target is with a specified range away from the charging entity.
- Configuration:
activationMinRange
andactivationMaxRange
: Range within which the task can activate.chaseSpeed
: Speed of the charge.distanceMultiplier
: Multiplier to determine how far beyond the target the NPC charges.waitTime
: Time to wait after charging.cooldownTime
: Cooldown before the task can activate again.
public class ChargeTask extends DefaultTask implements PriorityTask {
private static final int ACTIVE_PRIORITY = 10;
private static final int INACTIVE_PRIORITY = 8;
// ...
}
JumpTask
NPC jumps toward a target, bypassing obstacles, and simulates a jump arc in the y-direction. Upon landing, it performs an AOE attack. It waits after the jump for a given amount of time, then stops. It activates when the target is with a specified range away from the charging entity then waits after the charge for a given amount of time before stopping.
- Configuration:
activationMinRange
andactivationMaxRange
: Range within which the task can activate.jumpDuration
: Duration of the jump.waitTime
: Time to wait after jumping.cooldownTime
: Cooldown before the task can activate again.
public class JumpTask extends DefaultTask implements PriorityTask {
private static final int ACTIVE_PRIORITY = 10;
private static final int INACTIVE_PRIORITY = 7;
// ...
}
RunAwayTask
NPC runs away from a target when its health falls below a certain percentage and the target is within a certain set range of the NPC.
- Configuration:
activationMinRange
andactivationMaxRange
: Range within which the task can activate.activationHealth
: Health percentage below which the NPC will run away.runSpeed
: Speed at which the NPC runs away.stopDistance
: Distance to stop running.maxRunTime
: Maximum time to run.cooldownTime
: Cooldown before the task can activate again.
public class RunAwayTask extends DefaultTask implements PriorityTask {
private static final int ACTIVE_PRIORITY = 10;
private static final int INACTIVE_PRIORITY = 9;
// ...
}
RangeAttackTask
NPC performs a ranged attack on a target entity. It gives the inactive priority when the target is within a specified range.
- Configuration:
activationMinRange
andactivationMaxRange
: Range within which the task can activate.attackNum
: Number of attacks to perform.cooldownTime
: Cooldown before the task can activate again.attackType
: Type of ranged attack ("single"
or"spread"
).
public class RangeAttackTask extends DefaultTask implements PriorityTask {
private static final int ACTIVE_PRIORITY = 9;
private static final int SINGLE_INACTIVE_PRIORITY = 5;
private static final int SPREAD_INACTIVE_PRIORITY = 6;
// ...
}
AOEAttackTask
NPC performs an Area of Effect (AOE) attack with a preparation phase. It gives the inactive priority when the target is within a specified range.
- Configuration:
activationMinRange
andactivationMaxRange
: Range within which the task can activate.preparationTime
: Time spent preparing (e.g., charge-up animation).cooldownTime
: Cooldown before the task can activate again.
public class AOEAttackTask extends DefaultTask implements PriorityTask {
private static final int ACTIVE_PRIORITY = 10;
private static final int INACTIVE_PRIORITY = 6;
// ...
}
BulletStormTask
An NPC moves to the centre of the room, enables BossRangeAttackComponent
and becomes invincible. This runs after the NPC drops below 50% health and deactivates after a specified duration has passed. It can only be activated once. This has been designed for bosses to use.
public class BulletStormTask extends DefaultTask implements PriorityTask {
private static final int TASK_PRIORITY = 15; // Highest priority
private static final float ACTIVATION_HEALTH_PERCENTAGE = 50f;
private final Vector2 centerPosition = new Vector2(7, 5); // Centre of room
// ...
WaitTask
Task that does nothing other than waiting for a given time. Used within other tasks as it is not a priority task.
- Configuration:
duration
: Duration to wait.
public class WaitTask extends DefaultTask {
// ...
}
MovementTask
Moves the entity to a given position, finishing when it gets close enough. Used within other tasks as it is not a priority task.
- Configuration:
target
: The target position.stopDistance
: Distance from the target at which to stop.
public class MovementTask extends DefaultTask {
// ...
}
Implementation
The tasks are implemented in the NPCFactory
class, which creates the AITaskComponent
based on the configuration:
private void addAIComponent(Entity npc, Entity target, TaskConfig tasks) {
AITaskComponent aiComponent = new AITaskComponent();
Map<TaskType, Object> taskConfigs = tasks.getTaskConfigs();
for (Map.Entry<TaskType, Object> entry : taskConfigs.entrySet()) {
switch (entry.getKey()) {
case WANDER -> aiComponent.addTask(new WanderTask((TaskConfig.WanderTaskConfig) entry.getValue()));
case STRAIGHT_WANDER
-> aiComponent.addTask(new StraightWanderTask((TaskConfig.StraightWanderTaskConfig) entry.getValue()));
case FOLLOW -> aiComponent.addTask(new FollowTask((TaskConfig.FollowTaskConfig) entry.getValue()));
case CHASE -> aiComponent.addTask(new ChaseTask(target, (TaskConfig.ChaseTaskConfig) entry.getValue()));
// ... other tasks ...
npc.addComponent(aiComponent);
}
Extensibility
The task system is designed to be easily extensible. To create a new task:
- Create a new configuration class in
NPCConfigs.NPCConfig.TaskConfig
. - Implement the task class extending
DefaultTask
and implementingPriorityTask
. - Add the task creation logic in the
NPCFactory.createAIComponent
method.
This modular design allows for the creation of complex behaviors by combining simpler tasks, all configurable through the NPCConfigs
class.