Can PathfindingService fail?

I want to know if PathfindingService can fail, or has received any updates that could result in failure. I apologize if I’m posting in the wrong area, but this felt the only place apt where I have the ability to post.

Recently, I’ve been noticing the enemies in one of my testing games begin to collectively, intermittently, stop moving. For reference, I use SimplePath - Pathfinding Module to do my pathfinding, and employ a combination of its loops and events to go from A to B, chasing the player.

The number of AI is typically between 5 and 15, but regardless of number of AI, they’ll suddenly stop, before also collectively agreeing to begin working again, in spite of good ping.

I’ve noticed this occurring in other games where I suspect PathfindingService to be employed, like WW2 Zombie Survival, where the AI will perform flawlessly with no observable slowdowns before collectively stopping altogether, and some length of time will transpire before they work again.

I hope to understand whether I have agency over this problem or not, or see if anyone else has similar issues.

2 Likes

Are they all targeting you? Are you sure you’re not just temporarily in a spot PathfindingService thinks is unreachable?

1 Like
  1. Are they all targeting you?
    Yes.

  2. Are you sure you’re not just temporarily in a spot PathfindingService thinks is unreachable?
    Yes.

The video here demonstrates my current woes. This enemy is scripted on a looped Path:Run(Goal) in the context of SimplePath. Checking the console reveals that an error lies in this block, at self._humanoid:MoveTo(self._waypoints[self._currentWaypoint].Position) and #self._waypoints == 2 then, which would mean that the waypoints either did not calculate, or the path itself no longer exists. I notice that when this happens, a lot of these errors appear, but I don’t understand the reason why these failures happen only simultaneously across multiple AI.

if self._humanoid then
		self._humanoid:MoveTo(self._waypoints[self._currentWaypoint].Position)
	elseif #self._waypoints == 2 then
		self._target = nil
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		self._events.Reached:Fire(self._agent, self._waypoints[2])
	else
		self._currentWaypoint = getNonHumanoidWaypoint(self)
		moveToFinished(self, true)
	end

Without discrediting GrayZcale and their work, it is also true that this module is a couple of years old. However, throughout them, the module has worked nigh-flawlessly until now, which I would take to imply as a change in PathfindingService in that timeframe.

1 Like

The only possibility I can think of, is that Path:GetWaypoints has a new bug that causes it to occasionally return nil. According to the Documentation,

, even if the path fails to be computed, it shouldn’t return nil.

Also, in your video, the error says it’s coming from like 364, but on the latest version of SimplePath (from March of 2022), the Module is only 350 lines long:

And, for the elseif #self._waypoint == 2 then code to be reached, you would have to have a non-Humanoid NPC. Is it? But, these are more secondary questions, not really related to your actual issue.

Anyway, you can report this as a bug. The only way for self._waypoints to be nil, would be for Path:GetWaypoints to return nil, and there was recently a bug report for PathfindingService causing a crash, so maybe there have been some internal changes and this new bug slipped through the cracks.

As a workaround, you can add an additional condition to the SimplePath code, and change this block of code:

--Begin pathfinding
if self._humanoid then
	self._humanoid:MoveTo(self._waypoints[self._currentWaypoint].Position)
elseif #self._waypoints == 2 then
	self._target = nil
	self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
	self._events.Reached:Fire(self._agent, self._waypoints[2])
else
	self._currentWaypoint = getNonHumanoidWaypoint(self)
	moveToFinished(self, true)
end

, to this:

--Begin pathfinding

-- If `_waypoints` is `nil` due to the `Path:GetWaypoints` bug,
if not self._waypoints then
	-- , create our own waypoints list directing the NPC
	-- to just move in a straight line to their target
	self._waypoints = {
		PathWaypoint.new(
			self._agent.PrimaryPart.Position,
			Enum.PathWaypointAction.Walk
		),
		-- A Jump waypoint to our target position
		-- `Enum.PathWaypointAction.Jump` could be changed to
		-- `Enum.PathWaypointAction.Walk` if you don't want the 
		-- agent to jump
		PathWaypoint.new(
			(typeof(target) == "Vector3" and target) or target.Position),
			Enum.PathWaypointAction.Jump
		)
	}
end

if self._humanoid then
	self._humanoid:MoveTo(self._waypoints[self._currentWaypoint].Position)
elseif #self._waypoints == 2 then
	self._target = nil
	self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
	self._events.Reached:Fire(self._agent, self._waypoints[2])
else
	self._currentWaypoint = getNonHumanoidWaypoint(self)
	moveToFinished(self, true)
end

Check for errors before running, I just wrote this out in the DevForum Reply Editor thing, I didn’t test it out.

1 Like

I see. It must have slipped my eyes when I was reviewing the documentation again. Regarding the video, I checked the module I used and the SimplePath module and compared the two; the extra lines came from a number of comments I made.

Thank you for your help and insight.

1 Like