Questions about the instantiate method

Godot Version

v4.6.2

Question

Hi, I’m new to Godot and programming as a whole so I wanted to consult some people who were a bit more experienced to figure out how I should handle this.

I’m created a grid-based ecosystem game where you can choose which animal you’d like to be and so far it’s going pretty well. The problem I keep encountering, however, is that some things get loaded in before others, for instance:

My game would load my menus then my main scene and then add my player into it.

My problem came with the health bars, which were added alongside the main scene and freaking out because they couldn’t see the player’s health components and saying values were null (which were added a few seconds later with the player). Even when I added the healthbar to the Player scene it returned null - that stumped me for a day or two. Finally I added a signal that, after the player had been added as a child to the main scene, would emit that “player was ready” and that’s worked great so far - the only annoying thing being that I have to add it to the ready function of literally anything trying to interact with something that hasn’t been ‘created’ yet.

I have a few questions:

  1. Is there a way around this / is this bad practice (regarding the ‘player ready’ signal)? Is there an easier way than doing what I’m doing? I just started working on a FoodSpawner script for the food in the ecosystem and am running into some issues trying to access a TileMapLayer on the main scene that hasn’t been loaded yet.
  2. Should I instantiate my world from the launch of the game and pause it while the player is in the menus or should I only instantiate after they’ve selected their character and pressed start?
  3. If I instantiate at character select, how do I access nodes that ‘don’t exist yet’?

instantiate() doesn’t run any code in your scene except _init() functions which you likely don’t use.

Your _ready() functions will run only when you add instantiated scene to engine’s main scene tree, typically via add_child().

They can’t all run at once. Only one _ready() can run at a time. The order in which they will run is determined by the order of nodes in the scene’s branch. Being aware of the order in which your _ready()s will run is important.

If something is initialized in one _ready() and some other _ready() depends on it being initialized, you need to make sure that they run in that order. This is called initialization order. You need to make sure that dependencies are always initialized before the code that depends on them runs. Otherwise you’ll get infamous “null reference” errors.

1 Like

Its probably a good idea to make nodes that dont rely on the instantiation of others,
as @normalized stated, using a _ready() functions can only be done once per script, and as such will only run once, this in mind, it is very helpful and often all i need for setting things up in my scenes.

I recommend using @onready for node variables, and using a globals script. (which you seem to be doing)

I find its always a good practice to go the React route (dont mind if you arent familliar, its a web development framework), which would be splitting separate components into different scenes, if they work by themselves, they should work together.

I have never encountered that many issues with instantiation of nodes, what exactly is your main system?