-
Notifications
You must be signed in to change notification settings - Fork 4
feat(platforms): add CLI support for Linux through Proton #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add steam_path field to Config dataclass and --steam-path CLI argument for specifying Steam installation path on Linux systems. - Add BALATROBOT_STEAM_PATH environment variable mapping - Add --steam-path CLI flag with help text
Add LinuxLauncher class for running Balatro through Steam's Proton compatibility layer on Linux systems. Features: - Auto-detect Steam installation from known paths: - ~/.local/share/Steam (standard) - ~/.steam/steam (symlink) - ~/snap/steam/common/.local/share/Steam (Snap) - ~/.var/app/com.valvesoftware.Steam/.local/share/Steam (Flatpak) - Auto-detect Proton runtime (Experimental or latest versioned) - Set required Proton environment variables: - STEAM_COMPAT_CLIENT_INSTALL_PATH - STEAM_COMPAT_DATA_PATH - WINEDLLOVERRIDES for lovely injection - Launch via: proton run Balatro.exe Closes #128
Update get_launcher() to return LinuxLauncher for 'linux' platform instead of raising NotImplementedError.
- Add TestLinuxLauncher class with Linux-only tests - Test validate_paths error cases (missing/invalid Steam dir) - Test build_env includes Proton environment variables - Test build_cmd returns correct proton run command - Update test_linux_not_implemented to test_linux_returns_linux_launcher
|
Hey @stirby 👋 Since you have Balatro installed with Proton on Linux, would you mind testing this PR? Quick Test Instructions# Checkout the PR
gh pr checkout 134
# Install dependencies and run all checks
make all
# Run platform tests specifically (Linux-only tests will run on your machine)
pytest tests/cli/test_platforms.py -v
# Run just the new Linux launcher tests
pytest tests/cli/test_platforms.py::TestLinuxLauncher -vManual Testing# Test auto-detection (should find your Steam installation)
balatrobot --platform linux --debug
# Or specify Steam path explicitly
balatrobot --platform linux --steam-path ~/.local/share/Steam --debugWhat to verify
Let me know if you hit any issues! 🎴 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements Linux platform support for BalatroBot by adding a new launcher that uses Steam's Proton compatibility layer to run the Windows version of Balatro on Linux. The implementation includes automatic detection of Steam installation paths, Proton runtimes, and game files, with comprehensive configuration options via CLI arguments and environment variables.
Key Changes:
- Added
LinuxLauncherclass with auto-detection for Steam, Proton, and Balatro paths - Extended configuration system with
steam_pathfield andBALATROBOT_STEAM_PATHenvironment variable - Implemented Proton environment setup with Wine DLL overrides for lovely injector support
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/balatrobot/platforms/linux.py |
New launcher implementation with Steam/Proton detection and validation logic |
src/balatrobot/platforms/__init__.py |
Updated platform factory to return LinuxLauncher for Linux platform |
src/balatrobot/config.py |
Added steam_path field to Config dataclass and environment variable mapping |
src/balatrobot/cli.py |
Added --steam-path CLI argument for specifying Steam installation path |
tests/cli/test_platforms.py |
Added basic test coverage for LinuxLauncher validation and command building |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/balatrobot/platforms/linux.py
Outdated
| # Find versioned Proton installations (e.g., "Proton 9.0", "Proton 8.0") | ||
| proton_dirs = [] | ||
| for entry in common.iterdir(): | ||
| if entry.is_dir() and entry.name.startswith("Proton "): | ||
| match = re.match(r"Proton (\d+(?:\.\d+)?)", entry.name) | ||
| if match: | ||
| version = float(match.group(1)) |
Copilot
AI
Jan 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converting version strings to float for comparison can lead to incorrect sorting for versions with multiple decimal points. For example, "Proton 8.0.5" would be captured as "8.0" and converted to 8.0, while "Proton 8.1" would be 8.1. However, the regex r"Proton (\d+(?:\.\d+)?)" only captures one optional decimal component, so this limitation is consistent. Consider documenting this limitation or using a more robust version comparison approach if multi-decimal versions are expected in the future.
| # Find versioned Proton installations (e.g., "Proton 9.0", "Proton 8.0") | |
| proton_dirs = [] | |
| for entry in common.iterdir(): | |
| if entry.is_dir() and entry.name.startswith("Proton "): | |
| match = re.match(r"Proton (\d+(?:\.\d+)?)", entry.name) | |
| if match: | |
| version = float(match.group(1)) | |
| # Find versioned Proton installations (e.g., "Proton 9.0", "Proton 8.0", "Proton 8.0.5") | |
| proton_dirs = [] | |
| for entry in common.iterdir(): | |
| if entry.is_dir() and entry.name.startswith("Proton "): | |
| # Capture one or more dot-separated numeric components after "Proton " | |
| match = re.match(r"Proton (\d+(?:\.\d+)*)", entry.name) | |
| if match: | |
| version_str = match.group(1) | |
| # Parse version into a tuple of integers for correct numeric sorting | |
| version = tuple(int(part) for part in version_str.split(".")) |
| @pytest.mark.skipif(not IS_LINUX, reason="Linux only") | ||
| class TestLinuxLauncher: | ||
| """Tests for LinuxLauncher (Linux only).""" | ||
|
|
||
| def test_validate_paths_missing_steam(self, tmp_path): | ||
| """Raises RuntimeError when Steam installation not found.""" | ||
| launcher = LinuxLauncher() | ||
| config = Config(steam_path=str(tmp_path / "nonexistent")) | ||
|
|
||
| with pytest.raises(RuntimeError, match="Steam directory not found"): | ||
| launcher.validate_paths(config) | ||
|
|
||
| def test_validate_paths_invalid_steam(self, tmp_path): | ||
| """Raises RuntimeError when Steam directory has no steamapps.""" | ||
| # Create a fake Steam directory without steamapps | ||
| steam_path = tmp_path / "Steam" | ||
| steam_path.mkdir() | ||
|
|
||
| launcher = LinuxLauncher() | ||
| config = Config(steam_path=str(steam_path)) | ||
|
|
||
| with pytest.raises(RuntimeError, match="Invalid Steam directory"): | ||
| launcher.validate_paths(config) | ||
|
|
||
| def test_build_env_includes_proton_vars(self, tmp_path): | ||
| """build_env includes Proton compatibility environment variables.""" | ||
| launcher = LinuxLauncher() | ||
| config = Config(steam_path="/path/to/Steam") | ||
|
|
||
| env = launcher.build_env(config) | ||
|
|
||
| assert env["STEAM_COMPAT_CLIENT_INSTALL_PATH"] == "/path/to/Steam" | ||
| assert "compatdata/2379780" in env["STEAM_COMPAT_DATA_PATH"] | ||
| assert env["WINEDLLOVERRIDES"] == "version=n,b" | ||
|
|
||
| def test_build_cmd(self, tmp_path): | ||
| """build_cmd returns proton run command.""" | ||
| launcher = LinuxLauncher() | ||
| config = Config( | ||
| balatro_path="/path/to/proton", | ||
| love_path="/path/to/Balatro.exe", | ||
| ) | ||
|
|
||
| cmd = launcher.build_cmd(config) | ||
|
|
||
| assert cmd == ["/path/to/proton", "run", "/path/to/Balatro.exe"] |
Copilot
AI
Jan 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test coverage for LinuxLauncher is incomplete compared to other platform launchers. Consider adding tests for:
- Missing Balatro.exe (similar to test_validate_paths_missing_balatro_exe in WindowsLauncher)
- Missing version.dll (similar to test_validate_paths_missing_version_dll in WindowsLauncher)
- Missing Proton runtime
- Missing Proton prefix (compatdata directory)
- Platform check validation (testing the RuntimeError when not on Linux)
- Add --steam-path option to CLI options table - Add 'Linux Platform (Proton)' section with: - Auto-detected paths (Steam, Balatro.exe, version.dll, Proton) - Requirements (Steam, Proton, Lovely, Proton prefix) - Launch examples
Use tuple instead of float for semantic version comparison to correctly handle multi-decimal versions like 'Proton 8.0.5'. - Change regex from \d+(?:\.\d+)? to \d+(?:\.\d+)* to capture all parts - Parse version as tuple: '8.10' -> (8, 10) for correct comparison - Fixes: (8, 10) > (8, 9) vs incorrect float 8.10 < 8.9
Add test_validate_paths_missing_proton_prefix to verify LinuxLauncher raises RuntimeError when compatdata directory doesn't exist.
Summary
Implements Linux platform support for BalatroBot using Steam's Proton compatibility layer.
Closes #128
Changes
Configuration
steam_pathfield toConfigdataclass--steam-pathCLI argumentBALATROBOT_STEAM_PATHenvironment variableLinux Launcher (
src/balatrobot/platforms/linux.py)LinuxLauncherclass for running Balatro through Proton~/.local/share/Steam(standard)~/.steam/steam(symlink)~/snap/steam/common/.local/share/Steam(Snap)~/.var/app/com.valvesoftware.Steam/.local/share/Steam(Flatpak)STEAM_COMPAT_CLIENT_INSTALL_PATHSTEAM_COMPAT_DATA_PATHWINEDLLOVERRIDES="version=n,b"for lovely injectionTests
TestLinuxLauncherwith Linux-only tests (@pytest.mark.skipif)Usage
Requirements
version.dll) in Balatro directory