Bot doesn't update quick enough to account for slower player speed

What i tried

		if mag < 7 and canSeePlayer() then
			repeat
				wait()
				mag = (target.Position - botRoot.Position).Magnitude
				humanoid:MoveTo(target.Position)
			until mag >= 7 or not canSeePlayer()
		end

It still did the exact same thing

I just found another devforum post that explains that the issue is latency between the player and the server, they’re looking for a fix so I’ll mark this as solved and leave a link to that post

Post:AI unable to catch up to player - #36 by IAmTheRedGeek

Thank you @Downrest and @MeCrunchAstroX for your help, shame we couldn’t fix it though, but if there’s a solution I’ll @ you with it if you want

1 Like

Alright so, I just looked at the entire script you sent in DMs.

I replicated your entire setup and did a few tweaks. Got some pretty good results, let me show you the changes I did:


To make a faster AI, you gotta make the code faster in itself!

In general, if you want to make something work better, optimize the code itself. The entire script you gave me was clustered with messy while loops which decreased readability and performance in general.

You had about 3 while loops in total, one in the start of the script and two at the end. I basically mashed them all up together into one while loop.

I also did some tweaks to followPlayer() function you had. And just cleaned up some parts of the code.

(I didn’t use the loopWaypoint() function for getting pathfinding waypoints and just went in with a for i,v loop, if you want to use it, just change the code)


local players = game:GetService("Players")

while #players:GetChildren() < 1 do task.wait() end

local bot = script.Parent
local humanoid = bot.Humanoid
local botRoot = bot.HumanoidRootPart
local head = bot.Head

local walk = 12
local run = 16

local gameFolder = workspace:WaitForChild("Game")
local waypointFolder = gameFolder:WaitForChild("Waypoints")

local player = players:GetChildren()[1]
local playerChar = player.Character or player.CharacterAdded:Wait()
local playerHum = playerChar:WaitForChild("Humanoid")
local playerRoot = playerChar:WaitForChild("HumanoidRootPart")

local pathfinding = game:GetService("PathfindingService")
local runService = game:GetService("RunService")
local tracking = false
local countdown = 20
botRoot:SetNetworkOwner(nil)

local function canSeePlayer()
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {gameFolder.Bots, bot}
	params.FilterType = Enum.RaycastFilterType.Blacklist
	local result = workspace:Raycast(botRoot.Position, (playerRoot.Position - botRoot.Position).unit * 30, params)

	if result then
		if result.Instance:IsDescendantOf(playerChar) then
			countdown = 20
			return true
		end
	end
	return false
end

local function getPath(target)
	local pathParams = {
		["AgentHight"] = 9,
		["AgentRadius"] = 2.75,
		["AgentCanJump"] = true
	}
	local path = pathfinding:CreatePath(pathParams)

	path:ComputeAsync(botRoot.Position, target.Position)

	return path
end

local function loopWaypoint(waypoints)
	local int = 3
	if waypoints[int] == nil and int < #waypoints then
		int = #waypoints
		return waypoints[int]
	else
		return waypoints[int]
	end
end

local function followPlayer()
	if playerRoot ~= nil and playerHum.Health > 0 then
		local target = playerRoot
		local path = getPath(target)
		
		if path.Status == Enum.PathStatus.Success then
			for i,v in ipairs(path:GetWaypoints()) do
				local canSee = canSeePlayer()
				
				if canSee == true then
					repeat
						canSee = canSeePlayer()
						humanoid:MoveTo(target.Position)
						task.wait()
					until canSee == false or humanoid.Health == 0 or target == nil
				else
					if v.Action == Enum.PathWaypointAction.Jump then
						humanoid.Jump = true
					end

					humanoid:MoveTo(v.Position)
					local check = humanoid.MoveToFinished:Wait()

					if not check then
						followPlayer()
					end
				end
			end
		end
	end
end

local function patrol()
	local random = math.random(1, #waypointFolder:GetChildren())
	local target = waypointFolder:GetChildren()[random]
	local path = getPath(target)
	local waypoints = path:GetWaypoints()
	if path.Status == Enum.PathStatus.Success then
		if path and waypoints or loopWaypoint(waypoints) then
			for i, waypoint in pairs(waypoints) do
				if waypoint.Action == Enum.PathWaypointAction.Walk then
					if canSeePlayer() then
						return
					end
					humanoid:MoveTo(waypoint.Position)
					humanoid.MoveToFinished:Wait()
					humanoid.Jump = false
				end

				if waypoint.Action == Enum.PathWaypointAction.Jump then
					humanoid.Jump = true
				end
			end
		end
	end
end

local function setup()
	humanoid.WalkSpeed = run
	--[[ADD YOUR EYE CHANGING CODE HERE]]
	countdown -= 1
	task.wait(1)
	if countdown == 0 then
		tracking = false
		countdown = 20
		humanoid.WalkSpeed = walk
		--[[ADD YOUR EYE CHANGING CODE HERE]]
	end
end

task.spawn(function()
	while true do		
		if canSeePlayer() == true then
			task.defer(function()
				setup()
			end)
			followPlayer()
		else
			patrol()
		end	
		task.wait()
	end
end)

Compared the two scripts, and the one I tweaked wasn’t jittering anymore. Hopefully this can help!

I’ll test it out, it definitely looks neater and faster, and I’ll get back to you

It’s still stuttering, the other post explained that that’s because of latency between the client and the server, so it think it’s done moving when actually the player is a bit further away

One of the people in that thread said they’re working on a solution, so I’ll wait and see what that is

1 Like

I see, alright then. Good luck on solving your issue!

1 Like

Thank you, have a good day :yum:! (max chars)