#💻・modding-dev
1 messages · Page 82 of 1
function Card.set_sprites(self, _center, _front)
set_spritesref(self, _center, _front)
if next(SMODS.find_card("j_lobc_youre_bald")) and (self.ability and not self.ability.lobc_censored) then
if _center then print("has center") end
end
end
the center print line isn't being called when a card is created
set sprites is a part of set ability and it happens before any of set ability unless it's a playing card
self.ability doesn't exist upon first set_sprites
the way i bypass this issue is by calling set sprites within my set ability so the sprite is set correctly even on creation
but idk if that'd work for this
oh wait-
fuck that was the issue
before it was just if next(SMODS.find_card("j_lobc_youre_bald")) then
okay thank you!!!
Yeah I think that should work?
yeah, I downloaded mono, and figured out the parent .cs was Program.cs, but got this error:
```"Program.cs(5,22): error CS0234: The type or namespace name Forms' does not exist in the namespace System.Windows'. Are you missing `System.Windows.Forms' assembly reference?"
Seems to be a thing that can't be directly fixed on linux. Ofc Wine being Wine. I'm sure there's still a way, just not savvy enough personally
iirc there are other tools for generating code for steamodded api jokers btw
the only one I know didn't get nearly as far iirc
there's https://github.com/tyuugy/tomFoolery (I think you've seen this one already) and there's https://www.balaui.dev/joker
those were the 2 I could find quickly at least
yeah the second one seems to be more at parity with Steak's
wonder why there doesn't seem to be a thread here?
there is
it also encourages localization files which gets a big 👍 from me
loc_txt ride til I die :P
not because it's better but because I'm lazy and like the aesthetics, lol
Nice, that balaui one looks sick
Still not a waste though, because I like having a personal tool for my own use
seriously though, not even having an option for loc_txt (that I can see) on balaui blows. It's not that I don't want my mod to be translatable, I just... really really prefer the object to just... have everything
Especially because I'll be making jokers that are identical for multiple suits, flounders-mod style
(suits will have their uncommons/rares (snow's mods style coins and fusion-jokers style 'heros') made for them, but also ported to every other suit)
it's not too difficult to add loc_txt tbf
yeah ofc I can just copy what it spits out in the locale file to a loc_txt entry ofc
and just edit that object for the duplicate jokers
en-us and default aren't exactly identical though
you may want the english version to be one thing, but another thing to be filled in for unsupported languages
mods are just gonnna follow this example and when 2.0 comes out in like 2026 and /is/ compatoble with 1.0 mods will run into trouble
though I'd say that's rarely the case
wait nvm
gladur vers
still applies kinda
non-existing major versions shouldn't be listed as incompat
wow that comment highlighting is not great
unless that's indicating invalid json? 🤔
json doesn't always support comments ig
guess I'll have that be talisman then
also i might include a minimal example for copying
you should really fix your tabs/spaces inconsistency btw
To use more advanced typesetting, specify your description as a localization entry at G.localization.descriptions.Mod[id]
so does this support{C:color}and line breaks
yes
sweet
i switched to js highlighting because that was atrocious
crashes when hovering a joker with the new system
{
"id": "LobotomyCorp",
"name": "Lobotomy Corporation",
"author": ["Mysthaps"],
"description": "",
"prefix": "lobc",
"main_file": "LobotomyCorp.lua",
"badge_colour": "FC3A3A",
"display_name": "L Corp.",
"version": "0.9.0-pre2",
"dependencies": [
{
"id": "Steamodded",
"min_version": "1.0.0~ALPHA-0909a"
}
],
"carmen_says": "You should distort yourself... NOW!"
}
is it fucking up because of my custom generate_ui.....
i don't see how that's related?
shrug
I think I see why will fix later
you could also try using yaml highlighting and comments with # (also disallows tabs btw)
does this allow for localized mod name/display name?
yes but I didn't account for badge display names iirc
thanks but I'll just restructure to have the descriptions outside the actual structure
Can we pretty please specify the default config file in here now please
So I can use config.lua
Provided should also have a version in it (and I should be able to provide multiple versions of a provided package)
(Specicizklly I would like to be able to provide DebugPlus api things people can depend on and I could support multiple versions but one version is never guaranteed to be compatible with another)
Although this would need some kind of optimal dependency thing to be greatly utilized
Also the metadata for mod icon so it may be show for disabled mods
Also what happens when a mod has both a header and metadata file
Also what happens when multiple json files in a folder
Also does nested still work (and how so kf it does)
About nested, json metadata is checked for the same say as legacy header
At least from when I last looked
TBH I think I would prefer a constant name for the json file and also not spport nesting/multiple mods per folder but I know this will break some mods that already exist
Specifically for the mod index having multiple mods in a downlaod would make it way more complicated
Also since we're discussing changing metadata stuff can we please define I'd restructions
Sepcifixlalt I want to make it possible to have internal smods IDs able to not be used by eztenrla mods (such as the mods used to represent lovely mods)
Page says
Using the legacy file header system is still supported, though switching to metadata files is encouraged. ... If you are transitioning away from using this method, make sure to remove the header to prevent Steamodded from trying to load your mod twice.
A possible hacky solution would be creating a second file with only the steamodded headers and a conflict header for steamodded version < current? 🤔
though it'd be better if steamodded just... didn't load the mod twice
I think it's clearer it can be hovered on with the exclamation mark rather than keeping the mod icon the same
That's why i specify disabled and not failed to load
yeah that seems iffy. I belive it should be okay, because it will just abort if two mods are detected with the same id, then it will just abort the second one it trys to load. Howveer, you need to keep the metadata in sync betwen the two. I assume there will be a breaking change someday to remove the old header method
oh it's an absolutely horrendous approach
if we did move to this then you could check for the presence of the json file and then switch behaviour
I'm getting the feeling that not everything being loaded by json is parsed.
Got the same error from D6 Jokers when adding display_text into the json metadata
actually, wouldn't that be a good way of hackily supporting both metadata variants?
Though... ugh, it'd still actually load twice so nevermind
Trying to debug this resulted in a print error that's saying that self.config.colour is a string.
Just so happens that legacy converts string to HEX and json doesn't.
ok the string error thing is unrelated lmfao
damnit
noticed this earlier but haven't gotten around to fixing it
it doesn't actually load twice, it's just inconsistent which one loads
Ok the engine/ui crash is definitely related to json loading
Specifically with mod badges
So for now omit display_name
sure
yes and no (multiple versions don't work with the current system)
yes (by means of the specified filename not existing)
I agree
It is basically the same SMODS.Atlas code for all mods anyways, the only "new" thing is the path to the icon
the resolution differs sometimes, no?
Does it actually check
I think I mseed up the specified resolution one time but I had the real resolution and I don't think it actually effected it
oh, seriously?
It was off by one pixel so I might have just not noticed it
or maybe 2
oh also metadata mod icon means the index can get the mod icon
BTW steamodded does not do this
our system is more like debian versioning lite
seems to use the px and py as specified by the atlas, but it should be able to just auto-detect the size if needed
this is me being lazy
I'm not sure how balatro's atlas thing works but it moght be worth seeing if we can just look at the image resolution as most are just one sprite anyways (the only one I've seen with multiple is the Steamodded one)
it's not semver
I could document the versioning protocal
I'll have to go through and make sure I understand everything
<major>.<minor>.<patch><rest> is pretty much all. it's considered less than <major>.<minor>.<patch> when rest starts with ~
and patch is optional
I think it technically supports just like a version like 1
I'd have to double check
it doesn't, at least with the current pattern
that being this lua pattern ^(%d-)%.(%d+)%.?(%d*)(.*)$
i guess technically we could make the minor version number optional
It could be nice in some cases
I'm not sure i see the use of that
I would use it
for the debugplus api
as it's a simpler api
also for dependancies I can then just depend on Steamodded>=1
Steamodded>=1~ actually
get_id() or smth
assuming I want to support beta versions
but yes
non-beta versions do not yet exist
well technically, there are versions that would match >=1 but yes true
also can we dpeend (or mostly conflict) any version?
I'm not so sure about this one
anything considered a valid version can be depended on or conflicted
like can I specifcy no version to match all versions
okay
also can we specify complex api things?
like (steamodded < versiona AND somedep >= 1 ) or steamodded >= versiona
I don't like the current system, and I think it'll be super messy with a version index
Also it would be nice to have this for a fake lovely package so mods can depend on certain lovely versions
oh also on the topic of breaking everything do we want to change the default prefix to the full mod id?
it's required now?
ok sounds good
whats the fail behaviour?
does it show up as a mod failed to load or just a log in the console and not sane
not sane
maybe we should add some dev mode where all not sane things are put somewhere, and then we can add other stuff (like keep track of any warnings found and present them)
there should have to be some way to do this, actually
also I just checked the commits and we're at version f already today
oh also a fake balatro version so this can be done with balatro itself too
i feel like this is not reasonable to put in JSON config files
if you want to go the route of complex requirement specification a requirement text file would probably be better
just support the debian control format
or you can specify a preload file that is run to check for any unsupported requirements
What does debian have to do with anything? I mean unless balatro is going native sometime soon?
this just seems overkill 95% of the time
Because it has a well defined metadata file (the control file) that has all the version dependancies and defines how versions work and relations work
yeah but how would I know if all my deps are present (especially when they also have preload file)
ah I see. It's just a complete and thought out versioning system
just looked at it and there is genuinely some cool stuff in there, though extremely overkill lol
yeah nevermind that
Yeah. However, it is nice to look at to see how they handle certain behaviours
and probably contributes to debendecy hell in its actual application
lmfao
~=?
i'll try
I say this as a daily driver of a debian based OS who's tried to upgrade dependecies before. Not a good time
I was trying to find this but couldn't, thanks
maybe a structure like this can do
base := { id,min_version,max_version::string; };
operator := "and"|"or"|"xor"|"maybe something else idk"
version_spec :=
| base
| { type::operator; values::version_spec[] };
dependencies := version_spec[]
I think that many operators is overkill
don't you only need and and or?
the debian one just has a , (for and) and | for or
yeah and+or is complete
xor seems like just have a conflict
Wilson's version is much more intuitive to me ngl
nested objects are also annoying ig
for this
This example would just be steamodded >= version or somedep >= 1 I just overcomplicated it
if you have to write out something like (a|b),(c|d)|e,f as basically an AST
well if you need steamodded anyways you can do steamodded >= versiona and steamodded >= versionb or somedep >= 1
I'm getting antlr4 flashbacks
I think just don't support bracketing
fair enough
yeah I think you should stay away from ASTs and stuff
Debian doesn't do it so I trust them to figure out it worked
oh also make sure you treat provides properly
liek if I provide a package I conflict with don't disable myself
DNFs are logically complete so there's no issue here
next question, +-35? ._.
so deps and conflicts are just strings again
doesn't almost all software use strings for dependencies/conflicts/etc?
JS package.json doesn't but it doesn't support more complex dependency stuff like this (becuase we can have multiple versions of the same package to keep everybody happy and there's no conflicting)
so we have
- config file name
- provides versioning
edit version pattern to allow major(+rev) only- mod icon metadata
fix display name errorrework deps/conflict parsing
I'm not dealing with multi-versioning
anything I've missed?
We need to discuss the nesting and multiple mods thing a bit more
If we have a fixed conifg name we can't have multiple mods per folder anymore
(Without nesting)
we've established the config file goes unfixed
Make "Poor Raccoon's Fortune" fit on a badge, even with the legacy header
isn't this just the "should we allow multiple nested mods" conversation?
I think not having a fixed name is a bad idea though ( we could parse a json file for something as a mod config) and Its easier to not scan everything
Yes
But particularly its result can effect how the config file is defined
And we don't want to be changing things manorly when it's been around for a while and everyone has adopted ot
I wonder how many new words you've 'invented' Wilsom :P
I think if we do desicded to allow multiple mods in a folder, then the config file should specify what all the mods are and where (ar at the least just specify the paths for the individual mod json files)
actually took me a min to understand
Sepcifixlalt I want to make it possible to have internal smods IDs able to not be used by eztenrla mods
haha
I'm just as bad, lol
hold on I'm getting confused between config.lua and metadata.json, you're talking about the latter right?
sorry yes the metadata
Maybe if it is fixed, Betmma will finally have to turn their abomination into one actual mod
lol
or just have a few seperate mods installed seperatly
I mean at the end of the day it'll be
pros: people stop making weirdly confusing nested mods (real world issue: increased load time?)
vs
cons: it will be harder to install mods (mostly for first-timers and modpack makers)
right?
that'd blow for modpackers without multiple repos though
oh also I noticed a werid behaviour with betmma's where adding a lovely ignore to the top level mod will disbale the lovely patch won't disable the mods in it's sub directory
Well it would basically be what it is now, but bettama's mods would just be like 5 mods instead of 1 (or it would be reworked to actually be one mod)
also modpacks are are just a collection of files you put in the right spot
yes, and due to how submodules work, putting them 'in the right spot' and having them automatically update is... impractical if there's multiple mods in the same repo
it'd require external scripts which I certainly don't wanna mess with, instead of just git
I mean it's already that way if you just want one out of a few like any of the mods in https://github.com/WilsontheWolf/Balatro-Mods
the only collection like that I personally use is a couple things from jen's, which thankfullly don't really get updated much, so I can just add static copies directly to my modpack repo
like you may want a couple of the mods in there like the score improvements, metal pipe crashing noise and maybe rumble but theres some actively you don't want ones like crashing, negateInvis, negateEverything nobackground
Also those multi mod packs are just bound to not work well with the mod index
the way those are done currently by modpacks is by copy-pasting the files and manually updating them if the mod does iirc
Honestly any kind of modpack pretty much needs some manual work anyways
Like ever made a minectaft modpack?
never have and I thank god every day
I made one for my friends and it's annoying
with the mod index, you can probably make a script to just have the mods by id and then make a mods folder from it
Good point. The mod index still feels pretty far away for me though
I just tend to prefer people give mod's their own repo
(why are apostorophe and return so close together?)
can someone tell me what i am doing wrong?
Yeah but I don't want an additional 12 repos for mods I'm never going to touch again
i feel like i did it ok
what's the issue?
I mean making the same check twice seems odd
yeah and because they're not actively updating, it'd be fine for me to just copy them into my repo if I wanted them
looks like nothing gets added
only a problem for active mods
mb
I think honestly just make a script™️
the indentation is a tad off
oh btw
like for mine it would be clone the repo somewhere and rm -rf Mods/Rumble ; cp -r ClonedRepo/Steamodded/Rumble Mods/Rumble 👍
dependencies in DNF makes intuitive sense, but that's not so much the case for conflicts
Yea, nothing does
what is DNF btw?
In boolean logic, a disjunctive normal form (DNF) is a canonical normal form of a logical formula consisting of a disjunction of conjunctions; it can also be described as an OR of ANDs, a sum of products, or — in philosophical logic — a cluster concept. As a normal form, it is useful in automated theorem proving.
(I'm assuming)
yeah
oh symbolic logic
or wait?
for conflicts, it seems the top-level operation should be OR
iirc context.before doesn't ahve any return values
or and and's?
Can you give an exampe where it wouldn't make sense?
I can tell you're frustrated, slipping into L1
i might be trippin
L1?
your first language (I saw it was in dutch at first)
no it would be a and b and c
That yea, its bed time
that's not my condition though
But i don't wanna untill it works
the condition is, one or more of these mods is present
oh I see
you need to use card_eval_status_text to display your message instead
yeah wait why are you checking context.individual and context.before?
do those actually happen at the same time? 🤔
but say I wanted (a and b) or c or d
See I see it as this is a list of mods I conflict with
that's fine if it's in CNF
oh this is also a major problem
but in DNF that's a or c or d and b or c or d
A - I conflict with a
A AND B - I conflict with a and b
I see this as follows. In order to load, I need <dependency condition> AND NOT <conflict condition> to be met
I guess I would think or conflicts as a I anti-depend on these
so
A AND B - would actually be NOT A AND NOT B
except the logical equivalent is NOT A OR NOT B
Well if NOT A AND NOT B then I can load
that's A OR B
which is exactly my point
I can easily parse as CNF (reverse roles of AND and OR) and thus have no operator precedence whatsoever and confuse the hell out of everyone
well it's NOT (A OR B) technically
I would just have it behave the exact same as depeandacies, but each low level check is negated instead of the whole thing
So A OR B AND C is treated as NOT A OR NOT B AND NOT C
do we really need DNF for the deps though
unless we support bracketing (which I won't), it's always either a representation of DNF or CNF
do you understand what I'm saying?
not sure if you're asking me or aure
aure
sort of depends on the operators you will use in both dependencies and conflicts?
I think we just want and and or
but internally when doing conlficts any "literal" (like A or A > 5.0.0) just gets inverted
is either intuitive enough for
conflicts: A and B
conflicts: A or B
?
yeah I just confused myself
a,b|c,d should parse (a) and (b or c) and (d)
for dependencies
yes
which has AND being weak, which is not how that works normally
Yes I guess it does
if (a) and (b or c) and (d) is a stand-in for (not a) and (not b or not c) and (not d) and that's just another condition for loading (not one for not loading)
that means in order to NOT load, I have the condition
(a) or (b and c) or (d)
so shouldn't the focus be on making the json format intuitve to uh... non-CS majors, and then converting it into logic from there?
which to be fair seems like what you're doing
it makes enough sense for dependencies
Well we need to figure out how to program it before we specify how to define it
A, B | C, D makes sense for dependencies right?
well that's a choice, but I guess the sort of choice a programmer would make. I read on some stackoverflow thread that I guess what I'm reffering to would be called 'readme-driven' development
lmao love that term
Well in this case it's moreso we need to figre out how to interprit sutff before we figure out how to parse it
this conflicts either one of A<=1.2 and A>=1.0, which is all instances of A
okay
no
idk about that
especially if we want to do stuff like optional depeandies (which would just mostly be load me later)
! but still I don't really like that
negation just makes reading it a pain in the ass
So i guess if we were just to simplify it, , would just be seperating seperate elements and | would be conditions that support multiple
I wonder if someone made a version resolving thing we can just steal
including negation extends it logically to having conflicts and dependencies interact
Steamodded>=1.0, !Talisman>=1<=2, !SomethingElse|CompatLayer
See the issue is that gets harder to parse (as a human)
Like is !SomethingElse|CompatLayer ~(A|B) or (~A)|B
and then also if we want the other now we need backets
so then how do I represent ~(A|B)
besides ~(A|B) is ~A,~B
isn't the provides supposed to do that
Well you could have 2 things that provide similar apis and have the logic to choose between one or the other,
I could normally conflict with something unless something else is present
I'm not sure how provides helps there
ah
provides would be so somethingelse could provide compatlayer at the specific version
I'm not sure I understand the purpose of a negation oprerator when the field is already for anti-depends?
.
my point is to get rid of anti-depends as a field
Well the idea is we get rid of conflicts and you just negate your depedancies for conflicts
there's one dependency field for both depends and anti-depends
I like the idea of an anti-depends/conflicts field
oh that seems needlessly convoluted on the users
yeah I agree
feels like there's no intuitive way to do this though
tbh could this discussion use a thread?
probably yea
I feel like it's a longer discussion and not getting it buired in modding dev may be nice
Make a #1209506514763522108 thread or one in this channel?
this channel really could use its own dedicated threads counterpart
Depedancy Discussion
as could modding-chat tbh (for casual topics not fit for #1209506514763522108)
I think just threads in their channel is fine
The issue is they're not really persistent or browsable. Fine for their intended use case of break-away convos, but less so if you want actual forum topics that don't fit the #1209506514763522108 vibe
It's also possible I just have some sort of allergy to understanding Discord's interface, lol
they are very much persistant and browseable
they even do the same thing under the channel for with messages
Indeed I just... never knew what that button was before
This I did see ofc
Just didn't know about the list of all of them
Threads in channels don't make a lot of sense except in more active channels
cause most of the itme you're not going to exceed two convos at a time
and often they don't need to be followed up
so a new convo is fine
I still think it'd make sense to have an additional forum channel for more modding-chat style memes and like "what's your favorite mod atm" type threads. Leaving #1209506514763522108 to its defacto use case of mostly project threads
how would one use a joker to change what a seal does
for example i want to make a joker that changes blue seal to have a 1/2 chance to give a blackhole
Looking at the code for this would probably be a good start
oh ok
huh
Look at elbe's port
?
oh hmm
Mika's is abandoned so this is the canonical version
Maybe was a better example?
Oh hmm
this is for a joker in cryptid so il have to make it compatable with this somehow right
Tbh I don't know how sensible this stuff In mika's is coded, so take it witb a grain of salt
How do you mean?
?
Make what compatible with what?
i mean im doing this for a joker in cryptid should i worry about this or no
The stuff in mika's will probably take care of itself Idk
im just goign to not for now if modpacks break modpacks break
You'd have to ask @dense jasper
bro out here @ing people
Idk how many people have both cryptid and mika's. I guess dimserene's pack users
Seems not to bother people. I don't do it with Myst or anyone else I know minds
Harp seal is, I believe, hard coded to just replicate what the vanilla seals do.
So yeah it shouldn't break anything. Just not exactly follow the description
Long term plans were to make it work for modded seals just haven't gotten to it
Could you reuse the logic for stuff like oversatuated and glitched but just apply it to seals
Since it is a cryptid joker
I'm a complete 0 in programming, and my translator is clumsy, but here's what I came up with: let's add a variable, if this variable has a value of 0, then the blue seals work as usual, but if the value is greater than 1, then they will give black holes, and the joker will simply add 1 to the value of this variable
appreciate it
@muted kite sorry if the ping bothers you, but would you happen to know if steamodded supports giving jokers custom Card:draw functions?
anyone know how to get rid off other event queues? they keep stacking and stacking up and laging out my game
afaik no
also you'd be better off pinging @ aure__ for steamodded now
you need to find which mod is calling all the events
well i know that the events increase whenever cards get drawn or redeposited back in the deck, but somehow, not in challange decks
no
but stickers do, for some reason
:]
Honestly forgot the reason
Oh wait I know
Using a different shader for the shine or not having it all
Felt for intuitive to just expose drawing the sticker over a variable that disabled the shine.
You can clear the queues as well, but I don’t remember the syntax off the top of my head
Probably something like queue:clear_queue()
@frosty dock have you fixed the hovering crash?
because i just updated and it still does that
ah no i still need to do that
🥀
i was too busy discussing dependencies
done
tyty
i'm trying to add a new challenge, but its name shows up as ERROR
name = "Debug Challenge",
id = "c_debug_1",
rules = {
custom = {
},
modifiers = {
{ id = "dollars", value = 1e200 },
}
},
jokers = {
},
consumeables = {
},
vouchers = {
},
deck = {
cards = { { s = "S", r = "K", e = "m_glass", eternal = true } },
type = 'Challenge Deck'
},
restrictions = {
banned_cards = {
},
banned_tags = {
},
banned_other = {
}
}
You need either a loc_txt or a full localization file
i'm having trouble getting loc_txt to work
table.insert(G.CHALLENGES, {
name = "Debug Challenge",
id = "c_debug",
key = "c_debug",
loc_txt = {
["en-us"] = {
name = "Debug Challenge"
}
},
rules = {
custom = {
},
modifiers = {
{ id = "dollars", value = 1e200 },
}
},
jokers = {
},
consumeables = {
},
vouchers = {
},
deck = {
cards = { { s = "S", r = "K", e = "m_steel" }, { s = "S", r = "K", e = "m_steel" }, { s = "S", r = "K", e = "m_steel" }, { s = "S", r = "K", e = "m_steel" }, { s = "S", r = "K", e = "m_steel" }, { s = "S", r = "K", e = "m_steel" }, { s = "S", r = "K", e = "m_steel" }, { s = "S", r = "K", e = "m_steel" } },
type = 'Challenge Deck'
},
restrictions = {
banned_cards = {
},
banned_tags = {
},
banned_other = {
}
}
})
where are you putting this code
body of main file
loc_txt can only possibly work with steamodded APIs
you're directly inserting into the game's challenge table
how do i do this properly
SMODS.Challenge({ your table here ... })
that worked! thanks
how do i ban blinds from other mods in challenges?
waitwaitwait lemme try something first
alright just include it in the table
it's ignored if the mod isn't active
also haha the challenge screen breaks if you ban too many blinds
also even though the blinds show the correct description, their sprites are wrong
i'm trying to make a challenge that debuffs certain poker hands, how would i go about doing that?
What is correct way to replicate creating cards for Standard Pack?
Ingame code so hardcoded, which is not good for other mods support (like seals)
And how to scale card properly?
Lovely injects are how most mods handle it right now
why lovely inject when you can monkeypatch 
local card_draw = Card.draw
function Card:draw()
if --[[ some condition ]] then
-- stuff goes here
else
card_draw(self)
end
end
i mean performance is probably the reason but who cares about performance :D
/j
because you're goiong to miss out lots of stuff
ah it's fineeeee

i mean look my end goal is a 3d joker
nothing's gonna work with that anyways
lmao
this is always way better than lovely patching when you can do it btw
oh?
lovely is only for cases when this isnt convenient
does lua implement tco?
sorry?
tail call optimization
now the REALLY bad this is overriding the function entirely
no clue but i know function call overhead is not that bad in lua
oh it does! awesome
so doing something like
function f(v)
if cond then return v end
g(v)
end
takes up zero additional stack space since it jumps directly from f to g
which means you don't get stack overflows from recursion and it's a little faster 🎉
this only works if the function call is deterministically at the end of the function
hence, tail call optimization
@hardy viper
WAIT HI MATHGUY !!
HI BALT factorial factorial
omg balt hi
kjdfghdf
we don't know each other
hi lol
i figured it out
omg hi cg
?
so what's a good way to load something that isn't a regular asset? do i just put it in the mod files and then load the file like how you usually do in love?
turns out that's not the case
currently trying to make a custom edition for playing cards, but it keeps crashing when I try to apply the edition and I have no idea why
So idk the issue, but in any case you should be developing these on the newest smods and lovely
am I not?
Lovely is on 0.6.0 now and steanodded gets updates at least every couple days including a fairly big one on the 30th
fun
I don't think the card.edition.phantom syntax is right? Unless you saw that somewhere
I saw that in the main code lol
they flag an extra variable on the edition for use with edition checks when it's set
and like the edition works fine in the collection
so I think either I'm setting it wrong or something funky is going on
Well if it's the key, then the actual key would include your mod prefix
I mean I can try that
Definitely worth a try. Smods always accounts for conflicting names
no change
Did you do card.edition.prefix_key?
Yeah I'm not sure you need those on_apply things for smods.edition objects
ah you're right
Here's what the editions in ortalab look like
You still want loc_txt ofc. Ortalsb just uses loc files instead
so I'm looking through the code in Steamodded to find out what's crashing
it's this line in their set_edition function
ok I got it working after a lot of pain
Looks lile it was a mod prefix error?
You also don’t need those on apply and remove functions at all
i can feel my motivation coming back
augh time to do 7 more arts so i can release OS
hey, looking for some assistance as am unsure what is wrong with code. trying to code it so that if current hand played is the same as last hand plated, joker will upgrade. currently it upgrads on every card played. looked through a few other mods that have something similar but have been unsuccessful
loc_txt = {
name = 'Bobo Doll',
text = {
"This Joker gains {C:chips}#2#{} Chips", "if played hand is the same","as previously played hand.", "{C:inactive}Currently {C:chips}#1#{} {C:inactive}Chips"
}
},
config = { extra = { chips = 0, chips_gain = 10, last_hand = 'High Card'} },
rarity = 1,
atlas = 'JestersPrivilegeAtlas',
pos = { x = 3, y = 0 },
cost = 4,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
loc_vars = function(self, info_queue, card)
return { vars = {card.ability.extra.chips, card.ability.extra.chips_gain, G.GAME.last_hand_played } }
end,
calculate = function(self, card, context)
local last_hand = G.GAME.last_hand_played
if context.joker_main then
return {
chips_gain = card.ability.extra.chips,
message = localize {type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}}
}
end
if context.before and not context.blueprint and context.cardarea == G.jokers then
if context.scoring_name == G.GAME.last_hand_played then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chips_gain
return {
message = "Upgraded!",
colour = G.C.CHIPS,
card = card
}
end
end
end
}
I imagine G.GAME.last_hand_played is updated before the joker is being calculated
yep you are right, just did a quick search in the server and seems to be the case lmao. thank you
you can store the last hand inside your jokers extra table though
Can I somehow inspect an object's full key ingame
Like jokers, booster packs, consumables, blinds, etc
local click_ref = Card.click
function Card:click()
click_ref(self)
print(self.config.center and self.config.center.key or 'no key found')
end
something like this should work
So then everytime I leftclick an object, the full key will be printed out?
yeah
In the console I assume
if you have debug plus it'll show up there too
hello me again. trying to make it so if a glass is played, xmult is added to the joker, however get this error: bad argument #1 to 'ipairs' (table expected, got nil) and am unsure why if anyone could help
loc_vars = function(self, info_queue, card)
return { vars = {card.ability.extra.x_mult, card.ability.extra.x_mult_gain } }
end,
calculate = function(self, card, context)
if context.cardarea == G.jokers and context.before and not context.blueprint then
local faces = {}
for k, v in ipairs(context.scoring_hand) do
if v.ability.effect == "Glass Card" then
card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.x_mult_gain
G.E_MANAGER:add_event(Event({
func = function()
card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')}); return true
end
}))
end
end ```
Check if context.scoring_hand exists too, I dont remember if its created on context.before
you don't want to do this in context.before
you want to use if context.cardarea == G.play and context.individual and not context.blueprint then and then use if context.other_card.config.center_key == 'm_glass' then
I believe that'll work
legend thank you. if i could ask, why not use context.before in this situation?
Hi, I'm new here. I wanted to know how modding this game is. I never really learn code, but I would be done to learn for this game, however, I would like to know how hard it can be.
I already understood how to change text and texture. But the thing I want to do the most is some Joker, would it be hard to start with that?
jokers are decently easy to do
as long as you don't do anything too outlandish like implementing an entire new system
there's probably a way to do it, or a similar method you can reference in another mod
also the steamodded example mods are great for that kinda stuff
Oooh, ok, good to know
the example mod re-makes a bunch of vanilla stuff in steamodded format
oops
cool video but wrong link
there we go
That's exactly what I need I think, ye. Thank you very much!!
that's the one for jokers, they have others for other game objects in there
and don't be afraid to look into other mods' code to see how they do a certain thing
you dont need to reinvent the wheel if someone else made a similar joker already
Perfect, I'll start looking that up, thanks
Perfect, good to know
the beauty of open source coding
Hehehhe
if you have any other more specific questions this is the place to ask and you'll get a reasonably timed response
anyone know any sites where i can edit my save? not sure where else i'd ask, but i want to port my joker stickers and stake wins from mobile -> pc, essentially "merging" my saves
oop! nvm, didn't realise the first result let you put in files other than just save.jkr

gotta love the spaghetti code that led to the stay_flipped parameter in the draw_card function being overridden inside the function in every use case
Guys, why is the game crashing when I try to play a sound, saying
Could not open file resources/sounds/buf_crystal.ogg. Does not exist.
The sound does, in fact, exist though. Also I'm using the same syntax I used to play another sound which works. Both sounds are .ogg files. They also have similar sizes / lengths. I can't figure this out
The /sounds folder. The 'explosion' sound works fine, but the 'crystal' one doesn't
seems like steamodded prefix shenanigans
I used the 'buf_' prefix on both occasions
Can you show the sound definition?
Here
No where you create the sound
Using SMODS.Sound
Oooooog
Right, omg

gonna potentially try to start nodding today, any tips on setting up a development / testing environment? are there any stub files available to make working with the api easier or testing mods to enable quick testing of a particular joker?
And cg
you shake your head up and down at a rhythmic pace

anyways no there's no way of doing what you're asking outside of a couple love2d definition extensions, the best way is to just use some sort of IDE with luals and make sure all the dependencies (like steamodded) are in the environment
as for testing a particular joker, use debugplus so you can just spawn it in with C and too many jokers to search it up in record time 
proud self insert right there
It's probably best to just use the game to test stuff. You can use DebugPlus to give yourself some debug tools to work with during testing and TooManyJokers to quickly find the joker you want to test.
https://discord.com/channels/1116389027176787968/1228149931257237664
https://discord.com/channels/1116389027176787968/1292542891800920215
Probably a good idea to create an in game profile just for testing, so you don't mess up your stats and stuff
awesome! thank you bothhh!!!
is there any way to reload a jokers functionality dynamically so i wouldn’t have to exit out to fix bugs? i know lua is interpreted so it should be theoretically possible but idk if steammodded is built in a way that supports it
we've tried but have never gotten it to work because side effects in mod files are extremely common. You can however, for testing purposes, use the watch command of debugplus to load/reload files when changed
awesome! thank you so much!
forcing myself back into balatro moddinf: how plausible is it to have a joker that gains the amount of chips each played card gives? i can kinda visualise the code in my head, but wanna ask people smarter than i 😭
seems very doable
yeah seems like a reasonably simple idea
oh thank god
i'd presume the main meat and potatoes of the could would be something along the lines of
card.ability.extra.chip = card.ability.extra.chip + card.ability.extra.chip_gain then
return{
message = "you played a card! good job!"
colour = [color here]
}
end
of course, within the correct contexts
more like
card.ability.extra.chip = card.ability.extra.chip + context.other_card.base.value
(if I remember my contexts correctly)
all my code is botched together unless theres an example version i can steal from
is there a good way to check another mod's settings?
im.. trying something, it just says attempt to perform arithmetic on field 'value'
(actual crash log, i know im missing something but no fucking idea what 😭)
base.value is a string like "8", "10" or "Ace", not a number
you'd want to use context.other_card.base.nominal for base chip value
thank you 😭
that works, ty ty
is there a way to make the joker trigger specifically at the end of the hand? currently this one triggers after every card played (and adds the chips every time), which is a little busted
Ice cream
oh yeah, true
funny
remove the chips return and throw a context.joker_main check in afterwards
ah, ty
SMODS.Mods.<other_mod>.config works I think?
i know this is me being stupid, but is this what you meant 
no
the if context.joker_main then needs to be a seperate statement
let me find you an example
thank you 😭
I pro e y ur run!
i wasnt sure if you meant throw the context in the main if line, so i guessed
ahhh, gotcha
ty
~~i was gonna make a triangle joker, with that exact same premise 😭 ~~
it works! ty

is it just me or does love.filesystem.read just. not work. it says the file doesn't exist when it very much does
paste the line
i imagine your issue is assuming the working directory is where your lua file is as opposed to the balatro appdata folder
local mesh = obj.load_obj((mod.path .. "assets/test.obj"):gsub("\\", "/"))
function obj.load_obj(path)
local obj_file, err = love.filesystem.read(path)
if not obj_file then
error("failed to load model: " .. err)
end
-- ...
end
and the error message is failed to load model: Could not open file C:/Users/baltdev/AppData/Roaming/Balatro/Mods/Jimbo3D/assets/test.obj. Does not exist.
weird
that gsub was me trying to fix it, didn't work
try with nativefs.read i guess? that'll tell you whether it's a love filesystem issue
nativefs?
lol
also yeah i'm loading a 3d model, mostly as a proof of concept
it's called love2d for a reason 
idc 
working off this and advice SDM and Eremel gave, have got it working so when a glass is scored it adds x mult, but also want it that if a glass shatters it resets.
thought it would be a simple steal glass joker code and tweak it but nope. I have tried many different things and nothing seems to work - current error is the same bad argument #1 to 'ipairs'. I understand that i probably shouldnt be using the ipairs anyway so i have tried looking for other mods that use shattered cards but havent been able to find anything that could help me, if anyone has any ideas.
calculate = function(self, card, context)
if context.joker_main and card.ability.extra.x_mult > 1 then
return {
Xmult_mod = card.ability.extra.x_mult,
message = localize {type = 'variable', key = 'a_mult', vars = {card.ability.extra.x_mult}}
}
end
if context.cardarea == G.play and context.individual and not context.blueprint then
if context.other_card.ability.effect == "Glass Card" then
card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.x_mult_gain
return {
message = "Upgrade",
colour = G.C.RED,
card = card
}
end
end
if card.ability.extra.x_mult > 1 and not context.blueprint then
for k, v in ipairs(context.glass_shattered) do
if v.shattered then
card.ability.extra.x_mult = 1
end
end
end
end
so how would i go about detecting if an arbitrary Card is my joker?
.name isn't set by steamodded
or if it is, name isn't set in the collection listing
this is for custom logic in Card:draw
Wouldn't it just be .key?
that's not set either
i looked into it and it
makes.
entirely new Card instances
in the collection.
Hmm maybe check the sprite object for the key? I'm kinda just throwing things out they'd, but it has to be there somewhere
okay, What
why do i have a value of type table
that when printed prints nil
and hard crashes when i do anything with it
is this deadass a null pointer
Your object should have mod in it, that could work no?
i think it might be which begs the question - how the fuck did i get that
lemme do some diggig to make sure that isn't whjatr's happening here
okay it isn't lmao
so uh, is there a way for me to access the SMODS version of a joker i've already taken ownership of?
any apparent reason why this code neither changes the card nor spawns a message?
nevermind i misunderstood how the function took the rank lol
hh i think 3d is a bust
can't get it actually drawing
wait love.physics exists
just had a REALLY funny idea for a joker
you know these things
"x3 mult when ball is inside cup", but the shake from Card:juice_up yeets the ball wherever the fuck
it's REALLY good so you kinda gotta pick it up when you see it but also REALLY annoying because you gotta reset it every. time. which takes like 5 minutes. and you can't really do retriggers on it
i was thinking "hgey i should make more jokers like this and make a content mod out of it"
and then i was like "okay what would i name it"
and fucking
Jimbotomy
just jokers that are Weird.
and to get their full potential you have to do esoteric and possibly frustrating things
do you like it
Not really
gottem
that's what i'm going for
LMAO another idea
"+20 mult if language is not set to system language"
hmm what else
"x5 Mult if Chips is prime, debuffed if Chips > 1,000,000,000"
X1 mult for every joker who's name doesn't include "Joker"
oh that's good
+1 mult for every modded boss blind installed
lkjfds
Roll the Dice: +{N} mult, 5/6 chance when selling this card to create a Roll the Dice with the same enhancements, edition, and seals with +{N+5} mult (N starts at 0)
Time to buy madness or dagger
no specifically when selling
Exactly
dagger destroys, doesn't sell
With eternal in parenthesis and a sell value listed I'm confused
Oh I see
It creates itself when sold
actually imma change the name
It's a good name tbh
Call it the gambler lol
Reminds me of Jimbo's Ouroboros
It's similar it just makes a stronger version of itself that costs more spawn in shop when you sell it
But this is distinct and interesting
alr imma make some of these lmao
maybe not the one that needs love.physics yet, don't wanna be up until 4am setting that up
ah wait this doesn't work because localization
well
ig i could take the localized string for jimbo ("Joker") and then search for that
yes
hmmmm you know
i've made raymarchers before
oh my god hilarious idea
Pirate Joker: +20 mult if Steam is not initialized
Dyslexic Joker: Each hand is scored as a random hand type
eh, no why would you take that
well ig with a little tweaking it could be good early game, bc you could random into things like flush five
tbh I feel the hand type matters too much to be left to chance like that
doesn't seem to
if (SMODS.Mods["Cryptid"] or {}).can_load and SMODS.Mods.Cryptid.config["Blinds"] then
table.insert(permamouth.restrictions.banned_other, { id = "bl_cry_oldhouse", type = 'blind' })
table.insert(permamouth.restrictions.banned_other, { id = "bl_cry_oldpillar", type = 'blind' })
table.insert(permamouth.restrictions.banned_other, { id = "bl_cry_oldflint", type = 'blind' })
table.insert(permamouth.restrictions.banned_other, { id = "bl_cry_oldmark", type = 'blind' })
end
looks like the mod would have to be loaded first 😅
maybe put it in the function where the run starts or smth
is it easy to "reimplement xchips"
Why not just depend on talisman
I don't think it's an issue to depend on it but a lot of people for some reason hate doing that
¯_(ツ)_/¯
I hate having talisman because the actual head-lining feature needs special compat, so I feel the need to have it, while also keeping it set to vanillia
which until math makes the config save to the config folder, has other issues
if i do anything xchips in tsunami it'll use talisman as a dependency because you're already getting fusionjokers as a dependency anyway so why do you care
I mean I already have Talisman and don't plan to play Tsumami (sorry), so it's not something that bothers me
I just think the Talisman situation is in general unfortunate
yeah you're (unfortunately) the last person i expect to play my mod
so for limit must be a number crash on this line in state events.lua
what's that mean
happens when i play a hand with the fusion i just made
it doesnt even do anything outlandish nor use retriggers so i'm confused
you need to add and not context.repetition iirc
yeah this is an unfortunate consequence of it adding all the extra stuff, though personally I'd never use xchips anyway so 🤷♂️
so is it difficult to reimplement xchips
can i copy borrow some code from talisman to do it or is it harder than that
I'm guessing your other jokers don't just use context.cardarea == G.hand
implemenet xchips is pretty straightforward
it's just a couple of lovely patches iirc
yeah none of the others do
so that's why it is, noted
yeah that shouldn't be so bad
one of the other projects i'm on uses xchips
so i'll do that for that one
tsunami will use talisman as a dependency
is there a way i can have this code (in lovely.toml) not load if talisman is present
dont want anything to break if this mod and talisman are both present
just change your variable name to be different to talismans
which variable name
oh I almost forgot about the sounds
for your xchip return
which one is that
this makes zero sense to me
so say talisman uses x_chip_mod as it's return value name, you can make yours tsunami_x_chips and it won't conflict with anything
this still makes no sense to me
i think this is out of my pay grade for now
just gonna bite the bullet and have talisman as a dependency
I think I saw a mod check in some .toml file of Cryptid's
Can't remember which one though
But it's probably possible
We need custom xchip or ^chip/mult api 😏
(jk, idk anything about that stuff so don't take me seriously)
It’s called talisman
on one hand true but i feel like xchip is common enough to warrant a smods inclusion
tbh same. I think that because it doesn't alter base game functionality, it should be fine
I feel like a large part of Talisman could be merged with Steamodded, ye
there are defintely an Amount of things that are common enough, but i 100% agree that xchips is common enough
out of all features i’d want next in steammodded, xchips is definitely up there
is there a way to enforce a max amount on a joker? for example, if i wanted a joker to only be able to gain 100 of something - would it be possible? 
that's
and i hate to patronise you
trivial
you take the increase amount, check if it's above 100, and if it is, set it back to 100
not patronising, and it just clicked in my head on how you’d so it
yeah
😭
i forgot code can code
increase = <insert calculation>
if increase > 100 then
increase = 100
end
card.ability.extra.value = card.ability.extra.value + increase
literally that
yeah, i was writing that out as you started typing 😭😭
it happens to the best of us
i mean yeah everyone whos good at coding forgets the simple shit
ong, clearly just means im amazing at code 
why do that when you can just oneline it
math.min(increase, 100)
How can I rename Joker by using some value from card.ability?
in the context of what im doing, just put:
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain and math.min(mult, 100)
?
random mult gain? cool :o
lol
card.ability.extra.mult = math.min(card.ability.extra.mult + card.ability.extra.mult_gain, 100)
did the most recent update break modding? I tried following the guides on installing mods and found nothing changed
If i were to restart the modding proccess, would a clean reinstall of balatro help?
balatro's 1.0.1m? no, everything should be fine as long as you're not using steamodded 0.9.8
hmmm, i think i installed the 1.0 alpha version
one sec
oop ok i did download the 9.8 version. do i just do a reinstall of vanilla balatro to restart and install 1.0?
it should all be in the guide https://github.com/Steamopollys/Steamodded/wiki/01.-Getting-started
kk thanks
how do i check how many enhanced cards are in the deck (for example drivers license)
?
if self.ability.name == "Driver's License" then
self.ability.driver_tally = 0
for k, v in pairs(G.playing_cards) do
if v.config.center ~= G.P_CENTERS.c_base then self.ability.driver_tally = self.ability.driver_tally+1 end
end
end
this is the code that tallies driver's license
what's the best way to organize code into different files like cryptid does?
@brisk rose i know you probably can't do much about this but when im using the modpack the game stack overflows when i try to switch profiles
^ someone else in the cryptid discord had the same issue
anyone using the blind animation tool in aseprite? I'm having some issues with it misaligning
Yeah I noticed that too. Dunno what mod is causing it
i think it's all of them
it must be loading in all of the unlocks, which is like a couple thousand stacks (a lot i think)
Try removing card-exporter. There's an update but I haven't pushed a release. I know it does things with unlocks
I don't think it's just a scale issue
is G.hand.highlighted supposed to be nil when a consumable is used?
i have this so far
use = function(self, card, area, copier)
local left = nil
local right = nil
print(G.hand.highlighted)
for k, v in ipairs(G.hand.highlighted) do
if v == card then
elseif left == nil then
left = v
else
right = v
end
end
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
left:flip()
play_sound("card1", 1.15 - (1 - 0.999) / (2 - 0.998) * 0.3)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
right:flip()
play_sound("card1", 1.15 - (2 - 0.999) / (2 - 0.998) * 0.3)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.1,
func = function()
local left_suit_prefix = string.sub(left.base.suit, 1, 1)..'_'
local left_rank_suffix = left.base.id
if left_rank_suffix < 10 then left_rank_suffix = tostring(rank_suffix)
elseif left_rank_suffix == 10 then left_rank_suffix = 'T'
elseif left_rank_suffix == 11 then left_rank_suffix = 'J'
elseif left_rank_suffix == 12 then left_rank_suffix = 'Q'
elseif left_rank_suffix == 13 then left_rank_suffix = 'K'
elseif left_rank_suffix == 14 then left_rank_suffix = 'A'
end
local right_suit_prefix = string.sub(right.base.suit, 1, 1)..'_'
local right_rank_suffix = right.base.id
if right_rank_suffix < 10 then right_rank_suffix = tostring(rank_suffix)
elseif right_rank_suffix == 10 then right_rank_suffix = 'T'
elseif right_rank_suffix == 11 then right_rank_suffix = 'J'
elseif right_rank_suffix == 12 then right_rank_suffix = 'Q'
elseif right_rank_suffix == 13 then right_rank_suffix = 'K'
elseif right_rank_suffix == 14 then right_rank_suffix = 'A'
end
left:set_base(G.P_CARDS[right_suit_prefix..right_rank_suffix])
right:set_base(G.P_CARDS[left_suit_prefix..left_rank_suffix])
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
left:flip()
play_sound("card1", 1.15 - (1 - 0.999) / (2 - 0.998) * 0.3)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
right:flip()
play_sound("card1", 1.15 - (2 - 0.999) / (2 - 0.998) * 0.3)
return true
end,
}))
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2,func = function() G.hand:unhighlight_all(); return true end }))
end
print says nil
hey first time modder here can anyone help?
I tried following a tutorial and it says the game crashed with a bunch of lines saying a whole bunch of stuff about errors and such
Hi first time modder!
Can you post that bunch of lines saying a whole bunch of stuff about errors and such
I can try im not sure how to take a screenshot and save it...
don't take a screenshot
copy+paste it
you can just press ctrl+c on the crash screen
Well I mean when I try to open the game it has a crash screen I cant interact with
it had alot of other stuff before I closed it but now it has this
oh wait I think I know what you mean
that one looks like steamodded isn't present
probably just nested on accident
Is this not correct?
it looks fine in this folder
Also it made the lovely folder after I tried launching the game it didnt have that before launch
where could I go to check for errors?
i wish steamodded had basic integrity checks
such as?
errors in nesting is the main issue that doesnt seem to be accounted for
sure, nested just means that instead of Balatro/mods/steamodded/ you have Balatro/mods/steamodded/steamodded/
thanks for clarifying im like a toddler when it comes to modding if its not minecraft or f&h
What now?
could you show the steamodded folder?
Im afraid im not sure what you mean
that's a "no" then, don't worry haha
although you are missing the steamodded/lovely folder 🤔
I apologize for being slow I dont want to try and waste your time as im trying to mod the first time-
no worries!
Could I just make a lovely folder out of nowhere?
well you could but you'd be missing a lot of files in the folder haha
can I see your Mods/lovely/ folder? it might've accidentally moved
Should I try re installing steamodded and see if I accidentally deleted lovely?
Because you can't.
Steamodded is nested -> lovely files inside SMODS can't patch -> code that detects if Steamodded is nested cannot load.
Hmm, nope. No idea where that folder went then
?
Yeah just delete the entire steamodded folder and "reinstall"
Are we sure the mods aren't nested?
alright, one moment...
I mean, steamodded missing its lovely folder should be fixed regardless
?
should I try launching?
go for it
well now im back with the huge line of error code let me take a phone picture...
if you could ctrl+c it that'd be better 😬
Sorry I didnt know I could do that for a sec-
If ultimately my pc just cant mod it i'd be a little disapointed but I could live I just really wanted to be able to mod
why's your balatro version 1.0.1f?
Well, I dont know how to update it as it isnt from steam... if I were to reinstall a "latest version" would it be better?
I think it's crashing because it's assuming you're using the latest version of balatro
Im not sure if that gets in the way as Ive modded lots of games not from steam
(there's some small code changes)
ig checking if mods being loaded are nested is definitely possible but it's more of an issue on created by Steamodded having a different file depth loading than lovely.
I don't recall there being anything else on the pc except steam? is this pirated?

