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)
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 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
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
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 +=
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
local runService = game:GetService("RunService")
function preciseWait(difference : number)
local start = tick()
while tick()-start < difference do
runService.RenderStepped:Wait()
end
end