Timer going 2x faster with 2 players

hi, so im trying to make a rounds system:

local events = game.ReplicatedStorage:WaitForChild("Events")

local playersRequired = 1
local timer = 0
local stopRound = false

function countDown(text, length)
	timer = length
	print("aaaaaaaaaaa")
	repeat
		print("bbbbbbbbbb")
		timer -= 1
		events:FindFirstChild("Countdown"):FireAllClients(text, timer)
		wait(1)
	until timer == 0
end

local round = coroutine.create(function()
	while true do
		wait()
		
		if stopRound == true then
			coroutine.yield()
		end

		-- count down until round starts
		countDown("round starting in ", 10)
		
		-- put at random spawn
		bringToSpawn(workspace.GrassMap, "Everyone")
		
		-- count down until round ends
		countDown("round ending in ", 10)
		
		-- put at random spawn in lobby
		bringToSpawn(workspace.Lobby, "Everyone")
	end
end)

local function checkPlayers()
	
	-- if not enough players
	if #game.Players:GetPlayers() < playersRequired then
		stopRound = true -- stop coroutine
		print("not enoguh players")
		
	-- if enough players
	elseif #game.Players:GetPlayers() >= playersRequired then
		if coroutine.status(round) ~= "running" then
			stopRound = false
			coroutine.resume(round)
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAppearanceLoaded:Connect(function()
		bringToSpawn(workspace:WaitForChild("Lobby"), player) -- bring to spawn
		checkPlayers() -- check if game can start now
	end)
end)
game.Players.PlayerRemoving:Connect(checkPlayers) -- check if game has to end

it works with 1 player, but if i try it with 2, it counts down 2 at a time. interestingly, its only inside the repeat that it gets called twice, the actual countdown function only gets called once:

also i get this error if i use task.wait instead of wait in the countdown function:

help would be appriciated

you don’t need to fire remote events for timers
you can add an instance int value and change it from server and when its changed update the value on client
{89C3CD42-5D42-40B3-BDC9-00B0A1BC0707}

example

Server

local Timer = game.ReplicatedStorage.Timer
Timer.Value = 10

while Timer.Value > 0 do
	Timer -= 1
end

Client

local Timer = game.ReplicatedStorage.Timer

Timer.Changed:Connect(function()
	TimerTextLabel.Text = tostring(Timer.Value)
end)

Thank you! I needed a script for the timer in my game.

1 Like

I think it’s counting down twice because both client scripts are counting it down by 1 at the same time.

Just to add on to what GE said, use Timer:GetPropertyChangedSignal("Value"):Connect(function()) instead of Timer.Changed:Connect(function())

both lines do the exact same thing

alright well i’ve changed it to this, but its still counting down by 2, so i’ll keep it like this, but it wasnt the issue unfortunately

local playersRequired = 1
local timer = game.ReplicatedStorage:WaitForChild("Timer")
local stopRound = false

function countDown(text, length)
	timer.Value = length
	while timer.Value > 0 do
		print("aaaaaaaaa")
		timer.Value -= 1
		wait(1)
	end
end

localscript:

local events = game.ReplicatedStorage:WaitForChild("Events")
local status = game.Players.LocalPlayer.PlayerGui:WaitForChild("GameGui"):WaitForChild("Status")
local timer = game.ReplicatedStorage:WaitForChild("Timer")

timer:GetPropertyChangedSignal("Value"):Connect(function()
	status.Text = timer.Value
end)

i managed to find the solution, so i’ll leave it in case anyone needs it ever:

this issue was that i was checking to see if the coroutine was running with coroutine.status, so that it doesnt trigger twice if its already running

-- if enough players
	elseif #game.Players:GetPlayers() >= playersRequired then
		if coroutine.status(round) ~= "running" then
			stopRound = false
			coroutine.resume(round)
		end
	end

this issue was however, is that coroutine.status can only be triggered inside of the coroutine, and since this is outside it always though it was suspended and let it trigger two times

the solution was to just use the stopRound value i already had:

-- if enough players
	elseif #game.Players:GetPlayers() >= playersRequired then
		
		if stopRound == true then
			stopRound = false
			coroutine.resume(round)
		end
		
	end

and also set it to true by default so that the round can start the first time around:

local stopRound = true

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.