Skip to content

API Pathfinding & Walking

Eisi05 edited this page Apr 11, 2026 · 2 revisions

NpcAPI supports:

  • Computing a Path via A* (PathfindingUtils)
  • Moving an NPC along that Path (NPC#walkTo(...))

Compute a path

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
});

Walk the NPC

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).

Movement Recording & Replay

NpcAPI provides a system to record player movements and replay them on NPCs with precise timing.

Record Movements

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);

Save & Load Recordings

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);

Replay Movements on NPC

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 Replay

// Stop by NPC
MovementReplayer.stopReplay(npc);

// Stop by session ID
MovementReplayer.stopReplay(replayId);

// Check if replaying
boolean isReplaying = MovementReplayer.isReplaying(npc);

Recording Session Info

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();
}

Movement Recording Info

long duration = recording.getDuration();
int movementCount = recording.getMovementCount();
MovementData first = recording.getFirstMovement();
MovementData last = recording.getLastMovement();
UUID playerUUID = recording.playerUUID();

Movement Data

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

Clone this wiki locally