Skip to content

Commit ea4dedc

Browse files
committed
Add initial docs for Entity Pathfinders and Mob Goal API
1 parent fc8ccf2 commit ea4dedc

File tree

3 files changed

+190
-0
lines changed

3 files changed

+190
-0
lines changed

config/sidebar.paper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ const paper: SidebarsConfig = {
139139
"dev/api/scheduler",
140140
"dev/api/plugin-messaging",
141141
"dev/api/plugin-configs",
142+
"dev/api/mob-goals",
143+
"dev/api/entity-pathfinder",
142144
"dev/api/folia-support",
143145
],
144146
},
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
slug: /dev/entity-pathfinder
3+
description: A guide to the Entity Pathfinder API.
4+
---
5+
6+
# Entity Pathfinder API
7+
8+
The Entity Pathfinder API is a way of controlling the movement of entities in Minecraft. It allows you to set a path
9+
for an entity to follow, such as moving to a location, or following a player.
10+
11+
## Accessing the Pathfinder
12+
13+
To access the pathfinder for a Mob, you need to call `getPathfinder()` on the Mob. This will return an instance of `Pathfinder`.
14+
15+
:::important
16+
17+
The pathfinder is only available for Mobs, not for all entities.
18+
19+
:::
20+
21+
Lets say that we have a `Cow` and we want it to move to a specific `Player`'s location. We can do this by getting the
22+
pathfinder for the cow and then setting the path to the player's location:
23+
24+
```java
25+
Cow cow = ...;
26+
Player player = ...;
27+
28+
Pathfinder pathfinder = cow.getPathfinder();
29+
// moveTo returns a boolean indicating whether the path was set successfully
30+
boolean success = pathfinder.moveTo(player.getLocation());
31+
```
32+
33+
If we want to access the current Path for the cow, we can call `getCurrentPath()` on the pathfinder:
34+
35+
```java
36+
PathResult path = pathfinder.getCurrentPath();
37+
38+
// A PathResult is essentially a wrapper around a List of Locations. These can be accessed with:
39+
List<Location> locations = path.getPoints();
40+
// It is important to note that the list contains points that have already been passed,
41+
// as well as future points. If you want to get the next point, you can use:
42+
Location nextPoint = path.getNextPoint(); // Or locations.get(path.getNextPointIndex())
43+
// Finally, you can access the final destination with:
44+
Location destination = path.getFinalPoint();
45+
```
46+
47+
## Pathfinding Rules
48+
49+
Much of the way that the Pathfinder works is dictated by the limitations of the actual entity pathfinding in Minecraft.
50+
For example, a Polar Bear cannot fly. This means that if you set a path for a Polar Bear to a location that is in the air,
51+
it will not be able to reach it.
52+
53+
There are some attributes that can be set on the pathfinder to change the way that the pathfinder works. These are:
54+
- `setCanOpenDoors(boolean)`: Whether the entity can open doors.
55+
- `setCanPassDoors(boolean)`: Whether the entity can pass through open doors.
56+
- `setCanFloat(boolean)`: Whether the entity can float in water.
57+
These all have respective getters as well.
58+
59+
## Stopping the Pathfinder
60+
61+
To stop the pathfinder, you can call `stopPathfinding()` on the pathfinder. This will stop the pathfinder and clear the
62+
current path. You can use `hasPath()` to check if the pathfinder is currently running.

docs/paper/dev/api/mob-goals.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
slug: /dev/mob-goals
3+
description: A guide to the PDC API for storing data.
4+
---
5+
6+
# Mob Goal API
7+
8+
The Mob Goal API is a way of controlling the behaviour of mobs in Minecraft. It allows you to set a goal for a mob to perform, such as
9+
attacking a player, or moving to a location. It also allows you to create your own custom goals.
10+
11+
## Registering a Goal on an Entity
12+
13+
To register a goal on an entity, you need to create an instance of the goal and then register it with the entity:
14+
15+
```java
16+
Cow cow = ...;
17+
Goal<Cow> goal = new ExampleGoal();
18+
19+
server.getMobGoals().addGoal(cow, 0, goal); // 0 is the priority, lower numbers are higher priority
20+
```
21+
22+
:::tip
23+
24+
You can access the Vanilla goals from the `VanillaGoal` class. These are the goals that are used by Vanilla Minecraft.
25+
They are specific to each mob type, so you can't use a cow goal on a zombie for example.
26+
27+
:::
28+
29+
## Creating a Custom Goal
30+
31+
To create a custom goal, you need to create a class that implements the `Goal` interface. This interface has several methods:
32+
- `void start()`: Called when the goal is started.
33+
- `void tick()`: Called every tick while the goal is running.
34+
- `void stop()`: Called when the goal is stopped.
35+
- `boolean shouldActivate()`: Called to determine if the goal should start.
36+
- `boolean shouldStayActive()`: Called to determine if the goal should continue running.
37+
- `GoalKey getKey()`: Called to get the key for the goal.
38+
- `EnumSet<GoalType> getTypes()`: Called to get the types of the goal.
39+
40+
:::note[types]
41+
42+
The `getTypes()` method is used to determine what types of goal this is. The types are:
43+
- `GoalType.MOVE`: The goal moves the entity.
44+
- `GoalType.LOOK`: The goal changes the direction the entity is looking.
45+
- `GoalType.JUMP`: The goal makes the entity jump.
46+
- `GoalType.TARGET`: The goal changes the target of the entity.
47+
- `GoalType.UNKNOWN_BEHAVIOR`: The goal does something else. Used for mapping Vanilla goals.
48+
49+
:::
50+
51+
Here is an example of a goal that makes a camel follow a player. This is essentially the same as the `FOLLOW_MOB` in Vanilla,
52+
but it is a good example of how to create a goal.
53+
54+
```java
55+
public class CamelFollowPlayerGoal implements Goal<Camel> {
56+
57+
public static final GoalKey<Camel> KEY = GoalKey.of(Camel.class, new NamespacedKey("testplugin", "camel_follow_player"));
58+
59+
private final Player player;
60+
private final Camel camel;
61+
62+
public CamelFollowPlayerGoal(Player player, Camel camel) {
63+
// The constructor takes the Player to follow and the Camel that is following
64+
this.player = player;
65+
this.camel = camel;
66+
}
67+
68+
@Override
69+
public boolean shouldActivate() {
70+
// This is whether or the goal should start. In this case, we want the goal to always start so we return true.
71+
// You could also return false here if you wanted to only start the goal in certain situations.
72+
return true;
73+
}
74+
75+
@Override
76+
public void start() {
77+
// This is called when the goal starts. In this case, we just send a message to the player.
78+
player.sendMessage(text("I am following you!"));
79+
}
80+
81+
@Override
82+
public void tick() {
83+
// This is called every tick while the goal is running. In this case, we make the camel move towards the player
84+
// using the Pathfinder API. The 5.0 is the speed of the camel.
85+
camel.getPathfinder().moveTo(player, 5.0);
86+
}
87+
88+
@Override
89+
public void stop() {
90+
// This is called when the goal stops. In this case, we just send a message to the player.
91+
player.sendMessage(text("I Stopped following you!"));
92+
}
93+
94+
@Override
95+
public @NotNull GoalKey<Camel> getKey() {
96+
// This is the key for the goal. It is used to identify the goal and is used to determine if two goals are the same.
97+
// It requires the class of the entity and a NamespacedKey. The NamespacedKey is used to identify the goal.
98+
// You should use the plugin's namespace for the NamespacedKey, not Minecraft or Bukkit.
99+
return KEY;
100+
}
101+
102+
@Override
103+
public @NotNull EnumSet<GoalType> getTypes() {
104+
// This is used to determine what types of goal this is. In this case, we are moving the entity and changing the
105+
// direction it is looking, so we return MOVE and LOOK. Return as many types as you need.
106+
return EnumSet.of(GoalType.MOVE, GoalType.LOOK);
107+
}
108+
}
109+
```
110+
111+
## Stopping a Goal
112+
113+
To stop a goal, you need to get the goal key and then call `stop()` on the goal:
114+
115+
```java
116+
Cow cow = ...;
117+
// This works because our example has a public static `KEY` field
118+
server.getMobGoals().removeGoal(cow, CamelFollowPlayerGoal.KEY);
119+
120+
// You can also remove Vanilla goals
121+
server.getMobGoals().removeGoal(cow, VanillaGoal.TEMPT);
122+
123+
// You can also remove all goals
124+
server.getMobGoals().removeAllGoals(cow);
125+
server.getMobGoals().removeAllGoals(cow, GoalType.MOVE); // Remove all MOVE goals
126+
```

0 commit comments

Comments
 (0)