Vibe Coding 做了 100 款浏览器游戏后,我搭了一套自动化质量审计流程

发布时间:2026/7/19 13:16:55
Vibe Coding 做了 100 款浏览器游戏后,我搭了一套自动化质量审计流程 本文是这个开源项目的第三篇复盘不再单独介绍某款游戏而是讨论一个更实际的问题AI 可以很快写出能运行的游戏但我怎样确认它真的运行完好开源项目GitHub - wangzifan396-wzf/mini-browser-games: 100 zero-dependency, single-file HTML5 browser games | 100 款零依赖浏览器小游戏支持桌面/触屏、离线运行与质量分级 · GitHub前两篇我用 Vibe Coding 做了 100 款浏览器游戏并把它们全部开源了100 款浏览器游戏里我最推荐这 8 款两款旗舰与 Vibe Coding 质量复盘做完 100 款游戏以后我遇到的最大问题已经不是AI 能不能写出来而是我凭什么相信它真的能玩。一个页面成功打开和一款游戏通过验收中间隔着很远按钮可能只在桌面端能点触屏拖拽可能没有释放存档导入可能让等级越界物理物体可能在第一帧自己倒塌胜利结算也可能在某个分支永远不触发。更麻烦的是这些问题往往不会以语法错误的形式出现。代码可以合法运行页面也可以看起来正常但玩家走到某一步时状态已经错了。所以当项目从100 个原型进入质量阶段后我给它补了一套自动化审计与专项回归流程。现在每一轮重要更新都要同时经过脚本语法、真实浏览器操作、桌面/手机布局、存档迁移、状态结算和全仓页面检查。图 1100 款浏览器游戏只是起点后续工作逐渐从继续生成转向持续验收。能运行为什么不是一个可靠的验收标准Vibe Coding 最容易让人产生满足感的时刻是页面第一次动起来的时候。但从质量角度看这只能证明浏览器成功解析了代码。下面这些问题依然可能存在页面加载正常但第一次真实操作没有反应鼠标可以玩触屏事件没有覆盖首屏没有溢出打开弹窗或进入后期内容后才溢出新存档工作正常旧版本玩家升级后数据丢失胜利流程能走通失败、重试、最终关返回大厅却会卡死单个关卡正常连续加载十几关后监听器或定时器重复注册系统数量很多但它们没有构成可重复游玩的闭环。前六项可以通过工程手段提高发现概率最后一项仍然需要真实试玩和人的判断。这也是我现在对自动化测试的定位它不能证明游戏好玩但能阻止大量不该交给玩家发现的问题。我把质量检查分成两层目前项目使用两层检查它们解决的问题不同。第一层100款游戏的全仓冒烟审计第一层不深入玩某一款游戏而是快速检查全部 HTML 页面。审计脚本会启动本地静态服务器用 Playwright 分别打开桌面和手机视口。当前固定视口是const viewports [ { id: desktop, width: 1440, height: 900 }, { id: mobile, width: 390, height: 844 }, ];每个页面至少检查HTTP 状态和加载超时pageerrorJavaScript 异常浏览器控制台错误是否包含 viewport页面是否产生横向溢出Canvas 和主要交互控件是否真实可见能否找到开始按钮并进入游戏状态。横向溢出的判断本身很简单horizontalOverflow: document.documentElement.scrollWidth document.documentElement.clientWidth 4但它放到 100 个页面、两个视口上执行就能快速发现人工很容易漏掉的响应式问题。截至 2026 年 7 月 18 日最新一轮结果是{ pages: 200, loadFailures: 0, javascriptFailures: 0, consoleFailures: 0, overflows: 0, missingViewport: 0, weakPages: 17 }这里的weakPages不是错误而是首屏文字很少且暂时没有可见 Canvas的启发式候选列表。它提醒我继续人工检查但不会直接把游戏判为失败。第二层核心游戏的专项深度回归全仓审计只能证明页面基础状态健康不能证明一个复杂游戏真的完成了关键流程。因此每次把 A/A 作品升级到 S 级时我会再写一个只针对这款游戏的专项测试。它不只点击开始而是检查玩法独有的状态。例如专项回归会覆盖真实拖拽、滑动、键盘或卡牌点击关卡数量、锁定关系和首领数据胜利、失败、重试、下一关和终章返回三星、分数、奖励和永久成长老存档迁移、异常字段清洗和跨设备存档码桌面与手机的弹窗、滚动区和主操作按钮。测试必须模拟玩家操作而不只是调用内部函数这是我踩过最重要的坑之一。如果测试只调用launchProjectile()它只能证明这个函数没有抛错却不能证明玩家真的能通过鼠标或手指触发它。输入坐标换算、Pointer Capture、拖拽阈值、静态物体释放都可能出问题。例如物理类游戏的专项测试会真实执行鼠标轨迹await page.mouse.move(pouch.x, pouch.y); await page.mouse.down(); await page.mouse.move(pull.x, pull.y, { steps: 8 }); await page.mouse.up();随后再检查弹丸是否真正变成动态物体、质量是否为有限值、速度是否大于最低阈值、发射次数是否增加。图 2物理游戏回归不是检查按钮存在而是真实执行拖拽、释放并验证弹丸状态。这种测试曾经抓到过一个很隐蔽的问题物体创建时直接设为静态释放后保留了不正确的质量与惯性。页面、瞄准线和按钮全部正常但弹丸就是发不出去。这类故障仅靠打开页面看一眼几乎发现不了。存档测试比我最初预想的重要当游戏只有一局时刷新页面重新开始并不严重。但当项目开始加入章节、长期成长、实验室、道场和里程碑后存档就变成了玩法的一部分。我的存档回归现在至少包含四项新版本可以读取旧版本的核心数据导出后再导入关键字段保持一致负数、超大等级、非法关卡等异常字段会被限制长流程游戏能够恢复最近一次安全断点。导入存档不能简单地把 JSON 覆盖到当前对象上需要逐字段清洗function cleanInteger(value, min, max) { const number Number(value); if (!Number.isFinite(number)) return min; return Math.max(min, Math.min(max, Math.floor(number))); }AI写代码之后我会让它重新站到测试者的位置同一轮 Vibe Coding 里我会刻意把实现和审查分开。实现阶段关注的是系统怎样接进去数据怎样流动界面怎样呈现。审查阶段则重新从零提问首次进入会发生什么玩家中途刷新会发生什么最后一关和普通关是否走同一条结算路径旧存档缺少新字段时会发生什么手机端弹窗内容超过一屏时按钮还能不能触达一个挑战条件到底记录的是整局还是被每次操作重置这种角色切换很重要。AI 很擅长沿着刚才的实现思路继续补代码也因此容易默认原来的结构是对的。重新建立验收条件比继续提示再优化一下有效得多。我的发布前检查清单现在一个重要更新准备提交前我会按下面的顺序检查。代码层内联脚本能被new Function()解析独立脚本通过node --checkgit diff --check没有空白和补丁错误只提交本轮相关文件不覆盖其他未提交修改。游戏层首次开始和真实操作有效胜利、失败、重试和终章有效关卡与首领初始化不会自毁成长奖励、解锁与挑战条件能够持久化音效关闭后不会继续创建声音。存档层旧版迁移新版导出与导入异常字段清洗长流程安全断点完成或失败后正确清除断点。设备层1440×900 桌面视口390×844 触屏视口无页面级横向溢出弹窗可滚动主要按钮始终可触达Canvas 实际绘制不是空白画布。仓库层专项回归通过100 款游戏的 200 页面全仓审计通过README、质量评级和更新记录与代码一致提交后本地HEAD与远端分支一致。自动化仍然不能回答好不好玩这套流程能证明很多事情但它不能证明一款游戏值得玩十小时。脚本可以计算关卡数量不能判断关卡是否只是换了数值可以确认成长系统保存成功不能判断成长是否制造了新策略可以验证按钮能点不能判断点击反馈是否令人满足。因此项目里的 S/A/B/C/D 评级仍然来自内容体量、系统闭环、重复游玩性、操作反馈和人工体验的综合判断。自动化只是底线不是作品质量的上限。这也是我做完 100 款游戏后最大的变化我不再把AI 成功生成了代码当作完成而是把它当作一次可以开始测试的候选实现。如果你也在用 Vibe Coding 做网页版项目不一定要一开始就建立很复杂的测试框架。最值得优先做的是固定一个桌面视口和一个手机视口记录页面错误和控制台错误让测试执行一次真实核心操作保存一张桌面截图和一张手机截图给存档写一次导出、清空、导入回归每修一个真正出现过的故障就把它加入永久测试。测试不需要一次写完。它可以和项目一起成长把每次踩坑变成以后不会重复踩的规则。我的 100 款浏览器游戏、全仓审计脚本和专项回归都已经开源GitHub - wangzifan396-wzf/mini-browser-games: 100 zero-dependency, single-file HTML5 browser games | 100 款零依赖浏览器小游戏支持桌面/触屏、离线运行与质量分级 · GitHub