My code for server age isn't good

Hi,
I have a working system whose job is to show server age in hours, minutes and seconds to every player but in my opinion it’s very “unsteady” and it could be better:

-- Script in ServerScriptService

local ChangeServerAge = game:GetService("ReplicatedStorage"):WaitForChild("ChangeServerAge")

while task.wait(1) do
	ChangeServerAge:FireAllClients(time())
end
-- LocalScript in TextLabel (StarterGui)

local ChangeServerAge = game:GetService("ReplicatedStorage"):WaitForChild("ChangeServerAge")

ChangeServerAge.OnClientEvent:Connect(function(serverAge)
	local TextLabel = script.Parent
	
	TextLabel.Text = string.format("Server Age: %02dh:%02dm:%02ds", math.floor(serverAge/3600), serverAge/60%60, serverAge%60)
end)

I’m almost sure that it can be better but I don’t know how to improve it

You should send the age to the client when they first join. Then you can keep track of how much time has passed on the client so you don’t have to fire an event every second.

1 Like

Clients with worse connection would have bad timing

For something like this I don’t think it’s too important for the time to be 100% accurate. This way, you’re only sending the information once and then the client is taking over in updating the time. The client would be behind by the time it took for the message to reach them. A second is a second and you’re not going to notice much deviation regardless of their connection. Sending an event every second to all the connected clients isn’t necessary.

1 Like

No, if anything it’d be the opposite. Because the client is simulating a very accurate time locally, connection will be an irrelevant factor.

@Sinblade if you send over a time to every player that was determined only once as soon as the script ran, it won’t be behind for any reason like bad connections.

An example of what I mean:

-- Server
local players = game:GetService('Players')
local remote = game:GetService('ReplicatedStorage').Remote

local start = DateTime.now().UnixTimestamp

local function Added(player)
    remote:FireClient(player, start)
end

for _, player in ipairs(players:GetPlayers()) do
    task.spawn(Added, player)
end

players.PlayerAdded:Connect(Added)
-- client
local start = -- time from remote

while task.wait(1) do
    local seconds = DateTime.now().UnixTimestamp - start

    print(seconds)
end
1 Like

You have a few options to use if you want to make it more accurate:

print(workspace.DistributedGameTime) -- Time the game started running
print(os.time()) -- Time since epoch (1 January 1970, 00:00:00) UTC
print(tick()) -- Time since epoch (1 January 1970, 00:00:00) system time
print(time()) -- Time the game started running
print(elapsedTime()) -- Time since Roblox started running

You can also use an attribute for workspace which I believe would be faster internally.

Server code would be that it sets the attribute every second or so, and client code would be that it listens to an attribute change instead of a remote event firing every single second.

2 Likes

Can I put an IntValue in workspace which will contain server start time (in unix timestamp) so LocalScript will only take the value from it and do the rest?

1 Like

You can if you want, It’d probably be more convenient.