Repository navigation
Processors and Validators
The pathfinder knows math. It calculates the shortest path. But it doesn't know that your "shortest path" goes through a pool of lava or a locked door.
Processors are how you inject game logic into the search pipeline.
There are two types of logic you can inject:
-
ValidationProcessor (The Bouncer): Decides if a move is allowed. Hard limits.
-
CostProcessor (The Taxman): Decides if a move is expensive. Soft preferences.
This is a binary decision. Yes or No. If any validator in your pipeline says "No", the node is dead. It will strictly not be entered.
Use this for: Walls, locked doors, faction territories, or level restrictions.
Imagine a robot that cannot enter zones marked as "Restricted".
public class RestrictedZoneValidator implements ValidationProcessor {
@Override
public boolean isValid(EvaluationContext context) {
// Check the world data for the current position
Zone zone = MyGame.getZoneAt(context.getCurrentPathPosition());
// If it's restricted, ban this node.
return !zone.isRestricted();
}
}Don't write spaghetti code with nested if statements. Use the Validators utility class to compose complex rules.
-
Validators.allOf(...): AND. All must be true.
-
Validators.anyOf(...): OR. At least one must be true.
-
Validators.noneOf(...): NOR. All must be false.
-
Validators.not(...): NOT. Invert the result.
NodeValidationProcessor doorIsOpen = new OpenDoorValidator();
NodeValidationProcessor hasKey = new KeyInventoryValidator();
// Logic: You can pass if the door is open OR if you have the key.
NodeValidationProcessor canEnter = Validators.anyOf(doorIsOpen, hasKey);This influences the path without blocking it. It adds Virtual Cost to a node. The pathfinder will try to avoid expensive nodes, unless the detour is even more expensive.
Use this for: Mud, water, hills, or "dangerous" areas.
Prefer quiet routes, but take the highway if the quiet route takes 10 minutes longer.
public class TrafficCostProcessor implements CostProcessor {
@Override
public Cost calculateCostContribution(EvaluationContext context) {
Zone zone = MyGame.getZoneAt(context.getCurrentPathPosition());
if (zone.isHighTraffic()) {
// Moving here costs 5x as much as normal movement.
// The robot will avoid this unless it saves significant time.
return Cost.of(5.0);
}
return Cost.ZERO;
}
}Every processor gets a context object. This is your intel.
-
getCurrentPathPosition(): Where are we right now?
-
getPreviousPathPosition(): Where did we come from? (Useful for detecting steep turns).
-
getSearchContext(): Access global data (Start, Target, User Data).
Inject your logic in the configuration.
PathfinderConfiguration config = PathfinderConfiguration.builder()
// Bouncers
.validationProcessors(List.of(
new RestrictedZoneValidator(),
Validators.not(new LavaValidator())
))
// Taxmen
.costProcessors(List.of(
new TrafficCostProcessor(),
new MudCostProcessor()
))
.build();