cc: @Secretum_Flamma, I think this is the thread that you are on about:
You should try and avoid wait() and any infinite loop in production code if you can:
Lua is single threaded meaning one task runs at any given time and the task scheduler decides when each task is ran. Each time you add a new script you aren’t actually creating a new thread for that script because the script has been coroutined. coroutine or spawn(f) don’t actually create new threads like in multi-threaded languages because Lua is single threaded at this present time but instead it is telling the task scheduler to run the code in a manner that looks like it is running at the same time.
You may be thinking why does this affect wait() and I have had no problems with using wait(). Whenever you call wait(), you are yielding the current ‘thread’ and letting other ‘threads’ run. The problem then comes when the wait() has finished waiting because it needs to wait for a slot to resume. When your code becomes more intensive wait starts waiting several seconds longer than you specified it to wait.
To avoid using wait() and loops you should always use events when you can because Roblox has events for everything you can think of. For your use case you could use RunService.Heartbeat and check the time difference through tick(). From my knowledge Heartbeat is more reliable than wait and a better option than using a loop. Here is a little bit of code that should serve your use case:
local RunService = game:GetService("RunService")
local Duration = 3
local StartTime = tick()
local EndTime = StartTime + Duration
RunService.Heartbeat:Connect(function()
if tick() >= EndTime then
-- Do what you want to do when the time has reached 0
StartTime = tick() -- Puts the start time to the current time
EndTime = StartTime + Duration
end
end)
Sorry if this code looks messy but you should be able to modify it to fit your use case. You should also note that you shouldn’t overuse Heatbeat.