Godot version:
Godot v3.0.5.stable.official.6a88e22 win64
OS/device including version:
Windows 10 Pro v.1803 (on 2 different pc)
Issue description:
Loading values in a two-dimensional array has different results if the array is local or global.
On a new project, I added a script (g.gd) as autoload-singleton enabled with the following code:
extends Node
extends Node
export var gridTiles = []
export var gridStat = []
I create a new scene assigned as main scene on project setting, on the root node added a script with the following code:
extends Node
func _ready():
var x
var y
var gridTiles = []
var gridStat = []
for y in range(3):
gridTiles.append([])
gridStat.append([])
for x in range(4):
gridTiles[y].append(null)
gridStat[y].append(0)
gridStat[0][0] = 1
print(gridStat)
print(gridStat.size(), " x ", gridStat[0].size())
print(gridTiles)
print(gridTiles.size(), " x ", gridTiles[0].size())
for y in range(3):
g.gridTiles.append([])
g.gridStat.append([])
for x in range(4):
g.gridTiles[y].append(null)
g.gridStat[y].append(0)
g.gridStat[0][0] = 2
print(g.gridStat)
print(g.gridStat.size(), " x ", g.gridStat[0].size())
print(g.gridTiles)
print(g.gridTiles.size(), " x ", g.gridTiles[0].size())
The resulting output is:
[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
3 x 4
[[Null, Null, Null, Null], [Null, Null, Null, Null], [Null, Null, Null, Null]]
3 x 4
[[2, 0, Null, 0, Null, 0, Null, 0], [Null, 0, Null, 0, Null, 0, Null, 0], [Null, 0, Null, 0, Null, 0, Null, 0], [], [], []]
6 x 8
[[2, 0, Null, 0, Null, 0, Null, 0], [Null, 0, Null, 0, Null, 0, Null, 0], [Null, 0, Null, 0, Null, 0, Null, 0], [], [], []]
6 x 8
Is it a bug or my poor knowledge of gdscript (python)?
Thanks for the attention.
I could reproduce the issue, here's a simpler example:
# g.gd, defined as "g" singleton
extends Node
export var arr1 = []
export var arr2 = []
```gdscript
extends Node
func _ready():
print(g.arr1, " ", g.arr2)
g.arr1.append(1)
g.arr2.append(2)
print(g.arr1, " ", g.arr2)
Output:
[] []
[1, 2] [1, 2]
If I remove `export` from the arrays in the singleton, or define them with a different starting value, the error goes away.
So it seems like `export` arrays defined in a singleton with the same value will end up shared (so they're actually the same array, modifying one modifies the other).
The bug also happens if both are initialized to the same non-null value, e.g.:
```gdscript
# g.gd, defined as "g" singleton
extends Node
export var arr1 = [3]
export var arr2 = [3]
Output:
[3] [3]
[3, 1, 2] [3, 1, 2]
If the export keyword is removed from one or both of them, the issue disappears.
I could reproduce the issue on 3.0.5-stable and in the current master branch (f778bd8e).
I removed the keyword export because it's not for my purposes (I just looked at the documentation of godot - my lack of knowledge of gdscript as I wanted to prove) and it works.
I hope the bug does not create problems for others and is easy to solve.
Thanks akien-mga for the prompt reply, it's great to see how godot is supported by the community.
Just tested when asked by @bojidar-bg: if g.gd is not a singleton, but e.g. a script attached to a child node, then there is no bug.
So it's buggy only in the singleton + export + same initialization case.
Can you still reproduce this issue in the current master branch?
Just downloaded Godot v3.1.beta2.official and tested, nothing has changed:
with "export" the bug is present, without "export" no bug.
Same issue in Godot v 3.1.2-stable in linux. Remove "export" solve the issue.
Godot version:
Godot_v3.1.2-stable_x11.64 for linux.
OS/device including version:
Ubuntu 18.04
Similar issue in Godot_v3.2.1-stable_win64. However, it applies to non-singleton scripts as well.
extends Node2D
export (Array) var arr_A = []
export(Array) var arr_B = []
func _ready():
for i in range(10):
arr_A.append("A")
#arr_B.append("B") # even bypassed it appends
print(arr_B)
Output:
[A, A, A, A, A, A, A, A, A, A]
3.2.2 beta3
I tried using:
Godot: 3.2.2 beta 3 - Launched Today
OS: Ubuntu 20.04
This is a script attached to a Node

got the same issue
yes, there is, just attach different initial values

I will look into this on my time off from FBX over the weekend.
1. export var a: Array = Array() # broken 2. export var b: Array = [] # broken 3. export var c: Array # works 4. export var b := [] # works
Based on this info, it seems like an issue with type inference where it has two sources of type. Here both are Array but that seems inconsequential.
In cases 1 and 2, we have type Array specified on both sides of =. Hence, fails.
In cases 3 and 4, we have type Array specified on only 1 side of =. Hence, successes.
I am just guessing right now. Will test it soon.
Update: @boruok I couldn't get case 4 to work if both are like that.
But, it works if they are different.
#failed
export var arr1:= []
export var arr2:= []
#works
export var arr1:Array
export var arr2:= []
Quick look at the code:
The main place where constant values might get merged together and mixed up is the GDScript compiler. It has the following code, when processing a ConstantNode:
https://github.com/godotengine/godot/blob/3be9c74d8b0337d387fb90b8b2c228ebaaae3317/modules/gdscript/gdscript_compiler.cpp#L376-L386
Now, this does not happen for all empty arrays. This is so because _reduce_expression in the parser converts an ArrayNode to a ConstantNode only when its elements are constant and when it is in a place where it should try to convert an expression to a constant (p_to_const).
https://github.com/godotengine/godot/blob/3be9c74d8b0337d387fb90b8b2c228ebaaae3317/modules/gdscript/gdscript_parser.cpp#L1740-L1753
This function is called through the place parsing TK_PR_VAR. p_to_const is set to true only when exporting the variable (code is a bit more convulted, but that's what autoexport || member._export.type != Variant::NIL means)
https://github.com/godotengine/godot/blob/3be9c74d8b0337d387fb90b8b2c228ebaaae3317/modules/gdscript/gdscript_parser.cpp#L4920
This does not happen in case 3 and 4 above, since when there is no assigned value _parse_and_reduce_expression does not get called. Instead, the code tries to generate a valid default value for the type, and that piece of code returns a proper ArrayNode for arrays.
https://github.com/godotengine/godot/blob/3be9c74d8b0337d387fb90b8b2c228ebaaae3317/modules/gdscript/gdscript_parser.cpp#L5025
@bojidar-bg case 4 is broken too.
Alright. Updated my comment.
Note that export(Array) var b should likewise work, as it does not have an assigned value, even though it lacks a data type.
This is fixed by #41983 in 4.0, but a fix is still needed for 3.2, so reopening.
Most helpful comment
I tried using:
Godot: 3.2.2 beta 3 - Launched Today
OS: Ubuntu 20.04
This is a script attached to a Node
got the same issue
There is a workaround?
yes, there is, just attach different initial values