#💻・modding-dev
1 messages · Page 206 of 1
if you want some sort of visual upgrade that'd change slightly
but this will destroy all scored cards with seals
oh sorry i am stupid it works now
these things definitely need to be documented lmao
this is the sickest joker ever what??
says someone who clearly hasnt read the docs
it's just missing one thing
there's no destroying_card in the docs
there is
I would like to have one yeah
there's destroy_card which is used for things like caino as far as i am aware
then add a message and message_card = card in the return table
in my defense, i thought you were referring to a different context XD
ty eremel
so cool
reusable pointer
how do i make a lucky card-like joker where it has two seperate chance systems? i havent done chance systems in a while
if pseudorandom("blahblahblah") < G.GAME.probabilities.normal/card.ability.extra.chance and you put it in whichever context you want
and you put another one with the other chance value
for whatever reason, this is overriding high-contrast cards... what are we not seeing here? giving the code for hearts as an example.
Add a hc_default = true line to each of your high contrast palettes
worked like a charm!
Excellent!
theyre done
How do you check if a joker has a sticker?
card.ability[sticker_key] eg. card.ability.eternal
Why is this doing nothing?
card cost is complicated
it resets every time set_cost() is called
im severely biting the big one with this code cuz smth seems to be missing
you have 2 loc_vars functions and you're missing the calculate function
Will you release this?
also u cant have 2 consecutive returns
very thankful for n' for giving me this power
if you spell win do you beat the blind?
if you get the score yeah
Doesn't register as a 6 of a kind
To do a 6 of a kind it might be best to start by making a HandPart that returns get_X_same(6, hand)
I'm trying to draw a cardarea that is underneath the deck with 3 cards peeking out. How do?
How can make cards in shop free if they have a certain sticker?
Check for the sticker.
I tried that though
ok i figured out what this issue is here
if you don't set should_apply = false it can appear at a 30% rate on all jokers created
is there a way to activate a joker's effect when it is bought
SMODS's add_to_deck
ty!
That's its own function outside of calculate btw
add_to_deck also happens when jokers are obtained through other means
Thats perfect
meow
finally added a keybind so I don't have to hold m 
how would i make a joker that makes it so discarded cards go back into the deck
sweet
Buff({
key = "card_profaner",
name = "Card Profaner",
atlas = "othercards",
pos = { x = 4, y = 4 },
text = { "Draw the last 3 cards", "from the {C:attention}discard pile" },
use = function(self, card, area, copier)
for i = 1, 3 do
draw_card(G.discard, G.hand, i * 100 / 3, nil, nil, nil, 0.07)
end
end,
can_use = function(self, card)
return #G.discard.cards > 0
end,
})```
ignore all the other stuff
just look at use
actually is there a way to do this with played cards
like would i just replace G.discard
the G.discard is where you're getting the cards from
what do you mean by this?
like after playing the cards they shuffle back into the deck
it was my take on Memory Card for the DNDG mod because DNDG Memory Card is literally just DNA like it has the literally exact same effect
I don't know a way to make them go directly into the deck from playing them
but you could use draw_card from G.discard to G.deck
i c
is it just me or this looks shinier than it should be
planning to do so, yea (got distracted while doing a run to make sure it wouldn't break anything somehow)
it looks like the booster shader is applied twice yeah
dont ask why i know what that looks like
i would check #1308143451040124969 for that, time crystals have this effect
ok chatters time for an odd question
I have a custom context being used in conjunction with a custom card area
and I have another card using that custom context (which is just a regular consumable)
I want to use the card to say a message, but the message appears after all of the cards are put away
I'll attach a vid to explain what I mean
calculate = function(self, card, context)
if context.weapon_hit then
G.GAME.blind.chips = G.GAME.blind.chips - 100
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
local chips_UI = G.hand_text_area.blind_chips
G.FUNCS.blind_chip_UI_scale(G.hand_text_area.blind_chips)
G.HUD_blind:recalculate()
chips_UI:juice_up()
play_sound("chips2")
return { message = "hit!"}
end
end
here's the caculate function too
I was thinking it may have something to do with the calculation order, but I'm not too sure
tbh I'm kinda clueless lmao
where's the context called
oh yeah
lemme get that
eventify(
function()
SMODS.calculate_context({weapon_hit = true, other_card = context.other_card})
sendDebugMessage("sent weapon hit context", "ContextCheck")
end
)
return {
mult = chosen_mult,
card = card,
}
here's an excerpt
eventify is just a wrapper function I wrote
it just puts things into an event
yeah
it gets called before the cards are scored
wait actually no that was something else
it specifically got called before you would see if you actually got a hit
are you setting blocking or blockable in the event?
nope
try putting blockable as false
I'll give it a try
the event is 100% the reason why it goes at the end
would returning func in calculate also do what they want? I assume so but never used it
yes it should do
question: are debuffs handled automatically by SMODS during calculation?
cuz official balatro code has things like this and I'm wondering if it's necessary to do in SMODS
lemme try this then lmao 😭
debuffed cards shouldn't hit any calculation functions
okay so now the stuff is happening with the chips but the message still happens at the very end
what's the code now
calculate = function(self, card, context)
if context.weapon_hit then
return {
message = "hit!",
message_card = card,
func = function()
G.GAME.blind.chips = G.GAME.blind.chips - 100
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
local chips_UI = G.hand_text_area.blind_chips
G.FUNCS.blind_chip_UI_scale(G.hand_text_area.blind_chips)
G.HUD_blind:recalculate()
chips_UI:juice_up()
play_sound("chips2")
end,
}
end
end
incredible indentation
yay
I actually kept both funcs and that makes the timing perfect
thanks for all the help
side note: making the restart one button press is so nice
is there a way to get the current hand size?
G.hand.config.card_limit
note that this may be inflated due to negatives in hand, dunno if there's a way to get the base hand size
is there a context in which it just specifies if a Joker is removed from the Joker slot?
where in the code does it decide when to do the flames?
Is it possible to recreate the effect of the Serpent in a joker? has anyone done that before?
yes me
Can you share the code for how that would work?
that patch is very specific to my joker of course but basically you want to put hand_space to the number you want to draw from deck
where would I put this and how do I apply this
I haven't done a patch before i don't htink
and do you have the text in text form, it's harder to look at what's going on in an image
just copy that one and modify the payload
https://github.com/nh6574/JoyousSpring/blob/main/lovely/effects.toml
Wait do I have to modify lovely?
Is there no way to do this in a self-contained mod folder?
or do patches apply to lovely from the mod folder
you need to put patches inside you mod's folder in a folder called lovely
you can also have a single file named lovely.toml
how do you get the config of stickers from jokers?
#1345543650469220363 message here's hopin' it works. if it doesn't, let us know!
ngl I'm very confused about what this code means but I'll figure it out over time I guess
essentially I'm wanting to do a joker that, if certain conditions are met, will make it so no new cards are drawn.
you only need the hand_space part and find_card for your joker
the rest is for the specific effect of my card
similar to mine
just so you know I made it so it always draw 1 when the hand is empty because the game tries to draw the entire hand again if not
Hi- not sure if this is the right place but I don't see a more fitting place to ask
I'm attempting to make a deck skin mod. I have the Custom Files set up, I have the .Lua file made (based off of the template by "VictinZero" ), but when I put it all in my mods folder it instead pulls up art from another mod I don't have installed (That being "Buddies of Scrubby Pack 2")
I don't know what's going on, does anyone know how I could fix this?
did you upscale the textures?
For the 2x ones, yes
Is there a way to check if a challenge was beaten?
Hello future person, I did it using
G.PROFILES[G.SETTINGS.profile].challenge_progress.completed[('c_PREFIX_KEY')]
assertoin failed for some reason
SMODS.Sound{
key = "BALATRO",
path = "BALATRO.ogg",
select_music_track = function()
return G.STAGE == G.STAGES.MAIN_MENU
end
}
it needs "music_" in the path
there's challenge_progress in profile.jkr, so it should be possible
you can probably check how the vanilla game displays the 20/20 unlocked/completed bars
yee, thanks! ^^
hey, sorry to ping but did you get any success on this? im trying something similar and not having any luck
this is a question I've had for a while but I was too afraid to ask, what does times mean in lovely patches?
iirc if the pattern appears more than once, instead of patching every instance you patch it times times
how can I get the localised name of the boss with the localize function?
Is there something similar to suit_conv for ranks?
Like, with the animation bundled in too?
no
any reason why my function might be considered a nil value? I have a function defined in a separate lua file (which is loaded with SMODS.load_file) but when I try to call it in the main file it thinks the function is a nil value global
i have another function in that same file that does get called correctly but any other function i try to put in doesnt work, even if i try putting it in its own isolated file
it's likely not the load_file where the nil is, it's prob something in the file being loaded
yeah but i dont know what or how
it does indeed load the file just fine but the function isnt recognized
but when i put the same code in the main file it works fine
send the code!!
SMODS.load_file('extraFuncs.lua')
if context.thiscontext:is_suit('Spades', true) then return 'Spades' end
if context.thiscontext:is_suit('Hearts', true) then return 'Hearts' end
if context.thiscontext:is_suit('Clubs', true) then return 'Clubs' end
if context.thiscontext:is_suit('Diamonds', true) then return 'Diamonds' end
end```
the code doesnt actually work for completely unrelated reasons but at least it does get called
tldr when i put this code in my main file it calls just fine
but when i load it in another file the game has never seen it before in its life
funny thing is theres another function in `extraFuncs.lua` that does get loaded fine for some reason
try putting an extra () after the end of the SMODS.load_file
SMODS.load_file('extraFuncs.lua')()
You might be accidentally running another mod's getSuit function that's also been carelessly introduced as a global. Consider declaring your functions as members of your mod's table like function MyMod.getSuit(...) to reduce this clutter - or load your files as modules through Lovely instead
ok now it just isnt loading the extraFuncs.lua file at all
it attempts to call a nil value at that line
SMODS.load_file('extraFuncs.lua')()
Loading as Lovely modules also has the benefit of making crashes and errors more easy to read, as the stack trace will show your module and the calling method, instead of simply a line number in the multi-thousands-long main.lua or game.lua
If i had any other mods with a getSuit function surely it wouldnt be a nil value though wouldnt it
also i dont know what a lovely module is
SMODS.load_file('extraFuncs.lua') works fine though
well "fine"
I don't think it was actually being run until now, it was only assigning the contents of an empty file to nothing. SMODS.load_file('file') returns a function, but you have to run that function with ()
Where is 'extraFuncs.lua' located?
theres another function in that file thats been working fine though so it has been being run
next to my main file
not to be annoying about reading the docs but
Is your mod on GitHub so that we can take a look at it?
no its currently not distributed (i have code that isnt mine in it, its just a personal project unless things change)
No worries
im not sure what this means
Short explainer on Lovely modules in the second half of this comment:
#💻・modding-dev message
that you need to run it like a function, like the example
ooh i see
thats odd though how come all the ones that arent run like a function work fine
ill try it
assert(SMODS.load_file('extraFuncs.lua'))() has an error when reading file
it might be a syntax error
so given the way that showman works, making a new joker that allows duplicates i'd have to patch the lua right? that's not something that i could do without a patch since currently "showman" is hardcoded in right now
The file isn't being found, possibly because it's loading too late after SMODS.current_mod has been reassigned. Try SMODS.load_file('extraFuncs.lua', 'MyModID')() like N' mentioned
AAH WAIT DANGIT I MISSPELLED THE FILE AS extraFucs
Fuc indeed
F
arghhh
idk how that function in it was even working if it technically didnt exist but whatever
It probably wasn't, you should try working that out next
ghosts man
exactly so i have no idea how the code it was called in even worked without it 😭
it doesnt seem to function any differently...
either my code is haunted or i just dont know how it works
for the sake of my ego ill just say its haunted and pretend like i know lua
you took a 5 minute Lua course, and aced it (except for all the quizzes)
my 5 minute lua course was a tiny bit of roblox studio years ago
alright anyway is there a way to get context in a function like this? or some alternative? im trying to run local mysuit = getSuit(other_card) in context.individual and context.cardarea == G.play but my function seems to think context is a nil value for it
the function code is above but ill put it here again
if context.thiscontext:is_suit('Spades', true) then return 'Spades' end
if context.thiscontext:is_suit('Hearts', true) then return 'Hearts' end
if context.thiscontext:is_suit('Clubs', true) then return 'Clubs' end
if context.thiscontext:is_suit('Diamonds', true) then return 'Diamonds' end
end```
That function seems like it might be redundant. Is this a situation where you can't just check card.base.suit directly?
oh is that just a thing
good to know now
yeah that works, cheers
The only pitfall is that it won't account for Wild Cards (SMODS.has_any_suit(card) or card.ability.name == 'Wild Card'), so you might have to deal with that in a way that makes sense for your use case
already have a check for wild cards that bypasses it
But this wouldn't have dealt with that neatly either, it would always report wildcards as Spades.
Great, no probs
check for SMODS.has_any_suit(card) or SMODS.has_no_suit(card) for the opposite effect (stone card)
more relevant for the latter since i dont think anyone is making wild card variants
but the SMODS function for checking wild cards can be hooked to look for other qualities than just enhancement too, so just generally better to use it
why do planet and spectral card edits not load when using a custom texture pack
it does use the tarot sheet, why does it not work
How to copy effects of multiple jokers in one joker?
How do i change the position of a joker with code?
Atlas position or joker slot position?
joker slot position
Sounds doable, but I’m not sure how to do so, either.
I’d try manipulating G.jokers.cards first.
uhh curiosity, can you use lovely patches on SMODS itself?
yes
The patches don't specify a "repo", so I was kind of under the assumption it could only target files from the main program
*G.jokers.cards
I'm still not confident if this could work as intended.
Looking to start making mods, mostly just looking at custom jokers. Anyone got any tips on where to start?
Based on your user name I hope it's Gravity Falls themed.
Haha, just experimenting for now. Want to know what I'm doing first.
Hmm yeah, patching SMODS and not overwriting it is inherently dependent on people's SMODS folder being named something specific in this case
since I can't control the mod installation of other mods, it's easier (even if vaguely disgusting feeling) to just copy whole smods functions and overwrite them lol
(at least I think)
At that point it would sound like function hooking is more tempting.
No? The name of the SMODS files that you would use as a file target does not include the SMODS file name.
So it should be completely irrelevant.
it works for some others, but the primary thing I need to do is to add basically a "quantum edition" calculation, which needs to be in specific places in calculate_context to match up with how editions are triggered in the vanilla game
I can do it for calculate_edition() though
You're gonna have to explain this further to me. I'm not really sure what the resulting file structure is when SMODS runs alongside the vanilla code
Because all the file targets use the root of the vanilla game's file tree, at least in the examples I can find
I.E. functions/state_events.lua is actually balatroCode/functions/state_events.lua
stupid question but is there a way to somehow put the scoring attention text on these small card areas
the coloured squares were rendering way behind in layers when i opened it from the collection
So just that as the target?
(do double vs singlequotes matter here?)
try with SMODS.calculate_effect?
yes
i did that and i think it still does the same thing as others
only make sure that there are no the same kind of quotes inside and outside
Cool, thanks 👍
is G.GAME only exclusively valid when you're actually playing
G.GAME is the table from game.lua that's loaded on startup afaik
Nah, G.GAME only loads after a run starts
Oh, I see. I thought some game values were used for startup. My mistake. Things like the splash screen are just in the global table
I do know that it's nil at certain times
ok so I'm trying to have my tooltip event not got at insane speed
Speaking of that, should I use SMODS.calculate_effect here instead of return?
i think so
oh instead of return? probably not why
instead of card_eval_status_text yes
So return is OK here?
Tried to see if I could get a card to be scored from hand and I really did not think its ramifications through
yeah, you use calculate_effect if you're trying to make a second message pop up or something
a card to be scored from hand like this?
Now that's exactly what I've been looking for in other places.
Were you trying to reply to me
yes
Yeah
I have it implemented as an enhancement
problem is I'm trying to figure out how to logically consistent with other effects because the game kind of expects that scored cards are obviously played
yeah sounds complicated
Is this usage correct?
Like this should logically be retriggered by Mime but I can't figure out a good way to do that
looks correct to me
so does it also take into account seals and editions
yeah I just shove all cards with this enhancements into scoring_hand so it basically gets scored like you played it outside your poker hand with Splash
if you want a second effect use extra in the return
also yeah
why does malverk have to be a pain in the ass to use
maybe its a you problem
becuase having to figure out what’s going on with a friend’s malverk texture pack mod is
not fun
here's the crash log they sent me, see if you can tell what's wrong.
Maybe the real pain in the hind is the communications we loss along the way.
how can i get this working with talisman? (crashing when scoring, cannot compare number with table)
"table expected, got string", yet not telling you what string it got. Love coding in lua.
example code from the lua
There's a to_big function to convert number to big number table.
And another function (the name of which I forget) vice versa.
to_number I think is the big->small func
The problem is text.
It should be text = { 'replaces some jokers' },
because usually the game expect there to be multiple lines of text.
I think the issue here is the > 0 bit
lua will refuse to compare a bignum (which is a table) with a number, you need to manually convert them to bignums
so like.. wrap your entire (math.floor(blah)) thingy with to_big() (I don't think you need to wrap the 0 with to_big too? but it doesn't hurt)
You might also want to wrap hand_chips/mult with to_big() as well - I can't remember if that's necessary but if they're both small-nums, that'll cap out there
if you want to be compatible with both talisman and not-talisman, probably check if to_big exists beforehand :P
Tell your friend to update their version of Steamodded and start a new run
how does baseball cards effect work?
as in how does it xmult after a specific joker is played
try searching for its effect in card.lua
So once I have some lua code, and I'm ready to start testing, how do I set up the actual files?
tried to reload the game while the lovely dump was open in my editor for the 10th time award
this doesn't work?
Usually when I boot the game back up it writes to the files as expected and they change while the editor is open
it complains about file being open in another process and crashes
hmm strange. Not sure why I don't have that issue
huh. strange
lmao
this is so real
To which steps have you finished so far?
Feel free to ask us.
Will do. I'm off to bed now though, so I'll fiddle with it more in the morning.
It's always the little things that trip me up, I often just have to go over it a couple times or have someone else point out my stupidity.
yeah okay im scrapping the scored from hand idea for now
wait what
huh
what did you scrap
"Scored when held in hand" enhancement
what is an iron card
ah no the idea was that the card is actually scored
yoinky sploinky
so a full hand of this would let Triboulet go wild
how do i pass loc_vars to center
Common or Uncommon?
we are honey
we live we love we lie
we joker
any ideas on why my super simple baron mimic isn't working properly? it should be returning 2.5x mult when a queen of a particular suit is held in hand. feels like it's missing some functionality code but i stole a lot of this code from card.lua so idk what it'd be missing
remove the "card = self"
If it's a center you should use G.P_CENTERS.<key>
it does not go in the center for some reason
What is it?
i tried making my own center
oh word, i remember someone told me abt this LOL lemme try that
That was not a reply to you
omg so sorry i replied to the wrong msg
i meant to reply to astrapboy just misclicked LOL
tried it with no change in functionality :p it still doesn't work
your suit check is weird
you're comparing card:is_suit() (which should take an argument of the suit youre checking iirc) to the smitten_card thing you define to be a table
try contex.other_card:is_suit(<that thing>.smitten_card.suit)
ah ya, i just figured out that the suit check was the issue. here's what i've got from that (code pulled from the castle example on the git)
wow, that worked perfectly! tysm. guess i never thought to give it an argument.
i want this thing to adjust speed based on if the original card is in the area which play is happening
how can i stop this from erroring? (n is a talisman big number)
for i = 1, n do
result = a ^ result
end
well, now it's still retriggering the scoring AFTER the hand wins, but i can figure that out myself LOL
to_number(n)
Also that number grow would be horrifying.
another one of those weird retrigger shenanigans
it only seems to retrigger the first played card
while according to this, it should retrigger all played spades cards
turned out
any effects that target cards will only retrigger for the first card
dunno why that happens 😭
lobotomized
maybe i can go for a workaround
like
saving the number of retriggers the joker has into a variable, then use context.repetitions
hm
good lord
is that a fucking balatro tutorial
me: "ooh, an ad saying that I won a million bucks? Don't mind me if I do!"
my PC, suffering from the consequences of my actions:
That's dang fire though
i just noticed the word lion in the notebook
dead lion reference?
not my art
How would I prevent this info card from appearing?
It's being pulled from the chrysalis info card but I'd rather it not do that
you think that's bad
This was my attempt to stop it but clearly it didn't work (this is in the chrysalis card code)
what the fuck happened 💀
unrelated but I might actually start using the practice of separating card.ability.extra into its own variable to keep my lines short
It is SO nice
I recommend
thank you random person in this chat for opening my eyes
any way this would actually work
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
for _, card in ipairs(G.playing_cards) do
if card:get_id() == '13' or card:get_id() == '11' then
assert(SMODS.change_base(card, nil, self.config.only_one_rank))
end
end
return true
end
}))
end
🙏
back
You might need to patch generate_card_ui in common_events.lua
oh yuck
Namely this part:
Actually it looks like you can define your own generate_ui function in a card
you can
Tho I'm not smart enough to do UI work lol
it overrides your joker's description too
so you will have to manually do the work ❤️
Or make a dummy center in localization file, and then copy-paste the description you want.
i decided to add a feature which auto adds some stuff in here to joker_main, so if i were to declare chips = 50 then the joker will return 50 chips in its joker_main calculation
❤️
if not card.fake_card then --add info queue
whats the G.___ for the whole deck
i do this for my artist tooltips so i dont attempt to take credit for other peoples' cards
G.playing_cards for the full deck
or G.deck.cards for the current deck
What is fake_card in this case?
I just put credit on my Readme page
its a value applied to the card when it is a fake card made for info queuing
Ah I see
development resumes yesterday
yesterday I asked you
it's just a short walk of 400 days through the void to get there
what?
reference
yiay
Worked like a charm. Plenty thanks
AKYRS.DescriptionDummy{
key = "yona_yona_ex",
generate_ui = function(self, info_queue, cardd, desc_nodes, specific_vars, full_UI_table)
local cards = {}
local card = AKYRS.create_random_card("yona")
card:set_base(G.P_CARDS["S_4"], true)
table.insert(cards,card)
local card = AKYRS.create_random_card("yona")
card:set_base(G.P_CARDS["C_7"], true)
table.insert(cards,card)
SMODS.Joker.super.generate_ui(self, info_queue, cardd, desc_nodes, specific_vars, full_UI_table)
AKYRS.card_area_preview(G.yonacards,desc_nodes,{
override = true,
cards = cards,
w = 1.2,
h = 0.6,
ml = 0,
scale = 0.5,
func_delay = 0.5,
func_list = {
function (ca) if ca and ca.cards then ca.cards[1]:juice_up() end end,
function (ca) if ca and ca.cards then ca.cards[1]:juice_up() end end,
function (ca) if ca and ca.cards then ca.cards[2]:juice_up() end end,
function (ca) if ca and ca.cards then ca.cards[2]:juice_up() end end,
}
})
end,
}
does this code makes sense
no
:3
G.E_MANAGER:add_event(Event({
func = function()
for _, card in ipairs(G.playing_cards) do
if card:get_id() == 13 or card:get_id() == 11 then
print("test") -- never gets here
assert(SMODS.change_base(card, nil, self.rank))
end
return true
end
end
}))
end
what do i do for this deck
@random sleet how would I apply this to a vanilla card, because I have one card that refers to The Wheel of Fortune and I'd ideally like to get rid of the holographic, foil and polychrome texts
Hey! How would I add a custom tab to run info? And all of a special consumable type was there
I'd say just take ownership of the wheel and edit its loc_vars to do that
that worked, ty!

Ok what do the repeater and observer do???
Your return true is inside the for loop. Drag it out.
assert was failing
minecraft part 2
What is your self.rank?
12, string
Try "Queen".
how do you check for the amount of money spent in the shop 
no clue sorry
you could try making a fake wheel of fortune localization to refer to
as much as it's a dumb solution, it is a solution
pong
oh man now wheel of wheel of fortune is gonna look less stupid if you have thac and mistigris together
mod compatibility 
We love accidental mod synergy
i figured it out im just dumb
thumbs up emoji
Im trying to create a joker that retriggers all heart cards, and has a 1 in 4 chance to destroy each heart card
but i cant figure out what im doing wrong, any suggestions?
@onyx sonnet remove the "s" at the end of context.destroying_cards
this was happening before removing the S too
if context.cardarea == G.play and context.individual and context.other_card:is_suit("Hearts")
no retriggers but no crashes
the destruction works fine
if context.repetition and context.other_card:is_suit("Hearts")
👍
Sometimes context doesn’t have other_card, so nested if might be needed.
it does here because of the fact that im checking in G.play, so a hand has been played
and the rep context happens before destroying_card
unless something happened in the scoring process at a time in which it shouldnt have, this should work fine
context.repetition always has other_card
doesnt work
if context.cardarea == G.play and context.repetition and context.other_card:is_suit("Hearts") then doesn't work?
i can assure you it does work
but
you're using a config value you never defined
oh my god
aure thank you for voucher calc
-# back under my rock i go
👀
thank you aure
it was
2014 is three months away...
"if context.other_card.area == G.play" should be
if context.other_card and context.cardarea == G.play
this context doesn't have a cardarea
what is this in then?
context.check_enhancement
oh wait
nvm
it gets run through SMODS.calculate_context
d'oh
but also that part isnt the issue
that's actually the part that works
the suit check screws up
like i can make this work on all played cards like that
whats the error log
Probably some infinite loop bullshit
Check enhancement is probably called inside is suit
@wintry solar hi, is this expected behavior?
I’d need to see the repetition code
oh, it needs to be in context.repetitions too?
i thought since its retriggering the joker itself, the effect should be retriggered too anyways
Well then the retrigger code
...uh, its the exact same code as yesterday
wait
its not the correct joker but thats how it calls the retriggers too
this is the part of the code which doesnt work as intended: it should give +5 mult for every spade card scored
how do i make a joker shake as long as a condition is being met? like trading card or DNA
the function the vanilla game uses keeps crashing my game
not sure if its right, but theres juice_card_until
https://github.com/AutumnMood924/TheAutumnCircus/blob/803c59a3f34d720983e70060e8d04282f10e16de/modules/BasicOddities.lua#L421
i have an implementation of it here
thats the one, but im not sure what i should replace the paramaters with
beyond self becoming card
Oops! The game crashed:
functions/common_events.lua:1277: attempt to call upvalue 'eval_func' (a nil value)
please observe above
should i replace the parameters of it with anything?
the middle function should return false when you want the card to stop juicing
👍
if context.cardarea == G.play and context.individual and context.other_card:get_id() == 12 then
card.ability.extra.queen_count = card.ability.extra.queen_count + 1
print(card.ability.extra.queen_count)
end
if context.joker_main and card.ability.extra.queen_count >= 2 then
print("Should work")
return {
Xchip_mod = card.ability.extra.Xchips
}
end
if context.end_of_round then
card.ability.extra.queen_count = 0
end
end
not doing anything
queens detected but no change is made
it's making the change invisibly
_mod versions of those are used to do invisible changes that will update on the next message
yeah so much so that the score is not changing
use xchips
nope
did you update your smods
do i need to have a function? would a variable be allowed?
it must be a function
the one i have set up just checks if the active variable is ever false, and then stops juicing
or if youd rather think of it this way,
it keeps checking if active, and if so it keeps juicing
nonono
put the function in-line like i have it
and it only takes one variable; this will be the card
you're attempting to call the function (which isn't working because you've defined it as a local variable of this object, and you're attempting to reference it globally.)
a key part of this is that functions are just variables
so function(function(f) hee_hee_hoo_hoo() end) end is valid
assuming the outer function expects to receive a function
which, here, juice_card_until does, on the second argument
should it be appearing in shop?
isn't in_pool supposed to be a function
yep
bruv, thanks
i love making random mod compat
oppenheimer
show graveyard
i see
what about V
just what i called the variable
do i need to replace it with something?
i see
card2 or something would also work
you could also call it weird_thing_with_A_REALLY_STUPIDface and it would work
can i see what you have rn
uhhhhh
are context.joker_main and context.end_of_round true at the same time
i dont think they are ?
yeah
jokers get evaluated as usual at the end of round
but without putting joker main, it evalues every possible element that could be evaluated at the end of round
so it does the ease ante for every card, consumable and joker present
you probably want context.end_of_round and context.cardarea == G.jokers ?
ill try that
this is what i have for a joker that triggers at the end of each boss blind
i think context.main_eval is the important part actually maybe
try that ><""
works perfectly!
i think thats to prevent retriggers
ohhhh yeah maybe
which i should probably add lol in case someone uses a mod that retriggers jokers
idk its been a while since i wrote that joker (like 3 weeks most)
ty for the help !
Does it not set the retriggers to 0 after the first time?
welp
`Oops! The game crashed:
main.lua:1370: bad argument #1 to 'load' (function expected, got nil)
Additional Context:
Balatro Version: 1.0.1n-FULL
Modded Version: 1.0.0~ALPHA-1414a-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.7.1
Platform: Windows
Stack Traceback
(3) global C function 'load'
(4) main chunk of file 'main.lua' at line 1370
(5) global C function 'require'
(6) LÖVE function at file 'boot.lua:323' (best guess)
Local variables:
c = table: 0x3d9ca5a8 {identity:false, version:11.5, accelerometerjoystick:true, modules:table: 0x3d9ca5f8 (more...)}
openedconsole = boolean: false
confok = boolean: true
conferr = nil
(7) global C function 'xpcall'
(8) LÖVE function at file 'boot.lua:362' (best guess)
Local variables:
result = boolean: true
(9) global C function 'xpcall'
(10) LÖVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])
inerror = boolean: true
deferErrhand = Lua function '(LÖVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])`
this
happens when i try to use trance
Maybe i've missunderstood the docs, buit this doesnt work. It doesn't register as a six of a kind.
...im not sure what you mean by that 
but i want the cards to all be triggered, not just the first one
Would this work?
SMODS.PokerHandPart {
key = "crjk_SixOfaKind",
func = function(hand)
if #G.play.cards == 6 then
if G.play.cards[1].rank == G.play.cards[2].rank and G.play.cards[1].rank == G.play.cards[3].rank and G.play.cards[1].rank == G.play.cards[4].rank and G.play.cards[1].rank == G.play.cards[5].rank and G.play.cards[1].rank == G.play.cards[6].rank then
return { hand }
else
return {}
end
end
end
}
And how would i intergrate it into my pokerhand?
A little tip that isn't related to your question:
local _tick = true
local _rank = G.play.cards[1]:get_id()
for i=2,6 do
if G.play.cards[i]:get_id() ~= _rank then
_tick = false
break
end
end
if _tick then
return {hand}
else
return {}
end
end```
Oh, thanks
Instead of a long-'S and/or chain, I'd always prefer checking each boolean value in a for loop.
It just looks nicer to me.
Looks nicer to me too...
So thankies
There's too many buttons inside escape menu now
can somebody help me to make the menu look better?
I have two ideas in mind
- two column layout
- a grid layout that looks like collection menu
yayyyy, the thing we knew was coming finally happened
which mods put their button there Dim 👀
While you're at it, would you consider also colourfying them? I lost count of how many time I mis-clicked the wrong button and ended up in different menu.
This is a concept image i quickly put together
Although I am not sure how to realize this... I was merely giving out ideas 😦
yeah as you can see, quite a few
why tf does Jimbo's Metrics have 3 buttons in there lol
Fold can just be removed ngl, Handy can be removed with SMODS installed, Jimbo's Metrics can use SMODS tabs instead
yeah Handy can probably move to SMODS config, and Jimbo's Metrics def needs to change something
?
oh yeah since I have always show seed, fold button can be removed
why tf does python's os.makedirs not respect shortcuts
but I still think the escape menu can be overhaulled
that menu is cluttered but there are so many unnecessary buttons there
Jimbo's Metrics has SMODS metadata i don't see why it can't be moved to the mods tab
I'll just @tacit hazel
that's windows's fault, shortcuts are neither softlinks nor hardlinks
sorry, should've specified; it's actually a softlink
13-Jan-25 02:29 <SYMLINKD> ManagerSettings [..\BalatroModded\ManagerSettings]
doesn't mean python's os.makedir should start doing the most unintuitive shit
try Path(your_path).mkdir(parents=True, exist_ok=True)
I think I'll just ask dim to use os.path.realpath
no reason to ever not use pathlib
python standard lib is sometimes a mess so i wouldn't be surprised if all the path handling shit from os is mostly untouched
to retain compatibility with, well, everything
yeah that sounds about right lol
anyway here's a handy table on how to transition to pathlib https://docs.python.org/3/library/pathlib.html#corresponding-tools
I already have better solution: give player a choice
🎉
🎉
Still waiting for single place for all lovely mods settings
❤️
hey yall, im kinda new to this so excuse the horrifying code at the bottom which is almost definitely wrong, but im currently unable to even see the text of the joker i've implemented. the lua code is here:
key = "wild_joker",
loc_text = {
name = "Wild Joker",
text = {
"{X:mult,C:white} X#1# {} Mult",
"when Wild Card is played"
}
},
config = { extra = {Xmult = 1.5} },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.Xmult} }
end,
rarity = 3,
cost = 8,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if SMODS.has_any_suit(context.other_card) then
return {
Xmult_mod = card.ability.extra.Xmult
}
end
end
end
}```
players don't look at the settings anyway
loc_txt
Also please make "Collection" dark green like main menu does.
Oof...that idea might not live long though
HOW DO I DRAWSTEP 😢
@frosty dock hello drawstep broke my letter and null card rendering what did it do
basically anything you were patching into Card.draw is now being overwritten
you can take ownership of draw steps you were patching, you can still patch them or you can add your own depending on what you need
Heyo, really easy question Im sure, so sorry if dumb
😭
But I got a skin for the tarot cards I made and I was wondering how to turn it actually...into a mod?
but the patch should still work in older version of steamodded right
I got it working on my game by replacing the resorce files, but I dont want others to have to do that
you're looking for Malverk
Whaaats that?
And that can help turn it *into( a mod?
pretty much you can turn that into a texture pack you can use with Malverk
i guess malverk is being affected too
Oh perfect. time to try remember how to code
active texture pack not being darkened
Its been like 6 years nooooooo
hey I've been digging through chat a while but has anyone been able to replace the soul gem sprite successfully for The Soul card yet?
you mean
just the soul?
just the soul itself yeah. I got the background sprite drawn out but I can't figure out in code how to replace the soul itself.
I'm doing a Subathon theme for my buddy and I want to replace the soul gem itself with a Bit
I've figured out 99% of everything I need for this project except how to actively replace the image drawn. Is it tied to the shaders or something I didn't consider looking into?
I did at least find the lines that point to the location of the sprite, but can't figure out how to replace where it is loading the assets specifically for the soul gem itself.
It doesn't look like it's actually pulling from Enhancers.png at the same stage it pulls assets from it for everything else in the image file.
Just replacing the atlas through SMODS isn't doing enough.
...
SMODS.Atlas({
key = "centers",
path = "Enhancers.png",
px = 71,
py = 95
}):register()
...
you need to replace the G.shared_soul sprite
@frosty dock also how do i prevent let's say front from rendering
sorry i went studying earlier
yeah, it does set self_retriggers to 0 after returning its value to repetitions
And like, a PNG that I grabbed from the games files that it uses for the Tarot and planet cards, does that just work or Do I gotta do something with that too-
i got halfway there but i will need to remove the frontal lobe of these cards to make them disappear
by setting replace_base_card on the center or by taking ownership or patching into the front DrawStep
patching steamodded also doesn't work on mac just yet
oh right
key = "wild_joker",
loc_txt = {
name = "Wild Joker",
text = {
"{X:mult,C:white} X#1# {} Mult",
"when Wild Card is scored"
}
},
config = { extra = {Xmult = 1.5} },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.Xmult} }
end,
rarity = 1,
cost = 8,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
return {
message = localize { type = 'variable', key = 'a_xmult', vars = { card.ability.extra.Xmult } },
xmult = card.ability.extra.Xmult
}
end
end
}
can anyone help me out with this? not exactly sure why there's no x-mult happening. sorry if this is obvious im quite new to modding balatro
wdym
how do i actually take_ownership
my brain is broken
context.individual and G.play is perfectly valid
yeah i mixed up individual and joker_main
but then i read the description
i'm being crazy rn leave me alone
oh because i was reading the steamodded docs and it said to trigger joker effects on cards we need context.individual and context.cardarea === G.play
oops nvm
ignore the description i just want to get xmult working first lol
ill need my frontal lobe ready
good to know
local old = SMODS.DrawSteps.front.func -- if you want to reference the old function
SMODS.DrawStep:take_ownership('front', {
func = function(self, layer)
-- do whatever, call old(self, layer) to access the original
end,
})
Okay So, Im dumb, where do this? It is apart of the Mod itself?
i legitimately don't see anything wrong with it
other than the message getting doubled
you will need to make a new mod
OKay, How do I do that-
try __X__mult
Im VERY new to this
xmult definitely should work
i use xmult
as i can tell it should be triggering every time a card is being scored. but it should happen at least once right
Oooh, perfect, thank you so much!
ok works now
whats up with the second row
ok i take it back this is better than patching who knows what
i duplicated a bunch of stone cards
correct it should be triggering every time a card in play is scored (ala idol, trib, etc.)
well its not doing that and im super confused now lol
same
let me just slap this into a blank mod and see how it reacts
im using the debug mode to spawn in the joker could that be affecting it somehow someway
nope
i test my jokers that way all the time
it works for me
what version of steamodded are you on
ok i just got it working with mult instead of xmult
but xmult should work on latest main (return "1.0.0~BETA-0301f-STEAMODDED"˙)
im not on latest main rn im on an older version i think
lemme just switch up rq
maybe some weird error with the specific version im using
always develop against something recent at least
good to know
holy shit SMODS.https
writing js backend for my balatro mod
what is a funny thing to do with this newfound information
a blind where every time someone defeats it it goes up by 1.01x
but if someone loses to it it decreases by 0.99x
this is awesome
i added compatibility for draw step api
never resume runs after updating smods
i guess I'll keep bumping the minimum version of smods in my mod
so basically always start from a clean slate
okay its working tysm
actual life saver
Real? Hmm, Daily challenge or daily jokers
maybe
Daily wordle
Daily jokes from Jimbo?
aikoyori about to buy an Anguilla domain for them
rq guys, whats the color for cash again?
money
Also how are you doing today
im fine, my parents dont talk to each other today at all, but so far nothing has happened
istg why cant it be collectively called something, like "dollars" 😭
thanks tho
yeah but in the game, the variable holding the amount of money you have in a run is literally G.GAME.dollars
😭
my point still stands, why is it called dollars
while the color is money
💔
we dont talk about consumeables
oh hey
oh thats neat
the second image looks better rite
i think so
can you also add a warning for when mods change
i could but that's more effort
what's with Minecraft modders naming mods after elements
also as good as Create mod is i think the mod name kinda sucks to look up
used to suck
Balatro and Spectrals
mainly optimization mods
mods still have plenty of fun names
Other cards too
I think it started with Sodium and everyone just followed suit
Cryptid, Aura, Trance, etc.
not the biggest fan of mods being named after ingame items
heyyy, that's pretty good
though that probably fucks with the sleeve select doesn't it 🤔
Do you reselect a sleeve on continue?
no but it's present
Well it shouldn’t be if you can’t reselect it
yeah and then you cant see the sleeve name
What if I use my mouse and hover over it
i mean i didn't specifically test with sleeves but i don't think i pushes the play button off screen?
“Maybe make it a pop up 😈” — The evil genie Descartes was talking about
that works just barely
And it doesn’t line up with the stake box anyways which ticks me off
It, as in, the warning
Oh it does in that one that John smods posted
that grey-on-red text makes my eyes bleed
Yeah I probably should have expected that
Figured it'd probably be good enough if the debug stuff didn't show up when in _RELEASE_MODE, but I could see how it's still irritating heh
Pushed out an update to move the debug stuff to the smods config menu
'tis supposed to do that
understood have a nice day
Isn’t there an animal that can squirt blood from its eyes as a defense mechanism
you know how well that works with warnings about mods not being able to load
is there a steamodded thread in #1209506514763522108 bcz istg i remember seeing it once
nice, thanks
also it's lying, we're not a mod loader
I was thinking of blocking the play button until the warning was closed. Either way they can ignore the warning
Steamoment 
hm that's not a bad idea
but I've done enough UI for today
i mean fine
that seems racist myst
but i think the dark text is more annoying
Okay, I got some more questions about this whole "Mod thing" cause the my first Mod thing has me confused
you should make the UI flashes red and white every frame aure
that would make it even more annoying ❤️
If anyone wants to answer that would be awesome
(im def getting a seizure if thats the case)
technically it does flash red every frame
Does anyone know if it’s possible to modify the .lua files to change the odds for things like Negatives to show up?
how so 😭
white > dark, you said so yourself...
Where do I actually write the code?? Can I just do anything that exports .lua files?
im taking yall's cat gifs, thank you
Do I need to download and compile Lua?
anything works, but i suggest visual studio code
Text editor works too just save it as a .lua file instead of .txt
Oh, its that easy? Damn
i do not recommend that in the slightest
OKay, Ill use visual studio, its what Im most used to
Yeah a lot of programming languages are
yeah no it's fine, just something I need to keep in mind
yeah use vscode, not notepad
It’s maybe harder to read, so easier to ignore
dont be naughty
visual studio code, not visual studio 💀
Any reason
@gaunt thistle do you have any preliminary information on why the lovely patches that patches other mods don't work on macOS
visual studio
aure, i used visual studio for coding 😭
😭
(for the first week)
Yeah, I know, looks like it has Lua built in
don't you need to check hand instead of G.play
So this doesn't work, probably me misunderstanding the docs
i didnt even know that until someone corrected me 😭
Idk
Also play boss music
I still use vsc
i had to manually indent my code, that was annoying
no clue, you're the only person I've heard of having that issue.
i feel like that would make it less annoying
what are the valid object types for malverk
anyone else having weird issues on Mac?
if you need more testing from my part please let me know
that's been fixed for weeks already 😭
macOS Apple Arcade version or macOS steam?
i know there’s the ones on the github readme but there’s secret ones… ones i’ve never seen before…like back
macOS Steam version
apple arcade?
no syntax highlighting, no language server
You can do it but you have to to a little more digging
Apple Arcade version is basically moving which I'm not going to mod
i got lovely and Steamodded working on mac
Oh I thought you meant editing the files to change odds
just not lovely patching other mods
Someone gave a tip of making that a poker hand part. I have done it, but idk how i include it.
wait can i use smods.https to stream thick of it
other mods or the game itself?
why does this look ass
Could be file/folder access permissions since macOS is always weird with those
show me one of the patches that whiffs
because you listened to the unbathed masses
By the way, how am I supposed to know if the LSP is working on VSC
try single quotes on the buffer name
I created the .luarc.json file but I feel like it’s not showing anything it wouldn’t show otherwise
the target?
sorry i had to accept a call for a bit
hover some smods functions and see if it shows you the annotations from the definition files
ya
OKay, Question Again-
So, when making a Mod, Im done the whole ID part, for the code, is just done below it?
you have quotes, try single quotes
A new tab, More likely
seriously this looks bad
make it flash aure
If I look at SMODS.injectItems it just says “any”
I think it’s too much text. People are going to ignore it
:>
Green!?
oh hey i have an excuse to make SMODS.Gradient
Do you want my gradient code which was akai’s
no ty
Anyways I think this means it’s not working
Im a dumbass, Im stuck-
This guide feels more like a wiki and I dont know where to start-
Yo, john, This dopesnt work
yo, lunacy

