ParallelPath
Parallel Luau pathfinding with zero MoveToFinished stutter
GitHub · Documentation · Wally
What is this?
ParallelPath is a pathfinding library for humanoids, vehicles, and custom rigs. It’s designed as a production-ready alternative to SimplePath that eliminates the most common cause of NPC movement jitter and adds parallel path computation via Actors.
The problem with MoveToFinished
If you’ve ever used Humanoid:MoveTo() with the MoveToFinished event for waypoint advancement, you’ve seen the stutter. The event fires on the server after the client has already moved past the waypoint. That tiny delay compounds across dozens of waypoints and creates visible jitter in smooth movement.
ParallelPath replaces MoveToFinished entirely with a Heartbeat distance-polling loop, borrowed from Roblox’s own ClickToMove controller. Every RunService.Heartbeat, the agent checks how close the model is to the current waypoint. When it’s within range, the next waypoint is queued immediately — no round-trip latency, no stutter.
Features
Heartbeat polling
No MoveToFinished. Waypoints advance the frame the model arrives, not a tick later.
Parallel path computation
Path requests run inside Actor-isolated Parallel Luau workers. Multiple agents compute paths simultaneously without touching the main thread.
Three steering modes
| Mode | When to use |
|---|---|
Humanoid |
NPCs, monsters, animated characters |
Vehicle |
Cars and tanks — PID-controlled steering |
Custom |
BodyVelocity, TweenService, AnimationControllers, anything else |
Built-in stuck detection
If an agent hasn’t moved for 3 seconds, it automatically attempts a recovery jump (humanoids) or fires a Stuck signal. Timeout and recovery strategy are configurable.
Failsafe hierarchy
On path failure: retry → partial path to nearest reachable node → optional direct steering fallback → Failed signal with a reason code.
No external dependencies
Signal and Promise are bundled. Drop it in and go.
Installation
Add to your wally.toml:
[dependencies]
ParallelPath = "metricrb/parallel-path@0.1"
Run wally install.
Quick start
local ParallelPath = require(game:GetService("ReplicatedStorage").Packages.ParallelPath)
local Agent = ParallelPath.Agent
local Scheduler = ParallelPath.Scheduler
-- Initialise once at game startup — spins up 4 Actor workers
Scheduler.init(4)
-- Create an agent for a humanoid NPC
local agent = Agent.new(workspace.MyNPC, {
steeringMode = "Humanoid",
})
-- Move
agent:MoveTo(workspace.Target.Position)
-- Events
agent.Reached:Connect(function(model, waypoint)
print("Reached target!")
end)
agent.Failed:Connect(function(model, reason)
warn("Movement failed:", reason)
end)
Performance notes
- Humanoid NPCs: 2–3× smoother waypoint transitions from Heartbeat polling
- 10+ simultaneous agents: 5–10× faster path computation with parallelisation
- Vehicles: Pathfinding support that SimplePath doesn’t offer at all
- Memory: Slightly higher due to Actor overhead — negligible at typical NPC counts
Issues, PRs, and feedback welcome on GitHub.