• Godot Help
  • "const x: Dictionary = {}" not working in autoload script - cannot assign to it

I thought that defining a dictionary as a constant meant you could change the contents of that dictionary by never assign a different one.

When declaring a dictionary with const, the dictionary itself can still be mutated by defining the values of individual keys. Using const will only prevent assigning the constant with another value after it was initialized.

source: https://docs.godotengine.org/en/stable/classes/class_dictionary.html

I'm getting an odd error when assigning values to a dictionary defined in this way.

As shown below, I have an autoload Globals singleton containing a constant dictionary named SSSM_GLOBAL_BLACKBOARD.

I assign a new keypair to the dictionary but Godot (v3.5.1) immediately throws an error about "invalid set index..." even though it did in fact add the value, as shown in the object inspector.

If I change the definition of SSSM_GLOBAL_BLACKBOARD from const to var, it works as expected. Or, if I test this using the same const dictionary assignment locally in a script, that works fine too. So it looks like this is something funky about doing it in an autoload script.

Maybe the keys have to be defined at compile time (i.e. when the dictionary is declared to be constant, yet before running the code), and their values can be assigned on-the-fly?

Yes, it says the values can change, it doesn't mention changing the keys.

Also, const really only makes sense for constant values (like the value of Pi). It doesn't make sense logically for variables that are changing at run-time.

Definitely agree that const may not be sensible here. However, the behavior of const dictionary is clear, which you can validate in testing:

  1. A const dictionary can start empty or populated. In both cases, you can later add, change, remove keys and values at will -- UNLESS you include the const dictionary in an autoload script, in which case it will throw the error in first post. In that case, the fact that it is actually adding the keypair and only then throwing the error suggest this is an unintended bug, otherwise it should be leaving the dictionary untouched and just throwing an error.

  2. Once you have defined a const Dictionary, you cannot later assign it a null value or another dictionary object or a new empty dictionary object. All three actions will throw an engine error.
    This fits with the doco description which says the constant is immutable, i.e. it is locked to the dictionary object assigned in the script. But the keys and values within that dictionary object can change at will, even by emptying the dictionary.

So this looks to me like a bug or perhaps an unavoidable side-effect of using a const dictionary in an autoload script.

Locking a dictionary to a single dictionary object is pretty useful to ensure that a dictionary property can never accidentally get assigned another dictionary object. Indeed, surely that is the expected behaviour: that you define a property as a dictionary and intend that the property will always reference that same dictionary object at all times.

As minor as this is, I'll go ahead and lodge an issue on Github, because this does seem like unexpected behavior rather than a designed one.

Oh I see. Yeah, this looks like a bug. Or at least undocumented "functionality".