一个人做游戏,怎么管住满地乱爬的文档?

05/09111 浏览开发心得
我是 TapTap 独立开发者,用 AI 辅助做了一款叫《今天也元气满满》的职场 SAN 值生存游戏。
上篇帖子讲了怎么用 AI 辅助写文案并保证质量,这篇讲另一个让我头秃的问题:文档一致性
这篇文章里的方法不只适用于我的游戏——任何用 AI 辅助开发、有多份设计文档的项目都会遇到同样的问题。

你的文档在骗你

你有没有遇到过这种情况——
你在设计文档里写着"玩家初始生命值 100",但代码里早就改成 150 了。三个月后你让 AI 帮你加个回血道具,AI 读了那份文档,按 100 来平衡数值——结果完全不对。
或者:你在角色表里写了 12 种敌人类型,但代码里已经有 16 种了。你让 AI 写新关卡,它参考了过期的角色表,少用了 4 种敌人。
或者:你改了某个 NPC 的名字——代码改了,策划文档没改。下次让 AI 写剧情对话,它写了一个已经不存在的角色名。
改一处忘另一处。改两处忘第三处。 直到某天你看着两份互相矛盾的文档,不知道哪个是真的。
这种现象有个名字:文档漂移
在大公司里,有专人维护文档、有 review 流程兜底。但你是独立开发者——你同时是策划、程序、美术、测试、文档管理员、以及唯一的校对人员。
你在给自己当 HR,而你管的"员工"是十几份文档。它们各说各话,阳奉阴违,表面上岁月静好,底下全是不一致。
拿我的项目来说:16 种角色类型,19 个场景分区,200 多条随机事件,十几份设计文档。每改一处代码,可能需要同步更新 3-4 份文档。光靠脑子记?迟早翻车。

什么是 SSOT?说人话

SSOT 是 Single Source of Truth 的缩写,翻译成大白话就是:每条信息只允许有一个"官方版本"。
举个生活中的例子:你的身份证号码。派出所的户籍系统是唯一真相源。你的银行卡、社保卡、驾照上都印着这个号码——但它们都是抄过去的副本。如果副本和户籍系统不一致,改副本,不改户籍系统。
游戏开发里也是一样。你的角色数据、关卡配置、数值平衡——这些信息可能同时出现在代码、设计文档、AI 提示词好几个地方。SSOT 要求你指定其中一个地方是权威的,其他都是影子。

为什么是代码?——Code as SSOT

我选择的权威来源是代码
为什么不是设计文档?因为代码是实际运行的东西。你文档上写着"Boss 血量 1000",代码里是 1500——玩家打到的是 1500。文档可以说谎,代码不会。
Code as SSOT(代码即真相源) 就三句话:
- 代码是权威:角色有几种、数值是多少——官方答案在代码里。比如"敌人类型"以 `config.lua` 为准
- 文档是派生物:设计文档从代码推导,不是独立存在。`角色表.md` 是代码的影子
- 冲突时代码赢:发现文档和代码不一致?改文档。永远不要反过来
听起来像常识。但当你凌晨两点在十几个文件之间反复横跳、试图搞清楚"到底是文档错了还是代码错了"的时候,你会发现这条原则能救命

为什么 AI 开发特别需要 SSOT?

传统开发流程里,文档漂移很烦但还不致命——因为最终是你自己写代码,你脑子里知道最新版本是什么。
AI 辅助开发把这个问题放大了十倍:
1. AI 没有记忆:每次新的对话,AI 都是一张白纸。它只看你喂给它的文档和代码——如果那份文档是过期的,它就会基于错误信息干活
2. AI 很听话:你说有 12 种敌人,它就按 12 种来。它不会质疑"你代码里好像有 16 种啊"
3. AI 看不出矛盾:两份文档说的不一样,AI 可能随机信一份,或者试图把两个矛盾的版本融合起来——产出一份四不像
过期文档 + 信任 AI = 批量生产垃圾。
这就是我建立 SSOT 的直接原因。不是为了"文档管理最佳实践"这种空话,是因为 AI 把过期文档的代价放大到了不可忍受的程度。

实战:三个等级的 SSOT 方案

下面从最简单到最复杂,介绍三个等级的做法。你可以根据自己项目的规模,选一个合适的开始。
等级 1:给文档贴一张"我不是官方"的标签
成本:30 秒。适合:信息量不大、条目不超过 20 个的文档。
做法:在设计文档开头加一段声明——
> ⚠️ SSOT 声明:角色列表和属性数据以代码(config.lua)为准。
> 本文档仅供参考,如与代码不一致,以代码为准。
就这么简单。
这段话不是写给你自己看的,是写给 AI 看的。 AI(比如 Claude)读到这段声明,就知道:“这份文档可能不是最新的,我应该去代码文件里确认。”
相当于给文档贴了一张条——“本文件仅供参考,如有出入以工牌信息为准”。就像你们公司前台贴的那种东西。
拿我的项目举例:我的部门设计文档 departments.md 开头就写了——
部门列表和 NPC 分配以代码(npc_cast.lua)为准。
结果:AI 每次读这份文档,都会自动去代码里确认最新的部门列表,不再盲目信文档上写的东西。
延伸技巧:在文档末尾加一个维护检查清单——
## 维护指南
新增角色类型时:
1. 在 config.lua 添加角色定义
2. 在 characters.md 补充描述
3. 更新 event-guide.md 的角色列表
不需要自动化。肉眼扫一遍比什么花哨工具都靠谱。

等级 2:克制"顺手复制一遍"的冲动

成本:0(甚至是负的——你少写了东西)。适合:所有项目。
这不是一个工具或技术,而是一个心态转变
做游戏的时候,你会下意识地把同一份数据复制到好几个地方——角色表里写一遍名字和属性,UI 文档里又写一遍,美术需求文档里再写一遍。“查阅方便嘛。”
而且如果你用 AI 辅助开发,这个问题会加倍。 AI 帮你写文档的时候,有时候规规矩矩只写引用——“角色数据详见 config.lua”;有时候它心血来潮,把另一份文档里的数据原封不动搬过来抄了一遍。同一个 AI,同样的指令,它今天写引用明天写复制,完全看心情。你以为你在管理文档——其实你在看 AI 脸色。
结果就是:你回头一看,有的文档是引用,有的文档是副本,分布毫无规律。而那些被 AI 随手复制过去的副本,从诞生那一刻起就开始默默过期了。
信息多一份拷贝,就多一个说谎的机会。
所以我现在的做法是:从源头上堵死复制的可能性。 在文档里明确写"本文档不重复这些数据"——这不仅是给自己看的,更是给 AI 看的。AI 读到这句话,就不会再"顺手"帮你抄一遍了。
以我的角色肖像文档为例。我在写美术需求时,手特别痒,想把 16 种角色的名字、emoji、配色全抄进去。然后我克制住了——这些数据在 config.lua 里已经有了,再抄一份就是定时炸弹。
我的肖像文档只写画面描述——“表情严肃刻板,衣领笔直熨烫,眼神像在检查你的工牌有没有戴正”。不写名字不写 emoji。需要这些信息?去代码里查。
> 本文档仅定义视觉设计特征。
> 角色基础数据(名字、属性)的唯一来源为 config.lua。
> 本文档不重复这些数据。
SSOT 的核心不是"把信息管好",而是"从源头上消灭冗余"。你不需要同步两份文档——如果根本只有一份。
这个道理适用于所有类型的游戏项目:
- 角色属性:❌ 代码一份、策划文档一份 → ✅ 代码为准,文档只写补充说明
- 关卡数据:❌ 代码一份、Excel 一份 → ✅ 代码为准,Excel 只做草稿
- UI 文案:❌ 代码一份、文案表一份 → ✅ 代码为准,文案表标注"已合入代码"
- 数值平衡:❌ 代码一份、平衡表一份 → ✅ 代码为准,平衡表标注数据来源

等级 3:让脚本替你盯着——审计工具

成本:让 AI 写脚本十几分钟,之后持续回本。适合:条目超过 100 个的项目。
当你的游戏内容量大到"手动盘点"不现实时,就需要脚本来帮你了。
拿我自己的项目说。我的游戏有 200 多条随机事件,分布在十几个代码文件里。我一直在扩充内容库——每个版本加几十条新事件。问题是:加到后面我自己都说不清楚,到底有多少条了,哪些类型还缺,哪些类型已经饱和了。
如果你做过内容驱动型游戏——关卡、对话、任务、道具——你一定懂这种感觉。内容量小的时候你心里有数,超过一百条以后就全靠猜了。
我需要一份"库存清单"。但这份清单不能是手动维护的——手动维护的清单和代码一定会脱节,那就又回到文档漂移的老问题了。
解法:让 AI 帮我写一个审计脚本,自动扫描代码、统计数据、生成报告:
代码文件(*.lua)               ← 这是 SSOT
       ↓
  审计脚本(Python)             ← 扫描代码,统计数据
       ↓
  输出报告                       ← "共 214 条事件,
                                    轻度事件 85 条,
                                    重度事件 42 条,
                                    Day1-3 缺口较大……"
有了这份从代码实时生成的库存清单,我和 AI 就能一起看着它讨论:"哪些类型还需要补充?下一批先做什么?"——而不是凭记忆猜。
这就是 SSOT 的高级应用:不只是"防止文档过期",而是"让代码自己告诉你全局是什么样"。
当然审计工具还有一个经典用法——对账。比如你文档里记着"事件总数 174",跑一遍脚本发现代码里实际有 214 条——差了 40 条。文档悄悄过期了,你自己不知道。审计脚本帮你发现。
重点来了:这不是"自动同步",是"自动对账"。
- 审计工具(推荐):只读取、只报告。最坏后果是报了个假阳性,你多看一眼。安全性高——不改任何文件
- 自动同步工具(危险):读取并自动写入。最坏后果是把错误数据静默写进代码。安全性低——出了 bug 你不知道
为什么不做自动同步?因为自动同步工具可能帮你把错误同步过去——而你不会知道。审计工具最安全:它只汇报,不裁决。就像公司里的内审——他告诉你"账对不上",但不替你做账。
我甚至给它起了个绰号:密报狗——跟我游戏里那个到处收集情报只汇报不做决定的角色一样。审计工具就该当密报狗。

围绕 SSOT 的工作流长什么样?

上面三个等级不是孤立的。在实际开发中,它们会自然地串成一条工作流。我拿自己的事件制作流程举个例子——
内容生产的具体流程(AI 怎么写、怎么校验、怎么导入代码)以后有机会单独聊。这里只讲和 SSOT 直接相关的两个环节
┌─────────────────────────────────────────────────┐
│                                                 │
│  1. 开工前——从代码提取情报                      │
│  ┌───────────────────────────────────┐          │
│  │ 工具:event_digest.py             │          │
│  │ 做什么:扫描所有事件代码文件,     │          │
│  │   自动生成"已有内容速查表"        │          │
│  │ 产出:一份从代码实时生成的摘要清单│          │
│  └───────────────────────────────────┘          │
│      ↓ 摘要清单给 AI 看,避免重复               │
│                                                 │
│  2. 中间……AI 写内容、导入代码(略)             │
│                                                 │
│  3. 收工后——审计对账                            │
│  ┌───────────────────────────────────┐          │
│  │ 工具:event_inventory_check.py    │          │
│  │ 做什么:扫描代码,数一数实际有    │          │
│  │   多少条,和文档记录对比          │          │
│  │ 产出:差异报告(哪些对不上)      │          │
│  └───────────────────────────────────┘          │
│      ↓ 更新文档 + 更新摘要,为下一轮备料        │
│                                                 │
└─────────────────────────────────────────────────┘
两个工具,一个负责"开工前搞清楚现状",一个负责"收工后验证一致性"。 中间的内容生产流程不管多复杂,SSOT 只管两头:从代码提取,向代码对账。
这两个工具有一个共同点:都是只读的,不写入任何文件。 这是故意的——读错了你多看一眼就好,写错了你可能不知道。

如果你也想试试

不需要一步到位。根据你的项目规模,从最简单的开始:
第一步:给每份文档贴标签(5 分钟搞定)
让 AI 帮你打开设计文档,在开头加一段:
> ⚠️ 数据权威来源:xxx.lua
> 本文档如与代码不一致,以代码为准。
然后在末尾加一个维护清单:
## 维护指南
> 修改 xxx 时,还需更新:
> 1. 文件 A 的第 X 部分
> 2. 文件 B 的第 Y 部分
这一步零成本,但效果立竿见影——AI 下次读到这份文档,会自动识别这些声明,去代码里确认最新数据。

第二步:让 AI 帮你排查冗余信息

让 AI 扫一遍你的文档,找出"同一份数据在好几个地方出现"的情况:
- 角色名字在代码里有,文档里又抄了一遍?→ 让 AI 把文档里的改成引用
- 数值在代码里有,文档里又存了一份?→ 让 AI 标注"以代码为准"
- 和代码重复的文字描述?→ 让 AI 删掉,或加"以代码为准"标注
你只需要告诉 AI:"这份文档做一下 SSOT"或者"code as SSOT"——意思就是:把文档里和代码重复的数据删掉,改成引用,标注代码为权威来源。用多了以后这就是一句话的事。
记住:少一份拷贝,少一个说谎的机会。

第三步:数据量大了再上工具(按需)

当你的内容超过 100 条——比如 100 个关卡、100 种道具、100 条对话——手动对账不现实了,让 AI 帮你写一个审计脚本。
审计脚本不需要多复杂。核心逻辑就一个:
> 扫描代码 → 数一数有多少条 → 和文档里记录的数字对比 → 不一样就喊一声
让 AI 用 Python 写,大概几十行就够了。跟 AI 说清楚一条规矩:只读不写

这套方法给我带来了什么

AI 变靠谱了
SSOT 声明就是 AI 的导航系统。AI 每次对话都是一张白纸——它不记得你昨天改了什么。但它读到文档开头那段声明,10 秒内就能搞清楚"这份文档不是权威,权威在代码里",然后自动去代码确认。
过去 AI 经常基于过期文档给我产出错误内容。现在这种情况基本消失了。
不焦虑了
以前改完代码,心里总在嘀咕:我是不是忘了改哪个文档?
现在不嘀咕了。文档明确标注了自己是"派生物"。它过期了,最坏的结果是下次审计脚本会告诉你。它不会悄悄给你下绊子——因为所有人(包括 AI)都知道它不是权威。
做减法比做加法有效
SSOT 看起来是"加了声明、加了脚本"。其实它的核心是做减法——消灭冗余的信息副本、消灭"这份文档是不是最新的"这个问题本身。
你不需要同步两份文档。你需要的是只有一份

懒人终极方案:一句话让 AI 自己干

上面说了三个等级、五个步骤。你可能在想:“道理我都懂,但我每次开新对话,都得跟 AI 重新解释一遍什么是 SSOT、怎么同步、脚本模式是什么——这不又成了人肉同步器?”
是的。你在教 AI 不要做人肉同步器的同时,你自己变成了教 AI 的人肉同步器。这就像你给每个新来的实习生讲一遍公司流程,讲到第五遍的时候你开始怀疑人生。
解决方案:把整套 SSOT 工作流做成一个 Skill——你可以理解为给 AI 预装了一套"老员工经验包"。装上以后,你只需要说一句话:
"code as SSOT"
AI 就会自动开始干活:扫描你的代码和文档,找出数据重叠的地方,数据量少就贴标签,数据量大就当场写一个同步脚本——按照标记对的模式(代码→文档单向同步,支持 dry-run 预览),然后把新工具记录到项目文档里。
不解释概念。不给你贴教程。不跟你讨论"SSOT 的理论基础"。直接干
就像你终于受不了了,给那个实习生写了一份 SOP,从此再也不用口述流程了。只不过这份 SOP 是给 AI 读的。
怎么做? 自己动手做一个。用 Skill 创建功能,把本文描述的 SSOT 三级体系和标记对同步模式写进去就行。Skill 的核心就是一份 SKILL.md——告诉 AI"别解释概念,直接扫描代码和文档,找到数据重叠就干活"。你的项目有什么特殊的同步需求,就往里加什么规则。比我给你一个通用模板好用,因为最了解你项目的人是你自己。
我们自己的工作流就是这样:说一句"code as SSOT",AI 先跑已有的同步脚本(比如结局文案同步、事件清单审计),再扫一遍代码和文档找新的数据重叠,发现了就当场写脚本或贴标签,最后把新工具补进文档。全程不需要解释什么是 SSOT。

总结:三条原则

1. 每条信息只有一个家 — 指定代码为权威来源,文档是影子
2. 声明比自动化便宜 — 文档头部加一行"以代码为准",30 秒见效
3. 审计工具只读不写 — 只汇报差异,不自动修改。读错了没事,写错了要命
独立开发者最稀缺的资源是注意力。不是代码能力,不是美术(有 AI 了),不是时间管理——是注意力。
文档漂移消耗的就是注意力。你要花精力去想"这份文档是不是最新的""这个数字从哪来的""代码和文档对不上谁错了"。
SSOT 不是什么高深的架构设计。它就是一条朴素的原则:别让自己的大脑当人肉同步器
给每份文档贴上"以代码为准"的标签。然后你就可以把注意力放在真正重要的事情上——做游戏。
游戏:#今天也元气满满(TapTap 搜索可玩)
有问题欢迎评论交流,踩过的坑越多越值得聊~
6
11