AI Game Playtester
AI 驱动的自动化游戏测试执行器。启动游戏实例,模拟玩家行为,收集运行指标,输出结构化质量报告。
⚠️ Hard Rules
- 测试过程中严禁修改游戏源码 — Playtester 的职责是"发现问题"而非"修复问题"。所有发现的缺陷写入报告,由开发者或其他 Skill 决定是否修复
- 必须在隔离环境中运行 — 测试运行不得影响用户的开发环境。使用独立的预览实例或沙箱进程,不得占用用户正在使用的编辑器或预览端口
- 超时必须强制终止 — 每个测试用例有硬性超时(默认 60 秒),超时视为 FAIL 并记录,防止死循环或卡死导致测试永远挂起
- 截图/日志必须伴随结论 — 每条 PASS/FAIL 判定必须附带可追溯的证据(终端输出片段、错误日志行号、截图路径),禁止无证据标记 PASS
- 性能数据必须连续采样 — FPS、内存等性能指标必须以 ≥1Hz 频率连续采样至少 10 秒,禁止只取单点快照。单点快照无法反映卡顿和内存泄漏
- 测试报告必须机器可解析 — 同时输出 JSON(机器消费)和 Markdown(人类阅读)两种格式
触发条件
当用户说以下内容时触发本 Skill:
- "测试一下游戏" / "跑个冒烟测试"
- "检查有没有崩溃" / "验证关卡能不能通关"
- "跑回归测试" / "性能测试"
- "run playtest" / "smoke test" / "QA check"
不触发条件
以下情况应使用其他 Skill:
- 用户想修复发现的 bug → 直接编辑代码或使用开发 Skill
- 用户想生成新关卡 → 使用
ai-game-level-generator - 用户想导入/生成素材 → 使用
ai-game-asset-pipeline - 用户想编写单元测试代码 → 使用项目的测试框架
输入参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
test_suite |
string | smoke |
测试集:smoke(冒烟)/ regression(回归)/ performance(性能)/ full(全量) |
|
scene |
string | 主场景 | 要测试的场景/关卡路径 | |
timeout_seconds |
number | 60 |
单用例超时秒数 | |
report_dir |
string | .playtest/reports |
报告输出目录 | |
capture_screenshots |
boolean | true |
是否在关键节点截图 |
测试集定义
Smoke(冒烟测试)— 快速验证核心链路
| TC-ID | 用例名称 | 步骤 | 期望结果 | 超时 |
|---|---|---|---|---|
| SM-01 | 游戏启动 | 启动游戏进程 | 进程存活,无崩溃日志 | 15s |
| SM-02 | 主场景加载 | 等待主场景加载完成 | 场景根节点存在,无加载错误 | 30s |
| SM-03 | 基础渲染 | 检查首帧渲染 | FPS > 0,画面非全黑/全白 | 10s |
| SM-04 | 输入响应 | 模拟键盘/触摸输入 | 游戏对象产生位移或状态变化 | 15s |
| SM-05 | 无致命错误 | 扫描运行日志 | 无 ERROR/FATAL 级别日志 | 5s |
Regression(回归测试)— 验证已有功能未被破坏
| TC-ID | 用例名称 | 步骤 | 期望结果 | 超时 |
|---|---|---|---|---|
| RG-01 | 场景切换 | 遍历所有已注册场景 | 每个场景均能加载,无崩溃 | 120s |
| RG-02 | 碰撞检测 | 移动玩家撞向墙壁/地面 | 不穿模,不卡墙 | 30s |
| RG-03 | 音频播放 | 触发 BGM 和音效 | 音频播放器状态为 playing(非静音/非暂停) | 15s |
| RG-04 | UI 交互 | 点击所有可见按钮 | 按钮触发对应回调,无未处理异常 | 30s |
| RG-05 | 存档加载 | 保存后立即加载 | 玩家位置/状态与保存时一致 | 20s |
| RG-06 | 资源完整性 | 扫描所有引用资源 | 无 missing resource 警告 | 30s |
Performance(性能测试)— 采集运行时指标
| TC-ID | 指标 | 采样方式 | 通过阈值 | 告警阈值 |
|---|---|---|---|---|
| PF-01 | FPS | 连续 10 秒,1Hz 采样 | avg ≥ 30, min ≥ 15 | avg < 30 或 min < 15 |
| PF-02 | 内存 | 连续 30 秒,1Hz 采样 | 增长 < 10MB | 增长 ≥ 10MB(疑似泄漏) |
| PF-03 | 启动耗时 | 从进程启动到首帧 | < 5s | ≥ 5s |
| PF-04 | 场景切换耗时 | 从调用到加载完成 | < 2s | ≥ 2s |
| PF-05 | Draw Calls | 主场景稳态 | < 500 | ≥ 500 |
执行流程
步骤 0:前置检查
- 检查游戏项目是否存在:
- 扫描项目根目录,确认存在引擎配置文件或可运行的构建产物
- 若找不到任何可识别的游戏项目 → 报错并停止
- 检查构建产物是否就绪:
- Web 游戏:检查是否存在
index.html或类似入口文件 - 桌面游戏:检查是否存在可执行文件或引擎项目文件
- 不存在 → 提示用户先执行构建/导出
- Web 游戏:检查是否存在
- 创建报告输出目录:
{report_dir}/不存在时自动创建
步骤 1:启动测试环境
在隔离环境中启动游戏实例。根据项目类型选择启动方式:
Web 游戏:
启动本地 HTTP Server(选用未占用的端口,如 18080-18099)
→ 加载游戏页面(index.html)
→ 等待 window.onload 或引擎 ready 信号
→ 确认渲染帧数 > 0
桌面游戏:
启动导出的可执行文件 或 引擎的命令行运行模式
→ 捕获 stdout/stderr
→ 等待主场景初始化完成
启动失败判定:
- 进程在 15 秒内退出(exit code ≠ 0)→ FAIL,记录 stderr
- 进程启动但 30 秒内无渲染帧 → FAIL,记录日志
步骤 2:执行测试用例
按 test_suite 展开对应的测试集,逐条执行:
执行逻辑:
FOR EACH test_case IN test_suite:
1. 记录开始时间
2. 设置超时计时器(timeout_seconds)
3. 执行测试步骤(模拟输入 / 读取状态 / 检查日志)
4. 对比期望结果
5. 若 capture_screenshots == true → 在关键节点截图
6. 记录结果:PASS / FAIL / TIMEOUT / BLOCKED
7. 记录证据:日志片段 / 截图路径 / 具体数值
超时 → 标记 TIMEOUT,强制终止当前用例,继续下一条
输入模拟方式:
| 游戏平台 | 输入模拟方法 |
|---|---|
| Web 游戏 | JavaScript dispatchEvent(new KeyboardEvent(...)) / Puppeteer page.keyboard |
| 桌面游戏 | 引擎 CLI 命令行输入注入 / 操作系统级键鼠模拟 |
| 移动游戏 | 触摸事件模拟框架(如 Appium) |
状态检测方式:
| 检测项 | Web 游戏 | 桌面游戏 |
|---|---|---|
| 元素/节点存在 | document.querySelector() / Canvas 状态检查 |
引擎调试接口 / 进程状态查询 |
| FPS | requestAnimationFrame 计数 / performance.now() 差值 |
引擎性能 API / 外部帧率检测工具 |
| 内存 | performance.memory(Chrome 限定)/ performance.measureUserAgentSpecificMemory() |
操作系统进程内存查询(如 ps、tasklist) |
| 日志错误 | window.onerror / console.error 钩子 |
捕获 stdout/stderr,正则匹配 ERROR|FATAL|EXCEPTION |
| 音频状态 | HTMLAudioElement.paused == false / Web Audio API 状态 |
引擎音频 API / 系统音频流检测 |
步骤 3:采集性能数据
性能测试单独执行(不与功能测试混合,避免互相干扰):
1. 启动游戏到主场景稳态
2. 等待 3 秒使初始化完成
3. 开始连续采样(采样间隔 1 秒)
4. 采样 10-30 秒
5. 计算统计值:avg / min / max / p95 / stddev
6. 与阈值对比,输出判定
性能数据结构:
{
"tc_id": "PF-01",
"metric": "fps",
"samples": [58, 60, 59, 45, 60, 60, 58, 60, 30, 60],
"statistics": {
"avg": 55.0,
"min": 30,
"max": 60,
"p95": 60,
"stddev": 9.2
},
"threshold": { "avg_gte": 30, "min_gte": 15 },
"verdict": "PASS"
}
步骤 4:生成报告
在 report_dir 下同时输出两种格式的报告:
4.1 JSON 报告 — playtest-{timestamp}.json
{
"schema_version": "1.0",
"test_suite": "smoke",
"timestamp": "2026-05-07T17:30:00Z",
"environment": {
"engine": "your-engine-name",
"engine_version": "x.x",
"platform": "web",
"project_root": "/path/to/project"
},
"summary": {
"total": 5,
"pass": 4,
"fail": 0,
"timeout": 1,
"blocked": 0,
"pass_rate": "80%"
},
"results": [
{
"tc_id": "SM-01",
"name": "游戏启动",
"verdict": "PASS",
"duration_ms": 2340,
"evidence": "进程 PID 12345 正常启动,exit_code=null(仍在运行)"
},
{
"tc_id": "SM-04",
"name": "输入响应",
"verdict": "TIMEOUT",
"duration_ms": 60000,
"evidence": "模拟 KEY_RIGHT 后 60 秒内 Player.position.x 无变化,疑似输入未绑定"
}
],
"performance": [],
"screenshots": [
".playtest/reports/screenshots/SM-02_main_scene_loaded.png",
".playtest/reports/screenshots/SM-04_input_no_response.png"
]
}
4.2 Markdown 报告 — playtest-{timestamp}.md
# 🎮 Playtest 报告
> 测试时间: 2026-05-07 17:30 | 引擎: your-engine x.x | 测试集: Smoke
## 📊 总览
| 指标 | 值 |
|------|-----|
| 总用例 | 5 |
| ✅ PASS | 4 |
| ❌ FAIL | 0 |
| ⏱️ TIMEOUT | 1 |
| 通过率 | 80% |
## 📝 详细结果
| TC-ID | 用例 | 结果 | 耗时 | 证据 |
|-------|------|------|------|------|
| SM-01 | 游戏启动 | ✅ PASS | 2.3s | 进程正常启动 |
| SM-02 | 主场景加载 | ✅ PASS | 1.8s | 场景根节点存在 |
| SM-03 | 基础渲染 | ✅ PASS | 0.5s | FPS=58 |
| SM-04 | 输入响应 | ⏱️ TIMEOUT | 60s | 输入后无位移变化 |
| SM-05 | 无致命错误 | ✅ PASS | 0.2s | 日志无 ERROR |
## ⚠️ 需关注
- **SM-04 输入响应超时**: 模拟 KEY_RIGHT 后 Player 节点 position.x 无变化,
可能原因:输入按键未在项目的按键映射中注册,或游戏主循环未处理该输入事件。
步骤 5:清理测试环境
- 终止测试启动的所有子进程(HTTP Server、游戏进程)
- 释放占用的端口
- 保留报告和截图文件,不删除
完成标志
报告已写入 report_dir 且测试环境已清理后,输出:
<promise>DONE</promise>
错误处理
| 场景 | 处理方式 |
|---|---|
| 游戏构建产物不存在 | 停止执行,提示用户先构建/导出 |
| 测试端口被占用 | 自动选择下一个可用端口(范围 18080-18099) |
| 游戏启动后立即崩溃 | 记录 stderr 和 exit code,所有用例标记 BLOCKED |
| 截图功能不可用 | 降级为仅日志模式,报告中标注"截图不可用" |
| 测试进程残留(清理失败) | 记录 PID 到报告的 cleanup_warnings 字段,提醒用户手动清理 |
| 报告目录写入失败 | 回退到 stdout 输出 JSON 报告 |
与其他 Skill 的协作
ai-game-level-generator
├─ 生成关卡配置
└─ 输出 level_id
↓
ai-game-asset-pipeline
├─ 生成/导入素材
└─ 写入引擎资源目录
↓
开发者 / AI Agent
├─ 实现游戏逻辑
└─ 构建/导出游戏
↓
ai-game-playtester (本 Skill)
├─ 自动运行游戏
├─ 执行测试用例
├─ 采集性能数据
└─ 输出质量报告
↓
开发者
└─ 根据报告修复问题