feat: add Steam Proton launcher for Linux (closes #128)#184
feat: add Steam Proton launcher for Linux (closes #128)#184felipefl142 wants to merge 12 commits into
Conversation
Implements ProtonLauncher for running Balatro via Steam Proton on Linux. Previously, `get_launcher()` raised `NotImplementedError` on Linux. This adds full support via Steam's Proton compatibility layer. ## How it works Balatro runs as a Windows executable under Wine/Proton. The launcher: - Invokes Proton as: `proton run Balatro.exe` - Sets `WINEDLLOVERRIDES=version=n,b` so Wine loads lovely-injector's `version.dll` DLL hijack (same mechanism as the Windows launcher) - Sets `STEAM_COMPAT_DATA_PATH` and `STEAM_COMPAT_CLIENT_INSTALL_PATH` required by Proton ## Auto-detection All paths are auto-detected if not explicitly configured: - **Balatro**: `~/.local/share/Steam/steamapps/common/Balatro` - **Proton**: scans `compatibilitytools.d/` and `steamapps/common/`, prefers GE-Proton > official Proton > Experimental by version number - **lovely-injector**: `version.dll` in the Balatro directory - **Compat data**: `steamapps/compatdata/2379780` ## Platform values Both `"linux"` (auto-detected) and `"proton"` (explicit override via `BALATROBOT_PLATFORM`) route to `ProtonLauncher`.
Remove the 'linux' platform name entirely. Users on Linux must now explicitly pass --platform proton. This avoids ambiguity between Proton (Steam) and native (LOVE) setups.
- Replace test_linux_not_implemented with test_proton_returns_proton_launcher - Add TestProtonLauncher class with 6 tests (build_cmd, build_env, validate_paths error cases) - Update PLATFORM_CHOICES assertion in test_serve_cmd
- Add Linux (Proton) Platform section to cli.md - Update --love-path and --platform descriptions in options table - Replace 'Help Needed' warning in contributing.md with Supported Platforms section - Update CLAUDE.md Platform Abstraction description
Review NotesI reviewed this PR on behalf of @S1M0N38 (pi agent). The core implementation looks correct — I pushed a few follow-up commits on top of this PR to address issues I found:
🚩 For the author to address
Comment by pi agent on behalf of @S1M0N38 |
… vars Add Flatpak and Snap Steam installation paths to _detect_steam_root() as suggested in PR review. Validate that STEAM_COMPAT_CLIENT_INSTALL_PATH and STEAM_COMPAT_DATA_PATH are resolvable in validate_paths(), failing with a clear error if steam_root is undetected and the vars are absent from the environment. Tested: proton run Balatro.exe works with GE-Proton10-34 and Proton Experimental.
|
Addressed all three reviewer flags: Flatpak/Snap Steam paths — added to STEAM_COMPAT_ silent skip* — Verified on hardware —
Auto-detection finds Steam root (only pacman Steam tested for this one), Proton executable, Balatro path, and compat data correctly without any manual flags. Test plan
|
The Snap Steam root is ~/.steam/steam symlink under snap/steam/common, not .local/share/Steam. Without this, _detect_steam_root() returns None on Snap installs, STEAM_COMPAT_DATA_PATH is unset, Proton uses a default Wine prefix where version.dll is absent, and lovely-injector fails to inject.
Wine via Snap Steam accepts TCP connections before the HTTP server is ready, causing ReadError instead of ConnectError. Add ReadError and RemoteProtocolError to the retry loop so health checks retry instead of crashing.
When Steam runs inside a sandbox (snap, Flatpak), calling proton directly from outside fails because the Steam Linux Runtime container is not available. --attach skips process management and waits up to 5 minutes for a game launched externally via Steam. Usage: 1. Set Steam launch options: BALATROBOT_PORT=12346 %command% 2. Launch game via Steam 3. balatrobot serve --attach [--port 12346]
For sandboxed Steam (snap, flatpak) we cannot invoke proton directly
because the Steam Linux Runtime container lives inside the sandbox.
Instead:
- Auto-detect the Steam package type from the Steam root path.
- For native Steam, keep the existing 'proton run Balatro.exe' path.
- For snap/flatpak, delegate to the sandboxed Steam client via:
snap run steam steam://rungameid/<id>
flatpak run com.valvesoftware.Steam steam://rungameid/<id>
and propagate BALATROBOT_* configuration to the game by writing it
to the Wine prefix's user.reg [Environment] section, which Wine
exposes to every process launched in the prefix.
This keeps the workflow identical across package systems:
uvx balatrobot serve --platform proton
Also bumps HEALTH_TIMEOUT from 30s to 90s to tolerate slower starts
when the sandboxed Steam client has to spin up.
Auto-detect via platform.system().lower() returns 'linux', which previously fell through to RuntimeError. Map it to ProtonLauncher alongside explicit 'proton'.
|
Finished testing. It all works. Tested via both flatpak and snap steam installation pathings, on ubuntu 25.10 VM. I had already tested everything via CachyOS (arch based distro, using pacman installed steam). |
Summary
Implements
ProtonLauncherfor running Balatro via Steam Proton on Linux, resolving #128.Previously
get_launcher()raisedNotImplementedErroron Linux. This adds full support by launching Balatro as a Windows executable through Proton.How it works
proton run Balatro.exeWINEDLLOVERRIDES=version=n,bso Wine loads lovely-injector'sversion.dllDLL hijack (same mechanism as the Windows launcher)STEAM_COMPAT_DATA_PATHandSTEAM_COMPAT_CLIENT_INSTALL_PATHrequired by ProtonAuto-detection
All paths are auto-detected if not explicitly configured:
~/.local/share/Steam/steamapps/common/Balatrocompatibilitytools.d/andsteamapps/common/; prefers GE-Proton > official Proton > Experimental, newest version firstversion.dllin the Balatro directorysteamapps/compatdata/2379780All paths can still be overridden via CLI flags or env vars (
BALATROBOT_BALATRO_PATH,BALATROBOT_LOVE_PATH,BALATROBOT_LOVELY_PATH).Platform values
Both
"linux"(auto-detected on Linux hosts) and"proton"(explicit viaBALATROBOT_PLATFORM=proton) route toProtonLauncher.Test plan
balatrobot serveon Linux with Balatro installed via Steam — should launch withoutNotImplementedError~/.local/share/Steam/compatibilitytools.d/)steamapps/common/Proton *)BALATROBOT_PLATFORM=protonoverride works on Linux