一份逐步手册,介绍如何使用 GPT-4o Astra 编写代码、Blender 制作模型,在四天内打造一款完整可玩的浏览器游戏。
AI translation, not an official translation. Refer to the original for technical details.
Adapted from @builtbysketch# 如何用 Blender 和 GPT-4o Astra 构建一款完整游戏(而不仅仅是一个演示) 我用 GPT-6 Astra 构建了一款完整游戏,这件事在 X 上引发了不小的轰动。 最初只是一个演示,但四天后我们有了完整的可玩版本。好,这可不是什么只能跑一局的垃圾演示。 请在 paperroute.lol 体验 PaperRoute。 这是一款设定在美国街区的送报员风格投递游戏,整个游戏是在数次开发会话中完成的——GPT-6 Astra 负责编写代码,Blender 负责制作模型。 问题在于,尽管"一次出手"的效果令人印象深刻,但要构建一款完整游戏完全是另一回事,而让游戏看起来有风格、令人眼前一亮,也不是提示一次就能搞定的。 以下是我用来在四天内打磨出一款(尽可能精良的)可运行、好看、不只有一个花样的游戏的操作手册——实际上甚至不到四天。视频在 X 上爆火之后,剩余时间基本上都花在了调整网站、为大家做准备上。 每一个小时、每一个 token 都被记录在案,所以我能告诉你实际花了多少,而不是感觉上花了多少。这是完整的方法,按事情发生的顺序呈现。我还对每一个步骤做了完整的开发日志。 在此阅读完整开发日志——每一个转折、每一个画面、每一项数据(https://www.paperroute.lol/devlog/) ## 背景 早在七月,我就想让 Fable 尝试构建一款送报员游戏,但要做现代版——于是我写了一份创意简报。 一周的投递任务,从周一到周日,有订阅用户和非订阅用户,有狗,有汽车,有斜角摄像机。我还希望它能构建为原生 iOS 版本,同时支持网页版。但七月份只做到了一条灰盒街道和一个骑手就卡住了。关于这部分,后面还会说到。 结果不太顺利,我放弃了。 Fable 能做出来的只有一辆横向行驶的自行车。 AGI?算了吧,还没到那一步(目前)。 好吧,其实也没那么糟。Fable 的表现相当令人印象深刻,我确实取得了一些进展,只是没能达到我想要的效果。 ## 第一步——从一个你自己信服的创意简报开始 这个概念并非来自 Astra。 当 Astra 发布、我看完 OpenAI 的演示时,我觉得它可能非常适合这个项目。 于是我重新写了原来的创意简报,而不是直接复用旧版本。 说实话,提示词非常简单。 用简单的英文描述了原版游戏和其中一些机制,然后说明了我希望它做什么。 这一阶段我们只专注于游戏机制,并给了它一张透视图的参考图——原版送报员游戏的视角。 我的目标从来不是克隆原版《Paperboy》,而是借用这个概念,赋予它新的诠释。但如果你要给一个模型一个起点,那就给它目前最好的起点——对于一款骑车投递的游戏来说,最好的基础就是原版。 先把机制做对,再在可玩之后加入新的创意。 ## 第二步——确定游戏方向 在这个阶段,我把两件事分开处理。 我给了 Astra 两个独立的任务: - 美术方向 - 游戏方向 两者在同一个对话线程中进行。 在第一次"一次出手"之后,Astra 给了我一个可以演示的版本。它给出的等距视角和游戏风格,我打算保留,只是想要改变游戏方向和机制,调整摄像机的角度以及整体的观感和手感。你看,最初它给我的第一个演示,基本上就是你在 Twitter 上常见的那种东西。 一击即中,效果不错,相当有趣,有着自己鲜明的艺术风格,以及你在其他所有演示中见过的那套大同小异的界面。 在那个阶段,我关心的只是概念和游戏机制,大量的美术指导只会稀释这一切。 这个决定在第一个晚上就证明了它的价值。 Astra 在午夜前完成了六次提交,构建了一个带有确定性模拟的浏览器版本:瞄准后投出的纸球会精准落在虚线弧线所指示的位置,邮箱得分系统,以及一条终点在公园球场的路线。它边写代码边写测试,这比我预期的更加重要——因为此后每一次美术修改,都有一套测试套件可以跑。 --- 是时候把它调校到位了。 ## 第三步——调校美术风格 在我完成第一轮迭代、确定了角度和游戏手感之后,我现在可以在提示词改进游戏机制(比如投纸动作等)的同时,着手调校美术风格。 我用 GPT 生成了一批图像。 就在这个节点,我暂时跳出了 Astra,趁游戏编译的间隙,切换到 ChatGPT,给它提供了几张参考图,让它生成一些概念艺术和情绪板。 不,那不是"吉卜力"风格,我从未提过那个词。 我给它的,是一段描述性参考——关于那种凉风习习的日本夏日电影感,带有手绘质感的笔触效果。 GPT 随后为我生成了一份风格参考情绪板,我将以此为基础,进一步调校方向。 我不想用过多关于游戏具体视觉效果的细节来压垮模型或提示词。 **在同一个线程中并行推进工作流** 我通常不这么做,通常会把事情拆分开来,但有了新的工作流和我定制过的 T3 代码形式,我觉得这是一个留在单一线程中的绝佳机会。而且 Astra 似乎比 Fablecap 更能胜任这一点——你可以打断它,它似乎不会掉链子,这真的很了不起。 我一个提示接一个提示地同步迭代美术风格和游戏本身——眼看着它把我的 MacBook 烧得滚烫,与此同时 Blender 悄悄在后台运行,不断吐出令人印象深刻的渲染图和测试结果。整个过程中,演示一直挂在那个 URL 上,基本上全程都可以玩。 负责跑游戏引擎的那条工作流——我一边实时体验一边调校——是那条枯燥重复的流,但我会再用完全相同的方式重来一遍。 松开就停的转向。一个碰撞恢复窗口,让同一个垃圾桶不会连夺三条命。真的会追人、能被跑开或被一张纸分散注意力的狗。移动端控制方案:拖拽转向,长按踩踏板,点击投纸。以上每一项都是一个提示,在浏览器里看一眼结果,一次提交。 **通过 Python 运行 Blender** 风格这条流用的是 Blender。Astra 不会直接打开 Blender,它写的是 Python 脚本,由 Blender 以无头模式运行,而非通过 MCP。 游戏里的每一栋房子、每一棵树、每一道篱笆和每一个邮箱,都是一段构建网格、拆分材质并导出 GLB 文件的脚本。第一遍是一份独立的夏日美术习作——一页房屋剪影、树木形态和街道道具,单独渲染,尚未接入可玩世界。 然后是房屋家族,然后是更茂密的花园,然后是带有绘画感的表面材质。到第二天上午十点,已经有七个房屋家族了。 将两条流程分开,是我会告诉任何人去借鉴的做法。当房子看起来不对劲时,你不想在同一个对话线程里还要跟模型争论投掷物理的问题。 ## 第四步 - 自定义模型 遇到困难时使用 Meshy 说实话,Astra 在制作房屋和相对简单的物体模型方面表现不错,但要让它们看起来好看,需要对每栋房子投入大量精力和提示词。 我的主骑手看起来像个木偶,说实话 Astra 也束手无策——它根本做不出一张脸。 所以最好的办法要么是去免费下载一些 Blender 资源,要么如果你心里已经有了具体的角色形象(我就是这种情况),就使用 Meshy,先在 ChatGPT 里生成图像。 花 8 美元把图像发给 Meshy。我实际上获得了 300 次图像生成配额,而我现在还远远没用完。 你字面意义上可以把图片上传到 Meshy,它会把图片转成 3D 模型供你下载,然后拖进 Astra,让它简化多边形,搞定——你就拥有了一个不那么丑的自定义 3D 模型放进游戏里。一直用 Astra 迭代只是消耗了大量 token,什么进展都没有。 在我使用这套 Meshy 工作流之前,那个模型真的一塌糊涂。 把模型贴合到我做的另一辆自行车上有点费劲,来回折腾了好一阵,但最终还是做到了,达到了一个说得过去的结果。不完美,但说得过去。我大概还可以多烧一些提示词来进一步打磨。 小技巧:如果你做好了骨骼绑定,天空才是极限 ## 第五步 - 添加细节 一键生成的游戏缺乏细节。 一键生成的游戏缺乏用心。 没错,它们可能内置了新鲜感,但自定义动画、更好的 UI 才能让游戏有真实感。 这并不是说我们正在见证的一切不是无可否认的奇迹,能做到这些真的太疯狂了。 但就目前而言,品味依然是护城河(还有耐心)。 我实际操作的时间和 Agent 轮次,有 80% 都花在了打磨、修复糟糕的网格、以及提示细节上,而不是在搭建游戏本身。 对于这个投递报纸的游戏来说,这些精雕细琢最终意义重大。 Astra 编写了 Blender 脚本,将身体多边形数量压缩到游戏预算范围内,同时保留原有的脸部、发丝和帽沿缝线;重建了袖子和手臂,防止皮肤穿透衬衫;将短裤下摆与腿部分离;将整个角色贴合到现有自行车上,保证手握车把和脚踩踏板的接触点正确;并用 23 根骨骼进行绑定,其中包括三根控制头发、三根控制衬衫下摆,使其随速度摆动。 我有大约 30 条提交记录,读起来活像一本裁缝的工作笔记。 修复骑手服装几何体、重建骑手手臂和袖子、保留短裤下摆、给自行车换上更直的 BMX 车把。 然后同样的流程又在那位拿报纸气呼呼走出房门的老头和拿着遥控器的男孩身上跑了一遍。 在 ChatGPT 里构思概念,用 Meshy 生成网格,通过 Astra 在 Blender 里跑脚本,绑定骨骼,审查渲染结果,导入游戏。一旦流水线搭好,第二个角色的成本只是第一个的一小部分。 小技巧:建立审查循环 审查渲染才是真正的核心工作。 我是在进行到一半时才真正理解这一点的。 早期我就提示并内置了一个始终循环审查工作的机制。我会让它自己检查模型有什么问题,对该模型进行孤立渲染,然后把结果发回给我审查,接着我再提示——从渲染一到渲染二,60%到70%的改进都是由 Agent 通过这套流程完成的。 你通过查看渲染图来审核模型的3D作品。 Astra设置了捕获脚本,将实际的Three.js骑手置于转向、投掷、冲刺和摔倒等姿势中,并在每次执行时保存正面、侧面、背面和黏土材质的全方位旋转图。 开发日志中的每个检查点旁边都有这些渲染图。当发现问题时,你指向那一帧,说帽子没有盖住头发,这就是下一步的提示。 ## 第六步:加入品味与点睛之笔 以上所有内容都是流程。流程能让你做出一款可以运行的游戏,但无法让人玩第二遍,而这之间的差距就是品味——这部分只能靠你自己来填补。 你无法一步到位地做出一款好看又完整的游戏,那样只会得到一堆垃圾。 这里的一些品味体现在丢弃东西上。 原来那批模型几乎全部被舍弃了,替换成了完全自定义的角色(或者说即将如此)。 从游戏美术转化为老人和拿着遥控器的孩子这一过程中可以看出这一点。如果我要再花更多时间,我会把它花在这里:增加更多角色,并让现有角色更有生命力,让街道感觉更有活力、更有个性。 然后是那些点睛之笔。 砸窗效果单独开了一个分支。雨天也是如此。同样是在一次直播内完成的,但是两条独立的子代理线程。全新的工作树和独立的游戏版本用于隔离测试,随时可以合并进来。 我甚至花了相当一段时间来调整摔倒动作。 小贴士:在将想法或功能折入主线之前,先运行实验性的游戏分支来测试它们。 我想要那个砸窗效果——但我不确定它是否奏效,所以我在独立分支中进行了测试。 只有砸窗效果,搭配一个完全独立的镜头,镜头推进到窗户,定格在撞击瞬间,然后摇回骑手。第一版完成后,我加长了末尾的滑板公园,把它打造成更像一个训练场,让路线以有趣的内容收尾,而不是戛然而止。 随着开发推进,我建造了更大的豪宅并将它们分布在街道沿线,增添动感。最重要的是,我制作了一套全新的天气系统。从小处着手——水坑溅起的水花和轮胎驶过留下的痕迹——然后做出了一整个纯粹的雨天。 这些都是让游戏焕发生命力、增添层次感的东西。 这款游戏原本很容易只是一条平坦的路,你反复跑一遍追求最高分就结束了。将这些元素融合进来赋予了它新的维度,而这正是品味真正发挥作用的地方。 网站也是如此。让我无法立刻上线的原因,是要让网站看起来可信,并用整体概念将其包裹起来。登陆页面是一份报纸,成绩页面是一份报纸,积分榜也是一份报纸。我觉得自己在这方面做得还算不错。 ## 成本明细 DevClocked全程追踪记录。从7月1日第一次规划提交到9月12日托管上线后的第四天: - 共39小时的追踪覆盖,其中25.2小时为人工操作,13.8小时为代理独立运行 - 15.6亿个token,其中15.3亿为缓存读取 - API价值2175美元,不是我的账单 - 11天内共90次提交 存在感追踪功能于9月6日才开始启用。在此之前,追踪时间默认将我标记为在场。此后,追踪时间中有三分之二的时长我并不在键盘前。 八次提交,然后是长达两个月的空白期。九月份的浏览器重建花了四天时间搭建,第五天才上线——这就是大家都在玩的游戏。我并不完全后悔七月份那段时间,因为设计文档和模拟系统设计都保留了下来,但如果我一开始就在浏览器端构建,第一天就能有一个可玩的版本。 还有一些悬而未决的问题,我宁愿直说,也不想假装没有。手机上稳定保持60帧还没有得到验证。一次受控测试保持住了,另一次平均只有58帧。Meshy生成的骑手模型有88,550个三角面,因为我保留了面部细节,而我还没有在真实手机上对此做过基准测试。 **TLDR:如果你想自己做,这是步骤顺序** - 先用自己的话写设计文档,然后挑选一个最接近你目标的参考作品,哪怕那是你不被允许克隆的东西。 - 把设计文档和两三张粗略的图片交给模型,在游戏机制可玩之前,先把美术方向压住不动。 - 将引擎和视觉风格作为独立的对话分开处理。 - 用Python在Blender中构建道具,这样每个资产都可以复现。 - 角色需要面部时,在ChatGPT里制作概念图,从Meshy获取网格,再交给Astra进行减面、绑定和适配。 - 每次修改都要获取审查渲染图。留出一天时间做点睛之笔——天气效果、破窗动画、结尾的公园场景——因为正是这些让人想再玩一遍。 - 记录你的工时和token用量,因为你以后会想知道这些数据。 然后把它部署到一个域名上。 这个项目在 paperroute.lol,那里的开发日志记录了背后的每一个检查点、每一张渲染图和每一个小时的投入。