个人游戏技术方案案例:剧情和关卡数据为什么没有直接写进代码

一个个人叙事游戏在内容管线、表格数据、脚本导入和编辑器工具之间做技术选择的案例,详细讨论 CSV、JSON、Notion、校验和版本管理。

写在前面:内容多的游戏,技术风险常常不在代码

个人叙事游戏最容易被低估的,不是文本量。

而是文本、条件、分支、道具、任务、触发器之间的关系。

一开始写在代码里很快。
第一个 NPC、第一段对白、第一个任务,都可以直接用脚本硬编码。

但当内容增长到几十个角色、几百段对白、上千行文本时,问题会集中爆发。

顾眠做过一款小镇信件叙事游戏。
玩家扮演邮差,每天分拣和递送信件,根据收件人的反应,慢慢改变小镇关系。

游戏没有复杂战斗,但内容很多:

  • 42 个居民
  • 180 封信
  • 16 条主要关系线
  • 400 多个条件分支
  • 多语言文本
  • 每天不同天气和事件

她很早决定:剧情和关卡数据不能直接写进代码。

最后她采用了 Notion 写作、CSV 导出、构建时转换 JSON、游戏内只读数据的方案。

一、为什么不直接用引擎编辑器

顾眠使用 Unity。

她最初想用 ScriptableObject 管理角色、信件和任务。
这个方案对少量内容很舒服。

但她很快发现几个问题:

  • 长文本在 Inspector 里编辑不舒服
  • 分支条件不适合在多个资源窗口里来回找
  • 多语言字段会让资源变得很宽
  • 内容修改和代码修改混在一起
  • 搜索某个角色所有相关信件不方便
  • 导出给校对人员很麻烦

ScriptableObject 适合结构化配置。
但这个项目的主要工作是写作、校对、查关系和改文本。

所以内容生产工具必须更像编辑环境,而不是程序资源面板。

二、为什么选择 Notion 加 CSV

顾眠用 Notion 不是因为它完美。

而是因为它解决了几个现实问题:

  • 写长文本舒服
  • 表格视图适合管理字段
  • 可以按角色、日期、任务线过滤
  • 评论和校对方便
  • 不需要自己开发编辑器
  • 导出 CSV 足够简单

她设计了几张表:

  • characters:居民基础信息
  • letters:信件内容、寄件人、收件人、日期
  • dialogues:对白节点和条件
  • quests:关系线进度
  • items:关键物品
  • terms:多语言术语表

每张表都有稳定 ID。

例如角色不是用名字关联,而是用 char_miller_anna 这样的 ID。
这样即使角色中文名改了,数据关系也不会断。

三、CSV 的问题怎么处理

CSV 很朴素,但有坑。

换行、逗号、引号、多语言字符、空字段,都可能出问题。

顾眠没有手写解析器。
她使用成熟 CSV 库,并规定:

  • 所有文件 UTF-8
  • 第一行必须是字段名
  • ID 字段不能为空
  • 文本字段允许换行
  • 多选字段用 | 分隔
  • 条件表达式不写复杂脚本,只写受限格式

例如一个对白条件写成:

has_item:old_photo|relation_ge:anna:3|day_ge:12

导入脚本会把它解析成结构化条件。

她刻意不允许在表格里写任意代码。
因为那会把内容管线变成另一个难调试的脚本系统。

四、构建时转换成 JSON

游戏运行时不直接读 CSV。

顾眠写了一个导入脚本,把 CSV 转成游戏使用的 JSON。

转换过程会做校验:

  • ID 是否重复
  • 引用的角色是否存在
  • 条件格式是否合法
  • 多语言字段是否缺失
  • 信件日期是否在有效范围
  • 任务线是否有断点
  • 文本长度是否超过 UI 限制

只有校验通过,才生成 JSON。

这让错误尽早出现。

如果玩家运行时才发现某封信引用了不存在的角色,已经太晚。
内容错误应该在构建阶段被挡住。

五、版本管理怎么做

Notion 本身不适合作为唯一历史记录。

顾眠每次重要导出都会把 CSV 提交到 Git。
生成的 JSON 也提交,但构建脚本可以重新生成。

她的目录大概是:

  • content_source/csv/
  • content_build/json/
  • tools/import_content/
  • docs/content_schema.md

content_schema.md 记录每个字段含义、是否必填、示例和注意事项。

这个文档很重要。

两个月后再回来看表格,开发者自己也可能忘记 trigger_afterunlock_after 的区别。
内容管线没有文档,最后会变成猜谜。

六、本地化如何提前考虑

顾眠一开始就为多语言留了字段。

她没有等中文写完后再加英文。

每条文本都有:

  • text_zh
  • text_en
  • note_for_translator
  • speaker
  • context

其中 note_for_translator 很有用。
它说明这句话的场景、语气、是否有双关、是否不能太长。

个人叙事游戏本地化最怕只给译者一堆孤立句子。
没有上下文,翻译质量会明显下降。

她还在导入校验里检查 UI 长度。
英文太长的按钮和对白,会在构建时报 warning。

这比发售前最后一周才发现文本溢出要好得多。

七、为什么没有做完整自研编辑器

顾眠考虑过做一个剧情编辑器。

节点图、条件可视化、实时预览,看起来很理想。

但她最后没有做。

原因很简单:编辑器本身会变成一个新项目。

她只补了两个小工具:

  • 对话预览器:读取 JSON,按条件展示一段对话
  • 引用检查器:输入角色 ID,列出所有相关信件和任务

这两个工具解决了真实痛点。
而不是为了“专业管线”去做一个庞大系统。

个人开发者做工具要克制。
工具应该服务内容生产,不应该成为逃避内容生产的地方。

结语:内容管线的目标是少犯错

顾眠的方案不高级。

Notion、CSV、JSON、校验脚本、两个小工具。
组合起来却很可靠。

它让写作、校对、导入、测试、本地化之间有了清楚边界。

个人游戏的技术方案,不一定要追求全自动和全可视化。
对于内容密集型项目,最重要的是:

  • 内容能舒服地写
  • 关系能查清楚
  • 错误能提前发现
  • 版本能回退
  • 本地化有上下文

当这些成立时,技术就真正帮到了创作。

继续阅读

探索更多技术文章

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

全部文章 返回首页