The navigation graph to search through
Pathfinder configuration options
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`);
}
});
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.