SuperAPI AI 工具集

godot-resource-data-patterns

编程与开发

查看项目

更新于 10-15 09:21

技能介绍

用途

本技能是 Godot 引擎中面向数据设计(data-oriented design)的专家蓝图,聚焦于使用 Resource 与 RefCounted 类来构建可复用的数据结构,例如物品数据库、角色属性模板、技能定义、对话表和敌人配置等。目标是让资源充当「可保存、可在 Inspector 中编辑的数据容器」,而把逻辑放到 Node 或专用的 RefCounted 类中。

主要能力

  • 提供 Resource / RefCounted / Node 三者的选择决策树:Resource 用于共享定义、可保存数据、@export 编辑(.tres/.res,Inspector 可用);RefCounted 用于临时运行时计算、非持久化辅助对象(不落盘、Inspector 支持弱);Node 用于场景中带 process/信号、挂在树上的实体(场景文件)。
  • 按场景提供必需脚本:
    • 基于共享 .tres 的每实例可变属性(HP)→ resource_local_to_scene.gd
    • 嵌套的 Item → Weapon → StatusEffect 树 / 保存整图 → nested_resource_serialization.gd
    • 多实体共享一份配置(flyweight)→ resource_flyweight_caching.gd / flyweight_enemy_config.gd
    • 自定义 @export 数据容器 → custom_data_resource.gd
    • 带信号的反应式属性 → character_stats_resource.gd
    • 基于 Resource 数组的库存 → resource_based_inventory.gd
    • 将 Resource 树保存到磁盘 → resource_save_system.gd(需检查 Error)
    • 运行前 preload / O(1) 缓存 → resource_preloading_strategy.gd
    • 运行时 Resource.new() 掉落生成 → dynamic_resource_generation.gd
    • 校验 / 池化 / 工厂 → resource_validator.gd / resource_pool.gd / data_factory_resource.gd

使用方式

技能以规则清单和模式脚本的形式给出。核心约束包括一条「NEVER 清单」:

  • 绝不直接修改资源实例——若不调用 .duplicate(),修改 HP 之类的值会改到共享 .tres,影响所有引用者。
  • 绝不在 Resource 中使用无类型数组——@export var items: Array 允许逻辑错误,应始终使用 Array[ResourceClass] 保证类型安全。
  • 绝不在 Resource 中存放 Node 引用——只存在于特定 SceneTree 的对象无法序列化,应存 NodePath 或 UID。
  • 绝不在 Resource 的 getter/setter 中做重计算——Resource 应是数据容器,逻辑应下沉到 Node 或专用 RefCounted 类。
  • 绝不跳过 ResourceSaver.save() 的错误检查——保存可能因权限、磁盘空间或路径问题失败,必须检查返回码。
  • 绝不用 Resource 承载高频运行时数据——若某值每秒变化 60 次(如 velocity),普通变量比 Resource 属性更快。
  • 绝不允许 Resource 循环引用——A.tres 引用 B.tres 且 B.tres 引用 A.tres 时,引擎可能在加载时崩溃。
  • 绝不忘记 _init 默认值——通过 new() 或在 Inspector 创建的 Resource 需要构造函数中的默认值才可编辑。
  • 若实体需要各自独立状态,绝不共享同一个 Resource——组件应使用 resource_local_to_scene = true 或 duplicate()。
  • 绝不用 .tres 承载超大数据集——若有 10,000 个物品,JSON 或自定义二进制格式可能比逐个 Resource 文件更高效。

此外技能给出了若干关键经验提示:

  • 运行时 HP/mana 若直接写在共享 .tres 上且未 duplicate(true) 或设置 resource_local_to_scene,会改写磁盘上的资产,即「打到一个等于打到全部」的 bug。
  • .res 与 .tres 的取舍:生产环境用二进制 .res,需要设计差分时用 .tres;嵌套树随父级一起通过 ResourceSaver 保存。
  • 缓存:外部编辑后使用 ResourceLoader.CACHE_MODE_REPLACE 绕过陈旧缓存。
  • local-to-scene / duplicate 对每实例组件是强制的。
  • 万行以上数据:逐个 .tres 文件不如 JSON/二进制,可参考官方文档的二进制序列化。

适用场景

  • 物品定义、属性模板、技能、对话表、敌人配置等共享定义型数据。
  • 需要嵌套结构并整体保存的资源图(如武器带状态效果)。
  • 多实体共享一份配置的 flyweight 缓存场景。
  • 需要在 Inspector 中编辑并持久化的自定义数据容器。
  • 需要信号驱动的反应式属性、基于 Resource 数组的库存与存档流程。
  • RefCounted 适用于伤害计算的临时对象、短生命周期状态机、无需保存的工具类。

限制与注意事项

  • 高频变化的数据(如每秒 60 次)不应使用 Resource 属性。
  • Resource 不能存放仅存在于特定 SceneTree 的 Node 引用,需改用 NodePath 或 UID。
  • 超大数据集(如 10,000 条以上)建议改用 JSON 或自定义二进制格式。
  • 禁止循环资源引用,否则可能加载崩溃。
  • 保存操作必须检查 ResourceSaver.save() 返回的 Error。
  • 官方文档链接建议按需查阅:Resources、Data preferences、Resource、ResourceLoader、ResourceSaver、RefCounted、Saving games、Background loading、GDScript exports、Binary serialization API、Scene organization。
  • 相关技能中,前置为 godot-project-foundations、godot-gdscript-mastery;互补为 godot-signal-architecture、godot-save-load-systems、godot-scene-management、godot-ability-system、godot-dialogue-system、godot-performance-optimization;下游消费者为 godot-inventory-system、godot-procedural-generation、godot-monte-carlo-balancer;总入口为 godot-master。

具体脚本实现细节、完整模式 1–7 的逐步讲解以及各官方 API 的用法示例,资料中未提供完整内容,需按需查阅对应资源文件与官方文档。