npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qaping/rig

v0.1.0

Published

Record one controller session, replay it against every build: a virtual XInput gamepad, screen capture, PresentMon frame times and a run receipt. Windows.

Readme

@qaping/rig

Your playtester's first pass becomes the regression test.

A person plays your game once, on a real controller. The rig records the exact inputs. From then on it can replay that session against every new build through a virtual XInput gamepad — recording the screen, measuring frame times, watching for crashes — and write a receipt of what happened.

No engine integration, no SDK, no source changes. The rig plays your packaged Windows build the way a person would: the game just sees an Xbox controller.

npx @qaping/rig doctor

What it is

  • record — a human plays with a physical Xbox-compatible pad; the session becomes a pingfusi-padscript/v1 file: sparse full-state keyframes on a drift-corrected tick.
  • play — that file replays through a virtual pad (a kernel-level ViGEmBus device; the game sees a real Xbox 360 controller in joy.cpl) against a build you point at — a .zip, an unzipped directory, or a URL. While it plays, the rig records the screen with ffmpeg, samples frame times with PresentMon, notices if the game dies, sweeps up the Windows crash dump it left, and stops on its own time budget if the build hangs.
  • overlay — burns the recorded input trace onto the capture, so you can watch the footage and the stick/button state together. The graphic is drawn from the run's own inputs.jsonl, not from a live widget: what you see is what was sent.
  • report — turns a receipt into readable findings, each stamped with the timestamp to seek to in the recording: every 2–10 s gap with no frame presented (a load screen, or a hitch the player experiences as waiting), every frame that ran 4× the median and at least 50 ms (a stutter), the crash if there was one, and every warning the run raised. Alongside them: average fps, p95, p99, 1% low.
  • Every run writes a pingfusi-rig-run/v1 receipt — the build's sha256, the script's sha256, every input event, the frame-time summary, the exit reason. A run is reproducible from its receipt or it did not happen.

Replay promises input determinism: the same bytes go to the pad at the same offsets on every run. inputs.jsonl is a pure function of the script and comes out byte-identical run after run — that is the property the whole thing rests on.

What it is not

  • Not an AI that plays your game. There is no agent, no exploration, no learning. It replays a human's inputs, and that is the entire trick.
  • Not a pass/fail gate. The rig reports; it never fails a build. Replay does not promise outcome determinism — game RNG and load variance are real — so anything it flags, including a run that diverges from the last one, is a warning for a person to adjudicate, never a verdict.
  • Not a replacement for playtesters. It is the boring half: the same session, again, on the build you shipped this morning. People are still the ones who can tell you the boss fight feels unfair.
  • Not a cloud service. It runs on your machine. See Privacy.

Requirements

| | | |---|---| | Windows 10 or 11, x64 | the virtual pad is a Windows driver; there is no macOS or Linux path | | Node.js 20+ | | | ViGEmBus driver | the virtual gamepad's kernel device — installed for you by vgamepad below | | Python 3 + vgamepad | the pad feeder: python -m pip install "vgamepad==0.*" (accept the driver prompt the first time) | | a physical Xbox-compatible controller | for record only | | ffmpeg (optional) | screen capture and overlay. Without it, play --no-capture still runs and still measures | | PresentMon (optional) | frame times. Without it you get a run and a recording, but no fps numbers |

Two things about the session, both learned the hard way:

  • Run the terminal elevated for play — PresentMon's ETW session needs it.
  • Do not RDP into the machine mid-run. RDP takes over the console session and breaks screen capture. Use a remote-desktop tool that leaves the physical session alone.

doctor checks all of it and tells you what is missing:

npx @qaping/rig doctor

There is also a one-shot provisioner, shipped with the package. Install it first (npm i @qaping/rig, or npm i -g @qaping/rig for a qaping-rig on your PATH), then run the script elevated, once: it installs Python, vgamepad, ffmpeg and PresentMon, pins each download's sha256 on first run, and enables Windows crash dumps.

powershell -ExecutionPolicy Bypass -File .\node_modules\@qaping\rig\scripts\provision.ps1 -Trust

Already have the tools somewhere else? Point at them: RIG_FFMPEG, RIG_PRESENTMON.

Quick start

# 1. one human session, on the physical controller
npx @qaping/rig record --out first-pass.padscript.json
#    play; Ctrl+C stops the recording and writes the file

# 2. replay it against a build (elevated terminal)
#    UNPLUG the physical pad first — the virtual one wants the first slot
npx @qaping/rig play ./build-1042.zip --script first-pass.padscript.json --label 1042

# 3. watch the inputs on the footage
npx @qaping/rig overlay rig-runs/run-20260904-1132-a1b2c3

# 4. read what came back
npx @qaping/rig report rig-runs/run-20260904-1132-a1b2c3

Then, for every build after that, step 2 again. The script is a plain JSON file: commit it next to the build it was recorded against and it stays replayable.

Useful flags on play: --exe <relative-path> when the zip holds more than one executable, --exe-args "…", --max-minutes <n> (default 35), --no-capture (no ffmpeg — worth it on a thin GPU, where capture itself costs frames), --no-telemetry, --expect-sha256 <hex> to refuse a build whose bytes are not the ones you meant (it needs a .zip or a URL — an already-unzipped directory has no digest, and the run is refused rather than quietly unchecked).

Replay starts a fixed delay after launch — 8 seconds, recorded into the script as start.wait_for.ms. If your game takes longer to reach a playable state, edit that one number in the JSON, or your first inputs land on a loading screen.

Where files land

Everything is written under the directory you ran the command from:

rig-runs/<run-id>/
  receipt.json            the run's durable record (pingfusi-rig-run/v1)
  inputs.jsonl            every pad state sent — a pure function of the script
  inputs-timing.jsonl     when each one actually went out (wall clock)
  presentmon.csv          raw frame times, if PresentMon was there
  recording.mp4           the capture, if ffmpeg was there
  recording-overlay.mp4   written by `overlay`
  annotations.json        written by `report`
  <name>.dmp              the crash dump, if it crashed

record writes its padscript to --out (default: session-<timestamp>.padscript.json in the current directory). Set RIG_RUNS_DIR to put runs somewhere else.

Privacy

Everything stays on your machine. No account, no sign-in, no key: none of the rig's commands authenticate against anything. Your build, your recording, your frame times and your receipts are files on your disk, and nothing uploads them.

The rig makes exactly two kinds of network request, both of them ones you asked for: downloading a build when you hand play a URL, and downloading the pinned tools when you run provision.ps1.

What's next

The rig is the machine half — the same session, again, on every build. The other half is people: qaping.dev files that build with real human playtesters and brings back a recording and what actually broke.

Windows only, today. Bugs and questions: qaping.dev.

MIT licensed.