Skip to main content

Overview

OpenFront implements multiple pathfinding algorithms optimized for different terrain types and use cases. The system is built around a flexible adapter pattern that allows different algorithms to be composed with transformers for enhanced functionality.

Architecture

The pathfinding system is organized into several layers:
  • Algorithms: Core pathfinding implementations (A*, BFS, Hierarchical)
  • PathFinders: Domain-specific pathfinding interfaces
  • Transformers: Composable path enhancement layers
  • Steppers: Animated path traversal for UI

PathFinder Interface

All pathfinding algorithms implement a common interface:
T | T[]
Starting position(s). Multiple starts enable multi-source pathfinding.
T
Target destination position.
T[] | null
Array of positions forming the path, or null if no path exists.

A* Algorithm

The core A* implementation uses an adapter pattern for flexibility:
src/core/pathfinding/algorithms/AStar.ts

Performance Optimizations

The A* implementation uses several optimization techniques:
  • Stamping: Avoids array clearing by using generation stamps
  • Typed Arrays: Uses Int32Array/Uint32Array for cache-friendly access
  • Buffer Reuse: Neighbor buffer allocated once, reused across searches
  • Bucket Queue: O(1) priority queue for integer priorities

Breadth-First Search (BFS)

BFS is used for unweighted searches and area exploration:
src/core/pathfinding/algorithms/BFS.ts

Visitor Pattern

BFS uses a visitor pattern for flexible search termination:
  • Return R: Found target, return result immediately
  • Return undefined: Valid node, continue exploring
  • Return null: Invalid node, skip but continue search

PathFinding Factory

The PathFinding class provides convenient factory methods for different terrain types:
src/core/pathfinding/PathFinder.ts

Terrain-Specific Pathfinding

Water Pathfinding

Water pathfinding uses hierarchical pathfinding for large maps:
  • Component Check: Verifies start/goal are in same water body
  • Smoothing: Reduces path zigzagging
  • Shore Coercing: Keeps ships near coastlines when beneficial
  • Mini Map: Operates on downscaled map for performance
Hierarchical Pathfinding Algorithm (HPA*) divides the map into clusters with gateway nodes, dramatically reducing search space for long-distance paths.

Rail Pathfinding

Rail pathfinding operates on the rail network graph:

Air Pathfinding

Air units use simplified pathfinding:
  • No terrain blocking: Can fly over any tile
  • Direct paths: Minimal pathfinding overhead
  • Range constraints: Limited by fuel/range

Path Transformers

Transformers wrap pathfinders to enhance functionality:

ComponentCheckTransformer

Early rejection for unreachable goals:

SmoothingWaterTransformer

Reduces path zigzagging for more natural ship movement:

MiniMapTransformer

Maps between full resolution and downscaled pathfinding:
Mini maps are typically 4x-8x smaller than full maps, providing significant performance improvements for long-distance pathfinding.

Stepping PathFinders

Stepping pathfinders enable animated path traversal for UI:

Usage Example

Performance Considerations

Optimization Techniques

  1. Stamp-based Visited Sets: Avoid clearing large arrays
  2. Typed Arrays: Cache-friendly memory layout
  3. Mini Maps: Reduce search space for long paths
  4. Component Analysis: Early rejection of impossible paths
  5. Buffer Reuse: Single allocation for neighbor queries

Iteration Limits

Iteration limits prevent pathfinding from hanging on extremely complex queries or bugs. For very large maps, the limit may need adjustment.