关于 godot-save-load-systems
面向 Godot 游戏存档与读取系统的技能指南,帮助开发者选择持久化格式,并实现带版本、校验和安全措施的存档流程;附有迁移、加密和完整性检查脚本。
主要功能
- 01JSON、二进制与 Resource 持久化方案
- 02版本字段与存档迁移
- 03备份、完整性校验与安全写入
- 04加密存档与数据验证
- 05PERSIST 组自动收集模式
适用场景
- 01为新游戏设计存档格式
- 02升级存档结构并迁移旧数据
- 03验证用户可编辑的存档文件
- 04保存敏感字段或大型数据块
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-save-load-systems安装后在 Claude Code 中输入/godot-save-load-systems确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/migration-notes.mdsave-patterns-deep.mdscripts/save_integrity_validator.gdsave_load_patterns.gdsave_migration_manager.gdsave_system_encryption.gd详细介绍
切勿执行
- 切勿在未包含版本字段的情况下保存——更新游戏的数据结构后,旧存档会失效。务必包含
"version": "1.0.0"字段,并实现迁移逻辑。 - 切勿使用操作系统绝对路径——硬编码
C:/Users/...会导致存档在其他所有计算机上失效。务必使用user://协议,Godot 会将其映射到对应操作系统的应用数据文件夹。 - 切勿尝试直接保存 Node 引用——Node 是对象,不是原始数据。应将必要的基本数据(位置、生命值、等级)提取到
Dictionary或Resource中。 - 切勿忘记关闭 FileAccess 句柄——文件保持打开可能导致句柄泄漏和存档损坏。在 Godot 4 中,变量超出作用域时文件会自动关闭,但对于长时间运行的逻辑,显式调用
close()更安全。 - 切勿将 JSON 用于非常大的二进制数据——将 10MB 的纹理数据以 Base64 形式存入 JSON 会很慢,还会使文件体积膨胀。请使用二进制
store_var()或单独的专用资源文件。 - 切勿不经验证就信任加载的数据——用户可以编辑存档文件。务必使用
data.get("field", default_value),并验证数字是否在预期范围内,以防崩溃。 - 切勿在高频物理或动画更新期间触发保存——写入过程中崩溃会导致文件损坏。仅在进入菜单、完成关卡或到达检查点等明确的游戏事件发生时保存。
- 切勿在遍历 Dictionary 的键时修改它——在遍历同一个字典的循环中调用
erase()或add()会导致迭代错误。请使用data.duplicate()安全地进行遍历。 - 切勿在未加密的 JSON 中存储原始密码或敏感凭据——如果有敏感数据,请使用
FileAccess.open_encrypted_with_pass()对其进行保护。 - 切勿在主线程中使用 ResourceLoader.load() 加载大型场景——这会造成明显卡顿。请使用
ResourceLoader.load_threaded_request()在后台加载关卡。 - 切勿依赖 get_instance_id() 进行跨会话标识——这些 ID 在运行时分配,每次游戏重启都会变化。请为游戏对象生成自己的持久化
StringUUID。 - 切勿忘记对已加载的 Resource stats 块调用 duplicate(true)——如果多个敌人加载同一个 "goblin_stats.tres",除非进行复制,否则它们会共享同一个生命值池。
- 切勿对不可信数据使用 store_var/get_var 的 "allow_objects" 标志——将其设为
true会允许完整对象解码,这对从网上下载的存档构成重大安全风险。 - 切勿对需要严格保留类型的数据使用 JSON——JSON 会将
Vector3转换为字符串或字典。需要严格保留数据类型时,请使用var_to_bytes()或二进制格式。 - 切勿在持久化字典中保留内部元数据(set_meta)——这会不必要地增大存档文件。序列化前请清理字典。
可用脚本
必须:编写 SaveManager 代码前,先阅读所选格式对应的脚本。
save_load_patterns.gd
必须用于 JSON / binary / PERSIST 收集——模式默认使用 store_var(..., false)。
save_migration_manager.gd
必须用于任何包含 version 字段且版本可能落后于当前构建的存档。
save_system_encryption.gd
必须在使用加密存档槽前阅读——密码应来自安全存储 / 用户机密,示例中绝不可硬编码。
save_integrity_validator.gd
滚动生成 .bak 备份 + SHA-256 校验后再信任存档槽;校验不匹配时回退到备份。
深入了解(按需加载)
对于 JSON/PERSIST 演练、二进制示例、注意事项和高级加密流程,必须阅读 references/save-patterns-deep.md。请勿将第 1–3 步的 Autoload 教程粘贴到场景中。
专家须知(关键)
CAUTION: 基础教程使用了
store_var(data, true)。不可信的user://存档必须使用allow_objects=false——经过改装的文件或创意工坊文件存在 RCE 风险。
- JSON 中的向量 — 存储
{x,y,z}分量;JSON 无法忠实地往返转换Vector3。 - 滚动备份 — 写入过程中崩溃会损坏主文件;覆盖前先复制到
.bak(save_integrity_validator.gd)。 - 何时保存 — 仅在菜单、检查点或关卡完成时保存——绝不要在每个物理帧都保存。
决策树:选择持久化形式
| 需求 | 格式 | 必须 |
|---|---|---|
| 可读性强、小型或中型进度数据 | JSON + version | save_load_patterns.gd |
| 类型保真 Variants / 较大的数据块 | 二进制 store_var,并使用 allow_objects=false | 同上 |
| 类型化 Resource 树 / 检视器架构 | ResourceSaver / .tres/.res | 同领域技能 godot-resource-data-patterns |
| 自动收集多个场景节点 | PERSIST 组 + save()/load() | save_load_patterns.gd |
| 架构已演进 | 先迁移,再加载 | save_migration_manager.gd |
| 防篡改 / 敏感字段 | 加密的 FileAccess | save_system_encryption.gd |
不要在此处粘贴第 1–3 步的 JSON Autoload 教程——请根据脚本实现。
allow_objects 信任边界
默认始终使用 store_var(data, false) / get_var(false)。
| 情况 | allow_objects | 规则 |
|---|---|---|
玩家 user:// 存档、创意工坊 Mod、下载内容 | false | 绝不设为 true——存在 RCE 风险 |
| 仅限可信本地环境(自有工具、由你控制的离线调试夹具) | 仅在无法避免时设为 true | 说明原因;绝不要将其作为默认值发布;优先使用 Resources / 基元类型字典 |
加密的高级路径仍使用 false,除非载荷明确仅限可信本地环境且不可由用户编辑。
黄金路径(版本 → 迁移 → 备份 → 原子写入)
- 每个存档数据块都要包含版本字段。
- 版本不同时,通过 save_migration_manager.gd迁移。
- 覆盖前备份现有文件(使用
DirAccess.copy_absolute复制到.bak)。 - 写入临时文件后再重命名,或先备份再写入;验证打开文件时的错误。
- 完整性检查为可选项:使用
FileAccess.get_sha256比较;不匹配时回退到备份。 - 路径仅使用
user://——绝不要使用绝对 OS 路径。 - 何时保存——菜单、检查点、关卡完成时保存——绝不要在每个物理帧都保存。
设置可以单独使用 ConfigFile,与运行进度 JSON/二进制数据分开保存。
参考
渐进式披露:仅在研究特定 API 时打开官方文档链接;在转向同领域内容时加载相关技能——不要预先加载整个技能体系。
官方文档
- 保存游戏 — 持久化分组序列化、JSON 行格式,以及本技能基于的规范存档/读档流程。
- Godot 中的文件路径 —
user://与res://在不同操作系统应用数据文件夹中的映射;切勿硬编码绝对路径。 - 二进制序列化 API —
store_var/get_var的 Variant 编码、类型保真度,以及allow_objects对不可信存档不安全的原因。 - 后台加载 — 在恢复存档后,使用
ResourceLoader.load_threaded_request无卡顿地加载关卡/资源。 - 文件系统 — 使用 FileAccess/DirAccess 进行存在性检查、备份和安全覆盖。
- 资源 — Resource 与 Dictionary 持久化、
duplicate(true),以及何时.tres/.res比手写 JSON 更合适。 - 组 — Persist/PERSIST 自动收集模式使用的 SceneTree 组成员关系。
- FileAccess — 打开模式、带密码的 AES 加密辅助方法、SHA-256、压缩标志和缓冲区 I/O。
- JSON — 使用
stringify/parse/parse_string保存可读存档,并验证解析错误。 - ConfigFile — INI 风格的设置(
user://settings.cfg),与完整游戏状态存档分开。 - ResourceSaver — 当无法接受 JSON 类型信息丢失时,持久化带类型的 Resource/自定义 Resource 树。
- AESContext — 用于自定义压缩加密存档流程的底层 AES 分组加密/解密。
相关技能
前置要求
- godot-project-foundations — 在 SaveManager 管理路径之前,必须先配置好 ProjectSettings、Autoload 注册和
user://项目身份。 - godot-gdscript-mastery — 为版本化序列化/反序列化代码提供 Typed Dictionary、Resource 和错误处理模式。
- godot-autoload-architecture — SaveManager 几乎总是一个 Autoload;可借助此技能处理单例所有权、启动顺序和场景切换后的存续。
补充
- godot-resource-data-patterns — 自定义 Resource 架构和
.tres工作流,可与 ResourceSaver 配合使用,而不是将所有内容都扁平化为 JSON。 - godot-scene-management — 使用多线程切换场景,并在加载后清除/重建 Persist 节点,避免旧世界状态泄漏。
- godot-signal-architecture —
game_saved/game_loaded事件总线,让 UI 和系统能够响应,而无需与 SaveManager 硬连接。 - godot-ui-containers — 设置菜单会写入 ConfigFile/音量键值;此技能会将它们与游戏进度分开持久化。
- godot-inventory-system — 物品堆叠和装备字典是负载最大的 Persist 数据;需与存档迁移共享 ID 方案。
- godot-quest-system — 任务标记/阶段 ID 必须能在版本化存档中往返保存,且不影响日志 UI。
- godot-economy-system — 货币钱包和商店解锁需要与玩家进度相同的版本字段和验证。
下游 / 使用方
- godot-adapt-single-to-multiplayer — 本地存档模式会转变为由主机权威控制的状态同步;多人游戏中绝不要信任客户端编辑过的 JSON。
- godot-monte-carlo-balancer — 当存档中保存的成长/经济曲线需要针对迁移默认值进行模拟平衡测试时使用。
- godot-multiplayer-networking — 服务端验证和快照格式,可在竞技模式中取代明文
user://存档。
主项
- godot-master — 库路由器和镜像模块入口;探索哪个领域技能负责持久化或内容系统时打开。