Is the only way to detect whether it has been X amount of minutes by using wait() or loops?

Basically wait() tends to not be very accurate and I wouldn’t want hundreds of loops either.

1 Like

I’d recommend using task.wait() as it’s a lot more reliable. You can learn more about it from this post here, but in summary it pauses the thread until the specified time has passed.

Hmm. However, since it’s based on runservice wouldn’t it be massively affected by client hardware and server performance?

wait is already probably based on client performance, and it sometimes “helpfully” throttles itself to save performance, so task.wait wouldn’t be much worse in terms of precision.

I see. So what would you recommend me to use to despawn an object after an X period of time?

My recommendation, do something like this:

local TimePassed = 0

RunService.Heartbeat:Connect(function(deltaTime)
    TimePassed += deltaTime

    if TimePassed < 120 then
        return
    end
    TimePassed = 0

    --\\ Do something
end)
1 Like

How is that more performance effective than a loop though?

This is from the dark ages, but some version might still work on roblox. I used to create a master table of event timers. Each time I would add a new event, I would put it in chronological order in that table with the time stamp when the event would trigger. Some events would jump to the front of the line, and others to the end.

Then I would only monitor the first value in the table, and compare it to the system time. Run it in a loop, when current time > event time, process the event. I was monitoring every event with a single if statement.

It was efficient enough I never needed to re-optimize it. I will be recreating this soon for my combat loop.

You can do this

local t = tick()
repeat wait() until tick()-t >= timeLength
local timeRemaining = 120
repeat timeRemaining -= wait(1) until timeRemaining >= 0  end

Is there anything other than loops? repeat is basically the same as a loop.

Also, this isn’t accurate as a roblox wait() will not be accounting for the excess time therefore it will actually be way longer than 120 seconds.

I’m on mobile, so my code might be wrong. I’ll revisit it tomorrow.

‘’’lua
local function timeFinished()
print(“done!”)
end

local connection

connection = script:GetAttributeChangedSignal(“Countdown”):Connect(function()
local value = script:GetAttribute(“Countdown”)

if (value <= 0) then
    connection:Disconnect()
    timeFinished()
else
    wait(1)
    script:SetAttribute(“Countdown”, value - 1)

end)

script:SetAttribute(“Countdown”, 120)

print(“Hello, I’m printing before the time finishes!”)
‘’’

(Cannot format code because I am on mobile)

I wasn’t asking for a countdown. But anyways I think I’ll stick to the delay function. Runservice is probably the best method of a countdown.

That’s just the name of the attribute, it waits 120 seconds then it runs a function.

That method is actually worse than using wait(120).

How is that? It is completely asynchronous, free of memory leaks, and achieves your goal…

Using wait(120) is more accurate than using 120 wait(1)s because wait() won’t take account of the excess time therefore if the client decides to freeze their tab for an X amount of time then it ends up being way longer than 120 seconds and remember they can do it at any of the wait(1)s whereas using a single wait(120) means there will only be 1 excess.

If you don’t mind me asking, what is happening after the wait()?

The reason I’m asking is that if you are destroying an object(s) you can use the debris service although I am unsure about it’s accuracy. Debris | Roblox Creator Documentation

I do not know of any other methods outside of wait() itself and loops so those may be your limit.

You can use Promises to generate an event after a delay without using a while-loop. I’m not at home so I can’t check if Promises use while-loops under the hood. Anyway, look into Promise.delay() which you can use to execute some code after a specified delay.