Using a Custom Resource to save game data including a PackedScene

Godot Version

4.2

Question

I’ve started adding save data to my game, and I was doing so by creating a custom resource that contains various things (like player inventory, facing direction, location) in addition to a PackedScene of the current scene whenever a save state is created.

I’ve got the save logic down, but when re-loading my custom resource’s PackedScene I’m running into a weird error:

E 0:00:27:0873   scene_manager.gd:28 @ finish_fading(): Signal 
    'body_entered' is already connected to given callable 
    'Area2D(door.gd)::_on_body_entered' in that object.

Now the odd thing is, nothing “appears” to break in the game. You can still interact with everything normally and the assets all load in correctly (specific to the second error all the doors trigger the collisions as you would expect).

This leads me to believe that for whatever reason my save game load state, when it loads the custom resource PackedScene is somehow loading twice, or isn’t deleting the old scene before instantiating the new one.

The logic to load the scene looks like so:

func _ready():
	$ScreenTransition/ColorRect.visible = false
	if Utils.loaded:
		var savedata = Utils.get_save()
		is_loading = true
		transition_to_scene(savedata.current_scene, savedata.player_position, savedata.player_direction)
		
func transition_to_scene(new_scene, spawn_location: Vector2, spawn_direction: Vector2) -> void:
	next_scene = new_scene
	player_location = spawn_location
	player_direction = spawn_direction
	$ScreenTransition/AnimationPlayer.play("FadeToBlack")
	
func finish_fading() -> void:
	$CurrentScene.get_child(0).queue_free()
	if is_loading:
		$CurrentScene.add_child(next_scene.instantiate())
		is_loading = false
	else:
		$CurrentScene.add_child(load(next_scene).instantiate())
	var player = Utils.get_player()
	player.set_spawn(player_location, player_direction)
	$ScreenTransition/AnimationPlayer.play("FadeToNormal")

Basically, there’s a global flag under Utils.loaded that checks if a save state was loaded, if it was then when the scene manager is ready we transition_to_scene() given all our parameters from the save state.

The FadeToBlack animation has a callback that triggers finish_fading() which is where I queue free the current scene and re-load a new scene.

The Scene manager, for reference looks like this:

Screenshot 2024-03-17 at 9.09.08 PM

I’m assuming that something is causing

CurrentScene.get_child(0).queue_free()

To not do what it’s supposed to do? I’ve tried removing the node from the tree (with node.get_parent().remove_child(node) before calling queue_free() but that doesn’t seem to solve the issue either.

I guess a potential fix could be to store the string to the resource path instead of saving the actual resource itself but that would mean that if the state of the scene changed in some way it wouldn’t be reflected in the loaded save state.

Either way, nothing appears to have broke but I’m sure something under the hood got messed up, and any help would be greatly appreciated.