-
-
Notifications
You must be signed in to change notification settings - Fork 18.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changing scene after three yields closes the game. #5247
Comments
It seems to be very similar to #4658, if any of those will be fixed we need to check other one. |
Using |
This is pretty much the same as #4658. Checking the test project there results in the same exception in the same spot. I'm not sure how to debug it though, it seems there's some corruption in the heap (if I understand it right). So I guess it's needed to evaluate with Valgrind or something. |
I ran some tests and it turns out that it doesn't matter whether the yield command is used directly in the _ready-method or in a method of its own. I changed the sample code above by moving everything after line 3 into a new method so that it looks like the yield()-sample-code from the official documentation (http://docs.godotengine.org/en/latest/reference/gdscript.html?highlight=yield#coroutines). What does matter though is whether reload_current_scene is called from within _fixed_process() / _process() or not. If I just move it to the end of the new function it works:
Another thing that also works (and would be a workaround for the case above) is using another yield-call to delay the reload_current_scene()-call like this:
Maybe this helps eliminate some theories about where to find the bug. |
Ok, I had another idea and I think I found something important. This code works:
I think that the actual problem is a race condition. By reloading the current scene the node is placed in the scene tree again and the _ready()-method is called again. But since the _process()-method was reactivated immediately and the space bar was still pressed reload_current_scene() was run again. This isn't a problem if loading the scene was finished, but if there are too many yield()-calls the engine tries to continue a yielded method in an object that was already destroyed. Putting the "set_process(true)"-line behind print("test 2") also crashes but putting it behind print("test 3") works, so to me it looks like a race condition. So to fix it yields would have to check whether the object they are referring to is still valid. And imho it shows that Godot is in dire need of better error messages. If there had been anything about an invalid reference this would have been a lot easier to debug (assuming that my theory is correct). |
While I can't deny that some error messages are cryptic, this issue is about a crash, and since it's crashing there's no time to send any message, it just fails. Thanks for looking into this. The problem is likely what you said: when it reloads the scene it loses the reference but the |
I am not talking about a popup or something, just an assert() resp. an ERR_FAIL_COND() so the debugger is stopped with a message (which imho should have a second parameter so you can specify a message that rephrases the condition in human readable form, but that's a discussion of its own and doesn't belong in this thread). |
Operating system or device - Godot version:
Ubuntu Linux / 2.1 alpha official
Issue description:
Having three or more yield within a function (it also happens if the yields are in different scripts) and reloading or changing the scene after those yields are already over closes the game. It only happens with three yields or more.
Steps to reproduce:
Set three yields in "_ready":
yield(get_tree(), "fixed_frame")
and then reload the current scene:get_tree().reload_current_scene()
when pressing a key.Link to minimal example project:
YieldDemo.zip
The text was updated successfully, but these errors were encountered: