Avoiding wait() and why

What you have looks fine, but change > PLAYERS_REQUIRED to >= PLAYERS_REQUIRED

2 Likes

Try this to see the accurate time of how much time has elapsed

local RunService = game:GetService("RunService")

local function RealWait(n)
	local DeltaTime = 0
	repeat
		DeltaTime = DeltaTime + RunService.HeartBeat:Wait()
	until not n or DeltaTime > n
	return DeltaTime -- return the time elapsed
end

print(wait(1))
print(RealWait(1))

It’s more accurate then tick()

1 Like

How big of a concern is this? There’s several places in my code where I use tick() to measure time differences, for instance the custom Wait() function that I currently use:

local function Wait(n)
    local now = tick()
    n = n or 0
    repeat game:GetService("RunService").Heartbeat:Wait()
    until tick()-now >= n
    return tick()-now
end

Is this a really bad practice? Should I start using the return of Heartbeat/Stepped instead of tick(), or is the difference not noticeable enough to matter?

1 Like

I’m not sure, I do it too, but I’m just relaying what I’ve heard from engineers.

1 Like

Tick is always correct relative to tick calls made locally, and will work perfectly for testing wait times in this thread. What you probably heard is that tick is not necessarily close to the actual standard unix timestamp, and can vary between the server and clients.

4 Likes

I have a question about this. Let’s say in a game, you give players a certain amount of money per second, or something to that effect. Would you use Heartbeat for this? Something like this:

local function checkLastTime(last, thresh)
	local currentTime = tick()
	if currentTime >= last + thresh then
		return true
	end
	return false
end

local lastPoll = 0
rs.Heartbeat:Connect(function(dt)
    if not checkLastTime(lastPoll, 1) then return end
    lastPoll = tick()
    givePlayersMoney()
end)

As opposed to:

while true do
    givePlayersMoney()
    wait(1)
end

Obviously both options work, but is there any impact in doing it one way vs the other? I don’t like the idea of permanent loops but I also don’t like the extra and isolated Heartbeat connection. But I’m probably just overthinking it. I don’t care about insane precision, but it should be about every second.

1 Like

You can (and arguably should) store a reference to the connection, then disconnect it whenever you are done.

local givePlayerMoneyConnection = rs.Heartbeat:Connect(function(dt)
    if not checkLastTime(lastPoll, 1) then return end
    lastPoll = tick()
    givePlayersMoney()
end)

and later disconnect the event connection:

givePlayerMoneyConnection:Disconnect()

OTOH, if the while loop works for your needs and you’re more comfortable with it then feel free to stick with that until it doesn’t work or you are ready to switch to event connections.

1 Like

I’m aware. But, it won’t ever be done. In that scenario, players should continue receiving money every second forever, so the connection would never need to be disconnected.

1 Like

While the heartbeat method has more overhead (in terms of code you have to write and manage), I would still prefer it. It would also let you sync to the second more properly without drifting at all (but you’d have to redesign it a little bit).

4 Likes

Just came here to add that @Maximum_ADHD did a funny but yet interesting experiment on this:

5 Likes

I understand the instability of the usage of wait(n)'s for the clients. However, with all of the replies, this caused some confusion in me. Does the same apply to the server-side scripts, and wouldn’t repetitive calculations with .Heartbeat throttle the server?

1 Like

Yes. The throttle exists for both sides.

No.

2 Likes

Sorry for the dead topic revival, but I’d like to address a big warning.

Heartbeat, RenderStepped and Stepped have been deprecated. As such, I highly recommend that you use PostSimulation instead of Heartbeat and PreSimulation instead of Stepped.

RunService (roblox.com)

3 Likes

Thanks for the update, I didn’t know this.

Edit: Roblox has not announced these updates yet, so continue using these until a proper announcement from Roblox. Also, Deprecation does not equal removal.

1 Like

Should I avoid wait() that has a number inside or just wait() without any number inside?

1 Like

He already mentioned it in the post:

2 Likes

Hey, don’t abuse the humble wait() >:(

In all seriousness, I do agree with the majority you’ve said.
However, wait() is still very useful for testing out code before you put in anything complex just to get a feel of what they do.

If you want to use a while loop rather than runservice just to check something, wait() is much simpler to type and see.

Overall, wait() does have its place in coding, else it would never be around. I haven’t had many opportunities to use :Wait() but after reading this post, I definitely will make more use of it!

1 Like

As much as I’d like to agree with you, some other’s don’t.

Check this article out. Spawn is evil

Wait, aren’t you supposed to write a function in a modulescript as (module).(function) not just (function)? You’re just writing “wait” instead of module.wait, right? Or am I just stupid

No…modules by default just happen to return tables since you are most likely to write a code library using them, so you would store them in a table. Code libraries have several functions to use. This one just returns a single function, so it is fine to just return the function.