Aligned Waiting Module: A more accurate way to yield in scripts!

Hello everyone!

This is my very first module, though tested, there still might be some bugs and bad coding. Also I am new to naming things so please give me a better name for it if you think of one.

Ever tried to make a timer, or a function that syncs with the beat of some music, but found your script is slipping behind? I’ve been there. Introducing Aligned Waiting, the simple way to have accurate timing. Basically, if your script slips behind, this new wait system will catch up for you! You can get the source here:



For a quick start, these are the basic functions you will use:

AlignedWaiting = require(4992254085) --Gets the module

AlignedWaiting:Start() --Starts the timer, you must use this before you can use :Wait()

AlignedWaiting:Wait(1) --This is the waiting function, provide a time to wait or use the default (1)



Use cases
Use cases for this would be anywhere you would want a wait() to be accurate. In this example, some text counts up by 1 each second:

while true do
AlignedWaiting:Wait(1)
Time = Time + 1
TextLabel.Text = Time
end



Some notes:
Try to avoid other yielding functions without putting them in a coroutine. If you don’t, the script will attempt to catch up to where it is meant to be, but while it’s doing that it may cause unwanted behavior.
:Start will reset the timer if you use it while already running, useful for if you want to have accurate timing only in certain places.
Do not use the same functions in parts of the script that are running at the same time. We will go through how to have multiple timers running in the same script soon.



Check this out
You may be wondering how accurate this actually is. To test it, I set up 2 while loops making a clock count up by 1 every second. I ran these at the same time as a stopwatch. This picture shows the result after timing for 6 minutes, the green one is Aligned Waiting, the red one is normal wait().

Running multiple in the same script
In the previous bits of the topic, we have been using a default table for the module to work from. The following code shows you how to get a new table:

new = AlignedWaiting:Create() --Makes a new table for the module to use

AlignedWaiting:Start(new) --Put the table as the first argument of this function

AlignedWaiting:Wait(1,new) --Put the table as the second argument of this function

Putting a different table in the same functions will make them run separately from each other. Here is how you might use it:

AlignedWaiting = require(4992254085)

--the first function
function1 = function()
local new1 = AlignedWaiting:Create()
AlignedWaiting:Start(new1)

while true do
AlignedWaiting:Wait(1,new1)
print("hi")
end

end

--the second function
function2 = function()
local new2 = AlignedWaiting:Create()
AlignedWaiting:Start(new2)

while true do
AlignedWaiting:Wait(1,new2)
print("hi")
end

end

These two functions can run at the same time without disturbing each other.

I thought it might be useful to some people to include a way to get the time position the script is aiming to be at so here’s a way to do that:

timepos = AlignedWaiting:GetTimePosition() --Put the timer you want to check as the first argument, or leave blank for the default one



So that’s it, a way to do something as simple as wait() but have it accurate enough to be used for keeping in time with music, an in game timer, etc. Thanks for reading.

4 Likes

If you’re timing something with music doesn’t it make more sense to use the TimePosition property of sounds?

I understand this probably has other use cases, but timing things to songs probably isn’t the best one.

Sounds will play at a slightly different time on server and client too, so TimePosition could be read by the client to perform the interaction there and then it will be timed as close as you’re going to get it.

3 Likes

Thank you for your feedback. Would it be useful if I made a way to use the timeposition of a sound rather than tick()?

I would just like to add that if you need actually accurate time (for example, a timer) then you should always use tick() and/or Stepped/RenderStepped deltas. Internally this module calls wait() so it suffers from the same issues as wait() as far as accuracy goes except this module makes it very slightly less inaccurate (on average it was 30-40ms more accurate than wait but still not near perfectly accurate.)