HI, I'm trying to make some objects globally accessible, but I run into problems with what I think is the objects not being fully initialized when I try to access them.

I have a global script (as described in the 'Singleton' / autuload docs which defines a var, for intance like this:

var debug

In the 'debug' Node2D (which is a child if the top node, and is supposed to be displaying labels with messages from various objects) I have this:

onready var global = get_node("/root/global") func _ready(): -- global.debug = self

Now I was hoping to be able to access the debug node from anywhere as global.debug, like this for instance: onready var global = get_node("/root/global") func use_debug(): -- global.debug.out ("Hooray, it's working!!") I get the error "Invalid call. Nonexistent function 'out' in base 'Nil'." So I suppose, there's no debug object there to call yet. I made this experiment (in the global script) <code>var debug = Dummy.new() class Dummy: -- func out(a, b): ----- print ("Dummy.out called")

and confirmed that Dummy.out was called once before being replaced with the actual debug object.

I also tried waiting for the debug node to be initialized, but that had the effect of freezing the game (i e, waiting for the other object to be ready blocked the thread responsible for initializing the object). Like so: while global.debug==null: -- pass

So after all this, I wonder 1. Are nodes initialized in a particular order, so that this deadlock might be prevented somehow (i e initialize 'debug' node first) 2. Is this a stupid approach? I know I could get the 'debug' through it's URL since I know where in the scene tree it's located, but there might be other cases where I want global objects (such as player) or objects that persist through scene changes. Still, perhaps it's wiser to use the global singleton just to store values, and initialize objects anew in each scene. How do you handle this?

The ready() call works its way down the tree from the top. So I believe the root node is created, then the autoloaded nodes, then your main scene, and its children down the hierarchy. But . . . the ready call isn't the most reliable thing in the world. It can call more than once in some situations, and may call before other nodes "ahead" of it have all their children.

The few times I've done stuff like this I just use call_deferred(). It delays the function call until the next frame, and everything will be initialized by then. So instead of using onready vars, just make a function to set them all and call_deferred() that.

However, you don't actually need it in this case. You can simply refer to global scripts by their node name, you don't need get_node(). So if you have an autoloaded script named "Debug" in project settings, with a var "bob", you can just type "Debug.bob" from any node to get it.

Generally I don't keep scenes around when changing level scenes or whatever. Say if you have persistent player info, just store that data in a global script and feed it to the player scene each time the player spawns. But you can do it however seems easiest to you.

I think he didnt have the debug node itself as a singleton just the reference var. Green_manalish, would it be an option to create the debug node in the global scripts _ready? Or define an function in global node get_debug() that creates the object if its still null.

Thank you both. And yes Hooni, the debug node isn't a singleton as I've set it up, but that's mainly because I didn't think of it. It seems a more straightforward solution. Also, creating the debug node from the script is a good option. The reason for my arranging things this way I think is that I like to have stuff in the scene tree from the start so that I get a view of what I'm doing and move things about.

6 years later