Is there any way to stop infinite yield in output?

  1. What do you want to achieve? i wanna stop the infinite yield because other towers doesn’t need to have that sounds. (that error is kinda annoying)

  2. What is the issue? I get the infinite yield error

  3. What solutions have you tried so far? None

Here’s the variables

local cooldownSound = newTower.HumanoidRootPart:WaitForChild("CooldownSound")
			local EndSound = newTower.HumanoidRootPart:WaitForChild("EndSound")
			local EmptySound = newTower.HumanoidRootPart:WaitForChild("Empty")
			local StartSound = newTower.HumanoidRootPart:WaitForChild("Start")

(is this correct category?)

2 Likes

Use WaitForChild with a second parameter indicating maximum time to wait:

--example
local cooldownSound = newTower.HumanoidRootPart:WaitForChild("CooldownSound", 5)
--this code will run after the instance is found or after 5 seconds:
if cooldownSound then
	print("The sound was found!")
else
	print("The sound wasn't found!")
end

Alternatively you can use more optimal event-related solutions, although that may complicate the code a bit and be code-specific depending on what you’re trying to do.

Also instead of defining the sound at the top you can search for it when you actually need it, to play it etc. So you don’t yield the code for no reason.

4 Likes

try thise

local cooldownSound = newTower.HumanoidRootPart:WaitForChild("CooldownSound",math.huge)
2 Likes

It’s important to remember that all code runs exclusively to the context it’s written in. If a child to wait for hasn’t been established at some point earlier in the code as something that will exist later, it’s almost like there’s nothing to wait for.

I agree that it’s sort of strange, WaitForChild can be sort of unreliable in many cases, so it’s often best to use a ChildAdded connection (or give it some options with a ternary operator [or nil], [or if X then Y else Z]) to break the yield without an error

ChildAdded solution:

local thing = Instance.new('Part')

local face -- establish an object to wait for

face = if face then face else thing.ChildAdded:Connect(function(newChild)
    -- If the face object already exists, this confirms that it exists.
    -- If not, whatever is returned from the Connection will be assigned to the face variable

    if newChild.Name == 'Face' then

        return newChild

    end

end)

Ternary solution:

local thing = Instance.new('Part')

local face = thing:WaitForChild('Face', 10) or nil

if not face then
    -- yield from here using a few different options.
    ----------- repeat wait:
    -- repeat wait() until thing:FindFirstChild('Face')
    -- face = thing:FindFirstChild('Face')
    ------------ or instantiate:
    -- face = Instance.new('Decal', thing)
    -- face.Name = 'Face'
    ------------ or simply return, break, or do whatever else until you're sure the object exists.
end
1 Like

It’s exactly the same functionality with not adding a second parameter, if the instance isn’t there it will yield forever. The only difference is that it removes the warning, so it yields forever and also not tell you about it.

What you provided is also known as the Ostrich algorithm

1 Like

imagine naming an algorithm after a bird that can’t fly

1 Like