Pathfinding Service Bugs Since Late 2021

Description
The pathfinding service is an incredible tool that has allowed me to create Zombie Uprising.
Unfortunately, it has become very buggy in 2022 and 2023, and did not have these issues until then. It has gotten much worse in late 2022 and 2023. This is the biggest issue in my game, and lowers the quality of the game and the player base.

Visual Aids:
Screenshot explanation:

  • The green, numbered cube is where the NPC is moving towards.
  • The grey, numbered cubes are waypoints in the pathfinding route

Pathfinding struggles to:

Other bugs:

  • Waypoints #2 and #3 often have the same position (I use code to compensate for this) (The official pathfinding tutorial recommends using the 2nd waypoint, as the 1st is the path start)

System Information:
The bug seems to be independent of system, happening on all devices

Reproduction Files:
I attached a place file for staff only. It was used to take these screenshots. It has excellent replicability.

Expected behavior
The NPCs should find suitable paths, like they almost always did until about Q1 2022. It has drastically recently.

Note:
The method of making the NPC jump and move has been the same since 2020.
I use:

Humanoid:MoveTo(Waypoint.Position)
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)

A private message is associated with this bug report

12 Likes

Thanks for the report. A ticket was filed to our internal database.

7 Likes

Thank you. Hopefully this can be solved soon.

The issue with the infinite jump loop seems to be that Humanoid:MoveTo() and Humanoid.WalkToPoint are inconsistent.

They usually work, but when they don’t, the NPC becomes stuck because the NPC is jumping, but not moving forward to the correct point.

1 Like

I’ve had some of these issues, but the one that is most relevant is one where the NPC cannot walk through doors.

I’ve also found that using Humanoid:Move is better than Humanoid:MoveTo in almost all cases with pathfinding scripts. NPCs also have unnatural movement and tend to take difficult routes that take longer than what a player would do.

1 Like

Have you tried using a PathfindingModifier volume with the PassThrough property set to true? Official guide has a section about this exact issue:

With the fix, NPCs will still be able to collide with the real door while still being able to pathfinding through it:

npc_walking_through_physics_door.rbxl (78.5 KB)

Sounds sort of like an issue the developer can fix rather than Roblox. Pathfinding is doing what it is supposed to, and finding the fastest path.

Can you explain how?

Could you show a situation where this happens? I think that would help the engineers improve pathfinding, but there are some things you could try.

Have you tried using PathfindingModifiers and the Costs value of the AgentParamaters you pass into CreatePath to try and encourage NPCs to pick better routes? This can be done by setting the cost to be less than one, or even negative:

-- Make any PathfindingModifier with the label "NPCNavPrefer" be
-- 10x less "costly" than any other area
local Path = PathfindingService:CreatePath({
    Costs = {
        NPCNavPrefer = 0.1
    }
})

You could do the opposite as well, make the paths that NPCs usually take have a cost higher than one to encourage them to pick different routes, but you could also try tweaking some AgentParameters like AgentRadius, AgentCanJump, AgentCanClimb.

1 Like

Sorry, I didn’t elaborate. I didn’t have doors in the door frame, the NPCs just could not walk through it.

True, but if you have a map with ledges and the NPC jumps down, it doesn’t drop down. This is one of many issues.

If MoveTo stops early for some reason, the NPC will never reach the path. Additionally, Move will allow the NPC to swim to the destination if underwater.

Here’s one:
pathfindingTakesLongerThanAPlayer.rbxl (64.8 KB)


Why couldn’t the NPC jump down? It could be solved with a modifier (I’d assume). It also jumped for the spawn location, but that was because of my code.

I could do that with my maps, but it would probably be very tedious. Additionally, if it was a terrain map, it would take a lot of parts to make that happen.

1 Like

MoveTo will fire MoveToFinished automatically when the NPC hasn’t reached the target for 8 seconds, but I suppose it cancels the actual move as well (but I haven’t tested, I feel like it continues anyways?). The workaround I used for some of my older projects was to repeatedly call :MoveTo every second, and use a custom distance-to-humanoidrootpart check because I couldn’t figure out how to use :Move at the time.

That is not specific to :Move? I believe :MoveTo really just normalizes the vector and calls :Move under-the-hood. I was able to get an NPC to swim through water with :MoveTo:

But, moving the target too close to the baseplate and therefore under more water caused me to get a NoPath pathfinding error, but using a PathfindingModifier with PassThrough = true covering the entirety of the water fixed it. Not ideal, and not consistent. Roblox, pls fix.

Actually, this problem doesn’t even need any new objects to fix it - pathfinding is just choosing the path which it considers less “costly”. By default, walking on anything costs, say, a dollar. However, jumping costs 4 dollars, quadruple times more expensive than simply walking.

By printing whether or not a waypoint is specifically set to be a “Jump” waypoint by pathfinding, we can see that the path it normally takes requires one jump:

image

Done with the following print:

part.Position = waypoint.Position
part.Anchored = true
part.CanCollide = false
humanoid:MoveTo(part.Position)

print(`Is jump waypoint: {if waypoint.Action == Enum.PathWaypointAction.Jump then "Yes" else "No"}`)
	
part.Parent=workspace.Camera2
part.Name="WaypointObject"

But, if we set the cost of a jump to be the same as walking with the following change:

-- Create the path object
local path = PathfindingService:CreatePath()

→ to →

-- Create the path object
local path = PathfindingService:CreatePath({Costs = {Jump = 1}})

Then, the NPC will take the route you want:

But, it now requires two jumps, something that previously would have costed a massive imaginary eight dollars:

image

I believe this is because most of the time, someone would not want NPCs to randomly jump around, they would want them to jump as little as possible, because usually we do not jump off high ledges in real life instead of taking the stairs. But, Roblox has given us the ability to customize these specific things, so you can always fulfil your dreams of watching NPCs jump off cliffs.

SIDE NOTE: In the place file you shared, the NPC has an Animate script under their character. Unfortunately, it looks like you forgot to convert it from a LocalScript to a regular, server Script. This means that the animations do not play, and the character is stuck in an intimidating default pose :cry:

This script is automatically placed by the Rig Builder, and I didn’t want to spend time beautifying the rig. I do have an animate script in my inventory, but due to a search bug with the toolbox, I was unable to find it. Converting it would take too much time in my opinion.

From what I’ve seen, it’s more complex than that. There’s the Humanoid.WalkToPart property, which is set via MoveTo, which does engine-level calculations to move the humanoid (much faster than calling Move every frame). Additionally, the NPC will stop if the model’s max extents reach the target, which might be problematic for pathfinding (such as a vehicle using pathfinding and having to turn around a corner).

I agree with the rest of your points.