Where pathfinding fails

Hey all, I want to help my users in my game figure out why their NPCs are failing to find paths. Right now, it’s very ambiguous as my game is a sandbox tycoon where players created their own tycoon using a placement interface. My internal feedback for when an NPC cannot compute a path is just “This npc failed, but IDK why”.

Since my users are confused, they think its the fault of the game, rather, its likely they slipped up and closed off a path.

I have tried path.blocked but this does me no good if it has already been blocked to begin with.

This is my NPC class moveto function, a lot of it may not make sense but what I’m after is the very bottom line where it tells the user a path was not created. I’d like to give them a visual idea of where it failed, preferably by placing a billboard UI at the object that blocked the path.

function npc:MoveTo(cframe,data)
	self.GUID = game.HttpService:GenerateGUID()
	self.LastAction = game.ReplicatedStorage.Time.Value
	if not data then
		data = {
			yield = false,
			aboutToSit = false,
		}
	end
	if typeof(cframe) == "Vector3" then
		cframe = CFrame.new(cframe)
	end
	if (self.ServerPart.Value-cframe.Position).Magnitude <= 2 then
		self:StopMoving()
		return
	end

	if self.PathConnection then
		self.PathConnection:Disconnect()
	end
	local Waypoints = {}

	self.Path = PathfindingService:CreatePath(pathParams)
	self.Path:ComputeAsync(self.ServerPart.Value,cframe.Position)


	self.PathConnection = self.Path.Blocked:Connect(function()
		self:Teleport(cframe.Position)
	end)

	if self.Path.Status == Enum.PathStatus.Success then

		Waypoints = self.Path:GetWaypoints()

		local waitTime = 0
		local tracker = Instance.new("Vector3Value")
		tracker.Value = self.ServerPart.Value
		for i,v in pairs(Waypoints) do
			local distance = (tracker.Value-v.Position).Magnitude
			waitTime += ((distance/16))
			tracker.Value = v.Position
		end
		self:SetState("Walk")

		self:Replicate("Path",Waypoints,cframe,data.aboutToSit)
		local guid = self.GUID

		self.ServerPart.Value = cframe.Position
		task.spawn(function()
			for i=1,#Waypoints do
				task.wait(waitTime/#Waypoints)
				if guid ~= self.GUID then break end
				self.LastAction = game.ReplicatedStorage.Time.Value
			end
		end)
		if data.Yield then
			task.wait(waitTime)
			if self then

				self:StopMoving()
			end
		else

			task.delay(waitTime,function()
				if self then 

					self:StopMoving()
				end
			end)
		end




	else
		
		local distance = (self.ServerPart.Value-cframe.Position).Magnitude
		local notification = require(Knit.Helpers.NotificationCenter)
		if self.Player then
			notification:SendNotification(self.Player,"Path Fail","Direct route taken, make sure your paths are clear.",false)
		end
		task.delay(distance/16,function()
			self:Teleport(cframe)
			self:StopMoving()
		end)
		
	end
end
1 Like

You could just look at what current waypoint the NPC is on and then create a visual representation at the exact spot of the waypoint to highlight where the NPC was blocked.

But if it’s blocked, to begin with, no waypoints exist.

Maybe you can use this:

local YourPath = -- path

if YourPath.Status ~= Enum.PathStatus.Success then

end

or you can use those:

Enum.PathStatus.NoPath -- Path doesn't exist
Enum.PathStatus.ClosestNoPath -- Path doesn't exist returns path to closest point
Enum.PathStatus.Success -- Path found successfully
Enum.PathStatus.ClosestOutOfRae -- Goal is out of MaxDistance range returns path to closest point you can reach within MaxDistance
Enum.PathStatus.FailStartNotEmpty -- Failed to compute path; the starting point is not empty
Enum.PathStatus.FailFinishNotEmpty -- Failed to compute path; the finish point is not empty
1 Like