Skip to content
Bring your skills

Godot Resources Explained: Data Assets for Items, Stats, Abilities, and Tuning

Learn Godot Resources for items and enemy stats, then debug shared materials: why hitting one enemy can change them all, and when to use Local To Scene.

On this page

Resources store reusable data such as item stats, enemy settings, and ability definitions. You can edit them in the Inspector and assign the same data to several scenes. Here is how to create a custom Resource and use it in a pickup scene.

The Short Version

A Resource is a saved data object. Godot already uses Resources everywhere: textures, materials, fonts, animations, themes, meshes, and audio streams. You can also create your own custom Resources for gameplay data.

  • Unity habit: custom Resources often feel like ScriptableObjects.
  • Unreal habit: custom Resources can feel like Data Assets for smaller, editor-friendly data.
  • Godot habit: scenes own behavior, Resources hold reusable data, and scripts connect the two.

Why Resources Matter in Production

Hardcoded values are fine for a five-minute test. They become painful when you are tuning ten enemies, twenty items, or several abilities. Resources move data out of scripts so you can reuse, duplicate, and tune it from the Inspector.

A Custom Item Resource

Create a script that extends Resource, give it a class_name, and export the fields you want to edit in the Inspector. Save it as something like ItemData.gd.

gdscript
extends Resource
class_name ItemData

@export var display_name: String = "New Item"
@export var icon: Texture2D
@export var value: int = 1
@export var max_stack: int = 1
@export_multiline var description: String = ""

Now you can create .tres files from that type, such as health_potion.tres, silver_key.tres, or coin.tres. Each file has the same structure but different values.

Using Resource Data in a Scene

A pickup scene can export an ItemData reference. That scene handles collision and presentation. The Resource provides the name, icon, stack size, and value.

gdscript
extends Area2D

@export var item_data: ItemData
@onready var sprite: Sprite2D = $Sprite2D

signal picked_up(item: ItemData)

func _ready() -> void:
    if item_data and item_data.icon:
        sprite.texture = item_data.icon

func _on_body_entered(body: Node) -> void:
    if body.is_in_group("player") and item_data:
        picked_up.emit(item_data)
        queue_free()

The useful part is that your pickup scene does not care whether it represents a coin, potion, key, or crafting item. Designers can duplicate Resource files and tune values without touching the collision script.

Good Resource Use Cases

  • Items: names, icons, stack sizes, sell values, rarity, tags.
  • Enemy stats: max health, speed, damage, detection range, loot table references.
  • Abilities: cooldown, mana cost, projectile scene, damage curve, UI icon.
  • Weapons: fire rate, spread, recoil, ammo type, sound references.
  • Difficulty tuning: spawn weights, score multipliers, wave timing.

When Not to Use Resources

Use ordinary variables for temporary state unless you need Resource features such as Inspector editing or serialization. Shared Resources need particular care: changing one at runtime can affect every scene that references it. Keep each actor’s changing state separate from shared definitions.

  • Use normal variables for temporary runtime state like current health.
  • Use JSON or a save file format for player save data.
  • Use scenes for reusable behavior and node composition.
  • Use Resources for reusable definitions and tuning values.

Resource Files vs Built-In Resources

Godot can store a Resource as an external file or embed it inside a scene. External files are better when multiple scenes should share the same data. Built-in resources are fine when the data belongs only to one scene.

For example, a shared fireball_ability.tres should be an external file if the player, enemy mage, and tutorial UI all reference it. A one-off material override inside a single prop can stay built in.

A Practical Folder Setup

text
res://
  scripts/resources/ItemData.gd
  scripts/resources/EnemyStats.gd
  scripts/resources/AbilityData.gd
  resources/items/health_potion.tres
  resources/items/silver_key.tres
  resources/stats/slime_stats.tres
  resources/abilities/fireball.tres

That split keeps the Resource class scripts separate from the actual Resource instances. If you want the bigger folder picture, pair this with the Godot project structure guide, then practice on the Learn page.

Why do all my enemies change when I hit one?

You hit one enemy and every enemy flashes the same color. Start by checking whether their materials point to the same Resource. A reader described this exact symptom: the enemy scenes were separate, but the material used for the hit effect was shared.

Two nodes can refer to one material. Changing that material changes the appearance of both. Saving it inside a scene does not automatically give each instance its own copy. For a scene-owned material that must change independently, enable Resource > Local To Scene on the material in the source scene before creating instances. Changing that flag after instances already exist does not retroactively separate them.

Here is a small reproduction you can run without enemy art. Attach this script to an otherwise empty Node and run that scene. It uses a StandardMaterial3D color value so you can inspect the sharing in Output, even without rendering a mesh.

gdscript
extends Node

func _ready() -> void:
    var first := StandardMaterial3D.new()
    first.albedo_color = Color.GREEN
    var second := first
    second.albedo_color = Color.RED
    print("Shared: ", first == second)
    print("First changed: ", first.albedo_color == Color.RED)

    var independent := first.duplicate() as StandardMaterial3D
    independent.albedo_color = Color.BLUE
    print("Independent: ", independent != first)
    print("First stayed red: ", first.albedo_color == Color.RED)

All four printed checks should be true. The first assignment shares a reference; duplicate() creates a separate material. This example changes a color property only. A shallow duplicate can still share nested Resources such as textures, so it is not a general instruction to copy every asset recursively.

If your actual effect uses a ShaderMaterial or a different material slot, inspect the Resource that the hit script modifies. Duplicating an unused material will not fix the effect. The lighting and materials guide explains where material appearance fits into a 3D scene.

Should every enemy get a separate stats Resource?

For the common case, keep max health in the shared definition and current health on each enemy node. Two slimes can both read a maximum of 30 while one has 20 health left. Damage should update that enemy’s current-health variable. Writing the damage result back into shared stats changes the definition other slimes read.

  • Place two enemies that use the same stats file. Record both current-health values before damage.
  • Damage only the first. Its current health should fall; the second enemy and the shared maximum should stay unchanged.
  • Change the maximum in the shared file before starting a new run. Both enemies should initialize from the new value.

If independent mutable Resources are part of your design, give them an explicit owner and copy only the data that needs its own state. The important check is whether changing one actor affects another. Use the health and HUD example to practice keeping that state on the actor and reporting changes through a signal.

The Habit to Build

If several scenes repeat the same exported fields, check whether those fields describe reusable data. A Resource can hold that definition while each scene handles its own behavior. Keep separate instances when those values need to change independently.

Frequently asked questions

What is a Resource in Godot?
A Resource is a Godot data object that can be saved, reused, exported, and assigned in the Inspector. Resources are commonly used for items, stats, materials, themes, animations, and custom gameplay data.
Are Godot Resources like Unity ScriptableObjects?
Yes, custom Godot Resources are often used in the same way Unity developers use ScriptableObjects: reusable data assets for items, stats, abilities, tuning, and configuration.
Should I use Resources or JSON for game data in Godot?
Use Resources when the data belongs inside the editor workflow and benefits from typed Inspector fields. Use JSON for external saves, modding, imports, or data that must be edited outside Godot.
Verification notes

Sources and revision context

Updated September 8, 2026. Added a shared-material reproduction and checks for independent enemy health. Resource sharing, Local To Scene, and material properties reviewed against the stable documentation on September 8, 2026. The material script produced all four expected checks in Godot 4.7.2 headless. Scene-local duplication and visible hit effects were not runtime-tested.