Perhaps I'm missing something right in front of my eyes but I'm a little confused. I'm making a character creator of sorts ... so I have 3 dictionaries. 1 to hold the choices the player is making 2 for the confirmed player stats 3 for the confirmed npc stats

So when the player clicks the button, I want to transfer all the Dic1 data to one of the other dictionaries to make a character. My problem is, after I've copied 1 dictionary to another, any time I edit one of the 1st dictionaries values the one I'm not editing seems to change as well.

Sorry if that sounds a little confusing but I made a simplified test to confirm my suspicions.

var p = {age = "1"}
var s = {age = "2"}
var t = {age = "3"}

func _on_Button_pressed():
	p = t
	print(p)
	print(s)
	print(t)

func _on_Button2_pressed():
	t.age = "4"
	s = t
	print(p)
	print(s)
	print(t)

The first button works fine but when I press button 2, even though I did nothing to Dictionary P, it still prints 4. Am I doing something obviously wrong? Does "x.key" Go through every key in every dictionary? I don't know why "p" is changing when I press button2.

I think the problem is in how you are using and accessing your dictionaries. To the best of my knowledge, you cannot assign and access variables in a dictionary like you do a class (unless you are using Javascript, which I think allows dictionary access like that).

Here is how I've always been told to use dictionaries (converting your simplified test):

"For a dictionary, you have to define your keys and values" "in the following format: dict = {key:value}" var p = {"age":"1"} var s = {"age":"2"} var t = {"age":"3"} func _on_Button_pressed(): "I'm using local variables instead of reassigning (feel free to change if you want)" var local_p = t print(local_p["age"]) print(s["age"]) print(t["age"]) func _on_Button2_pressed(): t["age"] = "4" "I'm using local variables instead of reassigning (feel free to change if you want)" var local_s = t print(p["age"]) print(local_s["age"]) print(t["age"])

Note: you can print the entire dictionary if you want, just remove ["age"] to print the entire dictionary.

Am I doing something obviously wrong? Does "x.key" Go through every key in every dictionary? I don't know why "p" is changing when I press button2.

This is because dictionaries aren't a base type (like ints, floats, strings, or Vectors), and so are passed by reference, not by value. You're changing the original dictionary because pressing the first button points p to t's dictionary in memory.

Basically, imagine that for base types, a variable holds the value itself. However, for anything else, the variable is a line to a box that contains the value. You can change the value in the box much in the same way, but the distinction is important because multiple variables can be tied to the same box and thereby refer to and change the same value.

This would also be the case with other kinds of objects, like arrays or class instances. Here's a simple code example:

#  Create a dictionary, and assign it to the variable dictA
var dictA = {"Test": 1} 

#  Create a dictionary, and assign it to the variable dictB
var dictB = {"Test": 2}

#  Assign the variable dictB the dictionary in dictA
dictB = dictA
print( dictB["Test"] )  # Prints 2

See the Godot API page on references.

6 days later

@TwistedTwigleg said: I think the problem is in how you are using and accessing your dictionaries. To the best of my knowledge, you cannot assign and access variables in a dictionary like you do a class (unless you are using Javascript, which I think allows dictionary access like that).

GDScript supports dot notation for accessing dictionaries, but only for constant values. This means that for example, person.age will be treated like person["age"], not person[age] (age being a variable in the second example).

GDScript supports dot notation for accessing dictionaries, but only for constant values. This means that for example, person.age will be treated like person["age"], not person[age] (age being a variable in the second example)

Oh, I didn't know that. Good to know!

5 years later