After refactoring some code around a very basic state machine I started having runtime errors. The state machine was attempting to call a method on the “state” variable, but this was null. Turns out the “initial_state” export variable was not set.
“initial_state” is set to “Idle” in the editor. As you can see, by the assert statement “initial_state” remains unset, despite the fact that by that point all children and even the owner are in the scene tree and ready. I don’t understand why this happens and would like to know why to avoid similar problems in the future.
As far as I remember, all I changed during refactoring were a few variable names and deleted some obsolete code. It worked fine before, and works well if I put a valid default value on “initial_state”.
@exports will be set before ready, maybe your scene was saved without the export set after refactoring your code. Double check your assignments, maybe even re-open the project.
I have tried all that. Even deleted the state machine node and added a new one, but the problem remains.
I also tried putting a default value on initial_state so the game runs and a different one in the inspector. Then used a breakpoint shortly after the scene starts running and on the stack trace initial_state is correctly set to the value from the inspector, so it is actually being set late rather than not being set at all.
What if you define a specific type (Node2D, Sprite2D, etc) to the exported variable instead of NodePath? I remember to face issues like this in 3.x using NodePath.
I see, looks like one of these race condition situation. You could use a custom initialization method instead of _ready(). Usually I create a initialize() function to have a better control of when things should happen. You just need to call this initialization method before the time you need this to be ready.
I don’t think that it’s a race condition. As @gertkeno says, exported vars are set before _ready (and there is no multi-threading/co-routines involved)
@Cero_Cero Can you post the errors you are getting? They might tell us what the problem is. Have you tried re-assigning the path (maybe with a different node)?
And can you try to add another exported variable to see if it is set in _ready?