Menu

Godot Resources in GDScript: Custom Resource Classes

What a Resource is in Godot 4, how to write a custom resource class for item or enemy data, edit it in the Inspector, save and load it as a .tres file, and why shared resources surprise people.

This page includes runnable editors. Edit, run, and see output instantly.

A Resource is a data object that Godot can save to a file and load back. Images, sounds, scenes, fonts and materials are all resources. You can write your own resource classes, which is the standard way to keep game data, such as items, out of your code:

# item_data.gd
class_name ItemData
extends Resource

@export var item_name := ""
@export var price := 0
@export var icon: Texture2D
@export_multiline var description := ""

In the editor you then create items without writing code: in the FileSystem dock choose New Resource, pick ItemData, fill in the fields in the Inspector and save the result as sword.tres. A shop node loads it like any file:

const SWORD: ItemData = preload("res://items/sword.tres")

func _ready():
	print(SWORD.item_name, " costs ", SWORD.price)

Resources in Code

A resource is an ordinary object, so you can also create one with new(). This version runs here, with the class written inside the script:

Sword 50
true true

Resources extend RefCounted, so they free themselves when nothing uses them. You never call free() on one.

Shared, Not Copied

This catches almost everyone. Godot loads a resource file once. Every node that uses it gets the same object, and so does every variable you assign it to:

3
3 10

In a game this is the "I hit one enemy and they all lost health" bug. Two fixes:

  • Call duplicate() in _ready() when each node needs its own copy: stats = stats.duplicate().
  • In the Inspector, turn on Local to Scene for the resource, so each scene instance gets a fresh copy.

Keep shared resources for data that really is the same everywhere, such as an item's base price.

Saving and Loading

ResourceSaver.save() writes a resource to a file, and load() reads it back:

func save_settings(settings: GameSettings) -> void:
	var error := ResourceSaver.save(settings, "user://settings.tres")
	if error != OK:
		push_error("Could not save settings: %s" % error_string(error))

func load_settings() -> GameSettings:
	if ResourceLoader.exists("user://settings.tres"):
		return load("user://settings.tres")
	return GameSettings.new()
  • res:// is your project folder and is read-only in an exported game.
  • user:// is a writable folder per user and per game; use it for saves and settings.
  • .tres saves as readable text, .res as a compact binary file.

Load only resource files your game wrote. A resource file can hold a script, and loading a file a stranger sent you runs it. For saves shared between players, JSON is the safer format.

Built-in Resource Types

Many engine types you set in the Inspector are resources:

ResourceHolds
Texture2Dan image
AudioStreama sound or music file
PackedScenea saved scene you can instantiate()
Font, Themetext and UI styling
Shape2D (CircleShape2D, RectangleShape2D)a collision shape
Curve, Gradientvalues you shape with a graph

Because they are all resources, the same rules apply: they are shared when loaded, saved as files, and copied with duplicate().

Frequently Asked Questions

What is a Resource in Godot?

A Resource is a data object Godot can save to a file and load back: textures, sounds, scenes, materials and fonts are all resources. You can write your own by extending Resource, which is how many games store item, enemy and level data.

How do I create a custom resource in Godot 4?

Write a script with class_name ItemData and extends Resource, and mark its fields with @export. In the FileSystem dock, choose New Resource, pick ItemData, fill in the fields in the Inspector and save it as a .tres file.

Why do all my enemies share the same resource values?

Godot loads a resource file once and every node that uses it gets the same object. Changing it on one changes it on all. Call duplicate() to get a separate copy, or enable Local to Scene on the resource so each scene instance gets its own.

Should I save game data as a Resource or JSON?

Resources keep Godot types such as Vector2 and Color and load with one load() call, which makes them convenient. JSON is plain text that other tools can read. Never load a .tres file from an untrusted source: a resource can contain a script that runs when loaded.

Coddy programming languages illustration

Learn to code with Coddy

Get started