Skip to content

feat: add Steam Proton launcher for Linux (closes #128)#184

Open
felipefl142 wants to merge 12 commits into
coder:mainfrom
felipefl142:feat/linux-proton-launcher
Open

feat: add Steam Proton launcher for Linux (closes #128)#184
felipefl142 wants to merge 12 commits into
coder:mainfrom
felipefl142:feat/linux-proton-launcher

Conversation

@felipefl142
Copy link
Copy Markdown

@felipefl142 felipefl142 commented Apr 15, 2026

Summary

Implements ProtonLauncher for running Balatro via Steam Proton on Linux, resolving #128.

Previously get_launcher() raised NotImplementedError on Linux. This adds full support by launching Balatro as a Windows executable through Proton.

How it works

  • 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:

Path Default location
Balatro game dir ~/.local/share/Steam/steamapps/common/Balatro
Proton executable Scans compatibilitytools.d/ and steamapps/common/; prefers GE-Proton > official Proton > Experimental, newest version first
lovely-injector version.dll in the Balatro directory
Compat data steamapps/compatdata/2379780

All 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 via BALATROBOT_PLATFORM=proton) route to ProtonLauncher.

Test plan

  • balatrobot serve on Linux with Balatro installed via Steam — should launch without NotImplementedError
  • Works with GE-Proton (community builds in ~/.local/share/Steam/compatibilitytools.d/)
  • Works with official Proton (steamapps/common/Proton *)
  • Explicit BALATROBOT_PLATFORM=proton override works on Linux
  • Error messages are clear when paths can't be auto-detected

felipefl142 and others added 4 commits April 15, 2026 02:50
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
@S1M0N38
Copy link
Copy Markdown
Collaborator

S1M0N38 commented Apr 19, 2026

Review Notes

I reviewed this PR on behalf of @S1M0N38 (pi agent). The core implementation looks correct — proton run Balatro.exe, WINEDLLOVERRIDES=version=n,b, and STEAM_COMPAT_* env vars all match the SMODS wiki and lovely-injector approach.

I pushed a few follow-up commits on top of this PR to address issues I found:

  • Renamed linuxproton as the only platform name (removed the linux alias). Users must pass --platform proton explicitly.
  • Fixed CLI which was rejecting --platform proton due to a stale allowlist.
  • Updated tests — the old test_linux_not_implemented was broken, added TestProtonLauncher with 6 tests.
  • Updated docs (cli.md, contributing.md, CLAUDE.md).

🚩 For the author to address

  1. STEAM_COMPAT_DATA_PATH silently skipped — In build_env(), if _detect_steam_root() returns None (user set paths manually, Steam not in a standard location), both STEAM_COMPAT_CLIENT_INSTALL_PATH and STEAM_COMPAT_DATA_PATH are silently omitted. Proton likely needs these. Consider validating them in validate_paths() with a clear error.

  2. Flatpak/Snap Steam paths_detect_steam_root() checks ~/.local/share/Steam, ~/.steam/steam, and /usr/local/share/Steam. The SMODS wiki also documents Flatpak (~/.var/app/com.valvesoftware.Steam/.local/share/Steam) and Snap (~/snap/steam/common/.local/share/Steam) paths. Worth adding?

  3. Please verify on your hardware — The unit tests cover the API contract (build_cmd, build_env, error messages) but not actual Proton execution. Please confirm:

    • proton run Balatro.exe launches the game with the mod injected
    • Auto-detection finds your Steam/Proton/Balatro paths correctly

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.
@felipefl142
Copy link
Copy Markdown
Author

felipefl142 commented Apr 20, 2026

Addressed all three reviewer flags:

Flatpak/Snap Steam paths — added to _detect_steam_root() candidates.

STEAM_COMPAT_ silent skip* — validate_paths() now raises a clear error if steam_root is undetected and STEAM_COMPAT_CLIENT_INSTALL_PATH/STEAM_COMPAT_DATA_PATH are absent from the environment, listing all searched paths and how to set them manually.

Verified on hardwareproton run Balatro.exe launches correctly with mods injected on both:

  • GE-Proton10-34
  • Proton Experimental

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

  • balatrobot serve on Linux with Balatro installed via Steam on Flatpak/Snap — should launch without NotImplementedError
  • Error messages are clear when paths can't be auto-detected

felipefl142 and others added 7 commits April 19, 2026 21:59
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'.
@felipefl142
Copy link
Copy Markdown
Author

felipefl142 commented May 11, 2026

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants