Skip to content
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

Switching back to previously loaded scene fails using load_scene_from_packed #93258

Open
MM4096 opened this issue Jun 17, 2024 · 8 comments
Open

Comments

@MM4096
Copy link

MM4096 commented Jun 17, 2024

Tested versions

  • 4.2 stable

System information

Godot v4.2.2.stable.mono - Ubuntu 24.04 LTS 24.04 - Wayland - Vulkan (Forward+) - integrated Intel(R) HD Graphics 4400 (HSW GT2) () - Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz (4 Threads)

Issue description

When assigning PackedScenes in the inspector, switching from scene A to scene B using get_tree().change_scene_to_packed(scene) will not let you go from B back to A using the same method, with the status not being OK (instead, 31 or ERR_INVALID_PARAMETER is returned).

Using status = get_tree().change_scene_to_file(scene.resource_path) throws an error instead.

Tested using 3 scenes instead of 2, but A -> B -> C again doesn't let you go back to A from C

Also discovered
In three scene mode
When the project is re-opened, none of the three scenes can be opened, with the Broken Dependencies popup showing up, without any broken dependencies. Opening up any of the other two scenes will also show up the same error pointing to the next scene, the scene specified in the export field. This problem persists until the reference is removed from the resource file through a text editor.

Steps to reproduce

Project given.
In the script.gd file, a boolean parameter is provided to switch between using change_scene_to_packed() and change_scene_to_file(). An exported PackedScene is provided as the scene to transition to. The main page (first scene) is just to select which scene to start with, and has no other effect. Other 2 (3 scenes available) scenes have their numbers put on buttons to differentiate them. Pressing the button takes you to the next scene (scene 2 back to scene 1).

Minimal reproduction project (MRP)

godot_bug_circular_scene.zip

@MM4096 MM4096 changed the title Switching between scenes fails Switching back to previously loaded scene fails using load_scene_from_packed Jun 17, 2024
@huwpascoe
Copy link

If the editor allowed for the creation of these cyclic references, that's a bug (please provide the workflow).

However if these files were manually changed outside the editor to try and bypass that behavior, that can't be helped.

I do have a ready to merge PR that might be an eventual fix to the preloading problem #91815.

@AThousandShips
Copy link
Member

AThousandShips commented Jun 17, 2024

Circular references are indeed not supported, and there's clear errors to indicate this, so this isn't a bug and the error messages should make it clear that this isn't supported IMO

And in my own experience adding circular references in the editor is prevented, so how was this achieved?

Unless this was not handled correctly in the editor, or the messages aren't clear enough, this isn't a bug and it is simply not supported, you can still work with it by loading things with paths, or with UIDs as mentioned above

If there aren't any of those issues here this should be discussed in this proposal instead:

@inhalt120g
Copy link

@AThousandShips

Circular references are indeed not supported, and there's clear errors to indicate this, so this isn't a bug and the error messages should make it clear that this isn't supported IMO

And in my own experience adding circular references in the editor is prevented, so how was this achieved?

Here is how to add a circular reference using the attached project (it's all about one node that spawns the next node when you press a button and removes itself, nodes S01 to S04 all use the same base scene).
Open S04 (it's one of the nodes in the root).
In S04, there's only one node. In the Inspector, you'll see that it has a "target" field. Drag, for example, S01 into it.
Save the project.
Quit to project list.
Reopen the project.
…It won't work.
engage set as handled comparison g43.zip

@inhalt120g
Copy link

Not sure my instructions make sense, so here it is in video format too (only without saving / reopening steps):

2024-06-17.19.18.59.mov

@AThousandShips
Copy link
Member

Then we need to check if something is missing when assigning here

@step-ani-motion
Copy link

Circular references are indeed not supported, and there's clear errors to indicate this, so this isn't a bug and the error messages should make it clear that this isn't supported IMO

And in my own experience adding circular references in the editor is prevented, so how was this achieved?

Unless this was not handled correctly in the editor, or the messages aren't clear enough, this isn't a bug and it is simply not supported, you can still work with it by loading things with paths, or with UIDs as mentioned above

Hey, we just ran into the same Problem in our current Project. In our case, the Editor did not prevent us from doing so or warn us about anything.

This can easily be reproduced in all Versions of Godot with two Scenes referencing each other via PackedScene Reference like this:

extends Node

@export var packed_scene : PackedScene

Attached are two minimal Godot Projects - one for Godot 3 and one for Godot 4 - demonstrating the issue.

Steps to reproduce:

  • open any of the two attached mrp's
  • doubleclick on scene_a.tscn in the FileSystem Dock
  • select the "Scene" Node in the Scene dock
  • verify that scene_b.tscn is referenced from the "Packed Scene" Slot in the Inspector

So far, so good. Now we create a cyclic reference by referencing scene_a.tscn in scene_b.tscn

  • doubleclick on scene_b.tscn in the FileSystem Dock
  • select the "Scene" Node in the Scene dock
  • drag scene_a.tscn from the FileSystem Dock to the "Packed Scene" Slot in the Inspector
  • save the scene

Note that the Editor doesn't give a Warning or Error about cyclic references or anything else and as long as the Project is open, everything seems to be fine.

Now restart Godot by selecting "Reload current Project" from the Project Menu and observe the chaos. At this point, the scenes can only be repaired by editing out the PackedScene References with an external text editor.

Minimal reproduction projects:
bug3.zip
bug4.zip

@GeminiSquishGames
Copy link

GeminiSquishGames commented Aug 27, 2024

This seems to still happen in 4.3... Working on a good example project to illustrate this, but it's kinda hard when the problem messes up the project after it happens. So far it almost seems like using change_scene_to_packed() makes it impossible to use the scene it's called in in the future with any node referencing it with @export var scene : PackedScene by making it null in every @export var across the board, if it exists in a node outside of itself, autoload, or a yet to be instantiated scene they all become null after the call is made. Then when you close the project, you cannot open your scenes as it cannot "find" the dependency scenes, though they are certainly there. Which I thought was supposed to not happen in 4.3 but I may have misunderstood what got fixed.

Scenes won't open in the editor without being fixed, the .tscn fils @exports references need to be cleared in a text editor . https://github.com/GeminiSquishGames/changescenetopacked-problems.

Still also makes these errors. All of this doesn't point to anything letting the developer know about the cyclic reference error with using preload() or using an @export var scene and setting it in the inspector... why can't @export do a load() but with the scene path? That way people won't get this problem? Probably not that simple then...

 scene/resources/resource_format_text.cpp:289 - Parse Error: Busy. [Resource file res://scene_2.tscn:8]
  Failed loading resource: res://scene_2.tscn. Make sure resources have been imported by opening the project in the editor at least once.
  scene/resources/resource_format_text.cpp:289 - Parse Error: Busy. [Resource file res://scene_1.tscn:8]
  Failed loading resource: res://scene_1.tscn. Make sure resources have been imported by opening the project in the editor at least once.
  scene/resources/resource_format_text.cpp:289 - Parse Error: Busy. [Resource file res://main.tscn:8]
  Failed loading resource: res://main.tscn. Make sure resources have been imported by opening the project in the editor at least once.

But it has all the steps needed to reproduce the problem in 4.3 that @MM4096 described.

"How does one get load() like funcitonality out of an @export var scene : PackedScene reference, rather than preload()?" is probably what people want to do. That way if you move the .tscn resource to a new location, it can still find it using FileSystem magic. But that is kind of beside the point if it's still corrupting everything when this happens.

To be clear, is it really a cyclic reference problem, or is it just that change_scene_to_packed() has freed the reference that the scene makes in the first place making it impossible since preload() kind of makes a static reference to the thing? Seems like that would be easy by keeping the reference but simply freeing the instance, not the preloaded scene data, but what do I know?

@huwpascoe
Copy link

I've finished a plugin that could help with this.
#91815 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants