How to achieve rooms with two way doors without cyclic scenes

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

Hey everyone, how would you go about creating a world with rooms that can be entered, left, and re-entered? I’m new to the Godot Engine and trying to learn best practices so I’ve been binging various tutorial series, with this question specifically relating to what was said on this video by GDQuest. I’ve already downloaded the files and messed with a few different ways of accomplishing the task, but it seems pretty set in stone that scenes can’t ever circularly reference themselves.

So my question is how one would create a world where scenes (rooms, levels, whatever you’re creating) have doors/portals/whatever that go both ways. I’ve thought of a few ideas but wanted to get an idea of what the best practice is:

  • My first thought is that the issue is due to the Portals themselves. Even if you try to preload every scene into the Portal and then tell the node which of those preloaded scenes to switch to (instead of giving it the packedscene it should switch to directly), you still get an issue because all the scenes are preloaded and the portal is a part of those preloaded scenes.
    • So my thinking is that you’d want some sort of World node that could have all the scenes preloaded and controls the actual teleportation. It’d always be the current scene, and the “current level” of the game would be instanced inside of this World node.
    • The actual portals in the scenes would then only have to signal up to the World which scene to switch to (or maybe signaling the scene to signal the World, I’m still figuring out best practices with signals so suggestions there would be appreciated as well).
  • I’m not a fan of this second idea since it wouldn’t work for two way doors that you can just enter and leave and enter and leave repeatedly, but you could have the door link back to a clone of the original level.
    • So A has a door to B and B has a door to C which looks exactly like A so as far as the player is concerned they went back to A. But then to go back to B you’d actually be going from C to D, and then D to E, and etc…
    • The real nail in the coffin is that making any changes to the rooms would be a pain as you’d have to go back through all the clones and make the changes (or re-clone everything).
  • My final idea is that there’s a better way to export the variable or do the teleportation. While I understand why a cyclic scene is a no-go, I’m not exactly following why this portal causes a cyclic scene.
    • From a high level, it should be instancing a different scene and replacing the current one with neither displaying the other inside of itself.
    • Maybe instead of a PackedScene I need some sort of reference to the PackedScene, as it seems the issue is that Level 2 is loaded inside of Level 1’s portal and waiting to be switched to but the process of loading Level 2 reveals a portal back to Level 1 and we’ve circled back around.
    • I feel this is further proven by the fact that circular scenes don’t just happen with two way doors (A to B and B to A) but also with longer chains that eventually circle back around.
    • So if for example Levels 1-5 were on the “ground” and then Levels 6-10 were in the “sky” and falling through holes in Levels 6-10 is supposed to drop you into Levels 1-5 you’d now have a circular reference (and quite a few as well lol).
      • 1 → 2 → 3 → 4 → 5 → 6 (with a portal back to 1) → 7 (portal to 2) → 8 (portal to 3) → 9 (portal to 4) → 10 (portal to 5)
:bust_in_silhouette: Reply From: chugwig

So turns out you can use change_scene instead of change_scene_to in order to avoid the issue. What I eventually decided on was:

export(String, FILE, "*.tscn") var scene_path = "res://src/Levels/"

This allows for you to just click the file button and it’ll start you off in the Levels folder which is the best I could come up with. I also changed the _get_configuration_warning function as necessary and switched out change_scene_toin teleport

func teleport() -> void:
	anim_player.play("fade_out")
	yield(anim_player, "animation_finished")
#	get_tree().change_scene_to(next_scene)
	get_tree().change_scene(scene_path)

If anyone has any suggestions about best practices and such please let me know, happy to mark a better answer as the actual answer.