Skip to content
Benjamin Sommerfeld edited this page Nov 20, 2025 · 3 revisions

Separate from the logic pipeline, Pathetic provides a system for observing the search in real-time.

Unlike Processors, which actually do work (like calculating costs or blocking nodes), Hooks are just spectators. They sit in the stands, watch the algorithm run, and report back. They cannot change the path.


When to Use a Hook

Hooks run frequently. Use them for diagnostics, not game logic.

  • Visualization: The #1 use case. Draw particles in your game world to show exactly which nodes A* is exploring. Great for debugging why your NPC is acting drunk.

  • Metrics: Count how many nodes were visited to find a path.

  • Sanity Checks: Log progress if a search takes suspiciously long.

[!WARNING] Performance Impact: Hooks are executed for every single step of the algorithm. If your hook does heavy math or I/O (like database calls), your pathfinding speed will drop to zero. Keep it lightweight.


Implementation

1. The Listener

Create a class that implements PathfinderHook. The onPathfindingStep method fires every time the algorithm expands a node.

public class DebugParticleHook implements PathfinderHook {

    @Override
    public void onPathfindingStep(PathfindingContext context) {
        // Get the position currently being looked at
        PathPosition pos = context.getPosition();
        int depth = context.getDepth().getValue();
        
        // Pseudocode: Spawn a particle in your game world
        // MyGame.spawnParticle(pos.getX(), pos.getY(), pos.getZ(), Color.RED);
        
        // Or just log it (RIP your console)
        // System.out.println("Checking: " + pos);
    }
}

2. The Registration

Attach the hook to the engine. You can register multiple hooks if you want.

// 1. Create the engine
Pathfinder pathfinder = myFactory.createPathfinder(config);

// 2. Attach the spy
pathfinder.registerPathfindingHook(new DebugParticleHook());

// 3. Run the search (The hook will fire hundreds/thousands of times now)
pathfinder.findPath(start, end);

Clone this wiki locally