-
-
Notifications
You must be signed in to change notification settings - Fork 27
NavigationPointProvider and NavigationPoint
Pathetic is an engine, not a mind reader. It doesn't know if your world is made of voxels, navigation meshes, or abstract data.
You have the map data. We have the pathfinding logic. The Provider is the handshake between the two.
You need to implement two things. Don't overthink them.
-
NavigationPoint (The Atom) Represents a single coordinate in your world.
- Job: Answer one question: "Can I stand here?" (isTraversable()).
-
NavigationPointProvider (The Map) The translator.
- Job: Take an (x, y, z) coordinate and return a NavigationPoint.
Let's assume you are building a Voxel game (because of course you are). Your world is a char[][][] array where 'X' is a wall.
Wrapper for your world data.
public class VoxelNavigationPoint implements NavigationPoint {
private final boolean solid;
public VoxelNavigationPoint(boolean solid) {
this.solid = solid;
}
@Override
public boolean isTraversable() {
// If it's solid, we can't walk there. Simple.
return !solid;
}
}This is where the pathfinder asks: "What is at 10, 50, -20?"
public class VoxelProvider implements NavigationPointProvider {
private final char[][][] grid;
public VoxelProvider(char[][][] grid) {
this.grid = grid;
}
@Override
public NavigationPoint getNavigationPoint(PathPosition pos, EnvironmentContext context) {
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
// 1. Safety Check: Don't let the pathfinder read outside your array.
if (isOutOfBounds(x, y, z)) {
return new VoxelNavigationPoint(true); // Treat void as solid wall
}
// 2. Lookup: Read your actual game data
char block = grid[x][y][z];
// 3. Wrap it: Return the interface
return new VoxelNavigationPoint(block == 'X');
}
private boolean isOutOfBounds(int x, int y, int z) {
return x < 0 || x >= grid.length ||
y < 0 || y >= grid[0].length ||
z < 0 || z >= grid[0][0].length;
}
}Tell the engine to use their eyes.
// 1. Your Game Data
char[][][] myWorld = new char[100][100][100];
// 2. Connect the Bridge
PathfinderConfiguration config = PathfinderConfiguration.builder()
.provider(new VoxelProvider(myWorld))
.build();If your logic is simple, don't waste time writing a VoxelNavigationPoint class. NavigationPoint is a functional interface. You can implement it on the fly.
// Look ma, no extra classes!
public class LazyProvider implements NavigationPointProvider {
@Override
public NavigationPoint getNavigationPoint(PathPosition pos, EnvironmentContext ctx) {
// Return a lambda for the NavigationPoint
return () -> {
// Your logic here. Return true if walkable.
return MyGame.getBlock(pos.getX(), pos.getY(), pos.getZ()) != Material.BEDROCK;
};
}
}