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.
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.
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
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.
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?