Instance:WaitForChild(string Name [, int TimeOut])

A timeout for WaitForChild that after (int) seconds, the method will either throw an error or return nil. The default with only a name provided would not time out.

Yay or nay?

1 Like

Don’t see a point in it since your code should already be setup so that it doesn’t need to time out.

Nay, 99% of the use cases would be error prone, I can’t see most code that waits for things actually being able to handle them not being there. A better solution is needed.

I’m a fan of the WaitForChild-causing-a-warning-on-long-waits approach.

4 Likes

[quote] Nay, 99% of the use cases would be error prone, I can’t see most code that waits for things actually being able to handle them not being there. A better solution is needed.

I’m a fan of the WaitForChild-causing-a-warning-on-long-waits approach. [/quote]

Not error prone if used with checks for nil, like if you just used WaitForC to check if a newly created/loaded model has an instance in it, and you don’t know if it does or not, the timeout could be a useful feature instead of having a wait, then a FFC check

I think it’s a given that if it’s going to return nil of the object is not there then the coder will create a case for if it’s there/not there… that’s the whole point of having it.

[code] obj = super:WaitForChild(ā€˜obj’, 30);

if obj then
–obj is there
else
–obj isn’t there
end[/code]

I think it’s a given that if it’s going to return nil of the object is not there then the coder will create a case for if it’s there/not there… that’s the whole point of having it.

[code] obj = super:WaitForChild(ā€˜obj’, 30);

if obj then
–obj is there
else
–obj isn’t there
end[/code][/quote]

The thing is though, this method shouldn’t need to time out. When you use :WaitForChild() it should be on something you know will be there.

If you want to check if an object is somewhere, then you should use :FindFirstChild()

I think it’s a given that if it’s going to return nil of the object is not there then the coder will create a case for if it’s there/not there… that’s the whole point of having it.

[code] obj = super:WaitForChild(ā€˜obj’, 30);

if obj then
–obj is there
else
–obj isn’t there
end[/code][/quote]

The thing is though, this method shouldn’t need to time out. When you use :WaitForChild() it should be on something you know will be there.

If you want to check if an object is somewhere, then you should use :FindFirstChild()[/quote]

The timeout would be a (hopefully) more efficient alternative to

local timeout, obj = 60, nil; repeat obj = super:FindFirstChild('class'); timeout = timeout - 1; until timeout == 0 or obj;

To elaborate on what I mean by ā€œerror proneā€ in this context:

The code that uses the time-outed WaitForChild itself would not necessarily be error prone (although I’m not convinced that most people could write non error prone code using it) in and of itself.

The error prone aspect that I’m talking about is the fact that if your WaitForChild is timing out, there’s going to be a real underlying problem most of the time that you really should be fixing rather than using a timeout band-aid. That is, most of the time, the fact that the WaitForChild is taking too long is an indication that some code somewhere in your project is broken and needs fixing, not that there is a problem with the WaitForChild and you should be adding a timeout to it.

On top of that issue, I’m not convinced that it’s actually reasonable to write code that handles a timed out WaitForChild in most cases. Consider this: What is your code going to do if the WaitForChild’d item actually does arrive, but after you’ve already handled it not arriving? Nothing? That’s probably going to cause problems, and it’s pretty hard to write code to correctly handle things when that situation does come up.

@Stravant

You bring up some excellent points, however I know a few users including myself have had issues with our code where the WaitForChild item never arrives, and we don’t even notice it because it yields the entire thread and there’s no way to warm myself that it hasn’t arrived after X amount of time without rigging my own WaitForChild that times out. One of my points of the timeout idea is to help with debugging, and helps the coder know ā€œDid I misspell?ā€ or ā€œWait, did I instance the object in time/at all?ā€. It’s assumed that people who are timing out their WaitForChild in these cases can handle when it’s not there with some alternative code or a warning

"One of my points of the timeout idea is to help with debugging, and helps the coder know ā€œDid I misspell?ā€ or ā€œWait, did I instance the object in time/at all?ā€. "

I understand those needs, but I don’t understand why you think a timeout is the right way to fill them. All the timeout is going to do is hide the problem, or move the bug to a different place than it is actually ocurring (now you have a nil variable possibly referenced in an entirely different location instead of a wait that’s hanging forever where the problem actually is).

That’s why I suggest the throw-warning-after-set-delay solution, it helps with debugging just as much, and doesn’t encourage people to band-aid the problem.

I also suspect that even most of the rare cases where you’d want timeouts, you’ll find that you really need a more sophisticated instrument than a WaitForChild with timeout to write the logic that you actually want (Suppose for instance that you chain 20 waitforchilds, each with a timeout of 10 seconds, is the user waiting 3 minutes really an acceptable outcome? Because under that code that is a possible outcome.)

Totally support this!
In many cases while I script, a script isn’t working and it outputs no error. Usually its because a waitforchild is waiting for a misspelled object. Having a timeout would make things easier.

Bump. I would really like the long-wait warning that Stravant described in his first post. I’ve spent close to hours debugging when I accidentally delete something from the game and find out I was waiting for it in in a script.

3 Likes

Bumping because I think this should be in the engine. Regular WaitForChild is too tedious because it will not notify you it’s still waiting.

function waitForChild(parent, name, timeout)
    local start = tick()
    repeat wait() until parent:FindFirstChild(name) or (timeout and tick() - start > timeout)
    return parent:FindFirstChild(name)
end

Not an optimized solution, but I don’t see why this is so difficult for you to write if you need it.

I think it would be super great to be able to provide a time until a warning is thrown. So the waitforchild behaves like usual, but if you provide a time and it waits for longer than that time a warning will be printed that tells you what object is waiting for what name, for how many seconds, and what line of what script called the function. The warning doesn’t cause the WaitForChild to change its behavior though.

Because you have to include it in every single script, clientside or serverside, in the entire game. Don’t put it one and use WaitForChild in that script? Oops – no more timeout warning. ROBLOX created the WaitForChild method even though it could be accomplished by that same function, and the same principle applies here. If we need to rewrite a ROBLOX function every time we use it, that should be a big red flag that something is probably wrong.

1 Like

We’re considering adding a studio setting to warn after a set amount of time. There’s some internal discussion on this too, but I want to get the community’s feedback.

Behavior would look closely like Nevermore’s current WaitForChild implementation, where after a set time (5 seconds),

What behavior would you prefer? Would a warning after a few seconds be annoying (i.e. is anyone using children + WaitForChild as a hacky yield system (i.e. MyFlagsFolder:WaitForChild("FlagGameReady"):Destroy()))

1 Like

Is it possible to get the warning to display in the in-game developer console as well? Occasionally I’ll come across a bug where I’m waiting for something to exist with WaitForChild, and it works fine in Studio, but it never exists online because of lack of replication (e.g. me waiting for something to exist that was created by the client in a FE game). It’d be awesome if it were possible to get warnings in-game as well.

Regarding the hacky usage of WaitForChild though, I personally never use it to wait for something that’s parented minutes later – I always use it to wait for pre-existing children that haven’t loaded in yet.

This would be possible if we changed default behavior to always warn on timeout. This will be fine unless someone is using WaitForChild to yield threads to handle tasks in their game code. In that case, the warning becomes annoying.

I sometimes use WaitForChild for certain object markers to be found, but typically those systems only yield for a quarter-second or so.

I feel like I’d rather have a second parameter called ā€œtimeoutā€ or something and it would throw an error if that amount of time is reached. Leaving the parameter out would assume no timeout thus allowed to wait indefinitely. Example:

local success, someItem = pcall(function()
   -- Maximum yield of 5 seconds; throw error if elapsed time exceeds given timeout:
   return model:WaitForChild("SomeItem", 5)
end)
if (not success) then
   error("Something ain't right: " .. someItem)
end
2 Likes