emulator: visual-pinball type: standalone core_classification: game_engine source: "https://github.com/vpinball/vpinball" upstream: "https://github.com/vpinball/vpinball" profiled_date: "2026-10-04" source_commit: "a31565f1589c17afd0502a8c6a690f408ede14b2" core_version: "10.8.1" display_name: "Visual Pinball X" cores: - vpinball - visual-pinball systems: - vpinball mode: standalone notes: | Pinball table simulator. The table is the content: .vpx and .vpt files are OLE Compound Documents holding the geometry, textures, sounds and a VBScript program, read through POLE (src/parts/pintable.cpp:1424-1427). Every build other than the Windows editor compiles the shared source set with __STANDALONE__ and links libwinevbs, Wine's VBScript engine with its COM and ATL headers, beside SDL3, SDL3_ttf, FreeImage and hidapi; PinMAME, AltSound, DMDUtil, DOF, FlexDMD, B2S, PUP, Serum, VNI and ScoreView are plugins staged in plugins/ next to the binary (make/CMakeLists_app.txt:525-546,597-603, make/CMakeLists_sources.txt:809-815, make/CMakeLists_plugins.txt:21-25,39-56). ES-DE finds VPinballX_BGFX or VPinballX_GL and runs ` -play `, Batocera builds the standalone tree at 3ec37c7f9a into /usr/bin/vpinball and runs `VPinballX_GL -PrefPath -Ini /VPinballX.ini -Play `, RetroBat drives the Windows build with its registered VPinMAME COM server. File location sits in one class. FileLocator holds m_appPath, the read-only installation folder, and m_prefPath, the preferences folder that -PrefPath overrides, and it works in one of two layout modes: AppPrefData splits static data, settings and table files across the three, AppOnly keeps everything in the application folder, which is the legacy Windows 9x behaviour. Which one applies is decided by where VPinballX.ini is found: in the preferences folder gives AppPrefData, else beside the executable gives AppOnly, else AppPrefData (src/core/FileLocator.h:11-25,57,63-66, src/core/FileLocator.cpp:195-206). The preferences folder is the SDL preference path for VPinballX with a major.minor subfolder (src/core/FileLocator.cpp:46-53). Batocera's 001-default-path.patch redirects the PinMAME root from $HOME/.pinmame to /pinmame. Table scripts pull their libraries through SearchScript, which walks ten locations in order, each case-insensitively: the table's own folder, then user/ and scripts/ beside it, then the installation folder with user/, scripts/ and tables/ under it, then the preferences folder with user/ and scripts/ under it (src/core/FileLocator.cpp:379-412, src/core/ScriptGlobalTable.cpp:346-375). The scripts/ directory the build ships carries the 71 .vbs files tables include by name, core.vbs and controller.vbs beside the per-manufacturer machine scripts (WPC.vbs, sam.vbs, s11.vbs, zac.vbs and the rest), copied from src/scripts (make/CMakeLists_app.txt:619-623). The Windows editor's completion parser asks for core.vbs through the same search without a table, so in the seven installation and preferences locations, and shows a warning box when none holds it (src/ui/win/codeview.cpp:2068-2076, src/core/FileLocator.cpp:238-245). Table scripts also read four directory properties. UserDirectory is the table's user folder, created on demand, TablesDirectory the system documents folder or the installation folder when SDL reports none, MusicDirectory the table's music folder with an optional subfolder, ScriptsDirectory scripts/ under the installation folder; each fails when its directory does not exist (src/core/ScriptGlobalTable.cpp:377-418, src/core/FileLocator.cpp:251-259). In AppPrefData mode user/, music/, cache/ and autosave/ sit beside the table; a folder missing there on a read is looked up the AppOnly way, where user/ hangs off the installation folder and music/ is tried under the installation folder, the table folder, then the preferences folder (src/core/FileLocator.cpp:267-377). The rest of the install tree is read the same way and ships with the binary: assets/ holds BallEnv.exr, AODither.webp and EnvMap.webp, the first two loaded with no fallback (src/renderer/Renderer.cpp:176-188), the bumper and kicker textures (src/parts/bumper.cpp:148,160,172,186, src/parts/kicker.cpp:198-239), the segment display textures (src/renderer/Renderer.cpp:1493-1510), TableSizes.csv, the table size database (src/core/TableDB.cpp:16), vpinball.png for the window icon (src/renderer/Window.cpp:280), LiberationSans-Regular.ttf, the textbox font used when the table folder holds no -