godotengine / godotengine/godot
ready() signal is called instantly from the Editor when loading the scene if connected via the Node tab's Signals menu
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
Reproducible in: v4.3.stable.official [77dcf97d8]
### System information
Godot v4.3.stable - Fedora Linux 41 (KDE Plasma) - Wayland - Vulkan (Forward+) - dedicated AMD Radeon RX 6600 (RADV NAVI23) - 12th Gen Intel(R) Core(TM) i5-12600KF (16 Threads)
### Issue description
When connecting the ready signal from the Node tab, the signal is called when loading the scene _via the editor_.
This leads to instantly running the connected function. It does not matter if the node is the scene's owner or a child, if it has a script, or whether it has a tool annotation or not.
If connected to methods like queue_free(), the editor will crash once it attempts to delete the corresponding node.
The editor will likely not remove any data from the scene. But if the scene is remembered as the most recent scene, it'll potentially leave the editor in a loop of starting -> loading the scene with signals -> running the method -> crashing.
The only solution is to either remove the signals from the .tscn file or change the last scene the editor "remembers".
I don't think this is the expected behavior, because it affects non-tool and script-less Nodes too. Fixing this would be helpful to create scenes with auto emitting and then freeing particles, for example. Without having to add scripts that aren't necessary.
https://github.com/user-attachments/assets/f497ace1-6b9a-4096-9da5-b7f524f6bd3e
### Steps to reproduce
1. Connect the ready signal to any node from the Editor's Node tab.
2. Close and reopen the scene. The connected function should run instantly.
### Minimal reproduction project (MRP)
The included reproduction project has 2 scenes: visibility_example and crash_example.
I recommend loading visibility_example first, as crash_example will make the editor stuck in the previously mentioned loop.
visibility_example only has a Label and TextureRect. The TextureRect has its visibility set to false (you can check the value in the tscn file), so it should be hidden. However, once the editor loads it, it'll trigger the ready signal, connected to that Node's show() method.
crash_example contains a node that will call queue_free() once the editor loads it, triggering the error.
[editor_signals_test.zip](https://github.com/user-attachments/files/17614057/editor_signals_test.zip)
Contributor guide
Research direction
Start with the attached editor_signals_test.zip and reproduce the behavior in visibility_example, then confirm the crash loop in crash_example. Inspect how the editor loads scenes and handles ready signal connections from the Node tab; done means reopening the scene no longer invokes the connected method in the editor or crashes when queue_free() is connected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- game-dev, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100