Weird varying behaviour with JSON dictionaries

Godot Version

4.4

Question

Okay, so something strange has been going on when I have been accessing and altering the contents of my JSON files.

Firstly, it starts with creating a “card”. In my game this appends an entry into my player_card_collection JSON file with the key being a unique card identifier and the value being the data associated with that card.

If I create multiple instances of a particular card, the unique card identifier is supposed to let the game differentiate between the different instances of that card. For instance, the player can create multiple goblin peons, in that case the game will create goblin_peon1, goblin_peon2, goblin_peon3 by appending a unique number to the end of each string.

Here is where the problem arises: In my game I let the player rename each card instance, which in practice means going into the JSON using the unique card identifier and changing the value for “card_name”.

However, when I do this, it ends up changing the “card_name” value for ALL cards with the same card_id, that is “goblin_peon”. Note that card data can only be accessed with the unique id, which includes a number at the end such as “goblin_peon51”. Below is the code used to do this. Note: I emit the event card_name_changed just to change the name of the card on the current screen, the listeners of that event don’t access or change any JSON.

func _on_pencil_button_pressed() -> void:
	var selected_card_uid: String = ScreenMaster.screen_data["selected_card"]
	var card_data = PlayerData.player_card_collection[selected_card_uid]
	card_data["card_name"] = properties_title_text.text
	EventMaster.card_name_changed.emit()

What’s even trickier is that this issue does not happen if I close then relaunch the game; it works just fine.

For instance, I create goblins, close the game, open the game, then the issue does not occur when I rename goblins.

Or I create goblins, try to rename them, the issue occurs, then I close the game, open it again, try to rename them, then the issue does not occur.

Does anyone know what causes this, or anything I can do to try to fix this or diagnose the problem?


Update 1: I found that the issue is also present with another card_id, “godot_tester”, so it isn’t just with “goblin_peon”, and one condition for the issue happening is if they have the same card_id property. So for example if I have two “godot_tester” cards and three “goblin_peon” cards, when I change the name of one of the “goblin_peon” cards, all the rest will update their names while “godot_tester” cards will remain unaffected. However, I’m still not sure how this is happening, as I am not accessing the cards with their card_id, but rather their uid which has a number at the end.

Ok, I solved it. It has to do with how when I create the card instances, I have been using a static data JSON dictionary which stores the default values for the cards. Since I passed this data directly to each of the card instances, they all stored the same reference to the same object in memory, meaning that modifying one would modify the rest (and also modify the default values). The solution was to use the duplicate method to copy the values rather than passing by reference.

1 Like