首页 / 资讯中心 / 文章详情

12家大模型同写一个游戏:谁更靠谱?最贵的竟翻车

12家大模型同写一个游戏:谁更靠谱?最贵的竟翻车 ★ FEATURED ARTICLE
1. 这场“AI天梯赛”到底在比什么第一次看到“12家大模型做同一个游戏”这个说法我脑子里冒出来的不是技术评测而是一个很朴素的疑问让一堆语言模型去写同一个游戏到底能比出什么是比谁的代码能跑起来还是比谁写出来的东西更好玩后来我自己动手复现了一遍类似的流程才慢慢摸清楚这类对比真正有价值的地方在哪里。先说清楚这件事的本质。所谓“AI天梯”并不是让模型直接去玩游戏而是让它们扮演一个游戏开发者的角色在同一个需求描述下各自产出一份可运行的游戏工程。这个需求通常包含几个固定要素一个明确的玩法目标、一套操作方式、一个胜负判定条件以及一个视觉呈现的基本要求。所有模型拿到的是同一份“需求文档”区别只在于它们背后的模型能力、上下文理解方式、代码组织习惯以及面对模糊需求时的补全策略。我之所以对这个话题感兴趣是因为它把平时很难量化的东西摆到了台面上。平时我们评价一个模型写代码行不行往往是零散地丢几个函数让它补全或者问它一个算法题。但游戏开发是一个典型的“多模块耦合”场景输入处理、状态管理、渲染循环、碰撞检测、分数统计这些东西必须同时成立游戏才能跑。任何一个环节掉链子整个工程就是一堆跑不起来的死代码。这就比单纯的算法题更能暴露模型的真实工程能力。还有一个容易被忽略的点游戏需求本身是“半开放”的。你告诉模型“做一个贪吃蛇”它可以选择用二维数组做网格也可以用链表做蛇身可以用定时器驱动也可以用帧循环驱动。这些选择没有绝对的对错但会直接影响代码的可读性、可扩展性和运行稳定性。观察不同模型在这些分岔路口怎么选比看它们能不能写出一个能跑的版本更有意思。所以这场天梯赛真正比的不是“谁更聪明”而是“谁更像一个靠谱的开发者”。靠谱体现在几个维度需求理解是否准确、架构选择是否合理、边界情况是否考虑、代码是否可维护、遇到自己不确定的地方是否会主动收敛而不是胡乱发挥。这些维度平时很难一次性看清楚但放在同一个游戏需求下差异会被放大得很明显。至于标题里说的“最贵的竟然翻车”我一开始也以为是噱头。但实际跑下来会发现价格高通常意味着模型更大、推理更慢、单次调用成本更高但这并不自动等于工程能力更强。有些大模型在自然语言表达上非常流畅可一旦进入需要严格状态同步的代码场景反而容易“想太多”——它会自作主张地加入一些需求里根本没提的机制结果把简单问题复杂化最后自己把自己绕进去。这个现象在后面会展开讲。2. 我复现这套流程时踩过的三个坑在真正动手之前我以为这件事很简单把需求写清楚丢给不同模型把返回的代码存下来跑一遍就行了。结果第一轮就翻车了而且翻得很有代表性。这里把踩坑过程完整记录下来因为如果你也想自己做类似的横向对比这几个坑大概率一个都躲不掉。2.1 需求描述写得太“人话”模型理解偏差极大我第一版需求是这么写的“做一个简单的打砖块游戏球碰到砖块砖块消失球掉到底部就结束。”这句话对人来说很清楚但对模型来说里面全是模糊点。球的速度是多少砖块排几行几列挡板怎么移动球碰到挡板后反弹角度怎么算分数怎么记这些我都没说。结果就是12个模型给出了12种完全不同的东西。有的把球速设得极快游戏三秒就结束有的砖块排了二十行屏幕根本放不下还有的干脆把“球掉到底部就结束”理解成了“球掉到底部就重新开始”做成了一个无限循环。这些差异不是模型能力问题而是我的需求描述本身有歧义。后来我调整了策略需求文档里必须包含一份“最小可运行规格”把那些不写就会导致理解偏差的参数全部固定下来。比如画布尺寸、初始球速、挡板宽度、砖块行列数、得分规则、结束条件。这些参数不需要很精细但必须存在否则对比就失去了基准。提示如果你要做类似的模型对比需求文档的详细程度直接决定了结果的可比性。宁可写得啰嗦也不要留模糊空间。2.2 直接复制模型返回的代码格式问题比逻辑问题还多第二个坑更隐蔽。很多模型返回的代码是带 Markdown 代码块标记的而且不同模型的标记习惯不一样。有的用html有的用javascript还有的干脆不写语言标记。如果你直接把这些内容存成文件文件开头就会多出几行 符号浏览器打开就是一片空白。更麻烦的是有些模型会在代码前后加解释性文字比如“这是为您生成的游戏代码”或者“您可以将以下代码保存为 HTML 文件运行”。这些文字混在代码里轻则导致语法错误重则让整个文件无法解析。我一开始手动清理了五六个文件后来实在受不了写了一个简单的脚本用正则把代码块标记和前后说明文字剥掉只保留html到/html之间的内容。这一步虽然简单但能省掉大量重复劳动。还有一个细节部分模型返回的代码里混用了全角符号比如中文引号、全角分号。这些在 JavaScript 里都是非法字符但肉眼很难一眼看出来。我的做法是跑一遍基础语法检查把报错位置定位出来再手动替换。这个坑不致命但很烦人。2.3 运行环境不统一导致“翻车”判断失真第三个坑是我自己造成的。第一轮测试时我有的文件用本地浏览器直接打开有的用了一个简易的本地服务器。结果发现某些模型生成的代码在直接打开时能跑走服务器就报跨域错误另一些则相反。这就导致我一开始误判了几个模型的表现。后来我统一了标准所有游戏都用同一个本地静态服务器托管浏览器版本固定屏幕分辨率固定并且每次测试前清空缓存。只有这样跑出来的结果才有可比性。否则你很难分清一个游戏跑不起来到底是模型写错了还是你的环境有问题。这三个坑总结下来就是一句话对比模型的前提是先把你自己这边的变量控制住。需求要统一、代码提取要干净、运行环境要一致。这三件事做到位之后后面观察到的差异才是模型之间的真实差异。3. 12个模型交出来的东西大致分成了四类把环境统一之后我拿到了12份可运行或不可运行的游戏工程。按照最终表现大致可以分成四类。这个分类不是按模型名字来的而是按它们交出来的东西的实际状态来的。你会发现同一类里的模型往往在代码组织方式上也有相似之处。3.1 第一类能跑而且玩法完整这一类大概有三到四个模型。它们交出来的游戏打开就能玩球会动、挡板会跟手、砖块会消失、分数会累加、结束条件会触发。代码结构也比较清晰通常会把游戏状态放在一个对象里用requestAnimationFrame驱动主循环碰撞检测用简单的矩形相交判断。我印象比较深的是其中一个版本它甚至考虑到了“球在挡板边缘反弹时角度要变化”这个细节。需求里我只写了“球碰到挡板反弹”没提角度变化但它自己补上了。这个补全不算越界因为它让玩法更合理而且没有引入额外的复杂度。这类模型的特点是在需求模糊的地方它们会选择“最符合直觉且实现成本最低”的方案而不是炫技。从代码量来看这一类通常在 200 到 400 行之间没有多余的依赖纯原生 JavaScript 加 Canvas。这种规模对于一个小游戏来说刚刚好既不会太简陋也不会让人读不下去。3.2 第二类能跑但玩法有明显缺陷这一类数量最多大概有五六个。它们的共同点是代码能运行画面能出来但玩起来总觉得哪里不对。常见的缺陷包括球速恒定不变导致后期过于简单、砖块消失后没有分数反馈、挡板移动没有边界限制导致可以移出屏幕、游戏结束后没有重新开始的方式。这些问题单独看都不致命但组合在一起就会让游戏显得“半成品”。我仔细看了其中几个的代码发现它们并不是写错了而是在需求没有明确要求的地方选择了最省事的做法。比如需求里没提“游戏结束后要能重开”它们就真的不做重开游戏结束就是一片死寂。这类模型的特点是它们能理解需求的主干但在分支和边界上缺乏主动性。你让它做 A它就只做 A不会去想“做了 A 之后用户可能还需要 B”。这在某些场景下是优点因为不会自作主张但在游戏开发这种需要完整体验的场景下就显得不够周到。3.3 第三类能跑但代码结构混乱到无法维护这一类有两三个。它们的游戏确实能玩但代码读起来非常痛苦。典型表现是所有逻辑都堆在一个函数里变量命名随意状态散落在各处改一个参数要翻遍整个文件。有一个版本甚至把球的坐标、速度、砖块数组、分数全部定义成了全局变量然后在主循环里用一长串 if-else 处理所有碰撞。这种代码能跑是因为逻辑本身不复杂。但如果我想在此基础上加一个“道具掉落”功能基本等于重写。这类模型的问题不在于能力而在于缺乏工程意识。它们把代码当成一次性脚本在写而不是当成一个可以迭代的项目在写。有意思的是这类模型在自然语言对话中往往表现得很“聪明”能跟你聊很多架构设计的原则。但一到实际写代码这些原则就全忘了。这说明“知道”和“做到”之间确实存在一条不小的鸿沟。3.4 第四类根本跑不起来这一类有一到两个。打开就是白屏控制台报错。常见的错误包括引用了不存在的函数、变量声明顺序错误导致初始化失败、Canvas 上下文获取失败但没有做错误处理。有一个版本甚至在 HTML 里写了script srcgame.js但它根本没有生成 game.js 文件所有代码都内联在 HTML 里。这类“翻车”往往发生在那些在对话中表现得最自信的模型身上。它们会用非常肯定的语气告诉你“以下代码可以直接运行”然后你打开一看连画布都没渲染出来。这种反差感大概就是标题里说的“最贵的竟然翻车”的来源之一。4. 为什么“贵”不等于“稳”几个反直觉的观察做完这轮对比之后有几个现象和我原本的预期不太一样。我原本以为模型越大、越贵写出来的代码应该越靠谱。但实际结果并不是简单的线性关系。这里把几个比较反直觉的观察整理出来供你参考。4.1 大模型更容易“过度设计”有一个价格较高的模型在接到“打砖块”需求后没有直接写游戏逻辑而是先定义了一套“实体组件系统”的雏形。它把球、挡板、砖块都抽象成实体给每个实体挂上位置组件、速度组件、渲染组件。然后写了一个简单的系统调度器来更新这些组件。这套架构本身没有问题甚至可以说是“更专业”的做法。但问题是需求只是一个小游戏用这套架构写出来的代码量是其他版本的三倍而且因为抽象层太多调试起来非常麻烦。更关键的是它在实现过程中引入了一个 bug组件更新顺序错了导致球在碰到挡板时先被渲染再被更新位置视觉上出现了明显的抖动。这个例子说明模型的能力越强越容易在简单问题上“用力过猛”。它知道很多设计模式于是忍不住要用上但忽略了场景的规模。对于一个小游戏来说一个 300 行的过程式脚本可能比一个 900 行的“架构示范”更合适。4.2 便宜模型反而更“听话”有几个价格较低的模型交出来的东西反而更接近“能直接用的半成品”。它们的代码通常比较直白没有太多花哨的抽象变量命名也偏实用。虽然功能上可能少一些细节但至少不会给你挖坑。我分析了一下原因这些模型在训练时可能接触了更多“短平快”的代码片段所以它们更倾向于用最直接的方式解决问题。而大模型因为见过的“高级写法”更多反而容易在简单场景下选择不合适的方案。这给我的启发是选模型和选人一样不是越资深越好而是要看匹配度。一个资深架构师去写一个静态页面可能还不如一个刚入行的前端写得快、写得好。模型也是同理。4.3 翻车往往发生在“自信的补全”上我统计了一下所有跑不起来的版本发现一个共同点它们在需求没有明确要求的地方做了大量的“自信补全”。比如需求里没提“暂停功能”它自己加了一个暂停按钮但按钮的事件绑定写错了导致点击后整个游戏卡死。又比如需求里没提“音效”它自己加了一段音频播放代码但音频文件路径是它虚构的加载失败后阻塞了后续逻辑。这些补全本身不是坏事如果做对了确实能提升体验。但问题在于它们在补全时没有做“失败兜底”。音频加载失败就让它失败不应该影响游戏主循环暂停功能如果没把握就不应该加。在工程里一个不确定的功能不如没有功能。这个道理模型显然还没完全学会。5. 如果让我重新设计这个对比我会怎么改经过这一轮折腾我对“模型写游戏”这件事有了更具体的认识。如果让我重新设计一次对比流程我会在几个地方做调整让结果更有参考价值。5.1 需求文档拆成“必做”和“选做”两层第一版需求把所有东西混在一起导致模型分不清哪些是核心、哪些是锦上添花。改进的做法是把需求拆成“必做项”和“选做项”。必做项是游戏能跑起来的最低要求比如画布渲染、球和挡板的基本运动、碰撞消失、结束判定。选做项是加分项比如分数显示、重新开始、难度递增。这样一来评价标准就清晰了先看必做项是否全部完成再看选做项完成了多少。而不是像之前那样因为一个模型加了音效但音效坏了就把它和什么都没加的模型混在一起评价。5.2 给每个模型两次机会第一轮我只让每个模型生成一次。但模型输出有随机性一次翻车不代表它永远翻车。更合理的做法是同一个需求让每个模型生成两次取表现较好的一次作为最终成绩。这样能过滤掉一部分随机波动让对比更接近模型的真实水平。当然这也带来一个问题成本翻倍。但如果你真的想得到一个靠谱的结论这点成本是值得的。否则你很容易因为一次偶然的失败就对一个模型下过于严厉的判断。5.3 增加一个“可维护性”评分维度之前我只关注“能不能跑”和“好不好玩”但忽略了代码本身的质量。后来我想加一个功能发现大部分版本都很难改。所以下一轮我会加入一个简单的可维护性评分变量命名是否清晰、函数职责是否单一、状态管理是否集中、有没有明显的重复代码。这个评分不需要很精确哪怕只是“好改”“勉强能改”“不想改”三档也能提供很多信息。毕竟在实际工作中代码写出来是要给人看的不是给机器跑的。6. 从游戏延伸到通用代码生成几条实用的经验虽然这篇文章的由头是“AI做游戏”但里面暴露出来的问题其实适用于所有让模型生成代码的场景。不管你是让它写一个爬虫、一个数据处理脚本还是一个简单的网页下面这几条经验都能用上。6.1 需求里必须包含“验收标准”模型不知道你心里的“好”是什么样。你必须把验收标准写出来。比如“游戏必须能连续玩三分钟不崩溃”“分数必须实时更新”“结束必须能重开”。这些标准写出来之后模型在实现时就有了目标你验收时也有了依据。我试过在需求里加一句“代码必须能在不修改的情况下直接运行”结果那一轮所有模型都主动去掉了需要额外依赖的写法全部用原生 API 实现。这说明模型是能理解约束的前提是你得把约束说出来。6.2 对“额外功能”保持警惕模型很喜欢加戏。你让它写个计算器它可能给你加一个历史记录面板你让它写个待办列表它可能给你加一个拖拽排序。这些功能如果做对了确实好用但如果做错了就会变成负担。我的做法是在需求里明确写一句“只实现以下功能不要添加任何未提及的特性”。这句话能挡掉大部分自作主张的补全。如果某个模型还是加了那至少说明它没有认真读需求这本身也是一个有用的信号。6.3 代码提取和运行环境要标准化这一点前面已经说过但值得再强调一次。如果你要做多个模型的横向对比一定要把代码提取和运行环境标准化。写一个简单的脚本自动从模型返回内容里提取代码块统一保存为固定文件名然后用同一个服务器托管。这些准备工作花不了多少时间但能让你后面的观察省心很多。6.4 不要只看“能不能跑”要看“改起来难不难”“能跑”只是最低标准。一个游戏能跑不代表它写得好。你要试着去改它比如把球速调快一点、把砖块颜色换一下、加一个简单的道具。如果改一个参数要翻三个文件那这个代码的质量就是有问题的。这个测试方法很土但非常有效。它模拟的是真实开发中“需求变更”的场景。一个模型如果只能写出“一次性代码”那它在实际项目中的价值就会大打折扣。7. 我在这轮对比里学到的几件小事最后说几个比较零散但我觉得挺有用的观察不一定成体系但都是实际跑下来才注意到的。第一个是关于“注释”的。有些模型生成的代码注释非常多几乎每行都有有些则几乎不写注释。我原本以为注释多的更好但后来发现注释太多反而会干扰阅读尤其是当注释和代码不一致的时候。最舒服的版本是只在关键逻辑处写一两句说明比如“这里用矩形相交判断碰撞”其他地方靠命名自解释。第二个是关于“错误处理”的。大部分模型生成的游戏代码都没有任何错误处理。Canvas 获取失败怎么办音频加载失败怎么办它们默认一切都会成功。这在演示场景下没问题但如果你想把这个代码放到一个真实的产品里这些缺失的兜底逻辑就是隐患。第三个是关于“命名”的。有些模型喜欢用a、b、temp这种命名读起来非常费劲。另一些则用ball、paddle、brick这种一看就懂的名字。这个差异看起来很小但对代码可读性的影响非常大。我在评价一个模型时会特别留意它的命名习惯因为这反映了它有没有“为读者考虑”的意识。第四个是关于“依赖”的。有几个模型生成的代码引用了外部库比如某个物理引擎或者某个动画库。但需求里并没有要求用这些库而且这些库的引入方式往往是错的——要么版本不对要么路径不对。相比之下那些纯原生实现的版本虽然代码量稍多但至少不会因为依赖问题跑不起来。这让我更加确信在需求没有明确要求的情况下少依赖比多依赖更安全。这轮对比做下来最大的感受是模型写代码的能力确实在进步但“工程判断力”仍然是稀缺品。它们能写出正确的语法能实现基本的功能但在“什么时候该简单、什么时候该复杂”“哪些地方要兜底、哪些地方可以省略”这些问题上还远远不如一个有经验的开发者。这大概也是为什么即使模型能生成代码我们仍然需要人去审查、去调整、去为最终结果负责。
阅读完成 · 觉得有帮助?
咨询建站