i know that typically WaitForChild is used when scripts are waiting for something (i.e. a new part called “Specific” to be created and have the parent of Workspace, or when the client-side needs to load its entities) but i want to be specific.
when can i effectively use WaitForChild? should i avoid it like the plague as well?
i noticed in a lot of my older scripts, i tend to use this almost religiously-- it’s everywhere. knowing from this post that i’m likely not supposed to rely on waiting, i want to be able to clean that up a bit so my code is more efficient.
i usually avoid wait() itself pretty good, since in general now that i understand events it’s much easier for me to avoid. but i wonder if WaitForChild falls under this?
I don’t use wait function. especially when i need precise control over the flow of the script. for example if i have a tween running, and i want to pause the next frame a button or something got triggered. i can do it easily using a loop and a variable that counts how much time have elapsed. accumulating Render delta.
So what do I do at times when I actually need wait? For example when I use it to wait a certain amount before setting something like a debounce or something (there is no event so :Wait() won’t work in this case)? will I have to make my own version of wait() using a loop and checking how much time has elapsed with render delta?
You said wait() is inconsistent with how long it actually waits? if so, should i make my own version of wait() as a custom wait? then why does wait() even exist?
local TickAmount = tick()
realWait(1)
print(tick() - TickAmount)
And I Got
0.26110482215881
I Waited Less Than 1 Second.
It Is Not Accurate At All. I Have Read Upon Other Posts Too And All The Implementations Seem To Be Similar But They Are Too Inaccurate. Thank You For Your Time.
Not sure where you’re getting that from. Here’s me putting it in a command line.
> RunService = game:GetService("RunService")
> function realWait(t)
local total = 0
repeat
total = total + RunService.Heartbeat:Wait()
until total >= t
end
> t = tick() realWait(1) print(tick() - t)
0.9992048740387
> t = tick() realWait(1) print(tick() - t)
1.0140511989594
> t = tick() realWait(1) print(tick() - t)
1.0150332450867
Note also that tick() is not actually guaranteed to be correct. I don’t know if it’s written anyway, but I’ve talked to engineers that caution against using it as a measure of time.
I did some similar tests and, I think it’s because heartbeat throttles when the game first starts, this should settle down after a few seconds.
Module Script
local RunService = game:GetService("RunService")
local Heartbeat = RunService.Heartbeat
return function(n)
n = n or 0
local Delta = 0
repeat
Delta = Delta + Heartbeat:Wait()
until Delta >= n
return Delta
end
Script
local wait = require(location to module script)
while true do
local Tick = tick()
wait(1)
print(tick() - Tick)
end
function RoundController:WaitForPlayers()
while #Players:GetPlayers() < PLAYERS_REQUIRED do
wait()
end
end
function RoundController:StartIntermission()
local beginTime = os.time()
while (os.time() - beginTime) < INTERMISSION_LENGTH do
wait()
end
end
I’m assuming the proper way to fix them would be like this:
function RoundController:WaitForPlayers()
local yield = Instance.new("BindableEvent")
local x = Players.PlayerAdded:Connect(function()
if #Players:GetPlayers() > PLAYERS_REQUIRED then
yield:Fire()
end
end)
yield.Event:Wait()
x:Disconnect()
end
function RoundController:StartIntermission()
local yield = Instance.new("BindableEvent")
delay(INTERMISSION_LENGTH, function()
yield:Fire()
end)
yield.Event:Wait()
end
please tell me if I did this the correct way, because I don’t want to make my code worse. thanks
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))
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?
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)
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).