#Lovely - A runtime lua injector for LOVE2D
1 messages · Page 3 of 1
wait wdym? those directories don’t exist
The first directory is the path to the game, and the last one is just pointing to the built in love binary the game has
apple
ok, so i assume the game directory would be the folder with all the code
so what should the second one be? i dont believe i have a love binary
right click the game icon in path to the game and select "show package content"
the .app extension usually don't appear
i'm running the game through the game engine
the game is a folder containing lua files
change the last directory to the folder instead
normally it would be Balatro.love
extracting it gives the folder you're using
I don't think that's even needed
if you look at the last directory, you'll find that it simply prepends the first
oh wait true
so what directory should i add the mods to now?
idk whether or not it's working, but the game does run
it's still ~/Library/Application Support/Balatro/Mods I believe
it doesn't matter how you run the game
i don't have a balatro folder, should i create one?
yea
steamodded itself, why not
sure
theres also a chance that the lovely binary won't work with the Love2d engine binary.
ok it doesn’t seem to be doing anything, but it could be because i installed steamodded wrong
ok i've tried for ages and this isn't working, so i'll put up a detailed outline of the problem i'm having:
i have the source code of balatro in a folder called 'balatro' as well as the love2d game engine. i normally run the game using the shell command love . from inside the 'balatro' folder. i've tries to instal love using the following shell script, also inside the 'balatro' folder:
export DYLD_INSERT_LIBRARIES=liblovely.dylib
/Applications/love.app/Contents/MacOS/love .```
the game runs successfully, and i get the following output in my terminal:
```INFO - [♥] Lovely 0.5.0-beta5
INFO - [♥] Game directory is at "/Applications/love.app/Contents/MacOS"
INFO - [♥] Writing logs to "/Users/myusername/Library/Application Support/love/Mods/lovely/log"
INFO - [♥] Using mod directory at "/Users/myusername/Library/Application Support/love/Mods"
INFO - [♥] Initialization complete in 3ms```
the directory `/Users/myusername/Library/Application Support/love/Mods` does not exist, and if i create it no logs appear. is it possible to get this to work, and if so what am i doing wrong?
(please reply ping me btw)
this is happening because we're deriving the name of the games app support dir from its executable. because you're launching the game via love, it uses that instead of balatro
@solar pebble the regex bug is causing issues. could you release a new version of lovely?
absolutely
🪲
🐛
is there anything i can do about this, like a file i can edit or something?
@solar pebble ok, i looked into it a bit and, from my complete lack of knowledge of rust and dynamic libraries in general, i wonder if you could make a version of the dylib that directly reads all the necessary paths from environment variables rather than inferring them, so i could set the all up manually from the shell script
let me know if this is completely stupid since, again, i know practically nothing.
I also just remembered that you can set the mod directory via --mod-dir
@solar pebble just saw this discussion. --mod-dir does not work with Steamodded on Mac
AH gotcha
yeah mb, a bit distracted atm
that should be integrated into the Mac version, will look at the code tomorrow.
that should fix your problem
I think env var support is reasonable
no, I think the problem was more complex than that- it was partly Steamodded's problem
uh, can't remember why it wasn't working. I'll get back to you on this
well we’ll get lovely working first, then move on to steamodded
yeah I'm a bit confused, I've been under the impression that it was working on Mac
it’s my weird environment i think
ok, just found it. --mod-dir should work with just lovely; steamodded needs nativefs to honor --mod-dir
so what does that mean for me practically?
@wooden portal if you're still around, I'm willing to help directly over DM
unfortunately i can’t rn, will you be available in 2-3 hours by any chance?
just message me, I'll probably be around
there's probably no reason not to bundle nativefs into steamodded at this point
@solar pebble --mod-dir is really inconvenient to use on Mac because the run_lovely.sh script itself changes directory
an env var would be nice to have. noted, will implement that maybe tonight and get a release out
hey will this be done sometime soon? just wondering if i should wait for it to release before installing
will lovely give any warning if two or even more mods are trying to modify the same line?
that could be horrible when you got many mods using lovely and find something is not working or even crashes the game
even worse, when mod A is modifying one line but mod B is modifying the whole code block that one line is in
Nevermind, fixed
I'd argue this is a bad idea. You can have multiple things match the same thing and not mess up (especially with adding instead of replacing) and also this lets you patch stuff other stuff is using if there is compatibly issues. Maybe some kind of debug thing that would help with finding issues caused by this would be a good idea.
the fact that way too many modders are using ats everywhere in the toml and im not criticizing if bc in some case its the only solution to implement some features. imagine if a modpack got 50 mods, tho not possible for now, the possibility of the game being in this situation could drastically increase. modders can be haunted wasting time troubleshooting troubles and doing patches for other mods that are not even caused by my own problem.
so yea its more like a must for me, at least in the near future
I had a cursed idea
Lovely patcher
Patch the game using lovely stuff
Tbh it could be handy for platforms without natively lovely support
Is that good idea
I mean simple stuff yes, but I'm curious about stuff like modules and how they would work
I should learn more about how the lua interpreter works
script files (e.g. lua modules) and functions (and loaded strings) are loaded/compiled to chunks which are lua bytecode and have debug info and upvalues (and environment pre lua 5.2), which decide the variables (globals and lexically scoped locals) that are available to that chunk, and truly global (chunk independent) storage is in the debug registry and the C API side
in LuaJIT that bytecode is further compiled to native code before it executes in the runtime
(no idea what the lua configuration is with love2D so just covering the bases)
when chunks are executed, they also are done so in a coroutine (usually the main thread), and there may be a debug hook set to interrupt this execution under certain conditions
AFAIK lovely is only capable of patching lua source files before they are loaded
well put and yes, that is correct
it's complicated to implement but not that complicated, I just haven't had the time to look into it. in theory we can simply maintain a set of references to the backing rope; when a write happens to one of them, blow up.
but like I said, time. I'm working on moving to a new place next couple weeks so don't expect anything substantial feature-wise
which reminds me that I need to get a release out
@queen spire sorry about that, like I said I've been a bit distracted
let me see if I can integrate this real quick
likely not going to happen for tonight as I want to redo how arg parsing is done
release is cooking, should be out in 10ish
yea nah i'll just casually expect a feature like that in the future, no hurry
as you should. I believe in setting the expectation that the expectation will always be unrealistic
@solar pebble obligatory poke, reminding you about the PR
I've allocated time to look at it tonight 👍
Is there/will there be a way to see what patches don’t find anything
Might be very helpful for finding bugs
I have ran into issues where sometimes it won’t show up.
Specifically when failing to make a pattern patch.
that's implemented for pattern and regex patches, just needs merging
PR is reviewed, I merge 2nite
mergied
mind releasing another version?
eating, been a busy day. allocated time for the release is in about an hour
and a general heads up that this is the last "beta" release. if the changes made here are validated to be good then expect a full release towards the latter end of this week.
hype
Had anyone else been getting this after lovely crashes from something else?
anything in the logs?
Had a crash from a different lovely syntax error and clicking the ok box of that make this pop up
Recreating rn
Looks like any error has it pop up actually
Just caused a unknown variant and expected '.', '=' error and it showed up so this doesn't look isolated
(also here's the ACTUAL logs and not a screenshot xdd)
my cursory guess is that we're panicking within the panic hook, interesting
@queen spire Issue #55 should be fixable by adding a flag to each patch which denotes whether or not that patch has been applied or not
however it's tricky though because we never know if we've actually patched every possible source file or not
that seems reasonable. I do question the algorithm used purely on a code style basis, of course
that's always fair
this is an annoying problem because there's no "end"
at least nothing certain
eh, it's an edge case
I think it'll probably be fine if we iterated through the collection of patches at the end of the hook to ensure that everything has been applied
either solution is reasonable
so could you give me a high-level overview of how lovely does patches?
(I am not asking just for myself, probably a lot of people have no idea...)
I'm curious as to why some people were having the problem of lua_reload.lua running during lovely patching. from my current understanding that would be impossible, but clearly I don't know what's going on
Prelude:
- Lovely injects itself into the game process via DLL sideloading - the technics are irrelevant, what we care about is getting our bootstrap code running.
- Lovely searches for patch files within the game directory, of which is either automatically determined from the executable name or provided as an argument.
- Stuff happens to these patch files which turns them into a text file into something that we can use in code.
- A function hook is installed into the Lua runtime function
lual_loadbuffer. This means that every time the game calls that function it runs our code instead.
Runtime:
- Every time the game calls
lual_loadbufferit provides a buffer of text code and the "name" of the module. Lovely uses the provided "name" to determine which patches are to be applied. - Each patch is applied by modifying the provided text buffer. Most common is the pattern patch, which searches through the code for a pattern match and then writes the payload to a position relative to the matched line.
- Once complete Lovely converts the now patched text buffer back into something that the Lua runtime can understand.
- And finally Lovely recalls the original
lual_loadbufferto load the patched code.
ok, lual_loadbuffer is some C function. Can Lua code override lual_loadbuffer? If it's just an entry in some table somewhere it can be modified
or, is that thing fixed
It's complicated - yes and no
Lovely in theory installs the loadbuffer hook prior to LuaJIT, but during runtime when the game is actually calling loadbuffer we can assume that code is being executed.
lual_loadbuffer itself can't be overwritten but the LuaJIT function reference to it absolutely can
I want to investigate hot-patching the game's Lua directly, not through lual_loadbuffer. It's more complex because it's a compressed buffer of an unknown size / location, but it would make problems like this go away.
But what's hard is that any solution we go for needs to be fundamentally portable
What I'm getting at here is that the executed Lua code is loading in this module, not Love2D. Love2D calls lual_loadbuffer directly in native code, so general module loading can't be overwritten.
alright. clearly debugging this problem is quite difficult. Thanks for explaining everything
I can look into it, send me the details to repro.
It's just some reverse engineering
you can't repro
fun
Random question: does failed pattern patches show up as a failed query in the logs or is that specific to failed regex patches?
The implementation should be pretty easy all things considered, it'll likely just be another Lua runtime function hook
But finding out which is causing that problem specifically is tricky
build failed
damn it worked on my end lmao
ah I see why
one moment
still confused about how this lua_reload bug can possibly happen. I can describe what lua_reload.lua might be doing- it overwrites the global require function, as well as a bunch of others. but all these functions are implemented in terms of lual_loadbuffer anyway?
gah
it's been a while since I've looked at the Balatro source - is this something bundled with the game?
no, it's a file distributed by Steamodded
that module is loaded at the beginning of main.lua, and then somehow when game.lua is loaded it's through that file's function
ok, edited- that may be trouble
main.lua gets executed as per JIT, lua_reload does some funky shit, blam bam boom
specifically, I thought that lua.reload was copied, but actually it's injected with a module patch
ah yeah that still incurs an execution
our solutions are to either hook the lua runtime C functions that lua_reload ends up calling, demand that lua_reload be rewritten with lovely in mind, or fundamentally change how we code injection
the former is the most plausible as of now
I can look into it tomorrow
more pressing is fixing the darwin build failure
Text wall jumpscare
oh yeah this
pattern patches dont, bad regex patterns will but that's purely on syntax
when the pattern can't be compiled
and it'll warn you when no matches have been found
I might be wrong though on pattern patches, I don't remember
ejwu didn't you add a warning when a pattern patch didn't find a match?
I ask because I don't remember seeing any indication of a fail and had to look at the lua dump directly to check.
Lemme try to force one
This pattern patch should fail (and it does), but doesn't show up in the logs.
yes, there is no check currently. I added one, but it'll only be there in next release
if you can build lovely yourself, you'll get the new tech
Unfortunately I don't, but good thing that it's there.
I just want to say that the console log is legit scary
so many patches
I feel bad for the game
The prints can also go crazy
Btw has anyone did some digging on why lovely requires don't work when reloading the game using love's built in reload?
Also iirc it breaks the logs
Can be seen with steamodded and crashing and hitting r to reload
There was discussion about lua_reload issues
Iirc Lua_reload is something different but maybe I'm wrong
Also I might have a use for getting my patches directory now
imo failing that, the latter is the most reasonable because the lua_reload code I saw is not 'unusual' for lua
like modules rolling their own subdirectories via loadfile rather than require should be fine too (unsure if that's relevant, just an example of there being multiple ways to do similar things in lua)
(regardless of however they're handled in 'steammodded')
better to avoid 'surprise' when a dev wants to take general lua stuff and apply it (unless it's somehow in conflict with Love2D itself, can't really control that)
I've been investigating it, it's not that difficult, just annoying.
And a general heads up that I'll be on vacation until August, so I won't be responding very quickly.
windows is for some reason always deleting version.dll from my balatro folder whenever i restart it
any solution to that?
i keep coping version.dll into the folder but it keeps deleting it each time
i guess its some windows defender issue
It’s getting flagged as a virus
Which we can’t do very much about other than turning Windows Defender off when handling version.dll
windows defender has recently started flagging lovely for some reason
finding the 'threat removed' event in protection history in defender and restoring the file seems to whitelist it from defender
Gotcha gotcha, we can likely mitigate this by submitting a copy to Microsoft for review.
I fear they won't approve if they're implementing strict policies like this
Given it's not fully wrong on the "potentially unwanted behavior" part - Bad actors could try to hide malware as a useful mod, and unsuspecting users may or may not run it without checking source, while defender would have a harder time catching on
Error
Syntax error: game.lua:4: '=' expected near 'Game'
Traceback
[love "callbacks.lua"]:228: in function 'handler'
[C]: at 0x7fffd6a52fa0
[C]: in function 'require'
main.lua:16: in main chunk
[C]: in function 'require'
[C]: in function 'xpcall'
[C]: in function 'xpcall'
chat can someone explain this
ive tried everything but i cant use lovely
if i try without steam modded it just doesnt load mods btw
That looks familiar
Verify game integrity
This is from the old steamodded injector trying to inject and failing.
ah sweet
quick question what exactly is match_indent? is it to set whether the patch should match the whitespace at the beginning of the pattern?
got wondering what lovely can actually patch into, and it turns out, it can patch built in love2D files
but it fails to dump due to invalid file names
[[patches]]
[patches.pattern]
target = '=[love "Data.lua"]'
pattern = "end"
position = "at"
payload = 'end -- Hi mom'
match_indent = true
overwrite = true
althoguh it doesn't let me patch steamodded mods
LMAO
wait I have a crazy idea
replacing love2d with unreal 5
what if I added a copy of the balatro crash handler into the first file loaded so you get a fancy error handler for syntax errors caused by lovely
That would be awesome.
doesn't look like every love file is hooked
not sure how it works
hmm a file named Data.lua is loaded a bunch of times but it looks like love doesn't have a file called that
wonder if its some kind of special wrapper
discussing how lovely works? it might be helpful to know, lovely changes the lual_loadbuffer C function
in theory that's used by most methods of loading
I don't understand how lua works well enoguh to know how that effects it
alright never mind, sorry
that's okay
The lovely crash handler is real
if anyone is intrested https://github.com/WilsontheWolf/balatro-mods/tree/master/lovely/crashhandler
I guess I could add a patch to remove the game's built in crahs handler and then its the steamodded crash handler for not steamodded copies of the game
Game is not launching with latest version
How to fix?
No errors, just not launching
could also be steam not running if steamodded is not or improperly installed / outdated
Do I need to patch (eject) an exe?
Ok, Windows Antivirus was a problem 🤦♂️
interestingley enough, beta-4 is allowed by microsoft
still, I'm hoping this issue gets solved
@solar pebble I'm once again coming back for lua_reload has ultimately failed me. Is it possible for lovely to provide a way to soft-reload game files?
Maybe I should see if I could fix lovely on hard reloads
I think it should be as simple as just rerunning the init stuff (I hope)
that would at least be better than literally running the game through steam again and killing the old instance
soft reloads would be nice but they might just be dead
Yeah
I also wonder if maybe lovely could provide a method to hard reload
Could maybe get some benefits, like if patch files haven't changed, don't have to repatch files (depending on if lovely caches that)
Regarding the issue, hard reloads are something we can do without steam right now (the crash handler does it right now), but it breaks lovley in the process (only partially)
I'm aware, just bringing it up as well because it's not workable currently
okay I just don't get rust
@solar pebble I'm trying to get lovely to work properly when reloaded using love's reload function. Basically, the main issue is that the lovely module get's de-registered, (theres also some other issues, like logs being lost). I belive that if I was able to re-run this block https://github.com/ethangreen-dev/lovely-injector/blob/master/crates/lovely-core/src/lib.rs#L147-L154, it should fix these issues (although not do everything, like reloading patch files). However, I don't know how I would get this once to reload. I figured, maybe I could destruct and reconstruct a new lovely object, which should properly reload everything. However, i have no idea how to do this in rust. Seems like you need to make a drop method, which I don't know how I would do, or even what all would need to be done to drop the lovely class. Is there anything else you could think of to acheive this? Some feedback would be appreciated. Also I got to try to figure out how to detect when the runtime is being reset, but I do have the love2d code and can kinda understand it, so I should be able to figure smth out
yeah I was messing around and I can't reset the once, or reset the runtime cause I don't have a mutible copy of lovely, but i can't make a mutable copy of lovely cause its not thread safe
I also am not sure how to get it hooking int varibles, but it appears that love2d calls luaL_newstate everytime it starts the machine, so you should be able to init in that and get the restart stuff working (?)
This is not a problem with reloading, it's a problem with how your code responds to it
on reload a signal should be passed to the reloaded file so it knows to only update code that contains idempotent side effects
such a signal can be modelled by the absence or presence of a variable in your chunk
such as whether your mod already exists
in the global container of mods
or something like that
it's easiest if all callbacks/listeners/hooks that a module subscribes to clears themselves by being notified when that module reloads
that way you don't need to defer the callbacks to definitions of functions
that get overridden by the reload, thus changing what the hook does without creating a new hook
you can't expect that reloading a mod (performing an action over the game state an additional time) wouldn't cause stacking side effects
moreover if there are effects that need to happen at certain points in the lifecycle of the game
then reloading will break the integrity of the game/mod if there's anything changed that relies on events that have already happened and can't be safely triggered again
lua_reload was meant to reload the base game files and remove the initial side effects
I have however been unsuccessful in finding a way that actually achieves this for modules that modify the global state
Reloading the base game seems extremely unlikely to work
but maybe love2D has a special model
like most games that have a lua system are still mainly managed in native code
Capture their global affects in an environment
recursively
then merge the result with a policy
this would be really slow because the global state is gonna be super dense
but you can contagiously populate only what those base things touch each
other than that, lol no the code is just not designed that way
I think getting love.event.quit('restart') to work again will be good enough tbh
¯_(ツ)_/¯
I'll catch up with everything when I've got internet and my PC setup in our new place. 
Understandable. Hope your ready for the insane ramblings of a guy who doesn't know what's happening
for some reason my computer is detecting a virus when i try to download the lastest version of this injector. what do i do. im on Windows 10 if that has anything to do with in
It's a false flag, Windows defender has been going hard on lovely recently
damn
you'll have to whitelist it
how?
In Windows Security, go to Virus & Threat protection > Manage settings
Scroll down and click Add or remove exclusions
from there, add the folder of your Balatro installation as an exclusion: C:\Program Files (x86)\Steam\steamapps\common\Balatro
turning off real-time protection can be useful to stop it from preventing you from moving the file where it needs to go
Honestly, there seems to be enough confusion about pattern matches and whitespace, it might be worth introducing partial line patches
Regex patches matching over multiple code lines get reeeeeally messy
huh
if your partial line appears multiple times in code, it doesn't matter if regex used or not
It's going to be matched in all those places
I think multi line pattern patch is what would make regex not needed for the most cases
it is also not well known that pattern patches support wildcards
if you don't know that patterns can match multiple different places in file then its more of a skill issue 
best solution for it is to mention that in readme
which doesn't work that well for replacement patches since you're still replacing the full line, but for before/after positions it's fine
I meant more in like text matches, but allowing for indentation in the source that's not present in the patch
Patch pattern:
if x then
y()
end
Source:
if x then
y()
end
isn't that just multi line pattern? the thing that I suggested?
allowing for indentation in the source that's not present in the patch
ye but I'm pretty sure multi line patterns aren't supported?
I thought you can only regex those
pattern = '''if x then
[\t ]*y\(\)
[\t ]*end'''
multiline patterns are regex only, yeah
then add [\t ]* in front of each line
quick and simple
The idea I'm suggesting is to add such a kind of multiline tab-insensitive pattern so we don't need huge regexes for them
ye that's fine by me
Maybe just even a multi-line option for pattern patches
Wait do they?
yeah but the readme only mentions it in the tldr
Someone should maybe rework the readme
The example is kinda a silly steamodded hybrid
But doesn't even work in steammodded yet
module patches use the file name of the before file for their crash file's
realisticsally, it should be the file name of the file I'm injecting, or some special chunk name liek love or Steamodded use
Are the regex patches supposed to be able to replace parts of lines? Or only whole lines?
regex can replace parts of lines
Is this intended functionality? The docs only mention replacing entire lines
it says that for pattern patches
IMO it should not match and replace parts of lines by default, it's leading to some unintuitive behavior right now
have fun making a custom regex implementation that does that
it's meant to be universal
also changing the default would break all existing patches, no thanks
I just implemented a change that does just that (in my own stuff), very little breakage
Internally it just puts line anchors on the ends of the pattern
uhm, how is it unintuitive
that works actually, though I'd prefer that be something you have to specify yourself
Though fair point, I think I have a more elegant solution that doesn't involve implicit anchoring
Just use ^ and $
If argue regex sould behave the exact same as if I ran the regex on the file manaully
What we should probably do is make pattern patches work better in more situations, so we aren't using regex when we dont need regex
Right
@solar pebble just in case you haven't seen this, my account (ejwu) has been hacked, ejwu and AlexIsGreat are compromised
how do I know that you're not an imposter 🤔
but heard, hope you can restore access to those accounts
actually Alex is someone else
I have restored access to ejwu, actually, Discord was really fast for once. thank you
When can you work on getting the next version of lovely out?
I might be able to build macos binaries, if you need it
I recently revived an old mac
I have them now.
actually er, gotta build for x86 probably
I'm also happy to build them tomorrow on my Linux VM
... if zigbuild isn't totally broken lol
still here?
I've sent you a friend request, I can't dm you
I still haven't figured out how to make my cross-compiles to the windows-msvc target not blow up
They seem to work right up to a particular point and then come crashing right down
For some reason, I observe the same behavior: Lovely makes some decent progress on patching, but right at a particular point it gets hit with some kind of fault signal
What os are you compiling on?
On linux, to get it to compile, I had to remove the #[cfg(target_os = "windows")] in lovely-win/build.rs and also change the path to where I had my version.dll (in my case /home/shorty/projects/external/lovely-injector/version.dll)
copiled using cargo xwin build --package lovely-win --target x86_64-pc-windows-msvc --release
Okay, I'll try that
I wouldn't think to try doing that, that's not a typical step in a cross-compile workflow
I should probably neaten up my hodgepodge of edits to contribute back
Where'd you source your original version.dll?
ok thank you
not balatro, but adding an extra empty line above some code causes the game to crash. any insight? other patches work fine for this game?
well, i found the problem? but i dont understand it. the output has cut off the last character of the file, which just so happens to cause it to fail entirely.
could you send the toml file you're running? as well as code snippet for the other game that should get affected
i dont have acess to the files at the moment, but it seems that at some point during the patching process, the last character was being removed. the change from return st to return s caused it to crash. i was able to fix it by adding another patch, replacing return s with return st again. As far as i can tell it either only happens in this file, or other files have a newline at the end, nullifing the issue.
yup
because it basically nullifies the first one
so if first one caused syntax error, no wonder the other patch fixed it
yeah, exactly
what is your point with ignoring last character tho
the question is why the 't' got removed at all
i was patching an entirely different part of the file
well, I really find it hard to understand what exactly you're doing, so can't help you with that without the code snippet and toml file
just know that patches apply to entire file, so pattern needs to be unique
if you only want to replace smth once
use regex patch
and cover multiple lines
i was taking one unique line, adding a print call before it, unrelated to the return at the end of the file
which by quantum entanglment??? i suppose, caused the character in an otherwise untouched part of the file, to dissapear.
I'd like to see the patch file as well, this could be a bug
patch was essentially [[patches]] [patches.pattern] match_indent = false target = "states/SongSelect.lua" pattern = "elseif self.menuItems[self.selection].editor then" position = "before" payload = ''' elseif self.menuItems[self.selection].reload then self:getMenuItems() '''
targeting inbetween 339 and 340 here
return at the end with the removed t (not missing in this image)
if you go to %appdata%/gamename/Mods/lovely/dump
you can find dump for this file
and see how it looks like after applying patch
the dump is exacly how i want it to be other than the missing t at the end. this is not caused by the patch, there is nothing affecting that area with a patch. ANY patch on the file causes the missing character.
must be lovely bug then
@solar pebble Is it intentional that regex patches can insert characters such that they concatenate to identifiers in the existing source? I'm currently wrestling with one such patch
And it's causing syntax errors in very confusing (and likely platform-dependent) ways
Right
because you can have regex that isn't a full line
and might want to insert something after like 1 word, within the same line
My problem is that the patch I have on hand is sticking chars immediately before its target, prepending characters to the beginning of a keyword and causing syntax errors
This is pulled right from the mod's source
just insert a newline at the end?
or a space
what mod?
Saturn
probably just a mod bug then 🤷♂️
Yeah but that this kind of bug is even possible seems like a flaw in lovely
do you have any other mods or steamodded?
because I know that saturn is incompatible with steamodded
Mhm
or, last I checked
maybe it's not anymore
I'd assume this behaviour might happen from some lovely patch failing because of steamodded/another mod
I've been hacking at Lovely at the source, and so far I've only been able to make the issue go away by making the injector automatically pad patches
And trying to be "intelligent" so as to not insert space where not needed to avoid this kind of issue is not really working out
Look, unless there's a good reason for it to be possible, I'm going to make it not possible (at least not without a more involved patch that explicitly matches against the identifier to modify)
I mean if you need to rename a variable
Again, capture it explicitly in the pattern
I'm not quite sure what your issue is?
I just described it above
Starting right here
I read that but I don't quite understand what you mean
This kind of thing should not be happening
This is the offending patch:
[[patches]]
[patches.regex]
target = "functions/UI_definitions.lua"
pattern = 'end\s*\n\s*end\s*\n\s*local\s+flip_col\s*=\s*G\.C\.WHITE'
position = 'before'
line_prepend = '$indent'
payload = 'view_deck.config.card_limit = card_count'
I'll once again have to advocate for leaving regex patches unrestricted as a default
What's not wrong with card_countend being formed and causing a syntax error
Don't think djynasty is much of a skill-issued person, this is either a subtle platform difference or a nasty interaction with another patch
well I assume it works like this, which is just a this patch is wrong
I took the raw source file and mapped it there
I'd argue we make it where pattern matches can properly match multi-line stuff so that less people need to use regex, rather than modify how the regex behavies, to maybe stop some accidental issues with patches
I'm all for reducing the use of regex patches, pattern patches are a lot more efficient
hmm it doesn't error like that on my lovely?
are you running the latest lovely release?
I wonder if there was some change in behaviour somewhere
are you running beta7?
can you verify you didn't break the patch with your changes?
On my own system, the patch is already borked on lovely 0.5 beta 6
hmm
the patch works on mine 5.0 beta 6
I gtg rn
I don't see how this patch would break, unless another patch is modifying something on top. There might be a lovely bug here
Do you have the other patxh that breaks this one?
Idk, I'll probably have to look for a patch that targets similar lines in the same file
anyone know why the version dll just vanished after a few days
I think my antivirus ate it when I turned it back on, is there a way to stop that from happening?
Whitelist your Balatro folder or add version.dll to your list of allowed threats in Windows Defender
thanks
hey, discussing weird behavior with lovely? It's probably a bug, I already made an issue for it
there is something wrong with the logic for regex patches, but I wasn't able to figure it out
What's your patch?
PR with changes: https://github.com/ethangreen-dev/lovely-injector/pull/68
god tier work, thanks
@opal bolt I'm going to add you to the review
well when I hop on my laptop later 
I was about to informally review it but there's too many superficial changes
hey how's the linux port going? (yes i know theres a pr but its just frozen up there)
what would running atively on linux matter when the game itself is proton?
im not even running the game on steam deck or anything proton related
There is no native linux version of Balatro, at least not through conventional means
the version on Steam is the Windows version run through proton
Unless you don't mean Balatro. I know there are other Love2d games
lovely's linux support got raised to high priority and theres literally a pull request implementing it so i am just asking the developers hows it going
fair
I can only guess it's for other Love2D games, unless Balatro is going native too
I mean it's fairly trivial to repack balatro into a Linux format, but yeah, if also helps with other native games
I haven't left a review yet since I can't test it atm, but it looks good and release pipeline integration shouldn't be too difficult.
# After Draw Context
[[patches]]
[patches.regex]
target = "game.lua"
pattern = "first_hand_drawn = true}\)\n(.*)end\n(.*)end"
position = "after"
payload = '''
if not (G.GAME.current_round.hands_played == 0 and
G.GAME.current_round.discards_used == 0) then
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({vic_hand_drawn = true, vic_facing_blind = G.GAME.facing_blind})
end
end
'''
match_indent = true
Does anyone know why this patch fails? The error message mentions some issue escaping a character
@celest swallow helped me—I had to use single or triple-quotes instead of quotation marks
is it expected that lovely does not work with love2d 12?
seems reasonable given it was made with love 11.5 in mind
I'm not entirely sure what love 12 changes, but I don't think it should be that hard to adapt to it?
???
but it is released
my assumption is that it uses something other than luaL_loadbuffer?
it actually still uses lua5.1 though
Think latest is still 11.5
That's what's on the front page
Also, Lovely on Linux? How?
Proton
there's no native Linux build for balatro
but also there's a PR for native Linux support on lovely
How can I try this out for myself
it seems like the LOVE2d files are working but the game files are loaded differently?
too wide
i found the fix but i dont know how to implement it in a way that still works with balatro.
yikes
Any rust heads know why this dosnt actually call the original and actually just calls the new detour, causeing a stack overflow every time the game is opened?
LuaLoadbufferx_Detour.call(a, b, c, d, e)
No but other love games may have nativr Linux builds
ik
@civic raft great work on that PR, left some review comments for you to resolve.
Also @clear oyster , excellent job. Left some comments for you to look over when you get a chance.
Next thing I'm interested in doing is adding diagnostics for which file (and line, if feasible) a patch came from
Also, possibility of having Lovely making its functionality available to Lua code as a Lua module?
One thing that makes that difficult is that you need to basically load the Lua before the file your patching is loaded.
However, if lovely can get a seperate Lua instance, it could probably run a peice of lua code while a buffer is loading and givr it the buffer and take it'd return value
I mean, like, as in being able to require lovely, and then load up your own file and lovely-patching it (at a time after the original code is already loaded and patched up, we're not doing self-modifying code)
What's the point if lovley patching your own file?
Okay, weird hackery aside, you might have your own files in your own dir that you want to do stuff with
Like, say, challenges like BU-CB does them https://github.com/OceanRamen/BU-CB
being able to patch loaded strings by source should be good enough for this?
Okay, maybe parts of the functionality, like much faster regexes or serialization/deserialization might be more compelling
TBH I think lovely should just have it where require works as intended for lovely modules
So they can require other parts of their code
I don't think there's enough information for that if your code is actually part of main.lua
Not for injected code but there should be for modules
yeah but wasn't there a thing where modules are also just in main.lua?
There filename matched whatever the beifre is (idk why) but they are still technically their own buffers
They keep their line length, etc
meh that's still jank
I mean require working like intended wouldnt be jank
yeah
I've been looking into the DebugPlus issue I've had, and my latest finding is... I'm somehow getting a string out of a require call?!
Printing the string, it seems to be an error string of some sort
... Hold on, lua_pcall's return value isn't being checked
Okay so it is an error message, for what is most likely an error in trying to evaluate the module's code
Can you print the error message?
attempt to call a string value
(Yes, that's literally the value of the string from printing it)
Which require are you printing?
(The module is from https://github.com/WilsontheWolf/DebugPlus/blob/dev/util.lua , and the site the error is coming from is https://github.com/WilsontheWolf/DebugPlus/blob/dev/console.lua#L277 )
I'm printing util
Hold on I reset to origin/dev and I'm not getting that anymore, I did a goof it seems
Well dangit all signs point back to me
Well glad you got it working
The ultimate culprit? A missing newline. (Specifically trailing at the end of util.lua)
That seems odd
That UX could use some improvement
Maybe check the return value of the pcall and respond accordingly?
Which pcall?
Oh lovlely's pcall
Would it make sense to move the lua FFI stuff over to https://docs.rs/mlua/latest/mlua/ ?
High-level bindings to Lua
It was considered but I never went through with using it. The power and simplicity of calling the native API was preferred back then.
iirc for windows reasons you can't really just extern lua symbols and you have to use libloading so that might also be an issue
huh, apparently it's only an issue for the detour target
Also just noticed that lua docs officially say package.preload is the official way of loading packages into lua from outside
Next thing I might try to do is inject things there instead of to package.loaded (and wrap the pcall a bit better)
Wondering if there's a way to make lovely patches interact with loaded strings, either by making them use luaL_loadbuffer as well or hooking whatever they are using?
Any more hurdles before better patches is merged in?
im sorry but the idleness of this project is lowkey driving me crazy
yeah fr I should learn rust just so I can go contribute
don't learn rust it is too good
you're right I won't be able to go back
Steamodded's death came suddenly in early 2025 after a bold but misguided attemp to switch to a Rust api
tbf I only just got back home yesterday. prs will be finalized and merged tomorrow if everything goes well.
@clear oyster merged your code, nice work
Alright up next, I'm making the lua module loading less janked
Is there a reason why the module chunk is evaluated immediately rather than being left as is (as a function)?
Or is this just a quirk of how the modules are being loaded?
I'm not too familiar with lia but I believe they are being added to its moduke cache as already loaded
Wait are they actually run as soon as they're injected?
Or just proxessrd
Seems like the files are being executed upon being loaded in
Then the results of evaluating those files are put into the cache
Oh no my typing skills are contagious :p
Nah I could never dpell
debugplus-ell 
Proof i cojkdt spell in 2019
that's not thta bad
then it's just proof you claimed you couldn't spell in 2019
Well I'm not on desktop so I can't just go to the start of that channel and scroll down to the first spelling mistake
Idk if there are maybe mods out there that subtly rely on the eager-evaluation nature of steamodded module loading
I could make use of it but I don't right now
Actually though it might be nice to run my code before a file (like the one patch that just injectd my code) but not actually injecy my code into the file to make stack traces nicer
Speaking of stack traces does anyone know why modules have the same name as the file they are injecting before?
I looked at the code and it should be fine
But it just doesn't work
I'd rather not people abuse the eager nature of lovely module injection unless there's no other way
Also why is everyone vendoring their own copy of NFS under the same name without even bothering to namespace
Also a while ago you mentioned something that you said needs to be done for restarts to work better, can you link me back to it
iirc the other way (which is what I was working on a while back) is to "inject" modules by either adding onto the module search path thingamajig or by shimming/replacing the search function itself.
I don't exactly remember what those components are specifically as it's been a minute
I'm suggesting using package.preload
But in general yes, eager execution isn't the best way to go about it, but it was convenient and enough for nfs at the time
ah yeah, that's what I was trying to remember
package.loaded is supposed to be the cache
I do remember having some weird behavior from mutating package.preload at runtime, but afaik it's likely a skill issue
The module system was sorta wholly meant for nfs lol, hence the fuglyness
Everyone's vendoring their own copy of nfs :p
I've actually went ahead and tried changing out things to use package.preload, seems to work fine
I'll look at that
did you verify game integrity?
good good
Oh yeah you should checkout the Dev brabch as I use modules a bit more (most notably I call modules from other modules)
Oh also for some reason the file name for modules in the current version is the file they are injected before and not their name
I looked at that one and I don't see why that'd the case
https://github.com/ethangreen-dev/lovely-injector/pull/73
I have 0 rust knowledge, but most of the code was copied from what was already there, so I hope there isn't too much memory leaks :)
I'm personally of the opinion that it might be better as an new patch variety
But honestly that's bikeshedding
Also I made progress with getting lua module support to be a bit less hacked together
huh how would that be better
I don't think it fits as a new patch type but it would be nice to have some kind of lovely config file that has things like this as well as some metadata like name author and version of the mod
yea I don't really feel like doing allat
just needed this to allow making steamodded more vanilla without splitting it up too much
Yeah that wouldn't be a simple PR but it would be nice
How exactly does patches.copy work? I'm trying to get code to append main.lua after Steamodded adds it's code (easier to add modded compat for a mod meant to work with vanilla when it's being loaded on startup after SMODS global is created) but no matter the priority I set the .toml file it seems to always be copied and added before the rest of the mods.
This is assuming that adding priority to a .toml works (it should).
In fact messing with the priority of any of the mod files that are currently append files though patches.copy seems to do absolutely nothing, order of the code does not change.
That doesn't seem right
iirc priority isn;t implemented
oh
It's a comment in lovely source code iirc
either way, I just used prepend instead of priority to work around that
that's dump_lua
yea I realised
I was thinking along the lines of an "include" patch which names some paths to search for patches in
heard, nice work
sorry for being quiet, I've been taking a break from personal projects due to medical reasons
I don't feel like this is the greatest way to implement this feature. It makes more sense imho to expand the search heuristic to look into sub-subdirs, but no further.
however my opinion is very uneducated
The times where you would want nested folders to still load lovely files is either 1: for multiple individual mods in one folder (e.x. Betmma Mods and Jen's Collection) and 2: to kinda get around incorrect downloads that result in the mod being nested.
The latter is never wanted and wouldn't be helped by file indication to check for if it's nested (because that file indicator would also be nested) and the former can just be done through expanding how deep lovely checks.
Definitely a good addition but requiring indication through .lovelynested file instead of just automatic is odd
I'll review this tomorrow. at first glance though it looks good.
Can lovely patch in dlls?
shouldn't be too hard
I’m trying to patch in a custom luasteam and steamapi.dll
i feel like you can probably just add a new module path to search for yours first
Haven’t been successful at that
just wanted to have it opt in
if you have a bunch of mods in one repo, it shouldn't be hard to add a file
and Idk how useful/harmful it might be if it was automatic
¯_(ツ)_/¯
if you're wondering, .unique() to handle cases like
which seems to be working
The most recent merge to lovely injector kind of messes up some things
#70? It was working fine on my end
It uses libc to try to load in lua instead of libloading
And it disrupts the linux support PR that I was using (I was able to modify things to work around the changes)
As far as I can tell it behaves the same, just throws some wrenches into other changes
Just checking on this
is there a way to patch localization without steamodded? targeting localization/[anything].lua does not seem to work
the way localization is laoded isn't caught by lovely
there was a pr recently that changed what it hooked, but I'm still not sure if that fixes it
you could probbaly patch whatever is loading the localizaion and load yours there
same feature request as mine for being able to patch steamodded files (loc files are loaded w/ loadstring)
really quickly peeked at your changes and they look good. I'll commit some time to an actual review tomorrow.
I've been smoke testing the latest commit and it seems to be performing 1:1. My big blocker rn is my SO's birthday and the Linux build pipeline.
Once those are done we can move forward with the release.
link to current version?
Also, another prerelease version please?
deploying it now
mac is still borked, dang
😦
Did github change something in the mac machines at some point
the mac builds run on a linux container so likely nothing to do with that, but it could be some update on Github's end + odd interactions between the latest version of Rust and cargo-zigbuild
alright, just ended up manually building the mac binaries. release is 100% live
a huge thanks goes to all of the huge brains that committed huge code to this release. ya'll are hugely great :-)
now lets see how broken everything is 
also dang, we've got 76k downloads on the repo right now. crazy stuff
xdd
great time to remember too, I've got to head to bed. can everyone handle the binaries being the wrong version until tomorrow? pretty please?
nah nevermind
I need a Mac guineapig to test a build out rq
actually NO we're fine, the version on the release binaries SHOULD BE beta7
I saw beta7 when I ran it
sweet. my past self has saved my current self
enjoy enjoy, let me know if anything is brokened
https://discordapp.com/channels/1116389027176787968/1255696773599592458/1285127782468157462 Spaghetti error has occurred.
Jist is the game loads but pressing play yeilds this.
oh also can confirm way more stuff is hookable
including the save files
(only if you know the entire contents of the file)
INFO - [G] 2024-09-16 22:17:35 :: ERROR :: StackTrace :: Oops! The game crashed
main.lua:39: attempt to concatenate field 'path' (a nil value)
After updating lovely injector to 0.50 beta 7, this error occurs.
send the full crash log
I belive this error is coming from cartomancer
Confirmed, after removing cartomancer, the game can be loaded normally.
seems to be because SMODS.MODS_DIR now returns full path even if it's default 😦 I guess I'm forced to use NFS now
yes but any filesystem logic will quickly turn into spaghetti
if I do
if SMODS then
//access file with NFS
else
//access file with love filesystem
end```
everywhere
If you assume that lovely's mod path is always in the same spot, you could trim the /Mods from it and then use that to trim the beginning of real paths
actually just a sec
you can use love.filesystem.getRealDirectory("") to get the save path
oh wait theres a function for that
love.filesystem.getSaveDirectory()
I dont really understand why lovely isn't bundled with nfs tbh
even more so now that it always returns full path for mods folder
I thought it always returned the full path for mods folder
seems rather annoying to have same file in every mod
well, I tested with previous version, and SMODS.MODS_DIR is Mods
with beta7 it's full path
huh
I don't belive that lovely changed it's path at all
that might just be a SMODS change
huh
I have 2 version.dll in my folder
one for beta6, which when I run it, returns
let me look at this
uhhh odd
I don't see a difference
actually thats odd
I'm looking at the code and it should trim it
I think
Think I found the issue
not sure what chnaged though
different types of slashes
so lovely is using backslash love is using forward slash
wait it's only using / for one path
oh wait smods patches the lovely one to use backslashes
not sure why the love one is not
no wait
@errant robin you wrote the function for handling paths originally, what is going on here?
why is is sometimes one way sometimes another?
ok I think I might see the issue
lemme double check tho
yeah SMODS.MODS_DIR apparently wasn't set in beta6
that's why it used Mods 😭
Idk wtf changed tho
oh is it because modules logic changed?
I remember something like modules are now loaded lazily
so my module was loaded before SMODS was ever initialized, that's why it never used mods_dir
oh smh
I'm down
since you're the first person that actually asked since I set my status this way, I'll consider
I'm just asking for patches on loaded strings by chunk name in return
sounds convincing if you ask me

Every mod seems to be vendoring their own copy of NFS to load in
It would be nice not having to do that.
tbh most mods don't need it for anything other than finding where there mod directory is and loading additional files
it would be nice if lovely at least told us where the patch(s) is located and also gave us the path for love.filesystem
although maybe lovely should just vendor some libs for common stuff
would also be nice for some stuff like https
maybe also some stuff that it already uses for itself like it's regex engine and toml parser
also json maybe
seen it vendored by quite a few lovely mods
- if we're gonna be moving to a json metadata file standard, I could see there being more use cases for wanting to read those
tbh even toml would probably be good enough for metadata files
oh btw @solar pebble do you have any idea why modules have their names as the file their targeting instead of the file that they are named after or their require name?
like this
eh, I'd rather stick to the standard
toml is a standard for config files
mod metadata isn't strictly a config file
technicall toml supports more types than json
you're not wrong
I just think it should be reserved for patch files to reduce potential for confusion
ok wait I just reread the code and I see now
nto sure how I missed that
what them mean
it means that a lovely patch in JensAlmanaic is invalid
ah
Its a jens almanac problem
The maximum i32 value is 2,147,483,647
And he put 9,999,999,999
why....
alright, have an amazing day both of yall
This is the fix for now
You open the toml file, look for the priority number and change it to the one indicated by Jens and save
ok @solar pebble thoughts on thsi format for the source name of lovely modules =[lovely <require-name> "<filename>"]?
This is based off the Steamodded source =[SMODS <id> "<filename>"] which is in turn based off the love2d source =[love "<filename>"]
the = has special meaning as defined here
(like the @)
This makes it clear lovely added this in crashlogs (like so)
this is also easy for the crash handler to read the info from to display
A++ recommendation
Left a comment, otherwise looks good
ok fixed
merged, nice work
"ERROR - [♥] lovely-injector has crashed:
panicked at crates\lovely-core\src\lib.rs:168:13:
The byte sequence at 0x2ce5dd28 is not a valid UTF-8 string: Utf8Error { valid_up_to: 49222, error_len: Some(1) }
ERROR - [♥] lovely-injector has crashed:
panicked at core\src\panicking.rs:221:5:
panic in a function that cannot unwind"
any advice on this?
what's your modlist?
I'm assuming it's related to this
Yea
It seems to happen on a bunch of different button inputs
Someone else mentioned loading profiles
Should be as easy as making invalid UTF8 a non-fatal case. I'll poke around at it tomorrow.
help pls
here is them lovely logs
i created a save without a problem, but when I press play it says that
@grave moss Amazing smart dude, do you have any idea of why this is happening?
sigmas? anybody have an idea of what is going on?
I see that you have https://discord.com/channels/1116389027176787968/1255696773599592458 you should ask there
try to go back to beta 6 of lovely
its fixed?
do we have a list of all the issues beta7 is causing somewhere?
UTF8 error #1214591552903716954 message
failed to collect file data (maybe) #💻・modding-dev message
I've seen this one around a bit (not sure if lovely, seems tied to cryptid) #⚙・modding-general message
I think thats it for new issues popping up with the new lovely build
other than the priority one
Hmm
idea print the lovely version in the console when started
or put it in the console title bar
oh wait it is printed out
I don't get the line printed to stdout though
but its in the logfile
I was able to replicate this one
Something odd is definitalty going on there
oh wait I had my diffs backwards
so it seems like we had some screwy indeting in the old version
this one seems odd
seems like its a bug in the steamodded version bundled with cryptid
in which case, it's probably not a concern
iirc it may be printed out before the log writer inits
if anyone is getting the UTF-8 crash while using lovely beta7 PLEASE have them use this binary instead and screenshot the error message. #1225831216939536394 message
has anyone gotten this to work on mac
Mac is a bit tricky but the instructions should still work fine
ptrace injection might work on andr**d when the game releases on the 26th
the current LD_PRELOAD technique won't work unless selinux disabled, which generally requires root.
are any of you guys experienced with android dev?
chcon might bypass this restriction, not totally sure
and then we can use setprop to set LD_PRELOAD
No but I have one to test on now
I also have familiarity with iOS twekas
is this the crash you're talking about?
yep!
@solar pebble the issues with Cryptid were because of an old bundled Steamodded version
#1209564621644505158 message
Steamodded already addressed this, so you shouldn't need to patch anything
nevertheless, if you're curious here is a mod folder of just the troubling steamodded version and lovely info
@solar pebble finally got this error for myself!
it appears to be from loading a savefile with Ankh
This appears to be the UTF8 string in question : return {]"BLINK","LOVELY",[{"ID":"20","Time":"2019-04-28T23:25:17Z","Status","Open"
gotcha. it's weird because the text in bracker's screenshot is different: if not OmegaMeta then return {["GAME"]={["won"]=true,},} end ret
and that string is being passed as the chunk name, not as the chunk itself
there might be some weird memory corruption going on
Ankh deals with decoding raw data when the crash happens, so it could be related to that
Side nkt it'd probably not useudk ever yo load unnamed chunks
Wonder if you could detect these and then just ignore then
By the way I just released the version that had this issue so I can give you some steps to reproduce:
- Install Ankh v2.0.0-beta3 only.
- Start a new run and play it for a bit.
- Quit the game. When relaunching the game, press the play button.
- lovely-injector has crashed
idk if this will be consistent, it was for me across the first save I tested but maybe not for all
Do i need anything else? I don't see mods on the main screen
mods tab is from steamodded #1209564621644505158
Than how do I know the mods are working?
by seeing functionality from the mods in game
lovely is just a tool that allows all mods to function
heard, thanks. I'll give this a shot when I have some free time.
if I can repro. then I'll be able to walk back in a debugger and see where/how things are breaking
also we might be able to improve av detections by replacing the memory injector with a iat patcher
since there's no actual asm injection it may be less sus
I think my #1 focus right now is how/what mobile support is going to look like
IAT?
IAT = import address table. it's a lookup table in PE (win32 .exe) files that stores the addresses of functions in external modules
Idea make an empty file named smth like dont put mods in this folder for the lovely folder
good idea
I'm going to go ahead and replace the bad utf8 panic with a warn. patch targets should have valid chunk names so I feel like there's 0 use-case for implementing a proper fix
Yeah
Not only that but chances are it's just a raw buffer in that case and patching is pretty much useless cause we would need to know the entire buffer to patfh it at all
before making a release gimme a sec
print statements are printed in backwards order in lovely
print("1", "2") prints INFO - [G] 2[G] 1 and printing with a nil in it causes all to be nil print("1", nil) prints INFO - [G] nil[G] nil
gotcha, should be as simple as popping strings off the stack and printing them in reverse
or the other way around
Hey all, I'm kinda new to this, but when I tried downloading Lovely, and ran the zip through virustotal, it showed like 30 things triggered, anyone know what I should do? (also popped up as malware on google)
it's a false positive
you could attach a debugger and see what the stack looks like after each pop. there's a good chance that we're not handling nil cases well
I'll check it out after work tomorrow
@twin bluff fixed, give this build a go
the nil seems fixed but its still printing backwards
thoguh the [G] between items seems gone
lol
I feel like the best way forward is to have a manifest that patch authors can use to declare the name, namespace, etc.
and then some native function on lovely's end that returns a dict of name:path pairs
in the meantime I'll implement a template variable which inserts the path of the patch file
some {lovely:PATCH_PATH}
this is the most simple way to do things without getting into the "how do we determine what is a mod directory in a game-agnostic way" question
I do think that a proper implementation will require some sort of lovely manifest, maybe as a breaking change to lovely.toml files
the only real value imho is that it would make it easier to support non-balatro games.
currently there's no need but in future if other games are added a general support server would be nice
Yeah I don't really see much need but if you do make one be sure to send me the invite
can there be an option to append raw text instead of a file with copy patch? or an alternative patch type that does it
actually was thinking of that
or even just a way for a pattern patch to match tbe beginning or end of the file
e.g. I want to have core functionality inside module, but then to call that module I have to create a one liner file just to require it
@solar pebble any updates on this?
got like 50% of the way there and then I got distracted
planning on having a PR up for it tonight
btw meth do you have thoguths on getting lovely to load patches from zip files?
idk how viable it is, but we can get smods to do it and it would help with managing mods
I was looking at nfs and it seems love exposes some c api for mountinf zips https://github.com/EngineerSmith/nativefs/blob/master/nativefs.lua#L248
but I think we need to commit to an actual on-god for real package metadata format first
oh perfect'
I'll maintain support for both zips and dirs obviously
I wouldn't get rid of directory mods cause they are way easier to dev on but for users just dropping a zip would be so helpful
yeah, you can remove an install step ez pz
@errant robin since you are like the main smods dev figure you might want to follow this
but keep in mind that archives essentially make the mod immutable
yes
which aolso means we don't need to worry about config or other runtime created files when upgrading mods
which means its a simple as delete and replace
fair enough, though this would mostly break them
but we can't just leave old files around cause if somone for example moves from lovely.toml to a lovely dir and we leave the old lovely.toml then patchs break
yes but then we are breaking them in a obious way and not a oh your mod was updated so config is lost
lovely mods can still use the config folder even if smods doesn't exist
yeah, I'll even expose a directory as a static var for use
the big thing we need to figure out right now is metadata
using that api if the name is known, we can use love.filesystem to explore it
idk how exactly you will explore it from rust land
I can query the lua runtime for info if needed
tbh I'd make lovely.toml have a metadata section
agreed
maybe that's inconsistent with having multiple patch files? idk
I think the lovely fodler doesn't have config
it's annoying because ideally we want lovely.toml to be purely package info
but I don't think it's insane to require a lovely.toml and make it possible to include patches
i mean I'll make steamodded have some json file ideally with some fixed undecided name and surely it's best to have lovely metadata separate from that but it creates redundancy possibly
name, author, and version for now
the real big deal is that it would make extending that metadata way easier
and even worse if you want to submit the package to ts
but that's an edgecase now
oh meth I was thinking is there a possiblity for us to have a buffer loaded before a file is loaded mostly for side effects. Was thinking it wouid make the crash ahndler more reliable if it could be loaded seperatly than the main.lua for syntax errors
eg. the crash handler could get the patched buffer as text?