返回 Skills 目录
gamedev-skills/awesome-gamedev-agent-skills已通过检查

SKILL DETAIL

godot-resources

gamedev-skills/awesome-gamedev-agent-skills/godot-resources

Design data-driven Godot 4.7 games with custom Resource classes: define typed data with class_name + @export, save/load .tres/.res files, instance and duplicate resources, and load on demand with ResourceLoader (incl. threaded loading). Use when modeling items/stats/configs as data in a Godot project, creating .tres resources, or working with custom Resource subclasses and ResourceLoader/ResourceSaver.

安装量 · 292查看来源

Installation

npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources

技能文件

SKILL.md

最近同步 · 2026年10月22日

references/resource-patterns.md›
# Resource patterns reference (Godot 4.7)

Depth companion to `godot-resources`.

## File formats

- `.tres` — text resource. Human-readable, merges/diffs well in version control. Default
  for hand-authored data.
- `.res` — binary resource. Smaller and faster to load; use for large/generated data.
- Convert by re-saving with the desired extension via `ResourceSaver.save`.

## Threaded (background) loading

Avoid frame hitches when loading large scenes/assets:

```gdscript
const PATH := "res://levels/big_level.tscn"

func begin_load() -> void:
    ResourceLoader.load_threaded_request(PATH)

func _process(_delta: float) -> void:
    var progress := []
    match ResourceLoader.load_threaded_get_status(PATH, progress):
        ResourceLoader.THREAD_LOAD_IN_PROGRESS:
            update_bar(progress[0])           # 0.0–1.0
        ResourceLoader.THREAD_LOAD_LOADED:
            var res := ResourceLoader.load_threaded_get(PATH)
            _on_loaded(res)
        ResourceLoader.THREAD_LOAD_FAILED, ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
            push_error("Load failed")
```

## resource_local_to_scene

By default a `.tres` is shared by every scene that references it. Tick **Local to Scene**
(or set `resource_local_to_scene = true`) so each scene instance gets its own copy at load
time — useful for per-instance materials/state without manual `duplicate()`.

## @tool resources

Add `@tool` to a Resource script to run setup in the editor (e.g. validate fields, derive
values). Guard with `Engine.is_editor_hint()` where needed. Combine with `@export_tool_button`
(4.4+) or a custom inspector plugin for editor actions.

## Custom ResourceFormatLoader / Saver

To load a non-Godot file format as a Resource (e.g. a custom `.deck` text format), register
a `ResourceFormatLoader` (and optionally `ResourceFormatSaver`) and add it with
`ResourceLoader.add_resource_format_loader(loader)`. Override `_get_recognized_extensions`,
`_handles_type`, and `_load`. This lets `load("res://x.deck")` return your resource type.

## Resource UIDs

Godot 4 assigns each imported resource a stable UID (`uid://...`). Scenes can reference by
UID so moving/renaming files doesn't break links. Get one with `ResourceUID`. Prefer
letting the editor manage UIDs; avoid hand-editing `.uid` files.

## Data-driven design tips

- Keep resources **pure data**; put behavior in nodes/systems that read them. This keeps
  data hot-swappable and testable.
- Use `StringName` (`&"id"`) for identifiers/keys — faster comparisons than `String`.
- Model registries (all items, all enemies) as an `Array[YourResource]` exported on an
  autoload, or a directory of `.tres` files loaded at startup.
- A typed export array (`@export var loot: Array[ItemResource]`) enforces element type in
  the Inspector and prevents dragging the wrong resource type.

## Common API

```gdscript
res.duplicate(deep := false)      # copy; deep also copies sub-resources
res.take_over_path("res://x.tres")
res.resource_path                 # where it loaded from ("" if in-memory)
ResourceLoader.exists(path, type_hint := "")
ResourceLoader.load(path, type_hint := "", cache_mode := CACHE_MODE_REUSE)
ResourceSaver.save(res, path, flags := 0)   # FLAG_COMPRESS, FLAG_BUNDLE_RESOURCES, ...
```
SKILL.md›
---
name: godot-resources
description: >
  Design data-driven Godot 4.7 games with custom Resource classes: define typed
  data with class_name + @export, save/load .tres/.res files, instance and duplicate
  resources, and load on demand with ResourceLoader (incl. threaded loading). Use
  when modeling items/stats/configs as data in a Godot project, creating .tres
  resources, or working with custom Resource subclasses and ResourceLoader/ResourceSaver.
---

# 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 `.tres` files 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

1. **Subclass `Resource`** with `class_name` and `@export` fields. It now appears in the
   "New Resource" dialog and as an `@export` type, editable in the Inspector.
2. **Create instances as `.tres`** files in the FileSystem dock (text, diff-friendly) or
   `.res` (binary, smaller/faster). Edit their fields in the Inspector — no code needed.
3. **Reference resources from nodes** via `@export var data: ItemResource`, or arrays
   `@export var loot: Array[ItemResource]`.
4. **Load at runtime** with `preload` (constant path) or `load`/`ResourceLoader.load`
   (variable path). Use threaded loading for large assets.
5. **Duplicate before mutating** a shared resource at runtime, or every node using it
   changes too (resources are shared references).
6. **Save generated/edited resources** with `ResourceSaver.save`.

## Patterns

### 1. A custom data resource

```gdscript
# item.gd
extends Resource
class_name ItemResource

@export var id: StringName = &""
@export var display_name: String = "Item"
@export_multiline var description: String = ""
@export var icon: Texture2D
@export var max_stack: int = 99
@export var value: int = 0
```

Create `sword.tres` from this class in the FileSystem dock and fill it in the Inspector.

### 2. Consume resources from a node

```gdscript
extends Node
@export var starting_items: Array[ItemResource] = []   # drag .tres files in the Inspector

func _ready() -> void:
    for item in starting_items:
        print("Have: %s (x%d max)" % [item.display_name, item.max_stack])
```

### 3. Duplicate before mutating shared data

```gdscript
func give_unique_copy(template: ItemResource) -> ItemResource:
    # true = deep copy sub-resources too; false = shallow (shares sub-resources).
    var copy: ItemResource = template.duplicate(true)
    copy.value += 5                # mutating the copy won't touch the template .tres
    return copy
```

### 4. Save and load a resource at runtime

```gdscript
func save_config(cfg: Resource) -> void:
    ResourceSaver.save(cfg, "user://config.tres")   # user:// = writable app data dir

func load_config() -> Resource:
    if ResourceLoader.exists("user://config.tres"):
        return ResourceLoader.load("user://config.tres")
    return null
```

## Pitfalls

- **Resources are shared by reference.** A single `.tres` assigned to many nodes is the
  *same* object — mutating it changes all of them (and re-saving the file). Call
  `duplicate(true)` for per-instance state.
- **`class_name` required to instance from the editor.** Without it the class won't appear
  in the "New Resource" dialog or as an `@export` type.
- **`res://` is read-only in exported games.** Write runtime data to `user://`, never
  `res://`. `ResourceSaver.save` to `res://` 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.
- **`preload` vs `load`.** `preload` needs a constant path and loads with the script;
  `load` accepts a variable path at runtime. Use `ResourceLoader.exists()` before `load`
  to 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`), `@tool` resources with custom
  setup, custom `ResourceFormatLoader`/`Saver`, resource-local-to-scene, and resource UIDs,
  read `references/resource-patterns.md`.

## Related skills

- `godot-gdscript` — `@export` annotations 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.