Dynamically loading scenes via script, is it possible? (Resource: is already being loaded. Cyclic reference?)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By acwr

I currently have a setup where a node has a door.gd script, which looks like this:

var root
# this loads a .tscn which I want the door to trigger and load
export(Resource) onready var node
signal door_entered

func _ready():
	root = get_tree().get_current_scene()
	var _sig = self.connect("door_entered", root, "enter_door")

func enter_door():
	emit_signal("door_entered", self)

I have a script which listens to this signal and then adds the resource var node as a child of the main game node/tree. So far so good! Everything works from a single script without needing to hard-code a hundred resource paths!

UNTIL, I put a door in the to-be-loaded scene which would intend to return the player to a previous scene.

Visual: (Room = [ ], Door to new scene = >, door to previous scene = <)
Example A: [ >][ >][ >] = All good! All doors lead to unique scenes
Example B: [ >][ >][< ] = Game over. Last room tried to return to a loaded scene.
Now the game won’t even start, throwing errors like:

ERROR: Resource: 'res://screens/exploration/Exploration.tscn' is already being loaded. Cyclic reference?
   At: core/io/resource_loader.cpp:361
ERROR: poll: res://screens/exploration/Exploration2.tscn:13 - Parse Error: [ext_resource] referenced nonexistent resource at: res://screens/exploration/Exploration.tscn

I’m not entirely sure why the scene is being unpacked including all its children, etc., etc. But anyway, cyclic reference seems like it should be easy to deal with… just, don’t load a resource that’s already loaded… But then how would I set the variable as a reference to the loaded resource?
(I assume something like: export(Resource) onready var node_resource = node_resource if not node_resource.exists() else ReferenceToCurrentlyLoadedResourceGoesHere?)

I think solving this would also solve the bogus referenced nonexistent resource error.

As a side note, it feels like prepping a resource for use should not get this far ahead of itself. Its not until later that the resource is even instanced or added to the tree, so why is it processing all this?

:bust_in_silhouette: Reply From: Lopy

When a Resource is loaded, all resources it depends on are also loaded, recursively. Sadly, loops are not allowed, so [ >][< ] is impossible.

To go around this, you can export a String instead, and call load() on it inside your _ready.