NPC shoots slower when there are multiple NPCs

So I have an NPC that shoots at other NPCs but as the number of NPCs increases, it shoots slower than ever.
Edit: Added the videos

I am a novice scripter so If I approached this horribly you can tell me that.

The npc is shooting with a delay randomly chosen between 0.1 and 0.15 but somehow when there are more than one NPC it shoots slower.

When there is only 1 NPC, it shoots at the desired speed. I will call this NPC the “initial” NPC(Will explain further down)

When there is a bunch of NPCs but shooting at the newer duplicated NPC:

When there is a bunch of NPCs again but now shooting first at the “initial” NPC:

The code doing the work:

while true do
	generateNewRandom() -- Recall a random number for firerate
	wait(firerate)
	local checkRay = Raycast.raycast(pointer, range) -- Check Raycasting
	local target = findTarget(hrp.Position) -- Check target
	local waypoints = path:GetWaypoints()
	if target then
		if path.Status == Enum.PathStatus.Success then
			for i, v in pairs(waypoints) do
				if(target.Position - hrp.Position).Magnitude < range then
					if target.Parent.Humanoid.Health > 0 then
						if checkRay then -- If target is in view
							shoot(target) -- Look and shoot at target
						else
							human:MoveTo(waypoints[2].Position)
						end
					end
					break
				end
				human:MoveTo(waypoints[4].Position)
			end
		end
	end
end

The generateNewRandom() function:

local firerate -- Global variable
function generateNewRandom()
	firerate = newRandom:NextNumber(.1,.15)
end

The findTarget() function:

function findTarget(pos)
	local detectRange = 10000
	local target
	for i, v in pairs(workspace:GetChildren()) do
		local model = v:IsA("Model")
		if model then
			local faction = v:FindFirstChild("Faction")
			if faction then
				if faction.Value ~= myFaction.Value then
					local humanofnpc = v:FindFirstChild("Humanoid")
					local hrpofnpc = v:FindFirstChild("HumanoidRootPart")
					if humanofnpc and hrpofnpc and humanofnpc.Health > 0 then
						if (pos - hrpofnpc.Position).Magnitude < detectRange then
							target = hrpofnpc
							detectRange = (pos - hrpofnpc.Position).Magnitude
							path:ComputeAsync(pos, target.Position)
						end
					end
				end
			end
		end
	end
	return target
end

The shoot() function:

function shoot(target)
	local bullet = Instance.new("Part")
	local bv = Instance.new("BodyVelocity")
	local pointlight = Instance.new("PointLight")
	pointlight.Range = 8
	pointlight.Brightness = 2
	pointlight.Color = Color3.new(1, 1, 0)
	pointlight.Shadows = true
	hrp.CFrame = CFrame.lookAt(hrp.Position, target.Position)
	bullet.Anchored = false
	bullet.Color = Color3.new(1, 1, 0)
	bullet.Velocity = pointer.CFrame.LookVector * bulletspeed
	bullet.Size = Vector3.new(.1,.1,1)
	bullet.Position = pointer.Position
	bullet.Material = Enum.Material.Neon
	bullet.CFrame = pointer.CFrame
	bv.Velocity = bullet.Velocity
	bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
	bv.P = math.huge
	pointlight.Parent = bullet
	bv.Parent = bullet
	bullet.Parent = workspace
	debris:AddItem(bullet, bulletDuration)
	shootanim()
	shootsound()
	bullet.Touched:connect(function(hit)
		local faction =	hit.Parent:FindFirstChild("Faction")
		local human = hit.Parent:FindFirstChild("Humanoid")
		local hrp = hit.Parent:FindFirstChild("HumanoidRootPart")
		local part = hit:IsA("Part")
		if faction then
			if human and hrp and human.Health > 0 and hit.Parent ~= npc then
				human:TakeDamage(bulletdmg)
				bullet:Destroy()
			end
		else if part and not human and not hrp and not faction and hit ~= pointer then
				local dmgPart = Instance.new("Part")
				dmgPart.Size =  Vector3.new(.5,.5,.1)
				dmgPart.Color = hit.Color
				dmgPart.Material = hit.Material
				dmgPart.Velocity = Vector3.new(math.random(-10,10),math.random(-10,10),math.random(-10,10))
				dmgPart.Position = bullet.Position
				dmgPart.CFrame = bullet.CFrame
				dmgPart.Parent = workspace
				bullet:Destroy()
				debris:AddItem(dmgPart, 2)
			end
		end
	end)
end

The Raycast.raycast module function:

Raycast.raycast = function(pointer, range)
	local rOrigin = pointer.Position
	local rDirection = pointer.CFrame.LookVector * range
	
	local rParams = RaycastParams.new()
	rParams.FilterDescendantsInstances = {pointer.Parent}
	rParams.FilterType = Enum.RaycastFilterType.Blacklist
	local rResult = workspace:Raycast(rOrigin, rDirection, rParams)
	
	return rResult
end

If the NPC is shooting slower then there must be something interfering with the firerate frequency method you are using which causes the wait(firerate) or the yield in the loop to be slower.

Looking through your code for lines which may yield I find this:

And yeah from the documentation.

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts.

And yeah this function will yield and so possibly causes the NPC to shoot slower as the npc is trying to think where to go with its big brain instead of shooting.

So yeah I believe this function will somehow be needed to be put in a separate thread within a coroutine somehow in order to not yield the fire rate and make the firerate slower. IDK the exact solution as I haven’t worked with NPC’s yet but yeah hope this helps.

Oh yeah, I just realized that is yielding it. Thanks!