Strange issue with @onready

Godot Version

4.1

Question

@onready seems to work when scene is executed per se, but not when it is instantiated by a singleton.

I followed the tutorial “Cute and Simple Dialog Box | Let’s Godot” (https://www.youtube.com/watch?v=1DRy5An_6DU).
The text box scene works perfectly fine, I tested it. At very least, it does not crash when I run it!

But then in the game I want to call it from the singleton DialogueManager as defined in the tutorial.

Well, in THIS case, the @onready variables label and timer are not properly assigned!!! They remain null, and the project crashes.

IF I assign then “manually” inside the display_text, i.e. if a write something like:

func display_text(parameters):
label = $MarginContainer/Label
etc.

then… it works!

Or, IF I run the scene per se, I don’t need to do add those lines, because @onready works.

But, if I run another scene, put in it a call to DialogueManager to show a dialogue, then the game crashes by telling me that label and timer are null!!!

This is driving me mad.
I mean, I can easily fix it, and I did, by adding two lines to the ready function. Everything works fine now.
But what on Earth is actually happening?! Why is @onready failing, and why only some times and not other times?

Edit: actually this does fix only the “label” part.
Not the timer one.
The timer is not added to the scene tree, never. Godot tells me to add it or set it to autostart. But even if I set it to autostart, it does not work.
There’s clearly a problem with this scene being instantiated by another one, and I’m starting to think it is a bug

I am performing some tests and it seems that the _ready function is litterally not executed sometimes.

I can tell it because if I put as a first and only line in _ready a “print(something)”, then I should see something in the output window before the game crashes, but I see notning.

Also it is not a problem of the “autoload”. I removed the autoload and did the same things inside a node that I added as a child of my main scene. Same problems.

Why is the _ready function called when I run the scene per se, but not when the scene is instantiated elsewhere?! I have added scenes so many times without this issue.

ok so by singleton you mean project settings globals
I might have reproduced what is going on. the var is ready but it is empty is the short.

this is my global auto load singleton
@onready
var myvar : int = 400

func _ready() → void:
print(“myvar”)
print(myvar)
var newsig : Sig = Sig.new()
print(“newsig.SigVar”)
print(newsig.SigVar)

this is my non singleton
extends Node
class_name Sig

@onready
var SigVar : int = 500

func _ready() → void:
print(“SingletonS.myvar”)
print(SingletonS.myvar)
print(“SigVar”)
print(SigVar)

the out put is
myvar
400
newsig.SigVar
0
SingletonS.myvar
400
SigVar
500

the first two are from the auto load notice how the newsig.SigVar is
0 this is because it has not yet been set. if it was more then a int it would be a null.

the global is the thing that loads first then even a @onready in something else must be set when it’s loaded.

All this is fine but does not explain why e.g. the timer does not work even if I set it inside the code and not as an onready variable. The code from the youtube channel has a lot of issues indeed. Sometimes, parts of it are not executed and I don’t get why. I understand that something is always executed or never executed, but some times yes and some times not drives me crazy. I think there’s some deep bug I am witnessing but I don’t understand exactly what. :\

You need to add the Scene as a singleton, not the script. When a script is added as a singleton Godot creates a single basic Node type to add to the scene, with a Scene Godot will create the entire Scene including your label child nodes

Thanks for your advice!

However, it is not the only problem.

In fact, I have already created the scene, and not as a singleton, just as a standard node; I added it to the npcs and tested it. It should work fine as for singletons, just it cannot be accessed from everywhere but only from scenes that have it as subscenes, but whatever.

Long story short: still random issues.

I have come to believe there are issues with the fact of awaiting for the resize signal.

This, simply put, seems to fails from time to time, so parts of the code are randomly non executed.

I solved it replacing them with a standard await for a timer created on purpose. The only issue is that I have to move the dialogue box outside of the view otherwise the process of adapting the size to the text is seen by the player, which obviously sucks.