这几天我把Step 5 Preview、DeepSeek V4 Pro、GLM5.3拉到同一个"考场"里,让它们各自从头写一个 3D 网页游戏。花了一天半,跑完三遍完整流程,中间经历了不少幺蛾子:浏览器白屏、角色原地起飞、模型对话跑偏、碰撞检测像开玩笑。认真说,结果比我预想的要好,但里面门道也特别多。这篇文章不聊虚的,直接把测试设计、统一提示词、三家模型的完整表现、代码质量对比和返修过程摊开给你看。如果你正纠结用哪个模型做小游戏开发,或者想评估自家代码任务的模型选型,这篇应该能当一份参考手册。
1. 为什么拿 3D 游戏当"考卷"
1.1 三个模型凑到一起的偶然与必然
先说背景。Step 5 Preview 是最近放出来的编程向预览版模型,主打的卖点是长上下文和复杂任务分解,官方示例里全是多文件项目重构之类的大活。DeepSeek V4 Pro 延续了 DeepSeek 一贯的推理与代码能力路线,社区里口碑一直很稳。GLM5.3 则带着 FlashX 变体来势汹汹,热词里不少人把它和 doubao-seed-2.0-code 放在一起比,说明大家确实在认真做代码模型选型,而不是只看排行榜分数。
我平时收到的私信里,问得最多的就是"XX 模型写代码到底怎么样"。说实话,这种问题没法用一句话回答。评测代码模型,很多人习惯丢几道 LeetCode,但那只能看到推理能力,看不到工程能力;也有人做个 CRUD 后台,级别又太轻,很难拉开差距。所以我一直想找一个"中等偏上复杂度"的真实任务:要有完整的项目流程,要有视觉反馈,要能直观看出做得好不好,还要能在单个文件里跑起来。3D 游戏刚好卡在这个位置上。
1.2 游戏选题的逻辑
我最终选的是"3D 第一人称躲避球":玩家用 WASD 控制移动,鼠标控制视角,躲避从前方飞来的随机障碍物,每躲过一个得一分,被砸到就结束。这个选题看起来简单,但背后的技术点一点都不少。
它涉及三维坐标运算、相机跟随与控制、碰撞检测、游戏主循环、随机生成、UI 状态管理。用 Three.js 实现的话,渲染部分由框架兜底,模型不需要写底层 GLSL,但恰恰因为 Three.js 本身有版本差异和 API 变迁,反而更容易暴露出模型的知识新鲜度。更妙的是,这是一个纯前端单文件项目,浏览器打开就能跑,环境依赖极少。你要是选 Unity 或 Unreal,光是工程导入和 IDE 配置就能折腾半天,根本没法横向对比三家模型的输出能力。
为什么不用贪吃蛇或者俄罗斯方块?因为那些 2D 游戏已经被模型们练成肌肉记忆了,测不出差异。3D 游戏对坐标系、空间思维和 API 调用的要求明显更高,模型的短板会在这里暴露得更明显。
1.3 测试环境与对照组设计
测试环境不复杂:一台 M1 Pro 的 MacBook,Chrome 浏览器,代码用本地静态服务跑起来。给三个模型建了完全独立的对话窗口,用同一套提示词,从零开始生成,不允许中途引导。整个过程在同一个下午完成,尽量排除时间因素带来的变量。
必须说清楚的是,这次三家都走官方对话接口,没有做本地部署。因为本地部署涉及的权重分发、显存占用、推理框架版本差异太大,GLM5.3 Flash 在不同 vllm 镜像版本下的行为表现就不一致,混在一起做横向对比本身就不公平。官方接口的算力相对稳定,至少能保证"同一道题,三家都在同一起跑线"。
2. 评分维度和判断标准
2.1 六个维度拆解
在测试开始前,我先定好了打分维度。没有标准就评测,容易变成"我觉得这个好",那写出来也没参考价值。这六个维度分别是:
| 维度 | 说明 | 权重 |
|---|---|---|
| 首轮可用性 | 第一轮生成的代码能不能直接运行 | 25% |
| 需求覆盖度 | 提示词里的需求点覆盖了多少 | 20% |
| 代码可维护性 | 结构是否清晰、命名是否合理、注释质量 | 15% |
| 渲染与交互 | 画面观感、光照、动画、操作手感 | 20% |
| 性能表现 | 帧率、内存占用、流畅度 | 10% |
| 返修效率 | 出问题后沟通几轮能解决 | 10% |
首轮可用性权重最高,因为这是大多数用户使用 AI 编程的真实痛点。模型生成得再聪明,如果第一版跑不起来,用户就得立刻面对"是继续纠缠还是放弃重来"的灵魂选择。返修效率我单独列了一档,后面会讲,这个维度非常能体现模型的对话能力和上下文理解能力。
2.2 统一提示词模板
提示词是这次测试的"考卷",三家必须做完全相同的题。我写了一个偏工程化的提示词,没有用网上流传的花哨模板,而是把需求点列成清单,顺便把输出格式也约束死。
请用 Three.js 实现一个 3D 第一人称躲避球游戏。要求如下: 1. 使用 PointerLockControls 实现鼠标视角控制,WASD 控制角色移动 2. 场景为浅色背景,有基础光照和阴影 3. 障碍物是随机生成的球体和立方体,从远处朝玩家飞来 4. 障碍物命中玩家则游戏结束,显示得分和"再来一次"按钮 5. 每成功躲避一个障碍物得 1 分,速度随分数提高 6. 页面需要包含标题、实时得分、操作说明 7. 请输出一个完整的 HTML 文件,包含全部 CSS 和 JavaScript,不要省略任何代码这段提示词信息密度很高。技术栈、交互方式、视觉风格、玩法规则、功能清单、输出形式全部覆盖到了。实际测试中,三个模型都读懂了需求,但理解和执行的程度确实有差距。提示词本身值得展开讲:里面故意没有指定 Three.js 的版本号,这是埋的一个雷。如果模型用的是比较旧的 API 记忆,就会在版本差异上翻车。
3. 三家模型实测全过程
3.1 Step 5 Preview:一次成型,但藏了不少版本陷阱
先跑的是 Step 5 Preview。第一轮生成耗时约 40 秒,输出一个 430 行左右的 HTML 文件。结构相当完整,CSS、HUD、Three.js 场景、PointerLockControls 都安排得明明白白,第一眼看过去是三个模型里工程结构最舒服的。
但把文件拖到浏览器一跑,直接白屏。控制台报了一条刺眼的错误:
THREE.Geometry is not a constructor这个错误我很熟,Three.js 从 r125 开始移除了THREE.Geometry,统一用BufferGeometry。模型在代码里用了旧版 API,说明它的训练数据里混了不少老教程的内容。我直接在对话里把报错原文甩给它,加了一句"注意 CDN 引入的版本是 r160,THREE.Geometry 已移除"。Step 5 Preview 的返修速度很快,把所有 Geometry 改成了 BufferGeometry,又顺手修了一个阴影设置的冲突。
第二次运行,游戏能动了。障碍物从远处飞过来,WASD 控制平移,鼠标转视角,手感还算正常。但我玩了一会儿发现阴影表现有点怪,走近障碍物时角色居然"穿模"了。检查代码后发现,它虽然用了 Raycaster 做碰撞检测,但只检测了玩家角色中心点,障碍物体积比较大时,中心点还没碰到就已经被视觉上"命中"了。于是又返修了一轮,让它把碰撞半径调大、加入障碍物半径补偿。改完以后判定就合理多了。
Step 5 Preview 给我留下的最深印象是"工程骨架好",它生成的代码模块化程度高,主循环和碰撞检测拆得很开,后期改动很顺手。但它的知识库里确实存在版本滞后,如果你不加注意,第一轮白屏几乎是必然的。
3.2 DeepSeek V4 Pro:稳中求胜,但需求覆盖不全
第二个跑的是 DeepSeek V4 Pro。生成耗时约 1 分钟,输出 520 行左右的代码,是三家里最长的。一运行就能跑,没有报错,这是第一个"首轮可用"的成绩。
DeepSeek V4 Pro 的场景风格最完整:浅色背景、网格地面、有雾效、障碍物有大小变化,视觉上非常接近一个正经小游戏。PointerLockControls 的引入方式也正确,用的标准 ES Module 写法,配合 importmap,一看就是照着官方例子改的。操作手感很顺,鼠标转向平滑,没有明显的抖动。
但需求覆盖出了问题。我玩了几轮才发现:没有计分板。障碍物飞过来、砸中、游戏结束,HUD 上只有标题和操作说明,得分没有显示。检查代码后发现,它把"得分"逻辑写了一半,碰撞处理后触发 gameOver,但得分的 DOM 更新逻辑整个漏掉了。这属于典型的"模型觉得自己写完了,其实需求没覆盖全"。我把提示词原文里第 4 条和第 6 条再贴给它,它很快补上了计分逻辑,顺便把"再来一次"按钮的状态管理也完善了。
DeepSeek V4 Pro 的突出优势是代码的工程完整度。变量命名规范、函数拆分合理、注释密度高,每段逻辑都能读明白。对新手来说,这种代码最友好,改起来不慌。缺点也很明显:对话响应比另外两家慢,而且它倾向于把需求"理解到位、覆盖不全",需要你反复核实需求点清单。
3.3 GLM5.3:最小实现主义,交互节奏最舒服
最后跑的是 GLM5.3,我用的 FlashX 版本。第一轮生成只用了约 20 秒,输出 260 行左右的代码,三家里最短。当时我心里一沉,担心它偷工减料。
启动后确实能跑,场景、移动、视角、障碍物生成都有,基础功能齐全。但玩了三十秒就发现了问题:碰撞检测是"伪"的——它用的是纯距离判断,但判定半径写得太小,障碍物从玩家身边飞过时,视觉上明明擦中了皮肤,游戏却不判定失败。换句话说,它把"被击中"的门槛放得很宽,于是躲避变得过分容易。这种 bug 在代码层面很难一眼看出来,必须实际操作才能发现。
我把这个现象反馈给 GLM5.3,没有贴完整代码,只说"障碍物和玩家视觉上擦边时没有触发 gameOver,请检查碰撞判定逻辑"。它的应对很老练:先复述了我的操作场景,然后定位到 getDistance 函数,给出了完整的替换函数和判定解释,最后还提醒我"如果要更精确的判定,建议用 AABB 碰撞检测"。这份诊断思路比另外两家都清晰,直接把修复方案和验证步骤一步到位。
改完之后,碰撞判定明显合理了。GLM5.3 的生成代码虽然精简,但每个函数都很短,边界明确。缺点是注释几乎没有,代码风格属于"聪明程序员懒得写文档"的类型。它的对话节奏是三家里最舒服的,响应快、定位准、解释少废话,返修成本最低。
3.4 返修轮次与时间成本对比
三个模型跑完,我把整个过程的量化数据整理了一下:
| 对比项 | Step 5 Preview | DeepSeek V4 Pro | GLM5.3 |
|---|---|---|---|
| 首轮生成耗时 | 约 40 秒 | 约 60 秒 | 约 20 秒 |
| 首轮可用性 | 白屏失败 | 可用但缺功能 | 可用但有逻辑缺陷 |
| 返修轮数 | 2 轮 | 3 轮 | 2 轮 |
| 总耗时 | 约 2.5 小时 | 约 3 小时 | 约 2 小时 |
| 最终评价 | 优秀 | 良好 | 优秀 |
总耗时不只是等模型回复的时间,还包括我每轮人工测试、定位、回贴反馈的时间。这里有个经验:返修效率往往比首轮生成速度更重要。GLM5.3 首轮只用了 20 秒,但两次返修都很干净,所以最终总耗时最少。Step 5 Preview 首轮虽然白屏,但问题集中,返修两轮就进入正轨。DeepSeek V4 Pro 首轮能用,却因为需求覆盖不全,来来回回补了三轮才补齐。
4. 代码与成品对比
4.1 实现方式对比
三个模型的成品功能一致,但底层实现思路有明显的风格差异。我挑了几个关键技术点做对比:
| 对比项 | Step 5 Preview | DeepSeek V4 Pro | GLM5.3 |
|---|---|---|---|
| 代码行数 | 约 430 | 约 520 | 约 260 |
| 相机方案 | PointerLockControls | PointerLockControls | PointerLockControls |
| 碰撞检测 | Raycaster 射线 + 半径补偿 | AABB 盒碰撞 | 距离判断(返修后加入半径补偿) |
| 阴影设置 | PCFSoftShadowMap | PCFSoftShadowMap + 雾效 | 基础 ShadowMap |
| 场景氛围 | 干净明亮 | 网格地面 + 雾效 | 极简风格 |
Raycaster、AABB、距离判断,这三种碰撞方案在 3D 游戏里都常见,但精度和成本不一样。Step 5 Preview 用射线检测,从玩家位置向障碍物方向发出一条射线,判断相交,精度最高,代价是代码略复杂。DeepSeek V4 Pro 用 AABB 盒碰撞,把玩家和障碍物都当作长方体,按轴对齐检测相交,简单可靠,也是经典做法。GLM5.3 一开始用距离判断,本质是把障碍物当作一个球体,用中心距判断,代码最少,但精确度依赖半径设置的合理性,返修后才补上。
4.2 渲染与性能实测
性能方面,三款游戏在 M1 Pro 上都能稳定跑到 55-60 FPS,基础流畅度没有明显差距。真正的差距在细节表现上。
DeepSeek V4 Pro 的视觉完成度最高。它加了雾效,远处障碍物逐渐显现,配合网格地面,场景层次感明显好于另外两家。Step 5 Preview 的场景最干净,浅色背景配合通透的光影,风格偏向工具演示。GLM5.3 的场景最简单,没有太多修饰,但基本光照和阴影都有,看起来像"能玩的 demo"。
内存占用上,我用 Chrome 任务管理器粗略观察,GLM5.3 生成的页面占用比另外两家低了一截。原因是它的障碍物数量控制更保守,场景元素少,GPU 压力自然小。DeepSeek V4 Pro 的元素最多,占用也最高,但远没到卡顿的程度。这个维度,如果你只做小游戏,三家的差距可以忽略;如果要做大型场景,GLM5.3 的"最小实现"反而是优势。
4.3 代码可维护性
代码可维护性是我这次特别关注的点。毕竟拿 AI 生成的代码,不能只看能不能玩,还要看后续能不能改。
Step 5 Preview 的代码结构是工程师范儿。主循环、场景初始化、碰撞检测、UI 更新,全部拆成独立函数,命名上偏好缩写,比如spd、cnt,理解需要一点上下文。DeepSeek V4 Pro 的注释密度最高,几乎每个函数都有说明,变量命名全拼,读起来像教科书。GLM5.3 的代码最短,函数粒度最细,一个函数只干一件事,但几乎没有注释,新手改起来需要先读代码。
我自己改代码的体验:DeepSeek V4 Pro 的代码最"省脑",因为注释把逻辑说明白了。Step 5 Preview 和 GLM5.3 都要求你自己读懂代码逻辑,前者靠结构清晰,后者靠函数短小。如果你后续要长期维护,DeepSeek V4 Pro 的体验最好;如果你希望代码体积小、易读核心逻辑,GLM5.3 的极简风格会更舒服。
5. 常见问题与排查技巧
5.1 三个高频翻车点
这次实测踩出来的坑,其实不止这三家模型会遇到。只要是用 AI 生成 Three.js 项目,这几个问题几乎人人都躲不过。
第一个是版本差异。Three.js 的 API 在近几年经历了几次大调整,THREE.Geometry被移除、PointLight的衰减参数变了、OrbitControls和PointerLockControls的导入路径也改过。AI 模型的训练数据里混着各个时期的教程,生成代码时很容易引用旧 API。解决办法很粗暴:在提示词里写明版本号,比如"使用 r160 版本 Three.js,注意 API 差异",同时 CDN 链接也要固定版本,而不是用 latest 这样的浮动版本。
第二个是 PointerLockControls 的引入方式。这个控件在新版 Three.js 里是 ES Module 形式,需要通过 importmap 或裸模块引入,不能直接在全局THREE.PointerLockControls上拿。模型经常弄混全局引入和模块引入,导致运行时报Cannot read properties of undefined。遇到这种问题,最直接的排查方式是看控制台报错里那个对象的来源,然后去查 CDN 目录结构,确认文件路径。
第三个是碰撞检测的判定范围。这是玩法层面的坑,代码不报错,但手感奇怪。AI 生成的碰撞检测,默认半径或范围经常是拍脑袋写的,需要你实际操作几把才能发现问题。遇到这种情况,不要跟模型说"手感不对",而是用具体的场景描述:"角色走到障碍物边缘时,中心点还没碰到,但视觉上已经穿模,请把判定半径从 0.5 调到 1.2 并考虑障碍物尺寸"。模型能听懂参数调整,但听不懂玄学表述。
5.2 模型返修话术
返修话术是这次测试里我总结的最大心得。同样遇到 bug,怎么跟模型沟通,直接决定返修效率。
先说反面案例。很多人反馈"不好使""有 bug""你写得不对",这种信息模型很难定位。我看到最有效的返修格式是:现象 + 报错原文 + 期望行为 + 修改范围。比如:
页面运行时控制台报错:THREE.Geometry is not a constructor 期望行为:游戏正常加载,障碍物可见 请检查所有 THREE.Geometry 相关调用,改为 BufferGeometry 的写法,输出修改后的完整文件。这里面"输出修改后的完整文件"很重要。我在测试中发现,如果只让模型"改一下",它经常只返回一个片段,或者用省略号跳过无关代码,结果你贴回去还是跑不起来。明确要求输出完整文件,能省掉大量来回确认的时间。
还有一种技巧是分段贴代码。当 bug 定位到具体函数时,把那个函数前后 30 行贴给模型,比让它读整个文件更精准。模型上下文窗口有限,代码越长,注意力越分散。局部贴代码,相当于帮它划了重点,修改质量明显更高。
5.3 部署与运行排查实录
最后录一段我实测过程中的排查记录,给第一次用 Three.js 跑 AI 生成代码的朋友参考。
启动本地服务我用的是最简单的命令:
python3 -m http.server 8080注意不要直接用 file:// 协议打开 HTML。Three.js 的 ES Module 加载和本地文件读取有跨域限制,直接双击打开会因为 CORS 报错,页面一片空白。这个坑我见过太多次了。
遇到页面白屏,第一步永远是按 F12 打开控制台看报错,不要自己瞎猜。常见几类错误:
Failed to resolve module specifier "three":importmap 没写或写错,检查<script type="importmap">里的 CDN 地址THREE.PointerLockControls is not a constructor:引入路径不对,确认是从three/examples/jsm/controls/路径引入的404:CDN 路径写错,去 npm 镜像站确认文件是否存在
排查完这几类问题,剩下的基本就能跑了。如果控制台没有任何报错但页面黑屏,大概率是相机或灯光问题,检查相机位置和光照参数,看场景里是否有东西被遮挡。
结尾:几条实在话
这次实测做下来,我的核心感受是:单文件、实时反馈、有视觉验证的 3D 小游戏任务,已经可以放心交给这三个模型。你把需求写得越细,返修就越少;你把运行环境锁得越死,首轮通过率就越高。选型参考上,我个人的排序是:GLM5.3 适合追求效率、返修沟通要快的场景;DeepSeek V4 Pro 适合需要长期维护、代码要被反复阅读的场景;Step 5 Preview 适合任务复杂度更高、多轮返修后仍有稳定输出的场景。最后再分享一个经验:不管用哪个模型,固定 Three.js 版本、锁住依赖、把需求清单写全,永远比换模型更重要。模型只是写代码的人,工程把控还是得自己来。