353 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 生成引擎 · 设计主文档
> 🚧 **架构演进中** —— 本子树描述的生成架构正处于 gameDefinition→`src/` 终态迁移 + 产线化(plan `2026-06-18-001` U1U4)中;文中标注的现行结论可能随 plan 推进变化。
> **这是什么**:绘境AI 生成引擎子树的设计主文档,回答"**一句话怎么变成一款可上线的游戏**"这条技术主线——它的现行架构、要往哪走的演进路线,以及贯穿全程的一条范式原则。
> **给谁看**:负责生成主线的工程师、新加入这条线的同事、架构评审、做尽调时想看清护城河关键路径的人。
> **怎么读**:先读 §1 建立"这台机器是什么"的整体认知,再看 §2 那张端到端流程图;想了解当前债与未来路线读 §4§6;想要更深的子系统细节,从文末的源档导航进去。
生成引擎是绘境AI 护城河的关键路径。竞品大多止步于"能生成";真正难的是让一个普通模型**稳定地、可维护地、可长期演进地**把一句话变成一款真游戏。这份文档讲的就是这条路怎么走通。
---
## 1. 一句话与一张图:生成引擎是什么
绘境AI 的游戏生成主线,本质上是一台**被刻意设计成可靠的、固定相位的生成机器**。它不是一个让强模型自由发挥的开放式编码助手,而是一条流水线:**用便宜的通用模型驱动、用确定性的图编排约束控制流、用一套自动验收门兜底**。
这台机器有三个互相支撑的设计支点,理解了它们就理解了整条线为什么这么搭:
- **便宜模型 + 门兜底,而不是训一个专用大模型。** 模型这一层硬编码了 11 个角色 → 模型的赋值(以便宜的 deepseek-v4-flash 打底,救场位升 deepseek-v4-pro 强档,视觉 / 分类 / 回退位用 MiniMax-M3),没有任何一个是为游戏代码专门训练过的通用模型。质量缺口不靠把模型做重来补,而靠模板约束和验收门来补。这是成本策略,也是差异化判断——大模型迟早会追上,真正的护城河不在生成引擎本身。
- **图编排约束控制流,而不是让模型自由决定下一步。** 整条线的骨架是 **SAA 裸 StateGraph**(SAA = Spring AI Alibaba,阿里的 Spring 生态 AI 编排框架;"裸 StateGraph"指直接用它的有向状态图原语手写编排,而不是用声明式 YAML 配置)。一共 16 个节点,每个节点是一段实打实的 Java 代码,节点之间的流转由图预先固定,而非由模型在运行时临场决定"下一步调什么工具"。
- **一套硬验收门当地板。** 这就是俗称的"**九门 harness**"(harness 指把生成产物放进一个真实运行环境去自动检验的测试夹具;"九门"是其中九道确定性检查):能不能装载、跑不跑帧、响不响应输入、到不到游戏终态……全部是确定性的判定。这一层是这套架构最大的工程价值,也是绝不动它的底座。
把这三点合起来,可以用一句话概括整台机器的定位:**LLM 在这里扮演的是"游戏工作室"的角色**——它替代的是一个真实游戏工作室原本要做的策划、写码、配资产的活,而不是充当一个一次性出活的黑盒。这个"LLM as 工作室"的定位是整条线的灵魂,§3 会专门展开。
这台机器当前的真实状态需要诚实说清:**结构正确、控制流确定、底层验收很硬的流水线已经建成并合入主干;但生成质量尚未稳定达到 80% 这道门,而且一部分本该可替换的"策略"被焊死进了不该重编译的"机制"代码里。** 换句话说,骨架立住了,接下来要解决的是"质量"和"策略外置"两件事——这正是 §4§6 演进路线要回答的。
还要钉死一条比技术债更根本的**范式定性**(出处:同目录[设计合理性裁决](设计合理性裁决.md),2026-06-20 对抗审查,status 待创始人拍板):这套"便宜模型 + 受限 schema + 九门验收"是一条**为超休闲轻游戏(Tier0:打砖块 / 合成 / 挂机 / 答题 / 网格点选)量身打造的可靠产线,而不是一个通用生成范式**。它最大的风险不在工程层,而在被当成通用范式去对标 demo 里的 **Marvel 平台动作 / KOF 格斗**那一档富交互游戏——那一档这套范式**结构性地够不着**(运行时没有承载那层复杂度的形状),不是补个分支能解决的,必须显式把愿景分层、复杂品类另开一轨。下文 §3/§5 把这台机器框成"护城河的关键路径""值钱的东西我们还没有",成立的前提正是把它锚在 Tier0 这档;读时务必带着这条天花板,别把它读成"再补几层就能通吃所有品类"。
---
## 2. 一张端到端流程图:一句话怎么变成一款游戏
下面这张图是整条生成主线的全貌。16 个节点不是抽象概念,而是图里真实存在的执行单元。读图时抓住三段就好:**先理解题面(render→classify→design)→ 再造出东西(generate→scaffold→asset→build)→ 最后反复验收直到合格或放弃(play/player/nreview→modify/repair/escalate→emit/giveup)**。
```mermaid
flowchart TB
Brief["一句话 / 选模板 + 素材"] --> Render["render<br/>渲染请求与上下文"]
Render --> Classify["classify<br/>判定游戏品类"]
Classify --> Design["design<br/>产出设计文档 GDD"]
Design --> Generate["generate<br/>便宜模型生成玩法逻辑"]
Generate --> Scaffold["scaffold<br/>脚手架出源项目结构"]
Scaffold --> Asset["asset<br/>生成 / 装配资产"]
Asset --> Build["build<br/>确定性构建出可玩产物"]
Build --> Play["play + player<br/>真机运行 + 视觉软门看截图"]
Play --> NReview["nreview<br/>九门 harness 机制验收"]
NReview -->|过门| Emit["emit<br/>发布产物 + 落库"]
NReview -->|可修| Modify["modify / repair<br/>定位并修复"]
NReview -->|升档| Escalate["escalate<br/>换更强模型重试"]
NReview -->|彻底失败| Giveup["giveup<br/>显式放弃 + 留证据"]
Modify --> Generate
Repair["repair"] --> Generate
Escalate --> Generate
Validate["validate<br/>校验中间产物"] -.横切.- Generate
style NReview fill:#f9e79f
style Emit fill:#a9dfbf
style Giveup fill:#f5b7b1
```
这张图里有几个名词第一次出现,先解释清楚:
- **GDD(Game Design Document,游戏设计文档)**:design 节点的产物。它把"做个游戏"这件开放的事,结构化成一张每一节都硬绑下游工具入参或代码文件的待办清单——资产表喂给资产工具、布局喂给贴图工具、数值合并进配置。它是约束便宜模型不跑飞的核心抓手。
- **品类(archetype)**:游戏的玩法类型(如平台跳跃、俯视射击、逻辑解谜)。classify 节点先把题面归到某个品类,后续的设计与生成都围绕这个品类的框架展开。
- **escalate(升档)**:当前模型反复失败时,图层会切换到一个更强的模型重试。这是图层显式的"加钱保质量"机制。
- **emit / giveup(发布 / 放弃)**:两个终态。emit 是成功出口——产物落库并进入发布链;giveup 是失败出口——**显式放弃并留下证据**,绝不交付一款坏游戏。"宁可显式失败,也不交付坏游戏"是这条线的铁律。
整条流程最关键的特征是**它是一个带回环的有向图,不是一条直线**:验收不过时,nreview 会把控制权交回 modify(确定性修复)、repair(基于经验的修复)或 escalate(升档重试),修完再重新走 generate→build→验收。这个回环是质量的来源,但也正是后面要小心治理的地方——出题的和被考的不能是同一只模型(§4 会讲)。
---
## 3. 范式原则:游戏是长生命周期的源项目,LLM 是它的工作室
在讲债和路线之前,必须先钉死一条**比任何技术债都更根本的范式原则**,因为它决定了这条生成主线"什么才算做对了"。这条原则由创始人在 2026-06-17 裁定、2026-06-20 进一步拍板,是整个生成引擎子树的定调。
### 3.1 范式转变:从"一次性产物"到"长生命周期项目"
过去的做法(称为"旧范式")是:生成 = 产出一坨能玩的打包文件存下来;想修改时就去 diff 这个打包产物——而这条路根本走不通。新范式把这个死结从根上解开了:
| 旧范式(一次性反模式) | 新范式(长生命周期项目) |
|---|---|
| 生成 = 产出一坨可玩的打包文件,存下来 | 生成 = LLM(工作室)**创建并长期维护一个游戏源项目** |
| 修改 = 想办法 diff 打包产物(不可行) | 修改 = 工作室在**源项目**上做一次开发迭代,再构建 |
| 产物 = 一次性、不可维护的硬编码代码块 | 规范物 = **结构化、可维护、数据驱动的源项目**(像工作室的代码仓) |
| 打包 / 发布是终点 | 打包 = 一个构建步、发布 = 一次版本发布;项目**持续演进** |
一句话:**把游戏建模成长生命周期的软件项目,LLM 是它的工作室;create / modify / extend / build / release / maintain 都是项目生命周期操作。** 这从根上化解了"怎么改打包产物"的死结——**不碰产物,在源项目上演进,再重新构建**。这里的"打包产物"和"源项目"是两个必须分清的东西:打包产物是给玩家跑的最终包,源项目是工作室回头要改的那份真实代码。
为什么源项目必须结构化、模块化、数据驱动?**因为工作室(LLM)将来要回来改它。** 一份长这样的源项目结构,正是为"可被 agent 快速定位、局部修改、增量扩展"而设计的:
```
game-project/
├── game.json # 项目元数据(引擎版本 / 入口 / 品类 / 标题 / 版本)
├── design.md # GDD:玩法意图 / 机制 / 胜负条件(工作室的"需求与设计")
├── config/
│ ├── params.json # 平衡参数(数值 / 难度 / 速度)——改这里 = 调平衡,免 LLM
│ └── levels/ # 关卡数据——加一个文件 = 加一关
├── src/ # 模块化游戏逻辑(按系统拆:input / spawn / score / physics…)
├── assets/ # 六类资产:sprite / character / effect / scene / ui / music(引用,非内联)
└── build.json # 构建配置
```
这样一来,生命周期里的每种操作都各得其所:**create** 是脚手架出这个项目;**modify** 时,换美术 / 调参 / 改关卡是确定性地编辑源文件(免 LLM、秒级),只有改玩法逻辑才让 LLM 重新生成那一个模块;**extend** 是加文件(additive,即只增不改);**build** 是确定性地把源项目构建成可玩产物;**release** 是把构建产物发布为一个版本、过审进入游戏信息流;**maintain** 是据玩家遥测和反馈,工作室回到项目继续演进——这一步把数据闭环接回了护城河。
### 3.2 终态硬约束:产物必须是 src/ 工程,gameDefinition 只是脚手架
创始人在 2026-06-20 拍下一条**不可妥协的终态定调**,它直接决定了生成产物"合不合格":
> **生成游戏的终态产物,必须是一个 `src/` 多文件代码工程——结构化、模块化、可导航、agent 能快速定位与探索的真实源码项目。无论游戏简单还是复杂,最终落地的都必须是 src/ 工程。**
由此必须诚实纠正一处此前的认知偏差。当前实现里有一个叫 **gameDefinition** 的 JSON 中间表示——它把整段玩法逻辑塞进 `behavior.code` 这个 JSON 字符串字段,运行时用 `new Function`(JavaScript 里把字符串当代码执行的机制)直接解释执行。这恰恰是设计明令反对的"硬编码代码块":改一行要在字符串里找、agent 无法结构化定位。所以两者的关系在此一次性钉死:
- **终态产物 = src/ 工程**(不可妥协);
- **gameDefinition = 通往 src/ 的中间妥协态**——妥协只允许在"输入端"(让便宜模型先产一个极简的声明式描述,因为便宜模型确实更擅长产这种结构),**绝不允许妥协在"产物端"**;它必须经过一道真实的"gameDefinition 编译 / 展开成 src/ 工程"的构建,而不是停在 JSON 里被 `new Function` 跑掉;
- **当前实现(JSON 内嵌 JS 串 + `new Function` 解释执行)= 已知偏离终态的债**,缺的正是"gameDefinition → src/"产物侧这一段展开。更尖锐的一处名实不符:**承载 100% 玩法逻辑的 `behavior.code` 这个自由 JS 串,根本没进任何契约**——它是靠 schema 的 `additionalProperties` 偷渡进 gameDefinition 的,所以"声明式结构化源"这个名号只覆盖了外壳的数据字段,逻辑核仍是一坨未受契约约束的自由 JS(这正是上面那条机制门要堵的口子)。
需要把"双证地基成立"这件事说准:它证明的是一件真实但有限的事——**便宜模型能可靠地产出连贯的 gameDefinition 中间表示**;它没有、也不能证明"gameDefinition 就是合格的终态产物"。
这条定调过去"写了却传不到实现",所以它必须配一道**机制门(doc↔code 兑现门)**:生成产物要能被自动断言为"存在 src/ 多文件结构、玩法逻辑落在真实源码文件里、不存在'逻辑只以 JSON 字符串形态存在 / 运行时 new Function 跑内嵌串'"。设计声称要 src/,代码就必须可验证地兑现 src/——否则"产物必须是 src/"这条就只是又一条等人自觉的软约束。
### 3.3 六维质量 → 生成产出的硬契约
这条范式原则不是口号,它落到生成产出上是六条可检验的硬约束(对应下表六行,其中"长期 / 可维护"是同一维的两面)。它们共同回答了一个被早期方案忽略的根本问题:**生成质量的真标尺不是"这次能不能玩",而是"工作室将来能不能维护它"。**
| 质量 | 落到生成产出的硬约束 |
|---|---|
| 长期 / 可维护 | 模块化代码 + GDD;工作室能回来定位并改 |
| 可扩展 | additive 内容模型(加关卡 / 资产 / 模块不重写) |
| 灵活 | **数据驱动**(行为走 config / data,不硬编码) |
| 稳定 | 确定性构建 + 版本化发布 + 回滚 + 构建门(九门 / 质量门) |
| 简单 | 轻游戏轻结构,不过度工程(够维护即可) |
| 高效 | 增量改 + 增量构建;确定性操作免 LLM;复用模块 / 资产 |
---
## 4. 现状诊断:我们的债在哪里
把这台机器拆开看,真正的病根不是"没建成",而是**机制已通、生成质量未达门,且策略下沉进机制层造成了多源漂移**。债集中在三类。
**第一类是策略下沉进机制层。** 本该作为可替换数据的策略,被焊死进了不该重编译重部署的代码里,造成三处倒置:
- **模型路由**:11 个角色的模型名(便宜打底 + 强档 + 视觉 / 回退位)和每个角色的采样配置,全是 Java 常量,换一个模型要改代码、重新构建。
- **prompt 正文**:gameDefinition 的生成约定(系统提示、运行时写法约定、命名对齐)是 Java 字面量,而另一侧的 Python worker(worker 指实际跑生成的独立工作进程)又镜像了一份。同一份约定存在两个源,这是一个潜在的 **split-brain**(直译"裂脑",指同一份事实存在两个独立副本、迟早会不一致的隐患)。当前 worker 走的还是纯 iife 路(iife 即立即执行函数,指把游戏打成一个单文件代码块的老路),这条裂缝尚未真正激活;但只要后续切换依赖 worker 线的数据,它就会立刻变成承重的坑。
- **品类骨架**:由 design 节点自己产出,没有外部锚点。
这三处倒置的共同后果是:凡涉及跨 Python 与 SAA 双轨的策略,一旦"策略化"做得不干净,就会从"一处硬编码"恶化成"多处不同步",拆东补西。
**第二类是验收 oracle 的 Goodhart 风险——九门是机制地板,不是质量裁判。**(oracle 在测试语境里指"判定对错的权威";Goodhart 风险指"一旦一个指标变成目标,它就不再是好指标"——刷指标而非真达标。)九门 harness 判的是**机制**:能不能装载、跑不跑帧、响不响应输入、到不到终态,全是确定性的,这一层我们确定性地领先,零理由动它。但它有两个真实口子:
- **latch 终态语义不分胜负**:latch 指"游戏到达了某个终态"的锁存信号。当前它由系统强加(永远期望为真),哪怕游戏弃守排空也能逼出一个游戏结束信号——这意味着一个空壳游戏可以蹭过这道门,而 latch 正是"机制有进展"那一门的承重件。它对"这到底是不是题面要的那个游戏"几乎零鉴别力。
- **出题与被考同源**:classify 自产品类、design 自产验收规格,而便宜模型的核心毛病恰恰是连 `ball.x``driver:none` 这种最基本的东西都会反复写错。让同一只待验模型既出题又答题,验收闭环就有一格没真正断开。
**第三类是 factory 与 gamedef 双轨未切换。** 我们有两条生成产线并存:
- 老的 **factory 路**(填参装配,当前默认产线,但实测成功率约 **60%**,低于 80% 门);
- 新的 **gamedef 路**(便宜模型友好的结构化中间表示,已双证"能被可靠产出",但产物侧"展开成 src/ 工程"那段尚缺,且尚未切为默认——见 §3.2)。
双轨并存本身是健康的演进态——新路没稳前不该贸然切换——但如果不立一道硬退役门,演进态就会沉淀成永久债。与之伴生还有一个成本侧盲区:generate 节点内部有一条回退链会静默切模型,但它不计入失败计数、也不进升档事件,与图层的 escalate 升档是两套互不相通的机制;这导致"一次失败到底走了几层模型"算不清,而切换的成本归因恰恰依赖这个数。
> **一处已被实证反掉的误判,记在这里免得重复建设**:源项目持久层不是悬空的。`game_source_project` 的持久层真实存在(V18 建表 + V20 加并发幂等唯一键 `uk_game_source_hash`,这两个是两道不同的迁移而非同一迁移的两份拷贝),落库与标记构建完成的调用在回调实现里被真正调用(事务外层、按内容哈希幂等)。所以它已经是一等公民,真实缺口只是血缘丰富度和 gamedef 路的端到端验证——这是 P2,不是要去补一条根本不存在的落库链。
---
## 5. 对标 OpenGame:我们缺哪几层
把当前最强的外部开源系统 **OpenGame**(一个把一句话变成游戏的开源生成系统,源码在 `github.com/leigest519/OpenGame`)看透之后,落到我们的现状上,真正的差距集中在三层。它们与 §4 的内部债不重叠——内部债是"已有的东西没做对",这三层是"值钱的东西我们还没有"。
在展开之前,要先讲清一个决定取舍边界的判断:**OpenGame 是命令式自主循环**(在一个 `while(true)` 里,模型自由决定下一步调什么工具,控制流由模型驱动),**我们是声明式有向图编排**(节点、边、条件预先固定,控制流由图驱动)。这是两种正交的范式。所以我们**不把 OpenGame 的主循环嫁接进来**——硬塞就成了项目明令反对的"缝合设计",而且对卡 80% 成功率门这件事,图的确定性本就比"DO NOT STOP"那种口头督促更稳。我们要抄的,是 OpenGame 的工具层、韧性兜底、防脏脚手架与经验复利机制,把它们当零件库,原样落进 SAA 节点内部;我们不抄它"模型自由驱动主循环"那套范式。
```mermaid
flowchart LR
subgraph 我方["绘境AI 生成引擎"]
G["声明式有向图编排<br/>16 节点 SAA StateGraph"]
N["九门 harness<br/>机制验收(领先)"]
end
subgraph 缺口["OpenGame 证明值钱、我们要补的三层"]
L1["① GDD 契约 + template_api<br/>把开放题收敛成填空题"]
L2["② 经验复利层<br/>Debug Skill + Template Skill"]
L3["③ 资产线 + 语义验收<br/>asset 接 mmx + player 软门做厚"]
end
G -. 当零件库落进节点内部 .-> 缺口
```
**第一层缺的是生成约束的厚度——最高价值缺口。** OpenGame 端到端能跑通的根本前提,是它有一套预建模板,外加每个品类一份 hook 清单当"填空靶子"(hook 指模板预留给生成代码挂接的接口点)。它的生成质量不来自强模型自由发挥,而来自**把开放问题收敛成填空题**:一份 GDD 把"做个游戏"结构化成每一节都硬绑下游工具或代码文件的待办清单。约束便宜模型不跑飞的是三条铁律:**数值只能进配置、只用模板已有行为、绝不许编造清单里没有的 hook**。而第三条铁律之所以**能**约束住便宜模型,正是因为有一份明确的 API 清单让它无从编造。
我们这一侧,classify 和 design 节点存在,但品类体系、物理优先的分类提示、GDD 的契约化程度,以及最关键的那份"**LittleJS 增强发行版 + 插件库公开 API 清单**"当我们的填空靶子——都还没补齐。(LittleJS 是我们选定的轻量 H5 游戏引擎,"增强发行版"指我们在它之上加了一层能力插件库。)没有这份清单,便宜模型一定会编造 API。这一层 OpenGame 抄不来、必须我们自建,而它恰好和"游戏 = 长生命周期结构化源项目"基座、"玩法模板 = 品类框架"的定位是同一个东西。
**第二层缺的是经验复利层,我们几乎从零。** OpenGame 真正的护城河是两套同构的离线经验自进化机制,都遵循同一个闭环:完成任务 → 抽取经验 → 去具体化 → 沉淀回本地 JSON 库 → 下次先查库命中复用 → 重复达阈值再升格成可执行规则——**纯本地、零向量、零 embedding,本质是基于案例的推理而非检索增强**:
- **Debug Skill(调试技能)** 是一本活协议:数据结构是(错误签名、原因、修复)三元组,签名匹配是纯算法零 LLM,只在"诊断新错"和"归纳新规则"两处兜底调 LLM。最实的一环是——同一个修复在重复出现三次后,会自动升格成"执行前的预校验规则",经验从"救火"升级成"免疫";而且只有跑通验证的修复才进库。
- **Template Skill(模板技能)** 从一个与具体游戏无关的元模板出发,每完成一个项目跑一条流水线,把具体代码泛化成带 KEEP / copy / hook 分层的模板,以"物理三元组 + 品类名"为匹配键复用整个家族。
我们规划过 Debug Skill 但 MVP 做了简化,Template Skill 那种"从完成的游戏项目反向生长品类骨架库"的能力则完全没有。它对便宜模型尤其划算——每一次签名命中都省一次 LLM 调用,把高频错变成确定性查表。
**第三层缺的是资产线,以及偏弱的语义验收。** 资产这块,OpenGame 走的是一整套"生成、抠图、视频抽帧、多级回退、清单装配"的重流水线,依赖视频模型 + ffmpeg + 抠图后端——便宜的文生图模型替不了动画质量,这是真壁垒。我们不照抄这套依赖,而是让 asset 节点接已拍板的 **mmx-cli**(王蓝莓投资人版定的媒体生成工具),大幅降级的部分(静态帧 + 程序音)照它的多级回退思路兜底即可。
语义验收这块要说准一个事实:**OpenGame 论文最响的"三轴 VLM 验收"在开源代码里其实并不存在。**(VLM = Vision-Language Model 视觉语言模型,指能看图打分的模型。)它的 README 描述得很全(用无头浏览器跑生成的游戏,VLM 沿 Build Health 构建健康、Visual Usability 视觉可用、Intent Alignment 意图对齐三轴打分),但全仓搜不到任何渲染真实像素、真实浏览器或 VLM 打分的代码,只留一句"will be released soon",真实验收只到构建 + 测试。所以**单比已开源的东西,我们的真机九门已经更硬**。
但这里要分清两层、别就此自满:九门判的是机制(对应 Build Health 那一轴),我们确定性领先;可另外两轴——好不好看、是不是用户要的那个游戏——九门根本判不了,它们在我们这边对应的是 **player 软门**(用视觉模型看截图打分的软性检查),而 player 软门是软的、跑便宜模型、不成体系,这恰恰是我们的弱项。所以正确动作不是"把九门结果套个三轴外壳就交差",而是**把 player 软门那条做厚**——OpenGame 论文那套三轴设计,正是这一层值得我们抄的蓝本,哪怕它代码并没放出来。
---
## 6. 统一演进路线
把内部债和外部缺口合起来,演进沿**两条并行的线**推进:**线 A 向内加固现有架构**(把硬编码的策略抽成数据契约、把跨进程对齐点锁成单一事实源、把验收信号补上独立的判定依据);**线 B 向外补齐 OpenGame 证明值钱的能力层**。
贯穿两条线的总原则有三条,它们是后面所有具体动作的护栏:
1. **不重写任何主干。** 裸图躯干、九门、源项目持久化都留着,改的只是策略层外置与验收门加固,而且全部是 additive(只增不改)加 fallback(失败回落)。
2. **所有新增的质量门默认只观测不收紧。** 当前是刻意宽门放量在攒数据(开闸两门焊死放行、三门只观测),任何新门若一上来就生效,会立刻掐断这条灰度闭环。所以新门一律默认关闭、只记录轨迹,达标率稳定后再一行翻开。
3. **凡涉及跨 Python 与 SAA 双轨的策略外置,数据契约必须是语言无关的 JSON / YAML、两轨都读它、CI 卡一致性(parity)**——否则"策略化"就沦为"跨语言漂移",把一处硬编码换成多处不同步。
两条线不是各跑各的:它们在两个点上解的是同一个问题,**必须合并成一处实现,不能各列一遍**;最后由一道里程碑门(cutover)收口。下面这张图先把这层关系摆清楚,再分小节展开:
```mermaid
flowchart TB
subgraph LA["线 A · 向内加固(把策略从机制里抽出来)"]
A1["trace 抽取 + 文件拆分<br/>(纯重构)"]
A2["★ prompt 同源<br/>解 split-brain"]
A3["模型外置 models.yaml"]
A4["latch 终态语义<br/>分胜利 / 弃守"]
end
subgraph LB["线 B · 向外补能力(抄 OpenGame 的零件)"]
B1["★ GDD 契约 + template_api<br/>(最高价值)"]
B2["Debug Skill<br/>diagnose / repair + checkpoint"]
B3["Template Skill<br/>按 gameDefinition 重写 + 九门门"]
B4["资产线接 mmx"]
end
subgraph X["两处交汇点(一件事,一处实现)"]
X1["交汇点一:品类独立交叉校验<br/>= 物理优先分类"]
X2["交汇点二:player 软门做厚<br/>= 验收去自评"]
end
CUT["★ cutover 里程碑门<br/>gamedef 成功率达 80% → 切默认产线<br/>二分退役 factory · 拦截门翻开"]
A4 --> X1
B1 --> X1
A4 --> X2
B1 --> X2
A2 --> CUT
X1 --> CUT
X2 --> CUT
style A2 fill:#fde68a
style B1 fill:#fde68a
style CUT fill:#fca5a5
```
关键路径(图中黄色 ★)是一条线:**prompt 同源(解 split-brain)→ 质量信号可信(两交汇点)→ cutover**;红色的 cutover 是最终里程碑门,只有 gamedef 路成功率真达 80% 才放行切换。下面三小节依次展开线 A、线 B、两处交汇点。
### 6.1 线 A:加固现有架构
| 事项 | 做什么 | 性质 |
|---|---|---|
| trace 抽取与文件拆分 | 把内联在近九百行调度器里的轨迹抽取逻辑(约 280 行)抽成独立纯函数 `SaaTraceExtractor` 补单测;把过载的 `SaaStudioNodes` 单文件(一千六百多行)按职责拆包。调度器从近九百行瘦到约六百行 | 纯重构、零行为变更 |
| **prompt 同源,解 split-brain** | 把 gameDefinition 的生成约定从 Java 字面量提为 `contracts/prompts` 下的版本化资产,让 Java 与 worker 都从这一份资产读、CI 卡到字节一致 | **线 A 关键路径起点** |
| 模型外置 | 把 11 个模型名 + 每角色采样配置外置为 `models.yaml`,加载逻辑从配置读、常量作 fallback | 契约先行 |
| latch 终态语义 | 区分胜利与弃守 / 超时——见交汇点(§6.3) | 线 A 唯一 P0 |
| **cutover(切换)** | 立硬退役门:gamedef 路成功率达 80% 后,切为默认产线、二分收敛退役 factory、把"失败即拦截"的门翻开、闭合 modify 的"从源真构建"。同期补成本侧盲区(给静默回退链加 `fallbackEvents` 进轨迹)、修诊断盲区(把全归一类的失败原因扩出子码,注意 DB 列宽 32 字符约束) | 线 A 收口里程碑 |
prompt 同源这一步一举两得:既根除了那处 P0 级 split-brain,又坐实了三段式缓存的前缀——前缀字节一致才能命中,实测命中率有 **76% 到 93%**。这里有一条硬纪律:**split-brain 未解之前,不得拿 worker 线的数据去做 cutover 决策。**
### 6.2 线 B:补齐能力层
线 B 的四件事全部源自 OpenGame,且全部落在 SAA 图内,不引入外部主循环:
- **GDD 契约 + template_api(最高价值项)。** 把物理优先分类的系统提示(含易错例)和品类体系做成 classify 节点;把 GDD"六节每节硬映射下游"的契约、三铁律做成 design 节点。但有一个范式级前提必须先立:**先得有那份"LittleJS 增强发行版 + 插件库公开 API 清单"当填空靶子**,否则 hook 完整性无从约束,便宜模型必然编造 API。
- **Debug Skill 落地为 diagnose / repair 节点 + checkpoint(检查点持久化)。** 把(签名、原因、修复)三元组账本、分组阈值升格这套机制对应到 SAA 图里。签名匹配纯算法零 LLM,便宜模型只在两处兜底,每次命中省一次 LLM 调用。种子协议里的错误码要从 OpenGame 用的 Phaser 引擎换成我们的 LittleJS 运行时和九门错误码,但结构原样可用。
- **Template Skill 按 gameDefinition 重写,且入库前过九门质量门。** 抄它的范式,但实现整体重写(它的物理信号正则和 hook 命名死绑了 Phaser)。**更关键的是:原版入库前没有任何回验门,带病的骨架会直接沉进库;我们必须给它加一道"入库前过九门或可构建校验"的质量门**——这恰恰是我们相对它的强项,把我们最硬的东西用在它最弱的地方。另要预警原版一个硬缺口:这套进化只有单调累积、没有遗忘 / 淘汰 / 冲突消解,也没有向量检索,家族一多会退化;等品类规模上来,我们可能需要补一层真正的检索。
- **资产线接 mmx。** asset 节点接 mmx-cli 替代那套重流水线,降级部分照多级回退思路兜底。顺带把它的确定性 bitmask 贴图(纯算法、与模型无关,用确定性算法绕开模型的空间推理)直接搬进来——这是 OpenGame 一个聪明的工程判断,几乎零成本可得。
### 6.3 两处交汇点:必须合并,不能各列一遍
线 A 和线 B 有两处在解同一个问题,必须合成一项实现:
- **交汇点一:品类的独立交叉校验。** 线 A 的"品类独立交叉校验"和线 B 的"物理优先分类"指向同一件事。内核是:保留 classify / design 自产骨架的生成路径,但**验收的判定依据绝不能押在同一只待验模型的分类输出上**。做法是引入一个独立于 design 的交叉校验——从题面关键词、从 player 软门的视觉反推品类,与 design 自报的品类比对,不一致即降权乃至拒发。线 B 的物理优先分类(看重力方向、视角、移动方式而非品类名,比如"Terraria 是平台跳跃不是俯视类"这类易错例)正好为这个独立校验提供高质量判定依据。**一件事,一处实现。**
- **交汇点二:把 player 软门做厚,验收去自评。** 线 A 的"九门去自评闭环"和线 B 的"补强 VLM 语义层"是同一件事。九门那一层(机制)已领先,不动它;要补厚的是判"好不好看、是不是要的那个游戏"的 player 软门。动作是让这条软门更系统、可复现:做成独立于生成方的交叉校验,甚至一个离线评测基准,蓝本就是 OpenGame 论文那套三轴。配套把"模型靠运行时内置基元蹭过门、还是真写了交互逻辑"的占比,以及 player 自评与九门判定的交叉一致性都进轨迹,长期背离即告警——用数据积累"门的有效性"证据。
### 6.4 统一迁移序列
已有三份执行计划承接本序列:`2026-06-17-001`(后端生成主线基座)、`2026-06-18-001`(生命周期 + 广度)、`2026-06-18-002`(广度后端)。下面的阶段挂入这些计划的验收,不新建编号;标 **★** 的是关键路径,标 **[新增]** 的是 OpenGame 对照带来的、需补进对应计划的新工作项。
```mermaid
flowchart LR
P0["阶段0<br/>零风险立桩<br/>收敛常量来源"] --> P1["阶段1<br/>线A·重构<br/>抽 TraceExtractor"]
P1 --> P2["阶段2 ★<br/>线A·解 P0<br/>prompt 同源"]
P2 --> P3["阶段3<br/>线A·契约先行<br/>模型外置 + 失败子码"]
P3 --> P4["阶段4 ★<br/>质量加固·全 flag-off<br/>latch + 两交汇点"]
P4 --> P5["阶段5 ★<br/>里程碑门·cutover<br/>达 80% 切默认产线"]
B1["阶段B1 ★ [新增]<br/>GDD 契约 + template_api"] -.越早越好.-> P4
B1 --> B2["阶段B2 [新增]<br/>Debug/Template Skill + 资产线"]
B2 -.支撑.-> P5
```
- **阶段 0(零风险·立桩)**:收敛 job 核心字段名、状态键集、轨迹键集的常量来源。这里要切分清楚——Java 内部键名可以收敛到常量类,而 Java 与 Python 之间的轨迹键只能靠契约和测试夹具对齐,不能并入 Java 常量类(这是一处假锚)。纯重命名,无行为变化。
- **阶段 1(线 A·重构)**:抽 `SaaTraceExtractor`、拆 `SaaStudioNodes` 分包,调度器瘦身,零行为变更。
- **阶段 2 ★(线 A·解 P0)**:gameDefinition prompt 约定提为版本化资产,两轨读它、CI 卡字节。关键路径:split-brain 未解前不得拿 worker 线数据做 cutover 决策。
- **阶段 3(线 A·契约先行)**:模型外置 + CI 一致性校验;失败原因扩子码(注意列宽 32);把作业对象在调度器边界 record 化。全 additive 加 fallback。
- **阶段 4 ★(质量加固·全 flag-off 落轨迹)**:① latch 终态语义区分胜利与弃守 / 超时(P0);② 交汇点一(品类独立交叉校验);③ 交汇点二(player 软门做厚 + 可观测化);④ fallbackEvents 入轨迹。全部默认关闭、只观测、不改放行行为。
- **阶段 B1 ★[新增]**:GDD 契约 + template_api(LittleJS 插件库公开 API 清单),classify 与 design 节点契约化。这是约束力的靶子和最高价值杠杆,建议优先排进 `2026-06-18-001`。其中"物理优先分类"与阶段 4 交汇点一是同一处实现,不重复建。
- **阶段 B2 [新增]**:Debug Skill 落 diagnose / repair 节点 + checkpoint;Template Skill 按 gameDefinition 重写并强制入库前过九门;asset 节点接 mmx 并搬入确定性 bitmask 贴图。可在 B1 之后并行。
- **阶段 5 ★(里程碑门·cutover)**:gamedef 成功率达 80% 门后,切默认产线、二分退役 factory、把拦截门翻开、闭合 modify"从源真构建"。依赖阶段 2(prompt 同源)、阶段 4(质量信号可信)与 80% 达标率三个前置。
**关键路径是一条线:阶段 2(prompt 同源解 split-brain)→ 阶段 4(质量信号可信)→ 阶段 5(cutover)。** 阶段 0 / 1 / 3 可并行。按价值排,最该立刻动手的三件依次是:**先补 template_api 与 GDD 契约(B1,一切约束的靶子)、再把 Debug Skill 落成 diagnose / repair + checkpoint、然后把 Template Skill 按 gameDefinition 重写并加九门质量门。**
---
## 7. 我们刻意不做的
有三件 OpenGame 看起来在做、但我们刻意不做的事,讲清楚为什么,免得被论文卖点带偏:
- **不专训专用大模型(GameCoder-27B)。** OpenGame 论文把一个为游戏定制的 27B 代码模型当支柱,但它的权重、训练码、数据都不在仓里,实测代码默认接的反而是通用强模型,设一个环境变量就能换。这恰恰证明它的框架被刻意设计成与模型无关——专用模型不是跑通的必要条件。我们的路线明确是便宜通用模型 + 门兜底,质量缺口靠模板约束加 Debug Skill 补。
- **不把 VLM 当硬门。** player 软门要做厚,但它的判定是视觉模型的概率性判断,不能用来定一次生成"算不算完成"。把软判定提成硬门,会直接撞上铁律——"完成"必须由确定性的门来定。所以 VLM 这条线只做软门、做离线基准、做交叉校验与告警,产出的是"门的有效性"证据和质量趋势,绝不进放行的确定性判定。**九门是机制地板,VLM 是质量观测,两者职责不混。**
- **不上重型沙箱。** OpenGame 的命令执行是重型的(独占进程组、信号管控、容器沙箱,深度绑定 Node 生态),这是它"模型自由写代码再跑构建看报错"那套自主循环的物理基座。我们走图编排,build 节点职责窄得多,MVP 阶段不需要这么重的沙箱;将来真需要,Java 侧自建等价物即可,绝不移植那套 JS 适配。同理 MCP(模型上下文协议)走 SAA 自带支持,不搬 OpenGame 那套 JS 适配层——何况 OpenGame 的游戏生成能力本就不来自 MCP,而来自内置确定性工具加工程模板。
---
## 8. 三级生成与契约体系(蓝图锚点)
上面讲的是 MVP 阶段的生成主线现状与近期演进。从更长的产品视角看,生成能力被规划为**三级**,对应创作者梯度和三条收入线。这部分是蓝图级锚点,这里只给骨架,细节在源档:
| 维度 | L1 模板成游戏 | L2 模板扩玩法 | L3 全栈造游戏 |
|---|---|---|---|
| agent 职责面 | 填参 + 文案 + 资产变体选择 | 受控补丁面改码 + 关卡 + 生成资产 | 全内容域,多 agent 分工 |
| 预算档(工程门) | ≤ ¥0.15 / 款全成本 | ≤ ¥5 / 款全成本 | ¥50~500 / 款(B 端定价覆盖) |
| 时延 SLO | P75 ≤ 30s | P75 ≤ 10min | 小时级,阶段进度可见 |
| 对应人群 | 小白(一句话) | 进阶创作者(资产 + 对话) | 专业 / B 端 |
> **一条重要的模板哲学拍板(2026-06-12)**:**模板 = 引擎能力插件**(碰撞 / 粒子 / 物理 / 手感等,LittleJS 二次开发件),**不含玩法 / 美术 / 关卡 / UI——这四者是 agent 生成域**。玩法模板层被废除(它是同质化的根源)。所以"玩法模板"在本项目语义里 = 品类引导框架,影响生成 prompt 与脚手架,**不是一个可执行的游戏壳**。
支撑这套体系的是**第 9 契约组**(生成工厂契约包,9a~9g):9a 模板协议(能力插件清单)、9b 作业与状态、9c 评估与就绪评分、9d 全链 trace、9e 代码补丁、9f 资产血缘、9g 收益归因。配套还有一个**生成控制平面**(配额 / 计费 / 背压 / 取消 / 幂等 / 补偿 / 防刷 / 降级——没有控制面的 agentic 系统会同时烧钱、压垮环境、放大滥用),以及一套**双轨灰度矩阵**(工厂路径按品类 × 人群灰度,黄金评估集通过率 ≥ 80% 且灰度 7 天错误率达标才切默认,跌幅 > 5pp 或破红线自动切回)。L2 起代码不可信,有一套七层信任边界(补丁面白名单、依赖锁定、静态安全门、构建隔离、运行取证、发布隔离、代码补丁契约)——细节都在源档,不在此展开。这里的"生成控制平面 / 双轨灰度矩阵"是蓝图级骨架;它的现行四组件设计(配置注册表、观测 / 审计仓、D12 运行治理门、管理面 UI,两条生成线共用)在同目录 [agentic 集成架构](agentic集成架构.md),以该档为现行口径。
---
## 9. 源档导航
本文档是生成引擎子树的策展层主档,把源档合成了一张可读的全景。要看更深的设计推演、逐条裁决与证据,从下面进去:
| 源档 | 回答什么 |
|---|---|
| [设计合理性裁决](设计合理性裁决.md) | 对这套生成范式"到底合不合理"的对抗式审查裁决:它合理在哪、天花板与裂缝在哪(本文 §1/§3/§5 那条"Tier0 可靠产线、非通用范式"警示的权威源) |
| [生成主线架构演进路线](../../../agent-specs/生成主线架构演进路线.md) | 生成主线"往哪走、先做什么"的单一 SoT:现状诊断、OpenGame 对标、统一演进路线(本文 §4§7 的权威源) |
| [生命周期项目管理 review](../../../agent-specs/2026-06-17-生成主线-游戏生命周期项目管理-review.md) | "游戏 = 长生命周期源项目、LLM as 工作室"范式的完整裁定与契约 delta(本文 §3 的权威源) |
| [游戏生成系统总体架构 review](../../../agent-specs/2026-06-12-游戏生成系统总体架构-review.md) | 三级生成、第 9 契约组、控制平面、灰度矩阵、29 条意图覆盖矩阵(本文 §8 的权威源) |
> **tier2 富游戏自治轨**(与上面现行线解耦并存的新轨,2026-06-21 设计)的三份设计也在本子树:[自治富游戏引擎](自治富游戏引擎.md)(引擎内核:O2 约束自治、Phaser/Pixi 选型、确定性地板加人工终审)、[agentic 集成架构](agentic集成架构.md)(控制 / 管理面治理层,两条生成线共用)、[tier2 实现详设](tier2实现详设.md)(源项目契约、统一 trace 实现接点、建设五步、0号 spike runbook、退路树)。
> **纪律**:本档是生成引擎的策展层 SoT——读它 = 当前真相。带日期的源档是留痕层,记录设计如何演进至此;两者职责不同,不互相重复。当现行真相与某份带日期的源档冲突时,以本档与它引用的最新裁定为准。
---
> **验证状态**:本文档为架构策展文档,由四份已评审源档(含 2026-06-20 设计合理性裁决)合成,未改任何代码。承重硬事实(V18 建表 + V20 加并发幂等唯一键、prompt registry 已存在、SAA 16 节点、九门、80% 门、¥0.15 / P75≤30s 预算时延门、76%93% 缓存命中、OpenGame 结论锚在其真源码、Tier0 范式定性锚在裁决档)均沿用源档已抽查属实的结论;品牌已统一为"绘境AI"。