Is already being loaded. Cyclic reference?

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

I don’t know what’s going on but I’m going crazy to find a logic to it, I’m trying to go from level 1 to level 2 in a project I’m doing and as I don’t have any more levels at the moment when I finish level 2 I want it to go back to level 1, but when I try to do this I get the next mistake:

E 0:00:00.489 load: Resource: ‘res://Assets/Levels/Cemetery/Level01.tscn’ is already being loaded. Cyclic reference?
<Error de C++>Condition “!success” is true. Returned: RES()
<Fuente C++> core/io/resource_loader.cpp:360 @ load()

Of course, the level scripts share a class and in turn child elements that use preload to be loaded. I have researched this before in doubts that have had similar problems and some say that it is because of the preload, that they better use load… I have tried it and it gives me the same problem, that of the extended class because I am not going to remove it obviously because it has a reason to be… but then what is happening? because now I have the luck that for the final project I don’t need to return to previous levels, but what if I wanted to do it in another project? I just want to find a logic to this problem.

I also thought that it was because of a loader that I made to preload the elements of the level, but it is that not because to make the test I have removed the loader and it continues giving the same problem… and even before changing the level I put a call_deferred(“queue_free”) just in case and nothing, it continues happening…

without code this is hard to guess

There is a cyclic loading … wich means level 1 loads level 2 wich loads level 1 etc. because preload loads the level on compile time it would do this forever before anything else happens.

Preloading the levels does not seem the best option. Preloading may not impact your game now but imagin you have 20 levels … all those levels will be loaded before the game even starts, filling up memory and increases loading time.

Load it when you need it.

I prefer to write a master script and implement it as singleton. This script then manages all states the game has → menu, level 1, level 2 … level x, game over etc.

klaas | 2020-07-20 17:45

I didn’t put the code because I would have to guess which is the code that is giving the problem and in fact it doesn’t exist, the important thing for me was to understand the logic of why I was throwing that error, since the way to change the scene is with a simple change_scene_to and as additional data I indicated that I am using preload() to load the elements of the scene. But you gave me an interesting fact, all that information you just gave me is extremely useful, and that makes me have another doubt:

I thought that when you use preload what I was doing was preloading those elements before loading the scene, but using change_scene or queue_free would free them from memory, but from what you tell me and I think I understood it means that the elements are never removed from memory right? so of course, I want to go back to the same scene that uses preload and Godot says “hey, what’s up? I loaded it before” is that right?

Let me do the test then, I’ll try to change preload() to load() and see what happens.

Edit: I already tried changing again to change preload() by load() and nothing, same for testing I omit the part of the Background Loading, that is I remove the loading screen to load the level directly and thus discard that it was for the Background Loading.

Nothing, it still gives the same error and all the fault is in this line:

export(PackedScene) var next_level : PackedScene

When you click on a button you go to the level saved in next_level, but if in level 2 I indicate to return to level 1 the game throws that cyclic loading failure at the very beginning…

I edit for the second time: I already made sense of it. Indeed, it had nothing to do with Background Loading and moreover, it had nothing to do with using load() or preload(), it was indeed that line, that export:

When exporting level 2 in level 1, it loads level 2 when loading level 1, which in turn loads level 2 and thus repeats itself to infinity, so that in the export the preload seems to be implicit. If I put a simple String and pass the route works great and the problem is solved.

Javier Ocampos | 2020-07-20 18:38

:bust_in_silhouette: Reply From: luislodosm

This triggers a cyclic error if the destination scene references the origin scene:

export var scene: PackedScene

func change_scene():
	if scene:
		var _error = get_tree().change_scene_to(scene)

This, on the other hand, works:

export(String, FILE, "*.tscn") var path_to_scene

func change_scene():
    if ResourceLoader.exists(path_to_scene):
        var _error = get_tree().change_scene(path_to_scene)
:bust_in_silhouette: Reply From: rockgg

I have solved this by making a yield(previous_scene, “tree_exited”) to make sure the previous scene is completely deleted before actually loading any other similar scenes. Though I am actually loading scenes with ResourceLoader.load_interactive() so im not entirely sure if it applies as the solution for this problem.