Is creating a custom wait() function even possible?

I’ve seen a lot of people tried to make their own custom wait(). I tried using @sjr04 but it doesn’t work well for me.

THIS IS NOT SENDING HATE TO HIM.

local RunService = game:GetService("RunService")

local function Pause(n)
    local accumulated = 0
    RunService.Heartbeat:Wait()
  
    while n > accumulated so
        accumulated += RunService.Heartbeat:Wait()
    end
end

If I use this function and tried to pause the thread for 5 seconds, it just waits for 4.5 seconds instead. I tried running multiple tests but none of them satisfies my needs. Am I doing something wrong?

EDIT 1: Turns out it works well for command bars, but if I use in scripts, doesn’t work effectively/

1 Like

I don’t quite understand that well. DeltaTime is used for testing how long does something gets something’s done.

I believe you can make up something as simple as this.

local function Wait(t)
	t = t or 0
	local t0 = os.time()
	
	repeat RunService.Heartbeat:Wait() until os.time() - t0 >= t
end

You should read the thread you linked. Wait on a signal returns the arguments it was fired with. Heartbeat is fired with DeltaTime, so using Wait will return DeltaTime. See RBXScriptSignal for more information on what exactly Wait does.

local deltaTime = Heartbeat:Wait()

OP shouldn’t be calling this twice though.

2 Likes

Still no use, doesn’t wait for the amount of seconds I want.

local Run = game:GetService("RunService")

local function Pause(n)
	local accumulated = 0
	local heartbeat = Run.Heartbeat
	
	while n > accumulated do
		accumulated += heartbeat:Wait()
	end
end

local start = os.time()

Pause(5)

print(os.time() - start)

You sure?

Worth noting that I also switched to os.clock so I could get a more precise measurement of how much time was being elapsed before and after the pause call, since os.time only returns whole seconds rounded. In all cases I’m reaching close to 5 seconds.

Ultimately not sure where you’re running this from or the specs of your device though considering Heartbeat is variable according to the current machine’s specs.

I used os.clock() and it just return numbers llike 4.7…, 4.5…, and not even close to like a 4.9 when pausing it for 5 seconds.

Could you give more information on your testing environment or your device’s specs? You could additionally check more variables in your script such as the DeltaTime being observed by the current iteration or your total time accumulation.

It is possible to create a custom wait and this is pretty much the way it’s done but it is very critical to note that point about RunService events being variable on the current machine. It’s certainly waiting 5 seconds for me but if not for you, some debugging is in order.

I’ve gone ahead and added some markers on the code you replied to me with:

local Run = game:GetService("RunService")

-- {accumulatedTime: deltaTime}
-- Check what the deltaTime was for an accumulated time point
local increments = {}
local deltaTimes = {}

local function Pause(n)
	local accumulated = 0
	local heartbeat = Run.Heartbeat

	while n > accumulated do
		local dt = heartbeat:Wait()
		accumulated += dt
		
		increments[accumulated] = dt
		table.insert(deltaTimes, dt)
	end
end

local start = os.clock()

Pause(5)

print("Time to run:", os.clock() - start)
print("Lowest delta:", math.min(table.unpack(deltaTimes)))
print("Highest delta:", math.max(table.unpack(deltaTimes)))
print("Exact increments", increments)

This is what incapaz used right?

local RunService = game:GetService("RunService")

local function wait(n)
    n = typeof(n) == 'number' and n or 0

    local spent = 0
    repeat
        spent += RunService.Heartbeat:Wait()
    until spent >= n
end

Well, I had this other implementation:
(it just makes sure using os.clock, so it actually takes the certain amount of seconds, SINCE the wait was called, not since the last frame was called, if you want to use delta time from wait, or you’re messing with things that are important to respect to frames, use the function above)

local RunService = game:GetService("RunService")

local function wait(n)
    n = typeof(n) == 'number' and n or 0

    local start = os.clock()
    local spent = 0
    while true do
        repeat 
            spent += RunService.Heartbeat:Wait()
        until spent >= n
        
        spent = os.clock() - start
        if spent >= n then
            return spent, os.clock()
        end
    end
end

Your issues are kind of weird? I’ve never seen anything like that happen to anyone.

CPU: i7-2630QM
RAM: 4GB
STORAGE: 500GB HDD
GPU: NVIDIA GEFORCE GT 540M

yeah it’s a 9 years old laptop

I got a bit confused about why you’re adding 2 tables for DeltaTime.

@LucasTutoriaisSaimo
I’ll try yours soon.

Debugging purposes: one is a dictionary, one is an array. The dictionary is meant to log what the deltaTime is at a certain point of accumulation (when Heartbeat fires) and the array is meant to collect all deltaTimes that have occurred in an array format for checking the minimum and maximum values that get assigned to deltaTime. This can help debug time issues.

1 Like

Idk if this is still a thing but you can try clonetrooper’s thread :man_shrugging:
Its got a custom wait function in it along with a few other things.
https://gist.github.com/CloneTrooper1019/538f0ab2541ef98912a2694dd8d274e7

Weird, if I tried using in the command bar, it works well. In scripts, it doesn’t.

This actually works very well, but I am still curious how would I make one for my own.

Then consider reinstalling Studio and see if it fixes the issue. Have you tried that?

Hm. Maybe it might be some weird beta you have enabled?

1 Like

DeltaTime is the time since the last frame was rendered.

Example

Timer Starts > Frame Gets Rendered > Timer Ends

So if a client would be running at 1 FPS the DeltaTime would be around 1 Second because it takes one entire second to render a frame.

You want to add the deltatime. EX:

local AccumulatedTime = 0
game:GetService("RunService").Heartbeat:Connect(function(delta)
if AccumulatedTime > 5 then
print("Waited five seconds")
else
AccumulatedTime += delta
end)
1 Like

Explanation: .Heartbeat fires every frame, and a new frame will optimally be created every 1/60 of a second. If for some reason, perhaps due to lag, your frame rate drops, a new frame may be created every 1/50 of a second, or 1/42, or even 1/23. You get the idea. Deltatime is the time between frames. If your framerate is low, deltatime will be higher. By adding deltatime, you can correct time lag.
However, if you have a very low framerate then by the time .Heartbeat fires again, time will have passed and you will have overshot.

1 Like

Why are you even trying to make a custom wait function??

2 Likes

Right, I forgot to mention the fact that Roblox’s global wait() function is unreliable in big game structures and big codes.