名称: “develop-web-game” 描述: “当Codex正在构建或迭代一个网页游戏(HTML/JS)并且需要一个可靠的开发+测试循环时使用:实现小更改,运行基于Playwright的测试脚本,带有短输入爆发和有意暂停,检查屏幕截图/文本,并通过render_game_to_text审查控制台错误。” 作者: openai
开发网页游戏
以小步骤构建游戏并验证每个更改。将每次迭代视为:实现 → 行动 → 暂停 → 观察 → 调整。
技能路径(设置一次)
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export WEB_GAME_CLIENT="$CODEX_HOME/skills/develop-web-game/scripts/web_game_playwright_client.js"
export WEB_GAME_ACTIONS="$CODEX_HOME/skills/develop-web-game/references/action_payloads.json"
用户范围的技能安装在$CODEX_HOME/skills下(默认:~/.codex/skills)。
工作流程
- 选择目标。 定义要实现的单个功能或行为。
- 小步实现。 做出最小的更改以推动游戏前进。
- 确保集成点。 提供单个画布和
window.render_game_to_text,以便测试循环可以读取状态。 - 添加
window.advanceTime(ms)。 强烈偏好确定性步进钩子,以便Playwright脚本可以可靠地推进帧;如果没有,自动化测试可能不稳定。 - 初始化progress.md。 如果
progress.md存在,首先读取并确认原始用户提示记录在顶部(前缀为Original prompt:)。还要注意先前代理留下的任何待办事项和建议。如果缺失,创建它并在附加更新前在顶部写入Original prompt: <prompt>。 - 验证Playwright可用性。 确保
playwright可用(本地依赖或全局安装)。如果不确定,首先检查npx。 - 运行Playwright测试脚本。 每次有意义的更改后必须运行
$WEB_GAME_CLIENT;除非必需,不要发明新客户端。 - 使用有效负载参考。 基于
$WEB_GAME_ACTIONS构建动作,以避免猜测键值。 - 检查状态。 每次爆发后捕获屏幕截图和文本状态。
- 检查屏幕截图。 打开最新屏幕截图,验证预期视觉效果,修复任何问题,并重新运行脚本。重复直到正确。
- 验证控制和状态(多步骤焦点)。 彻底测试所有重要交互。对于每个交互,思考完整的多步骤序列(原因 → 中间状态 → 结果),并验证整个链端到端工作。确认
render_game_to_text反映屏幕上显示的相同状态。如果有任何问题,修复并重新运行。 重要交互的示例:移动、跳跃、射击/攻击、交互/使用、菜单中的选择/确认/取消、暂停/恢复、重启,以及请求定义的任何特殊能力或解谜动作。多步骤示例:射击敌人应减少其生命值;当生命值达到0时应消失并更新分数;收集钥匙应解锁门并允许关卡进展。 - 检查错误。 审查控制台错误,并在继续之前修复第一个新问题。
- 在场景之间重置。 验证不同功能时避免跨测试状态。
- 用小增量迭代。 一次更改一个变量(帧、输入、计时、位置),然后重复步骤7-13直到稳定。
示例命令(需要动作):
node "$WEB_GAME_CLIENT" --url http://localhost:5173 --actions-file "$WEB_GAME_ACTIONS" --click-selector "#start-btn" --iterations 3 --pause-ms 250
示例动作(内联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运行中的最新屏幕截图。
- 最新的
render_game_to_textJSON输出。 - 控制台错误日志(在继续之前修复第一个新错误)。 您必须在运行Playwright脚本后实际打开并视觉检查最新屏幕截图,而不仅仅是生成它们。确保屏幕上应可见的所有内容实际可见。超越开始屏幕,捕获涵盖所有新添加功能的游戏截图。将屏幕截图视为真相来源;如果某物缺失,则在构建中缺失。如果怀疑无头/WebGL捕获问题,以头模式重新运行Playwright脚本并重新检查。修复并重新运行在紧密循环中,直到屏幕截图和文本状态看起来正确。一旦修复被验证,重新测试所有重要交互和控件,确认它们工作,并确保您的更改没有引入回归。如果引入了,修复它们并重新运行所有内容在循环中,直到交互、文本状态和控件都按预期工作。在测试控件时彻底;损坏的游戏不可接受。
核心游戏指南
画布 + 布局
- 偏好单个画布在窗口中居中。
视觉效果
- 保持屏幕文本最小化;在开始/菜单屏幕上显示控件,而不是在游戏过程中叠加。
- 除非设计需要,避免过于黑暗的场景。使关键元素易于看见。
- 在画布本身上绘制背景,而不是依赖CSS背景。
文本状态输出(render_game_to_text)
暴露一个window.render_game_to_text函数,返回一个简洁的JSON字符串,表示当前游戏状态。文本应包含足够信息以在没有视觉效果的情况下玩游戏。
最小模式:
function renderGameToText() {
const payload = {
mode: state.mode,
player: { x: state.player.x, y: state.player.y, r: state.player.r },
entities: state.entities.map((e) => ({ x: e.x, y: e.y, r: e.r })),
score: state.score,
};
return JSON.stringify(payload);
}
window.render_game_to_text = renderGameToText;
保持有效负载简洁,并偏向于屏幕/交互元素。偏好当前、可见的实体而不是完整历史。 包括清晰的坐标系说明(原点和轴方向),并编码所有玩家相关状态:玩家位置/速度、活动障碍物/敌人、可收集物、计时器/冷却时间、分数,以及任何做出正确决策所需模式/状态标志。避免大历史;仅包括当前相关和可见的内容。
时间步进钩子
提供确定性时间步进钩子,以便Playwright客户端可以以受控增量推进游戏。暴露window.advanceTime(ms)(或转发到您的游戏更新循环的薄包装),并让游戏循环在存在时使用它。
Playwright测试脚本在自动化测试期间使用此钩子以确定性步进帧。
最小模式:
window.advanceTime = (ms) => {
const steps = Math.max(1, Math.round(ms / (1000 / 60)));
for (let i = 0; i < steps; i++) update(1 / 60);
render();
};
全屏切换
- 使用单个键(偏好
f)切换全屏开/关。 - 允许
Esc退出全屏。 - 当全屏切换时,调整画布/渲染大小,以便视觉效果和输入映射保持正确。
进度跟踪
如果不存在,创建progress.md文件,并附加待办事项、笔记、陷阱和未完成事项,以便另一个代理可以无缝接续。
如果progress.md文件已存在,首先读取它,包括顶部的原始用户提示(您可能正在继续另一个代理的工作)。不要覆盖原始提示;保留它。
每次有意义的块工作后更新progress.md(功能添加、错误发现、测试运行或决策做出)。
在工作结束时,在progress.md中为下一个代理留下待办事项和建议。
Playwright先决条件
- 如果项目已有,偏好本地
playwright依赖。 - 如果不确定Playwright是否可用,检查
npx:command -v npx >/dev/null 2>&1 - 如果
npx缺失,安装Node/npm,然后全局安装Playwright:npm install -g @playwright/mcp@latest - 除非明确要求,不要切换到
@playwright/test;坚持使用客户端脚本。
脚本
$WEB_GAME_CLIENT(安装默认:$CODEX_HOME/skills/develop-web-game/scripts/web_game_playwright_client.js) — 基于Playwright的动作循环,具有虚拟时间步进、屏幕截图捕获和控制台错误缓冲。您必须通过--actions-file、--actions-json或--click传递动作爆发。
参考
$WEB_GAME_ACTIONS(安装默认:$CODEX_HOME/skills/develop-web-game/references/action_payloads.json) — 示例动作有效负载(键盘 + 鼠标,每帧捕获)。使用这些来构建您的爆发。