Hi everyone!

I was making a timer for my game, and needed the time to print in the chat after hitting the win pad. Here is the script that is supposed to detect when the player touches the win pad, to fire an event for the win message (server script).

isInWinPad = script.Parent.Parent:FindFirstChild("WinPad")
message = nil
activated = false
if isInWinPad then
	script.Parent.Touched:Connect(function(t)
		local player = game.Players:GetPlayerFromCharacter(t.Parent)
		local humanoid = t.Parent:FindFirstChild("Humanoid")
		local timer = player.PlayerGui:FindFirstChild("Main").Timer
		print(timer.Time.Value) -- prints an empty string
		message = script.Parent.Parent.Parent.Name
		local timebeaten = timer.Time.Value
		if humanoid then
			if activated == false then
				t.Parent.HumanoidRootPart.CFrame = workspace.Lobby.SpawnLocation.CFrame + Vector3.new(0,7,0)
				game.ReplicatedStorage.WinPadHit:FireAllClients(player, message, timebeaten)
				game.ReplicatedStorage.COremover:FireClient(player)
				activated = true
				wait(0.5)
				activated = false
				wait(0.5)
			end
		end
	end)
end

This script takes the "WinPadHit" remote event and the arguments associated with it to create a win message for all players to see (local script)

IsInFolder = script.Parent.Name == "StarterPlayerScripts"
if not IsInFolder then
	game.ReplicatedStorage.WinPadHit.OnClientEvent:Connect(function(player, message, timebeaten)
		game.StarterGui:SetCore("ChatMakeSystemMessage", {
			Text = player.Name .. " Has Beaten " .. message .. " in " .. timebeaten .. "!";
			Font = Enum.Font.SourceSansBold;
			Color = Color3.new(255,255,0);
			FontSize = Enum.FontSize.Size96;
		})
	end)
end

This is the local script that handles the timer. This script is enabled and disabled when certain events are fired within a different script (more on that later):

local rs = game:GetService("RunService")
local offset = false
local trueSec = 0
local startingSec = 0
rs.Stepped:Connect(function(sec, _)
	if offset == false then
		startingSec = sec
		offset = true 
	end
	trueSec = sec - startingSec
	wait()
	local truemili = math.floor(trueSec * 100)/100 - math.floor(trueSec)
	local miliseconds = tonumber(string.sub(truemili, 3, 4))
	if miliseconds == nil then miliseconds = 0 end
	local minutes = math.floor(trueSec / 60)
	local seconds = math.floor(trueSec)
	if seconds == 60 then
		seconds = 0
	elseif seconds > 60 then
		seconds = seconds - (60*minutes)
	end
	if miliseconds < 10 then
		miliseconds = "0" .. tostring(miliseconds)
	end
	if seconds < 10 then
		seconds = "0" .. tostring(seconds)
	end
	script.Parent.Text = minutes .. ":" .. seconds .. "." .. miliseconds
	script.Parent.Time.Value = minutes .. ":" .. seconds .. "." .. miliseconds
end)

This is the local script that takes bindable events inside the timer text label to activate and deactivate the timer script above.

local isRunning = false
local rs = game:GetService("RunService")
local script2 = script.Parent.RunServiceThing

script.Parent.Start.Event:Connect(function()
	if isRunning == false then
		isRunning = true
		local timer = script.Parent
		while isRunning == true do
			wait()
			script2.Disabled = false
			if isRunning == false then
				print("Ended")
				script2.Disabled = true
				break
			end
		end
	end
end)

script.Parent.Stop.Event:Connect(function()
	isRunning = false
	wait(0.2)
	script.Parent.Text = "00:00.00"
	script.Parent.Time.Value = "00:00.00"
end)

Finally, this is the local script that fires the binable events to begin and stop the timer

game.ReplicatedStorage.COspawner.OnClientEvent:Connect(function(Tower)
	local tower = game.Workspace.Towers:FindFirstChild(Tower)
	local towerFolder = game.ReplicatedStorage.COfolder:FindFirstChild(Tower)
	local allCOs = towerFolder:GetChildren()
	local killbrick = game.ReplicatedStorage:FindFirstChild("Kill Brick")
	local timer =game.Players.LocalPlayer.PlayerGui:FindFirstChild("Main").Timer
	if tower.ClientSidedObjects:GetChildren()[1] == nil then
		for i, v in pairs(allCOs) do
			local c = v:Clone()
			c.Parent = tower.ClientSidedObjects
		end
	end
	if killbrick then
		killbrick.Parent = game.Workspace.HiddenKilbrick
	end
	if active == false then
		for _,d in pairs(tower.ClientSidedObjects:GetDescendants()) do
			addPart(d)
		end
		active = true
	end
	timer.Start:Fire()
end)

game.ReplicatedStorage.COremover.OnClientEvent:Connect(function()
	local alltowers = game.Workspace.Towers:GetChildren()
	local timer =game.Players.LocalPlayer.PlayerGui:FindFirstChild("Main").Timer
	local killbrick = game.Workspace.HiddenKilbrick:FindFirstChild("Kill Brick")
	for i = 1, #alltowers do
		local tower = alltowers[i]
		local COs = tower:FindFirstChild("ClientSidedObjects")
		local allCOs = COs:GetChildren()
		if allCOs[1] ~= nil then
			for i = 1, #allCOs do
				local CO = allCOs[i]
				CO:Destroy()
			end
		end
		if tower:FindFirstChild("StartingTower") then
			tower.StartingTower:Destroy()
		end
		if killbrick then
			killbrick.Parent = game.ReplicatedStorage
		end
	end
	active = false
	timer.Stop:Fire()
end)

In the end, the time replicated in the server message is just an empty string. The only place i can think of having this empty string as the value that is interpreted is in the Starter Gui defaults, where the value is an empty string. How can i be referencing the starter Gui when i use the player gui to get the time?

If there's something you don't understand, feel free to ask. Any help is appreciated :)