godot-resources — Claude Code skill for Godot 4.7 data resources
This skill shows the agent how to model Godot game data as custom Resource classes with class_name and @export, then save and load them as .tres.
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources -a claude-codeWhat godot-resources does
The skill covers turning items, stats, enemy configs and dialogue lines into Resource objects instead of hard-coded values. The agent follows a set workflow: subclass Resource with class_name and @export fields, create instances as .tres or .res, reference them from nodes with @export var data: ItemResource or Array[ItemResource], and load at runtime with preload for constant paths or load/ResourceLoader.load for variable ones.
The part worth reading twice is sharing. A single .tres assigned to many nodes is the same object, so mutating it changes every node and rewrites the file. Per-instance state needs duplicate(true), and when a sub-resource lives in its own .tres, only duplicate_deep(Resource.DEEP_DUPLICATE_ALL) copies that too. Without class_name the class never shows up in the “New Resource” dialog or as an @export type.
Writing to res:// only works in the editor, since exported games treat it as read-only; runtime data belongs in user://. Secrets in .tres ship as plain text inside the export, so keep them out. Cyclic references between resources can fail to save or load, which is why the skill suggests keeping the data graph acyclic.
What it helps with
- model items and stats as data instead of constants
- author
.tresfiles and edit fields in the Inspector - load a config from a variable path at runtime
- duplicate a resource before mutating it so other nodes stay intact
- save a generated resource to
user://
Example prompts for the agent
- Create an
ItemResourceclass withid,display_nameandmax_stack, then makesword.tresfrom it - Load
user://config.treswithResourceLoaderand checkResourceLoader.existsfirst - Why does editing one
.treschange every node, and how do I copy a resource before mutating it?
How to install godot-resources
1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources -a claude-code2Manually: put the files in place
~/.claude/skills/godot-resources/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/godot-resources/
1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources -a codex2Manually: put the files in place
.agents/skills/godot-resources/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources -a cursor2Manually: put the files in place
.cursor/skills/godot-resources/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install gamedev-skills/awesome-gamedev-agent-skills godot-resources2Manually: put the files in place
.github/skills/godot-resources/SKILL.md1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources -a gemini-cli2Platform CLI
gemini skills install https://github.com/gamedev-skills/awesome-gamedev-agent-skills --path skills/godot/godot-resourcesManually: put the files in place
.devin/skills/godot-resources/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about godot-resources
How do I install godot-resources in Claude Code?
Run npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-resources -a claude-code. The skill lands at ~/.claude/skills/godot-resources/SKILL.md.
What does godot-resources do?
It guides the agent through designing Godot 4.7 data as custom Resource classes: @export fields, .tres and .res files, loading with ResourceLoader and saving with ResourceSaver.
How is it different from the other Godot skills?
This one is about data, not scenes: node structure goes to godot-nodes-scenes, player progress to save-systems, and the C# version to godot-csharp.
Source text
SKILL.md · Apache-2.0
---
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: copies nested arrays/dictionaries and *embedded* sub-resources, but
# sub-resources saved in their own .tres stay shared. Use
# template.duplicate_deep(Resource.DEEP_DUPLICATE_ALL) to copy those as well.
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.
- **A deep copy still changes the original's sub-resource** → `duplicate(true)` only copies
sub-resources embedded in the file; one saved as its own `.tres` (e.g. a shared
`stats.tres` inside `goblin.tres`) is still the same object. Use
`duplicate_deep(Resource.DEEP_DUPLICATE_ALL)` when those must be copied too.
- **`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.
© gamedev-skills · Apache-2.0 · gamedev-skills/awesome-gamedev-agent-skills