Sorry I probably can’t (not on pc atm) but it happened to me in multiple places with different scripts.
Basically it yielded infinitely anything after the line with customwait does not worked.
Example:
local cwait = require(game:GetService("ServerScriptService").CustomWait)
function module:New(n)
print("x")
cwait(n)
print("y")
end
And yeah I required both module scripts .
Edit: Hmm thats odd maybe can this be caused that I actually clone the ModuleScript?
If your game uses wait() a lot, then yes. wait() being used more often can cause major slowdown for events in your game. If you want to know more, read this thread.
I thought Heartbeat was better for this kind of stuff?
Someone mentioned it to me and it made sense, so I don’t know if it’s something people wrongly think? I don’t know.
I see now that my post was awful. So what I meant:
instead of writing;
while true do
print(“test”
wait(1)
end
you can write:
heartbeat:Connect(function()
if tick()-oldTick > 1 then
oldTick = tick()
end
end)
so you are basically checking if the time difference is more than 1, instead of waiting 1 second before re-running the “loop”.
AND THAT leads me to another question:
is the tick() method just as good as your module, for all things loops? And what is the difference between @Maximum_ADHD 's module and yours? Thanks.
I want to ask this question just to clarify, I scrolled through all of the posts and haven’t seen this addressed.
Do you recommend that this module be used in any game regardless of wait count or frequency? Is it a guarantee that your performance will be better? Or do the performance benefits of this module only apply in situations where there is a significant number of yields to actually clog the task scheduler.
The latter - there’s not really a reason to use this unless you rely on yields quite a bit. My game doesn’t really use wait itself all that much, but it does use a custom version of Debris:AddItem, which uses this module.
It doesn’t do any harm to use this module even if your game isn’t calling yields a lot, though.
It is not necessarily true. I ran some tests with your module and the regular “loop with Heartbeat:Wait()”. The result showed “loop with Heartbeat:Wait()” is slightly more accurate. My test code and outputs are provided below.
Test code:
local o_clock = os.clock
local c_yield = coroutine.yield
local c_running = coroutine.running
local c_resume = coroutine.resume
local Yields = {}
game:GetService("RunService").Stepped:Connect(function()
local Clock = o_clock()
for Idx, data in next, Yields do
local Spent = Clock - data[1]
if Spent >= data[2] then
Yields[Idx] = nil
c_resume(data[3], Spent, Clock)
end
end
end)
local function wait2(Time)
Time = (type(Time) ~= "number" or Time < 0) and 0 or Time
table.insert(Yields, { o_clock(), Time, c_running() })
return c_yield()
end
local function loopHeartbeat(seconds)
local elapsed = 0
local timeout = seconds or 0
repeat
elapsed = elapsed + RunService.Heartbeat:Wait()
until elapsed > timeout
return elapsed
end
wait(10) -- Wait 10 seconds for "Play Solo" to be stable
local function test(waitFunction, runCounts)
local totalTime = 0
runCounts = runCounts or 30
for i = 1, runCounts do
local waited2 = waitFunction(1)
totalTime += waited2
print(waited2)
end
local averageWaitTime = totalTime / runCounts
print("Average wait time: ", averageWaitTime)
return averageWaitTime
end
print("Pyseph's BetterWait")
local result1 = test(wait2)
print("Loop with Heartbeat:Wait()")
local result2 = test(loopHeartbeat)
local delta = result2 - result1
print("Final Results: ")
print("Pyseph's BetterWait average wait time " .. result1)
print("Loop with Heartbeat:Wait() average wait time " .. result2)
print(
"More Accurate Function: "
.. (delta < 0 and "Loop with Heartbeat:Wait()" or "Pyseph's BetterWait")
.. " by "
.. delta
)
Edit: Swap “Heartbeat” with “Stepped” is more accurate.
local function loopStepped(seconds)
local elapsed = 0
local timeout = seconds or 0
repeat
local _, delta = RunService.Stepped:Wait()
elapsed = elapsed + delta
until elapsed > timeout
return elapsed
end
Your benchmark is flawed…
First off, you do not type check properly for whether the input is a number or not, and also whether it is smaller than 0 or not. This already makes your function more performant (and not to mention that you use Heartbeat instead of Stepped to make the comparison more equal).
Switching to Stepped and adding the number check, you get this (forgot to rename Heartbeat:Wait() to Stepped:Wait()):
Now, yes, this does seem as if the latter is better, but I’m doubtful you are going to have one yield in your whole game. Utilizing tables is inevitably going to be a better option for updating several waits - I in fact don’t even recommend using this module if you’re going to barely use yields! You should only use this when you’re starting to worry about clogging your task scheduler, which is the real enemy here.
EDIT: I realized I came off as rude here… Definitely not the intention. TL;DR is that you shouldn’t use this module unless you use wait a lot.
Only differences are:
A) this version is more compact
B) slightly more performant (you shouldnt need to care about this though), and
C) publicly available on devforum.
Hey, I think you might have already talked about this, but I need a bit of clarification.
Is it performant to use wait() with an integer? Ex: wait(1)
Although I rarely use wait() by itself, I do use wait(integer) and the delay function quite frequently.
I’m writing the “engine” for a game I’m making, and I’d like to know what’s most performant early on before I have to sift through piles of code.
Depends. If you call wait(1)100 times across your game code, I.e have 100 active yields, then it’ll start to turn a bit sour. The task scheduler gets flooded whenever it has to yield and resume a lot of threads - which is especially easy to occur when you call wait(). wait(1) can still flood the task scheduler, but it’s more unlikely. So in the end, it depends.