Skip to content

Install on Linux

v1.0 is out. This page gets it running; if it does not, tell us what breaks.

Linux covers ordinary desktops and dedicated cabinets. One build, not a special one. This page gets it running; Getting started takes it from there.

  1. Download vPinOps-linux-x64.zip from Releases.

  2. Unpack it in your home folder.

    Terminal window
    unzip ~/Downloads/vPinOps-linux-x64.zip -d ~

    The zip contains a vpinops folder, so you end up with ~/vpinops/app/. Unpack it anywhere else and everything still works; the paths below just change to match. No unzip on the machine? bsdtar -xf ~/Downloads/vPinOps-linux-x64.zip -C ~ does the same job.

    It carries its own runtime. There is no .NET to install first, and nothing is added to your system. It ran on a machine that had never had .NET on it.

  3. Start it:

    Terminal window
    setsid ~/vpinops/app/vPinOps >/dev/null 2>&1 &

    That starts vPinOps on its own, so you can close the terminal straight away. A plain ~/vpinops/app/vPinOps works too, but it keeps the terminal busy until you quit vPinOps.

    You get a tray icon. That icon is how you talk to vPinOps from now on, and it is the only way to quit it.

    It creates ~/.vpinops/ on this first run: your config, your run log, and a generated OpsLink password. It also creates ~/vPinOpsData/, where your tables and Visual Pinball go. Nothing is installed system-wide and nothing needs root.

    You only need the terminal this once. That first run also puts vPinOps in your applications menu — ~/.local/share/applications/vpinops.desktop, with its icon beside it — so from now on you start it the way you start anything else.

    It is a file in your own home and it is yours: delete it and it stays deleted. If you already wrote one by hand, vPinOps leaves yours alone. To get ours back after deleting it, remove ~/.vpinops/launcher-installed and start vPinOps again.

  4. Install ffmpeg, if you want video on the wheel.

    Playfield and DMD videos are played through ffmpeg, which most distributions ship but do not install by default. Without it a surface shows its still image instead.

    Terminal window
    sudo apt install ffmpeg # Debian, Ubuntu, Kubuntu
    Terminal window
    sudo pacman -S ffmpeg # Arch, Omarchy

    On other distributions it is the same package, installed however your distribution installs software.

  5. Now set it up. Everything from here is the same on every platform, so it lives in one place: Getting started, from step 2.

OpsLink — the page you open on your phone — is an HTTP service on port 7833/tcp. Two separate things decide who can reach it, and they are worth keeping apart.

vPinOps decides which networks it listens on. Settings → Listen on. It is 0.0.0.0 by default, meaning every network this machine is on. Set it to 127.0.0.1 and it is reachable from this machine and nothing else — no phone, ever. That is the strongest lock available and it needs no firewall.

Your firewall decides who gets through. Plenty of Linux desktops run none at all, in which case there is nothing to open and your router is already what keeps the internet out. Find out which one you have before writing a rule for a tool you are not running:

Terminal window
sudo ufw status; sudo firewall-cmd --state; sudo nft list ruleset | head -n 5

Two of those three will say command not found or not running. The one that answers is yours.

Every rule below is scoped to your subnet. Find it:

Terminal window
ip -4 addr show scope global | grep inet

inet 192.168.1.42/24 means your network is 192.168.1.0/24. Substitute yours everywhere below.

Terminal window
sudo ufw allow from 192.168.1.0/24 to any port 7833 proto tcp comment 'vPinOps OpsLink'
Terminal window
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 port port=7833 protocol=tcp accept' && sudo firewall-cmd --reload
Terminal window
sudo nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 7833 accept

— ufw, firewalld, nftables, in that order. The nft rule lasts until you reboot; put it in /etc/nftables.conf to keep it.

To take a rule back, delete it the same way you added it — e.g. sudo ufw delete allow from 192.168.1.0/24 to any port 7833 proto tcp.

Two things decide whether a Linux cab works, and neither is your distribution.

1 · Use a normal user account with auto-login. Not a daemon account.

Section titled “1 · Use a normal user account with auto-login. Not a daemon account.”

A daemon account, a systemd service, a nologin shell, no session, can serve OpsLink perfectly well, because that is just an HTTP listener. What it has no way to do is put a window on a display, because there is no graphical session for it to put one in. That is how Linux works rather than anything about vPinOps.

⇒ So if you want vPinOps to play tables, give it a logged-in graphical session. A normal user with auto-login is exactly that, and it needs no privileges of any kind.

Auto-login is a setting in your display manager, not in vPinOps:

GDM/etc/gdm3/custom.conf, the [daemon] section
LightDM/etc/lightdm/lightdm.conf
SDDM/etc/sddm.conf

Most desktops also expose it in their own Settings → Users panel, which is the easier route.

Then make vPinOps start with that session: in the tray menu, tick Start vPinOps when I log in. It writes a standard autostart entry, ~/.config/autostart/vpinops.desktop, which your desktop runs when you log in. Untick it and the file is gone. With Launch front end at startup also on, the cabinet comes up straight to the wheel. Tested on Omarchy; KDE Plasma reads the same file, but that has not been tried yet.

vPinOps does not write your display manager’s config, and it never will. Those files need root, they differ on every distribution, and a front end that edits them is a front end that breaks somebody’s login. We document it; you choose it.

Your screens work on Wayland. The wheel and its backglass, DMD and topper go where you put them, and Visual Pinball’s own surfaces reach the right monitors too. How they are placed, and what to check when one lands on the wrong monitor, is on Screens and layout.

⚠ Tested on two desktops: KDE Plasma, and Hyprland on Arch Linux (Omarchy). Other desktops, GNOME included, are untested. It is the same download on both — vPinOps notices which desktop it is running under. Linux desktops vary far more than Windows or macOS, so if something does not behave, the run log is what to send us, along with which desktop you use and whether you are on Wayland or X11.

~/vpinops/app/ the program. Ours. Replaced wholesale when you update.
~/vPinOpsData/ your content. Never touched by an update.
tables/ one folder per table
pinmame/ the shared ROM fallback
.inbox/ tables sent from another device land here
visualpinball/ Visual Pinball's own settings
visualpinball/app/ Visual Pinball itself
~/.vpinops/ your config, your run log, your OpsLink password

~/vPinOpsData/ appears when you set your folders in Getting started; the rest is there from the first run.

Keep them separate, as above. An update replaces the program folder and never touches your content. Where things are has the full map.

The programwherever you unpacked it — ~/vpinops/app/ is the suggestion
Your content~/vPinOpsData/
Config~/.vpinops/config.json
Run log — read this first when anything is wrong~/.vpinops/last-run.log
OpsLink password~/.vpinops/remote-password
Uploads waiting to be imported~/vPinOpsData/.inbox
Visual Pinball’s own settingswherever VPX settings points in Settings — by default ~/vPinOpsData/visualpinball/VPinballX.ini

Quit vPinOps from the tray icon, replace ~/vpinops/app/ with the new one, start it again. Your content and your config are in the other two places and are not involved. To uninstall, quit it and delete that folder. Your tables are still yours.