Files
vpinball/README.md
T
valknarandClaude Sonnet 5 e493a12e68 Add vpinball: a browser Visual Pinball player
Next.js app that plays real .vpx tables via @valknar/vpinball-wasm
(WebAssembly Visual Pinball). Demo mode with the bundled default
table, drag-and-drop custom table upload, a cabinet-styled UI with a
coin-door HUD (fullscreen/stats/info/eject), a custom 404 page, PWA
support (hand-rolled service worker), and a static Docker Compose
deployment behind nginx.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012hQoM3jJT1Lx7CMTciMzvD
2026-08-23 05:25:15 +02:00

118 lines
4.2 KiB
Markdown

# vpinball
Play real `.vpx` pinball tables in your browser. Drop in your own table or try the bundled demo —
no plugins, no native install. Powered by [`@valknar/vpinball-wasm`](https://dev.pivoine.art/valknar/vpinball-wasm),
a WebAssembly build of the real [Visual Pinball](https://github.com/vpinball/vpinball) engine
(real physics, real VBScript table scripting, real WebGL2 rendering).
## Features
- **Play any self-contained `.vpx` table** — drag a file onto the landing page, or click to browse.
- **Demo mode** — a bundled table plays instantly with no upload required.
- **Fullscreen**, a live **FPS/stats** readout, and a **game info** panel (table name, size, load
time) in an in-game HUD styled after a pinball cabinet's coin door.
- **Installable as a PWA** — add it to your home screen or desktop; the engine is cached after
your first game so it's available offline afterward.
- **Deployable as a static site** via Docker Compose — no Node server at runtime, just nginx
serving prebuilt files.
## Prerequisites
- Node.js ≥ 20, [pnpm](https://pnpm.io) ≥ 11
- Docker + Docker Compose, for the containerized deploy
## Install
```bash
pnpm install --frozen-lockfile --trust-lockfile
```
`vpinball-wasm` is published to a private Gitea npm registry
(`https://dev.pivoine.art/api/packages/valknar/npm/`) under the `@valknar` scope. `.npmrc` maps
that scope to the registry; the package is publicly readable, so no auth token is needed to
install it.
To bump the engine to a newer published version:
```bash
pnpm add @valknar/vpinball-wasm@<version>
```
## Development
```bash
pnpm dev
```
`pnpm dev` copies the engine's build output into `public/vendor/vpinball-wasm/` first (via the
`predev` script) — it's gitignored and regenerated from `node_modules`, so this only needs
`pnpm install` to have completed. Re-run `pnpm run copy-engine-assets` by hand if you update the
dependency without restarting the dev server.
The dev server runs at `http://localhost:3000`.
## Build
```bash
pnpm build
```
Produces a fully static export in `out/` (`next.config.ts` sets `output: "export"`) — no Node
server needed to serve it.
## Docker deploy
```bash
docker compose build
docker compose up -d
```
Serves the static build via nginx on `http://localhost:8080`. No secrets or registry
authentication are required to build the image.
## PWA
The app can be installed from the browser's install prompt. A hand-rolled service worker
(`public/sw.js`) precaches the app shell; the engine's `.wasm`/`.data` files (~34 MB) are cached
on first visit to `/play`, not upfront, so installing the app doesn't force a large download
before anyone has actually played. After that first visit, offline reloads work.
When you ship a release that changes the app shell or updates the vendored engine build, bump the
cache version so returning visitors actually get the update:
```bash
pnpm run sw:bump
```
## Controls
| Key | Action |
| -------------- | ------------- |
| Left Shift | Left flipper |
| Right Shift | Right flipper |
| Enter | Plunger |
| 1 | Start game |
On touch devices, an on-screen control overlay appears automatically once a table is running.
## Limitations
Inherited from the underlying engine:
- Only self-contained `.vpx` tables are supported — tables that reference an external `.vbs`
script override or a `Music/` folder won't load correctly.
- No PinMAME, DOF, or FlexDMD plugin support.
- Single-threaded (no `SharedArrayBuffer`) — performance depends on your device's single-core
WebGL2 throughput.
- Initial engine download is ~34 MB (cached after the first visit).
- Gamepad input and DMD rendering are implemented but not yet confirmed on real hardware/tables.
- Raw cabinet hardware input (real nudge/plunger boards) has no browser equivalent.
## License
This app's own source has no license file yet — add one before distributing it. Separately, the
built output bundles the `@valknar/vpinball-wasm` engine and its default table, which redistribute
Visual Pinball source under a **mixed legacy/GPLv3+ license** (migrating file-by-file to GPLv3+
since October 2020) — see that package's own `LICENSE` for the authoritative terms before
distributing a build.