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

Could you also send your entire code?

1 Like

In a dm, i don’t really want to just send it where someone could steal it

Maybe try switching the while wait() do loop to RunService.Heartbeat and put the functions inside of it? Perhaps, You could also spawn/defer the functions using either task.spawn() or task.defer() — Task spawn will instantly run the code given and don’t yield it, While Task defer will await until the next resumption cycle to run it.

local RunService = game:GetService("RunService")
local Heartbeat = RunService.Heartbeat

Heartbeat:Connect(function()
     -- Bot Code
end)
1 Like

I think I have tried heartbeat, but I’ll try that again and the other ones too and get back to you

1 Like

Could you show what you tried for the repeat loop?

1 Like
while wait() do
	humanoid:MoveTo(playerRoot.Position)
	if (botRoot.Position - playerRoot.Position).Magnitude > 7  then
		break
	end
end

and a repeat loops that does the same thing

It worked the exact same :confused: so weird

runService.Heartbeat:Connect(function()
	if tracking then
		followPlayer()
	else
		patrol()
	end
end)

Is that just an example? Because I don’t see any raycasting on it.

Oh and, use the task library. (task.wait(), task.spawn(), task.defer)

1 Like

Maybe try using task.spawn(), Not sure if it’ll work.

-- RunService Heartbeat
task.spawn(function()
    -- Code
end)
1 Like

It doesn’t repeat the code, so i don’t know

Yeah, I forgot to add the “canSeePlayer” function in there, just pretend that’s in there

Try using an actual repeat until loop instead of a while loop one.

1 Like

I have, it was the same loop as this one just with repeat instead, same result

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)