Wait hangs forever in module script

Hello,

I have a module script that represents the class of a fish. I have declared the Move function as follows:

function Fish:Move()
	while true do
		print("Will wait a second")
		wait(1)
		print("Moving now")
		local aim = self:findFrontalPoint()
		if not aim then
			aim = self:findRandomPoint()
		end
		print("Going to move")
		self.bGyro.CFrame = CFrame.new(self.fish.Position, Vector3.new(aim.X, aim.Y, aim.Z))
		wait(1)
		self.bPos.Position = aim
		print("Finishing move")
	end
	print("I Exited the while")
end

This function is supposed to never stop. The actual usage is to make the fish move all the time. It is meant to be put in a coroutine and then run in parallel. However it hangs unexpectedly and without errors. To investigate I called the function normally (no coroutines) and inspected the output.

There are no errors. The wait(1) on the 4rth line just hangs indefinitely after the first iteration. As if the scheduler will not wake the thread ever again. I do not know how to debug further.

The output I get after I call the function is:

Will wait a second
Moving now
Going to move
Finishing move
Will wait a second

Then it hangs forever. I feel like there is something about module scripts that I do not know.

Any suggestions?

It should also never be restarted :wink:

Wouldn’t this never run, since the while true do loop has no condition that would halt it (true is always true)?

2 Likes

Yes, it was placed for testing purposes. I was afraid that the loop might be breaking for some other reason. However, that was not the case.

I am not sure what exactly you mean. I am not restarting it.

Will wait a second

Outputs twice. This leads me to believe you are calling function Fish:Move() more than once. Which will likely cause errors.

It is actually looping since it is a while loop. That is why you see that statement printed twice. The wait is the blocking factor.

Maybe self:findFrontalPoint() could be yielding at some point

1 Like

It should print “Moving now” then, right?

first and foremost, its not very intuitive to make a method specifically for starting a loop.
i suggest, instead, starting the loop when you make a new fish, and the loop calls Fish:Move()

if that doesnt fix the problem, because it probably wont, i cant see anything else. everything is done correctly. try commenting out that first wait(1) and tell me what happens.

Does your main thread ever yield? I don’t think a coroutine will resume unless either the currently running thread yields or it’s manually resumed.

(Don’t take my word for this, I don’t use coroutines much.)

3 Likes

I see that. There is no condition to exit, is what I am trying to say.
You have multiple forever non-ending while loops with waits().

Perhaps something like this would work:

function Fish:Move()
local moving = true
	while moving = true do
		print("Will wait a second")
		wait(1)
		print("Moving now")
              .....
		....
		print("Finishing move")
               moving = false
	end
	print("I Exited the while")
end

I run the code without a coroutine to debug it. What I expect to see, is the main thread never returning from the module while running the while loop. Indeed the call never returns but also the while loop does not run indefinitely, instead it blocks in the wait.

Anyways I solved the issue by putting my while loop inside a different script. The downside is that I do not have access to all of the properties of the class that I defined in the module. It is a workaround but at least it solves my issue. The problem looks to be engine/module related.

There has to be some misunderstanding here for sure. I write in my original post that the loop is not supposed to be exited, ever. My previous reply answers your question about a double call which is clearly not happening here.

I am not looking for help on how to break while loops.