I thank Kingdom for providing a great example.
#Objective:# My Objective is pretty simple, it's to create an NPC Respawn script that simply respawns the NPC to where it was from (place in studio) when it dies or falls out of the world. I'm trying to make scripts not laggy and avoid loops as much as possible.
#Set-up:#
in workspace I have a Folder called Bandits which holds all the NPC's.
in ServerStorage I have a Folder called NPCBackup Which holds a new Bandit ready to be used.
in ServerScriptService I have a script that manages the NPC's.
in ReplicatedStorage I have a Folder called ModuleScripts That holds ModuleScripts.
#Problem:# An error appears during testing but I'm not sure how to deal with it. When I try to make add an if statement, it just stops the entire system completely.
#Script:#
local RunService = game:GetService("RunService")
local Settings = require(game:GetService("ReplicatedStorage").ModuleScripts.SETTINGS)
local Respawn_Time = Settings.BANDIT.RESPAWN_TIME
local plrServ = game:GetService('Players')
local NPCBackup = game:GetService('ServerStorage').NPCBackup.Bandit
local function getClosestPlayer(myPos)
local pos, tor = Settings.BANDIT.RANGE
for _, plr in pairs(plrServ:GetPlayers()) do
if plr.Character then
if (plr.Character.PrimaryPart.Position - myPos).Magnitude < pos then
pos = (plr.Character.PrimaryPart.Position - myPos).Magnitude
tor = plr.Character.PrimaryPart
end
end
end
return tor
end
local function setupNPC(Bandit, BanditPosition)
local hum = Bandit.Humanoid
local npcPrimaryPart = Bandit.PrimaryPart
local targetTorso
spawn(function()
while wait(1) do
targetTorso = getClosestPlayer(npcPrimaryPart.Position)
hum:MoveTo(targetTorso.Position, targetTorso)
end
end)
--hum:MoveTo(targetTorso.Position, targetTorso)
-- clone new npc at same position
hum.Died:Connect(function()
wait(Settings.BANDIT.RESPAWN_TIME)
local cln = NPCBackup:Clone()
cln:SetPrimaryPartCFrame(BanditPosition)
cln.Parent = workspace.Bandits
Bandit:Destroy()
setupNPC(cln, BanditPosition)
end)
end
for _, Bandit in pairs(workspace.Bandits:GetChildren()) do
spawn(function() setupNPC(Bandit, Bandit.PrimaryPart.CFrame) end)
end
This is the section where it errors:
spawn(function()
while wait(1) do
targetTorso = getClosestPlayer(npcPrimaryPart.Position)
hum:MoveTo(targetTorso.Position, targetTorso)
end
end)
#Error:#
17:38:34.068 - ServerScriptService.NPCFollow.NPC Commander:29: attempt to index upvalue 'targetTorso' (a nil value) 17:38:34.069 - Stack Begin 17:38:34.069 - Script 'ServerScriptService.NPCFollow.NPC Commander', Line 29 17:38:34.070 - Stack End
I appreciate any feedback I get that improves this code to the best it can be or fixes my issue. Thanks for reading.

14 comments
I wonder if it is connected that childRemoved event to every npc in the folder, so when one dies, however many npcs are in the folder that function gets called?
I don't understand your comment. Once the child is REMOVED or DESTROYED from the folder, the event fires. So, if I detect the humanoid Died, simply destroy it and it should chain and activate the ChildRemoved Event
ahh, the way i see it, is that you are connecting that event function to all of the npcs in the folder, so when one gets removed all of the events fire for every npc in the folder.
This is why you never put Events inside of loops...
I will try changing the setup
is it ran once
Yes
You sometimes would want events in loops.
Help ;-;
Check your loop? , It might be running just once and your Event in loop is useless which results into massive collection of dead NPC in floor xD
you can use
game:GetService("RunService").Heartbeatif you don't want a loopThanks but do you know how to solve my current issue? I want NPC's to spawn at their original position
You have no error handling if nothing is in range.
Well it's suppose to do nothing if nothing is in range?