In the Array docs, all we have right now is this line:
Arrays are always passed by reference.
For someone who does not know what "passed by reference" means it means nothing.
I only learned through painful trail and error and by wasting a lot of time even that Arrays are somehow shared and PoolXArrays are not. I would have searched what "passed by reference" means sooner, if I somehow knew this expression is connected to my Array changing throughout my running project.
I think the Array documentation should have a clear statement about the fact that it is shared, a statement that is even understood by people who do no know yet what "passed by reference" means, or at the very least some hint that those are connected.
It'd be a good idea to link to a document that explains the differences between "pass by value" and "pass by reference" for those less familiar with programming languages. I've seen a handful of Stack Overflow questions on the subject :slightly_smiling_face:
It should be clear though in the Array doc already, that "passed by reference" or "passed by value" has something to do with my arrays being shared.
Because if not, it might take a loooong time until I look at that tutorial, because I would not think of it having any connection to my problem.
On a similar topic, the export documentation about Array type can be misleading:
https://github.com/godotengine/godot-docs/blob/master/getting_started/scripting/gdscript/gdscript_exports.rst#exporting-arrays
It insists on this fact:
"exported arrays are shared between all instances"
Which is only true if you keep the default value set in the script in all instances and modify the array without assigning a new one. But if you assign a new array in one of the instances by script or in the inspector, it does becomes unique.
Could this be considered a bug rather than how array export works? It seems related to this issue:
https://github.com/godotengine/godot/issues/20436
Otherwise it's important for this part of the documentation to be as clear as possible, in relation to how arrays generally work in the engine.
@pouleyKetchoupp This sounds similar to https://github.com/godotengine/godot/issues/24134. The documentation should be updated to reflect this.
@Calinou It's a different issue from #24234, and it's still not fixed in current master. It doesn't happen between two arrays in the same scripts, but between the same array in two instances of the same script if they both keep their default initial value.
Since the documentation says it's how it's supposed to work in general, I'm not sure if we need to consider it a bug or just update the documentation to be more specific.
I've just been testing and changing the array in any way in the inspector seems to create a new array, even if you just modify one of the values.
A workaround is doing the following:
const my_exported_array_default = ["foo", "bar"]
export(Array) var my_exported_array = my_exported_array_default
func _enter_tree():
if my_exported_array == my_exported_array_default:
my_exported_array = my_exported_array_duplicate()
That way after _enter_tree() you always have your own array. It also works inside _ready() but it doesn't seem to work inside _init()
This "sharing" issue also appears to apply to dictionaries. I've found that this solution works to prevent that:
var workaround = {"_temp": randi()}
export var data: Dictionary = workaround
func _init() -> void:
data.erase("_temp")
@Krypton-Nova
Yes, this applies to dictionaries too. Unfortunately it's only mentioned here. If a new user overlooks this paragraph, they might not know about it.
It's not mentioned in the API description, but I also think it should be mentioned there, as this is very important and might cause a lot of unnecessary bug hunting.
@golddotasksquestions yes, it applies to arrays, dictionaries and maybe some other data type I'm not remembering right now.
The docs are also misleading in https://docs.godotengine.org/en/3.2/getting_started/scripting/gdscript/gdscript_exports.html#doc-gdscript-exports since they state the arrays are shared across instances and that's only true if you never modify them through the UI, so it might set up false expectations.
The editor seems to be saving a different array every time you modify it but the only way to know it's doing it is either trial and error or reading the code, so it should be explicitly stated in the docs.
Most helpful comment
On a similar topic, the export documentation about Array type can be misleading:
https://github.com/godotengine/godot-docs/blob/master/getting_started/scripting/gdscript/gdscript_exports.rst#exporting-arrays
It insists on this fact:
"exported arrays are shared between all instances"
Which is only true if you keep the default value set in the script in all instances and modify the array without assigning a new one. But if you assign a new array in one of the instances by script or in the inspector, it does becomes unique.
Could this be considered a bug rather than how array export works? It seems related to this issue:
https://github.com/godotengine/godot/issues/20436
Otherwise it's important for this part of the documentation to be as clear as possible, in relation to how arrays generally work in the engine.