Repository navigation
Heuristic Strategies
A* works by guessing. It looks at a node and asks: "How far am I probably from the target?"
The Heuristic is the math behind that guess. If the guess is bad, your NPC walks like it's drunk. If the guess is good, it looks intelligent.
The IHeuristicStrategy interface controls this logic. You probably don't need to touch this, but if you do, here is how to mess with the algorithm's brain.
HeuristicStrategies.LINEAR (The Standard)
Calculates the actual Euclidean distance.
-
Pros: The paths look natural and correct.
-
Cons: Uses Math.sqrt(), which is computationally expensive.
-
Verdict: Use this. Unless you are running your server on a toaster, the performance difference is negligible.
HeuristicStrategies.SQUARED (The Speed Demon)
Calculates distances using squared values to avoid the square-root operation.
-
Pros: Faster.
-
Cons: It punishes long distances disproportionately. The path might look slightly "afraid" of open spaces.
-
Verdict: Use this only if you are profiling and desperate for that last 1% of CPU.
You can fine-tune the behavior using HeuristicWeights. This changes what the pathfinder cares about.
-
manhattanWeight / octileWeight Controls the preference for grid-aligned vs. diagonal movement.
-
heightWeight The Cardio Factor. How much does the entity hate climbing?
-
High Value: The path will go around a mountain.
-
Low Value: The path will go straight over the peak.
-
-
perpendicularWeight The Tie-Breaker. This is the secret sauce. In a grid, there are often 100 ways to walk from A to B with the exact same length (zig-zag vs. L-shape). This weight forces the pathfinder to stick to the "ideal line", making movement look robotic and precise rather than random and wobbly.
Imagine a wheeled robot that hates ramps (height) and wants to drive in straight lines (perpendicular), but doesn't care about diagonals.
// 1. Create the bias
HeuristicWeights weights = HeuristicWeights.create(
0.0, // Manhattan (Don't care)
0.0, // Octile (Don't care)
5.0, // Height: I HATE climbing. Go around.
2.0 // Perpendicular: Stay on the line!
);
// 2. Inject it
PathfinderConfiguration config = PathfinderConfiguration.builder()
.heuristicStrategy(HeuristicStrategies.LINEAR)
.heuristicWeights(weights)
.build();If you think you are smarter than Euclidean geometry, you can implement IHeuristicStrategy yourself. This gives you raw control over G-Cost (Movement) and H-Cost (Estimation).
Warning: If your heuristic is "inadmissible" (overestimates the cost), A* is no longer guaranteed to find the shortest path. You have been warned.