Cross-platform utility for the vpinball ecosystem
Join #vpxtool on "Virtual Pinball Chat" discord for support and questions.
Download the latest release for your operating system at https://github.com/francisdb/vpxtool/releases, extract it and
if wanted copy or symlink the binary to $HOME/bin to put in on your path
After extracting the archive you will have to remove the quarantine flag through
System Settings / Privacy & Security / Allow Anyway button or on the command line as shown below.
xattr -d com.apple.quarantine vpxtool
@gitfool set up a homebrew tap for vpxtool, with installation instructions in its repository:
https://github.com/gitfool/homebrew-vpinball
If you have cargo installed you can install vpxtool with the following command:
cargo install vpxtool
Show help
> vpxtool --helpVpxtool v0.35.1
Terminal based frontend and utilities for Visual Pinball
Usage: vpxtool [OPTIONS] [COMMAND]
Commands:
info Vpx table info related commands
table Vpx table level commands
diff Prints out a diff between the vbs in the vpx and the sidecar vbs
frontend Text based frontend for launching vpx files
index Indexes a directory of vpx files
capture Capture a playfield screenshot using vpinball
script Vpx script code related commands
ls Show the vpx file contents
extract Extracts a vpx file
extractvbs Extracts the script from a vpx file
importvbs Imports the vbs next to it into a vpx file
verify Verify the structure of a vpx file
audit Reports consistency problems in a vpx file
optimize Shrinks and repairs a vpx file
lock Lock a vpx file, preventing edits in vpinball
unlock Unlock a vpx file
lock-status Show the lock state of a vpx file
convert Converts a vpx file to a table pack, or a table pack to a vpx file
assemble Assembles a vpx file
patch Applies a VPURemix System patch to a table
new Creates a minimal empty new vpx file
config Vpxtool related config file
images Vpx image related commands
sounds Vpx sound related commands
collections Vpx collection related commands
materials Vpx material related commands
gameitems Vpx gameitem (table element) related commands
gamedata Vpx gamedata related commands
dipswitches NVRAM file DIP switch related commands
nvram PinMAME NVRAM related commands
scores Table high-score related commands
romname Prints the PinMAME ROM name from a vpx file
export Export a vpx table to obj, gltf or glb, or to a vpxz mobile archive
help Print this message or the help of the given subcommand(s)
Options:
-v, --verbose Enable verbose logging
-h, --help Print help
-V, --version Print version
Show help for a specific command
> vpxtool frontend --help
Text based frontend for launching vpx files
Usage: vpxtool frontend [OPTIONS]
Options:
-r, --recursive Recursively index subdirectories
-v, --verbose Enable verbose logging
--max-depth <MAX_DEPTH> Maximum directory depth to scan when indexing tables
-h, --help Print helpextract writes the whole table as a directory of JSON, script, image, sound and mesh files. To get only some
of them, filter on the paths that ls prints, relative to the output directory. A * does not cross a
directory separator, so gameitems/*.json is the game item files and *.json the top level index files.
# only the game data
vpxtool extract --only gamedata.json table.vpx
# the script and every game item, but no meshes
vpxtool extract --only script.vbs --only 'gameitems/*.json' table.vpx
# everything except the image and sound files; their index files are still written
vpxtool extract --no-media table.vpxFiles that are filtered out are not produced at all, so extracting only the JSON of a large table takes milliseconds. A partial directory cannot be assembled back into a table.
vpinball can also store a table as a pack: JSON documents and the assets in their own formats, as a .vpz zip
archive or as a folder. convert turns a vpx file into a pack and back, the way vpinball saves them; the output is a
vpx file for a .vpx name, a zip archive for a .vpz name and a folder otherwise.
vpxtool convert table.vpx # -> table.vpz
vpxtool convert table.vpz "Table 1.5" # -> a pack folder
vpxtool convert "Table 1.5" # -> Table 1.5.vpxaudit and info show also take a pack, and the frontend indexes and launches packs, see below.
verify checks the signature (MAC) vpinball stores in a table against its content. --json prints the stored and the
computed MAC of each file, for scripting:
vpxtool verify --json table.vpxoptimize applies the lossless fixes from the vpin library and rewrites the table in one go, which also compacts the file: unused embedded fonts are dropped, and bitmap, png and tga images are re-encoded as lossless webp where that is smaller. Images the script hands to FlexDMD are left alone. Sounds with the legacy * Backglass Output * path, which vpinball 10.8.1 fails to load, get the sound name with .wav as path. It prints what changed with the bytes saved and what was left alone and why; --dry-run reports without writing.
--mono downmixes stereo playfield sounds to the mono vpinball 10.8.1 and later play them as, exactly as vpinball does it, and --flac re-encodes PCM WAV sounds as lossless FLAC. Both are opt-in: vpinball 10.8.0 plays stereo playfield sounds in stereo in its two speaker mode and does not decode FLAC.
--max-image-size scales every image with a side over that many pixels down to fit, keeping the aspect ratio, for phones and other devices with a texture size limit; without a value it takes 1536, vpinball's mobile default. vpinball does the same on load for images over its "Maximum texture dimension" video setting (1536 by default on mobile), so the table stores what such a device shows anyway, resampled once with a better filter, and no longer carries the pixels the device throws away: the file is smaller, loads faster and needs less memory. It is lossy, a jpeg is re-encoded, so keep the original for other setups. Images FlexDMD draws, color grade LUTs and images whose smaller encoding would not be smaller are left alone and reported.
vpxtool optimize table.vpx
vpxtool optimize --dry-run table.vpx
vpxtool optimize --mono --flac table.vpx
vpxtool optimize table.vpx --max-image-size
vpxtool optimize --max-image-size=768 table.vpxaudit reports the findings these fixes act on, next to everything else it checks.
To get more information about what vpxtool is doing, you can set the -v flag to increase verbosity.
vpxtool -v extract test.vpxYou can also set the log level using the RUST_LOG environment variable. For example to get debug output:
RUST_LOG=debug vpxtool extract test.vpxShow the high-score entries stored for a table:
vpxtool scores show /path/to/table.vpxWorks with PinMAME tables (resolved through pinmame-nvram maps) as well as rom-less tables backed by VPReg.ini, GLF <cGameName>_glf.ini sidecars, or Black's-style user/*.txt EM hiscore files. Use --format tsv for scripting or --format pinemhi for a PINemHi-like layout.
Vpxtool can act as a frontend for launching vpx files. It will index a directory of vpx files and then present a menu to
launch them. Table packs, a .vpz file or a folder with a vpinball pack manifest.json, are indexed and launched too;
they need a vpinball version that loads packs, and the menu only offers the actions that do not read the vpx file
itself.
> vpxtool frontend
Every launch from the frontend is appended to a play log in the platform data directory
(~/.local/share/vpxtool/play_log.jsonl on Linux). The "Recently played" and "Most played" entries
in the main menu are built from it; runs shorter than 30 seconds are kept in the log but do not count
as a play.
A configuration file will be written to store among others the Visual Pinball executable location. The config file is using the TOML format.
When launching the frontend for the first time, it will help you to set up the required settings.
The config file is stored in the default config location for your operating system:
- Linux:
$XDG_CONFIG_HOME/vpxtool/vpxtool.cfgor$HOME/.config/vpxtool/vpxtool.cfg - macOS:
$HOME/Library/Application Support/vpxtool/vpxtool.cfg - Windows:
C:\Users\<user>\AppData\Roaming\vpxtool\vpxtool.cfg
To show the current config location, use the following command:
vpxtool config path
To edit the config file using your system default editor, do the following:
vpxtool config edit
vpx_executable = "/home/myuser/vpinball/VPinballX_BGFX"
# Optional settings below, only needed if the defaults don't work
tables_folder = "/home/myuser/vpinball/tables"
vpx_config = "/home/myuser/.local/share/VPinballX/10.8/VPinballX.ini"
# how deep the frontend looks for tables below the tables folder
tables_scan_max_depth = 3Further settings will be picked up from the Visual Pinball config.
Sometimes you want to use a different executables, extra arguments or environment variables. This can be done by setting up launch templates. Each entry will show up on top of the frontend table menu.
To force fullscreen or windowed mode, point a template at a separate vpinball ini file (passed to vpinball as
-Ini <path>) with the relevant FullScreen / PlayfieldFullScreen keys overridden. The previous
-EnableTrueFullscreen / -DisableTrueFullscreen CLI flags are deprecated upstream and not present in
modern (BGFX) vpinball builds.
[[launch_templates]]
name = "Launch fullscreen"
executable = "/home/myuser/vpinball/VPinballX_BGFX"
vpinball_config = "/home/myuser/.local/share/VPinballX/10.8/VPinballX.fullscreen.ini"
[[launch_templates]]
name = "Launch GL"
executable = "/home/myuser/vpinball/VPinballX_GL"
[launch_templates.env]
SDL_VIDEODRIVER = "X11"When actions are invoked that run diff, the default diff configured for your system will be used. In case you want to override this with a specific diff, optionally specifying the path, you can add the following line to the config file:
# use mydiff as default diff
diff = "/path/to/mydiff"When actions are invoked that open an editor, the default editor configured for your system will be used. In case you want to override this with a specific editor, optionally specifying the path, you can add the following line to the config file:
# use Visual Studio Code as default editor
editor = "code"vpxtool export vpxz bundles the chosen vpx and its parent-folder contents into a .vpxz archive for the Visual Pinball mobile app. A few classes of files are dropped automatically:
- other
.vpxfiles in the tree (the mobile importer rejects archives with more than one vpx) and their stem-keyed sidecars, .directb2sfiles whose stem doesn't match the chosen vpx,- previously generated
.vpxzarchives.
Anything else is included by default. To skip additional patterns, set vpxz_excludes in the config file. Patterns are gitignore-ish globs matched against paths relative to the vpx's parent folder; a trailing / matches the directory both at the top level and nested anywhere:
vpxz_excludes = [
"Downloads/", # the table author's original archive / install docs
"downloads/",
"cache/", # VPX runtime cache, regenerated on the device
"**/Thumbs.db", # Windows folder thumbnails
"**/.DS_Store", # macOS folder metadata
"**/*.bak", # editor / VPX backups
"**/*~", # Emacs-style backups
# Add your own. Examples:
# "user/", # also drop desktop save state (high scores, options)
# "**/*.pov", # camera POV files (desktop only)
# "**/*.res", # legacy B2S Server resolution files (desktop only)
]The list above is the built-in default; if you don't set vpxz_excludes, that's what gets applied. Setting it replaces the default in full, so copy the entries you still want.
- https://github.com/jsm174/vpx-editor
- https://github.com/syd711/vpin-studio
- https://github.com/jsm174/docker-vpxtool-resize
- https://github.com/mpcarr/aztec-quest
- https://github.com/francisdb/vpinball-example-table-extracted
- https://github.com/surtarso/vpx-gui-tools
Other related projects that read and/or assemble vpx files:
- https://github.com/vpinball/vpinball
- https://github.com/vpdb/vpx-js
- https://github.com/freezy/VisualPinball.Engine
- https://github.com/stojy/ClrVpin
- https://github.com/vbousquet/vpx_lightmapper
An example vpx managed in github with some imagemagick scripts to compose textures
https://github.com/vbousquet/flexdmd/tree/master/FlexDemo
The project uses the default rust build tool cargo. To get going read the docs on
installation and first steps at https://doc.rust-lang.org/cargo/
Some dependencies require extra dependencies. Make sure you install developer tools:
- Fedora:
sudo dnf install @development-tools - Ubuntu:
sudo apt install build-essential
cargo build --release
