Improve Custom Wait Function

I want to know how I can improve my wait function. Any criticism or feedback is appreciated.

local RunService = game:GetService("RunService")
local heartbeat = RunService.Heartbeat

local wait = function(waitTime)
	assert((waitTime ~= 1/0),"WaitTime is undefined.")
	local startTime = tick()

	while (tick() - startTime) <= waitTime do
		heartbeat:wait()
		if (tick() - startTime) >= waitTime then
			break
		end
	end
end
1 Like

First of all, why don’t you just use wait()? There is a function implemented in Roblox for that.

Wait is put in Roblox’s second queue and isn’t exactly accurate. Evaera outlined some of the issues with it here https://eryn.io/gist/3db84579866c099cdd5bb2ff37947cec

2 Likes

To avoid extra comparisons and arithmetic, you can just have your end time calculated first. Also, tick() will be deprecated in the future, so os.clock() is preferred.

Here’s an alternative way of writing it:

local function wait(waitTime)
    -- the assert should check more cases so I didn't add it here
    local endTime = os.clock() + waitTime

    while os.clock() < endTime do
        heartbeat:Wait()
    end

    return os.clock() - endTime + waitTime
end

The changes also include dropping the check inside the loop, because it’s unnecessary as the loop jumps right back to the condition anyways. You can also return (an approximation of) the delta time to better mirror wait()'s original behavior.

10 Likes

Well in my opinion, you should never code a timeout function like that. The function is basically polling until os.clock is equal to the time which is pretty accurate. But the real issue, is the longer you wait, the more dangerous this function is. Since, each frame you call yieldMethod:Wait(), you are adding an instruction to the task scheduler and when you delay the task scheduler to do a certain task, it will move the future task on to the next frame which to be concise, delays the other tasks. So the expense of this function is based on how long you poll for. You can search up what the roblox task scheduler is for a more clear explanation.

No. Yielding just pushes the same thread back into the scheduler. No extra work is done.

3 Likes

Well I just asked someone and this was their response

2 Likes