Your phone is the lightgun.
Turn any ARCore Android phone into a drift-free lightgun for PC rail shooters — WebXR aim tracking in the browser, absolute mouse input on the desktop. No custom hardware. No markers. No sensor bars.
Start here (players) · Documentation · API Reference
▶ Watch: Time Crisis on a projector — the phone is the lightgun
There's a little boy in the next room who thinks his dad makes video games. The truth is his dad chases calibration bugs at midnight and whispers "one more build" while other people whisper goodnight.
I made point-bang because arcades made my childhood magical, and I
wanted to hand that feeling to my son and share it for free to strangers
on the internet.
The hours in this repo came from somewhere — a coffee can't buy them back — but it turns them into something I can show him one day and say: look, buddy, it mattered. People played because of us.
If point-bang made you feel eight years old again, even for one evening — the yellow button below is how you say it.
No Node, no build tools, no certificates — three steps:
Then set up an actual game — the game guides → walk through Time Crisis in DuckStation. Prefer a cable? The USB flow has the lowest jitter of all and charges the phone while you play.
Alternatively, you can skip setting up a game and just move the PC cursor around with your phone to test the aim.
Requires Node ≥ 23.6 (TypeScript runs natively via type stripping — no build step anywhere in the dev loop):
git clone https://github.com/ggcaponetto/point-bang.git
cd point-bang
npm install
npm run start:adb # USB flow: sets up the adb tunnel for you
Open http://localhost:8443 in Chrome on the phone, tap START AR,
capture the three corners. npm start additionally prints the QR for the
wireless flow, npm run start:tunnel exposes a public ngrok URL, and the
development guide
covers testing the remote flow against uncommitted code.
npm run validate # format:check + typecheck + knip + tests (90% coverage gate)
npm run build:sea # single self-contained executable -> dist/point-bang[.exe]
node cli.ts --help # every option is a flag
flowchart LR
subgraph phone [Phone — Chrome WebXR]
A[ARCore 6DoF pose] --> B[aim ray × calibrated screen plane]
B --> C[One Euro filter]
H[on-screen buttons<br/>from buttons.json]
end
C -- "WebRTC DataChannel (LAN)<br/>or WebSocket (USB)" --> D
H --> D
subgraph pc [PC — Node]
D[protocol handler] --> E[newest aim sample<br/>no prediction, ever]
E --> F[2ms cursor loop]
F --> G[absolute mouse input]
D --> I[button executor<br/>key combos and clicks]
end
ARCore's visual-inertial tracking gives absolute, drift-corrected aim at top-class latency (~15–30ms phone-side) — the camera corrects the IMU, so there's no yaw drift and no recentering. You calibrate once per session by pointing at three screen corners; WebXR anchors keep the calibration self-correcting as ARCore refines its map of your room. The wireless setup needs zero certificates: the phone page is hosted over HTTPS, signaling is one Local-Network-Access fetch, and WebRTC brings its own encryption.
immersive-ar with two-ray corner
calibration that works on any screen (no surface tracking needed);
anchor-pinned self-correcting hit-test mode one toggle away.b0 — remappable like everything else./editor.html, URL in the startup banner): move and resize buttons on a
phone-shaped canvas, remap keys, tune haptics — Save applies instantly,
the PC remaps without a restart and a connected phone re-renders
mid-session without recalibrating.point-bang monitors lists your displays;
--monitor 2 aims at one of them, --monitor all spans the whole
desktop with each monitor calibrated as its own plane (bezels and
angled panels stay accurate, with independent aim correction per
monitor), and the default stays the primary screen. During calibration
the PC cursor jumps to the monitor you should aim at next, and if you
still calibrated them in the wrong order, one tap on SWAP in the aim
panel fixes the assignment — no recalibration. (X11 multi-monitor
setups that relied on the old implicit span: that is --monitor all
now.)shift+s pauses tracking so the real mouse
works, and resumes right where you left off; configurable, and never
swallows the combo from the focused game.Working end-to-end: calibrate, aim, shoot — over USB, WiFi (QR → WebRTC), or an ngrok tunnel. On the roadmap: a measurement harness (accuracy/drift reports), MAME/RetroArch integration testing, and multi-gun support.
PRs are very welcome — including community guides, hacks and mods,
which get linked from the docs. Read
CONTRIBUTING.md for setup, the npm run validate gate
and commit conventions, and mind the Code of Conduct.
MIT © 2026 ggcaponetto
85 commits
TypeScript
83.9%
JavaScript
8.8%
HTML
7.3%
Your phone is the lightgun.
Turn any ARCore Android phone into a drift-free lightgun for PC rail shooters — WebXR aim tracking in the browser, absolute mouse input on the desktop. No custom hardware. No markers. No sensor bars.
Start here (players) · Documentation · API Reference
▶ Watch: Time Crisis on a projector — the phone is the lightgun
There's a little boy in the next room who thinks his dad makes video games. The truth is his dad chases calibration bugs at midnight and whispers "one more build" while other people whisper goodnight.
I made point-bang because arcades made my childhood magical, and I
wanted to hand that feeling to my son and share it for free to strangers
on the internet.
The hours in this repo came from somewhere — a coffee can't buy them back — but it turns them into something I can show him one day and say: look, buddy, it mattered. People played because of us.
If point-bang made you feel eight years old again, even for one evening — the yellow button below is how you say it.
No Node, no build tools, no certificates — three steps:
Then set up an actual game — the game guides → walk through Time Crisis in DuckStation. Prefer a cable? The USB flow has the lowest jitter of all and charges the phone while you play.
Alternatively, you can skip setting up a game and just move the PC cursor around with your phone to test the aim.
Requires Node ≥ 23.6 (TypeScript runs natively via type stripping — no build step anywhere in the dev loop):
git clone https://github.com/ggcaponetto/point-bang.git
cd point-bang
npm install
npm run start:adb # USB flow: sets up the adb tunnel for you
Open http://localhost:8443 in Chrome on the phone, tap START AR,
capture the three corners. npm start additionally prints the QR for the
wireless flow, npm run start:tunnel exposes a public ngrok URL, and the
development guide
covers testing the remote flow against uncommitted code.
npm run validate # format:check + typecheck + knip + tests (90% coverage gate)
npm run build:sea # single self-contained executable -> dist/point-bang[.exe]
node cli.ts --help # every option is a flag
flowchart LR
subgraph phone [Phone — Chrome WebXR]
A[ARCore 6DoF pose] --> B[aim ray × calibrated screen plane]
B --> C[One Euro filter]
H[on-screen buttons<br/>from buttons.json]
end
C -- "WebRTC DataChannel (LAN)<br/>or WebSocket (USB)" --> D
H --> D
subgraph pc [PC — Node]
D[protocol handler] --> E[newest aim sample<br/>no prediction, ever]
E --> F[2ms cursor loop]
F --> G[absolute mouse input]
D --> I[button executor<br/>key combos and clicks]
end
ARCore's visual-inertial tracking gives absolute, drift-corrected aim at top-class latency (~15–30ms phone-side) — the camera corrects the IMU, so there's no yaw drift and no recentering. You calibrate once per session by pointing at three screen corners; WebXR anchors keep the calibration self-correcting as ARCore refines its map of your room. The wireless setup needs zero certificates: the phone page is hosted over HTTPS, signaling is one Local-Network-Access fetch, and WebRTC brings its own encryption.
immersive-ar with two-ray corner
calibration that works on any screen (no surface tracking needed);
anchor-pinned self-correcting hit-test mode one toggle away.b0 — remappable like everything else./editor.html, URL in the startup banner): move and resize buttons on a
phone-shaped canvas, remap keys, tune haptics — Save applies instantly,
the PC remaps without a restart and a connected phone re-renders
mid-session without recalibrating.point-bang monitors lists your displays;
--monitor 2 aims at one of them, --monitor all spans the whole
desktop with each monitor calibrated as its own plane (bezels and
angled panels stay accurate, with independent aim correction per
monitor), and the default stays the primary screen. During calibration
the PC cursor jumps to the monitor you should aim at next, and if you
still calibrated them in the wrong order, one tap on SWAP in the aim
panel fixes the assignment — no recalibration. (X11 multi-monitor
setups that relied on the old implicit span: that is --monitor all
now.)shift+s pauses tracking so the real mouse
works, and resumes right where you left off; configurable, and never
swallows the combo from the focused game.Working end-to-end: calibrate, aim, shoot — over USB, WiFi (QR → WebRTC), or an ngrok tunnel. On the roadmap: a measurement harness (accuracy/drift reports), MAME/RetroArch integration testing, and multi-gun support.
PRs are very welcome — including community guides, hacks and mods,
which get linked from the docs. Read
CONTRIBUTING.md for setup, the npm run validate gate
and commit conventions, and mind the Code of Conduct.
MIT © 2026 ggcaponetto
85 commits
TypeScript
83.9%
JavaScript
8.8%
HTML
7.3%