Tried opening my Godot project this morning and was greeted with the following error:

Auto-generated description: A computer screen displays a development environment with an error message pop-up about an invalid or missing scene file.
scene/resources/resource_format_text.cpp:284 - res://scenes/falling_platform.tscn:14 - Parse Error: 
Failed loading resource: res://scenes/falling_platform.tscn. Make sure resources have been imported by opening the project in the editor at least once.
Failed to instantiate scene state of "res://scenes/falling_platform.tscn", node count is 0. Make sure the PackedScene resource is valid.
Failed to load scene dependency: "res://scenes/falling_platform.tscn". Make sure the required scene is valid.

Traced it back to the technique I was using to respawn the falling platform. Looks like Godot didn’t like the two preloads I included:

# file: scripts/falling_platform.gd

@onready var FallingPlatform = preload("res://scenes/falling_platform.tscn")
@onready var FallingPlatformScript = preload("res://scripts/falling_platform.gd")

This resulted in a parse error and Godot thinking the level scene was corrupted. In retrospect, this kinda makes sense. What I doing was technically a circular dependency, where the scene and script was trying to preload itself. I was hoping Godot was smart enough to recognise this, but I guess not.

So I had to change the respawn code. I modified it to make use the duplicate method. Here’s the revised version:

func respawn():	
    var dup = self.duplicate()
    dup.global_position = init_global_position	

    # Duplicate also copies the velocity so zero it out here
    dup.velocity = Vector2(0, 0)
    get_tree().current_scene.add_child(dup)

After some limited testing, this seems to work. One good thing about this approach is that it looks like duplicate copies the script, so I no longer need to do anything special here.

So I guess the lesson here is don’t try to preload the script within itself.