Menu
CoddyTech

Copying Dictionaries

Part of the Logic & Flow section of Coddy's GDScript journey. Lesson 22 of 78.

Assigning a dictionary to another variable does not copy it. Both variables refer to the same dictionary, so a change through one shows through the other:

var template := {"type": "slime", "hp": 30}
var enemy := template
enemy["hp"] = 10
print(template["hp"]) # 10

duplicate() creates a new dictionary with the same pairs. Changing the copy leaves the original alone:

var original := {"type": "slime", "hp": 30}
var copy := original.duplicate()
copy["hp"] = 99
print(original["hp"]) # 30

duplicate() makes a shallow copy: the copy has its own pairs, but a value that is an array or a dictionary is still shared between the two:

var hero := {"stats": {"hp": 100}, "items": ["sword"]}
var clone := hero.duplicate()
clone["stats"]["hp"] = 1
clone["items"].append("shield")
print(hero)
{ "stats": { "hp": 1 }, "items": ["sword", "shield"] }

Pass true for a deep copy: duplicate(true) also copies every array and dictionary inside, so the two share nothing:

var twin := hero.duplicate(true)
twin["stats"]["hp"] = 50
print(hero["stats"]["hp"]) # 1

A shallow copy is enough when every value is a number, a string or a boolean. As soon as a value is an array or a dictionary, use duplicate(true). Arrays work the same way: grid.duplicate(true) copies a 2D array together with its rows.

challenge icon

Challenge

Easy

Spawn a wave of enemies from a template. The dictionary template is given. The program reads two whole numbers, one per line: how many enemies to spawn (n) and an hp bonus.

For each enemy number i from 1 to n:

  1. Make a copy of template that shares nothing with it.
  2. Add the key "id" with the value i.
  3. Add bonus * i to the "hp" inside "stats".
  4. If it is the last enemy, append "crown" to its "loot".
  5. Print the enemy.

Finally, print Template: followed by the template, which must be unchanged. For the inputs 2 and 10, the output is:

{ "type": "slime", "stats": { "hp": 40, "speed": 2 }, "loot": ["gel"], "id": 1 }
{ "type": "slime", "stats": { "hp": 50, "speed": 2 }, "loot": ["gel", "crown"], "id": 2 }
Template: { "type": "slime", "stats": { "hp": 30, "speed": 2 }, "loot": ["gel"] }

Try it yourself

extends Node

func _ready():
	var template := {"type": "slime", "stats": {"hp": 30, "speed": 2}, "loot": ["gel"]}
	var n := int(OS.read_string_from_stdin())
	var bonus := int(OS.read_string_from_stdin())

	# Spawn and print the n enemies

	# Print the template
	pass
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow

Practice on your own: Online GDScript compiler