个人游戏技术方案案例:存档系统为什么要从第一周开始设计

一个个人游戏在本地优先存档、配置版本、迁移和云同步之间做技术选择的案例,详细讨论存档边界、兼容性、测试和发布风险。

写在前面:存档不是最后加一个保存按钮

很多个人游戏项目早期只关心玩法能不能跑。

存档常常被放到后面:

“先用临时 JSON 存一下。”
“等内容稳定了再做正式存档。”
“发售前补上云同步就行。”

这种想法很常见,也很危险。

沈知衡做过一款轻量基地经营游戏。
玩家在一列环城列车上安排车厢、招募乘客、生产食物和零件,让列车在不断变化的城市边缘维持运转。

项目看起来不复杂,但状态很多:

  • 车厢顺序
  • 每节车厢设施等级
  • 乘客属性和心情
  • 库存资源
  • 城市事件进度
  • 已解锁蓝图
  • 当前任务
  • 每天的随机种子

他在第一周就决定把存档系统单独设计。
这个决定后来救了项目。

一、先区分三类数据

沈知衡最初做的不是写保存代码,而是给数据分类。

他把游戏数据拆成三类:

第一类是静态配置。
比如车厢类型、设施价格、乘客职业、事件文本。这些随版本发布,不属于玩家存档。

第二类是运行状态。
比如当前库存、乘客位置、任务进度、今天发生了什么。这些需要保存。

第三类是派生状态。
比如每分钟产量、车厢舒适度、乘客满意度。这些可以从前两类计算出来,不直接保存。

这个分类看似基础,但非常关键。

如果把派生状态也存进去,后期平衡调整会很痛苦。
例如更新后设施产量改了,但旧存档里保存着旧产量,就可能出现不一致。

他的原则是:能计算出来的,不进存档。

二、存档格式选择 JSON,而不是二进制

沈知衡考虑过二进制格式。

二进制体积小,也不容易被玩家随手改。
但他最后选择 JSON。

原因很现实:

  • 开发期容易打开检查
  • 玩家反馈 bug 时可以让他定位问题
  • 版本迁移脚本更好写
  • 个人项目存档体积不大
  • 不需要防作弊

他做了一点基本保护:

  • 存档文件包含版本号
  • 写入时先写临时文件,再原子替换
  • 保存前做 schema 校验
  • 关键字段有默认值
  • 崩溃时保留上一份备份

这比复杂加密更有价值。

个人单机游戏的存档系统,第一目标不是防玩家改,而是别丢玩家进度。

三、版本号必须从第一个存档开始

沈知衡在第一版存档里就放了:

{
  "saveVersion": 1,
  "gameVersion": "0.1.0",
  "createdAt": "...",
  "updatedAt": "...",
  "profileId": "..."
}

很多开发者会觉得早期没必要。

但版本号越晚加,越难补。
因为你无法可靠判断旧文件属于哪个结构。

他还写了一个 SaveMigrator

  • v1 -> v2:给乘客增加健康字段
  • v2 -> v3:把车厢设施从字符串改成对象
  • v3 -> v4:加入事件历史记录

每次迁移只做一件事。
迁移完成后再保存成新版本。

这让测试变得可控。

四、为什么先不做云同步

项目早期,有玩家建议支持 Steam Cloud。

沈知衡没有立刻做。

他先把本地存档做稳,再考虑云同步。
理由是云同步会放大存档问题。

如果本地存档偶尔损坏,只影响一个文件。
如果云同步把损坏文件上传,玩家可能在多台设备上都丢进度。

他设定了几个前置条件:

  • 本地保存连续压力测试通过
  • 旧版本迁移通过
  • 备份恢复流程可用
  • 存档路径符合平台规范
  • 多档位逻辑稳定

这些完成后,Steam Cloud 才有意义。

个人开发者不要把云同步当成简单勾选项。
它是建立在本地存档可靠之上的功能。

五、自动保存的时机比按钮更重要

这款游戏有明确的天数推进。

沈知衡设计了三种保存:

  • 手动保存:玩家主动存档
  • 日结自动保存:每天结束时保存
  • 关键操作备份:车厢重排、事件选择前保存临时备份

他没有每秒保存。

因为频繁写盘会增加性能和损坏风险,也让 bug 更难回滚。
他选择在状态边界清楚的时刻保存。

例如玩家点击“结束当天”时,游戏先生成明天事件,再保存完整状态。
如果中途崩溃,仍能回到当天结束前的备份。

存档系统不是保存得越勤越好。
关键是保存点要符合玩家的心理预期。

六、存档测试怎么做

沈知衡写了几类简单测试。

第一类是往返测试。
创建一个复杂列车状态,保存,再读取,确认关键字段一致。

第二类是迁移测试。
保留几份旧版本样例存档,确保新版本能打开。

第三类是损坏测试。
手动删字段、改类型、截断文件,确认游戏能提示错误或使用备份,而不是直接崩溃。

第四类是长流程测试。
模拟 200 天推进,检查存档体积和读取时间。

这些测试不华丽,但非常实用。

个人游戏如果没有专门 QA,存档测试更应该自动化一点。
因为存档 bug 往往发售后才最痛。

七、最后采用的方案

沈知衡的最终方案是:

  • 本地优先 JSON 存档
  • 明确区分配置、运行状态和派生状态
  • 每个存档包含版本号
  • 所有版本迁移集中管理
  • 原子写入加备份
  • 发布前再接入 Steam Cloud
  • 保留旧版本样例存档用于回归测试

这个方案不复杂。

但它稳定、可检查、可迁移,适合一个人维护。

结语:存档系统是玩家信任的一部分

沈知衡后来遇到过一次严重平衡问题,也遇到过几次崩溃。
但因为存档和备份做得稳,玩家没有大规模丢进度。

这比很多新功能都重要。

个人游戏的技术方案,不一定要先进。
但涉及玩家投入时间的地方,必须保守。

存档不是工程边角料。
它是玩家愿意继续玩、愿意等待修复、愿意相信开发者的基础。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页