What you have looks fine, but change > PLAYERS_REQUIRED
to >= PLAYERS_REQUIRED
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()
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?
I’m not sure, I do it too, but I’m just relaying what I’ve heard from engineers.
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.
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.
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.
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.
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).
Just came here to add that @Maximum_ADHD did a funny but yet interesting experiment on this:
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?
Yes. The throttle exists for both sides.
No.
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.
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.
Should I avoid wait() that has a number inside or just wait() without any number inside?
He already mentioned it in the post:
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!
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.