0 votes

Hi, hope you've had a good day.

I'm new to Godot and a few days into my project I've noticed some strange behavior from the singleton (autoloaded script) I've made. For example:
In the Globlas.gd

export var life := 5
export var cooldown_time := 5

When I edit the value of life in the editor to 10 and print it:

func _ready():
    print(life)

I get 10, but then I reduce life by 1 in the same Globals.gd script and print the new life value:

func change_life(num):
    life += num
    print(life)

I get 4, as tho the game forgot that the value was changed (and yes I've made sure that there's nowhere where I set life to 5 inbetween these two prints)

Also a similar thing happened to dictionaries:

onready var game_state = {
    menu = 1,
    play = 0
}

func _on_Start_button_up():
    game_state.menu=0
    game_state.play=1
    print(game_state.play)

print is 1 but then in another script where I check game_state.play it sais that it's 0:

func _unhandled_input(event):
    print(Globals.game_state.play)
    if Globals.game_state.play == 1:
        ...

this prints 0, as tho nothing has changed even tho the print before showed that there was a change.

I think this might also be a problem when I try to reload the current scene, I have a dictionari in my Globals that contains the path of some nodes, in the debugger I see that dictionari being filled with new node id's but then when we get to another script it's as tho the dictionari is null. Basically for some reason the singleton didn't update for the rest of the game, as tho it isn't a singleton at all (and yes I did try re adding it to autoload)

Pleas help, this is extremely frustrating and I haven't really seen anyone else with this problem

Godot version v3.2.3
in Engine by (18 points)

It's strange to me that onready and _ready() in the Globals.gd gets run through twice at the start of the app, is this suposed to happon ?

going step by step it runs through all the onready variables and the _ready function and when that's finished the steps go through that again, that's also why there's two Life in Globals 0 in the prints in my last post.

Tho I should note, in the first pass life doesn't get set with the value I put in the editor, but on the second pass it does.

Can you send the project-folder?

I would feel uncomftorable doing that, I can send the GDscripts in question tho, would that suffice. It'd mostly be the Globals.gd and the RidgedBody script. These are the only places that life is being edited anyway, and the RidgedBody script only calls a method that's in Globals.gd anyway

you can also make a small example project, where your problem appears.
Its much much easier to help, if i have smothing to work with.

Here's a Media fire link to an example project:
https://www.mediafire.com/file/kugw8t8ady89ciy/AutoLoadError.zip/file

All that's there is a Globals.gd that's autoloaded and a NewScript.gd that calls a function in the Globals when you press the left mouse button.
Globals has a life var that is set to 5 in the editor but you can see that NewScript thinks it's set 0

When you run the project you'll see text telling you which button to press to get which problem, there's another gettree().reloadcurrent_scene() problem that I found in my project and it's show here as well

1 Answer

0 votes
Best answer

You include your Globals.gd to a node in your Scene. Thats not how Singeltons/Autoloads work in Godot. You just have to include it in Autoload (ad .gd or as .tscn).
It then gets loaded parallel to your Scene. The tree then looks something like this

+root
|-Globals
|+Node2D
 |-Globals (<- this is wrong and causes the problems)
 |+NewScript
  |-Info

When you change the scene, Globals stays in the scene, so _ready() in Globals is not called again. so newscript_node in nodes_pleas becomes invalid/null, because it's from the old scene, that no longer exists.

Hope you understand what i mean.
Just remove Globals from you scene and leave it in autoloads, then it will do what you want.

PS.: that means you cannot export variables to Globals in the Scene itself, but you can just use

Globals.life = 5

in the scenes _ready() method

PPS.: You can inspect this in the Scene-Tree under "remote" in the editor while running your game.

by (1,448 points)
edited by

I think I understand, basically, I shouldn't have a node in my scene that contains the autoloaded gdscript because it'll be loaded automatically as a child of root.
This intern means that I can't set any variables in the editor directly like I could normally with export.
Also this way of dealing with nodes is improper since the dictionary wont be updated after the scene has been reloaded so I need to deal with nodes in a better way.

Can you pleas tell me if I understand this correctly.

And thank you for the help and time <3 !

you understand it correctly.

You can autoload a complete scene and not only a script. you can then use exports on this scene, but you can only "set" the exports once.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.