Why won't my GUI change/why does it go twice as fast?

This is a script in the workspace that changes script disabling depending on the number of children in Players. When putting wait() in the while loop, the timer (second script) goes twice as fast than usual. When the wait() is changed to a wait(1), it completely stops and does not change.

local timer = game:GetService("StarterGui").timer.timer
local timerscript = timer.timer
local insidescript = workspace.timer.timerscriptinside
local teleport = workspace.UUTeleport
local players = #game:GetService("Players"):GetChildren()

while true do
	local players = #game:GetService("Players"):GetChildren()
	if players >= 2 then
		timerscript.Disabled = false
		insidescript.Disabled = false
		teleport.Disabled = false
	elseif players <= 1 then
		timerscript.Disabled = true
		insidescript.Disabled = true
		teleport.Disabled = true
		timer.Text = "Waiting for more players.."
	end
	wait()
end

This is the script in question that makes the GUI change its text. (assigned as insidescript in the script above)

--comments are to represent the stages of gui it currently goes through
local timer = script.Parent
while true do
	if timer.Value ~= 0 then
		timer.Value -= 1
		wait(1)
		--gui.Text = timer.Value
	elseif timer.Value == 0 then
		--gui.Text = "Round Ended! " .. #workspace.PlayerIngameFolder:GetChildren() .. " winners!"
		wait(3)
		--gui.Text = "Intermission.."
		wait(3)
		--gui.Text = "Round Starting"
		wait(3)
		timer.Value = 120
		--gui.Text = timer.Value
	end
end

This is the script (assigned as timerscript) that controls the timer and how it works.

local timer = workspace.timer
local gui = script.Parent
local folder = workspace.PlayerIngameFolder
local teleport = workspace.UUTeleport
local players = #game:GetService("Players"):GetChildren()

timer.Changed:Connect(function(newValue)
	gui.Text = newValue
	if newValue > 0 then
		teleport.Disabled = false
	else
		teleport.Disabled = true
		print(#workspace.PlayerIngameFolder:GetChildren())
		gui.Text = "Round Ended! " .. #workspace.PlayerIngameFolder:GetChildren() .. " winners!"
		task.wait(3)
		gui.Text = "Intermission.."
		task.wait(3)
		gui.Text = "Round Starting"
	end
end)

So, what is the problem here?

you can try to use runservice insteasd of while true do

well that doesnt fix his issue itself.

try this:

(you might wanna adjust some stuff to get it to work for you)

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")

local timer = StarterGui.timer.timer
local insidescript = workspace.timer.timerscriptinside
local teleport = workspace.UUTeleport

local function gameplayService()
    teleport.Disabled = true

    local playerCount = #workspace.PlayerIngameFolder:GetChildren()

    if playerCount == 3 then
        timer.Text = "Round Ended! " .. playerCount .. " winners!"
    elseif playerCount == 6 then
        timer.Text = "Intermission.."
    elseif playerCount == 9 then
        timer.Text = "Round Starting"
    end
end

local function PlayerCheck()
    local playerAmount = #Players:GetPlayers()

    if playerAmount >= 2 then
        timer.Disabled = false
        insidescript.Disabled = false
        teleport.Disabled = false
        gameplayService()
    else
        timer.Disabled = true
        insidescript.Disabled = true
        teleport.Disabled = true
        timer.Text = "Waiting for more players.."
    end
end

RunService.Heartbeat:Connect(PlayerCheck)

p.s, will be really buggy if you test with a friend, timer is not the same across all clients