Contributing
Guide for contributing to BalatroBot development.
Help Needed: Linux (Proton) Support
We currently lack CLI support for Linux (Proton). Contributions to implement this platform are highly welcome!
Please refer to the existing implementations for guidance:
- macOS:
src/balatrobot/platforms/macos.py - Windows:
src/balatrobot/platforms/windows.py - Linux (Native):
src/balatrobot/platforms/native.py
Prerequisites
- Balatro (v1.0.1+)
- Lovely Injector (v0.8.0+) - Installation
- Steamodded (v1.0.0-beta-1221a+) - Installation
- DebugPlus (v1.5.1+) (optional) - Required for test endpoints
Development Environment Setup
direnv (Recommended)
We use direnv to automatically manage environment variables and virtual environment activation. When you cd into the project directory, direnv automatically loads settings from .envrc.
Contains Secrets
The .envrc file may contain API keys and tokens. Never commit this file.
Example .envrc configuration:
# Load the virtual environment
source .venv/bin/activate
# Python-specific variables
export PYTHONUNBUFFERED="1"
export PYTHONPATH="${PWD}/src:${PYTHONPATH}"
export PYTHONPATH="${PWD}/tests:${PYTHONPATH}"
# BALATROBOT env vars
export BALATROBOT_FAST=1
export BALATROBOT_DEBUG=1
export BALATROBOT_LOVE_PATH='/path/to/Balatro/love'
export BALATROBOT_LOVELY_PATH='/path/to/liblovely.dylib'
export BALATROBOT_PARALLEL=1
export BALATROBOT_RENDER_ON_API=0
export BALATROBOT_HEADLESS=1
export BALATROBOT_AUDIO=0
Setup: Install direnv, then create .envrc in the project root with the above configuration, updating paths for your system.
Lua LSP Configuration
The .luarc.json file should be placed at the root of the balatrobot repository. It configures the Lua Language Server for IDE support (autocomplete, diagnostics, type checking).
Update Library Paths
You must update the workspace.library paths in .luarc.json to match your system:
- Steamodded LSP definitions:
path/to/Mods/smods/lsp_def - Love2D library:
path/to/love2d/library(clone locally: LuaCATS/love2d) - LuaSocket library:
path/to/luasocket/library(clone locally: LuaCATS/luasocket)
Example .luarc.json:
{
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
"workspace.library": [
"/path/to/Balatro/Mods/smods/lsp_def",
"/path/to/love2d/library",
"/path/to/luasocket/library"
],
"diagnostics.disable": ["lowercase-global"],
"diagnostics.globals": ["G"]
}
Development Setup
1. Clone the Repository
git clone https://github.com/your-repo/balatrobot.git
cd balatrobot
2. Symlink to Mods Folder
Instead of copying files, create a symlink for easier development:
macOS:
ln -s "$(pwd)" ~/Library/Application\ Support/Balatro/Mods/balatrobot
Linux:
ln -s "$(pwd)" ~/.local/share/Steam/steamapps/compatdata/2379780/pfx/drive_c/users/steamuser/AppData/Roaming/Balatro/Mods/
Windows (PowerShell as Admin):
New-Item -ItemType SymbolicLink -Path "$env:APPDATA\Balatro\Mods\balatrobot" -Target (Get-Location)
3. Activate Virtual Environment
Activate the virtual environment to use the balatrobot command:
macOS/Linux:
source .venv/bin/activate
Windows (PowerShell):
.venv\Scripts\Activate.ps1
4. Launch Balatro
Start with debug and fast mode for development:
balatrobot --debug --fast
For detailed CLI options, see the CLI Reference.
5. Running Tests
Tests use Python + pytest to communicate with the Lua API. You don't need to have balatrobot running—the tests automatically start the required Balatro instances.
Separate Lua and CLI test suites
The Lua and CLI test suites must be run separately. Running them together (e.g., pytest tests) is not supported.
# Install all dependencies
make install
# Run all tests (runs CLI and Lua suites separately)
make test
# Run Lua tests (parallel execution recommended)
# Use -n 6 (or lower if your system is resource constrained)
pytest -n 6 tests/lua
# Run CLI tests (must be run separately)
pytest tests/cli
# Run specific test file
pytest tests/lua/endpoints/test_health.py -v
# Run tests with dev marker only
pytest -n 6 tests/lua -m dev
# Run only integration tests (starts Balatro)
pytest tests/lua -m integration
# Run tests that do not require Balatro instance
pytest tests/lua -m "not integration"
Available Make Commands
The project includes a Makefile with convenient targets for common development tasks. Run make help to see all available commands.
make help # Show all available commands with descriptions
make install # Install all dependencies (dev + test groups)
make lint # Run ruff linter with auto-fix
make format # Format code (Python, Markdown, Lua)
make typecheck # Run type checker (ty)
make quality # Run all code quality checks
make fixtures # Generate test fixtures (starts Balatro)
make test # Run all tests (CLI + Lua suites)
make all # Run quality checks + tests
Test Fixtures
The make fixtures command is only required if you need to explicitly generate fixtures. When running tests, missing fixtures are automatically generated if required.
Code Structure
src/lua/
├── core/
│ ├── server.lua # HTTP server
│ ├── dispatcher.lua # Request routing
│ └── validator.lua # Schema validation
├── endpoints/ # API endpoints
│ ├── tests/ # Test-only endpoints
│ ├── health.lua
│ ├── gamestate.lua
│ ├── play.lua
│ └── ...
└── utils/
├── types.lua # Type definitions
├── enums.lua # Enum values
├── errors.lua # Error codes
├── gamestate.lua # State extraction
└── openrpc.json # API spec
Adding a New Endpoint
- Create
src/lua/endpoints/your_endpoint.lua:
return {
name = "your_endpoint",
description = "Brief description",
schema = {
param_name = {
type = "string",
required = true,
description = "Parameter description",
},
},
requires_state = { G.STATES.SHOP }, -- Optional
execute = function(args, send_response)
-- Implementation
send_response(BB_GAMESTATE.get_gamestate())
end,
}
- Add tests in
tests/lua/endpoints/test_your_endpoint.py
When writing tests for new endpoints, you can use the
@pytest.mark.devdecorator to only run the tests you are developing withpytest -n 6 tests/lua -m dev.
-
Update
src/lua/utils/openrpc.jsonwith the new method -
Update
docs/api.mdwith the new method
Code Quality
Before committing, always run:
make quality # Runs lint, typecheck, and format
Test markers:
@pytest.mark.dev: Run only tests under development with-m dev@pytest.mark.integration: Tests that start Balatro (skip with-m "not integration")
Pull Request Guidelines
- One feature per PR - Keep changes focused
- Add tests - New endpoints need test coverage
- Update docs - Update api.md and openrpc.json for API changes
- Run code quality checks - Execute
make qualitybefore committing (see Code Quality Tools) - Test locally - Ensure both
pytest -n 6 tests/luaandpytest tests/clipass
CI/CD Pipeline
The project uses GitHub Actions for continuous integration and deployment.
Workflows
- code_quality.yml: Runs linting, type checking, and formatting on every PR (equivalent to
make quality) - deploy_docs.yml: Deploys documentation to GitHub Pages when a release is published
- release_please.yml: Automated version management and changelog generation
- release_pypi.yml: Publishes the package to PyPI on release
For Contributors
You don't need to worry about most CI/CD workflows—just ensure your PR passes the code quality checks:
make quality # Run this before pushing
If CI fails on your PR, check the workflow logs on GitHub for details. Most issues can be fixed by running make quality locally.