-
-
Notifications
You must be signed in to change notification settings - Fork 0
API Pathfinding & Walking
Eisi05 edited this page Apr 11, 2026
·
2 revisions
NpcAPI supports:
- Computing a
Pathvia A* (PathfindingUtils) - Moving an NPC along that
Path(NPC#walkTo(...))
import de.eisi05.npc.api.pathfinding.Path;
import de.eisi05.npc.api.pathfinding.PathfindingUtils;
List<Location> waypoints = List.of(start, mid, end);
Path path = PathfindingUtils.findPath(
waypoints,
50_000, // maxIterations
true, // allowDiagonalMovement
null // progressListener (segmentIndex, totalSegments)
);Async:
PathfindingUtils.findPathAsync(waypoints, 50_000, true, (i, total) -> {
// progress updates
}).thenAccept(path -> {
// use the path
});import de.eisi05.npc.api.enums.WalkingResult;
npc.walkTo(
path,
0.3, // walkSpeed (clamped 0.1 .. 1)
true, // changeRealLocation
(WalkingResult result) -> {
// SUCCESS or CANCELLED
}
// optionally: viewers...
);Notes:
- Calling
walkTo(...)cancels any current walking task. - Walking is tracked per viewer. Use
npc.isWalking(viewer). - Stop walking via
npc.cancelWalking(viewer).
NpcAPI provides a system to record player movements and replay them on NPCs with precise timing.
import de.eisi05.npc.api.movement.MovementRecorder;
import de.eisi05.npc.api.movement.MovementRecording;
// Start recording a player's movements
long sessionId = MovementRecorder.startRecording(player, 1); // 1 tick = 50ms interval
// ... player moves around ...
// Stop recording and get the data
MovementRecording recording = MovementRecorder.stopRecording(player);import java.io.File;
File file = new File("plugins/NpcApi/recordings/my_recording.dat");
// Save recording to file
recording.saveToFile(file);
// Load recording from file
MovementRecording loaded = MovementRecording.loadFromFile(file);import de.eisi05.npc.api.movement.MovementReplayer;
import de.eisi05.npc.api.objects.NPC;
long replayId = MovementReplayer.startReplay(
npc -> npc, // NPC supplier (can customize NPC before replay)
recording,
1.0, // speedMultiplier (1.0 = normal speed, 2.0 = 2x speed)
true, // changeRealLocation
result -> {
// ReplayResult.COMPLETED, CANCELLED, or ERROR
},
viewer1, viewer2 // viewers who will see the replay
);// Stop by NPC
MovementReplayer.stopReplay(npc);
// Stop by session ID
MovementReplayer.stopReplay(replayId);
// Check if replaying
boolean isReplaying = MovementReplayer.isReplaying(npc);MovementRecorder.RecordingSession session = MovementRecorder.getActiveSession(player);
if (session != null) {
long sessionId = session.getSessionId();
int intervalTicks = session.getIntervalTicks();
long startTime = session.getStartTime();
long duration = session.getDuration();
int movementCount = session.getMovementCount();
List<MovementData> movements = session.getMovements();
}long duration = recording.getDuration();
int movementCount = recording.getMovementCount();
MovementData first = recording.getFirstMovement();
MovementData last = recording.getLastMovement();
UUID playerUUID = recording.playerUUID();MovementData data = recording.movements().get(0);
Location location = data.toLocation(world);
long timestamp = data.getTimestamp();
double x = data.getX();
double y = data.getY();
double z = data.getZ();
float yaw = data.getYaw();
float pitch = data.getPitch();
UUID worldUUID = data.getWorldUUID();
// Time difference between movements
long diff = data.getTimeDifference(otherMovement);Notes:
- Recording uses scheduler-based approach for precise timing (better than PlayerMoveEvent)
- Minimum recording interval is 1 tick (50ms)
- Replay speed multiplier minimum is 0.1x
- NPC is automatically created and deleted after replay completes (unless custom data "movement-replayer" is set to something other than "delete")
- Movements over 10 blocks are teleported, shorter movements use smooth transitions
- Recording and replay are thread-safe