Pathetic Java Pathfinding Library

repository·trunk·Indexed 18 days ago

https://github.com/bsommerfeld/pathetic

A high-performance, zero-allocation Java pathfinding library optimized for extreme concurrency and long-distance paths. It provides an asynchronous API via the Pathfinder and PathfindingSearch interface to minimize CPU and memory overhead, making it suitable for demanding environments such as Minecraft servers.

Tokens
1K
Snippets
5
Records
5
Agent score
13%

What's inside Pathetic

  1. Install Pathetic engine

    trunk

    Add the engine artifact to your project dependencies. Use the following coordinates for Maven or Kotlin/Gradle.

    ### Maven
    ```xml
    <dependencies>
        <dependency>
            <groupId>de.bsommerfeld.pathetic</groupId>
            <artifactId>engine</artifactId>
            <version>5.5.2</version>
        </dependency>
    </dependencies>

    Kotlin

    implementation("de.bsommerfeld.pathetic:engine:5.5.2")
  2. Find a path using Pathfinder

    trunk

    To perform pathfinding, use a Pathfinder instance created via a factory. The findPath method is asynchronous and returns an Optional containing the result. You can then use the path to move an entity or handle the case where no path is found.

    Pathfinder pf = factory.createPathfinder(config);
    
    pf.findPath(start, goal, context)
    .ifPresent(result -> {
        moveThatEntity(result.getPath());
    }).orElse(result -> System.out.println("No path found!"));
  3. Check pathfinding status and abort searches

    trunk

    You can monitor the lifecycle of a pathfinding request using these methods:

    • done(): Returns true if the pathfinding operation has completed (successfully or otherwise).
    • abort(): Triggers the abortAction associated with the search to attempt a controlled cancellation of the operation.
    if (!pathfindingSearch.done()) {
        pathfindingSearch.abort();
    }
  4. Handle pathfinding results with PathfindingSearch

    trunk

    The PathfindingSearch interface (implemented by PathfindingSearchImpl) provides an asynchronous API for managing pathfinding operations. You can register callbacks to handle different outcomes of a search without blocking the main thread.

    • Use ifPresent(Consumer<PathfinderResult> callback) to execute logic when a path is successfully FOUND or a FALLBACK path is provided.
    • Use orElse(Consumer<PathfinderResult> callback) to execute logic when the search fails (e.g., FAILED, ABORTED, LENGTH_LIMITED, or MAX_ITERATIONS_REACHED).
    • Use exceptionally(Consumer<Throwable> callback) to handle unexpected errors during the search process.
    • Use abort() to trigger a controlled cancellation of the ongoing search.
    pathfindingSearch
        .ifPresent(result -> System.out.println("Path found: " + result))
        .orElse(result -> System.err.println("Search failed: " + result.getPathState()))
        .exceptionally(ex -> {
            ex.printStackTrace();
            return null;
        });
  5. Retrieve pathfinding results synchronously

    trunk

    If you need to wait for the pathfinding operation to complete before proceeding, use the following methods on a PathfindingSearch instance:

    • resultBlocking(): A blocking call that waits for the search to complete and returns the PathfinderResult. This uses CompletableFuture.join() internally.
    • result(): A non-blocking call that returns an Optional<PathfinderResult>. It returns Optional.empty() if the search is not yet done(), if the future is cancelled, or if an exception occurred during retrieval.
    // Blocking approach
    PathfinderResult result = pathfindingSearch.resultBlocking();
    
    // Non-blocking approach
    Optional<PathfinderResult> optionalResult = pathfindingSearch.result();
    if (optionalResult.isPresent()) {
        // Process result
    }