Ideal way to make a timer display?

My on-going project has a round system, which has a timer.
I was wondering how I could make the timer on the client as precise as possible to feel in sync with everything.
The only solution I found was to send a remote to inicialize a timer display until a certain time, but I am looking for better alternatives.

All help is appreciated.

2 Likes

You can have the server update something the client can read, like an IntValue. When its value changes, display a text in some GUI.

2 Likes

Yes, but at the same time I do not want the seconds to pass at different speeds due to replication time nor give some players a head start for better ping. I would like the players to have the same time to work with. Could I do something with their ping, perhaps?

Maybe you could do a timer in the server and then fire a remote event to the client to start a “Dummy Timer”. The dummy timer would be a way of convincing the client the game is functioning smoothly and the only time the player would experience ping difficulties would be at the last second and would not be very noticeable. It all would be secure because the client is not handling a timer that does anything. :penguin:

edit: lol i just saw that the description is similar to what i said. :joy:

1 Like

You can have global timers which run server-sided.

local hint = Instance.new("Hint")
hint.Parent = workspace

local function startTimer(startTime)
	for count = startTime, 0, -1 do
		task.wait(1)
		hint.Text = count.." seconds remaining!"
	end
end

startTimer(10)

just straight up make the timer in the server and update every player timer from there (if its a text label or anything like that)

Could I somehow compensate for the delays though?

Making the timer on the server is not a problem - the problem is making it as accurate as possible to the client. I would like to compensate for ping somehow.

Yeah so make the timer on the client?? Why would you do it on the server, there’s obviously going to be replication lag.

1 Like

I am not sure how to compensate, though.

Why would you have to compensate? Unless your game is insanely laggy. Furthermore it’s just a mere round time, are you sure a fraction of a second is necessary?

That’s a fair point. I was going for the optimal user experience but now that you mention it, it seems exagerated.

I just thought about this. :upside_down_face:

What if it’s all server sided. No local scripts at all. :exploding_head:

Example:

local Count = 30
While Count ~=0 do
Count -= 1
for _,player in pairs(game.Players:GetChildren()) do
player.PlayerGui.ScreenGui.TextLabel.Text = Count
end
wait(1)
end

Kinda crazy, but here it is. :penguin:

local function StartTimer(Player: Player, Time: number)
    local Timer = Player.PlayerGui.ScreenGui.TextLabel -- Replace ScreenGui and TextLabel with the actual ScreenGui and the Frame/TextLabel location.

    for i = Time, 0, -1 do
        local Minutes = math.floor(i/60)
        local Seconds = math.floor(i%60)
        Timer.Text = tostring(string.format("%i:%.2i", Minutes, Seconds))
        task.wait(1)

        if i == 0 then
            break
        end
    end
end

for _, v in ipairs(game.Players:GetPlayers()) do
    StartTimer(v, 360)
end

That should work, just follow the instructions in the code! (This should be a ServerScript btw!)

Enjoy! :grin:

1 Like

Absolutely unnecessary to do it on the server, it’s a waste of resources. Just get the client to display the countdown for themselves.

That’s why I said it’s kinda crazy. :penguin:

I wouldn’t say it’s crazy because it’s useless. Instead of crazy it’s lazy. :scream:

Create a StringValue on ReplicatedStorage, Make the Server modify it, And then you can just check whenever the value changes on the Client so you can update the Gui. Updating it would look like this:

-- Services, Instances, Paths, etc...
GameTimer:GetPropertyChangedSignal("Value"):Connect(function()
	TimerLabel.Text = GameTimer.Value
end)

Another cool thing that you could do is create a function that formats the timer into 00:00. But only Format it on the Client whenever the value changes. This is what the function looks like:

local function FormatTimeToMS(Time: number): string
	local Seconds = (Time / 60)
	local Minutes = (Time % 60)
	return string.format("%.2i:%.2i", Seconds, Minutes)
end

print(FormatTimeToMS(60)) -- 01:00
print(FormatTimeToMS(600)) -- 10:00

And then, You can just run the Format function whenever the Timer changes so it displays the Formatted version to the Clients/LocalPlayer:

local function FormatTimeToMS(Time: number): string
	local Seconds = (Time / 60)
	local Minutes = (Time % 60)
	return string.format("%.2i:%.2i", Seconds, Minutes)
end

GameTimer:GetPropertyChangedSignal("Value"):Connect(function()
	TimerLabel.Text = FormatTimeToMS(GameTimer.Value)
end)