What are the best ways to use task.wait()?

So, from what I have seen, there are many usages for task.wait(), along with wait() that I have seen, and it got me wondering about how to use it properly.

One example I have seen was with a timer system, like so:

-- Normal Version
Timer += 1

-- Better Version
Timer += task.wait(1)

Another way was with the usage of RunService.Heartbeat using its DeltaTime Argument.

But this isnt really about Alternate Usages for a system, This Topic is about Better usages to improve a system, which is something that I want to know.

There are plenty of usages for wait() and task.wait(), and we pretty much see them as ok. but there are plenty of uses where they improve compared to other things.

So what would be a better way to use task.wait()?

As little as possible :slight_smile:

Try making your game event based, if you have to wait a second, wait a second. Counting up time is usually a bad sign.

The difference between your examples is that task.wait will return how much time actually passed while waiting. The “Better Version” will be more accurate to the elapsed time

1 Like

It depends on the specific use case:

If you want to use it with an AnimationTrack to time an event when a certain part of the animation plays, you are better off with using AnimationTrack.KeyframeReached or AnimationTrack:GetMarkerReachedSignal(MarkerName)

If you want to do something like time a dialogue with multiple messages, you can resort to using task.wait()

Whenever you use task.wait() and need a proper delta time (let’s say, a timed event on the server which happens every 5 seconds), you should attempt to always make use of the fact that it returns a delta time. It’ll make your game play better because in case of lag, it’ll not delay for more than 5 second but only until the server unfreezes (in the case of extreme server lag, for example)

It’s also possible to perform that with RunService.Heartbeat in a more optimized manner:

local RunService = game:GetService("RunService")
local TimeElapsed = 0

local function OnHeartbeat(DeltaTime: number)
	TimeElapsed += DeltaTime
	if TimeElapsed < 5 then return end

	TimeElapsed = 0
	-- do the special event here


You should also avoid using while loops to await for a specific connection to fire with a specific element, instead you can do something like this: (example shown on an AnimationTrack)

local Thread = coroutine.running() -- get the current thread
AnimationTrack.KeyframeReached:Connect(function(KeyframeName: string)
	if KeyframeName == "Keyframe2" then -- there would also be Keyframe 1 and etc..
		task.spawn(Thread, 5)
		-- can also be done with coroutine.resume(Thread, 5)

local NewVariable = coroutine.yield()
-- returns the thing task.spawn was called
-- with, alongside the thread

print(NewVariable) -- 5

The same goes for waiting for a variable to change to something specific, use a similar piece of code to what I made as an example (resume the thread where it’s changed)