

Hello! Just wanted to take this moment to thank everyone in this amazing community for their ingenuity and creativity and wonderful drive. It's really rare for a game to persist for as long as Balatro and I'm so proud that I have been able to be a part of it for the past (almost) two years.
I can't even begin to explain how thankful I am to have the incredible @WilsontheWolf and @cg-223. They have taken care of so much work between now and v0.8.0 and I am so lucky to have them as maintainers. They deserve so much appreciation for keeping up the pressure and making this release happen.
And remember to thank the hardworking people that make the mods, they keep this community alive.
You are obligated to try these mods out: (and legally obligated to try out every mod you see elsewhere, too)
Entropy, Tangents, Matador, LobotomyCorp, Amulet, Hatchet, Gros Balatro, Stocking Stuffer, MrBones, Insignia, MyDreamJournal, Balatro Plus, Arrow, TooManyJokers, Multiverse, 45DegreeRotatedBeatblock, Basslatro, Joyous Spring, Incognito, Galdur, Hyperfixation, Hot Potato, UltraViolet, Qualatro, Corrupted Nether, Fusion Jokers, Fortlatro, 1 in 10000 Chance for Withered Foxy Jumpscare Every Second, BeatblockPlus, Beattools, Scruffy Plays Pikmen, Lovely Mobile Maker Revo's Vault Dilatro
| OS | Download |
|---|---|
| Windows | lovely-x86_64-pc-windows-msvc.zip |
| Mac (Arm) | lovely-aarch64-apple-darwin.tar.gz |
| Mac (x86) | lovely-x86_64-apple-darwin.tar.gz |
| Linux | lovely-x86_64-unknown-linux-gnu.tar.gz |
@WilsontheWolf has created https://lmm.shorty.systems, it lets you mod Balatro on mobile with lovely by porting the Steam version of the game. Try it out.
[!IMPORTANT] BREAKING CHANGES:
- Module patches with
load_now = truethat fail to load or execute now properly propagate errors instead of failing silently.- On Linux native, the mod directory has changed from
~/.config/<game>/Modsto~/.local/share/<game>/Modsto follow XDG standards. You'll need to move your mods to the new location.
Big thanks to the following contributors:
reload_patches, variable store), load_now error handling, Linux directory fix, and luaL_loadbuffer hook, and lots more--vanilla segfault on Unix and adding Nix support[!IMPORTANT] Most mods WILL NOT WORK AS ZIPS until modloaders have added support. NO EXCEPTIONS!
TL;DR: Mods can now be distributed as zip files.
Lovely can now load mods packaged as zips. Packaging is simple, just drop your mod files into the archive into either the top-level or into a folder, both are valid.
mod.zip
lovely.toml
...
works the same as
mod.zip
mod/
lovely.toml
...
TL;DR: Patch files are loaded recursively, clean your lovely dirs.
Patch files inside the lovely/ directory are loaded recursively from subdirectories.
For example:
tangents/
lovely/
questionable_feature.toml
features/
real_feature.toml
content.toml
tweaks/
balanced.toml
TL;DR: Pattern, regex, and copy patches can target multiple files.
Patch away with reckless abandon:
[[patch]]
[patch.pattern]
target = ["main.lua", "game.lua", "init.lua"]
pattern = "old_code"
payload = "new_code"
TL;DR: Copy patch payload field
Copy patches now have an optional payload field that lets you inject code without the fuss of a separate file:
[[patch]]
[patch.copy]
target = "main.lua"
position = "append"
payload = """
-- Inline code here
print("Injected!")
"""
TL;DR: New Lua APIs for runtime patch manipulation.
The lovely module now exposes several new functions for runtime control:
lovely.reload_patches() - Reload all patches from disk without restarting. This does not reapply patches, you need a restart for that.lovely.apply_patches(buffer_name, buffer_content) - Apply patches to arbitrary buffers at runtime. You can patch shaders with this! And whatever you want, really.lovely.set_var(key, value) - Store a var in the store.lovely.get_var(key) - Retrieve a var from the store.lovely.remove_var(key) - Remove and return a var from the store.Example usage:
-- Store configuration
lovely.set_var("is_tangents_questionable", "true")
-- Retrieve it later
if lovely.get_var("is_tangents_questionable") == "true" then
panic!("What?")
end
-- Apply patches to a dynamically loaded buffer
local patched = lovely.apply_patches("buffer_name", buffer)
-- Force a patch reload (not a restart)
lovely.reload_patches()
TL;DR: You can patch injected modules.
Injected modules can now be patch targets! =[lovely modname "filename"]
run_lovely_linux.sh)--vanilla flag on Unix--vanilla by @kasimeka in https://github.com/ethangreen-dev/lovely-injector/pull/263run_lovely_linux.sh by @WilsontheWolf in https://github.com/ethangreen-dev/lovely-injector/pull/338Full Changelog: https://github.com/ethangreen-dev/lovely-injector/compare/v0.8.0...v0.9.0
Full Changelog: https://github.com/ethangreen-dev/lovely-injector/compare/v0.7.0...v0.7.1
A huge thanks goes out to the following contributors:
TL;DR: You can specify more patch targets.
Patches can now target other mods and even love2d itself. Since non-Balatro buffer names can be complex you should use --dump-all and the corresponding .txt file in dump/ to determine the name of your target.
[!IMPORTANT] Patching other mods can cause problems if done incorrectly - problems that can be impossible to debug even with a complete dump. Be careful with this tool, communicate your intent with other devs as needed, document what you've done, and remember to have fun!
TL;DR: Pattern and regex order inconsistencies have been fixed.
Lovely patches have a strict order in which they are applied: module → copy → pattern → regex, however this was not the case in v0.6.0. This version (and all the ones preceding it) merged the pattern and regex patches together such that they were applied in the same step in the order that they were defined within the patch file. This has been resolved by separating and applying these patches sequentially.
--dump-allTL;DR: Use
--dump-allto dump everything.
Every encountered buffer can be dumped, not just the ones that have been patched. Alongside each is a text file which contains the internal name of the buffer - use this name in the target field of patches.
TL;DR: Use
{{lovely_hack::patch_dir}}in your payloads to access the patch's mod directory.
This variable will be replaced with the parent directory of the patch (either ../lovely.toml or ../../lovely/patch.toml, for example. It's a hacky and temporary solution that WILL be replaced at some point in the future, but it'll work fine for now.
TL;DR: Native Linux support but you must build it yourself (for now).
Follow the guide written by @Rick1029: https://github.com/Rick1029/lovely-injector/
Full Changelog: https://github.com/ethangreen-dev/lovely-injector/compare/v0.6.0...v0.7.0
dwmapi.dll binary is found within the game directory by @ethangreen-dev in https://github.com/ethangreen-dev/lovely-injector/pull/12--disable-console argument by @ethangreen-dev in https://github.com/ethangreen-dev/lovely-injector/pull/13overwrite deprecation warning by @ethangreen-dev in https://github.com/ethangreen-dev/lovely-injector/pull/39Full Changelog: https://github.com/ethangreen-dev/lovely-injector/compare/v0.4.0...v0.6.0
Add mac support by @tetraminus in https://github.com/ethangreen-dev/lovely-injector/pull/2 Not yet released - requires more testing and implementation work. This is however an important first step.
Change DLL proxy to version.dll by @ethangreen-dev in https://github.com/ethangreen-dev/lovely-injector/pull/3
This fix is required to ensure lovely is loaded by the upcoming Balatro release, which includes a newer build of Love2D.
Fix panic caused by invalid utf8 log msg in Lua print hook by @ethangreen-dev in https://github.com/ethangreen-dev/lovely-injector/pull/4
Fixes an edge-case panic caused by lossless UTF-8 conversion of log messages across Lua FFI within sys::override_print.
Full Changelog: https://github.com/ethangreen-dev/lovely-injector/compare/v0.3.1...v0.4.0
[9f1c346] Implement native print override
This fixes missed output from Lua print calls
[436fcc7] Implement lua module injection.
This allows modules to be injected and require-ed. Initially implemented for nativefs.
[436fcc7] Add Lovely metadata injection. This makes it possible for a Lua caller to query information about the Lovely environment.
[7ceeace] Add LOVELY_INTEGRITY global const to patched source files.
This has been implemented to enable runtime integrity checking for Ankh.
[ffeb76f] Fix missing target name check in PatternPatch.