mcpField
P
playproof

playproof

本地服务
github.com开发工具06 天前更新

关于 playproof

playproof 是面向开发者和编码 Agent 的浏览器游戏测试工具集。它借助虚拟时钟实现可重复的逐帧检查、脚本化游玩、崩溃检测、设备布局测试和性能测量。

主要功能

  1. 01确定性逐帧捕获与对比
  2. 02脚本化输入和分镜运行
  3. 03可重复的随机崩溃排查
  4. 04跨设备尺寸的布局检查
  5. 05帧节奏和性能指标
  6. 06基于场景的动作快照

适用场景

  1. 01逐帧检查动画改动
  2. 02根据记录步骤复现游戏崩溃
  3. 03检查手机和桌面屏幕布局
  4. 04在 CI 中运行动作与设备检查

MCP 相关

playproof 也可作为供调用工具的应用使用的 MCP 服务;其工具会直接返回图像供检查。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"emirhanozl-playproof": {
"command": "npx",
"args": [
"-y",
"playproof"
]
}
}
}
启动命令npx -y playproof

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmplayproof0.3.2

工具

6

收录的工具列表 · 更新于 5 天前

参数类型必填说明
fpsnumber否图集每秒的图块数(默认:适配约 24 个图块)
areastring否游戏区域的 CSS 选择器(默认值:最大的画布)
zoomstring否裁剪到运动区域("auto"),或按游戏区域的百分比指定 x,y,w,h
readystring否游戏加载完成后为 true 的 JavaScript 表达式
stepsstring否用 ";" 分隔步骤。步骤(用 ";" 或换行分隔,"#" 开头的行为注释行):wait <time> 等待一段时间(虚拟时间:即时且精确)tap <x,y>|@label 在游戏区域内轻触/点击("50%,80%" 或像素坐标 "120,300")press <x,y> <time> 长按 drag <x,y> <x,y> [time] 滑动/拖动(默认 300ms)key <Key> [time] 按键,例如 Space、ArrowLeft、a、Enter(默认按住 50ms)type <text> 输入文本 click <css selector> 点击 DOM 元素(菜单、HTML 按钮)shot [label] 为故事板拍摄截图 film <time> [fps] 在时间流逝期间捕获帧 until <js expression> [time] 推进时间,直到表达式为真(默认超时 5s)js <js expression> 在页面中执行 JavaScript 并记录结果 时间格式:500、500ms、1.5s。
devicestring否要模拟的设备:"iPhone 15"、"Pixel 8"、"desktop"(默认值)或 "390x844@3 mobile"
targetstring否游戏的 URL(例如 http://localhost:5173)、文件夹(./dist)或 HTML 文件。若 playproof.config.json 中已设置,则可选。
comparestring否用于比较的早期 frames 运行输出文件夹
waitForstring否开始前等待的 CSS 选择器
durationstring否录制时长,例如 800ms 或 1.5s(默认值 1s)
scenariostring否playproof.config.json 中场景的名称:提供步骤、时长、缩放和设备

详细介绍

README 配图

playproof

为浏览器游戏提供眼睛和双手。

npm CI License: MIT Node

编码 Agent 几分钟就能写出一款网页游戏,却无法看着它运行。playproof 让 Agent(也让你)逐帧查看游戏、通过脚本输入操控游戏、搜寻崩溃、检查手机屏幕上的效果,并测量运行流畅度;既可以在桌面上运行,也可以在真实的 Android 手机上运行。所有结果都会以便于阅读的图像形式呈现,并附上简短摘要,指出可能存在的问题。

一张有问题的游戏的联系表:两帧白屏闪烁和一个瞬移的球被红色标出,并在图表下方加以说明

已使用 Canvas 2D、DOM、Phaser 3、PixiJS 8、three.js、Godot 4 网页导出项目和 Unity WebGL 构建进行测试:每项测试连续运行两次,生成的帧都完全一致(npm run test:engines)。

安装

让你的 Agent 来安装

将以下内容粘贴到 Claude Code、Codex、Cursor、Gemini CLI 或其他编码 Agent 中:

Install playproof from https://github.com/EmirhanOzl/playproof

它会为自己选择下方合适的命令。

Claude Code
claude plugin marketplace add EmirhanOzl/playproof
claude plugin install playproof@playproof
Codex
codex plugin marketplace add EmirhanOzl/playproof
codex plugin add playproof@playproof
Gemini CLI
gemini extensions install https://github.com/EmirhanOzl/playproof
Cursor、OpenCode、GitHub Copilot 和其他 Agent
npx skills add EmirhanOzl/playproof
Claude Desktop 和其他 MCP 应用

对于通过调用工具而不是运行命令来工作的应用,playproof 也是一个 MCP 服务,工具会直接返回图像。将它添加到应用的 MCP 配置中:

{
  "mcpServers": {
    "playproof": { "command": "npx", "args": ["-y", "playproof", "mcp"] }
  }
}
不使用 Agent

无需安装。在游戏文件夹中运行 npx playproof init,即可生成 playproof.config.json(它会查找你的开发服务器、构建文件夹或 HTML 文件);或者直接向任意命令提供开发服务器、构建文件夹或 HTML 文件:

npx playproof frames http://localhost:5173 --device "Pixel 8" --do "tap 50%,50%" --duration 1s

playproof 使用你已安装的 Chrome 或 Edge。如果你希望使用自带的 Chromium,可以运行 npx playproof install-browser 下载。

为什么

截图只能捕捉随机的一瞬间,因此那些让游戏玩起来不对劲的问题往往无从察觉:没有预备动作的跳跃、瞬移的精灵图、只闪烁一帧的画面、按了却毫无反应的按钮、点击一百次后才发生的崩溃,以及在所有手机上都模糊的画布。

playproof 使用虚拟时钟运行游戏。时间只会在 playproof 推进时前进,每次精确推进一帧,因此它可以记录任意时刻,而且每次运行都会生成完全相同的像素。随后,它会将这些帧排列起来,让模型(或人)能够真正查看。由于每次运行都完全一致,Agent 可以记录一段动作、修改代码、再次记录,然后准确地查看修改带来了什么变化。

它能做什么

frames:监视动画

逐帧录制游戏并制作联系表:虚线框标出与上一帧相比发生变化的区域,柱状图显示每一帧中屏幕的变化幅度。playproof 会标记突然跳变(瞬移、补间动画缺失)、单帧闪烁(绘制顺序错误、状态只更新了一半)、停顿(卡住)以及完全没有动静。

npx playproof frames ./dist --device "Pixel 8" --do "tap @Play; wait 400ms; key Space" --duration 700ms

跳跃的联系表:14 个画格,覆盖 700 ms,虚线框标出移动的内容,每帧下方有一根柱形

添加 --animate,还可获得一段真实速度的动画 PNG,供你自行观看或添加到拉取请求中。移动物体较小时,添加 --zoom auto:playproof 会以设备的完整分辨率截图,并将每一帧裁剪到动作最集中的区域,让角色的挤压和拉伸效果填满画格。

它还会绘制洋葱皮:在一张图中展示完整动作,最早的时刻最淡。重影之间的间隔体现缓动效果(间隔宽表示速度快,间隔窄表示速度慢),动画师正是通过这些来判断弧线、预备动作或过冲。

跳跃的洋葱皮:重影在弧线顶端附近聚集,此时角色正在减速
frames --compare:查看更改带来的效果

录制一次,修改代码,再使用 --compare <earlier run> 录制一次。较早运行中的每个采样帧都会显示在当前对应帧的上方,并用轮廓标出差异;较早运行的动作轨迹则绘制为新柱状图上的一条线。由于运行结果是确定的,“完全相同”就意味着完全相同。

npx playproof frames http://localhost:5173 --do "tap @Play; key Space" --out .playproof/before
# ...change the jump...
npx playproof frames http://localhost:5173 --do "tap @Play; key Space" --compare .playproof/before

跳跃动作变得更利落前后的对比:新版本的画格更早到达顶点,也更早落地

play:运行脚本,生成故事板
npx playproof play http://localhost:5173 --device "Pixel 8" \
  --do "shot title; tap @Play; wait 400ms; key Space; film 600ms; until window.playproof.state().screen === 'over' 20s; shot game over; tap @Retry; shot retry"

故事板:标题画面、跳跃的四帧、游戏结束画面以及重试

monkey:随机游玩,寻找崩溃

随机执行点击、拖动、长按、快速三连击、按键以及将标签页切到后台等操作,但可通过种子重复运行。它会报告未捕获的错误、失败的请求、卡死(无限循环)、软锁(持续输入但画面没有变化)以及停止运行的渲染循环。每个错误都附带一条可精确复现问题的命令,整个运行过程会保存为 repro.steps,play --script 会逐个操作重放脚本:删除行,直到只剩下相关操作。

当游戏公开其按钮时(见下方的钩子),monkey 会进行探索:在每个画面中,它会先尝试尚未按过的按钮,再重复之前的操作。screens.png 展示它到达的所有不同画面,让你了解随机玩家能探索到多远,以及哪些地方始终无法到达。

npx playproof monkey ./dist --device "Pixel 8" --steps 300
ERROR   Uncaught error: TypeError: Cannot read properties of undefined (reading 'activate')
        during: action 13: tap 699,820, wait 119ms
        at HTMLCanvasElement.<anonymous> (http://127.0.0.1:52009/:51:40)
        Reproduce: playproof monkey "./dist" --seed 1 --steps 13 --device "Pixel 8"
devices:并排测试手机、平板和桌面设备

在九种屏幕上加载游戏,并检查仅在这些设备上出现的布局问题:画布模糊(未按 devicePixelRatio 缩放)、画布拉伸、画布被截断、页面滚动、缺少 viewport meta、缺少 touch-action: none、文本被裁切以及触控目标过小。同一问题在多个设备上出现时只报告一次。

npx playproof devices http://localhost:5173

六台设备并排显示;横屏设备和桌面设备上的球被拉伸的问题一目了然,下方列出了检查结果

在真实 Android 手机上、Chrome 中或应用内

frames、play、monkey 和 perf 可通过 --android 在连接 USB 的 Android 手机上运行(使用 Chrome 中的标签页),也可通过 --app <package> 连接到使用 Capacitor、Cordova 或 Ionic 构建的应用内 WebView。playproof 会使用虚拟时钟重新加载应用页面,让你在真实设备上的真实应用中获得相同的帧级精准图像序列;完成后会将页面恢复为正常状态。本地主机端口会自动转发到手机。

npx playproof frames http://localhost:5173 --android --do "tap 50%,60%" --duration 800ms
npx playproof monkey --app com.example.mygame --steps 200
npx playproof perf --app com.example.mygame --duration 10s --monkey

Capacitor 和 Cordova 应用的调试版本默认启用 WebView 调试;其他版本请参阅 webContentsDebuggingEnabled。在 Chrome 中,playproof 会打开自己的标签页,只与该标签页通信,并在完成后关闭它;绝不会列出或读取你的其他标签页。

perf:帧节奏,可在本地或真实手机上运行

在游戏空闲、运行脚本(--do)或随机点击(--monkey)时测量实际帧耗时:fps、p95/p99、相对于显示器刷新率的丢帧数、主线程长任务和堆增长。在本地,CPU 会降速 4×,以近似中端手机的性能。使用 --android 时,它会测量连接 USB 的 Android 手机上运行的 Chrome;本地主机端口会自动转发到手机。

npx playproof perf ./dist --duration 10s --monkey
npx playproof perf http://localhost:5173 --android

帧耗时图表,大多数柱形超过 16.7 ms 预算线,并标为红色

场景和 check:动作的快照测试

在 playproof.config.json 中填写游戏默认设置和需要观察的时刻(编辑器会根据架构为其提供自动补全):

{
  "$schema": "https://unpkg.com/playproof/schema/config.schema.json",
  "target": "http://localhost:5173",
  "device": "Pixel 8",
  "scenarios": {
    "title": { "duration": "800ms" },
    "jump": { "do": "tap @Play; wait 400ms; key Space", "duration": "700ms", "zoom": "auto" }
  },
  "check": { "monkey": { "steps": 200 }, "devices": true }
}

随后可以省略目标,并使用 --scenario jump 替换整个步骤列表:

npx playproof frames --scenario jump

playproof check 会录制每个场景并与 playproof-baselines/ 中的基线进行比较,然后运行 monkey 和 devices。首次运行会写入基线(请将其提交)。此后,任何导致场景动作变化的修改都会使检查失败,并生成 compare.png,准确显示发生的变化;直到你使用 --update 接受更改。基线按操作系统分别保存,因为不同系统的字体和抗锯齿效果有所不同。

npx playproof check                 # everything
npx playproof check --only jump     # one scenario
npx playproof check --update        # accept the current motion
在 CI 中
- uses: actions/checkout@v7
- uses: EmirhanOzl/playproof@v0
  with:
    start: npm run preview
    wait-for-url: http://localhost:4173

该操作会安装 Chromium,运行 playproof check(或通过 command 和 args 执行任意命令),将摘要写入作业页面,并将图像作为构件上传。在 CI 中生成一次 Linux 基线(首次运行会写入基线;从构件下载,或在那里运行 --update),确保基线与执行检查的机器匹配。

步骤

由 --do 和 --script <file> 使用(文件中每行一个步骤)。用 ; 分隔步骤。坐标相对于游戏区域(最大的画布,或 --area <selector>)。

步骤含义
wait 500ms让时间流逝(在虚拟时钟上即时且精确)
tap 50%,80% / tap 120,300 / tap @Play点击;@label 使用游戏公开的目标
press 50%,50% 800ms长按
drag 10%,50% 90%,50% 300ms滑动
key Space [200ms]按下按键(默认按住 50 ms)
type hello输入文本
click #start点击 DOM 元素
shot [label]为分镜截图
film 1s [30]时间流逝期间捕获帧
until <js> [5s]推进时间,直到表达式为真
expect <js>除非表达式为真,否则运行失败(会显示左侧的值)
background 5s将游戏切换到后台(不生成帧),然后再切回前台
js <js>求值并记录结果

时间:500、500ms、1.5s。

可选:在游戏中添加钩子

这些都不是必需的,但添加四个小函数可以让测试更精确:

window.playproof = {
  ready: () => assetsLoaded,               // boolean, function or promise: when to start
  state: () => ({ screen, level, score }), // logged; used to tell a soft-lock from a busy screen
  targets: () => [{ x, y, width, height, label: "Play" }], // CSS px; enables "tap @Play" and aims the monkey at buttons
  area: () => ({ x, y, width, height }),   // the game world inside a letterboxed canvas; crops every capture
};

如果不添加钩子,可使用 --ready "<js expression>" 或 --wait-for <selector> 等待加载完成,并使用百分比进行点击。examples/jumper 展示了一个包含完整钩子的游戏示例。

工作原理

  • 虚拟时钟。 在任何游戏脚本运行之前,playproof 会替换 requestAnimationFrame、setTimeout/setInterval、performance.now 和 Date,并停止 CSS 动画时间线。时间初始处于冻结状态。推进时间时,计时器和帧会按精确顺序以 60 fps 运行,因此 wait 2s 只需几毫秒,两次运行也会产生相同的帧。
  • 可重复的加载。 页面加载期间,playproof 会自行推进帧。只要游戏有需要真实时间的进行中任务(网络请求、WebAssembly 编译、图像和音频解码、IndexedDB),虚拟时间就会等待这些任务完成,因此慢速设备或连接也能产生与快速设备相同的帧。稳定时间从游戏渲染循环启动时开始计算,也就是 Unity 和 Godot 等引擎启动自身时钟的时刻。
  • 带种子的随机性。 Math.random 使用种子(--seed,或 --seed off)。
  • 真实输入。 触屏设备会收到真实的触摸事件(以及 Chrome 根据这些事件生成的指针和鼠标事件);其他设备会收到鼠标事件。按键会保持按下数帧,让通过轮询输入的游戏能够检测到按键。
  • 图像,而非日志。 联系表、洋葱皮视图、分镜和图表都在空白 Chromium 页面中绘制,因此 playproof 只有一个依赖项(playwright-core),不需要原生图像库。

输出

每次运行都会写入 .playproof/<time>-<command>/(或 --out <dir>):图像、包含所有数值的 report.json(逐帧运动、步骤日志、帧时间)、summary.txt,以及保存在 tiles/ 中以供日后比较的采样帧。将 .playproof/ 添加到 .gitignore。--json 会输出报告,而非摘要。

退出代码:0 表示未发现严重问题,1 表示发现错误(崩溃、请求失败、步骤失败、真实手机上的丢帧),2 表示 playproof 本身无法运行。因此,monkey 和 devices 可用作 CI 检查。

要求

  • Node.js 22.18 或更高版本。
  • 基于 Chromium 的浏览器:已安装的 Chrome 或 Edge,或 npx playproof install-browser。使用 --browser chromium|chrome|msedge|<path> 选择浏览器。
  • 使用 --android 和 --app 时:需要 adb(Android platform-tools)、一部允许 USB 调试的手机,并确保屏幕已亮起且处于解锁状态。

限制

  • 音频、视频、Web Workers 和 WebAssembly 线程仍使用真实时间;模拟运行在 worker 中的游戏无法做到帧级精确。
  • 本地 perf 数值来自无 GPU 的模拟:适合比较更改前后,不适合用来承诺帧率。使用 --headed 进行 GPU 渲染,或使用 --android 测试真实设备。
  • 运动检测结果是启发式判断。突然跳变可能是有意的切镜,单帧闪烁也可能是刻意设计的受击闪光,因此相关描述会将其表述为值得检查的问题。
  • 目前仅支持 Chromium。

开发

npm install
node src/cli.ts install-browser   # once
npm run check                     # type check + unit and end-to-end tests
npm run docs:images               # regenerate the README images with playproof itself

两个示例游戏也是测试目标:examples/jumper 是一款简洁的小型游戏;examples/buggy 中埋设了八个测试期望 playproof 捕获的错误。

欢迎提交问题和拉取请求。请参阅 CONTRIBUTING.md。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。