Godot Resources (4.x)
Model game data as reusable, Inspector-editable Resource objects instead of hard-coded
values, and load/save them as .tres/.res. Targets Godot 4.7.
When to use
- Use when representing items, stats, enemy configs, dialogue lines, or level metadata as
data; authoring
.tresfiles in the Inspector; or loading/saving custom resources.
When not to use: nodes/scene structure → godot-nodes-scenes; saving the player's
runtime progress (engine-agnostic save format/slots) → save-systems; the C# variant of
this pattern → godot-csharp.
Core workflow
- Subclass
Resourcewithclass_nameand@exportfields. It now appears in the "New Resource" dialog and as an@exporttype, editable in the Inspector. - Create instances as
.tresfiles in the FileSystem dock (text, diff-friendly) or.res(binary, smaller/faster). Edit their fields in the Inspector — no code needed. - Reference resources from nodes via
@export var data: ItemResource, or arrays@export var loot: Array[ItemResource]. - Load at runtime with
preload(constant path) orload/ResourceLoader.load(variable path). Use threaded loading for large assets. - Duplicate before mutating a shared resource at runtime, or every node using it changes too (resources are shared references).
- Save generated/edited resources with
ResourceSaver.save.
Patterns
1. A custom data resource
Create sword.tres from this class in the FileSystem dock and fill it in the Inspector.
2. Consume resources from a node
3. Duplicate before mutating shared data
4. Save and load a resource at runtime
Pitfalls
- Resources are shared by reference. A single
.tresassigned to many nodes is the same object — mutating it changes all of them (and re-saving the file). Callduplicate(true)for per-instance state. class_namerequired to instance from the editor. Without it the class won't appear in the "New Resource" dialog or as an@exporttype.res://is read-only in exported games. Write runtime data touser://, neverres://.ResourceSaver.savetores://only works in the editor.- Storing nodes in a Resource doesn't serialize them. Resources hold data, not live
scene nodes. Reference scenes via
PackedScene, not node instances. - Cyclic resource references (A holds B holds A) can fail to save/load cleanly — keep data graphs acyclic or use IDs/lookups.
preloadvsload.preloadneeds a constant path and loads with the script;loadaccepts a variable path at runtime. UseResourceLoader.exists()beforeloadto avoid errors on missing files.- Don't put secrets in
.tres— they ship in plain text inside the export.
References
- For threaded/background loading (
load_threaded_request),@toolresources with custom setup, customResourceFormatLoader/Saver, resource-local-to-scene, and resource UIDs, readreferences/resource-patterns.md.
Related skills
godot-gdscript—@exportannotations used to define resource fields.godot-nodes-scenes— instancing scenes vs. sharing resource data.save-systems— persisting runtime progress (separate from static data).unity-scriptableobjects— the equivalent data-asset pattern in Unity.


