#đ»ă»modding-dev
1 messages · Page 417 of 1
Now make it spawn the perfect cards for my run
all obelisks
oh my god i got it right on the first attempt
why wouldnt you
anyway im going back to sleep zzz
see u gamers
if only i could figure out why the lucky card version isnt working
gn n!!!! 
Fair enough I have one that does this
I would like to know how much n!!!! is
Gn bestie
3
the blue mult should be ilegal
what???
I did that to mess with my friend and she was very mad
he should kill you 
I gotta grind to get mine up that high though
Cause its unlocked by killing a card and letting its hp reset
Then bonuses double to get added
oh yeah no it only gets this high from testing
all probability gets /10
WOF becomes a 0.1 in 4
So nothing changes actually
Oic
Mine is a boss type beat that has phases
He has hp
Below like half hp he starts debuffing jokers, then at 25% starts destroying random cards played/in hand
If you win you get cash and an increase in the unlocked bonuses
After 2 win you unlock +100 chips i think, then 3 is +10 mult, then 4 is x2 mult
Then you get each number added (or in mult case its just doubled) and the hp is increased 5x each time
self destructs if any chance based card activates
oml đ
Jokers also arent undebuffed until hp is above 50% again (aka defeat)
So he can kill runs if you can't deal high enough chip
oh no
WHAT LMAO
can anyone explain this btw
Do u not like him
Lucky trigger gets set to nil unlike glass.
WHAT
I eventually intend on making him spawn minions that will make him invincible until they're beaten
And those 2 will do diff things as well
But thats a whole lot of effort
N I'm about to snuggle you
yeah I'm installing this, send the link
hi
it's because glass is taken_ownership by smods and it adds a calculate function
lucky is hardcoded
Its not yet ready for release because I am waiting for my STUPID artists to hurry up
But once they are done I'll be making a thread in the mods area!
CURSE YOU
I AM WAVING MY FIST IN set-conditional-to-false CURSE YOUUUU
(I say stupid artists lovingly)
thank you n
now rest your head
a tired mind requires bed
I love when my artist @rigid pebble DOESNT MAKE ME ART đ„°
THE PING?
hard to sleep after picking up the phone
nooo
We have decent progress, this is my current sheet
FYM NO
Is that just perkeo
Nuh uh
Says joker not perkeo
I had to beg him to make art for a Partner for Partners Plus today 
How do I add a title card to the main menu
well im not calling him jerkeo
He looks nice
Look how cryptid does it
villainous answer
I'm trying to display the info for a joker in the info queue of another joker, using the center doesn't have the loc_vars information tho, is it possible to do this?
Its a bootleg variant of trib funny enough
+0.2x mult per king or queen played in the round but resets at end of each round
So if you have enough retriggers you can get to like, idk, 15x mult
But it resets by the end of the round
MAN đ
I'm friends with John Cryptid 
did you eat his code
That is a SMODS issue.
no I just borrowed it permanently
I did a probably not great patch for my title card but it works which means frankly its perfect
The other day when coding one of my partners I accidentally made every card give +2 mult (including in deck and in hand) lol
I made a joker that gives +1 joker slot per revealed hand (and it works for hands revealed before you got it) but I accidentally made it give +1 slot for every hand that exists
Imagine my surprise when 19 or so joker slots
breathe on it and itâs gone
I have so many patches don't say this I'll cry
get the mod that adds like 50000 poker hands, then you'll be all good
I already add like almost a dozen or some shit
Uggggh I got an error
[SMODS Cryptid "lib/modifiers.lua"]:287: attempt to index field 'ability' (a nil value)
Cause you can play up to like 7 card hands
I used to hate lovely patches but I love them now
REAL
I couldn't figure them out before lol
I rely on lovely patches way too much when I should probably be hooking
You should fix that
Cause this is the length of my patches file
Lovely patches shouldn't be used unless absolutely necessary đ
Lovely patches can get messy...
hi quick question: where do i find resources to learn about animating text in jokers?
Half of my shit or more do be necessary
wdym animating text? Like misprint text?
not limited to but yes
wrong
(accurate)
main_endâŠ.
is that John lovely
I wanna have a badge that alternates between tect
All I'm saying is if lovely patches shouldn't be used all the time they wouldn't exist
omg mr John lovely
lovely patches are like nuclear bombs
yes this makes metherul Oppenheimer

So the correct way to solve a problem
Nuclear bombs solve problems the fastest and most efficient way
just be responsible
Smiley face
bomb responsibly guys
"Now I am become lovely, the destroyer of balatro" đŁïž đ„
Probably

my sides hurt
Tell it to stop
Whats something i can do whenever a card is first drawn? In shop, or in the collection?
ur so right
Wdym
I remember once being able to force a card to always be eternal, and it even happened in the collection, I was hoping to recreate that
bump (context: how do i animate text)
something something smods wiki text styling
something something dynamic descriptions
What if we deleted all wikis
Iâd blame you and have you covered in tar and feathers
What if I eated the tar and feathers
Checkmate
Can i ask my easily-answered questions (abt random things pertaining to Balatro modding, obviously) here?
thats why this exists actually
Oh, sweet!
Does anyone know anything about shaders? đ
I've been trying to add some but they all keep breaking from the same reason
how can i find the length of a played hand?
"Shader uniform 'mouse_screen_pos' does not exist"
wrong chat, sorry
What you consider the dumbest possible question is valid to be asked provided it has to do with modding
So always feel free to ask
Yay!! (I am immensely stupid at times)
You can probably use #context.scoring_hand to get the length I think no? Someone can call me stupid and correct me if I'm wrong
i can do one of those
D:
which one is important context here
Its true I'm dum
I wear the dunce cap
i found the text styling (thanks!)
but i coulddnt find anything about dynamic descriptions
you solved my question so yoinks and puts on
oh thats a whole thing that my 3 in the morning brain would rather explode than explain
That's in Localization
how the fuck does loc_var work again lol
lol
thx
Im glad to be of help :D
im so stupid, your solution to my problem was right there if i had just bothered to scroll up
thereâs gullible on the ceiling
how can I have a tarot chose a random Joker to destroy
Get a pseudorandom_element of G.jokers.cards then start_dissolve() it.
Oh did someone else already answer it before me
I didn't notice
Right, i forgot that was there
no, in the code im copying editing writing
Ah icic
Erm well I'm taking credit I'm a genius I'm super smart they call me Mr smarts
I doubt I'm right, but I think im close to something
I also want it to destroy a specific set of Jokers
update = function(self, card, dt)
self.ability.extra.chips = tonumber(os.date('%d'))
self.ability.extra.mult = tonumber(os.date('%m'))
self.time = (self.timer or 0) + dt
if self.timer >= 1 then
self.timer = self.timer - 1
self.ability.extra.chips = tonumber(os.date('%d'))
self.ability.extra.mult = tonumber(os.date('%m'))
end
end
loc_vars = function(self, info_queue, card)
return {
vars = {
self.ability.extra.chips,
self.ability.extra.mult,
}
}
end,
You should be using card not self
it crashed when i was using card
Log?
one sec
line 621 is this line btw
card.ability.extra.chips = tonumber(os.date('%d'))
any ideas?
Do you have extra in config?
i have this
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.chips,
card.ability.extra.mult,
}
}
end,
Yes, but what about config.
i assume not, i dont know about config
Since we're still slightly on the topic, how would i dissolve a specific scored card?
You wouldn't, you would use context.destroy_card
that makes so much more sense, ty!
so like context.destroy_card.math.random(#context.scoring_hand)?
No.
Also don't use math.random
alr
can this be coded? like the only way to spawn this joker is if this specific joker destroys another specific joker?
Yes.
How?
Are these specific jokers jokers you made?
Yes
I think you can reference how Gros Michel and Cavendish work
so just context.destroy_card and it automatically targets a random card?
No.
I'm missing smth here
if context.destroy_card then
return {remove = true}
end
``` Would destroy all cards in hand, in play, in deck and in discard.
interesting, im still struggling with how you would make it remove a card from the scored cards, something to do with replacing the {remove = true} with a random number in the context of scored_hand, right?
No.
im just at a loss then
if context.destroy_card and context.cardarea == G.play then
return {remove = true}
end
``` Would destroy all cards in scoring.
== for conditions, = for assignment.
how to find something in a list?
table.contains(table, element)?
table.contains isn't built-in...
Yes.
oh
for _, scoringCard in ipairs(context.scoring_hand) do
if context.destroy_card and context.cardarea == G.play do
return remove = true
break
end
end
?
-# (i forgot the return but i meant to put it so i edited it in)
im stressing my 5 braincells and this i feel is close?
why wouldnt you use return
If you want to destoy every scoring card, the code I provided does that.
that's what i wanted to say
i want it to destroy just one random scored card
function table.contains(table, element)
if table and type(table) == "table" then
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
end
yeah table.contains doesnt exist i think
Yes.
oh
yeah if i create it
ok thanks
how can i delete an item of a list without having its position in the list?
table.remove(table, position)
yeah, but i have the item name, and not the number
You would loop over the table and find it then.
im just going to make it destroy the leftmost card and call that joker "done" im tired of working on this one
if context.destroy_card and context.destroy_card == context.scoring_hand[1] then
return {remove = true}
end
Itâs not hard, youâre just being given awful help
Whatâs the effect you want to do?
i think the specification of "one random card" was overlooked at first, and i wouldn't call it "bad" bc it actually made me try and think
at first i wanted it to destroy a random card in the scoring hand but im going with the leftmost card so that i can work on any other joker
For a random card to be destroyed, youâll need to select a card in a previous context, Iâd usually use context.before, and assign it a flag, then in context.destroy_card you check to see if the card has that flag and then return remove = true
I helped someone do a similar effect that destroyed a random scored face card yesterday if you need a code example
id imagine its the same code but added an extra check for face cards, and sure
pseudorandom_element(face_count, pseudoseed('exampleseed')).ability.destroyed_by_sizzziii holy what you can do that?
question that's much simpler but is related: why is pseudorandom_element used instead of math.random?
All of the pseudo functions respect the game seed, so youâll have expected outcomes if you reload a snapshot
So that if you play seeded runs you always get the same result
Can you replace music on the fly?
ooohhhhhh, yea that is important here, ty!
Yes.
this means that pseudorandom_element(#context.scoring_hand, psudoseed('balala')) would get a random number that can still be seeded?
Itâll give you a card
a card that was scored or a card in the deck?
(I really hope this is a yes bc I'm getting more and more tired the more i think of this)
Does that mean i can use that to replace the 1 in:
if context.destroy_card and context.destroy_card == context.scoring_hand[1] then
return {remove = true}
end
and it'll select a random scored card to destroy?
...well, it should... but it will do it for every card which can cause more than intended card amount to be destroyed.
It seems that Talisman is causing issues.
oh because of identical copies, remove the brackets and add a break maybe?
Crashes when I have another mod (Fool's Gambit) on, but the fun part is that said mod does NOT touch that shit in any way I know.
As was said, just "mark" a card for destruction in context.before with pseudorandom_element(context.scoring_hand, psudoseed('balala')) giving you said random card... then, in context.destroy_card, check for said mark.
try updating your mods? Youâre definitely on outdated smods
That's the latest release, nothing wrong with that
Looks like more Talisman shenanigans. Try starting a new run first, and if that crashes, try a new save profile
latest commit is typically better because reasons
Except for the times when it's worse because reasons

Still crashes :
Iâd recommend most people using the latest release nowadays
-# minus the view deck crash oops
Speaking of which, @paper zealot I think BMM is targeted at the main branch, do you think you could take a look at that?
Eremel do you know if first_hand_drawn occurs before or after Blind:stay_flipped?
It's kinda weird cuz blind debuff happens after so idk why flipped would occur before
At this point BMM downloads the latest release for Steamodded by default. Same for Talisman and Cryptid also, I've pushed for it to become the norm.
The balatro-mod-index entries are misleading for Steamodded and Talisman specifically, they're manually implemented within BMM instead
Oh sweet thatâs fine then
Though for the sake of other programs that want to use the index, we should probably update the links to release too
I believe it happens after
Yeah hand drawn is after
If flipped happened after the cards would be drawn and then flipped I believe
There's no context that fetches cards before flipping?
I donât think so
I don't think setting_blind would work
What are you looking to do?
Oh hands_played_at_create exists
Prevent flip and debuff on first hand drawn cards
nvm that might not work with discards
You could always just unflip the cards if thereâs no way to tell stay flipped to not do it
Iâve not looked properly at the blind calc stuff tbh
Oh right since it occurs after the flip I can just do that đ
If I put a return { prevent_stay_flipped = true} in a context.first_hand_drawn check it won't persist right?
Not sure if the prevent is for current or any future cards, I need to test it
SMODS.recalc_flip when? 
I donât think itâll do anything in first hand drawn
Darn
Itâs a flag unique to stay flipped
You could set a flag on the joker in setting blind and remove it in first hand drawn
That should allow you to use stay flipped properly
True, good idea, ty đ
i think
Got it working, thanks again, never made such a joker with many context checks đ
Praise be to the context wizard
Maybe it's about time to make some functions for checking triggers step for contexts?
I need to finish the calc docs
That should have a complete ordering of contexts when itâs done
Maybe a debug function would help too
Like, ```
context.is_playing_card_scoring = function()
return context.individual and context.cardarea == G.play
end
-- or
SMODS.CTX.is_playing_card_scoring = function(context)
return context.individual and context.cardarea == G.play
end
I have something like that to prevent bp effects and retriggers đ
As a bonus, adding this checks can provide better types
Also SMODS.in_scoring exists
but that's more for utility than calculating purpose I guess
Iâm not sure I agree on the need for something like that
This also provides more opportunities for overriding, if some modder decide to add "disable all in hand triggers" or "trigger this things also when..." effect for own joker
Also, easier to adjust when main game updates will happen
This can be achieved easy by providing metatable with some getters for functions, and types for them
Is this enough arguments? 
Canât SMODS.can_calculate be used for most of those effects if we passed the context through to it?
Doing something like this would be a major breaking change if you wanted the functions to be hooked for other effects, and would require rewriting the entirety of vanilla calculate joker - main game updates would definitely not be easier to adjust for. It would be a huge undertaking and I canât see the community being willing to learn a load of other new checks to be required during calculation to allow for proper mod compatibility, when we already have the context system allowing very specific checks to be done and the option to patch/hook the various calculation functions to allow for âdo this thing when âŠâ effects
Hey, again, how does one save data only inside a given run.
i.e. the value doesn't get lost when restarting the game or exiting a run, but does get reset when the player starts a new run.
for a card, put it in card.ability otherwise G.GAME works too
-# how does G.GAME work, exactly?
It's a table initiated in the function Game:start_run that likes initialize all necessary value and acts as a save table
How would I go about making something float like The Soul does
I'm looking at the Vanilla Remade code and I'm not sure what specifically brings forth the specific texture
ye
o
thank u :3
How can I make a joker instantly polychrome when it appears in the shop or is added to the jokers table?
check set_ability in SMODS.Joker
Hey does anyone know how to prevent a joker from showing up in the shop? Or can someone tell me where the code is in the shop to prevent jokers from spawning?
check in_pool in SMODS.Joker
tyvm! :)
in_pool = function (self, args)
return false
end
``` so would this work?
i just dont want the joker to show up in shops that's it
no conditonal stuffs
when need a check the docs command
tru
that works but do you want the joker to still spawn for like judgement and stuff?
no
oh ok then that's fine
but that'd be a good thing to know actually
if you can tell me so i can write that down :p
i have written it before but i need to find it
but basically args.source in in_pool has the source of the spawning
how would one code this silly little idea I had
context.poker_hands contains the list of hands inside so you can check that for the 3oak and the pair probably
how would I do something after the hand is played, I am trying to make a joker instantly win the blind when meeting a certian condition
Hey question, where tf do used (i.e. scored, discarded) cards go?
G.discard
context.after
so I tried that however I still get the error message of "attempt to index field state [a number value]" at like 138
what's the context for ending antes
this is my little evil joker idea I am trying to make
setting the condition to high card just for testing at the moment
too much drawing for little ol me
just use a premade, and make the art from there
how do I add this side text?
info_queue
ty!
where would i find more information about info_queue?
Sorry if I'm being a lil annoying đ
oh wait i see now nvm!!!
i found it lol
Okay wait now how would I add the description of a specific Joker?
info_queue[#info_queue+1] = G.P_CENTERS.j_key
yes
sounds good
so real :3
whenever i hover over flesh prison this happens, can someone understand what I'm doing wrong? I'm guessing it's cause of the info queue.
Okay so it actually has nothing to do with the loc_vars????
I think it's something to do with your config?
instead of set make it key
(i also fixed the atlas typo already lol)
Nice
what context do i use if i want a joker to do stuff when its destroyed?
You don't, you use the remove_from_deck function.
dont know how i missed that
How does one make a new tab on the Run Info menu specifically to the right of Poker Hands?
and how do i make sure it doesnt happen when sold?
You would have to set a flag on context.selling_self
is it as easy as doing
if not from_debuff and not context.selling_self then
print'boom'
end
end```
?
No.
Are you just looking for the joker being destroyed?
yeah
Maybe it would be better to hook Card:remove() and make a context.
i've just added a new keyboard layout to typist, it's pretty trivial code-wise. if you have suggestions or ideas around an intuitive one handed layout you can send them in the mod's thread or in a github issue and i'll implement it. i also want to implement talonvoice commands that map to typist keypresses at some point to make the game accessible to that voice control users (but im not that good at using talon or writing code for it)
Talon enables you to write code, play games, and control your computer with voice, eye tracking, or noises.
â
i dont think i saw anyone respond to this so if i had to guess, you can check specifically for if its a boss at the end of the round
i think some jokers like rocket operate like this actually
time to open vanillaremade
if context.end_of_round and context.game_over == false and context.main_eval and G.GAME.blind.boss then
Or at least some mods that do similar for reference?
You need loc_vars
where do i need that
where to find vanilla remade?
guys do i make my balatro mod jokers unlocked and discovered by default or :3c, im planning to upload what i have to github rn and i don't want any bad surprises to happen when people actually download it
discovered = true and unlocked = true
In the joker definition.
Well yeah I know how to do that, i'm moreso asking if i should
I feel that's more of a https://discord.com/channels/1116389027176787968/1209506360987877408 question.
Fair enough
In your enhancement.
Also, move Xmult out of the extra and make it x_mult
ok
How do I balanced the base chips and mult?
Do return {balance = true}
tips on making my blind compatible with matador?
Use blind.triggered in calculate.
I think I messed up
You need to make a custom context.
Do you know how to lovely patch?
SMODS.Enhancement {
key = 'wooden',
loc_txt = {
name = 'Wooden Card',
text = {
"{X:mult,C:white}X#1#{} Mult",
},
atlas = 'gb_Enhancements',
pos = { x = 1, y = 0 },
config = { Xmult = 1.5 },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.Xmult } }
end
}
this is an abridged bit of code from my own mod. as you can see loc_vars is used to show values when you hover over the card, so that you could change Xmult (not x_mult) in the config and have that reflected across the rest of the code
đš no
This comma will need to be removed, as the return statement isn't part of a list
that too
when do you want the balance to happen?
but you never set a value in loc_vars (that's what config is for), it's only used to show values in descriptions
Whats this codes problem? when i play this enh nothing happens.
before any scoring happen, so its just base chips and mult being balanced, and only when playing flush/full house
For spotting simple syntax errors like this, I recommend installing the Lua extension for VSCode.
It's also generally helpful to include the line numbers in your screenshots, especially for syntax-based errors
ill do it later
You can just click the install button, it's very easy
i'm trying to do this blind effect:
The Lance - Cards discarded this Ante are drawn face-down
so i look at the pillar's code, and there's a card ability called played_this_ante. okay. i can't find where it's set, or where it changes, only when it resets (which looks as if it has an SMODS inject for resetting abilities like this) and when pillar checks if played_this_ante is true for debuffing. how would i do this effect?
It's set in G.FUNCS.play_cards_from_highlighted
Full code : SMODS.Enhancement {
key = "two",
atlas = "two2",
pos = {x = 0, y = 0},
replace_base_card = false,
no_suit = false,
no_rank = false,
always_scores = false,
loc_txt = {
name = "Double Card",
text = {
"After being played,",
"splits into {C:attention}two{} cards"
}
},
set_card_type_badge = function(self, card, badges)
badges[#badges+1] = create_badge("Double", G.C.ORANGE, G.C.WHITE, 1.2)
end,
calculate = function(self, card, context)
if context.after and context.card == card then
G.E_MANAGER:add_event(Event({
blocking = true,
func = function()
card:remove()
` for i = 1, 2 do`
`local new_card = create_card("Base", G.deck, nil, nil, nil, nil)`
` new_card:set_base(card.base)`
` new_card:add_to_deck()`
`new_card:start_materialize()`
` new_card:juice_up()`
`end`
` return true`
` end`
` }))`
`end`
`end`
}
context.card doesn't exist in context.after
Ok lemme try it
of course it was in the one place i didn't look. now that i've found it, it's also right below a function that does the same thing for discards. i've found a good place for a patch, but i don't know how to add a variable to card.ability and how to have it show up in reset_keys
â
does anyone know how i can get my mod to detect when mipmap levels are changed? manual sprite replacement w/SMODS.Atlas + raw_key works fine but the sprite changes are discarded when mipmap levels are changed, so i just need a pointer on how to detect that and trigger an event as soon as it happens
is there a mod/option to get any joker,etc so i can debug easily?
thank you
how could i go abt creating a blueprint-esque joker that was compatible with all jokers and effects (including copying upgrades and stuff)
https://github.com/nh6574/VanillaRemade/blob/713f51e2fa3744b385a83491057a3f60eb385601/src/jokers.lua#L3831
read from here
this is the vanillaremade version of the blueprint joker
isnt that just a regular blueprint tho
how do i make it compatible with all jokers
how do i put a key into this reset_keys function (card.lua) with this SMODS helper function?
im guessing from that code that you just return a list of keys
i'm not sure where the set_ability_reset_keys would even go
SMODS.current_mod.set_ability_reset_keys = function() return {"discarded_this_ante"} end?
https://github.com/ethangreen-dev/lovely-injector/releases/tag/v0.8.0 almost a full release, just need to fix the mac build CI. otherwise feel free to try it out.
â
thank you for your work
Anyone know how to fix this little misshap?
thanks to everyone who contributed to the release :-)
does it fix macos cross mod patches?
You require a custom context.
How do I check how much money the player has?
yep
đ„ł
and I think it should behave better when you restart the game
but that was a wilson feature so I don't know for sure
G.GAME.dollars
I did it by stealing the flint's code xd
Much obliged
im sorry to ask, but what "G" stands for? i see it commonly
Game
so game.game.dollars?
global
_G.G.GAME
what context would I use to do something after a specfic hand is played, not during scoring but afterwords
context.after?
have tried that, I am making a joker that wins the blind outright and I believe I am winning the blind during scoring which gives me an error
Code?
try
G.E_MANAGER:add_event(Event({
blocking = false,
func = function()
if G.STATE == G.STATES.SELECTING_HAND then
G.GAME.chips = G.GAME.blind.chips
G.STATE = G.STATES.HAND_PLAYED
G.STATE_COMPLETE = true
end_round()
return true
end
end
}))
idk what that formatting is
it works, thank you!
"if if ret then"?
after using this code with the psychic my game crashes when playing less than 5 cards
making an enhancement that scales every time a card of its type is scored, but its value resets if the game is closed in the middle of a run, and saves if you end the run and play a different game
is context.individual when the card is scored?
does it have a crashlog
â
Here, it only happens after pressing the cash out button oddly
wait
im stupid
ignore all this
It's when playing cards are scored yes.
I do still need help with this
You need to put it in config.
changed it to that, but when I play a flush for example, each card played in that flush gains 1 mult when I want EVERY card with that enhancement to gain 1 mult for each played card
Do you only want present ones to gain it or all ones that ever exist in that run?
all ones that ever exist
Change everything to self.config instead of card.ability
that works, thank you
ok thanks (sry for late ans)
What do I do so that before this is executed it checks if the destroyed joker is the right one?
only call the event if the condition is met?
I think I did it:
yea
How do I separate the three of a kind and pair from a full house, like do something that only effects one of them
if context.scoring_name == "Three of a Kind" or context.scoring_name == "Pair"?
is there any like page with a list of all the context thingies? I couldn't find any
thanks :3
How can i increase the rank of a card?
For example, 4 to ace?
SMODS.change_base(card, nil, "Ace")
Thanks
does balance = true work for things other than the plasma deck? (looking at vanillaremade rn)
yes, I have used it in a joker before
here is how I used it
It works for everything that uses calculate.
this correct?
No.
What's wrong?
How do I access the debug menu? It's time to thoroughly test my mod out now xP
SMODS.find_card would return a table of cards.
Press Tab
then how do I make it check for a specific joker?
Is it possible to create an Edition that blocks the effect of the Joker card?đ€
so debuffed?
right
if sliced_card.config.center.key == "j_modprefix_key"
I forgot to ask how exactly it is used đ
probably but what would the difference be with debuffed
that's reasonably simple to do nowadays
do you know if smth is wrong with this calculate function then (sticker code)
Thank you! I've been stomped on this for 2 hours
Try context.main_scoring
instead of context.individual?
Instead of everything between if and then
is this for a joker?
sticker, it works now
is there a SMODS.debuff_card()?
Yes.
it's in the utility docs
Thx, I was just looking for the descriptions of these functions.
am i able to do smth like context.other_card == (card and context.scoring_hand[1])?
No.
That would just check if it's the first scoring card.
intended check (sticker code) here is for if the card is the card with the sticker on it (which would be context.other_card == card) and if the card is also the first card in scoring hand (context.scoring_hand[1])
If you are using context.main_scoring it would be card == context.scoring_hand[1]?
this isnt for the same sticker but this does help a bit since i am using context.main_scoring on it
and since the context works now the copier code from dna actually works
I presume I have to enable debug mode for this to work, is that a command line thing or what
hold tab?
No, neither tab nor ctrl + tab work. Though from peaking through the thread for the mod, it seems there are some incompatibilities with Brainstorm, so I will remove that
EDIT: This was the answer.
<@&1133519078540185692>
Boom
The everyone ping is always so funny
How do i change the sprite of one of the jokers?
what ahppened?
hi, i made this code for an enhancement so the cards with it destroy themselves when the blind starts but its not working. What did i do wrong? lua calculate = function(self, card, context) if context.main_scoring and context.cardarea == G.play then return { chips = card:get_id() * 10 } end if context.setting_blind then SMODS.destroy_cards(card) end end}
Just the free steam giftcard thing that's been popping up everywhere
Hello chat good schmorning
How can i edit the sprites of balatro cards?
Are you talking about vanilla cards
Playing cards or jokers or similar?
The previous message said jokers
Vanilla, jokers preferably
i know (G.GAME.blind.boss) is used to detect boss blinds but how do i do to make it detect the Ante 8/Finisher Boss Blinds ?
Do you have deck calculations enabled?
G.GAME.blind.boss.showdown?
Oh okay, thanks
I'll look into it, thanks
i dont think i do, how do i enable it?
Theres some type of guide to start making mods for balatro?? For people that dont know shi, I tried and I didnt get what tf to do
thanks!
Oh yeah, curious, can you use the glasst trigger context to somehow prevent a glass card from breaking?
what would be the best way to get the previously played hand? do i need to hook calculate_context, to write that to G?
jokerforge sucks
what is the file name for the music when you are in-game
nvm
why is it slowed down though
A number of sounds/music in the game have altered pitches from the original files
You would use SMODS.Sound and select_music_track and do return G.STAGE == G.STAGES.MAIN_MENU I think.
ok
i made this in order to create a bunch of cards a custom suit but for some reason its sometimes creating cards of another suit, whats wrong? lua for i = 1,card.ability.extra.amount do G.E_MANAGER:add_event(Event({ func = function() local _rank = pseudorandom_element({"2","3","4","5","6","7","8","9","10","11","12","13","14"},pseudoseed("seed")) local _card = create_playing_card({ front = G.P_CARDS["G"..'_'.._rank], center = G.P_CENTERS.c_base}, G.deck, nil, nil, {G.C.SECONDARY_SET.Enhanced}) _card:set_ability(G.P_CENTERS["m_gold"], nil, true) return true end})) end
I don't think so because by that point they're already in the cards_destroyed table
hi dilly
darn
:D
Always looking for ways I can simplify stuff
Easy just take ownership it or patch it teehee
a prevent_remove return would be cool actually
(bump)
Try looking at Blue Seal
how much lua do i need to know in order to start making a simple mod
No I do take ownership, the issue with Glass cards specifically is because they have built in x_mult in their ability table. So the take ownrship is a lot more invasive because it has to remove that value
And probably may be funky with other mods
So yeah prevent_remove would be awesome tbh
Is that a new pr i smell
yaknow what fair nuff u were right last night bout context before
I could see a ton of issues with clarifying what specifically it's preventing though
Since if you have multiple remove effects at once it gets weird
Most prevent_X returns don't care about what's preventing
or all im just saying most because im not sure
so if you return prevent_debuff it always take priority over any debuffs
but what if I want to prevent all debuffs besides one debuff but give priority to no debuffs whilst giving a single debuff
Basically my use case is this card
aha, it already exists as G.GAME.last_hand_played :D cheers
would i need to know more lua, or understand the steamodded documentation better
Damn mfs always want spades
how would i change a card's suit to a club?
SMODS.change_base(card, "Clubs")
I'm trying to make my joker works on boss blinds and if the boss blind is a showdown/finisher boss blind, it would destroy itself, but apparently i get this error, not a 'nil' value for once, but it crashes my game when entering into a blind, some helps as always is welcome
key = "goldkey",
loc_txt= {
name = 'Gold Key',
text = { "{X:mult,C:white}x5{} when entering a Boss Blind"
},},
--atlas = 'key',
pos = { x = 0, y = 0 },
rarity = 3,
cost = 7,
pools = {["pseudoregamod"] = true},
unlocked = true,
discovered = false,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
config = { extra = {xmult = 5}},
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.xmult } }
end,
calculate = function(self, card, context)
if context.setting_blind and (G.GAME.blind.boss) and not (G.GAME.blind.boss.showdown) then
return {
message = "x".. card.ability.extra.xmult,
xmult = card.ability.extra.xmult
}
elseif context.setting_blind and (G.GAME.blind.boss.showdown) then
card:start_dissolve({G.C.RED})
return {
message = "Used !"
}
end
end
}```
boss is just true/false
you'd likely have to check if the ante is a multiple of 8 instead
unless there is some stat that shows if it is a showdown, but boss.showdown isn't a thing since boss is only true or false and not a table
im trying to make an edition that makes cards impossible to disable or destroy, does anyone have any idea of how id go about that?
G.GAME.blind.config.blind.boss.showdown?
ariral detected
also personally i would go with hooking whatever function handles trying to destroy a card, checking if it has that edition, and if it does then not running the original function
alright alright
For debuffs you can prob just return that prevent_debuffs
going to use it and see where it goes
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play and not context.other_card.debuff and pseudorandom("blue") <= G.GAME.probabilities.normal / 4 then
SMODS.change_base(card, "Clubs")
return {
message = "Converted!",
colour = G.C.CLUBS
}
end
its not working
it shows the message but like
It should be context.other_card not card
Curiosity if someone can help me figure this out. I have a card that's supposed to treat Steel Jacks as Glass Cards, but for some reason this also appears to treat any other cards regardless of enhancement as glass cards????
if context.other_card.config.center.key == 'm_steel' and context.other_card.base.value == 'Jack' then
sendDebugMessage('returning glass enhancement')
return {
['m_glass'] = true,
}
end
end```
is there a list of base game sounds anywhere
resources/sounds in the source game files?
........huh
It seems like there's a long string here where context.other_card consistently only refers to the jack card
???????????
How do you add custom negatives sprites for your jokers, itâs safe to say mine are not looking good at all.
You mean change what the joker looks like when it is negative?
Yes, mine are practically pure white xd
You'd have to overwrite the default negative shader
you could hook set_edition and change the sprite position when negative is applied/unapplied
this looks like something else is destroying the cards
Something about my overridden glass enhancement here is being fucky it seems
I'm trying to use the bottom element here to modify the top element, but I am not sure how to access and change the element's selected value. Any suggestions?
{
n = G.UIT.R,
config = {
align = "cm"
},
nodes = {
create_option_cycle({
label = "Ante",
scale = 0.8,
w = 4,
options = antes,
no_pips = true,
opt_callback = "change_search_ante",
colour = G.C.PURPLE,
current_option = Showman.config.SEEK.search_ante or 1
})
}
},
{
n = G.UIT.R,
config = {
align = "cm",
scale = 0.6
},
nodes = {
UIBox_button({
button = 'set_to_current_ante',
label = {"Set to Current Ante"},
colour = G.C.PURPLE
})
}
}
Currently the button function changes Showman.config.SEEK.search_ante which does change it, but it requires the user to back out of the menu and go back in for the change to be reflected.
I'll spam here that 0.8.0 is officially out https://github.com/ethangreen-dev/lovely-injector/releases/tag/v0.8.0
Youre super smart
how would you go about referencing multiple jokers with info_queue and not having duplicate tooltips display?
(ie. both referenced jokers also reference negative, making the negative tooltip display twice)
You would do info_queue[#info_queue + 1] = {key = "j_modprefix_key", set = "Joker"}
would this go on the base joker, the ones with the negative tooltip or both?
I just released the first release of my mod
details:
https://www.reddit.com/r/balatro/comments/1l5sfqg/the_reddit_bonanza_mod_has_been_releasedish/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button
mod link:
https://github.com/ItsGraphax/reddit-bonanza
would be happy if you guys check it out and leave feedback (both on the code and the balance) tysm
The base one.
also does this work with custom types?
Yes.
Do Jokers have a draw = function(self, card, layer) function or is that just consumables
just checking
Yes.
oki
this is vanilla code with my patch inserted in for readability, for some reason this isn't working
i also have this patch to reset it alongaside played_this_ante
i'm trying to get discarded_this_ante to keep track of which cards to debuff for a boss blind
what kind of not working?
and the patch is applying aok?
do you see the result of the patch in the dumps?
yeah
you can check in the dump folder
It's also possible the function is fully overwritten
no other mods loaded except debug_plus
yeah, another reason to check the dumps
where do i look for those
Mods/lovely/dump
How do I get rid of the The Soul sprite from some of my cards
Not sure why they're showing up; the soul_pos is set to other spots in my atlas
Show more of the code
this is the entire thing
you missed an end line 75
no problem
doesn't seem like it (should patch right after calculate_seal)
Does your object have an atlas? Show one of them's code
SMODS.Joker {
key = 'requiem_softAndWet',
config = {extra = {}},
rarity = "jojo_requiem",
cost = 50,
blueprint_compat = true,
atlas = "jokers",
pos = { x = 7, y = 5 },
soul_pos = { x = 8, y = 5 },
-- Imagine the rest of my code goes here
}
the first applies in discard_cards_from_highlighted, and the second in end_round
Oh yea because your atlas is the same as the vanilla one I think
Try it, it won't hurt you (maybe)
time to hope find and replace didn't hurt anything
yeah but is this from the dump or
didn't seem to work 
No, it adds a prefix automatically.
yeah
yeah so your patches aren't applying correctly
not sure why
verify that your patterns are accurate and your patches are in the right place
I was about to say "this didn't happen with my consumable" but I can't tell if it did or didn't because the soul sprite is too big to tell
isn't it functions/state_events
same code but straight replaced by five of a kind
why did it just..... explode
Five of a kind
Can you make mods for balatro on a steam deck
yep, it's just a compooter
i mean it works like a pc so i guess so
Oh cool
Well I guess what I'm really asking is can you make mods for balatro on linux
apparently this has something to do with the draw function
draw = function(self, card, layer)
if (layer == 'card' or layer == 'both') and card.sprite_facing == 'front' then
local scale_mod = 0.05 + 0.05 * math.sin(1.8 * G.TIMERS.REAL) + 0.07 * math.sin((G.TIMERS.REAL - math.floor(G.TIMERS.REAL)) * math.pi * 14) * (1 - (G.TIMERS.REAL - math.floor(G.TIMERS.REAL))) ^ 3
local rotate_mod = 0.1 * math.sin(1.219 * G.TIMERS.REAL) + 0.07 * math.sin((G.TIMERS.REAL) * math.pi * 5) * (1 - (G.TIMERS.REAL - math.floor(G.TIMERS.REAL))) ^ 2
G.shared_soul.role.draw_major = card
G.shared_soul:draw_shader('dissolve', 0, nil, nil, card.children.center, scale_mod, rotate_mod, nil,
0.1 + 0.03 * math.sin(1.8 * G.TIMERS.REAL), nil, 0.6)
G.shared_soul:draw_shader('dissolve', nil, nil, nil, card.children.center, scale_mod, rotate_mod)
end
end
Guessing it has to do with G.shared_soul, though I was under the impression that was just the specific soul sprite of the card in question
I was going for something to imitate how it moves
Do you mess with a drawstep or hooked/overrides a drawing function? What if you redo the atlas and joker alone in it's own standalone mod?
right, the line number changed.
G.shared_soul is specifically the floating sprite for the soul
The second sprite? You mean like Hologram's floating Jimbo?
Bump
well I have two sprite things on my cards
You can see both, there's the floating text and the normal text, the soul is sandwiched in between
the sprite the soul_pos variable uses
And you tried with the atlas key changed?
yep
doing a rewrite of a cryptid joker, any reason this displays as nil in the collection but is fine ingame?
Is possible the variable used only exists in game
is it like spelled wrong or something?
i'm not sure, it references the same variables as the original joker to my knowledge
maybe the vars return is nested in the same if condition as the main_end
Check if context.poker_hands exists before doing the next check
Does the banana do that?
nope
oh idk what cry_prob is
Hmm
i don't believe it's relevant, it
What are you spellchecking
Try and compare your stuff with other joker mods that uses soul sprite
what's the rest of the loc_vars
i don't know đ
seems pretty identical minus the draw function
it's exactly what i said
Oh your joker has a draw function? Can you show it?
#đ»ă»modding-dev message
Need to replace shared_soul with something
what should i do then?
Are you sure that's how 5 of a kind is referred to internally?
you can copy the same return outside the if removing the main_end part
Btw its "Five of a Kind", not "Five of a kind"
It's case-sensitive
oml
This is one of the bronze age programming errors, it happens to everyone
is the free codeacademy course on lua enough to start making mods?
i think i'm a tad lost
I would recommend the love2d wiki, there is an excellent tutorial by sheepolution linked there and some other ones as well
the original code looks roughly identical, except that main_end is much longer, which unless im mistaken is no longer needed in my code
ok
Love2d is the name of the framework balatro uses
ah
you're returning only when G.jokers exists, that's the problem
ohh
i see
so should i move the entire return statement outside the if statement?
or do i need something else
you can do that yes
That is a lot of indentation, is that normal for balatro code?
for UI code yes
yeah, this specific code is very bloated and outdated though, which is why i'm rewriting it
Oh cool
Hi, new to modding, how can I set the selected deck type and stake in code. eg set it to the blue deck at red stake
modding balatro cant be that hard
its hard enough to have a channel dedicated to questions abt it
Surely i can figure out how to make a joker
If it's taken me 3 days to code a joker and the card still doesn't actually do anything I think it's hard :,)
I mean yahiamice did it, you probably can too
I have zero code experience so idk abt that
from scratch it can be hard, especially if you don't look to other mods for reference
Go to the love2d wiki and look for tutorials
Sheepolution makes a great one
I've been eyeing up several other mods and I still don't know what's wrong lmao
i only have a month and a half or so of coding experience and ive accomplished things i never even dreamed of
I would say for a beginner love2d is a great way to start still
i would have probably quit early on if i tried starting with that tbh
Is there a spelling mistake in the code
as far as I see, no spelling mistakes but I could be completely missing it, the card exists in game no crashes at all, just when actually playing and testing it, it just doesn't do anything it's supposed to
Ah, well I personally learned a lot thanks to learning love2d but that's just my experience, I'll take your guy's word for it
How does the card function
Or, how is it meant to function
I'm back with another question 10 hours later:
The below code keeps crashing with the message psudoseed is a nil value but idk why as, by my understanding, it should just be grabbing a random number in the list then assigning enhancement said number
local enhancements = {
G.P_CENTERS.m_fm_resonant,
G.P_CENTERS.m_fm_dissected,
G.P_CENTERS.m_fm_finalized
}
local enhancement = enhancements[pseudorandom_element(#enhancements, psudoseed('balalala'))]
pseudoseed
yea typo
i cant believe i overlooked that
ik, its the length of the enhancements table
yes, pseudorandom_element takes tables
oh
you want
local enhancement = pseudorandom_element(enhancements, pseudoseed("seed"))
got it, ty!
Can't figure it out from looking at the base game code
Hey all, I'm trying to make my first Balatro mod and wanted to make a deck that makes Tarot cards free, but I'm not really sure how to run a function for cards in the shop.
Here's what I have so far, just based on the Steamodded example:
SMODS.Back{
name = "Vagabonded Deck",
key = "vagabonded",
pos = {x = 1, y = 3},
config = {only_one_rank = "4"},
loc_txt = {
name ="Vagabonded Deck",
text={
"Start with {C:money}$-20{} and",
"earn no {C:attention}Interest{}, but all",
"{C:tarot}Tarot{} cards and packs",
"are free."
},
},
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
for _, card in ipairs(G.playing_cards) do
assert(SMODS.change_base(card, nil, self.config.only_one_rank))
end
G.GAME.dollars = -20
G.GAME.interest_cap = 0
return true
end
}))
-- Can make cards couponed to make them free?
end
}
...probably would hook into create_card_for_shop and check against type of card...
does anyone know how to get rid of or hide the lovely window? it's really annoying and whenever i tab out of balatro it will cover my screen until i tab out again and minimize it
-# Just my random thought cents.
You can hook Card:set_cost, it's where Astronomer does its change
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
Thanks!
tbh my only issue with it is that if you restart the game it doesn't automatically close the old one
How do I change the seal texture in main.lua?
You mean the mod icon? Otherwise check the Malverk mod
Hi, first time modder, I'm trying to add the amount of consumables to a xmult joker, how do I reference the current amount of filled consumable slots?
#G.consumeables.cards
Keep in mind mods like Incantation and (more optimal imo) Overflow will "compress" cards into stacks under certain conditions.
okay sure, I'm mostly just doing this as a learning exercise so no biggie but good to know
đ
Or just don't care about them 
-# Also valid, lmao.
I am trying to implement an Edition called âBounty,â which disables the Joker's own effect, but the advantage is that it increases the bounty (i.e., the price at which the Joker is sold) by a large amount each round/ante (with an upper limit).
Regarding the disable effect, I called SMODS.debuff_card(), which worked. However, when modifying the sale price, I tried using card.sell_price = 10, but it did not work.đ
Yea I'd recommend incrementing card.ability.extra_value instead
(It's what "Egg" uses)
It seems to be saying that G.consumeables.cards is a table, so I can't use it for arithmetic, I assume theres some value within the table I should be referencing?
Don't forget the #
OH
# is the length function
thank you đ
lmao
Damn N so rude shouting at people 
Nâ could never
Can I be S' ?
yes
Ty
Too late
can i be Mâ
@cursive gazelle
Failed
Chicken sandwich
I CANT SEE
we love file compression
code so long you cant fit the whole thing in one image
<@&1133519078540185692>
<@&1133519078540185692> I
main_end shouldn't be a global
bye
mods seize him
What a pain!
wow y'all are on it lol
consider him seized
mods just obliterate this . thing
Why are you using local variable and not smods.joker
was it just a scam link? I missed it by like 1 sec
Yeah
because thats how cryptid does it
Are you re creating cryptid ?
no just rewriting one joker
Oh
because the old code was like 400 lines long
Oh youâre optimizing the code
Fuck i fell for the XY problem
I'm trying to change a card's enhancement to a random enhancement in the list i provided earlier, but it's crashing when i do set_ability(enhancement) even though ive set a card's enhancement before by putting one of the items in the list into where enhancement is. attempt to index local center (a nil value) is the error now
you're not passing a valid enhancement
What's your code
They're custom enhancements
I've got this joker that's meant to make the joker to the right eternal, however, when removing eternal from any jokers not to the right of this joker, it also removes eternal from jokers that were eternal before. Is there some way I could make it only remove eternal from cards that it made eternal?
calculate = function(self, card, context)
if G.jokers then
local other_joker = nil
local protected_joker = nil
for i = 2, #G.jokers.cards do
if G.jokers.cards[i-1].config.center.key == 'j_willatro_bodyguard' then
protected_joker = G.jokers.cards[i]
if protected_joker then
protected_joker:set_eternal(true)
end
end
if G.jokers.cards[i-1].config.center.key ~= 'j_willatro_bodyguard' then
if G.jokers.cards[i]:set_eternal() == true then
other_joker = G.jokers.cards[i]
if other_joker then
other_joker:set_eternal(nil)
end
end
if G.jokers.cards[1]:set_eternal() == true then
other_joker = G.jokers.cards[1]
if other_joker then
other_joker:set_eternal(nil)
end
end
end
if context.selling_card and context.card.config.center.key == 'j_willatro_bodyguard' then
G.jokers.cards[i]:set_eternal(nil)
end
end
end
end
the error means what you're passing to set_ability is not a valid option
dont you have to do some jank work around stuff regarding tracking destroyed jokers specifically?
if i recall correctly
yeah somewhat
hmm
oh, that's odd bc those same enhancements have been called earlier in the code
(also idk why the pictures are out of order, for that im sorry)
well that's not what i said
pseudorandom_element already returns the value, not the index
yeah not even sure where to start on that beyond tracking every single individual effect that can destroy a joker and that seems like a mod compat nightmare
so get rid of enhancements[ and ]?
tried that, still has the same error
pseudorandom_element returns 2 values so it's better saving it to a local beforehand
can you screenshot that part of the code again
I havent tested it after adding the local yet
N are you still using lovely 0.7.1?
Same error
Yeah idk if i have the patience to learn a whole language for a funny bit, kudos to anyone that has the mental capacity to do any of this
i updated lovely why
I need to see if a patch was missing before and I cba downgrading đ€Ł
I'll just check my logs from the other day
can u paste the error here
in fact, when you launch do any of the smods patches miss right now?
it doesnt seem like it
can you send it with aiko's mod disabled?
It'll take a second but yea
oh this PR steals a space from a patch target đ
oh if it's mine it might be the autoformatter lol
sometimes i forget to save without it
I did wonder why yours sometimes had random whitespace changes đ€Ł
I'll be more careful lol
Tbh more people should use it đ
I'll see if I can disable it for toml
doesn't work
only the mod causing it, debug, and jokerhub
F
no yeah i have no idea
how would one go about creating a specific card in your hand?
yeah this doesn't work for me either for some reason
tho I haven't tried in lovely 0.8
i took that image from metherul like a week ago so its not a 0.8 thing
didn't know it updated that's cool
although when using that launch option the window is renamed to "LOVE Console" instead of "lovely"
try printing out the enhancements in debugplus
man, N is cooking with all these PRs lately

pull requests
i miiiiggggghhhhhttttt have possibly maybe forgot to save and thats why it didnt work
something I've noticed now I'm actually testing them though, is it possible for the SMODS.add_card supporting playing cards to spawn a specific enhancement?
yes, using "Base" + enhancement
although that might a little jank
unless thats not working for some reason
yeah but might cause problems with setting an enhancement twice maybe
It's now applying the enhancements bc i remembered to save this time!
crashes again
The fuck-
(attempt to perform arithmetic on field 'chips' (a nil value))
hmmm yeah maybe, perhaps it should force "Base" if an enhancement is provided
i agree
it's not necessary but it's a pain to do later if you need it
and for some things it is needed
yes
Like what things
like if you want a card to change names and/or descriptions dynamically
odd random sudden question
if context.other_card:get_id() == 11 then
so if I wanted that to be for wild cards instead of Jacks
I've drawn blanks as to how to go about this so I'm begging for help
if SMODS.has_enhancement(context.other_card, 'm_wild') then
i was too slow..
đ thanks so much
Understandable

âs fault

