How do i make a infinite countdown loop

This should work:

local seconds = 30


while true do

     wait(1)

     if seconds > 0 then
         seconds = seconds - 1
         script.Parent.Text = seconds
               else
	               seconds = 30
                   script.Parent.Text = seconds
	               -- Award the player here
end


end

Edit: @waterrunner is correct.

4 Likes

thankyou so much,<3________________________________

1 Like

Alternatively, cut out the middleman, wait(1) and do

local seconds = 30
while wait(1) do
    if seconds > 0 then
        seconds = seconds - 1
        script.Parent.Text = seconds
    elseif seconds <= 0 then
        seconds = 30
        script.Parent.Text = seconds
        --award code
    end
end

Either one works of course, but you can skip a step this way.

2 Likes

what if i have another award script from ServerScriptService i want to run it at the same time without delay
my award script:amount1 = 10 --amout to give each time
amount2 = 20
amount3 = 40
amount4 = 80
amount5 = 160

timedelay = 10 --give delay
currencyname = “Bucks”

for count = 1, 2 do
wait(timedelay)
for i,v in pairs(game.Players:GetPlayers()) do
if v:FindFirstChild(“leaderstats”) and v then
v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount1
end
end
end

wait()

for count = 1, 2 do
wait(timedelay)
for i,v in pairs(game.Players:GetPlayers()) do
if v:FindFirstChild(“leaderstats”) and v then
v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount2
end
end
end

for count = 1, 2 do
wait(timedelay)
for i,v in pairs(game.Players:GetPlayers()) do
if v:FindFirstChild(“leaderstats”) and v then
v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount4
end
end
end

wait()

while true do
wait(timedelay)
for i,v in pairs(game.Players:GetPlayers()) do
if v:FindFirstChild(“leaderstats”) and v then
v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount5
end
end
end

Please correct me if I’m wrong, but wasn’t there a post here that explained doing while waits was inefficient/bad practice?

cc: @Secretum_Flamma, I think this is the thread that you are on about:

You should try and avoid wait() and any infinite loop in production code if you can:

Lua is single threaded meaning one task runs at any given time and the task scheduler decides when each task is ran. Each time you add a new script you aren’t actually creating a new thread for that script because the script has been coroutined. coroutine or spawn(f) don’t actually create new threads like in multi-threaded languages because Lua is single threaded at this present time but instead it is telling the task scheduler to run the code in a manner that looks like it is running at the same time.

You may be thinking why does this affect wait() and I have had no problems with using wait(). Whenever you call wait(), you are yielding the current ‘thread’ and letting other ‘threads’ run. The problem then comes when the wait() has finished waiting because it needs to wait for a slot to resume. When your code becomes more intensive wait starts waiting several seconds longer than you specified it to wait.

To avoid using wait() and loops you should always use events when you can because Roblox has events for everything you can think of. For your use case you could use RunService.Heartbeat and check the time difference through tick(). From my knowledge Heartbeat is more reliable than wait and a better option than using a loop. Here is a little bit of code that should serve your use case:

local RunService = game:GetService("RunService")

local Duration = 3
local StartTime = tick()
local EndTime = StartTime + Duration

RunService.Heartbeat:Connect(function()
	if tick() >= EndTime then
		-- Do what you want to do when the time has reached 0
		StartTime = tick() -- Puts the start time to the current time
		EndTime = StartTime + Duration
	end
end)

Sorry if this code looks messy but you should be able to modify it to fit your use case. You should also note that you shouldn’t overuse Heatbeat.

1 Like

RemoteEvent. If your timer is in a localscript, which it should be, you can set up a remote event in ReplicatedStorage.

When you want to award the player, fire the event from the local script:

game.ReplicatedStorage.RemoteEvent:FireServer(plr) – make sure you are passing a 
value that refers to the player, else they can’t recieve rewards.

To recieve the function in your server script (Parented by ServerScriptService) you will write your function like this:

game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(plr) -- make sure 
the player value is the same as the one in your LocalScript

Of course, round it all off with:

end)

at the end of your code :slight_smile:

Feel free to ask any more questions, but this should be all you need! :smiley:

~ salcret

1 Like

You are correct, waits in general aren’t as efficient. Both of our examples suffered this, @waterrunner has listed a better example. I’ve never really done that to tell you the truth, but I can definitely use that as a reference from now on.

1 Like

game.ReplicatedStorage.RemoteEvent:FireServer(plr)

where should i put this?

and thx for helping me <3

1 Like

You should put in the LocalScript where you want the rewards to be given.

1 Like

so confuse ------------------------------------

what about
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(plr)
where to put this

local seconds = 30
while wait(1) do
if seconds > 0 then
        seconds = seconds - 1
        script.Parent.Text = seconds
    elseif seconds <= 0 then
        seconds = 30
        script.Parent.Text = seconds
        game.ReplicatedStorage.RemoteEvent:FireServer(plr)
    end
end

This needs to be put at the very beginning of your script (that handles the rewards) in ServerScriptService.

game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(plr)

P.S - Make sure you also put

end)

at the end of the script.

3 Likes

and what do you mean with
make sure
the player value is the same as the one in your LocalScript

game.ReplicatedStorage.RemoteEvent:FireServer(plr)

Notice how they both have the value plr?

game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(plr)

The value should be the same. If you just copy and paste this code, you will be fine.

1 Like

and do i just put a remote event in ReplicatedStorage?

1 Like

alright_________________________________________<3

i think there is something wrong with my award handler

local seconds = 30
while wait(1) do
if seconds > 0 then
seconds = seconds - 1
script.Parent.Text = seconds
elseif seconds <= 0 then
seconds = 30
script.Parent.Text = seconds
game.ReplicatedStorage.RemoteEvent:FireServer(plr)
end
end

there is a error on plr its said unknown global “plr”

(This is starting to get off-topic so I urge you to create a new topic for further discussion on events. Your original issue with an infinite countdown loop seems to have been solved by a few previous posts.)

You should read over both of these developers hub articles because they explain events and the Roblox client and server model:

RemoteEvents and RemoteFunctions provide a communication between the client and the server. RemoteEvents provide a one way communication whereas RemoteFunctions provide a two way communication because you need to return a value. Here is a little example of how to you could use RemoteEvents:

(Hierarchy):

Image

(Server script in ServerScriptService):

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage.RemoteEvent

RemoteEvent.OnServerEvent:Connect(function(Player) -- Fires when the client fires the server. The first parameter automatically becomes the player.
	print(Player.Name.. ": Has fired the server")
	RemoteEvent:FireClient(Player) -- Fires the client
end)

(Client Scrip in StarterGui):

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage.RemoteEvent

RemoteEvent:FireServer() -- Fires the server

RemoteEvent.OnClientEvent:Connect(function() -- Fires when the server has fired the cliet
	print("Fired client")
end)

You don’t need to put the player in FireServer() because the first parameter automatically becomes the player when you use the OnServerEvent on the server.

The reason why you are getting this error is because you aren’t specifying the player. As I explained above you don’t need to put the player in FireServer() because the first parameter automatically becomes the player when you use the OnServerEvent.

The reason why you put the RemoteEvent in ReplicatedStorage is because it is a shared contained between the client and the server. This means both the client and server can access it.

1 Like