Searching¶
NavigationService computes a path from a player to a destination. Use it to measure distance,
test reachability, or render a path yourself. To guide a player, use Trips instead.
Running a search¶
import org.cobblestonemc.api.NavigationResult;
import org.cobblestonemc.api.SearchHandle;
import org.cobblestonemc.minecraft.api.MinecraftStepPayload;
import org.cobblestonemc.paper.api.CobblestoneCoreApi;
SearchHandle<Location, MinecraftStepPayload> handle =
CobblestoneCoreApi.navigationService().navigatePlayer(player, destination);
handle.future().thenAccept(result -> {
switch (result) {
case NavigationResult.Success<Location, MinecraftStepPayload> success -> {
Path<Location, MinecraftStepPayload> path = success.path();
log("{} steps, about {}s", path.steps().size(), Math.round(path.duration()));
}
case NavigationResult.Failure<Location, MinecraftStepPayload> failure ->
log("no path: {}", failure.reason());
case NavigationResult.Error<Location, MinecraftStepPayload> error ->
log.warn("search failed", error.throwable());
}
});
import org.cobblestonemc.api.NavigationResult;
import org.cobblestonemc.api.SearchHandle;
import org.cobblestonemc.minecraft.api.MinecraftStepPayload;
import org.cobblestonemc.sponge.api.CobblestoneCoreApi;
SearchHandle<ServerLocation, MinecraftStepPayload> handle =
CobblestoneCoreApi.navigationService().navigatePlayer(player, destination);
handle.future().thenAccept(result -> {
switch (result) {
case NavigationResult.Success<ServerLocation, MinecraftStepPayload> success -> {
Path<ServerLocation, MinecraftStepPayload> path = success.path();
log("{} steps, about {}s", path.steps().size(), Math.round(path.duration()));
}
case NavigationResult.Failure<ServerLocation, MinecraftStepPayload> failure ->
log("no path: {}", failure.reason());
case NavigationResult.Error<ServerLocation, MinecraftStepPayload> error ->
log.warn("search failed", error.throwable());
}
});
Searches always originate at a player, since traversability depends on the player's world, permissions, and abilities.
Regions¶
To target any cell within a box, pass two opposite corners:
The search targets the cheapest reachable cell in the box.
Cancellation¶
Idempotent. If the search is still running, the future completes with FailureReason.CANCELLED.
Cancel searches that are no longer needed.
Settings¶
MinecraftSearchSettings combines algorithm limits with Minecraft-specific exclusions:
MinecraftSearchSettings settings = new MinecraftSearchSettings(
SearchSettings.builder()
.maxCellsVisited(50_000) // cheaper than the server default
.maxWallClockMillis(5_000L)
.heuristicWeight(2.0) // faster, slightly suboptimal
.build(),
Set.of(MinecraftStepType.MINE), // don't route through digging
Set.of(), // excluded world keys
Set.of("the_nether")); // excluded dimensions
navigationService.navigatePlayer(player, destination, settings);
MinecraftSearchSettings.defaults() uses library defaults, not the values in config.yml. Short
queries, such as reachability checks, should set smaller limits.
| Setting | Default | Meaning |
|---|---|---|
maxCellsVisited |
200 000 | Cell limit; a few hundred bytes per cell |
maxWallClockMillis |
60 000 | Time limit |
heuristicWeight |
1.5 | 1.0 is optimal; higher is faster and bounded-suboptimal |
tier1UnsolvedPessimism |
1.5 | Cost multiplier for unsolved route legs |
runningAverageWidth |
5 | Heuristic smoothing window |
Paths¶
record Path<P, T>(P origin, List<Step<P, T>> steps) { }
record Step<P, T>(P position, double cost, double time, T payload) { }
origin: The player's position when the search ran.steps: Positions in order. The last is the destination.cost,time: Per step, not cumulative.path.cost()andpath.duration()compute sums; cache the results.payload: AMinecraftStepPayloadcontaining theMinecraftStepType(WALK,SWIM,FLY,MINE,FALL,CLIMB,BOAT,HORSE,OPEN_DOOR,PLACE_BOAT,MOUNT_HORSE,TELEPORT) and an optionalMinecraftInstruction.
Paths may cross worlds at TELEPORT steps.
Threading¶
- Call
navigatePlayerfrom the server thread. It returns immediately. - The future completes on a Cobblestone worker thread.
- World data is read on the threads the platform requires; no preloading is needed.
Failure reasons¶
| Reason | Meaning |
|---|---|
NO_ROUTE |
No route connects the origin to the destination. |
DESTINATION_UNREACHABLE |
The destination itself is not reachable. |
LIMIT_EXCEEDED |
The cell limit was reached. |
TIMED_OUT |
The time limit was reached. |
CANCELLED |
cancel() was called, or the player disconnected. |
LIMIT_EXCEEDED and TIMED_OUT indicate that no route was found within the limits, not that none
exists.