commands.cd = function(sender, arguments)
local countdown = tonumber(arguments[1])
for ea, child in ipairs(game.Players:GetPlayers()) do
local announcement = game.ServerStorage.Countdown:Clone()
announcement.Header.Description.Text = sender.Name.."'s Countdown"
announcement.Parent = child.PlayerGui.Countdowns.Holder
for i = countdown, 0, -1 do
announcement.Announcement.Text = tostring(i)
wait(1)
end
announcement:Destroy()
end
end
The reason is that you have a loop going through each player, and then on each player creating and counting down a timer. The issue right now is that the code won’t move on to the next player until the code for the first player (the timer) is done.
Wrapping it in a coroutine moves that code to another thread, in essence meaning it will carry it out while moving on to the next player.
Also, consider changing wait() to task.wait(). More accurate version of it.
commands.cd = function(sender, arguments)
local countdown = tonumber(arguments[1])
for ea, child in ipairs(game.Players:GetPlayers()) do
local announcement = game.ServerStorage.Countdown:Clone()
announcement.Header.Description.Text = sender.Name.."'s Countdown"
announcement.Parent = child.PlayerGui.Countdowns.Holder
spawn(function()
for i = countdown, 0, -1 do
announcement.Announcement.Text = tostring(i)
task.wait(1)
end
end)
announcement:Destroy()
end
end
I prefer to use spawn over coroutines, but it’s up to you.
[The reason to what happend here is mentioned by @ifkpop ]
The issue is the final line of code, announcement:Destroy(). That should be moved inside the coroutine / spawned func. Right now you destroy the announcement object while the function is attempting to manipulate it.
commands.cd = function(sender, arguments)
local countdown = tonumber(arguments[1])
for _, child in ipairs(game.Players:GetPlayers()) do
coroutine.wrap(function()
local announcement = game.ServerStorage.Countdown:Clone()
announcement.Header.Description.Text = sender.Name.."'s Countdown"
announcement.Parent = child.PlayerGui.Countdowns.Holder
for i = countdown, 0, -1 do
announcement.Announcement.Text = tostring(i)
task.wait(1)
end
announcement:Destroy()
end)()
end
end
In this code I also moved all of it inside a coroutine, since there is no downside to doing so. If coroutine.wrap() isn’t working as intended, use spawn() as @Valkyrop mentioned.
EDIT: Looks like you are not using the key in the for loop, so I replaced the variable name ea to _, since a _ indicates that it will not be used.