存档为什么要提前设计
个人游戏很容易把存档留到后面:先用内存变量跑通流程,测试时按一个键跳关,等内容差不多了再写存档。这样做在小原型里可行,但对准备上 Steam 的项目风险很高。存档一旦接入,关卡解锁、收集品、成就、设置、云同步、Demo 到正式版迁移都会受影响。
玩家最难原谅的技术问题之一就是丢档。哪怕游戏内容很小,只要玩家投入了时间,存档损坏、进度回退、设置丢失都会直接影响评价。Steam 云存档能帮助玩家跨设备同步,但它不是替你设计存档系统;如果本地文件结构混乱,云同步只会把混乱传播到更多机器。
先确定存档范围
不要一开始就把所有东西塞进一个 JSON。先列清楚哪些数据属于存档,哪些属于设置,哪些属于运行缓存:
| 数据 | 建议位置 | 是否云同步 |
|---|---|---|
| 主线进度 | 存档槽 | 是 |
| 收集品 | 存档槽 | 是 |
| 当前关卡临时状态 | 自动存档或检查点 | 视类型 |
| 音量、画面设置 | 本机设置 | 通常否 |
| 键位绑定 | 本机设置 | 通常否 |
| 语言选择 | 本机设置或账号设置 | 看需求 |
| 日志、崩溃报告 | 本机日志 | 否 |
这个拆分很重要。把键位和画面设置放进云同步,玩家在台式机调好的 4K 全屏配置可能同步到掌机,造成启动体验变差。反过来,收集品和章节进度不进云同步,玩家换电脑就会觉得 Steam 云存档没有生效。
存档文件结构
一个清晰的文件结构可以这样设计:
Saves/
slot_01/
save.json
screenshot.png
backup.json
slot_02/
save.json
screenshot.png
Settings/
local_settings.json
Logs/
latest.log
存档槽目录里只放与进度相关的内容。截图可选,但对继续游戏界面有帮助。backup.json 用于防止写入过程中损坏。设置和日志分离,后面配置 Steam 云同步时就能只同步 Saves/,不把日志、缓存、机器设置一起上传。
存档格式要可迁移
即使首发版本很简单,也要在存档里写版本号:
{
"saveVersion": 3,
"gameVersion": "0.9.0-rc1",
"slotName": "Chapter 2",
"playTimeSeconds": 6420,
"progress": {
"chapter": 2,
"checkpoint": "factory_gate"
}
}
版本号不是摆设。开发过程中你会重命名关卡、删除道具、调整任务结构。如果没有迁移逻辑,旧存档可能直接报错。迁移可以写成一组小函数:v1 -> v2、v2 -> v3。加载存档时逐步升级,升级成功后再写回新版本。
个人项目不需要写企业级数据库迁移,但要尽量避免旧 Demo 存档、测试玩家存档和正式版候选存档轻易报废。Steam 首发前如果有公开 Demo,这点尤其重要。
自动保存的触发点
自动保存要让玩家安心,但不能频繁到影响性能或制造错误状态。常见触发点包括:
| 类型 | 触发点 |
|---|---|
| 章节游戏 | 进入新房间、完成关键目标、过场结束 |
| Roguelite | 每个房间结束、商店购买后、死亡结算 |
| 模拟经营 | 每天结束、重要订单完成、手动保存 |
| 解谜游戏 | 关卡开始、解开关键机关、退出关卡 |
不要在危险的中间状态保存,例如角色正在死亡动画、物理对象尚未稳定、任务奖励还没发完。存档应该记录一个可恢复的稳定点。否则玩家读档后可能站在陷阱里、任务无法继续或 UI 卡在过场状态。
写入要防止损坏
存档写入不是简单覆盖文件。更稳妥的流程是:
- 把当前
save.json复制为backup.json。 - 写入
save.tmp。 - 校验
save.tmp内容可解析。 - 原子替换为
save.json。 - 保留最近一次有效备份。
如果游戏在写入中崩溃或断电,至少还有旧文件可恢复。加载时也要有策略:先读主存档,失败后读备份;如果备份可用,提示玩家恢复,而不是直接清空槽位。
Steam 云同步目录
Steam 云存档配置时,关键是同步路径和文件模式。个人游戏要先决定本地存档放在哪里,再去 Steamworks 后台配置对应路径。不要今天写到游戏安装目录,明天改到用户文档,后天又放到 AppData。
设计路径时考虑:
- 不要写入安装目录,玩家可能没有权限。
- Windows、macOS、Linux 路径要有明确规则。
- 云同步只覆盖必要文件。
- 文件数量和大小要可控。
- Demo 和正式版是否共用存档要提前决定。
如果 Demo 存档可以迁移到正式版,目录和 App ID 关系要谨慎。正式版读取 Demo 存档时,最好做一次显式导入,而不是两个产品随意读写同一目录,避免测试包、Demo 包和正式包互相覆盖。
存档与成就关系
Steam 成就通常由游戏事件触发,但存档会影响成就补发。玩家离线游玩后重新上线,或者从旧版本升级到新版本,游戏需要根据存档判断是否补发已满足条件的成就。
建议把成就条件分为两类:
| 类型 | 处理 |
|---|---|
| 事件型 | 击败 Boss、完成关卡时立即触发 |
| 状态型 | 收集数量、通关难度、结局达成可从存档补发 |
状态型条件要能从存档里可靠计算。不要只在触发那一刻发成就却不记录状态,否则玩家错过同步时很难补救。
存档 UI 的基本信息
继续游戏界面不要只显示“存档 1”。至少显示章节、地点、游玩时长、最后保存时间。如果类型允许,显示一张小截图能帮助玩家回忆。
存档槽操作要防误触:
- 删除存档需要二次确认。
- 覆盖手动存档要提示。
- 自动存档和手动存档要区分。
- 损坏存档要给恢复或反馈入口。
这些细节看起来不属于“核心玩法”,但对 Steam 玩家很重要。尤其是长流程游戏,存档界面就是玩家信任系统的入口。
测试清单
存档测试不要只测“能保存能读取”。至少覆盖:
| 测试 | 预期 |
|---|---|
| 新游戏保存后退出 | 重新启动可继续 |
| 写入中强制关闭 | 可从主档或备份恢复 |
| 旧版本存档加载 | 迁移成功或给出清楚提示 |
| 删除设置文件 | 游戏重建默认设置 |
| 多槽位切换 | 槽位互不污染 |
| 离线启动 | 本地存档可用 |
| Steam 云冲突 | 玩家能识别时间和设备 |
| Demo 到正式版导入 | 不覆盖正式版已有存档 |
云冲突尤其要认真测。玩家在两台设备上分别玩了不同进度,Steam 可能提示冲突。游戏内如果也有存档选择,要让时间、章节和设备信息尽量清楚,降低误选概率。
给个人开发者的实现顺序
一个可落地的顺序是:
- 定义存档数据结构和版本号。
- 实现本地保存、读取、备份和错误处理。
- 实现设置文件分离。
- 加入自动保存触发点。
- 做存档槽 UI。
- 写迁移框架,即使只有一个版本。
- 接入 Steam 云同步路径。
- 用两台机器或两个系统账号测试冲突。
不要等游戏内容全部完成再补存档。越晚接入,越多系统会默认“当前状态只存在内存里”,后面改起来更痛苦。
最终检查清单
- 存档、设置、日志目录分离。
- 存档包含版本号和游戏版本号。
- 写入过程有临时文件和备份保护。
- 自动保存只发生在稳定状态。
- 旧存档有迁移或清楚提示。
- 云同步只覆盖必要进度文件。
- Demo 与正式版存档关系明确。
- 存档 UI 能让玩家判断内容和时间。
存档系统做得好时,玩家几乎不会注意到它;做得不好时,玩家会记得非常清楚。个人项目资源少,更要把存档当成基础设施,早做、少变、可恢复。
存档问题的玩家沟通
如果上线后出现存档问题,公告和回复要尽量具体。不要只写“已修复若干问题”,而要说明影响范围、是否会自动恢复、玩家是否需要备份文件、旧版本存档是否仍可读取。涉及丢档时尤其要谨慎,先保护玩家现有文件,再提供修复包。
游戏内也可以准备一个简单的恢复入口:检测到主存档损坏时,显示最近备份时间,让玩家选择恢复或退出。即使恢复功能不复杂,也比直接覆盖或静默失败更让人安心。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。