Alternative to wait function

I have heard that wait can be very imprecise especially if your using it in a lot of scripts. So I was wondering if there were any precise alternatives that preferably stop execution in the thread it is called from? I have read a few potential ones but they all either use wait or something else with similar problems(Defeating the purpose of having an alternative) or renderstepped(Kind of a bad solution because they were implemented assuming it was running at exactly 60fps also only works on client)

2 Likes

I use a custom wait

I call it sleep() because it looks clean

If you’re feeling really ambitious, could you use a signal system?

local function wait(seconds, callback, ...)
    local timeElapsed = 0

    local tempListener; 
    tempListener = runService.Heartbeat:Connect(function(dt)
        timeElapsed += dt

        if timeElapsed >= seconds then
            callback(...)
            tempListener:Disconnect()
        end
    end)
end


wait(4, function() print'hello world' end)

This module by CloneTrooper1019 is what I use. It’s faster than a normal wait.

This wouldn’t pause the thread which is probably what they want

There’s really no good way to yield a thread efficiently (imo), unless you used coroutines then maybe that’d be better. Generally, there’s really no reason to use the wait global that much unless for stuff like lobby countdowns and such. I’ve been getting around fine by using :Wait() on specific events I need to yield for, and also by using implementations such as this, more of a ‘timer’ based approach than actually yielding the thread.

here’s a none efficient but precise alternative for wait()

local function Rwait(n)
	local dt = 0
	while dt < n do
		dt = dt + RunService.Heartbeat:Wait()
	end
	return false, dt
end

This was what they originally asked for, and your implementation still has the inaccuracies of doing something like, what you’ve basically done is just write a custom delay

function Thread.Wait(length)
	local Start = os.clock()
	while ((os.clock() - Start) < length) do
		RS.Heartbeat:Wait()
	end
	return os.clock() - Start
end

1 Like

They were concerned about performance, so I told them about performance.

It’s better than wait. I saw a benchmark with it being called on many objects each frame I believe and it was horrendous. (opening/closing doors)

If you have an alternative that always waits precisely the exact amount of seconds specified, let me know :slight_smile:

honestly I don’t know what the best custom wait is but a custom wait is the way to go when replacing wait()

I tested this and it appears to be precise to about 26 milliseconds when I was running it in 1k different threads with a 1 second delay

local function Rwait(n)
	local dt = 0
	while dt < n do
		dt += RunService.Heartbeat:Wait()
	end
	return false, dt
end

line 4 can be shortened with +=

1 Like
local function BetterWait(waitingAmount: number?)
	local currentThread = coroutine.running()
	
	local listener;
	local timeElapsed = 0
	
	listener = RUN_SERVICE.Stepped:Connect(function(dt)
		timeElapsed += dt
		if (timeElapsed >= waitingAmount) then
			coroutine.resume(currentThread, timeElapsed) -- Resuming the thread
			listener:Disconnect() -- Disconnecting the signal
		end
	end)
	
	return coroutine.yield(currentThread)
end

you do know you forgot to define RUN_SERVICE
easy fix tho

It’s defined in my actual full script. I just copied from there and pasted it here.

my point was they wouldn’t have it defined initially

1 Like
local runService = game:GetService("RunService")

function preciseWait(difference : number)
 local start = tick()
 while tick()-start < difference do
  runService.RenderStepped:Wait()
 end
end