@rbxts/path
v1.0.5
Published
A TypeScript wrapper for Roblox's PathfindingService
Maintainers
Readme
@rbxts/path
A TypeScript wrapper for Roblox's PathfindingService with async/await support, robust error handling, and a built-in Finite State Machine (FSM) for advanced path state management. Includes utilities for pathfinding, waypoint manipulation, and a SmartPath class with automatic retry and recovery.
Features
- Async/await path computation
- Finite State Machine for path state transitions and events
- SmartPath: automatic retry and recovery on failure/blockage
- Utility functions for distance, waypoints, and performance estimation
- TypeScript types for all core concepts
Installation
npm i @rbxts/pathUsage
Basic Pathfinding
const path = new Path();
async function computePath() {
const status = await path.computeAsync(startPos, endPos);
if (status === PathStatus.Success) {
const waypoints = path.getWaypoints();
if (!waypoints || waypoints.size() === 0) {
print("No waypoints found in the computed path.");
return;
}
for (const waypoint of waypoints) {
const targetPos = waypoint.position;
humanoid.MoveTo(targetPos);
const moveStatus = await new Promise<boolean>((resolve) => {
const connection = humanoid.MoveToFinished.Connect((reached) => {
connection.Disconnect();
resolve(reached);
});
});
if (!moveStatus) {
print(`Failed to move to waypoint at ${targetPos}`);
return;
}
}
}
path.destroy();
}
computePath();Using the Finite State Machine
import { Path, PathState, PathStatus } from "@rbxts/path";
const path = new Path(
{},
{
onStateChanged: (oldState, newState) => print(`State changed: ${oldState} → ${newState}`),
onWaypointReached: (waypoint, index) => print(`Reached waypoint ${index}`),
onPathCompleted: () => print("Path completed successfully!"),
onPathFailed: (reason) => warn(`Path failed: ${reason}`),
onPathBlocked: () => warn("Path blocked!"),
},
);
async function computePathWithFSM() {
const status = await path.computeAsync(startPos, endPos);
if (status === PathStatus.Success) {
path.startFollowing(humanoid);
while (path.getState() === PathState.Following) {
task.wait(0.1);
}
const finalState = path.getState();
if (finalState === PathState.Completed) {
print("Successfully reached destination!");
} else if (finalState === PathState.Failed) {
print("Path following failed");
} else if (finalState === PathState.Blocked) {
print("Path was blocked");
}
}
path.destroy();
}
async function advancedExample() {
await path.computeAsync(startPos, endPos);
if (path.isSuccess()) {
path.startFollowing(humanoid);
task.wait(3);
path.pause();
print(`Paused - State: ${path.getState()}`);
task.wait(2);
path.resume(humanoid);
print(`Resumed - State: ${path.getState()}`);
}
}
computePathWithFSM();SmartPath: Automatic Retry
import { SmartPath, PathStatus } from "@rbxts/path";
async function smartPathExample() {
const smartPath = new SmartPath(
{},
{},
{
maxRetries: 5,
retryDelay: 1,
useExponentialBackoff: true,
},
);
const status = await smartPath.computeAsync(startPos, endPos);
if (status === PathStatus.Success) {
smartPath.startFollowing(humanoid);
print("SmartPath started - will auto-retry if blocked!");
} else {
print(`Initial path computation failed: ${status}`);
}
}
smartPathExample();Utilities
import { PathfindingUtils } from "@rbxts/path";
const exists = await PathfindingUtils.pathExists(start, finish);
const distance = await PathfindingUtils.getPathDistance(start, finish);
const waypoints = await PathfindingUtils.getWaypoints(start, finish);API Reference
Path: Main pathfinding classSmartPath: Path with retry/recoveryPathFSM: Finite State Machine for path statesPathfindingUtils: Utility functions- Types & Enums:
PathOptions,PathState,PathStatus,Waypoint, etc.
License
MIT
Contributions
Contributions are welcome (and encouraged)! Please feel free to submit a Pull Request. I am newer to rbxts package creation and would appreciate all recommendations!
