phaser-playtest
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePhaser 4 Playtesting (Runtime Verification)
Phaser 4 游戏测试(运行时验证)
npx tsc --noEmit| Failure | What the player sees | What TypeScript says |
|---|---|---|
| Asset path typo | Invisible sprites | Nothing — it's a string |
Scene missing from | Black screen | Nothing |
| Half-built scene | Nothing |
| Depth/alpha/camera-scroll mistake | Blank canvas | Nothing |
| Physics body never added | Player falls through floor | Nothing |
| Uncapped emitter | 12 fps | Nothing |
Runtime verification is not optional. Run the harness after any change that touches
scene lifecycle, asset loading, physics, or rendering — before telling the user it works.
npx tsc --noEmit| 故障类型 | 玩家看到的现象 | TypeScript的反馈 |
|---|---|---|
| 资源路径拼写错误 | 精灵不可见 | 无提示——因为这是字符串类型 |
场景未添加到 | 黑屏 | 无提示 |
| 场景加载不完整 | 无提示 |
| 深度/透明度/相机滚动设置错误 | 空白画布 | 无提示 |
| 未添加物理体 | 玩家穿过地面掉落 | 无提示 |
| 粒子发射器未限制数量 | 帧率仅12fps | 无提示 |
运行时验证必不可少。任何涉及场景生命周期、资源加载、物理系统或渲染的代码修改后,都要先运行此测试工具,再告知用户功能正常。
Run It
运行方式
bash
node "${CLAUDE_PLUGIN_ROOT}/skills/phaser-playtest/scripts/playtest.mjs" --project .The harness starts the dev server itself, drives headless Chromium, and shuts the
server down again. No config, no test files required.
Requires Playwright in the project (once):
bash
npm install -D playwright && npx playwright install chromiumbash
node "${CLAUDE_PLUGIN_ROOT}/skills/phaser-playtest/scripts/playtest.mjs" --project .该测试工具会自行启动开发服务器,驱动无头Chromium浏览器,测试完成后自动关闭服务器。无需配置,也无需编写测试文件。
项目中需提前安装Playwright(仅需一次):
bash
npm install -D playwright && npx playwright install chromiumWhat it checks
检查内容
- Page loads — HTTP status of the document
- Canvas created — a sized exists (fails ⇒ Phaser never booted)
<canvas> - Phaser instance reachable — finds the on
Phaser.Gamewindow - Game booted —
isBooted === true - Active scenes — which scenes run, and how many display objects each holds
- Scenes render content — warns on a scene with an empty display list
- Frame rate — median and 5th-percentile FPS sampled over real frames
- Canvas renders content — pixel analysis; catches the black screen
- No uncaught exceptions — with stack
pageerror - No console errors
- All assets load — including files the dev server masks as
200 text/html
Exit code = pass, = check failures, = harness error. Writes
plus PNG screenshots.
012.playtest/report.json- 页面加载情况——文档的HTTP状态码
- Canvas是否创建——是否存在已设置尺寸的元素(失败则表示Phaser从未启动)
<canvas> - Phaser实例是否可访问——在对象上找到
window实例Phaser.Game - 游戏是否启动完成——
isBooted === true - 活跃场景——运行中的场景有哪些,每个场景包含多少显示对象
- 场景是否渲染内容——若场景的显示列表为空则发出警告
- 帧率——采样真实帧数据得到的中位数和第5百分位FPS
- Canvas是否渲染内容——像素分析,可排查黑屏问题
- 是否存在未捕获异常——带有调用栈的
pageerror - 控制台是否有错误
- 所有资源是否加载成功——包括被开发服务器伪装成的文件
200 text/html
退出码表示测试通过,表示检查项失败,表示测试工具自身出错。测试完成后会生成文件及PNG截图。
012.playtest/report.jsonOptions
可选参数
| Flag | Purpose |
|---|---|
| Project root (default: cwd) |
| Test an already-running server instead of starting one |
| |
| Drive a scripted play session (see below) |
| Mobile viewport, DPR, touch, and UA |
| Wait before probing (default 3000; raise for slow preloads) |
| Treat console warnings as failures (CI) |
| Emit only JSON — use when parsing results |
| Show the browser |
| 参数 | 用途 |
|---|---|
| 项目根目录(默认:当前工作目录) |
| 测试已运行的服务器,而非启动新服务器 |
| |
| 执行脚本化的游戏测试流程(详见下文) |
| 模拟移动设备视口、设备像素比、触摸事件及用户代理 |
| 等待时间(默认3000毫秒;若预加载较慢可延长) |
| 将控制台警告视为测试失败(适用于CI环境) |
| 仅输出JSON格式结果——适用于解析测试结果的场景 |
| 显示浏览器窗口 |
Make the Game Testable (one line)
让游戏可测试(仅需一行代码)
The deep checks need the game instance. Bundled games keep it in module scope, so
expose it in dev builds only:
typescript
const game = new Phaser.Game(config);
if (import.meta.env.DEV) (window as any).__PHASER_GAME__ = game;
export default game;Without it the harness still catches black screens, exceptions, and 404s, but skips
scene, FPS, and state assertions — and says so. Add the line; it costs nothing in
production. See for deterministic-testing hooks
(seeded RNG, time control, state injection).
references/instrumenting-games.md深度检查需要获取游戏实例。打包后的游戏会将实例保存在模块作用域中,因此只需在开发构建中暴露它:
typescript
const game = new Phaser.Game(config);
if (import.meta.env.DEV) (window as any).__PHASER_GAME__ = game;
export default game;如果不添加此行,测试工具仍可检测黑屏、异常和404错误,但会跳过场景、帧率和状态断言——并会提示相关信息。添加此行不会对生产环境造成任何影响。如需确定性测试钩子(种子化随机数生成器、时间控制、状态注入),可参考。
references/instrumenting-games.mdScenario Scripts
场景脚本
A scenario drives input and asserts on live game state. is bound to the
running instance inside every .
gameexpressionjavascript
// playtest/combat.mjs
export default [
{ name: 'reaches gameplay', action: 'expect',
expect: { expression: `game.scene.isActive('GameScene')`, equals: true } },
{ name: 'walk right', action: 'key', key: 'ArrowRight', duration: 600 },
{ name: 'player advanced', action: 'expect',
expect: { expression: `game.scene.getScene('GameScene').player.x > 400`, equals: true } },
{ name: 'attack lands', action: 'press', key: 'Space',
expect: { expression: `game.registry.get('enemyHp')`, atMost: 90 } },
{ name: 'after-combat', action: 'screenshot' },
{ name: 'holds frame rate', action: 'expect',
expect: { expression: `game.loop.actualFps`, atLeast: 55 } },
];Actions: (), (, ), (), (,
canvas-relative), (), .
Assertions: (deep), , , or bare for truthy.
waitmskeykeydurationpresskeyclickxyscreenshotnameexpectequalsatLeastatMostexpressionFull reference: .
Worked example: .
references/playtest-harness.mdexamples/scenario.example.mjs场景脚本可驱动输入操作并对实时游戏状态进行断言。在每个中,会绑定到当前运行的游戏实例。
expressiongamejavascript
// playtest/combat.mjs
export default [
{ name: '进入游戏玩法场景', action: 'expect',
expect: { expression: `game.scene.isActive('GameScene')`, equals: true } },
{ name: '向右行走', action: 'key', key: 'ArrowRight', duration: 600 },
{ name: '玩家已前进', action: 'expect',
expect: { expression: `game.scene.getScene('GameScene').player.x > 400`, equals: true } },
{ name: '攻击命中', action: 'press', key: 'Space',
expect: { expression: `game.registry.get('enemyHp')`, atMost: 90 } },
{ name: '战斗结束后', action: 'screenshot' },
{ name: '帧率达标', action: 'expect',
expect: { expression: `game.loop.actualFps`, atLeast: 55 } },
];支持的操作:(等待毫秒数)、(按键,持续时间)、(按键)、(点击坐标、,基于Canvas相对位置)、(截图名称)、(断言)。
支持的断言:(深度相等)、(至少)、(至多),或直接使用判断是否为真值。
waitmskeykeydurationpresskeyclickxyscreenshotnameexpectequalsatLeastatMostexpression完整参考文档:。
示例:。
references/playtest-harness.mdexamples/scenario.example.mjsTurning a Plan into Tests
将需求转化为测试
Acceptance criteria from or the phaser-architect agent translate
directly into scenario steps. Write the scenario when the feature is specified,
not after it breaks:
/phaser-gdd| Acceptance criterion | Scenario assertion |
|---|---|
| "Player jumps 3 tiles high" | |
| "Enemy dies in 3 hits" | press attack ×3, then |
| "Score persists across scenes" | start GameOver, then |
| "Runs at 60fps with 50 enemies" | spawn via |
来自或phaser-architect agent的验收标准可直接转化为场景步骤。应在功能需求确定时编写场景脚本,而非在功能出现问题后:
/phaser-gdd| 验收标准 | 场景断言 |
|---|---|
| "玩家可跳跃3格高" | |
| "敌人受3次攻击后死亡" | 按下攻击键3次,然后断言 |
| "分数在场景切换时保留" | 进入游戏结束场景,然后断言 |
| "50个敌人时仍保持60fps" | 通过 |
Reading a Failure
故障排查
| Harness output | Root cause to check first |
|---|---|
| Scene threw in |
| Scene missing from |
| Objects off-camera, |
| |
| Path typo, or the asset is in |
| Uncapped particles, no object pooling, per-frame allocation. Use |
| Add the |
| 测试工具输出 | 首先排查的根本原因 |
|---|---|
| 场景在 |
| 场景未添加到 |
| 对象在相机视野外、 |
| |
| 路径拼写错误,或资源放在 |
| 粒子发射器未限制数量、未使用对象池、每帧都有内存分配。可使用 |
| 添加上文提到的 |
CI
CI集成
yaml
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx tsc --noEmit
- run: node scripts/playtest.mjs --project . --mode build --fail-on-warnCopy into the project's own so CI does not depend on the
plugin being installed.
playtest.mjsscripts/yaml
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx tsc --noEmit
- run: node scripts/playtest.mjs --project . --mode build --fail-on-warn将复制到项目自身的目录中,这样CI环境就无需依赖该插件的安装。
playtest.mjsscripts/Discipline
规范要求
- Run the harness before reporting a feature complete — not after the user reports a bug.
- A passing plus a failing playtest means the work is not done.
tsc - When it fails, read and the screenshots before editing code. Investigation-first applies here exactly as in
.playtest/report.json.phaser-debugger - Keep a scenario per major feature under ; they are regression tests.
playtest/
- 在报告功能完成之前运行测试工具——而非在用户报告bug之后。
- 检查通过但游戏测试失败,说明工作未完成。
tsc - 测试失败时,先查看和截图,再修改代码。这与
.playtest/report.json中的“先调查再修改”原则一致。phaser-debugger - 为每个主要功能在目录下保留一个场景脚本——它们可作为回归测试用例。
playtest/