Strata - v1.4.10
    Preparing search index...

    Function createPathfinder

    • Creates a pathfinder using the A* algorithm (NBA* variant).

      A* combines the benefits of Dijkstra's algorithm with a heuristic to guide the search toward the goal, making it faster for most game scenarios. The pathfinder instance can be reused for multiple path queries on the same graph.

      Parameters

      Returns StrataPathfinderInstance

      A pathfinder instance ready to find paths

      import { createGraph, addNode, addEdge, createPathfinder } from '@jbcom/strata/core/pathfinding';

      const graph = createGraph();
      addNode(graph, 'A', { x: 0, y: 0, z: 0 });
      addNode(graph, 'B', { x: 10, y: 0, z: 0 });
      addNode(graph, 'C', { x: 10, y: 0, z: 10 });
      addEdge(graph, 'A', 'B', { bidirectional: true });
      addEdge(graph, 'B', 'C', { bidirectional: true });

      const pathfinder = createPathfinder(graph);
      const result = pathfinder.find('A', 'C');

      if (result.found) {
      console.log('Path found!');
      console.log('Nodes:', result.path); // ['A', 'B', 'C']
      console.log('Positions:', result.positions); // [{ x, y, z }, ...]
      console.log('Total cost:', result.cost); // ~14.14 (distance)
      console.log('Waypoints:', result.nodeCount); // 3
      }
      import { createPathfinder } from '@jbcom/strata/core/pathfinding';

      // Default uses Euclidean distance (good for most cases)
      const standardPathfinder = createPathfinder(graph);

      // Manhattan distance for grid-based movement (no diagonals)
      const gridPathfinder = createPathfinder(graph, {
      heuristic: (from, to) => {
      return Math.abs(to.position.x - from.position.x) +
      Math.abs(to.position.y - from.position.y) +
      Math.abs(to.position.z - from.position.z);
      }
      });

      // Flying units: Ignore Y-axis in heuristic
      const flyingPathfinder = createPathfinder(graph, {
      heuristic: (from, to) => {
      const dx = to.position.x - from.position.x;
      const dz = to.position.z - from.position.z;
      return Math.sqrt(dx * dx + dz * dz);
      }
      });
      import { createPathfinder } from '@jbcom/strata/core/pathfinding';

      // Track which nodes are currently occupied by units
      const occupiedNodes = new Set(['node_5', 'node_12', 'node_23']);

      const pathfinder = createPathfinder(graph, {
      blocked: (nodeData, fromData) => {
      // Don't allow paths through occupied nodes
      // (except we can path TO an occupied node to attack it)
      return occupiedNodes.has(nodeData.position.toString());
      }
      });

      // Update occupiedNodes as units move, pathfinder adapts automatically
      import { createPathfinder } from '@jbcom/strata/core/pathfinding';

      // Each node has a terrain cost multiplier
      const pathfinder = createPathfinder(graph, {
      distance: (from, to, edgeData) => {
      const baseDistance = edgeData.weight ?? 1;
      const terrainCost = to.cost ?? 1;

      // Total cost = distance × terrain difficulty
      return baseDistance * terrainCost;
      }
      });

      // Paths will prefer roads (cost: 0.5) over grass (cost: 1.0)
      // and avoid mud (cost: 3.0) unless it significantly shortens the path
      // For buildings with multiple floors
      const pathfinder = createPathfinder(graph, {
      distance: (from, to, edgeData) => {
      const baseDistance = edgeData.weight ?? 1;

      // Penalize vertical movement (stairs/elevators)
      const verticalChange = Math.abs(to.position.y - from.position.y);
      const verticalPenalty = verticalChange * 2; // Stairs take 2x longer

      return baseDistance + verticalPenalty;
      }
      });

      // Agent will prefer staying on same floor unless necessary
      const pathfinder = createPathfinder(graph);

      // Efficiently reuse pathfinder for multiple queries
      const agents = [
      { id: 'guard1', from: 'node_0', to: 'node_50' },
      { id: 'guard2', from: 'node_10', to: 'node_45' },
      { id: 'enemy1', from: 'node_30', to: 'node_5' }
      ];

      const paths = agents.map(agent => ({
      agentId: agent.id,
      result: pathfinder.find(agent.from, agent.to)
      }));

      paths.forEach(({ agentId, result }) => {
      if (result.found) {
      console.log(`${agentId}: ${result.nodeCount} waypoints`);
      }
      });