Hello, I have a for loop that loops through NPCs, but only problem is after a second the game crashes. There’s 50 NPCs which isn’t extremely a lot. So what’s the issue?
Error:
Script timeout: exhausted allowed execution time
Script:
for _, target in pairs(enemyTeam:GetChildren()) do
coroutine.wrap(function()
if target and not target:IsA("Model") or not target:FindFirstChild("HumanoidRootPart") then return end
local targetRoot = target:FindFirstChild("HumanoidRootPart")
local targetHumanoid = target:FindFirstChild("Humanoid")
local distance = (rootPart.Position - targetRoot.Position).Magnitude
if targetRoot and targetHumanoid then
if targetHumanoid.Health > 0 and distance < current_distance then
current_target = targetRoot
current_distance = distance
end
end
end)()
end
Also it could be because the for loop is in a while true do loop. So a loop inside a loop would most definitely crash a game. If this is the issue how could I fix it? I could use task.wait(), but this will cause stuttering which I don’t want.
You may add a very small delay so it won’t throttle.
for _, target in pairs(enemyTeam:GetChildren()) do
coroutine.wrap(function()
if target and not target:IsA("Model") or not target:FindFirstChild("HumanoidRootPart") then return end
local targetRoot = target:FindFirstChild("HumanoidRootPart")
local targetHumanoid = target:FindFirstChild("Humanoid")
local distance = (rootPart.Position - targetRoot.Position).Magnitude
if targetRoot and targetHumanoid then
if targetHumanoid.Health > 0 and distance < current_distance then
current_target = targetRoot
current_distance = distance
end
end
end)()
task.wait()
end
Try pulling the 3rd line logic into the for loop and pass if it resolves as false. It’s not performant to create coroutines unnecessarily. You could also consider using a run service function. Ideally you’d probably want to find an event driven way to do what you’re doing, though.
How are you deciding when to generate the NPCs? Or are they just generated when a new game instance is made?
As of right now I just have an admin button where you click it and it generates 50 NPCs.
Here’s the updated script:
for _, target in pairs(enemyTeam:GetChildren()) do
if target and target:FindFirstChild("HumanoidRootPart") then
local targetRoot = target:FindFirstChild("HumanoidRootPart")
local targetHumanoid = target:FindFirstChild("Humanoid")
local distance = (rootPart.Position - targetRoot.Position).Magnitude
if targetRoot and targetHumanoid then
if targetHumanoid.Health > 0 and distance < current_distance then
current_target = targetRoot
current_distance = distance
end
end
end
if i == 5 or i == 10 or i == 15 or i == 20 or i == 25 then
task.wait()
end
end
end
Edit: After testing the game doesn’t crash with some stuttering. But, I’m curious can I optimize it even more for lower end devices?
I found a solution! Instead of always finding for a target I just decided to find a target at one time. If there’s no target it will loop. This is much better optimized and for me I don’t need it to constantly look for target so it works out great. Thank you so much everyone! Combined it works great!