godot-resource-data-patterns

$npx mdskill add thedivergentai/GD-Agentic-Skills/godot-resource-data-patterns

Implement data-oriented design using Godot Resource and RefCounted classes.

  • Avoids shared mutable state by enforcing .duplicate() before modification.
  • Uses typed arrays (Array[ResourceClass]) for type-safe data collections.
  • Decides based on serialization needs, avoiding Node references in Resources.
  • Delivers reusable data structures like item databases and character stats.

SKILL.md

.github/skills/godot-resource-data-patternsView on GitHub ↗
---
name: godot-resource-data-patterns
description: "Expert blueprint for data-oriented design using Resource/RefCounted classes (item databases, character stats, reusable data structures). Covers typed arrays, serialization, nested resources, and resource caching. Use when implementing data systems OR inventory/stats/dialogue databases. Keywords Resource, RefCounted, ItemData, CharacterStats, database, serialization, @export, typed arrays."
---

## Godot 4.7 Baseline

- Expert patterns in this skill target **Godot 4.7+** (stable, 2026-06-18).
- Consult the [Godot 4.7 migration guide](https://docs.godotengine.org/en/4.7/tutorials/migrating/upgrading_to_godot_4.7.html) when upgrading projects from 4.6.
- **NEVER** assume 4.6 defaults (stretch mode, audio area_mask, RichTextLabel percent flags) without checking 4.7 migration notes.

# Resource & Data Patterns

Resource-based design, typed arrays, and serialization — decision tree + scripts, not Inspector tutorials.

## NEVER Do in Resource Design

- **NEVER modify resource instances directly** — Without `.duplicate()`, changing a value (like HP) modifies the shared `.tres` for everyone.
- **NEVER use untyped arrays in Resources** — `@export var items: Array` allows logic errors. Always use `Array[ResourceClass]` for type safety.
- **NEVER store Node references in Resources** — Objects that only exist in a specific SceneTree cannot be serialized. Store `NodePath` or `UID`.
- **NEVER perform heavy calculations in Resource getters/setters** — Resources should be data containers. Offload logic to Nodes or specialized RefCounted classes.
- **NEVER skip `ResourceSaver.save()` error checks** — Saving can fail due to permissions, disk space, or path issues. Always check the return code.
- **NEVER use Resources for high-frequency runtime data** — If a value changes 60 times a second (like velocity), a standard variable is faster than a Resource property.
- **NEVER allow circular Resource references** — If A.tres references B.tres and B.tres references A.tres, the engine may crash on load.
- **NEVER forget the `_init` defaults** — Resources created via `new()` or in the Inspector need default values in their constructor to be editable.
- **NEVER share a Resource between entities if they need unique state** — Use `resource_local_to_scene = true` or `duplicate()` for components.
- **NEVER use `.tres` for massive datasets** — If you have 10,000 items, a JSON or custom binary format might be more efficient than individualized Resource files.

---

## Decision Tree: Resource vs RefCounted vs Node

| Type | Use when | Disk / Inspector |
|------|----------|------------------|
| `Resource` | Shared definitions, saveable data, `@export` authoring | `.tres`/`.res`, Inspector ✅ |
| `RefCounted` | Temporary runtime calcs, non-persistent helpers | No disk / weak Inspector |
| `Node` | Scene entities with process/signals in the tree | Scene files |

**Use Resources for:** item defs, stats templates, abilities, dialogue tables, enemy configs.
**Use RefCounted for:** damage calc scratchpads, ephemeral state machines, non-saved utilities.

## Available Scripts — MANDATORY by Scenario

| Scenario | MANDATORY read |
|----------|----------------|
| Per-instance mutable stats (HP) sharing a base `.tres` | [resource_local_to_scene.gd](scripts/resource_local_to_scene.gd) |
| Nested Item → Weapon → StatusEffect trees / save whole graph | [nested_resource_serialization.gd](scripts/nested_resource_serialization.gd) |
| Many entities sharing one config (flyweight) | [resource_flyweight_caching.gd](scripts/resource_flyweight_caching.gd) / [flyweight_enemy_config.gd](scripts/flyweight_enemy_config.gd) |
| Custom `@export` data containers | [custom_data_resource.gd](scripts/custom_data_resource.gd) |
| Reactive stats with signals | [character_stats_resource.gd](scripts/character_stats_resource.gd) |
| Inventory arrays of Resources | [resource_based_inventory.gd](scripts/resource_based_inventory.gd) |
| Save Resource trees to disk | [resource_save_system.gd](scripts/resource_save_system.gd) — check `Error` |
| Preload / O(1) cache before play | [resource_preloading_strategy.gd](scripts/resource_preloading_strategy.gd) |
| Runtime `Resource.new()` loot | [dynamic_resource_generation.gd](scripts/dynamic_resource_generation.gd) |
| Validate / pool / factory | [resource_validator.gd](scripts/resource_validator.gd) / [resource_pool.gd](scripts/resource_pool.gd) / [data_factory_resource.gd](scripts/data_factory_resource.gd) |

## Expert WHY (critical)

> **CAUTION:** Runtime HP/mana on a shared `.tres` without `duplicate(true)` or `resource_local_to_scene` mutates the asset on disk — the **"damaging one damages all"** bug.

- **`.res` vs `.tres`:** binary `.res` in production; `.tres` for design diffs; nested trees save with parent via `ResourceSaver`.
- **Cache:** `ResourceLoader.CACHE_MODE_REPLACE` after external edits bypass stale cache.
- **Local-to-scene / duplicate:** mandatory for per-instance components — [resource_local_to_scene.gd](scripts/resource_local_to_scene.gd).
- **10k+ rows:** individualized `.tres` files lose to JSON/binary — see Official Docs binary serialization.

## Deep dive (load on demand)

Pattern 1–7 walkthroughs (ItemData, databases, RefCounted calcs, directory scan, O(1) cache) — [references/resource-patterns-deep.md](references/resource-patterns-deep.md). Implement nested weapons from [nested_resource_serialization.gd](scripts/nested_resource_serialization.gd), not memory.

## Reference

> Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.

### Official Documentation
- [Resources](https://docs.godotengine.org/en/stable/tutorials/scripting/resources.html) — Custom Resource scripts, `.tres`/`.res`, sharing vs `duplicate()`, and `resource_local_to_scene` for per-instance state.
- [Data preferences](https://docs.godotengine.org/en/stable/tutorials/best_practices/data_preferences.html) — When to store data in Resources vs dictionaries, ConfigFile, or plain scripts for inspector and serialization needs.
- [Resource](https://docs.godotengine.org/en/stable/classes/class_resource.html) — `duplicate`, `emit_changed`, `resource_path`, and local-to-scene flags used by every data container pattern here.
- [ResourceLoader](https://docs.godotengine.org/en/stable/classes/class_resourceloader.html) — Cached `load` / threaded requests that power flyweight sharing and preload caches.
- [ResourceSaver](https://docs.godotengine.org/en/stable/classes/class_resourcesaver.html) — Persist custom Resources to `user://` or `res://` and always check the returned `Error`.
- [RefCounted](https://docs.godotengine.org/en/stable/classes/class_refcounted.html) — Lightweight runtime objects when you need refcounting without disk serialization or Inspector exports.
- [Saving games](https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html) — Broader save strategies that pair with ResourceSaver for slot-based `.tres` state.
- [Background loading](https://docs.godotengine.org/en/stable/tutorials/io/background_loading.html) — Threaded `ResourceLoader` polling so databases and VFX packs do not hitch the main thread.
- [GDScript exports](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html) — Typed `@export` / `Array[T]` so item and quest Resources stay Inspector-safe.
- [Binary serialization API](https://docs.godotengine.org/en/stable/tutorials/io/binary_serialization_api.html) — Compact FileAccess packing when thousands of rows outgrow individualized `.tres` files.
- [Scene organization](https://docs.godotengine.org/en/stable/tutorials/best_practices/scene_organization.html) — Why shared Resources live outside scene trees and how component scenes compose exported data.

### Related Skills

#### Prerequisites
- [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — Project layout, import, and `res://` hygiene before authoring shared `.tres` databases.
- [godot-gdscript-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-gdscript-mastery/SKILL.md) — `class_name`, typed arrays, setters, and `@tool` discipline every custom Resource script depends on.

#### Complements
- [godot-signal-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-signal-architecture/SKILL.md) — Ownership and fan-out for Resource `changed` / custom signals that drive reactive UI and stats.
- [godot-save-load-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-save-load-systems/SKILL.md) — Slot versioning, migration, and secure paths that wrap ResourceSaver/ResourceLoader save flows.
- [godot-scene-management](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-scene-management/SKILL.md) — Packed scenes and threaded loads that consume preloaded Resource caches without hitch spikes.
- [godot-ability-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-ability-system/SKILL.md) — Ability/buff definitions are Resource data; this skill owns the container and serialization patterns.
- [godot-dialogue-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-dialogue-system/SKILL.md) — Dialogue graphs and line tables are nested Resources that reuse typed-array and save patterns here.
- [godot-performance-optimization](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-performance-optimization/SKILL.md) — Flyweight sharing, pooling RefCounted payloads, and when `.res` beats text `.tres` at scale.

#### Downstream / consumers
- [godot-inventory-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-inventory-system/SKILL.md) — Item stacks, equipment, and bags consume `ItemData` / inventory Resource arrays defined here.
- [godot-procedural-generation](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-procedural-generation/SKILL.md) — Generators that instantiate loot, quests, and configs via `Resource.new()` at runtime.
- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — `.tres` stats and economy tables are the preferred extract source — build the data layer before regex farms.

#### Master
- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored module entry for cross-skill discovery.

More from thedivergentai/GD-Agentic-Skills

SkillDescription
godot-2d-animationExpert patterns for 2D animation in Godot using AnimatedSprite2D and skeletal cutout rigs. Use when implementing sprite frame animations, procedural animation (squash/stretch), cutout bone hierarchies, or frame-perfect timing systems. Trigger keywords: AnimatedSprite2D, SpriteFrames, animation_finished, animation_looped, frame_changed, frame_progress, set_frame_and_progress, cutout animation, skeletal 2D, Bone2D, procedural animation, animation state machine, advance(0).
godot-2d-physicsExpert patterns for Godot 2D physics including collision layers/masks, Area2D triggers, raycasting, and PhysicsDirectSpaceState2D queries. Use when implementing collision detection, trigger zones, line-of-sight systems, or manual physics queries. Trigger keywords: CollisionShape2D, CollisionPolygon2D, collision_layer, collision_mask, set_collision_layer_value, set_collision_mask_value, Area2D, body_entered, body_exited, RayCast2D, force_raycast_update, PhysicsPointQueryParameters2D, PhysicsShapeQueryParameters2D, direct_space_state, move_and_collide, move_and_slide.
godot-3d-lightingExpert patterns for Godot 3D lighting including DirectionalLight3D shadow cascades, OmniLight3D attenuation, SpotLight3D projectors, VoxelGI vs SDFGI, and LightmapGI baking. Use when implementing realistic 3D lighting, shadow optimization, global illumination, or light probes. Trigger keywords: DirectionalLight3D, OmniLight3D, SpotLight3D, shadow_enabled, directional_shadow_mode, directional_shadow_split, omni_range, omni_attenuation, spot_range, spot_angle, VoxelGI, SDFGI, LightmapGI, ReflectionProbe, Environment, WorldEnvironment.
godot-3d-materialsExpert patterns for Godot 3D PBR materials using StandardMaterial3D including albedo, metallic/roughness workflows, normal maps, ORM texture packing, transparency modes, and shader conversion. Use when creating realistic 3D surfaces, PBR workflows, or material optimization. Trigger keywords: StandardMaterial3D, BaseMaterial3D, albedo_texture, metallic, metallic_texture, roughness, roughness_texture, normal_texture, normal_enabled, orm_texture, transparency, alpha_scissor, alpha_hash, cull_mode, ShaderMaterial, shader parameters.
godot-3d-world-buildingExpert patterns for 3D level design using GridMap with MeshLibrary, CSG constructive solid geometry, occlusion, and runtime GridMap builders. Use when building 3D levels, modular tilesets, or BSP-style geometry. For sky/fog/Environment recipes, route to godot-3d-lighting. Trigger keywords: GridMap, MeshLibrary, set_cell_item, get_cell_item, map_to_local, local_to_map, CSGCombiner3D, CSGBox3D, CSGSphere3D, CSGPolygon3D, OccluderInstance3D, bake CSG.
godot-ability-systemExpert patterns for RPG/action ability systems including cooldown strategies, combo systems, ability chaining, skill trees with prerequisites, upgrade paths, and resource management. Use when implementing unlockable abilities, character progression, or complex skill systems. Trigger keywords: PlayerAbility, AbilityManager, cooldown, SkillTree, SkillNode, prerequisites, can_use, execute, ComboSystem, ability_chain, global_cooldown, charge_system, upgrade_path.
godot-adapt-2d-to-3dExpert patterns for migrating 2D games to 3D including node type conversions, camera systems (third-person, first-person, orbit), physics layer migration, sprite-to-model art pipeline, and control scheme adaptations. Use when porting 2D projects to 3D or adding 3D elements. Trigger keywords: CharacterBody2D to CharacterBody3D, Area2D to Area3D, Camera2D to Camera3D, Vector2 to Vector3, collision_layer migration, sprite to MeshInstance3D, 2D to 3D conversion.
godot-adapt-3d-to-2dExpert patterns for simplifying 3D games to 2D including dimension reduction strategies, 2.5D fake-depth, isometric ports, camera flattening, physics conversion, 3D-to-sprite art pipeline, and control simplification. Use when porting 3D to 2D, building 2.5D / isometric / fake-depth gameplay, creating 2D versions for mobile, or prototyping. Trigger keywords: CharacterBody3D to CharacterBody2D, Camera3D to Camera2D, Vector3 to Vector2, flatten Z-axis, 2.5D, isometric, fake depth, Y-sort, simulated Z, orthogonal projection, 3D to sprite conversion, performance optimization.
godot-adapt-desktop-to-mobileExpert patterns for porting desktop games to mobile including touch control schemes (virtual joystick, gesture detection), UI scaling for small screens, performance optimization for mobile GPUs, battery life management, and platform-specific features. Use when creating mobile ports or cross-platform mobile builds. Trigger keywords: TouchScreenButton, virtual_joystick, gesture_detector, InputEventScreenTouch, InputEventScreenDrag, mobile_optimization, battery_saving, adaptive_performance, MOBILE_ENABLED.
godot-adapt-mobile-to-desktopExpert patterns for scaling mobile games to desktop including mouse/keyboard controls, increased resolution and graphical fidelity, expanded UI layouts, settings menus, window management, and platform-specific features. Use when creating desktop ports or cross-platform releases. Trigger keywords: mouse_controls, keyboard_shortcuts, resolution_scaling, graphics_settings, fullscreen_toggle, window_modes, Steam_integration, desktop_optimization.