Skip to content

Processors and Validators

Benjamin Sommerfeld edited this page Jan 29, 2026 · 6 revisions

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.


The Bouncer

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.

Example: "Employees Only"

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();
  }
}

Logic Composition

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);

The Taxman

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.

Example: Avoiding High Traffic

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;
  }
}

Read the Room

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).


Putting it all together

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();

Clone this wiki locally