I am looking to create a timer system to track the time for a player to reach point A to B. While the basic fundamentals work properly, the time itself does not. Passing tick to the server and tracking the elapsed time creates a discrepancy due to client timezones. os.time also produces unwanted results as I am looking to achieve millisecond-precision.
I would start and stop the timer event on the Server rather than the client. Add the Players in a table at the Start event and remove on the End event.:
-- Server
local playerStartTimes = {}
remotes.Events.StartTimer.OnServerEvent:Connect(function(player)
playerStartTimes[player] = tick.os
end)
remotes.Events.EndTimer.OnServerEvent:Connect(function(player)
local playerEndTime = tick.os
local timeTaken = playerEndTime - playerTimes[player]
print(player, timeTaken )
end)
Obviously needs an End event sent from the client.
Are you looking for millisecond timing? A client firing an event to the server should really be equivalent to the ping time (give or take a few milliseconds for processing). Alternatively, if you are using Touch events, the trigger them on the server.
You could calculate the timezone difference first, store it on the server in a list and then use that to remove the difference.
-- Server
local timezones = {};
remotes.Events.StartTimer.OnServerEvent:Connect(function(player, t)
if (timezones[player.Name] == nil) then
timezones[player.Name] = tick() - t -- timezone difference
end
RunService.RenderStepped:Connect(function()
local elapsed = math.floor((tick() - t - timezones[player.Name]) * 1000) / 1000
print(elapsed) -- outputs inaccurate time based on player's timezone
end)
end)