Is it worth having a "Wait Unless" function?

When a player enters my game and there’s still some time left until their next daily login reward, the server waits however long they have left and then check if they’re still in the game to grant the reward.

I’m wondering whether it would be worth checking regularly whether the player is still in the server so the server doesn’t unnecessarily use up resources waiting to award the player, especially since this can take hours.

I’m currently using the following function

function utilityModule.fastWaitUnless(n, func)
	local t = 0
	
	repeat
		t = t + runs.Heartbeat:Wait()
	until (t >= (n or 0)) or func()
end

In this case the func function is a simple check

utilityModule.fastWaitUnless(timeLeft, function()
    if not (plr and plr.Parent) then
        return true
    end
end)

I’m not really sure if the extra computation is worth doing.

3 Likes

It might be more accurate? but I don’t see the purpose in having your own wait thing
is there any problems your facing with just a simple wait(n) and checking for player parent?

Computers are fast, so you’ll maybe see a few nanosecond difference per loop if you benchmark this system vs something that waits then checks, but in the end, waiting then checking after the wait has finished yielding is faster, because most of the time players will stay in the game to get the reward, so checking roughly every 60th of a second if they are still in the game would just be a small bit of extra computation.
@Thedagz, a custom wait(n) function is better than roblox’s built in function, simply because wait(n) can sometimes be seconds before it stops yielding. See this thread: Coroutines V.S. Spawn()... Which one should I use? - #10 by buildthomas and this video

1 Like

You misundestood that article the main message that writer was trying to convey was to avoid using wait() not wait(n)

" Let’s talk about wait() . Not wait(n)"

The reason to avoid using wait() is because most people often use it incorrectly in his example he posted that people often use it to wait for something like
repeat wait() until Player.Character
where the alternative can be using events instead
Player.CharacterAdded:Wait()

He does state at the end that wait(n) can trigger much later then usual this is due to the task scheduler most likely be filled with task, since if X task cant be completed in this frame then it gets moved onto the next frame, you should always strive to make optimize code when possible so if you have this issue then you need to address that, not to mention that would still effect custom waits since they still relie on frames to calculate time

(expecting something to run perfectly in time is a bit naive regardless of what method your using)

In summary most of the things stated in that article is mostly true but its mostly intended for newer developers, if you know what you’re doing it’s completely fine using wait() or wait(n)

That post you linked is not talking about wait(n), just wait() with no parameters, there is a difference.

@Thedagz @cjjdawg I linked the wrong topic in my haste to show the OP was correct in using a custom wait function, please forgive my stupidity. Here is the correct topic that shows the actual reason you should not use wait(): Coroutines V.S. Spawn()... Which one should I use? - #8 by evaera and this: Coroutines V.S. Spawn()... Which one should I use? - #10 by buildthomas. I was simply explaining why you would use a custom wait over roblox’s built in function.

The posts that you linked still apply to wait():

“Don’t set yourself up for failure. Use coroutine.wrap if you need to begin a new thread. Never use spawn , delay , or wait() in your code.”

“After switching from spawn to coroutine.wrap / firing a BindableEvent to start a new thread, and using a Heartbeat-based wait rather than wait()”

You only would need to use a custom wait function for very small values(<1)

No problem! we all make mistakes sometimes,
In response to the new article you sent, which she stating mostly that

“has no guarantees about when (or if) it will begin executing the new thread. spawn is especially evil because it seems innocent at first, but once you have a lot of code that all uses spawn , you can see significant delays in execution upwards of several seconds in a resource-intensive game.”

Bit unrelated since we are still not using wait() and using wait(n), but my response to this is that I personally never seen issues with spawn when done correctly… and both are essentially almost the same (I have made a few games before too probably not as many or as complex as her though). I don’t want to get to deep into it but I am assuming she comparing spawn(functioin() end) versus coroutine create vs resume, the reason why this is a unfair comparison is because spawn() does have a builtin yield if you were to put a yield inside of a coroutine it will essentially have the same effect, it will still put task on the task scheduler and can still traffic the task scheduler causing FPS to drop. (I’ve never used coroutines without a yield inside of them)

I have heard that spawn(wait) uses a different task scheduler although I never have found any evidence of this, I also never seen nor heard of anyone seeing threads never executing

Frankly if you suffer more then 1 second delays for spawn your probably not optimizing correctly or using spawn incorrectly since even in my most abusive uses of spawn I never seen more then a 0.04 second delay

Personally I would like to see multiple roblox enginners or even a documentation update based on her post, but from my current knowledge I still firmly believe that wait() is perfectly fine if used properly

If for some reason you do not side with me, and still think that spawn is evil then I would recommand using coroutine.wrap() instead of there bindable event method :slight_smile:

Again I don’t want to get to deep into it or go off topic if you wish to discuss this more with me you can message me here (no friend request needed)
Discord
Thedagz#4176

No, just waiting a long time is completely fine. Periodically checking would cost more (although, still a negligible amount). No resources are used during a wait.

2 Likes

He can do which ever one, the performance saved is nothing. This imo is a micro-optimization and you have much more important things in your game to focus on.

2 Likes

The general consensus seems to be that the performance cost is negligible and that this is more or less of a micro-optimisation.
My main worry was that the amount of threads would build up and cause performance issues over time.

No but I prefer to stay consistent and I’d rather use a custom wait function all the time rather than the infamous built-in wait function.