Game UI is showing "305:00" for 5 minute game modes. Works just fine in studio

In my game, there is a timer at the top that is controlled by 2 scripts and a ui. (i know im sorry, but its based off a game mode and voting system) The thing is it works perfectly fine in studio. It starts at 300 then just keeps going down, but the game modes and actual server timers work fine.

I cannot figure out what is going on and how to fix this. It is in the same area and in the same format as it should be.

Inside start gui’s theres a frame with a text called “Timer” and has 2 texts inside of it

There is also a part of code inside the game mode manager that seems to have a impact on it. (IM SORRY FOR IT BEING IN DIFFERENT SCRIPTS I STARTED THIS WHEN I WAS 15)

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local rs = game:GetService("ReplicatedStorage")
local ts = game:GetService("TweenService")

local remotes = rs.Remotes
local plr = Players.LocalPlayer
local plrUI = plr:WaitForChild("PlayerGui")

local votingSystem = workspace:FindFirstChild("VotingSystem")
local tickdiff = 0
local curMode = nil
local used = false
local gamemode = nil

local mapHighlights = {}
local gamemodeHighlights = {}

local function createHighlight(parent)
	local highlight = Instance.new("SelectionBox")
	highlight.Adornee = parent
	highlight.LineThickness = 0.025
	highlight.Color3 = Color3.new(0, 1, 0)
	highlight.Transparency = 0.25
	highlight.Parent = parent
	highlight.Visible = false
	return highlight
end

-- Create highlights for maps
for i = 1, 3 do
	local mapElement = votingSystem["Map" .. i]
	mapHighlights[i] = createHighlight(mapElement)
end

-- Create highlights for game modes
local gamemodeNames = {"CTF", "Rando", "Headhunter", "TDM", "FFA", "Juggernaut"}
for i, name in ipairs(gamemodeNames) do
	local gamemodeElement = votingSystem[name]
	gamemodeHighlights[i] = createHighlight(gamemodeElement)
end

-- Event connections (connect immediately)
function UpdateMapVotes(VoteData, leadingMaps)
	local mapElements = {votingSystem.Map1, votingSystem.Map2, votingSystem.Map3}
	local maxVotes = 0
	for _, votes in pairs(VoteData) do
		if votes > maxVotes then
			maxVotes = votes
		end
	end
	for i, mapElement in ipairs(mapElements) do
		mapElement.Votes.SurfaceGui.TextLabel.Text = VoteData[i]
		if maxVotes > 0 and table.find(leadingMaps, i) then
			mapHighlights[i].Visible = true
		else
			mapHighlights[i].Visible = false
		end
	end
end

function UpdateGamemodeVotes(VoteData, leadingGamemodes)
	local gamemodeElements = {votingSystem.CTF, votingSystem.Rando, votingSystem.Headhunter, votingSystem.TDM, votingSystem.FFA, votingSystem.Juggernaut}
	local maxVotes = 0
	for _, votes in pairs(VoteData) do
		if votes > maxVotes then
			maxVotes = votes
		end
	end
	for i, gamemodeElement in ipairs(gamemodeElements) do
		gamemodeElement.Votes.SurfaceGui.TextLabel.Text = VoteData[i]
		if maxVotes > 0 and table.find(leadingGamemodes, i) then
			gamemodeHighlights[i].Visible = true
		else
			gamemodeHighlights[i].Visible = false
		end
	end
end

remotes.UpdateVotes.OnClientEvent:Connect(function(gamemodeVotesData, mapVotesData, Individual, leadingGamemodes, leadingMaps)
	UpdateMapVotes(Individual and mapVotesData or gamemodeVotesData, leadingMaps)
	UpdateGamemodeVotes(gamemodeVotesData, leadingGamemodes)
end)

remotes.UpdateScore.OnClientEvent:Connect(function(typeUI, blueScore, redScore)
	if not plrUI:FindFirstChild("RoundSystem") then return end
	local scoreFrame = plrUI.RoundSystem:WaitForChild("ScoreFrame")
	local victoryFrame = plrUI.RoundSystem:WaitForChild("VictoryMessage")
	if typeUI == "updateScore" then
		scoreFrame.Blue.Text = tostring(blueScore)
		scoreFrame.Red.Text = tostring(redScore)
		return
	end

	if typeUI == "winBlue" then
		victoryFrame.Win.TextLabel.Visible = true
		victoryFrame.Win.Blue.Visible = true
	elseif typeUI == "winRed" then
		victoryFrame.Win.TextLabel.Visible = true
		victoryFrame.Win.Red.Visible = true
	elseif typeUI == "tie" then
		victoryFrame.Tie.Visible = true
	elseif typeUI == "plrWin" then
		victoryFrame.Win.Player.Text = blueScore
		victoryFrame.Win.Player.Visible = true
		victoryFrame.Win.PlayerWin.Visible = true
	end

	task.delay(4, function()
		victoryFrame.Win.TextLabel.Visible = false
		victoryFrame.Win.Blue.Visible = false
		victoryFrame.Win.Red.Visible = false
		victoryFrame.Tie.Visible = false
		victoryFrame.Win.Player.Visible = false
		victoryFrame.Win.PlayerWin.Visible = false
	end)

	scoreFrame.Blue.Text = "0"
	scoreFrame.Red.Text = "0"
	scoreFrame.Blue.Visible = false
	scoreFrame.Red.Visible = false
end)

ReplicatedStorage.newmaps.OnClientEvent:Connect(function(MapData, GamemodeData)
	votingSystem.Map1.Map.SurfaceGui.ImageLabel.Image = ReplicatedStorage.mapimages[MapData[1]].Image
	votingSystem.Map2.Map.SurfaceGui.ImageLabel.Image = ReplicatedStorage.mapimages[MapData[2]].Image
	votingSystem.Map3.Map.SurfaceGui.ImageLabel.Image = ReplicatedStorage.mapimages[MapData[3]].Image
end)

ReplicatedStorage.Events.ShowGamemode.OnClientEvent:Connect(function(action, gamemodeName)
	if not plrUI:FindFirstChild("RoundSystem") then return end
	local scoreFrame = plrUI.RoundSystem:WaitForChild("ScoreFrame")
	if action == "Show" then
		scoreFrame.Gamemode.Text = gamemodeName
	else
		scoreFrame.Gamemode.Text = ""
	end
end)

-- Voting clicks
for _, v in ipairs(votingSystem:GetChildren()) do
	if v:IsA("Model") and v.Name ~= "Map1" and v.Name ~= "Map2" and v.Name ~= "Map3" then
		local textLabel = v.Gamemode.SurfaceGui.TextLabel
		v.Gamemode.ClickDetector.MouseClick:Connect(function()
			remotes.UpdateVotes:FireServer("gamemode", table.find(gamemodeNames, textLabel.Text) or 1)
			gamemode = textLabel.Text
		end)
	end
end

votingSystem.Map1.Map.ClickDetector.MouseClick:Connect(function()
	remotes.UpdateVotes:FireServer("map", 1)
end)
votingSystem.Map2.Map.ClickDetector.MouseClick:Connect(function()
	remotes.UpdateVotes:FireServer("map", 2)
end)
votingSystem.Map3.Map.ClickDetector.MouseClick:Connect(function()
	remotes.UpdateVotes:FireServer("map", 3)
end)

-- Wait for LoadUIV2 cleanup
local loadUI = plrUI:FindFirstChild("LoadUIV2")
if loadUI then
	local removedEvent = loadUI.AncestryChanged:Connect(function(_, parent)
		if not parent then
			removedEvent:Disconnect()
		end
	end)
	while plrUI:FindFirstChild("LoadUIV2") do
		task.wait()
	end
end

-- Wait for RoundSystem
repeat task.wait() until plrUI:FindFirstChild("RoundSystem")
local screenUI = plrUI.RoundSystem
local scoreFrame = screenUI:WaitForChild("ScoreFrame")
local timerUI = scoreFrame:WaitForChild("Timer")

-- Timer event
remotes.UITimer.OnClientEvent:Connect(function(startTimerTick, currModeLength, currGamemode)
	if curMode == currGamemode then return end
	startTimerTick = startTimerTick + tickdiff

	scoreFrame.Timer.WaitingForPlayers.Visible = false
	scoreFrame.Timer.Intermission.Visible = false

	if currGamemode ~= 0 and (currGamemode == 1 or currGamemode == 4) then
		scoreFrame.Blue.Visible = true
		scoreFrame.Red.Visible = true
	end

	if currGamemode == -1 then
		curMode = -1
		scoreFrame.Timer.WaitingForPlayers.Visible = true
		timerUI.Text = "Waiting For Players"
		return
	end

	if currGamemode == 0 then
		scoreFrame.Timer.Intermission.Visible = true
	end

	local lastTick = tick()
	curMode = currGamemode
	repeat task.wait()
		if curMode ~= currGamemode then break end

		local curTick = math.floor(currModeLength - (tick() - startTimerTick))
		curTick = math.clamp(curTick, 0, math.huge)

		local min = math.floor(curTick / 60)
		local sec = math.floor(((curTick / 60) - min) * 60 + 0.5)

		local sectext = sec < 10 and ("0" .. sec) or tostring(sec)
		local mintext = min < 10 and ("0" .. min) or tostring(min)

		timerUI.Text = mintext .. ":" .. sectext
	until tick() - startTimerTick >= currModeLength or curMode ~= currGamemode
end)

This is the ui manager code.

Here’s how you can make your current timer using modern code:

local totalTime = 5*60 --total timer time in seconds
local refreshRate = 1 --how often you want it to refresh

local start = os.clock() 
while true do
	local timeLeft = math.round(totalTime+start-os.clock())
	local minutes, seconds = timeLeft//60, timeLeft%60
	--pad with 2 zeros using string formating
	local text = string.format("%02d:%02d", minutes, seconds)
	--instead of print, update the timer text
	print(text)
	task.wait(refreshRate)
end

try to use this modern alternative and see if the error persists.

I haven’t read all of your code but it is probably because when you test in studio, the server and client time are the same. but Roblox servers in the app have UTC time which is different from your time. Instead of using tick() on the client, replace it with workspace:GetServerTimeNow()

Works now. Thanks a lot for your help!

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