Collections: Arrays, Dictionaries & Packed Arrays

Typed arrays are checked on insertion, offer better autocomplete, and iterate faster.

9.1 Array

var a := [1, "two", Vector2(3, 3)]     # untyped: any mix of types
var nums: Array[int] = [5, 2, 8]       # typed array
nums.append(1)          # or push_back
nums.push_front(0)
nums.insert(2, 99)
nums.erase(99)          # remove first occurrence of value
nums.remove_at(0)       # remove by index
var last := nums.pop_back()
nums.size(); nums.is_empty()
nums.has(8); nums.find(8); nums.count(8)
nums.sort()             # ascending
nums.reverse(); nums.shuffle()
nums.pick_random()
nums.max(); nums.min()
nums.slice(1, 3)        # sub-array [1, 3)
nums.clear()
var copy := nums.duplicate()          # shallow copy
var deep := nested.duplicate(true)    # deep copy
var filled := []
filled.resize(10)
filled.fill(0)
print(nums[-1])                       # last element

9.2 Functional helpers

map() returns an untyped Array; assign to a typed array with Array(result, TYPE_INT, "", null) or typed.assign(result).

var squares := nums.map(func(n): return n * n)
var evens := nums.filter(func(n): return n % 2 == 0)
var total: int = nums.reduce(func(acc, n): return acc + n, 0)
var any_big := nums.any(func(n): return n > 100)
var all_pos := nums.all(func(n): return n > 0)

var enemies: Array[Enemy] = get_enemies()
enemies.sort_custom(func(a: Enemy, b: Enemy) -> bool:
	return a.global_position.distance_squared_to(global_position) < b.global_position.distance_squared_to(global_position)
)

9.3 Typed arrays

Typed arrays are checked on insertion, offer better autocomplete, and iterate faster. Use assign() to fill a typed array from an untyped one:

var names: Array[String] = ["Ada", "Linus"]
var bodies: Array[Node2D] = []
var scenes: Array[PackedScene] = [preload("res://a.tscn")]
names.append(5)         # error: wrong type
var found: Array[Node] = []
found.assign(get_tree().get_nodes_in_group("enemies"))

9.4 Dictionary

Keys can be any type (int, String, Vector2i, Object...). Dictionaries preserve insertion order.

var stats := {"hp": 100, "mp": 30, "name": "Ada"}
var lua_style := {hp = 100, mp = 30}        # identifier keys become String keys
stats["hp"] -= 10
stats.hp += 5                               # dot access works for String keys
stats["level"] = 2                          # add a key
stats.get("xp", 0)                          # default if missing
stats.has("mp")                             # or: "mp" in stats
stats.erase("mp")
stats.keys(); stats.values(); stats.size()
stats.merge({"xp": 0, "hp": 999}, false)    # don't overwrite existing keys
for key in stats:
	print(key, " = ", stats[key])
for value in stats.values():
	print(value)
var copy := stats.duplicate(true)

9.5 Typed dictionaries (Godot 4.4+)

Typed dictionaries can be exported and shown in the Inspector with proper editors.

var scores: Dictionary[String, int] = {"Ada": 10, "Linus": 7}
var tiles: Dictionary[Vector2i, TileInfo] = {}
var by_type: Dictionary[StringName, Array] = {}
scores["Grace"] = "high"    # error: value must be int

9.6 Packed arrays

Contiguous, memory-efficient arrays of a single type — ideal for large data, file bytes, and engine APIs.

PackedInt32Array / PackedInt64Array PackedFloat32Array / PackedFloat64Array 32/64-bit float

PackedVector2Array / PackedVector3Array / PackedVector4Array (4.3+)

var points := PackedVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(50, 80)])
$Polygon2D.polygon = points
var bytes := "hello".to_utf8_buffer()
print(bytes.get_string_from_utf8())
var parts: PackedStringArray = "a,b,c".split(",")

9.7 Value vs reference semantics

Passed/assigned as int, float, bool, String, vectors, Color, transforms Value (copied) Value semantics (copy-on-write) Array, Dictionary

Reference (shared; use duplicate()) Object, Node, Resource

var a := [1, 2]
var b := a
b.append(3)
print(a)          # [1, 2, 3] — same array!

9.8 Read-only collections

const arrays/dictionaries and arrays returned by make_read_only() cannot be modified:

var frozen := [1, 2, 3]
frozen.make_read_only()
frozen.append(4)   # error