Improving Pathfinding Quality With New Algorithm

lets hope that the moderation is next to get improved :- :clap:

1 Like

FINALLY! I’ve always had a knack with Roblox pathfinding. Incredible work guys

2 Likes

A big issue here is Documentation and people not being able to understand how to do something. I’m not sure of all the answers, but I do know there’s a lot to read to get familiar with it.

A video about Pathfindining by @DucksAreYeIIow and the team behind the recent LevelUp videos would be awesome! Making a project/video showing each step to make pathfinding work in different scenarios would be helpful. Of course, that production is made difficult with differing versions.

7 Likes

robloxapp-20241115-0023361.wmv (348.7 KB)
It wont let me upload in mp4 format but this is what happens to me

1 Like

This isn’t directly related to Pathfinding, but I have a quick question. When moving the Humanoid from point to point, it micro-stops, causing the animation script (Default Animation Script on all characters, Server Script ) to stop the walking animation and restart it at the next waypoint.

How can I fix this? (Ownership of parts is server) (Yes I am using MoveToFinished as well but happens as well with just polling)

Also great work! I am already using the ClosestPath feature.

3 Likes

Wow! You guys just made this Pink Bearded dev extremely happy!
I cannot wait to use this new algorithm for pathfinding in our projects :smiley:

1 Like

hold up, the update is fire!?!?!? this is awesome sauce!

Just don’t move through all the waypoints. I don’t think returning partial paths will really give better performance, because currently they return the closest one, which means all options have been exhausted. They’d still have to calculate the closest path or a full path to give you a partial, because otherwise it may as well be an entirely random set of waypoints.

1 Like
local function followPath(destination)
	-- Compute the path
	local success, errorMessage = pcall(function()
		path:ComputeAsync(character.PrimaryPart.Position, destination)
	end)

	if success and path.Status == Enum.PathStatus.Success then
		-- Get the path waypoints
		waypoints = path:GetWaypoints()

		-- Detect if path becomes blocked
		-- some code

		-- Detect when movement to next waypoint is complete
		if not reachedConnection then
			reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					-- Increase waypoint index and move to next waypoint
					nextWaypointIndex += 1
					humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end

		-- Initially move to second waypoint (first waypoint is path start; skip it)
		nextWaypointIndex = 2
		humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	else
		warn("Path not computed!", errorMessage)
	end
end
while wait() do
	followPath(workspace.Target.Position)
end

This code could potentially lead to complex states due to its frequent calls to ComputeAsync and connections to MoveToFinished. There might be multiple instances of MoveToFinished:Connect existing concurrently, which can result in the MoveToFinished event moving the NPC backward during navigation.

Notably, the official tutorial does not recommend calling followPath within a while do loop.
Could you disconnect the previous MoveToFinished connection at the start of followPath with the following code:

if reachedConnection then
    reachedConnection:Disconnect()
end

Additionally, to reduce the frequency of ComputeAsync calls and potentially mitigate excessive event firing, consider adjusting the loop to execute less frequently, such as every 0.3 seconds:

while wait(0.3) do
    followPath()
end
4 Likes

This is a good feedback. We will think about it.

6 Likes

Not moving through all the waypoints isn’t ideal, that means there are a lot of calculated waypoints that go completely unused.

There’s actually a way to implement pathfinding with estimate / approximation and it can work surprisingly good.

It’s able to navigate through hallways and buildings, it just doesn’t do well in mazes obviously since those have a way more complex layout but that’s the point, it’s supposed to not be perfect.

With a partial path function, you could essentially tell it “go calculate a path until you reach 20 waypoints, then stop abruptly”.

20 waypoints would still be enough to navigate around objects and obstacles, just not enough waypoints to get out of a maze.

But instead of calculating a long path and throwing away waypoints (waste of performance), instead we don’t calculate the waypoints at all.

And no, this will not result in completely random paths, it’s called APPROXIMATION for a reason.

You calculate a path that is SOMEWHAT accurate, just not entirely.
And this CAN actually lead to slight performance improvement.

Sure that’s all well and good, but at the end there’s nothing to prevent pathfinding straight into a dead end that was not a path at all. Seems like a feature with few use cases. I wouldn’t worry about the performance, you can easily run hundreds of NPC’s with zero problem, just offset their path computation and replicate the NPCs without humanoids.

Yes, we still use A*, but we have improved a few heuristics and the waypoint offset logic. Additionally, a lot of effort has gone into fixing navmesh-related issues. It’s not necessarily a new navmesh algorithm, but an improved one.

6 Likes

The initial point of this mini-feature request was to save a lot of work, and I figured that it might not be that hard to make it a built-in feature since one would simply have to stop computations early and it already is capable of returning unfinished paths.

Sure I can make this my own, but then I’ve basically have to rewrite pathfinding and come up with an own algorithm from scratch to achieve the same thing.

(I already did come up with my own algorithm but actually coding it is kind of a pain and rather time consuming.)

Finally! This was so very necessary.

1 Like

Is there any chance we ever get access to the navmesh? I’m currently using A* with nodes, and it would be nice to be able to keep my heuristics while still getting the benefits of more fine grained and dynamic pathfinding. It’s just much easier to write complex agent behavior when you can make choices. Not hoping for any manipulation of the mesh or anything, I just want it exposed and readable.

4 Likes

This is something we are discussing internally. We have heard that developers wanted navmesh access to fix issues themselves. With these improvements, we sincerely believe that should no longer be necessary. In cases where the navmesh is still problematic, we will treat it as a bug and fix it.

That said, there are scenarios where developers might want to query the navmesh, such as getting the closest point on the navmesh or performing a raycast on it. We are exploring options to see if those functionalities can be exposed, but nothing can be promised yet. If I understood your request correctly, you are more interested in accessing those APIs rather than the actual navmesh?

12 Likes

I have few questions:

  1. Will agent jump height be ever exposed so that we can control it? Right now I think it might be tied to the agent height.
  2. Will navigation mesh generation be improved for meshes? Last time I checked, it kept failing to generate proper nav mesh for a structure in my game and I was forced to place invisible collidable parts to fix it.
  3. Will we get an ability to disable Humanoid behavior so that pathfinding won’t exclude models that have it, and get an instance that makes its parent model get excluded from pathfinding?
  4. Will we get an ability to generate alternative paths? Sometimes I want have my monster take an alternative path, not always the shortest.
7 Likes

would it be possible to be given direct access to the generated navmesh as well? navmesh generation is hard so being able to use it for any custom pathfinding implementations would be very helpful

6 Likes

I’d be most interested in accessing the navmesh directly as a set of nodes or however it’s setup, so that I can run a pathfinding algorithm on it.

3 Likes