Help with syncing a timer with all players

Hey there,
I have this script here that counts down from 5 minutes and I was wondering how I can make the timer the same for everyone even if they join the game after the timer is already halfway done.

Script:

--Variables

local textlabel = script.Parent
local seconds = textlabel:WaitForChild("Seconds").Value
local Minutes = textlabel:WaitForChild("Minutes").Value
local Speed = textlabel:WaitForChild("Speed").Value

--function

while true do
	if seconds == 0 and Minutes == 0 then
		print("Timer ended!")
		break
	else
		if seconds == 0 and Minutes ~= 0 then
			seconds = 60
			Minutes -= 1
			textlabel.Text = Minutes..":".. seconds
		else
			if seconds <= 10 then
				seconds -= 1
				textlabel.Text = Minutes.. ":0".. seconds
				wait(Speed)
			else
				seconds -= 1
				textlabel.Text = Minutes.. ":".. seconds
				wait(Speed)
			end
		end
	end
end
1 Like

The way I’d do it is count down on a server script and fire the player clients, with a remote event, for the GUI update every time the timer runs out.

3 Likes

What about when a new player joins the game? I would want them to have the same amount of time left on the timer.

Change it manually in a serversided script and update all the players uis to it

2 Likes

thats smart, thank you ill try that

Snipping since no longer relevant.

1 Like

So from my understanding, you want this timer to change even when a new player joins? Make sure not to use a LocalScript, and just don’t change the text for the client. Change it in StarterGui, as PlayerGui is only for players, and StarterGui is for the entire server.

1 Like

Thanks ill give that a shot, if I were to use this how would I make all players die when the timer reaches 0?

By changing this bit here.

timerRemote.OnClientEvent:Connect(function(i)
	local playerGui = player:WaitForChild("PlayerGui")
	local screenGui = playerGui:WaitForChild("ScreenGui")
	local frame = screenGui:WaitForChild("Frame")
	local textLabel = frame:WaitForChild("TextLabel")
	textLabel.Text = i.." seconds remaining!"
end)

To:

timerRemote.OnClientEvent:Connect(function(i)
	local playerGui = player:WaitForChild("PlayerGui")
	local screenGui = playerGui:WaitForChild("ScreenGui")
	local frame = screenGui:WaitForChild("Frame")
	local textLabel = frame:WaitForChild("TextLabel")
	textLabel.Text = i.." seconds remaining!"
	if i <= 1 then
		local character = player.Character
		local humanoid = character:WaitForChild("Humanoid")
		humanoid.Health = 0
	end
end)
1 Like

Thanks Ill go try it out.
3030

Hey, The script isnt working, I made the remote event and everything but the text just isnt updating at all with 0 errors

Well yeah, you need to change it to fit your game.

	local playerGui = player:WaitForChild("PlayerGui")
	local screenGui = playerGui:WaitForChild("ScreenGui")
	local frame = screenGui:WaitForChild("Frame")
	local textLabel = frame:WaitForChild("TextLabel")

ScreenGui>Frame>TextLabel

Your StarterGui likely works differently to this (I just used it as an example).

1 Like

Yeah I did but still nothing happens

Here, this works, I’ve tested:

--SERVER SCRIPT--
local players = game:GetService("Players")
local repStorage = game:GetService("ReplicatedStorage")
local timerRemote = repStorage:WaitForChild("TimerRemote")
local timer = 20 --change to number of seconds

function startTimer()
	for i = timer, 0, -1 do
		local playerList = players:GetPlayers() 
		for _, player in pairs(playerList) do
			timerRemote:FireClient(player, i)
		end
		task.wait(1)
	end
end

task.wait(5)
startTimer()
--LOCAL SCRIPT--
local players = game:GetService("Players")
local player = players.LocalPlayer or players.PlayerAdded:Wait()
local repStorage = game:GetService("ReplicatedStorage")
local timerRemote = repStorage:WaitForChild("TimerRemote")

timerRemote.OnClientEvent:Connect(function(i)
	local playerGui = player:WaitForChild("PlayerGui")
	local screenGui = playerGui:WaitForChild("ScreenGui")
	local frame = screenGui:WaitForChild("Frame")
	local textLabel = frame:WaitForChild("TextLabel")
	textLabel.Text = i.." seconds remaining!"
end)

Proof: https://gyazo.com/8dbf922cbcf97b8f7d6fb32f20ccb201

I just needed to add a wait before the timer itself is called to start to allow for things to load in.

1 Like

Sorry for the late reply buy thanks ill go test it out

It works great thank you! Also quick question, how would i make the timer restart after it reaches 0 then it does a 5 second wait?

--SERVER SCRIPT--
local players = game:GetService("Players")
local repStorage = game:GetService("ReplicatedStorage")
local timerRemote = repStorage:WaitForChild("TimerRemote")
local timer = 20 --change to number of seconds
local timerRunning = false

function startTimer()
	timerRunning = true
	for i = timer, 0, -1 do
		local playerList = players:GetPlayers() 
		for _, player in pairs(playerList) do
			timerRemote:FireClient(player, i)
		end
		task.wait(1)
	end
	task.wait(5)
	timerRunning = false
end

task.spawn(function()
	while task.wait() do
		if not timerRunning then
			startTimer()
		end
	end
end)
1 Like

Thank you so much! It works great!