What is os.clock, and what even is os?
local Time = os.clock()
task.wait(1)
print(os.clock()-Time)
What does this even means? And how do you use os.clock?
(os | Documentation - Roblox Creator Hub)
os.clock() would probably be best used when benchmarking code and seeing how fast/slow something is executed.
tick() is good for things like input/ability/interaction cooldowns and things like ingame timers. (more relative to ingame stuff)
os.time() is great for saving/comparing timestamps, especially if you use os.date("!*t", os.time())
to convert it to UTC, and then you dont have to worry about servers timezones. (NOTE: os.time() doesn’t have millisecond precision)
there is many ways to compare time.
local cooldown = 0
function handleAction()
if tick() >= cooldown then
cooldown = tick() + 0.5 --reset the cooldown to half a second.
--handle action
end
end
or
local cooldown = 0.5 --set the cooldown to half a second
local last = 0
function handleAction()
local current = tick()
if current - last >= cooldown then
--handle action
last = current
end
end
I usually prefer the first approach, although the second seems to be used more conventionally and all functions (tick(), os.clock() and os.time()) can be compared this way, with a minor exception to what os.date(“!*t”,os.time()) returns.
Not really, Its recommend that you dont use tick()
, and instead use os.time()
for the same purpose as its faster and more precise, tick()
may also get Deprecated in the future, and os.time()
is also based off of UTC time, while tick()
is based off of Device Time.
os.time() cant be used for fractions of a second though (which is quite useful for some input cooldowns/timers), and i usually used tick() or os.clock() because they had more precise timing on such things.
i didn’t know about the possible deprecation of tick() though
tick()
sounds perfect - it has a high resolution (usually around 1 microsecond), and a well-defined baseline - it counts since UNIX epoch! Or, well, it actually doesn’t. On Windows, it returns you a variant of the UNIX timestamp in local time zone. In addition, it can be off by 1 second from the actual, real UNIX timestamp, and might have other idiosyncrasies on non-Windows platforms. We’re going to deprecate this in the future.
thank you for the information.
DateTime.now() exists for that
No. Terrible advice. Tick() is ok for cooldowns but if you validate against a server it is terrible. While tick() does have millisecond accuracy it is local epoch time relative to your timezone. For example if you do a tick() on client then tick() on server and then compare the timestamp cooldowns youll quickly find out they differ due to timezone difference.
Someone mentiond DateTime.now()
but thats DateTime object. You really want to use DateTime.now().UnixTimestampMillis
.
when would you be comparing a cooldown?
for my systems i have cooldowns on the client and cooldowns on the server. instead of comparing a cooldown to see if its valid, i check if the cooldown is done on the client → fire a remote → see if cooldown is done on the server.
no need for comparing cooldowns here. also prevents clients from sending spoofed data to confuse your systems.
also os.clock > tick
Late reply but general practice for time is to use epoch.
While your approach is fine it is not the best for several reasons. For a combo skill system you run into the risk of hitting the message limit.
My combat skill combo system caches the data in both local player and server. So for example when a skill is used it is computed locally with checks performed locally, then if passed the server is notified once.
Server performs the same computation against its own cache and responds with success or not. The issue arises when you do the computation and have to roll-back. If the system does things like animation cancel/ allow conditional chaining into other skills with different timing then you result in the scenario where you notify the server several times (which runs into time drag and mismatch of the caches).
So by design my system sends one event only with 2 parameters (the skillname and clientTimestamp). When server receives the clientTimestamp you can use this as a measure of time to adjust for network/ping fluctuations. In more advanced systems you can use this as reference for client prediction and server validation.
But most of all this is specifically useful for hybrid implementation of rollback netcode. Typically for networking you generally want to follow 2 rules. Avoid spamming network with packets already in flight to avoid packet throttling and minimal parameters passed to avoid spoofing as you mention. In my implementation if I do not pass in client timestamp I resort to passing time checks sending multiple events due to the conditional checks my system has. If it fails it will rollback using a history of the cache. Rollbacks with multiple events can be extremely error prone and when combined with a fast action system can result in odd edge cases that are difficult to reproduce and debug. All in all if you must send time you can but it should be Epoch.
Generally not just for games but many distributed systems- you should always use epoch time to tag packets. Once on the local client (on either end) then you can favor tick() and higher precision times like clock.os specific to the hardware. But before you even get there you want to avoid time conversion due to timezones (which is exactly what epoch time was invented for).
So for network use epoch with DateTime.now().UnixTimestampMillis
For local script computation tick/os.clock is fine
Sending time without any way to measure ping is bad practice.
Sending time without any consideration of timezone is also bad practice.