← 返回作品

今晚吃什么

像素风「吃东西进化」类幸存者游戏:一只靠吃进化的史莱姆,边打边吃、三选一养成,还能让 AI 现场为你生成本局专属食物。也是一次方法论实验——当代码几乎全部由 AI 产出,如何让它的产出可被信任。

角色 · 独立开发 + 质量体系设计 2026 独立游戏 / Godot 4.7 技术栈 · Godot 4 / GDScript / DeepSeek / gpt-image-2 / PowerShell
今晚吃什么
925
次提交 · 24,865 行 GDScript
129
项自动化检查(47 静态 + 82 运行时)
45 + 62
份设计规范与执行计划
6 级
判定状态 · 只有 1 种允许重试 ↓

吃食物攒进化度,攒满三选一,四大流派 × 三层进化树叠加金色组合卡。战死或通关回小屋,用掉落的调味料熬煮、购物、换装,再来一局。向大厨点一道菜,游戏会现场生成它——文案、像素图、数值、专属进化分支,只属于你这一局。

游戏 Lobby:熬煮站、大厨史莱姆、服装管理员、小卖铺老板等 NPC 围绕着玩家小史莱姆
整备小屋把点菜、熬煮、换装、情报四条系统收在一屏内——AI 生成的入口就是中间那个大厨
PRODUCTION · 怎么做的

代码不是我写的,是我定义、审查、验收的

一句话:AI 负责把东西做出来,我负责定标准、挑毛病、决定它能不能上线。

稀缺的能力不在产出,在判定——所以工程重心从「怎么做出来」移到了「怎么知道它真的对」。

  1. 想做的功能
  2. 先写设计规范 要什么、不要什么 · 45 份
  3. 再写执行计划 分几步做 · 62 份
  4. 按风险决定怎么协作 低:直接做 / 中:先讨论 / 高:做完两轮审查
  5. AI 实现
  6. 129 项检查全过才算完 有红的:定位 → 先复现 → 再修
  7. 人工评审
  8. 写进优化日志 16 批 · 含明确没修的项 · 回头改规范
先写清楚要什么,AI 再动手;做完必须过自动检查;踩到的坑回头写进规范。整个闭环里没有一步依赖「我看着没问题」。
AGENTS.md · 按风险分级的协作契约
低风险   技术债 / 重构 / 补测试          直接实现  →  聚焦验证
中风险   玩家可感知的 UI / 手感 / 数值    先讨论再实现  →  单次评审
高风险   跨模块行为 / 发布就绪            实现  →  规范审查  →  质量审查
哪些活能直接交给 AI、哪些必须先跟我对齐,写死在契约文件里,不靠临场心情决定。

规范先行。 我先把要做的东西写清楚,AI 再动手。同一个功能,规范写得含糊,AI 给你的就是一个「能跑但不对」的版本;规范写死,基本一次过。这在几十次迭代里是可观察、可复现的因果关系,不是玄学——所以这个项目里 45 份设计规范加 62 份执行计划,是最不像代码、却最决定代码的部分。

踩过的坑要变成清单。 一年下来沉淀的不是「AI 很好用」这种感受,而是一份 AI 在真实引擎项目里会怎么翻车的清单:什么现象、什么原因、以后怎么绕开。下面三条可以展开看。

AI 失败模式 · 节选三条
检查脚本自己打印「全部通过」,判定却是失败
现象 脚本最后明明打印了 ALL OK,整套判定给出的却是 FAIL。
原因 脚本里直接引用了某个全局类名,引擎在加载阶段就要把这个类背后一整条依赖链编译出来。链上任何一环有问题,错误已经被引擎写进了错误流,而脚本自己的断言当然还是全过——它压根不知道外面已经炸了。
以后怎么避免 检查脚本不直接引用类名,改成运行时按文件路径加载;判定也不能只看脚本自己的结论,必须同时看引擎的输出。
进程假死,一行输出都没有
现象 跑着跑着卡住,不报错也不退出,最后被超时干掉。
原因 代码里用「延迟到下一帧再试一次」来做重试。但引擎清空延迟队列时会一直处理到队列为空——你在清空过程中新塞进去的任务,会在同一次清空里立刻再跑一遍。于是「下一帧再试」变成了同一帧内的无限递归。
以后怎么避免 重试必须真的跨过一帧(等待下一帧或用计时器),不能用延迟调用假装跨帧。
换台电脑检出代码,几十项检查同时报错
现象 本机全绿,干净环境里几十项检查一起报「找不到这个类型」。
原因 全局类名表是编辑器扫描出来写进本地缓存的。新加的类在自己机器上早被扫进了缓存,干净环境没有这份缓存,就全都找不到。
以后怎么避免 让 CI 每次从零检出跑一遍——这正是 CI 唯一不可替代的价值:它提供一台「没用过的电脑」。
QUALITY GATE · 怎么验的

怎么让「检查通过了」这句话可信

「门禁」就是一堆自动跑的检查脚本:任何一条不过,这次改动就不许合并。这一节讲的是——怎么让这些检查真的说真话。

代码能跑不等于代码是对的。中间隔着三种假象:AI 自己说测过了、本机缓存把问题挡住了、失败重试一次就变绿。还有第四种最阴——全程没有任何报错,产出的东西却是废的。

L0
静态检查 · 不启动游戏
47 项 · 约 1.5 分钟 · 唯一进 CI 的一层

只看数据和规则本身:字段有没有填错、文件有没有缺、算法结果对不对、该接的线有没有接上。快到每次改动都能跑一遍。

L1
运行时检查 · 真把游戏跑起来
82 项 · 10–20 分钟 · 本地全量

起完整引擎跑真实的帧,验系统之间的配合:怪刷得对不对、buff 叠得对不对、技能相位、UI 有没有按时绑上。慢,但能抓到只在跑起来时才暴露的问题。

L1'
真图回归 · AI 生成的图有没有变差
按需运行 · 刻意不放进套件

把以前买过的每张真实原图重新切一遍,跟上次的成绩比:只许更好,不许变差。单独放,是为了不让「素材没准备好」变成整套检查飘红的理由。

L2
人看的部分
UI 越界 / 溢出 / 字号 + 实机目验 + 结构化评审

机器判不了的东西:构图、颜色、好不好读,只能对着美术规范一张张看。诚实地说,这部分至今没有自动化判据。

快的那层每次改动都跑,慢的那层攒着跑;CI 只跑最快的一层,因为它给的不是速度,而是一台没有本地缓存的干净电脑。
检查跑完之后,怎么判它到底算不算过
判定什么情况给这个判定拦不拦合并为什么值得单独分一档
TIMEOUT超时还没退出(默认 180 秒)拦断言失败时场景常常忘了退出、就一直挂着。不单独分一档,它看起来就像「还在跑」
FAIL输出里出现失败标记(SCRIPT ERROR / FAILED 等)拦检查自己报告的失败
ERRLOG出现了不在白名单里的引擎报错拦引擎级的运行时错误。加这一档之前,这一整类问题被系统性漏掉
EXITCRASH断言全过,只是退出的时候崩了不拦唯一一种已经查清原因的失败,也因此是唯一允许自动重试一次的
PASS正常退出,并且打了通过标记不拦—
WARN没报错,但也没打通过标记不拦不允许闷声通过:没打标记,说明这项检查可能压根什么都没验
先看输出内容、再看退出码;而且日志、标准输出、错误输出三份要合起来看——只盯一份会严重低估问题数量。
Principles

四条写下来的原则

它们都不是通用工程常识,而是这套体系被现实纠正之后留下的形状。

重试只能吸收已经查清原因的抖动

早期是「失败就重试一次」,套件确实变绿了,代价是把真正的偶发 bug 一起洗绿——一个 30% 概率复现的问题,重试一次后有 91% 的概率显示为通过(两次都撞上只有 9%)。所以现在只有「断言全过、仅退出时崩溃」这一种允许重试。

老债冻结,新债零容忍

新规矩遇上历史烂摊子,常见的两个选项都很差:全修完再上规则(阻塞太久),或者只写进文档不做检查(等于没有规则)。用的是棘轮——像只能朝一个方向拧的扳手:把现存的 72 处违规冻成基线,断言总数不许超过它。老的不挡路,新增一处立刻顶破基线报错;顺手清理后把基线调低,数字再也回不去。

CI 不是再跑一遍本地跑过的东西

它只跑最快的 47 项,不是图省事。开发机上堆着各种本地缓存,很多问题被缓存挡着看不见;CI 每次从零检出,相当于换一台没用过的新电脑跑一遍——新类找不到、文件漏提交这类问题只会在这里现形。

要确认门禁真的会报警,每个方向都要

故意把合格线抬高一次,看着评测报出合格率从 1.000 掉到 0.000、并以失败退出。一个从来没红过的门禁,和一个不存在的门禁没有区别。但只红过一次还不够:后来复查发现,另外三种变差它全漏了(见本节末)。有几种变差,就得各让门禁红一次——只红过一种,就只能信一种。

EVAL AUDIT · 评测的评测

评测体系本身,也要被评测

回头拿本机真实流水账(每次交付、每次评审各记一行)逐行对照代码,把评测体系自己复查了一遍。查出来的问题都是一个形状:每次都「跑了」、一处报错没有,却没在做它声称在做的事。

最刺眼的一处:被当作基线的交付流水账,134 行里曾有 126 行是检查脚本自己写的,真实交付只有 8 行。

复查核出来的 · 节选五处
原以为实际上现在
交付流水账就是真实基线134 行里 126 行是检查脚本写的:跑检查的进程和玩家共用一份账,之前的测试隔离只隔离了存档按启动参数判来源,检查一律写进隔离目录;跑满 129 项,真实行数仍是 8
真图回归验过会报警只验过「合格率下滑」这一个方向。基线被静默从 1.000 调到 0.893、4 张没登记的新图、不合格格子从 3 涨到 6,都照样通过调低基线必须写理由、留历史;没登记的判失败;不合格格子数也纳入比较
CI 拦得住引擎报错报错刷屏时 20 次漏 20 次——恰恰是最该抓的时候新写法 0 / 20;本地和 CI 的引擎版本、报错白名单是否一致,改由一条检查来判
带上违规理由重发,模型会在上一稿上改请求是单轮的,模型根本看不到上一稿,等于带着约束重新掷骰。另一个项目(守线)实测过同一根因:只给理由救回 12%,加上上一稿 75%改成多轮、带上上一稿。这条路径在这里还没触发过,75% 是另一个项目的数,这里只是预期
美术交付有检查守着那项检查查的是打包时被排除的副本,像素质量信的是 QA 记录里自报的「ok」——把图换掉照样绿守真正发出去的那份,从像素重算;每条规则都做过变异测试:改坏它,检查必须变红
这几处没有一处会自己报错——数据要单独验,报警要一个方向一个方向地验。样本还小(真实交付 8 行、评审 9 行);修完跑满 129 项检查,这两个数一行没多。
评审者也要被评测 · AI 子代理逐任务评审的 14 个任务
漏掉的问题出在哪个数说明
改动内4问题就在评审者眼前的改动里
改动外5问题在没改的文件里,逐任务评审结构上就看不到。最贵的一条在这里:删了一个字段、另一个文件还在给它赋值,每次生成玩家都报错——还被两份任务报告标成了「早就存在」
两个工程合计。漏判要按「改动内 / 改动外」拆开报,否则流程的盲区会被记成评审看漏。样本很小;其中一个工程的评审记录所在目录从第一天起就被版本管理忽略、已经找不回,那部分结论是按时间先后推断的——评测数据的留存,本身就是评测体系的一部分。
DATA PIPELINE · AI 出美术

两条 AI 生产线,难的不是生成,是验收

一条离线画美术,一条在玩家点菜时现场生成整套素材。两条都不是「调个 API 拿结果」——重点全在生成之后:这东西到底能不能用,谁来判、按什么判。

生成 → 校验 → 后处理 → 验收 → 入库,五步一步不少。

先有规范,再有生成。 一份全项目美术规范先定死视觉基调、像素网格、色板与明度、描边与色阶、动画帧率、UI 字体这些硬规矩,最关键的是最后两章:四类资产各自的验收标准,以及具体怎么审。不合格的资产在入库前就被打回,而不是「生成出来了就用」。

外观必须能拆着用。 主角一局之内要进化好几次,所以外观不能是一整张图:把角色拆成固定区域,每块独立生成、独立替换,再用一份主控骨架保证所有部件对得上位。难点不在画得好不好看,在于怎么让模型的一次输出里,同时给出好几块都能直接拿来用的区域。

一次请求,交付一整套素材。 玩家点一道菜:先让 DeepSeek 写出结构化的菜品文案,再让 gpt-image-2 在一张 1024×1024 的大图里按格子画完整套素材——1 个食物图标,加 3 条进化支线 × 3 个品质的部件,本地再切开装配。为什么不一个部件请求一次?因为这个图像 API 按「画了多少像素」收费,跟请求几次无关,一张画完最省。

  1. 菜品文案 DeepSeek 产出结构化 JSON
  2. 拼出整页提示词 禁止模型自己写背景
  3. 一张 1024×1024 大图 1 个图标 + 3 支线 × 3 品质
  4. 切图:找像素团 不能按格子硬裁——模型会画歪、会溅出碎屑,所以改成挑「连在一起的那团像素」
  5. 去掉粉边 洋红底会把白蒸汽染粉,得把被染的颜色通道压回去
  6. 统一尺寸对齐
  7. 装到角色身上
一次请求交付整套素材——难的不是让模型画出来,是把一张自由发挥的大图,切成能对齐、能装配的独立部件。
同样一套素材,换个画布尺寸的花费
1536×1024
1372 token
1024×1024
1056 token
省了 23%。注意不是按面积算的 33%——这个 API 的画布是分档计价、不是连续的。写成「省了 33%」,被追问一次就穿帮。
两种画布下,主体能用的高度都是 256px,缩掉的只是横向没人要的背景——所以这 23% 是白省的,画质没有牺牲。

把「能看」变成数字。 2026 年 8 月的一次事故:供应商正常出图、正常扣费,文案和技能全都成功,玩家拿到的却是默认模板外观,而且全程没有任何一处报错。问题分三层,每层都不是「报错了」,而是「根本没人判」。

  1. 模型正常出图并扣费,文案与技能全部成功
  2. 切图按 9 列 × 3 行去找精灵,模型却只在每个「支线 × 品质」块正中画了一个
  3. 于是有 5 个格子是空的,超过了 3 个的阈值
  4. 整页判废 因为当时的降级是按「整页」算的
  5. 已经切好的食物图标被一起丢掉——它是这份付费产出里最值钱的一格
  6. 玩家拿到模板外观,而全程无一处报错 日志只有一句「流程完成」,NPC 台词还把锅甩给了供应商
切图「没报错」和切图「结果能看」是两回事。三处修法各对应一层:让布局向模型的实际画法收敛、降级改按支线结算且图标永不连坐、每次入库都打日志记流水账。
每切出一格,就给它打五个分
指标合格范围越界说明什么级别
coverage · 这格画满了多少0.05 ~ 0.82太低=这格基本是空的或只有碎屑;太高=背景底板没剥干净FAIL
edge_touch · 贴到格子边的比例≤ 0.20主体在原图上就被旁边的格子切断了FAIL
chroma_residue · 残留的粉边≤ 0.02洋红底没抠干净,边缘发粉FAIL
fragments · 碎成了几块≤ 3主体碎了,或者把邻格的碎屑一起并了进来WARN
center_offset · 偏离中心多远≤ 0.25取景没框准WARN
前三项越界=这格根本不能用(FAIL),后两项=能用但值得看一眼(WARN)。整页汇总成一个合格率:≥0.95 算过、≥0.75 警告、更低算废。用本地占位顶上的格子直接计入不合格——它不是模型产出,不能拿来凑分。

降级要比付费更细。 那次事故里 5 个空格就让整页作废,连已经切好的食物图标一起丢。现在改成:图标和部件分开算,降级按支线算,只有所有支线都废才允许整页降级。另外整页原图永久存盘,所以切坏了的第一反应不是重新买一张,而是换个参数档位离线重切——那张炸鸡就是这么从「整页降级」救回「零降级」的,花了 0 元。

整条链路是围绕失败设计的。 模型一定会偶尔抽风,所以每一类失败都提前想好了兜法,而不是等它炸了再补。

会出什么问题怎么兜
文案模型写的提示词自带「深色背景」,和整页的洋红底指令打架生成侧禁止写背景,拼装侧再兜底剥一次——旧的缓存内容也一起受益
返回的 JSON 被代码围栏之类的噪声污染先剥掉噪声再重试,而不是直接判失败
网络抖一下按错误类型分开处理:连接 / DNS / TLS / 429 / 5xx 重试;超时不重试(推理本来就要几十秒,重发只让玩家多等一倍);400 / 401 / 402 重试也没用,直接失败
真的失败了降级到「招牌菜」池。关键是招牌菜和正常菜走同一条生产管线——一条平时不跑、配置更弱的降级路径,真触发时只会制造出没人测过的新故障
玩家怎么感知由大厨 NPC 出面道歉,玩家看到的是角色行为,不是一个错误提示
最后两条最容易被忽略:降级路径必须和主路径同构,否则它自己就是下一个 bug 的温床。
−23%
单次交付花费(换画布口径)
1.000
真机实测切图合格率
0 元
那次事故的恢复成本(离线重切)
5 项
每格质量指标 + 整页合格率
GAMEPLAY · 玩法

组合空间远大于内容体量

四大流派 × 三层进化树,叠加金色组合卡;四把餐具主题自动武器可购买、可抽卡升级;敌人按类型掉落带品质的调味料,熬煮站三合一,商店按风味点总值加配方计价。精英词缀、主题协同、菜谱墙、Boss 变体四组机制交叉相乘,让每局的组合空间远大于内容本身的体量。

Engineering

技术实现

用 Godot 4 + GDScript 独立完成,数据驱动贯穿始终。

数据驱动关卡

地图、波次、Boss、天然食物、进化池全部放进 .tres 资源文件,Stage 只是共享骨架——新增一张关卡几乎不用写代码。

组件化战斗

角色由 Health / Hitbox / Hurtbox / Mover / StatBoard 等组件拼装,投射物技能走对象池;四把餐具主题自动武器可购买、抽卡升级。

调味料经济

敌人按类型掉落带品质的调味料,熬煮站三低阶合一高阶,商店按风味点总值加配方计价——一套纯静态函数实现的经济系统。

VERIFIABLE · 可复核

上面说的每件事,项目里都有对应文档

这些文档是开发过程中真在用的,不是为作品集补写的,也没有为它重写过一行。

文档里面有什么
质量门禁与 AI 协作评测体系分层门禁 · 六级判定细则 · 噪声白名单怎么从实测统计推出来的 · AI 失败模式清单 · 评测体系自己的复查:查出了什么、怎么修、怎么复验
评审漏判率复盘两个工程、14 个任务 · 漏在改动内与改动外分开算 · 注明哪部分结论是推断的
全项目美术重制规范视觉基调 · 硬规则 · 四类资产的验收标准与审核方法
上线就绪评审P0/P1/P2 分级 · 发布门禁清单 · 每条结论配一条 30 秒能复现的命令
AIGC 交付页质量标准成本口径 · 五项指标的阈值和理由 · 去粉边的硬约束 · 回归评测怎么用、基线什么情况下才许调低
优化日志16 个批次,每次都写清怎么复现、怎么验证、以及明确没修的是哪些
上线评审里最该被看到的是取证表:一张表,每条结论都配一条 30 秒内能自己跑一遍的命令;末尾还明确标出哪几个数字来自当天的运行观测、无法从仓库静态复核。

同一套判断标准,两种生产方式。在 Liberty Engine 的海洋系统里,它是手写 HLSL、Compute Shader 和 GPU 稳定性预算;在这里,它是写给 AI 的验收细则。

— 横向联动
Liberty Engine 海洋系统 →守线 Hold the Line →
下一个项目
守线 Hold the Line →