Balatro Mod Development
Create and debug Balatro mods with Steamodded, Lovely, and SMODS.
Quick Agent Selection
When researching, spawn the right agent:
| Need to find... | Use agent | Search boundary |
|---|---|---|
| Game function implementation | game-source-researcher | Balatro_src/ only |
| SMODS API usage/hooks | smods-api-researcher | smods/ only |
| How other mods do X | mod-pattern-researcher | Mods/ folder only |
| Lovely patch syntax | lovely-patch-researcher | lovely files only |
| Run temp script for data | script-runner | N/A (execution) |
Parallel: When researching DIFFERENT sources - spawn multiple agents at once Sequential: When second query depends on first result
See references/sub-agents.md for boundaries, workflow patterns, and creating new agents.
Repo Type Awareness
| Type | Description | Implications |
|---|---|---|
new | My own mod from scratch | Full docs, Logger.lua, localization (en-us/zh-cn) |
fork | Contributing to others' mod | Minimal changes, temp logs only, follow existing patterns |
See templates/project-rules-template.md for detailed rules per type.
File Naming Convention (Claude & Codex)
Both Claude and Codex use the same file structure:
| File | Purpose | Git |
|---|---|---|
INIT.md | Project rules, constraints for AI agents | ignored |
AGENT.md | Mod structure, functions, dependencies, dev status (for handover) | tracked |
mod.config.json | File lists for sync/release scripts | ignored |
docs/knowledge-base.md | Issues & lessons learned | ignored |
AGENT.md Purpose: Enable seamless handover between agents. Another agent should quickly understand mod structure, functions, dependencies, and current development status without losing context.
File Placement Rules
Only these .md files belong in root:
- •
README.md,README_zh.md - •
CHANGELOG.md,CHANGELOG_zh.md - •
AGENT.md,INIT.md - •
LICENSE.md
ALL other .md files MUST go in docs/
External References (No Symlinks Needed)
Access reference code directly via absolute paths. No setup required.
Source Locations (macOS)
| Resource | Path |
|---|---|
| Game Source (desktop) | ~/Development/GitWorkspace/Balatro_src/desktop/ |
| Game Source (mobile) | ~/Development/GitWorkspace/Balatro_src/ios_plus/ |
| Steamodded Source | ~/Development/GitWorkspace/smods/src/ |
| Steamodded Lovely | ~/Development/GitWorkspace/smods/lovely/ |
| Lovely Docs | ~/Development/GitWorkspace/lovely-injector/ |
| Installed Mods | ~/Library/Application Support/Balatro/Mods/ |
| Lovely Logs | ~/Library/Application Support/Balatro/Mods/lovely/log/ |
Source Locations (Windows)
| Resource | Path |
|---|---|
| Game Source | Varies by setup |
| Installed Mods | %APPDATA%/Balatro/Mods/ |
| Lovely Logs | %APPDATA%/Balatro/Mods/lovely/log/ |
Finding Patterns & Examples
When you need to find how something is implemented:
| What to Find | Where to Search | Command |
|---|---|---|
| Game functions | Balatro_src/desktop/ | grep -rn "function Game:start_run" ~/Development/GitWorkspace/Balatro_src/desktop/ |
| SMODS API usage | smods/src/ | grep -rn "SMODS.Joker" ~/Development/GitWorkspace/smods/src/ |
| Lovely patch examples | smods/lovely/ | grep -rn "patches.pattern" ~/Development/GitWorkspace/smods/lovely/ |
| Other mods' implementations | Installed Mods | grep -rn "pattern" ~/Library/Application\ Support/Balatro/Mods/ |
| Mobile differences | Balatro_src/ios_plus/ | Compare with desktop version |
Key Dependencies
| Dependency | Purpose |
|---|---|
| Steamodded | Core mod loader, SMODS API |
| Lovely | Lua injection framework |
| Malverk | Texture pack API (AltTexture, TexturePack) |
Pattern References
Read these files for specific topics:
| Topic | Reference File |
|---|---|
| Lovely.toml syntax | patterns/lovely-patches.md |
| SMODS hooks, config, localization | patterns/smods-api.md |
| Desktop vs mobile differences | patterns/mobile-compat.md |
| UIBox, CardArea, draw order | patterns/ui-system.md |
| Game source file map + search tips | references/game-files.md |
| G.GAME, G.STATES, G.P_* globals | references/globals.md |
New Mod Setup (type: new)
Templates in templates/ folder:
| File | Purpose |
|---|---|
project-rules-template.md | INIT.md template (rules) |
agent-md-template.md | AGENT.md template (repo docs) |
agent-texture-pack-template.md | AGENT.md for Malverk texture packs |
mod-config-template.json | Script configuration |
gitignore-template | Standard .gitignore |
logger-template.lua | Centralized logging utility |
Meta Files:
| File | Purpose |
|---|---|
mod-json-template.json | SMODS mod manifest ({ModName}.json) |
manifest-json-template.json | Thunderstore manifest |
User Docs in templates/docs/:
| File | Purpose |
|---|---|
description-template.md | Concise README for docs/ |
NEXUSMODS_DESCRIPTION-template.txt | BBCode for NexusMods |
knowledge-base-template.md | Issues & lessons learned |
Required User Docs (new repos):
Root:
├── README.md, README_zh.md # Main docs (EN/ZH)
├── CHANGELOG.md, CHANGELOG_zh.md # Version history (EN/ZH)
└── {ModName}.json, manifest.json # Meta files
docs/:
├── description.md # Concise README
├── NEXUSMODS_DESCRIPTION.txt # BBCode format
├── knowledge-base.md # Issues & lessons
└── AGENT.md # Repo structure (AI)
Basic Mod Structure (new repos):
{ModName}/
├── main.lua # Entry point, mod registration
├── config.lua # Config defaults (optional)
├── lovely.toml # Lovely patches (if needed)
├── {ModName}.json # SMODS mod manifest
├── manifest.json # Thunderstore manifest
├── mod.config.json # Script configuration
├── Utils/
│ └── Logger.lua # Centralized logging
├── localization/
│ ├── en-us.lua # English (required)
│ └── zh_CN.lua # Chinese
├── assets/ # Sprites, shaders
├── scripts/ # Utility scripts
└── docs/ # Documentation
AI Agent Config Templates
| Folder | Contents |
|---|---|
templates/claude-config/ | Claude hooks.json, init command |
templates/codex-config/ | Codex-specific templates (if needed) |
Logging
For new/my repos:
Use Utils/Logger.lua (from templates/logger-template.lua):
local Logger = require("Utils.Logger")
local log = Logger.create("ModuleName")
log("info", "Initialized")
log("error", "Failed: " .. err)
For forks/others' repos:
Use temp logs only (remove before PR):
pcall(print, "[Debug] checkpoint: " .. tostring(var))
Utility Scripts
| Script | Purpose |
|---|---|
scripts/sync_to_mods.template.sh | Sync mod files to game's Mods folder |
scripts/create_release.template.sh | Create release packages |
scripts/fix_transparent_pixels.py | Fix grey borders on sprites |
scripts/mod-scripts-guide.md | Detailed script usage |
Workflow: Init Any Existing Repo
For ALL non-empty repos (own or fork), ALWAYS do these first:
- •Delete
References/folder if exists (legacy symlink approach) - •Move extra
.mdfiles todocs/- only keep in root: README*.md, CHANGELOG*.md, AGENT.md, INIT.md, LICENSE.md - •Add dev files (if missing): AGENT.md, INIT.md, mod.config.json, scripts/sync_to_mods.sh
- •Add Claude config (if missing):
.claude/commands/,.claude/hooks/,.claude/agents/ - •Update .gitignore with agent folders
Then for OWN repos: Also check manifest, scripts version (2.0.1), add create_release.sh, Logger.lua
Then for FORK repos: Keep AGENT.md lightweight, use fork-mode INIT.md, don't add release scripts
Workflow: Debugging
- •Check platform (desktop vs mobile)
- •Search game source for function
- •Check other mods for implementations
- •Add logs (Logger.lua for own, temp for fork)
- •Check Lovely logs
- •If fix fails 3+ times: Document in
docs/knowledge-base.md
Workflow: Update User Docs
When user says "update all user docs":
- •Review ALL files: README(_zh).md, CHANGELOG(_zh).md
- •Review docs/: description.md, NEXUSMODS_DESCRIPTION.txt
- •Update version in {ModName}.json, manifest.json
- •Ensure EN/ZH consistency
Workflow: Draft PR Message (fork repos)
Use /draft-pr command. Style: 3-5 sentences, casual tone, what/why/done.
Sub-Agents for Research
Main agent handles code. Sub-agents handle information gathering.
| Situation | Use |
|---|---|
| Research (game, SMODS, mods, lovely) | Sub-agent |
| Running temp scripts for data | script-runner |
| Writing/editing code | Main agent |
| User interaction needed | Main agent |
See references/sub-agents.md for detailed boundaries, workflow patterns, and creating new agents.
Available Commands
- •
/init-balatro-mod- Initialize new mod - •
/sync-mod- Start sync with watch mode (run once at start) - •
/bump-version [patch|minor|major]- Increment version, update changelogs - •
/release- Create release packages (auto-detects version from manifests) - •
/fix-sprites <directory> [--preview]- Fix grey borders on sprites - •
/refactor [focus-area]- Review code for redundancy, outdated fallbacks, modularization - •
/debug- Verify fix by checking Lovely logs (auto-detects mod key from repo) - •
/draft-pr- Draft PR message (for forks) - •
/update-docs- Review all user docs - •
/update-skill [file|instruction]- Update skill based on new knowledge
Sub-agents available after setup:
- •
game-source-researcher- Find game functions and injection points - •
smods-api-researcher- Find SMODS API patterns and usage - •
mod-pattern-researcher- Find how other mods implement features - •
lovely-patch-researcher- Find Lovely patch syntax and examples - •
script-runner- Run temp scripts and return results