Skip to content
dekay edited this page Sep 23, 2026 · 14 revisions

Note

This page expands upon the official File Layout Documentation on VPinball's Github with more details and examples. In the event of a discrepancy between that page and this one, the former is likely correct.

Note

This page is a work in progress and will be expanded upon over time.

Table of Contents

VPinball started in the 2000's as a Windows only all-in-one application with a simple file layout scheme: put everything in a global folder mixing all types of assets together. The growth of the ecosystem over the years added a lot of new components and optional features, multiple front ends, thousands of tables, and cross-platform support that rendered this file layout scheme obsolete. A more organized layout was developed during the 10.8.1 development cycle to address this.

Tip

For ease of transition from existing installations, the legacy file layout is still supported but discouraged: support for it will likely be dropped at some point.

VPinball's Structure

VPinball is structured into three parts: the main application, the configuration files, and the table-related data. They parts are located on each host platform as follows:

  • The main application
    • Windows: C:\Program Files\...
    • MacOS: /Applications/VPinballX_BGFX.app/
    • Linux: dependent on how your distro has packaged it or where you self-installed it
    • iOS, Android & Meta Quest: system application folder (not directly accessible)
  • The configuration files
    • Windows: C:\Users\<username>\AppData\Roaming\...
    • MacOS: /Users/<username>/Library/Application Support/VPinballX
    • Linux: /home/<username>/.local/share/VPinballX
    • Android & Meta Quest: /data/data/org.vpinball.app/files/
    • iOS: preferences are stored in the app's Documents directory
  • The table and table-related data
    • Windows: name and location are the user's choice, but often within C:\Users\<username>\Documents\...
    • MacOS: name and location are the user's choice, but often within /Users/<username>/Documents
    • Linux: name and location are the user's choice
    • Android & Meta Quest: /data/data/org.vpinball.app/files/
    • iOS: in the app's Documents directory

Starting with VPX 10.8.1, settings are stored in a subdirectory per minor version, that is to say 10.8, 10.9, etc. This allows the installation of multiple minor versions on the same system without settings conflicts.

File Management on Mobile Platforms

To simplify file management, VPX includes a built-in web server on all mobile platforms. Enable it in settings to upload tables and transfer files from any browser on the same network.

  • On Android, on first launch, VPX copies required assets from the APK to the app's internal storage, typically: /data/data/org.vpinball.app/files/assets/
  • On iOS, to provide additional user-friendly file access:
    • The Documents folder is accessible via the Files app on the device
    • When connected to a Mac, files can be transferred through Finder

Global Settings and Table Overrides

VPinball is a very flexible game engine with thousands of settings, allowing it to be used in a wide variety of use cases ranging from desktop computers, virtual reality headsets, pinball cabinets, mobile phones, minipinball devices based on single chip computers, etc. See this section for details on changing settings either globally or per table.

Table Folder Organization

A Visual Pinball X table may come as a single .vpx file, but it will usually benefit from additional companion files: table overide ini file, backglass file, pupvideo folder, DMD colorization, music, etc. Therefore, it is preferred to store each table in its own folder along with its companion files.

Moreover, to simplify and unify the way things are managed between the VPX application, the core plugins and third-party components, a common file search scheme is defined, based on a folder per table logic. Companion files are searched following these 3 steps:

  • first search along the table file, with a name matching the played table file,
  • then search along the table file, with a name matching the name of the folder containing the played table file,
  • finally, eventually search in a custom legacy folder (custom behavior is defined by each component).

The following tree is an example of this file organization:

Table Name (Manufacturer Year)/              <= We created a dedicated folder to hold all the files for this table
├── Table file v1.1.vpx                      <= This is the main VPX file
├── Table file v1.1.ini                      <= This file holds the table setting overrides
├── Table file v1.1.vbs                      <= For some reason, we decided to override the table script by a custom script
├── Table file v1.1.scv                      <= ScoreView plugin will use this layout file if present (otherwise defaulting to its global scoreview folder)
├── Table file v1.0.vpx                      <= For example, we decided to keep an older version for reference
├── Table Name (Manufacturer Year).directb2s <= We chose to name the backglass after the folder name, as it is shared between all table versions
├── Table Name (Manufacturer Year).info      <= This is an information file to store frontend datas, we decided to name after the folder name (not directly linked to VPX, see below)
├── Installation.txt                         <= Additional file the table authors decided to include
├── Rulesheet.pdf                            <= Additional file the table authors decided to include
├── altsound/                                <= AltSound plugin will look here for altsound files
│   └── xxx/
│       └── ...
├── cache/                                   <= VPX cache some informations for smoother play, they will be stored here
│   └── ...
├── medias/                                  <= This is a common folder to store frontend files (not directly linked to VPX, see below)
│   ├── (Backglass) Table Name (Manufacturer Year).mp4
│   ├── (Playfield) Table Name (Manufacturer Year).mp4
│   ├── (Wheel) Table Name (Manufacturer Year).apng
│   └── ...
├── music/                                   <= Folder from which music are loaded when script use the PlayMusic command
│   ├── Multiball Theme.ogg
│   └── ...
├── pinmame/                                 <= PinMAME plugin will look here for rom, nvram, config, and alias files
│   ├── roms/
│   │   ├── xxx.zip
│   │   └── yyy.zip
│   ├── nvram/
│   │   ├── xxx.nv
│   │   └── yyy.nv
│   ├── cfg/
│   │   ├── default.cfg
│   │   ├── xxx.cfg
│   │   └── yyy.cfg
│   ├── altcolor/
│   │   ├── xxx.zip
│   │   └── yyy.zip
│   └── alias.txt
├── pupvideos/                               <= PinUp player plugin will look here for pinup videos
│   └── xxx/
│       └── ...
├── scripts/                                 <= When a table loads additional script, they are searched here as well as in core script folder
│   └── ...
├── serum/                                   <= Serum plugin will look here for colorization files
│   └── xxx/
│       └── xxx.crz (or .cromc)
├── Table Name.UltraDMD/                     <= Folder with FlexDMD or UltraDMD content (name is directly defined in the table script)
│   └── ...
├── user/                                    <= VPX stores values saved from script in this folder
│   └── VPReg.stg
└── vni/                                     <= VNI plugin will look here for colorization files
    └── xxx/
        ├── xxx.pal
        └── xxx.vni

The following sections will explain these sections in more detail.

The Main Table Folder

Excluding subdirectories, the files within the main table folder are as follows:

Table Name (Manufacturer Year)/              <= We created a dedicated folder to hold all the files for this table
├── Table file v1.1.vpx                      <= This is the main VPX file
├── Table file v1.1.ini                      <= This file holds the table setting overrides
├── Table file v1.1.vbs                      <= For some reason, we decided to override the table script by a custom script
├── Table file v1.1.scv                      <= ScoreView plugin will use this layout file if present (otherwise defaulting to its global scoreview folder)
├── Table file v1.0.vpx                      <= For example, we decided to keep an older version for reference
├── Table Name (Manufacturer Year).directb2s <= We chose to name the backglass after the folder name, as it is shared between all table versions
├── Table Name (Manufacturer Year).info      <= This is an information file to store frontend datas, we decided to name after the folder name (not directly linked to VPX, see below)

Each of these files will be discussed in their own subsection, followed by the subdirectories contained within.

The .vpx Table File

Think of the .vpx file as "the table" or "the game". A .vpx file contains a table's artwork, sounds, layout,and scripting in a compressed format used by the latest version of Visual Pinball - Visual Pinball X. They are the product of a lot of hard work from the many talented creators in the virtual pinball community and we greatly appreciate their efforts.

The VPinball program you installed on your machine does not include any tables besides a simple example. You'll need to download these tables separately. Fortunately, the Virtual Pinball Spreadsheet has your back. It has a searchable index of over 5500 tables at time of writing, with more being created all the time. Take a look around, find something you like, and download it to your machine. Note that any table with a .zip extension will need to be extracted before VPinball will recognize it.

Having said that, some tables will require other files besides the .vpx file itself to run. For example, any table that emulates an original machine's CPU and audio hardware via Pinmame (e.g. AC/DC Luci, The Addams Family, Black Knight 2000, etc) must have the original ROM files to run as discussed here.

The .ini Settings Override File

VPinball's settings system is based on two files:

  • the global settings file, named VPinballX.ini and stored in the configuration file directory
  • an optional table override .ini file which is loaded and applied when playing a table, named against the table filename or containing folder. The table override file allows the user to tweak a few settings for playing a given table by overriding the settings defined in the global settings.

All the settings can be adjusted using the in-game UI, available when playing by pressing F12. When clicking the Save button (floppy disk image in top right corner of the window), the user is asked whether the modifications should be saved as global preferences or as table overrides.

Save Settings

Save Choices

Settings that have been overriden for the played table can be identified by a circle & dot icon in the in-game UI.

For advanced uses, it is possible to specify the global and table override ini files on the command line.

Tip

Run VPinball with -help from within a terminal to see all supported command line parameters e.g. VPinballX_BGFX -help for the BGFX version.

The .vbs Sidecar File

The .vbs "sidecar" file is a complete Visual Basic script file for the table that, if present, will override the VBScript file contained within the main .vpx file. There are a number of reasons why the original script might need to be overridden:

  • an older table might have issues running on newer versions of VPinball that can be fixed with some tweaks to the script
  • a table might not run properly on systems other than Windows without script changes
  • you want to tweak the script yourself based on some tips in the table documentation.

A good example of a table needing a tweak to run on the latest version of VPinball is Blood Machines 2.0 discussed in this Github issue. Basically, Blood Machines has some hardcoded file paths that cause issues. Another example is AC/DC Luci v1.1.3 where the lighting looks bad on current VPinball implementations.

The VPX Standalone Scripts repo on Github contains table patches for a large number of tables and is often referred to on forums and in Discord. To install a patched table script from that repo using Blood Machines 2.0 as an example:

  • browse to the VPX Standalone Scripts repo on Github
  • search for a folder that is an exact match with the table name and the table version you are trying to patch. Patches are not compatible across different names and / or versions. For our example, click on the folder named Blood Machines 2.0. You should see something like this:

Blood Machine 2.0 Patches

  • click on Blood Machines 2.0.vbs and you'll see something like the window below. Ignore the .original file. Ignore the .patch file.

Blood Machines 2.0 Raw File Access

  • click on the Down arrow button icon next to the pencil icon to download the file as raw text. Save the file in the same directory as the table's .vpx file. The two file names should be exactly the same with only the extension being different. If you have to manually change one or the other, the two are likely incompatible and the sidecar file won't work. The one exception is if at some point you manually renamed the .vpx file yourself. Your table directory should look like this
Blood Machines (Original 2022)
├── Blood Machines 2.0.vbs
├── Blood Machines 2.0.vpx
... any other files ...

After running through these steps, give the table a try. VPinball should automatically pick up the sidecar .vbs file and override that contained within the .vpx file.

Should you wish to extract the VBScript .vbs file from the .vpx file so you can make your own changes, you can do so from the command line with the -extractvbs parameter and the path to the table. Here's an example for Getaway - High Speed II using the BGFX version of VPX on Linux:

./VPinballX_BGFX -extractvbs "/bigdisk/dk/games/vpinball/The Getaway - High Speed II (Williams 1992)/Getaway_(Williams 1992)_mod_1.0.vpx"

VPX will extract the Getaway_(Williams 1992)_mod_1.0.vbs script file and place it alongside the Getaway_(Williams 1992)_mod_1.0.vpx table file.

The .directb2s Backglass File

TODO

The cache Subdirectory

The cache directory is used for caching data to improve performance. At time of writing, it is only used to store the list of textures which are used by each table during play. This allows for preloading of the needed textures in subsequent runs, limiting stutters during play.

Table Name (Manufacturer Year)/
├── cache/
│   └── ...

VPX manages the contents of this directory itself so just let it do its thing. In fact, it is safe to delete the cache directly entirely: VPX will simply regenerate it the next time the table is played.

Tip

If you see corruption or missing textures on some parts of the table, try deleting the cache directory. This problem pops up for some people now and then when upgrading from an older build. The cache can be permanently disabled by searching for CacheMode in the VPinballX.ini file and setting it to CacheMode = 0

The medias Subdirectory

This subdirectory is reserved for frontends like VPinFE to store files and is not used by VPX itself.

Table Name (Manufacturer Year)/
├── medias/
│   ├── (Backglass) Table Name (Manufacturer Year).mp4
│   ├── (Playfield) Table Name (Manufacturer Year).mp4
│   ├── (Wheel) Table Name (Manufacturer Year).apng
│   └── ...

VPinball suggests a file structure like that above but the frontend is free to use its own naming convention within this folder: VPinball doesn't use the medias directory itself so it doesn't care what the frontend chooses to do. Refer to the VPinball File Layout docs for more details on the suggested guidelines for this directory if you're interested.

The pinmame Subdirectory

The pinmame subdirectory is the second most important folder in the table directory structure.

Table Name (Manufacturer Year)/
├── pinmame/
│   ├── roms/
│   │   ├── xxx.zip
│   │   └── yyy.zip
│   ├── nvram/
│   │   ├── xxx.nv
│   │   └── yyy.nv
│   ├── cfg/
│   │   ├── default.cfg
│   │   ├── xxx.cfg
│   │   └── yyy.cfg
│   ├── altcolor/
│   │   ├── xxx.zip
│   │   └── yyy.zip
│   └── alias.txt

Tables that are recreations of real machines use PinMAME to emulate the electronic hardware and run the same code as the originals. If you are familiar with MAME, PinMAME is the pinball equivalent. PinMAME is in fact built as an add-on to the historic MAME 0.76 source code.

The pinmame/roms Subdirectory

Tip

One of the most common VPinball questions is "where do my ROMs go?" They go into this directory.

The roms subdirectory within pinmame contains the emulated machine's original program code in .zip format. VPinball does not ship with ROMs so you'll need to track them down for yourself. Thankfully, the Virtual Pinball Spreadsheet will often provide a link to a table's ROM, often from sites like VPUniverse, VPForums, and Archive.org.

Generally speaking, there is one zipped ROM file per table unless you have specified an alias. The name of the ROM is completely unrelated to the name of the table. For example, Black Knight 2000 (Williams 1989) has a VPX file named something like Black Knight 2000 (Williams 1989) w VR Room v2.0.2.vpx and a ROM named bk2k_l4.zip.

If a PinMAME-based game is not running after repeated attempts, chances are VPinball can't find the correct ROMs. In the case of Black Knight, VPinball will display the message Failed to start emulation of rom 'bk2k_l4' on the playfield display and the table will appear frozen. The vpinball.log file in the config directory will also show NOT FOUND messages like these:

2026-09-06 14:01:14.481 ERROR [33755] [PinMAME:PinMAME::OnLogMessage@235] display_rom_load_results():
bk2k_u26.l4  NOT FOUND
bk2k_u27.l4  NOT FOUND
bk2k_u21.l1  NOT FOUND
bk2k_u22.l1  NOT FOUND
SOUND WAS DISABLED DUE TO PROBLEMS WITH SOUND ROMS
ERROR: required files are missing, the game cannot be run.

If a PinMAME-based table freezes the first time you try to run it but works fine on subsequent runs, that is expect behavior as discussed in the NVRAM section.

Important

Never unzip the ROM files! VPinball expects to find them zipped and won't be able to find them otherwise. For the same reason, never rename the ROM files: the ROM file name is specified within the PinMAME source code and can't be user-specified.

The pinmame/nvram Subdirectory

PinMAME emulation of the real machine's hardware includes that of any non-volatile RAM (NVRAM) in that machine as required. The nvram subdirectory within pinmame then contains a file representing that data across runs. This type of data includes service menu settings, high scores, number of credits, etc.

The name of the file will be the same as that of the ROM but with an .nv extension. Using Black Knight 2000 (Williams 1989), as an example, VPinball will require a ROM named bk2k_l4.zip and will create a file in the nvram subdirectory named bk2k_l4.nv. There is one .nv file per table unless you have specified an alias. VPinball manages this file for you automatically so just let it do its thing and don't worry about it. Deleting the file effectively resets the machine to factory defaults.

Important

The first time you run many PinMAME-based tables, VPinball will lock up as soon as the main playfield is displayed because the .nv NVRAM file did not exist. Exit VPinball and try the table again. VPinball should create a default .nv file in the nvram subdirectory that allows it to start up successfully the second time. If VPinball locks up every time, you might not have the ROMS installed correctly.

The pinmame/cfg Subdirectory

TODO

The pinmame/altcolor Subdirectory

TODO

The pinmame/alias.txt File

Note

The multi-line vpmalias.txt file that was supported in VPX 10.8.0 that used a separate VPinmame install is no longer supported by the newer "Standalone" versions of VPinball that use the built in libpinmame plugin. vpmalias.txt has been replaced by this per-table folder single-line alias.txt version described here (Reference). Tables that automated the addition of an entry to the vpmalias.txt file like Mass Effect Version 1.0.7 won't work unless you manually create the alias.txt file yourself. Tables like Godzilla Limited Edition Dual Table Pup that instructed manual addtions to vpmalias.txt must also be adjusted accordingly.

The alias.txt file within the pinmame directory is used if you want to use the same ROM with different settings for different tables. But why would you want to do this? A prime example is the table Mass Effect. Mass Effect is a reskin of JP Salas' Attack from Mars and both of them use a ROM named afm_113b. The problem is that any changes to the NVRAM or Config settings on one table could in some cases interfere with the other table.

To work around this, Mass Effect's table script specifies a ROM named afm_113b_me that doesn't actually exist. Instead it depends on an alias.txt file with this single line in it:

afm_113b_me,afm_113b

When Mass Effect runs, VPinball will see that it asks for the afm_113b_me ROM but it will provide the game with the real afm_113b ROM instead. Also, VPinball will respect the original afm_113b_me ROM name when it comes to NVRAM and Config directories so that the two tables won't interfere with each other's settings.

The serum DMD Colorization Subdirectory

VPinball supports a number of DMD colorization schemes that bring multiple colors to what were originally monochromatic displays. Serum is the newest of the three possible DMD colorization schemes besides the open VNI format and the closed PAC format and brings numerous advantages over the other two. Serum is:

  • completely open source with no license keys required, unlike the PAC format
  • actively developed
  • 65K color support
  • low in memory usage (when using the compressed .cromc format vs the original .crz format) Reference

This snippet from the file layout tree shows the Serum file locations expected by the latest version of VPinball:

Table Name (Manufacturer Year)/
├── serum/
    └── xxx/
        └── xxx.crz (or .cromc)

Let's work through an example of installing a Serum colorization file for AC/DC Luci.

  • Ensure you have Serum Plugin support enabled within VPinball: F12 -> Plugin Settings -> Serum -> Enable -> Save changes -> Save globally
  • Assuming you already have the table itself working, create a serum directory within the AC/DC Luci table directory
  • AC/DC's ROM is named acd_170h so create a subdirectory of that name within the serum directory
  • Head over to the Virtual Pinball Spreadsheet and search for "AC/DC Luci Premium". Select the table found in the search result
  • Scroll down to the "Colored Roms" section of the page and you should see a link to the Serum file acd_170h.cROMc on VPU. Click that link to be redirected

AC/DC Serum link

When you're done, your table directory should look something like this:

AC-DC LUCI Premium VR (Stern 2013)
├── AC-DC LUCI Premium VR (Stern 2013) v1.1.3.vpx
└── serum/
    └── acd_170h/
        └── acd_170h.cromc
... any other files ...

After running through these steps, give the table a try. VPinball should automatically pick up the files in the serum directory and you should be greeted with a colorized DMD display.

AC/DC Luci Colorized DMD via Serum

VPinball also support a fallback location for Serum files in pinmame/altcolor at time of writing but this may break in the future if fallback support is removed:

AC-DC LUCI Premium VR (Stern 2013)
├── AC-DC LUCI Premium VR (Stern 2013) v1.1.3.vpx
├── pinmame/
    └── altcolor/
        └── acd_170h/
            └── acd_170h.cromc
... any other files ...

The vni DMD Colorization Subdirectory

As discussed in the section on Serum,VPinball supports a number of DMD colorization schemes that bring multiple colors to what were originally monochromatic displays. VNI is an older method originally designed for the Pin2DMD project that delivered a full color LED DMD controller for real and virtual pinball machines. The VNI approach always requires two files: a .pal file and a .vni file. We won't talk much more about the format on this page because the wiki has an entire page dedicated to the this format and all of the openly available tables it supports.

This snippet from the file layout tree shows the file locations expected by the latest version of VPinball:

Table Name (Manufacturer Year)/
└── vni/
    └── xxx/
        ├── xxx.pal
        └── xxx.vni

The trick is that you'll often find VNI colorization files as pin2dmd.pal and pin2dmd.vni so some renaming may be in order for some tables. An example of this is Monster Bash (Williams 1998) VPWmod. Let's use that table as an example.

  • Ensure you have VNI Plugin support enabled within VPinball: F12 -> Plugin Settings -> VNI -> Enable -> Save changes -> Save globally
  • Assuming you already have the table itself working, create a vni directory within the Monster Bash table directory
  • Monster Bash's ROM is named mb_106b so create a subdirectory of that name within the vni directory
  • Head over to the wiki's VNI plugin page and click on Monster Bash. Save the pin2dmd.pal and the pin2dmd.vni files to the vni/mb106_b directory
  • rename pin2dmd.pal to mb106_b.pal (skip this step if the file for your table is already named after the ROM)
  • rename pin2dmd.vni to mb106_b.vni (skip this step if the file for your table is already named after the ROM)

When you're done, your table directory should look something like this:

Monster Bash (Williams 1998)
├── Monster Bash (Williams 1998) VPWmod v1.0.vpx
└── vni/
    └── mb_106b/
        ├── mb_106b.pal
        └── mb_106b.vni
... any other files ...

After running through these steps, give the table a try. VPinball should automatically pick up the files in the vni directory and you should be greeted with a colorized DMD display.

Monster Bash Colorized DMD via VNI

Having said all that, VPinball does support pin2dmd file names at time of writing but this may break in the future if fallback support is removed:

Monster Bash (Williams 1998)
├── Monster Bash (Williams 1998) VPWmod v1.0.vpx
└── vni/
    └── mb_106b/
        ├── pin2dmd.pal
        └── pin2dmd.vni
... any other files ...

Ditto this layout...

Monster Bash (Williams 1998)
├── Monster Bash (Williams 1998) VPWmod v1.0.vpx
├── pinmame/
    └── mb_106b/
        ├── mb_106b.pal
        └── mb_106b.vni
... any other files ...

... and this one

Monster Bash (Williams 1998)
├── Monster Bash (Williams 1998) VPWmod v1.0.vpx
├── pinmame/
    └── altcolor/
        └── mb_106b/
            └── pin2dmd.pal
            └── pin2dmd.vni
... any other files ...

Clone this wiki locally