AIGC标识 AI-Native游戏开发(1):为什么选择图数据库

0. 系列文章导航

3句话,AI给我生成了一个galgame
AI-Native游戏开发(1):为什么选择图数据库
AI-Native游戏开发(2):角色美术生产链
AI-Native游戏开发(3):角色声音生产链
AI-Native游戏开发(4):场景与BGM生产链
AI-Native游戏开发(5):剧情台词生产链
AI-Native游戏开发(6):叙事图自增长

1. 从 Vibe Coding 到 Spec Coding

Vibe Coding 的核心流程非常简单:

想法 → Prompt → 代码 → 运行 → 反馈 → 继续修改。

它非常适合项目早期的产品原型。当需求不断变化时,开发者直接告诉 AI 想做什么,AI 负责改,人负责看效果。这个循环的吞吐量惊人,但也埋着一个前提:AI 对项目的全部理解,都来自当前对话的上下文

问题出现在项目逐渐变复杂之后。代码越来越多,模块越来越多,项目上下文越来越大。任何一次修改,AI 都需要重新理解一遍项目;任何一个新会话,都要从零建立认知。此时瓶颈悄悄换了位置——问题从:

「AI 能不能写代码?」

变成了:

「AI 能不能理解这个项目?」

于是有了自然的下一步:引入 Specification,把项目知识从对话里抽出来,变成长期保存在仓库中的规格说明。需求、设计、实现分层落档,AI 的工作不再依赖某个具体对话,而是依赖这些规格。这种工作方式可以称为 Spec Coding:它的核心价值,是让项目知识从短期对话上下文中抽离,形成可以长期维护的资产。

对一个要持续迭代几个月的项目,这一步是必须的。但它仍然没有解决一个更根本的问题。

2. Spec Coding 的三堵墙

墙一:前驱无法同步更新

假设一个功能由三层组成:功能设计 → 接口设计 → 代码实现。手工修改代码之后,很容易变成这样的局面:

  • 功能设计 ✓(还是旧的,但没人发现不一致)
  • 接口设计 ×(已经和代码对不上了)
  • 代码实现 ✓(这才是最新的真相)

代码变了,前驱文档没跟上。当然,可以要求 LLM 顺手更新这些文档。但这件事没有想象中简单——真实项目的文档是逐步细化的,一个功能可能有四层前驱。当最底层代码变化时,AI 首先要回答:哪些前驱受到了影响?影响从哪一层开始?哪些要改、哪些其实不用改?

如果没有显式的依赖关系,AI 只能重读大量文档、靠上下文猜。 猜就有猜错的时候,也有每次都猜、每次都猜得不一样的时候。

墙二:Token 与准确率

靠重读文档来推断关系,代价是双重的。第一是 Token 消耗:每次修改都要扫一遍可能相关的全部文档,项目越大Token消耗越夸张。第二是准确率:一个典型的失败模式是——项目里某个公共方法已经存在,本来只需要一次重载,AI 没有准确理解项目结构,于是重新实现了一个新的,甚至每次都扫描整个项目来「确认」。

这不是模型能力问题,而是信息组织问题:知识都在,但关系不可见。

墙三:关系不可见

三堵墙其实是同一堵:AI 缺少的不是更多文档,而是文档之间明确的关系。文档系统天然是一棵树(目录、章节、引用),树擅长表达「包含」,不擅长表达「依赖」「影响」「归属」。而长期项目里最要命的知识恰恰是后者。

3. 文字创作会把这个问题放大

软件项目的问题,在复杂文字创作里会更加明显,因为文字的依赖是语义级的。

设想一部武侠小说里的配角 A,最初的人设是「玉树临风,擅长飞刀」。小说写到第 50 章时有这么一句:

小 A 从隐蔽处摸出武器朝主角丢去。

这句话里没有出现「飞刀」两个字。之后作者修改角色设定:小 A 不再玉树临风,而是一个莽夫,使用双锤。

第 50 章那句话,现在成了一处潜在冲突——但没有任何机制能发现它。如果整个小说只是几十个 Markdown 文档,AI 无从知道「改角色设定」和「第 50 章第 37 句」之间有什么关系。

更麻烦的是,这种影响往往不是一步直达的:角色设定影响行为,行为影响事件,事件影响对话,对话又影响其他角色的关系。改动在语义网络上传播,而文档树里没有这个网络。这已经不是文档同步问题,而是关系传播问题

4. 游戏开发会进一步放大它

游戏比纯文字创作再多一层:一个角色同时活在好几张生产网里。

以序章(demo 已发布的第 0 章)的主角陆择为例:轻浮、无根、自我感觉良好的海王,一个雨天的路口把他的日常拦腰截断。就这一个角色,在项目里同时存在:

  • 叙事层的陆择:序章三节的事件、与顾盈、小夏(咖啡店店员)、伊芙的关联;
  • 视觉层的陆择:外貌设定、着装方案(日常的商务休闲、灵魂形态的云雾蔽体)、三视图设计稿、每套着装的立绘设计、每句台词对应的表情立绘;
  • 声音层的陆择:语言风格(海王式的轻佻措辞)、基线音色设计、全部台词的逐句配音;
  • 剧情层的陆择:出现在剧本的每一行里,每行又挂着立绘引用和音频引用。

现在改一个设定试试:给外貌换个发型方向。叙事层几乎无感;视觉层的三视图、每套立绘设计、全部立绘变体都要重画;声音层不受影响;但已生成的每一句台词配的画面可能变了。谁能把这个影响面列全?靠人脑记,靠文档互相引用,都不可靠。

一个地点也同样如此:马路路口不只是「一个地点」——序章里它出场时是骤雨状态,有自己的背景图、环境音与背景音乐;换一段晴天剧情,就需要另一个状态的一整套画面。

所以游戏项目从来不是一组独立文档,它是一张不断变化的关系网络

5. 文档与图的职责分工

走到这里,结论已经浮现,但要说得精确一点,因为它容易被误读为「用图替换文档」——不是。

我们的分工是:

  • 文档描述内容:角色的详细设定、提示词的措辞、剧本的正文、音乐的描述——这些是「世界长什么样」的信息,自然语言最合适,人也直接读改它们。
  • 图描述关系:谁参与哪个事件、哪张图从哪张图派生、哪句台词用哪个立绘、改了什么会导致什么作废——这些是「什么东西和什么东西有关」的信息,图数据库中的节点和边最合适。

还有一个同样重要的原则,管住了「图会不会变得臃肿」的担忧:

  • 文件系统存产物,图存真相。 生成的图片、音频、剧本正文,全部作为普通文件按流水线阶段归档;图上的节点不塞二进制、不存长文本,只存指向产物的路径生产状态。图回答「有什么、关系是什么、做到哪了」,文件回答「打开看看」。
flowchart LR subgraph V["氛围编程"] A1[想法] --> A2[提示词] --> A3[代码] --> A4[运行] --> A5[反馈] --> A2 end subgraph S["规格编程"] B1[需求] --> B2[规格说明] --> B3[设计] --> B4[实现] end subgraph K["知识图谱"] C1[叙事图<br>世界实体与关系] --- C2[生产图<br>产物链与状态] C2 --- C3[级联<br>变更影响传播] end V ==>|项目变大| S ==>|关系不可见| K

三个阶段的演进逻辑:Vibe Coding 输在「理解不可持续」,Spec Coding 输在「关系不可见」,知识图谱补上的是最后一块。
事实上,现在也有项目使用图数据库来管理代码中各个类、各个方法之间的继承、调用关系。我还未尝试,但是效果应该不错。

6. 双层建模:叙事图 + 生产图

落到工程上,整个项目的图分成两层。这个切分是全系列最重要的一个设计决定。

叙事基础层:世界本身

游戏世界首先由五种实体构成:

节点 含义
Character 有名字的人物
Event 某时某刻发生的某件事
Location 具体地点
Info 一条有意义的认知碎片(可以分层:玩家知道多少、谁知道多少)
Choice 一个关键选择点

核心关系(部分):

从 → 到 含义
relation Character → Character 人物关系
involved Character → Event 人物参与事件
occurred_at Event → Location 事件发生地点
at Character → Location 人物与地点的关联
link 实体 → Info 实体关联信息
evt_relation Event → Event 事件因果 / 时序
presents / option Event → Choice → Event 事件触发选择、选项导向后续事件
graph LR CH[角色] --> EV[事件] CH --> CH CH --> LO[地点] EV --> LO EV --> IN[信息] EV --> CO[选择] CO --> EV EV --> EV

拿序章的真实剧情填充一下这五种节点:Event 是「雨天路口,陆择死于车祸」;Character 是陆择、顾盈、小夏与伊芙;Location 是酒店客房、咖啡店、马路路口与灵魂夹缝;Info 是一条条认知碎片——比如伊芙交付的试炼规则本身(六个试炼、每个约三十天)。Choice 是玩家的干预点——序章还没得到体现。

值得强调的是 Choice 是一等公民实体,不是剧本里的一行语法糖。这是GalGame玩法决定的:玩家只能在选择点干预,意味着「选择」就是这个游戏的核心机制对象,它要能挂自己的属性、能被事件触发、能通向别的事件。把它建成实体之后,「这个选择通向哪些结局」「两条分支各自牵动哪些事件」就成了可查询的结构,而不是散落在剧本各处的文字。

生产层:世界如何变成素材

在生产层,每个节点代表一个产物:外貌设定、着装方案、三视图、立绘设计、单张立绘、音色设计、章节提纲、剧本定稿、单句台词的配音……产物之间用「派生」关系连成链,例如角色美术链:

Character → AppearanceStyle(外貌)→ DesignSheet(三视图)→ IllusDesign(着装立绘设计)→ StandingIllustration(单张立绘)
Character → CostumeStyle(着装)→ IllusDesign

每一个生产节点都带 status、每一条派生边都带 sync。这两样东西,就是下一节和下下节的主角。

双层合起来回答了两个不同的问题:叙事图回答「世界是什么」,生产图回答「世界被做到哪了」。AI 生成任何内容之前,先查图;生成之后,写回图。图数据库是整个项目唯一的读写入口——所有 skill、所有工具、人工管理后台,都对着同一个图操作,没有任何一条旁路。

7. status:把进度变成机器可调度的事实

有了生产节点,马上面临的问题:AI 怎么知道哪些事要做、哪些事做完了?

最直觉的答案是「看产物文件存不存在」。我们试过,这条路是死的:文件存在不代表合格,更不代表最新——它可能是被上游变更连坐作废的旧版本。调度判据必须是图上的 status,而不是文件系统

status 速查:-1 作废重做(级联重置后,必须重新生成并覆盖旧产物)/ 0 待处理 / 1 已完成 / 2 图片完成 / 10 待审 / 11 批准(解锁下游)。

status 的六个值在上面速查表里。它看起来平淡,但两个语义细节决定了调度系统的成败:

第一,-1 与 0 都是「需要做」,但含义不同。 0 是从没做过;-1 是做过后被作废、必须覆盖旧产物重做。对调度器来说二者都要捡起来,对执行器来说 -1 意味着「不许因为文件已存在而跳过,不许读旧 prompt 旧图」。这个值救了整个系统:级联作废(下一节)之后,哪些东西要重做一目了然。

第二,数值分段是有意的。 生产态 0/1/2 与审批态 10/11 在数值上隔开,status >= 10 一眼就是「进入人工审批轨道」,代码和人都不容易混淆。

stateDiagram-v2 [*] --> 待处理: 节点创建 待处理 --> 已完成: 数据类节点写入 待处理 --> 图片完成: 生产类节点出图 已完成 --> 待审: 生产完成直写 图片完成 --> 待审 待审 --> 批准: 人工审批通过 待审 --> 待处理: 人工驳回 批准 --> 待处理: 已批准节点被编辑 待处理 --> 作废重做: 级联重置 图片完成 --> 作废重做: 级联重置 待审 --> 作废重做: 级联重置 批准 --> 作废重做: 级联重置 作废重做 --> 图片完成: 重新生成并覆盖

注意「批准」并不是终点:一旦有人编辑了一个已批准的节点,它自己回到待处理,并触发级联。状态机守护的是「一致性」,不是「完成」。

8. sync 级联:让变更的影响自动传播

现在回到第 2 节那堵墙:上游变了,下游谁知道?

图数据库里这个问题有一个近乎天然的解法:给每条边加一个 sync 布尔属性。上游节点属性变更后,沿 sync 为true的出边做广度优先遍历,把所有可达的下游节点 status 重置为 -1(作废重做);sync 为false的边天然阻断传播。

拿陆择走一遍:外貌设定上一处修改 → 级联沿 produces 边到三视图(重画)→ 再到着装立绘设计(商务休闲、云雾蔽体每套全部重做)→ 再到表情立绘(全部变体重画)。一次 BFS,整条视觉链精确作废,而陆择的 Event、关系、剧本台词毫发无损——因为叙事边不带 sync。

反过来,sync 为false也有明确语义:世界事实不因产物作废而消失。Event 与 CostumeStyle 之间的 wears 边(「这个事件里角色穿这身衣服」)是叙事判断,不参与级联——三视图作废重做不影响「陆择在夹缝以哪套服装示人」这个叙事事实。类似的还有场景对背景音乐的关系:换一张背景图,不该作废音乐。

flowchart TD UP[上游节点属性变更] --> BFS{沿出边 BFS} BFS -->|sync=true| D1[下游一层: 重置 -1] D1 --> D2[下游二层: 重置 -1] D2 --> D3[下游 N 层: 重置 -1] BFS -.->|sync=false 阻断| SAFE[无关下游不受影响]

至此,Spec Coding 的三堵墙都有了对应解:前驱失同步 → 级联自动作废下游;Token 与准确率 → AI 只查局部子图不重读全库;关系不可见 → 关系本身就是数据。

9. 验收闭环:诚实地讲,人工审批才是现实

原始概念稿里,我们对验收的想象非常自动化:图像识别检查发色发型服装、音频分析检查频率削波、规则引擎检查剧情一致性。落地之后,这个想象被大幅修正了。

现实是:自动验收基本没有实现,也暂时不值得实现。

目前真正的自动校验只有点状的几处——章 JSON 的 schema 校验、发布期字体子集的关键标点断言这类「机器有唯一正确答案」的检查。其余所有验收,走的是同一条人工闭环:

AI 生产完成 → status=10(待审)→ 人工在管理后台审批 → 11(批准)→ 下游解锁
                                    ↘ 驳回 → -1(重做)

这不是妥协,是清醒的取舍。立绘的「气质对不对」、音色的「听感像不像这个人」、台词的「这个角色会不会说这种话」——这些判断今天仍然只有人做得又快又准。硬上自动评分,得到的不是验收,是把不可靠的判断洗成看起来可靠的数字。

于是系统里所有的「验收」收敛为一个动作:10 待审,人工过目,11 批准。管理后台的审批中心为此而建:立绘看图、音色设计逐候选试听、剧本定稿读全文、逐句配音按节聚合试听。人工成本被这个体系控制在一个可接受的节奏上——因为 AI 生成便宜、返工便宜,人工只花在「判断」这个最贵的动作上。

自动验收没有被放弃,只是被放到了正确的位置:机器验收「有没有做错」,人验收「够不够好」。前者在系统成熟后逐步补(第 6 篇会回来清算这笔账),后者不外包。

10. 一份 Schema,两端消费

最后一块地基:这张图的结构本身,定义在哪里?

答案是五份 Markdown 文档(叙事基础、角色美术、场景美术、剧情、声音五个模块),每份用表格定义该模块的节点、属性、边、方向、基数、sync 缺省值。它们是唯一事实来源:AI 每次写图操作之前必须先读对应模块,按其中的英文标签与属性名生成语句;管理后台启动时解析同一批表格,直接驱动出节点编辑表单——改一处 Schema,AI 的行为和人工后台的界面同时生效

有一个反直觉的细节:status 的合法值与流转规则,刻意放在这些 .md 里,而是在后台代码中显式定义。原因朴素——.md 是给人读的散文,格式会漂;状态机是给机器执行的,必须长在代码里。Schema 文档定义「图长什么样」(结构),代码定义「状态怎么走」(行为),两者的可靠性等级不同。

这个「表格驱动」的架构还有个意外的红利:新增一种节点类型几乎零成本——在 Schema 里加一张表、在状态机里补一条规则,AI 和后台就都认识了它。反过来,它也把「图结构变更」变成了一个显式的、可评审的动作:想加一种节点,先改 Schema 文档——这份文档本身就是变更提案,人看一眼表格就知道这次变更会影响哪些边、哪些界面。第 5 篇会看到剧情链在项目中期大幅重构,Schema 驱动的架构让那次重构没有变成一次全系统的改造。

posted @ 2026-09-01 23:26  CrazyJinn  阅读(12)  评论(0)    收藏  举报