How would I count down from a designated number in the clientside realm? I feed it a variable (let say 10) and the text dynamic changes every 1 second.
You can do it several ways. What’s it for exactly?
I did this for my MOTD system to have the accept button disabled until the time is up, and it changes the text.
The way I did it was by doing a for i = 1, wait_time_in_seconds do loop.
Inside, this was the logic which is pretty straight forward. If it counted down to 0 ( note, this means the loop is at the end, and the wait_time - loop index integer is 0 ) then set text to LANG Accept.
Otherwise, simply set the text to LANG Accept, with a counter in parenthesis.
[lua] for i = 1, MOTD_ACCEPT_WAIT do
timer.Simple( i, function( )
if ( MOTD_ACCEPT_WAIT - i == 0 ) then
_accept:SetText( “#Accept” )
_accept:SetText( “#Accept” … " ( " … MOTD_ACCEPT_WAIT - i … " ) " )
So, that’s a way using timers.
Another way would be if your logic is being run in a tick/think/draw/paint/render hook where it’s being called frequently enough to call basic logic. There, you’d just create a start time, and when the end should come. Counting up, subtract the end and you have your basic counter until something happens.
I’m still a tad confused (My brain is fuzzy tonight). As an example with a fixed number, here is what it’s for.
This should get you started.
local time = 10
timer.Create(ply:EntIndex()…"_respawntimer", 1, 10, function()
time = time - 1
if time == 0 then
//This is what I have serverside so far
function GM:PlayerDeath( ply, weapon, killer )
local time = 10
umsg.Start( “dead” );
umsg.Short( time );
timer.Create(“DeathTimer”…ply:UserID(), time, 1, function()
local time = data:ReadShort()
What is the direct way to draw the countdown?
This is something you could use as a base.
if SERVER then
local deathDelay = 10 hook.Add("PlayerDeath", "Delay.PlayerDeath", function(ply) ply:Lock() net.Start("ply_DeathTimer") net.Send(ply) timer.Simple(deathDelay, function() if !IsValid(ply) then return end ply:UnLock() ply:Spawn() end) end)
local deathDelay = 10
timer.Create(“Delay.DeathTimer”, 1, 10, function()
deathDelay = deathDelay - 1
hook.Add("HUDPaint", "Delay.HUDPaint", function() local ply = LocalPlayer() if !IsValid(ply) or deathDelay == 0 then hook.Remove("HUDPaint", "Delay.HUDPaint") end draw.RoundedBox(0, 0, 0, ScrW(), ScrH(), Color(255,0,0,150)) draw.DrawText("You can respawn in "..deathDelay.." seconds.", "TabLarge", ScrW()/2, ScrH()/2, Color(255,255,255), TEXT_ALIGN_CENTER) end) end)
My code could actually work for you. Just set the WAIT variable to 10, and where it says SetText #Accept, put you may respawn now, where it has the timer, just add your text and leave that logic the same.
So, on popup of that vgui, do that simple logic and you’re done!
Of course, a lot of these others would work fine.
Why would you use a timer for this…? It’s easier to just use CurTime.
Here’s an example of what I mean:
local time = 0
hook.Add( “HUDPaint”, “Let’s count”, function()
if time <= CurTime() then
time = CurTime() + 10
local num = math.Round( time - CurTime() ) draw.SimpleText( "Countdown: "..tostring( num ), "Default", ScrW()/2, ScrH()/2, color_white, TEXT_ALIGN_CENTER )
CurTime is synchronized between the client and server, and it’s constantly increasing, so you don’t need to change the value yourself; you won’t get a small amount of difference between the client and server either, as you would if you used timers and usermessages to send and keep track of the value.
By the way, don’t lock the player. Use PlayerDeathThink.
Just for you:
local spawnDelay = 5
if SERVER then
hook.Add(“PlayerDeath”, “Delay.PlayerDeath”, function(ply)
ply.SpawnDelay = CurTime() + spawnDelay
hook.Add("PlayerDeathThink", "Delay.PlayerDeathThink", function(ply) if (CurTime() >= ply.SpawnDelay) then return end return false end)
local timeLeft, countdown
hook.Add(“HUDPaint”, “Delay.HUDPaint”, function()
local ply = LocalPlayer()
if !IsValid(ply) then return end
if ply:Alive() then if ply.SpawnDelay then ply.SpawnDelay = false end else if !ply.SpawnDelay then ply.SpawnDelay = CurTime() + spawnDelay else countdown = math.Round(math.Clamp(ply.SpawnDelay-CurTime(), 0, spawnDelay)) timeLeft = "in "..countdown.." seconds." if countdown == 1 then timeLeft = "in "..countdown.." second." elseif countdown == 0 then timeLeft = "at any time." end draw.RoundedBox(0, 0, 0, ScrW(), ScrH(), Color(255,0,0,150)) draw.DrawText("You may respawn "..timeLeft, "TabLarge", ScrW()/2, ScrH()/2, Color(255,255,255), TEXT_ALIGN_CENTER) end end end)
That’s the thing, it depends where it’s being run. If it’s a VGUI element, I’m not going to add a Tick/Think hook unless it’s absolutely necessary. Adding 10/11 simple timers to achieve the same goal is more ideal than using a Tick/Think hook just for this purpose.
If he’s drawing this in the hud already, then yes a counter using CurTime or RealTime would work quite well. It really just depends on where it’s being called. He posted a snippet of code, which sends data via UMSG; I don’t know if on the other end it creates a Vgui element, or if it just displays it on the other end. It would be ideal to maybe create a Vgui or HUDPaint hook for the duration of the counter and then depending which route you use, a timer setup or a dynamic counter to count down and then destructing that hook when the count is finished.