If you’re planning to use larger values (such as 10 seconds), it should run fine; it wouldn’t hurt for a countdown to fluctuate by 0.1-1%.
I would’ve expected someone to have made them a thing by now; they’ve even stolen Jasmine (a testing framework) and stuck it into the CoreScripts.
I always used:
repeat wait() until players.LocalPlayer.Character
I never knew
local character = player.Character or player.CharacterAdded:Wait()
was faster/even existed so will be using this from now on! Great tutorial!
Dang it, sorry for the necro-bump!
Thank you so much for explaining this.
wait() is generally snake oil when it comes to performance and such.
The worse thing is,
wait(5) can make the script wait at least 10 seconds if the client is not performing well in terms of FPS. So that’s why I’d prefer anything but
Though we’ve embarrasingly used
wait() in our lives, it isn’t like that will be removed any later on. It’s a good start for newcomers, though. They’ll eventually learn to use
It’s not really related to FPS. A client rendering at 60Hz can still have delayed resumes on yielded/newly created threads. It’s just a matter of how many yielded threads you are trying to resume at a certain moment. There’s a quotum on how much can be resumed every 2 frames.
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?
Nothing wrong with WaitForChild, no.
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?
Implementing a custom wait is pretty easy.
local function realWait(t) local total = 0 repeat total = total + RunService.Heartbeat:Wait() until total >= t end
Hi I Tried Your Method Doing
local TickAmount = tick() realWait(1) print(tick() - TickAmount)
And I Got
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.
Hi Again, I Tried A Different Waiting Time.
local t = tick() realWait(5) print(tick() - t)
I Don’t Think It Is Due To
Because I Have Used It In Other Places In My Code And It Works Reliably. I Now Waited Even More.
However At Least It Is More Accurate Than
Using The Delta Time Return Value Of Wait (For 5 Seconds) I Got
2.1 Extra Seconds.
Time this with a stopwatch, and not through Roblox. Let me know the results, this code is extremely basic and battle tested.
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.
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
local wait = require(location to module script) while true do local Tick = tick() wait(1) print(tick() - Tick) end
2.1537821292877 1.0095615386963 1.007693529129 1.0085482597351 1.0157716274261 1.0159933567047
So currently I have these 2 functions:
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
What you have looks fine, but change
> PLAYERS_REQUIRED to
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
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.