Npc follow and kill

This code checks if there are players close to an npc and if so, it chases and attacks. Currently he can scan up to 300 enemies without loss of performance. Is there anything that can improve? I really want to optimize it

local folder = workspace.Folder --Folder with enemies
local array = folder:GetChildren()

local deleyBetweenVerifications = 3 
local distanceForChase = 15
local distanceForAttack = 5
local attackDeley = 0.5

local function attack(humanoid, plrHumanoid, part, hrp)
	while humanoid.Health >= 0 and (hrp.Position - part.Position).Magnitude < distanceForChase do		
		humanoid:MoveTo(part.Position, part)
		if (hrp.Position - part.Position).Magnitude < distanceForAttack and plrHumanoid and plrHumanoid.Health >= 0 then

			plrHumanoid.Health = plrHumanoid.Health - 10
		end
		wait(attackDeley)
	end
end

local function Verification()
	while wait(deleyBetweenVerifications) do
		for x = 1, #array do
			
			wait(0.001)
			local hrp = array[x].HumanoidRootPart

			local posX = hrp.Position.X - distanceForChase
			local posY = hrp.Position.Y - 2
			local posZ = hrp.Position.Z - distanceForChase

			local posTable = workspace:FindPartsInRegion3WithIgnoreList(Region3.new(
				Vector3.new(posX - distanceForChase, posY, posZ - distanceForChase),
				Vector3.new(posX + distanceForChase, posY+4, posZ + distanceForChase)), 
				{folder}, --descendants to ignore
				50) -- max of objects that will returned
			
			for z = 1, #posTable do

				local part = posTable[z]

				if part.Name == "HumanoidRootPart" and part.Parent.ClassName == "Model" and part.Parent:FindFirstChildOfClass("Humanoid") then

					local humanoid = array[x].Humanoid
					coroutine.wrap(attack)(humanoid, part.Parent.Humanoid, part, hrp)
				end
			end
		end
	end
end	

spawn(Verification)
2 Likes

Just a few things that I can see so far, I will edit this as I find more things to improve.


Number 1:

You should switch the spawn(Verification) to a coroutine.wrap() function. spawn is not recommended for use because it has a built-in wait() at the beginning. From what I have read in your code, this should be possible.

A good example I found that can explain this is linked here.


Number 2:

The usage of wait(0.001) is unnecessary here, as the lowest you can wait with wait() is 0.03, or to make things simple, just putting wait(). I would recommend editing this here, but you don’t have to do it as it automatically waits 0.03 since that’s what its limited to.

In other news, I would recommend not using wait at all. See here.


Other than that, your code looks good! As of right now I can’t see anything else to improve, but I did say that I would edit this if I find anything else.

1 Like

After this post I changed (improved) the code a lot. I replaced the wait (0.001) with a RunService.Heartbeat:Wait() and made other improvements that ensure the impossibility of errors and delays.

Is there a way to make the code wait less time than a hearbeat but still guarantee the stability of the loop?

1 Like