AI 写代码有个尴尬的毛病:写得快,改得慢。
你说”帮我做一个贪吃蛇”,它 30 秒给你一个完整的 HTML 文件。你打开一看,蛇不动。你告诉它”蛇不动”,它修了蛇,键盘坏了。你再让它修键盘,蛇又不吃了。
这种”打地鼠式”的开发体验,根子不在 AI 笨。根子在于 AI 不会自己测试自己写的东西。
OpenAI 的 develop-web-game Skill 就是冲这个来的。它不是教你写游戏,是给 AI 装了一套”写完立刻跑测试、截屏、查状态、修 bug”的自动化肌肉记忆。看完这个 Skill 的设计,我最大的感受是:这比很多人类开发者的工作流都严谨。
工作流拆解
develop-web-game 的核心是一个 14 步迭代循环,每一步都精确到”改一行代码就跑一次测试”的粒度。
先把这 14 步拆开看看:
-
Step 1-3(定方向):定目标、最小改动、集成点检查 -
Step 4(核心技术): window.advanceTime(ms)确定性时间步进钩子 -
Step 5-6(环境准备):progress.md 进度追踪、Playwright 可用性检查 -
Step 7-10(执行验证):运行测试脚本、构建 action payload、截图+读状态、肉眼检查截图 -
Step 11-13(质量闭环):全交互链测试、控制台查错、场景间重置 -
Step 14(迭代):单变量小增量调整,回到 Step 7
第一步,定目标。不是”做一个完整的游戏”,而是”让蛇能向左移动”。第二步,最小改动。只写足够推进目标的那几行代码,不贪多。第三步,集成点检查。游戏必须暴露一个 <canvas> 和 window.render_game_to_text() 函数,让测试脚本能读取游戏状态。
第四步是整件事的精髓:window.advanceTime(ms)。这是一个确定性时间步进钩子。什么意思?正常的游戏循环依赖浏览器的 requestAnimationFrame,帧率不稳定、机器负载影响时序。而 advanceTime 让 Playwright 客户端可以精确控制游戏内的时间流速,每一帧的输入输出完全可复现。

第五步是进度追踪。每个 Agent 会话开始前,先读 progress.md,确认原需求、看上一个 Agent 留下的 TODO。如果没有这个文件就新建,把用户原始 Prompt 记在文件顶部。这一步解决了一个很现实的问题:AI 会话有长度限制,多轮开发很容易”忘本”。
第六步,环境检查。确认 Playwright 可用,不行就装。第七步,运行测试脚本。每次改完代码后,必须跑 $WEB_GAME_CLIENT,这是强制步骤,不许自己发明测试方式。第八步,用预设的 action payload 构建输入序列,比如连续 3 帧按住左键、6 帧松开、再按空格跳跃。
典型的测试命令长这样:
node "$WEB_GAME_CLIENT" --url http://localhost:5173 \
--actions-file "$WEB_GAME_ACTIONS" \
--click-selector "#start-btn" --iterations 3 --pause-ms 250
Action payload 用 JSON 定义每一步的按键和持续帧数:
{
"steps": [
{ "buttons": ["left_mouse_button"], "frames": 2, "mouse_x": 120, "mouse_y": 80 },
{ "buttons": [], "frames": 6 },
{ "buttons": ["right"], "frames": 8 },
{ "buttons": ["space"], "frames": 4 }
]
}
这种帧级别的精确控制是整件事能跑通的关键。
接下来四步是测试执行的核心:
-
截图 + 读状态。Playwright 在每段输入 burst 后自动截图、调用 render_game_to_text获取 JSON 状态。 -
肉眼检查截图。这一步我特别喜欢:不是看一眼模糊的缩略图就过,而是仔细验证画面上的每个元素位置、颜色、是否存在。 -
多步骤交互验证。移动、跳跃、攻击、收集道具、打开菜单、暂停,每个高级交互都要走完整的”原因→中间态→结果”链式测试。
12-14 步是质量闭环:查控制台错误(修完第一个再往后看),测试间重置状态(避免交叉污染),小增量迭代(每次只改一个变量,回到 Step 7 重跑)。
架构解析
这个 Skill 的架构分三层:指令层、执行层、集成层。
指令层是 SKILL.md 本身。它把所有规则写在一个文件里:
-
14 步工作流(从定目标到小增量迭代的完整循环) -
核心约束(单 canvas、render_game_to_text、advanceTime 三个硬性接口) -
测试检查清单(涵盖移动/跳跃/碰撞/菜单/得分等关键交互) -
游戏设计规范(Canvas 居中、亮色调、F 键全屏切换)
这种”单文件+环境变量”的设计让整个 Skill 极其轻量,安装就是一行 npx skills add。

执行层是 web_game_playwright_client.js,一个基于 Playwright 的动作循环脚本。它支持三种输入:
-
动作文件( --actions-file),适合预设的完整测试用例 -
内联 JSON( --actions-json),适合快速临时测试 -
单次点击( --click-selector),适合调试单个按钮
每次执行后输出三类产物:截图(PNG)、文本状态(JSON)、控制台错误日志。关键参数:--iterations 控制循环次数,--pause-ms 设定操作间暂停时间,--url 指定目标页面地址。
集成层是游戏代码本身。这层有两个硬性接口要求。window.render_game_to_text 返回一个 JSON 字符串,包含当前模式、玩家坐标、实体列表、分数等核心状态。最小实现长这样:
function renderGameToText() {
const payload = {
mode: state.mode,
player: { x: state.player.x, y: state.player.y },
entities: state.entities.map(e => ({ x: e.x, y: e.y })),
score: state.score
};
return JSON.stringify(payload);
}
window.render_game_to_text = renderGameToText;
window.advanceTime(ms) 将游戏更新分成确定性的时间步长:
window.advanceTime = (ms) => {
const steps = Math.max(1, Math.round(ms / (1000 / 60)));
for (let i = 0; i < steps; i++) update(1 / 60);
render();
};
这让 Playwright 客户端完全掌控帧推进节奏,同一组输入永远产生相同的游戏状态。
这种”强接口约束”的做法,本质上是在 AI Agent 和游戏代码之间建立了一套契约。只要游戏实现了这两个函数,测试脚本就能无缝工作,不管游戏是横版跳跃、贪吃蛇、俄罗斯方块还是塔防。架构上最大的亮点是解耦了”开发”和”测试”两个环节。你不用给每个游戏类型写专门的测试脚本,一个 Playwright 客户端通吃。
但这里有代价。这两个函数不是游戏的天然组件,是你必须主动加的。对习惯了”写完 html 直接打开浏览器看”的开发者来说,多了一层心智负担。另一个隐形成本是 Playwright 本身的安装和兼容问题,特别是在无头模式下 WebGL 渲染可能异常,Skill 文档也提到了必要时要切 headed 模式排查。
使用场景
构建浏览器平台游戏。比如做一个横版跳跃,你可以让 AI 先写玩家站立和移动,跑测试验证角色能在画面左右移动。再逐层叠加跳跃、重力、平台碰撞、敌人 AI、得分系统。每一层加完立刻跑完整交互测试。
调试碰撞逻辑。这是游戏开发最容易出 bug 的环节。传统做法是手动操作角色靠近碰撞体、肉眼判断是否穿模。用 develop-web-game,你可以写一组精确的坐标动作序列,让 Playwright 逐帧执行,截图对比。Sprite 重叠了?坐标偏移了?render_game_to_text 的 JSON 输出里一目了然。
跨会话接手半成品。如果你写了一半的游戏被另一个 Agent 或另一个用户接手,progress.md 里记录了一切:
-
原始需求(文件顶部,不会被覆盖) -
已完成功能列表 -
已知 bug 和修复状态 -
待办事项和下一步建议
新 Agent 读一遍文件就知道从哪开始,不会推倒重来。这个场景特别适合团队协作或者长周期游戏项目。
不适合的场景也很明确。需要后端逻辑的联机游戏不适合,这个 Skill 只管前端 HTML/JS。依赖复杂物理引擎的游戏也勉强,因为确定性时间步进和物理引擎的碰撞检测之间可能有微妙冲突。纯视觉效果项目更不适合,这套流程的重心在逻辑验证,不是视觉打磨。
洞察与反思
我一开始觉得这 14 步有点过度设计。做个贪吃蛇而已,需要这么严谨?
但我在脑子里跑了一遍”不做这些步骤”的后果。没有 render_game_to_text,你永远不知道蛇有没有吃到那个苹果,只能靠截图猜。没有 advanceTime,帧率波动导致同样的按键序列产生不同结果,AI 修了半天发现是”测不稳定”。没有 progress.md,换了新会话后 AI 已经忘了用户要做水果忍者还是贪吃蛇。

这些步骤不是在增加复杂度,是在补 AI 原生开发的缺口。AI 写代码的最大短板不是生成质量,是”看不见自己的输出效果”。develop-web-game 本质上给了 AI 一双眼睛。
还有一层设计哲学值得聊。传统游戏开发里,测试是独立环节。你写代码,你测试,这中间有时间差。develop-web-game 把这个时间差压缩到零:每改一行就跑一次测试。这不是 TDD,比 TDD 更狠。TDD 是先写测试再写代码,这里是写代码的同时测试就已经在跑。
局限也有。目前这个 Skill 和 OpenAI Codex 绑定较紧,虽然 SKILL.md 本身是通用格式,其他 AI 助手也能用,但 Playwright 的安装和配置环节对新手不够友好。另外,render_game_to_text 需要开发者主动实现,对初学者来说等于多了一个”先学接口规范”的门槛。
对想入门的开发者,我建议从最简单的游戏开始。贪吃蛇就行。先把两个函数加好,让 AI 写玩家的基础移动。跑一次测试,看截图是不是你要的效果。一旦你习惯了”改代码、跑测试、看截图”这个循环,你会发现自己回不去了。
Skill 附带了一份值得贴在显示器旁边的测试清单:
-
基础操作:移动、跳跃、射击/攻击、确认/选择 -
胜负转换:通关/失败的状态切换是否正确 -
数据变化:分数增减、血量变化、资源消耗 -
边界条件:碰撞检测、墙壁限制、屏幕边缘行为 -
菜单流程:暂停/继续、重启、全屏切换 -
特殊机制:道具效果、连击系统、定时器触发
这份清单的精髓是”多步骤验证”。不是测”跳跃有没有动画”,而是测”按下空格→角色上升→到达最高点→下落→落地→回到空闲状态”这一整条链路。
资源地址
| 资源 | 地址 |
|---|---|
| 官网 | https://smithery.ai/skills/openai/develop-web-game |
| GitHub | https://github.com/openai/skills/tree/main/skills/.curated/develop-web-game |
| 安装命令 | npx skills add https://github.com/openai/skills --skill develop-web-game |
总结
develop-web-game 解决了一个 AI 编程工具长期忽略的问题:怎么让 AI 知道自己写的代码对不对。
它用一套轻量但严格的 Playwright 测试循环,把不确定的”你试试看对不对”变成了确定的”跑完 14 步就知道了”。这套工作流不仅适用于游戏开发,里面的”最小改动 + 自动验证 + 状态输出”模式,完全可以迁移到任何需要 UI 交互的前端项目。
它的最大局限:目前只覆盖纯前端游戏。但这不是缺陷,是定位。一个好的工具知道自己不做什么,比什么都想做更重要。
这种 Skill 代表了 AI 编程工具的一个重要方向:不是让 AI 变得更聪明,而是给它一个结构化的验证环境。聪明需要用对地方才有价值。
