Pathfinding problem

I am using PathfindingService to make this monster wonder around the map until it’s near a player, then it chases them. I also have code to teleport the monster to an open room if it hasn’t moved a certain amount of studs in a given time (this is incase the monster gets stuck). My problem is after about 2 minutes, the monster starts inching (video 1) instead of smoothly moving (video 2) and I have no idea why.

(Video 1, the teleporting is my code in attempt to unstuck it, but then it gets stuck again)

(Video 2)

At first I thought it was a memory leak, but then I rewrote the code and made sure there were none and it while rewriting it didn’t fix the problem, it did make it better as before, the monster couldn’t last longer than 30 seconds before bugging out.


I’ll also sometimes get this if I leave the game running for too long. There’s no error, it just links to the line where I restart the Pathfinding function. I have no idea what this means

I’m not showing the code, as it’s about 500 lines long and am confident I can fix it myself, I just want to know if anyone else has ran into this problem, so I can narrow down where exactly the problem might be within those 500 lines.

Without code there’s not much we can help you with. By the looks of it, there may just be a memory leak or a recursive pattern that infinitely repeats itself and may cause the monster to lag.

It is a loop as I want the monster to forever wander and seek out players, I just want it to not bug out like that. I’ll see if I can shorten the code so you can see what I’m doing.

I tried my best to break this down as much as I could so you can quickly skim through it to see if you can find any potential memory leaks
Let me know if you have any questions

-- Moves monster to chase people, this is a module script
function MONSTER.Move()
	-- Variables you'll see used, you should be fine ignoring these
	local PATH = PATH_FINDING:CreatePath{
		AgentRadius = 1,
		AgentHeight = 1,
		AgentCanJump = true,
		WaypointSpacing = 2,
		Costs = {}
	}
	local WAYPOINTS
	local NEXT_WAYPOINT_INDEX
	local REACHED_CONNECTION
	local BLOCKED_CONNECTION
	local lastCheckStuck = {tick(), nil}
	local lastDesitinationRoom
	local lastDesitinationSpawn
	local lastChasedPlayer
	
	-- Picks a random spawn point farthest from any players and moves the monster there
	local function MoveToSpawn()
	end

	-- Check if there is a close player, if not, check if there is a current destination, if not, find a random room to wander to
	local function GetDestination(destination, stuck)
		-- Loops through all players and checks if one is in range of monster to chase them
		
		if (no close player and monster isnt stuck) then
			-- Find a random room to wander to
		elseif (no close player and a current destination) then
			-- Continue on to room
			return destination, true
		end

		return position of player or the new random room
	end
	
	-- Main loop, creates waypoints and moves the monster to them
	local function FollowPath(destination)
		task.wait()
		-- Determine whether to continue wandering, find a new room to wander to, or chase a player
		local continuing = nil
		destination, continuing = GetDestination(destination)
		local humanoid -- Monster's humanoid
		local rootPart -- Monster's root part

		local success, errorMessage = true, nil
		if (not continuing) then -- If a new room or new player to chase
			-- Compute path
			success, errorMessage = pcall(function()
				PATH:ComputeAsync(rootPart.Position, destination)
			end)

			-- If found a path
			if (success and PATH.Status == Enum.PathStatus.Success) then
				WAYPOINTS = PATH:GetWaypoints()

				if (BLOCKED_CONNECTION) then
					BLOCKED_CONNECTION:Disconnect()
				end

				BLOCKED_CONNECTION = PATH.Blocked:Connect(function(blockedWaypointIndex)
					if (blockedWaypointIndex >= NEXT_WAYPOINT_INDEX) then
						-- Disconnect all events
						-- Basically stop whatever it is doing right now
						-- You'll see this a lot, anywhere you see 'restart' I'm doing this
						REACHED_CONNECTION:Disconnect()
						BLOCKED_CONNECTION:Disconnect()
						WAYPOINTS = nil
						NEXT_WAYPOINT_INDEX = nil
						REACHED_CONNECTION = nil
						BLOCKED_CONNECTION = nil
						destination = nil
					end
				end)

				if (not REACHED_CONNECTION) then
					REACHED_CONNECTION = humanoid.MoveToFinished:Connect(function(reached)
						if (reached and if there is a next waypoint) then
							-- Move to next waypoint
							-- I do have code here to jump if need to jump
						else
							-- Reached destination

							-- Restart
						end
					end)
				end

				NEXT_WAYPOINT_INDEX = 2
				-- I do have code here to jump if need to jump
				if (if monster is higher than 23) then
					-- If the monster somehow ends up on top of the map, move to a spawn and restart
					MoveToSpawn()
				elseif (been more than 3 seconds since last checking) then -- Check how long it's been since last checking
					-- Check how far the monster has traveled
					if (movedSince < 20) then
						-- Stuck, move to a spawn and restart
						MoveToSpawn()
					end
					-- Time and position for next time
					lastCheckStuck = {tick(), MONSTER_OBJ.PrimaryPart.Position}
				end
				-- Move to next waypoint
			else
				-- No success
				warn("Path not computed!", errorMessage)
				destination = nil
			end
			
			-- Do everything again
			FollowPath(destination)
		else
			-- This runs when there is no new destination and the monster is continuing to a random room or player
			if (monster is below the map) then
				-- If monster fell out of the map

				-- Restart

				MoveToSpawn()
			elseif (monster is higher than 20) then
				-- Again if monster is on top of the map

				-- Restart

				MoveToSpawn()
			elseif (been longer than 3 seconds since last checking and lastCheckStuck[2]) then
				-- Check how far the monster has moved
				if (movedSince < 20) then -- Check how long it's been since last checking
					-- Move to a spawn and restart
					-- Restart

					MoveToSpawn()
				end
				
				-- Time and position for next time
				lastCheckStuck = {tick(), MONSTER_OBJ.PrimaryPart.Position}
			end
			
			-- Do everything again
			task.wait()
			FollowPath(destination)
		end
	end
	task.spawn(function()
		-- Start everything
		FollowPath()
	end)
	return
end