#💻・modding-dev
1 messages · Page 375 of 1
got that too
add your hand to the dictionary
how would i make two pairs be considered full houses?
with a hook
i found the problem
had to make a new save
Maybe hook evaluate hand?
i hate everything
if i had a jimbo plushie at this very moment i would hang him on my door
if (add_mult or 0) > 0 then?
Basil's issue was creating a new hand requires you to make a new save, or else it crashes.
Try looking at Sync Catalyst?
how the fuck do you solve this
balatro-kai is now shoving this in my face whenever i try to launch it
here's some ideas ive been doing for jokers
it is just uses mult 
always trim your mod folders of lovelyignores
im going insane
if context.destroy_card and context.cardarea == G.hand then
return {remove = true}
end
how do i make the uhh joker detect which card i want to destroy
i have a function that picks a random number from 1 to however many cards are in hand
is there a context for cards drawn after opening a booster pack?
context.open_booster doesn't seem to work
Don't return remove true if the card is the selected card.
Why do the cool joker effects take the longest to make
I spent like all day on one joker
whats with all this setup here just wrap any comparisons with to_big
as in to_big(1) < to_big(0) lmao
return = context.destroy_card == G.hand.cards[destroycard]?
Also context.destroy_card does not happen during joker main.
i've made a "mystery" enhancement that hides a card's suit and rank until it's drawn, and i've got it removing itself when drawn during a blind but it's still there when you open a tarot pack or spectral pack and i need this to not be the case.
is there an easy way to do this?
yahiamice saw my bluesky post so i have to stop procastinating on this (wait i'll fix that double message)
Try G.P_CENTERS.m_wild
nope
try nil instead of false
context.other_card:set_ability(G.P_CENTERS["m_wild"], nil, true)
smth like this
nope
Hey can i put to vanilla jokers pools?
for example cavendish, gross michel, etc in a food pool?
Take ownership of it then do pools = {["Food"] = true}?
Or you could just put the key in cards of the object type?
asking again what the issue here is
are you trying to return a concatonated string?
no idea
like "X" and then the chip value all as one strong?
what are you trying to return i should ask
this is how the joker code looks
im setting up operator scaling
just try putting shit in parentehses ngl
card.ability.chips
not card.ability.extra.chips
I don't really know how this shit works, but concatination might not be concatonating
or just this
yeah you ofc cannot concatenate a nil value :V
huh
they put a chips value in their extra table?
but they might not have used it
so do i have to move chips from extra to the root of the config?
I see card.ability.extra.chups existing
are you syre they just don't need parentheses?
i am not sure of anything 😭
I meant haya
tbh I don't blame you, I might be new to coding for mods, but this shit looks weird
yeah
like idek what this means
this is what the joker is intended to do
except nil should be 100
tbh I've coded 0 kokers, all my experience has been fucking with the graphics code
basically
which is... its own beast
chips scale
when it reaches X100, it increases the operator and resets to 1
so, it would become ^1
reach 100 again and it becomes ^^1
etc
I mean... this feels simplier to do with loc vars and just normal joker code, then all the weird concatination
i dont think i understand
like have the operated as a loc var in your description and switch it and reset using normal if statements?
"arrows" is the operator
I just mean you don't need to use the in-built lua formatting when the game has loc vars for that, and you can switch it in the logic with normall loops and if statements and whatnot. The arrows are like any other text i presume
unicode is unicode, just need to escape them or smth
or do the arrows not use unocde characters in the font?
it might be late or i might be stupid but i have no idea what you're trying to say 😭
same tho. i might be being stupid
sorry if this is the wrong place and sorry to interrupt your chat but im trying to add a new challenge and the game recognizes it but its locked. how do i make it unlocked
definitely the right chat
why does it still say nil?
lemme see the code again and actually try to make sense of it this time
its long so let me know if i need to zoom in the screenshot a bit
Because you're asking for #4# but you aren't providing it?
#4# is in config and loc_vars
also, happens when the operator is supposed to increase
ah i see
what could be causing this?
this is supposed to detect if the chips reach or go above 100, increase the operator, and reset it to 1
yeah that's my bad
talisman
which is required in this cazse i know
probably missing some to_big's
also is the 'message' how you send values to loc vars? As I said I'm new, sorry
@daring fern I just don't see themdefining it anywhere?
What "message"?
so I was wendering if it was in built
it's in her returns
what does this mean? i'm very new to modding balatro and lua as a whole
okay one more issue
it is giving mult instead of chips
for some inexplicable reason
OH
i know why
how do i generate a random joker while respecting their rarities
Does SMODS.add_card({set = "Joker"}) not do that by default?
i dont know, ill try that
i figured it out sorry for being dumb
hey yall,
i'm making an enhancement that's supposed to remove itself when the card is drawn to hand. i've got it working for drawing cards during a blind, but i'm not sure how to go about making it do the same thing when it's drawn for a tarot/spectral booster pack. the "open_booster" context seems to be useless
if G.booster_pack and not G.booster_pack.REMOVED and SMODS.OPENED_BOOSTER?
w here would that be applicable. in the context check function?
i can try that there, sure
It should be true while a booster pack is open.
oh is this for the erratic deck testing
github issues
mhh, I'll look into it, thank you
a txt file that you edit occasionally and says stuff like "check the thing that makes the jokers bad"
im new to modding and I'm looking through the example jokers mod on the steammodded github
what's the purpose for this?
text in the joker's description
ohhh ok
If you mean the #1# it references variables returned from an object's loc_vars function. For example here the #1# will be replaced by the value from card.ability.extra
{C:mult} changes the color of the text, #1# has it so the text in there changes dynamically depending on a variable's value
I'm trying to figure out what the whole "text = {" part is used for
Oh then yea it's for object descriptions
anyone knows the key of a gluttonous joker?
i think gluttonous is misspelled as "gluttenous"
cant remember if its gluttenous or gluttenous_joker though
Assuming you check for context.hand_drawn you can also check for context.other_drawn for when it’s in packs/any other addition that draws cards
Suit Joker
is that a thing? i didnt see that in docs for smods
gluttonous doesn't work, i'll try _joker
Yes it is a thing
hmm, well the other solution i got seems to be working for now but the thing im doing might break it, i'll consider that if i need to change it cuz that looks more stable
there it is, thanks
mhm!
do i use if context.other_consumeable then... to go through all held consumables for effects
just to be sure :p
yes
It works the same as how you'd use context.other_joker
icic, thanks
Question, you get a cards seal by doing card.seal, easy enough
Why is it to get the enhancment it's SMODS.get_enhancements()? 
hmm
Why did they add only quantum enhancements specifically?
idk, it was there when i first started modding lol
might need to ask the ogs around here :p
errr can anyone help me with some smod stuff
i want there to be a 1 in 3 chance to turn playing cards into bonus cards but im not really sure how the pseudorandom function works and i cant find any documentation on it
Why are you returning SMODS.calculate_effect?
idk
have been kind of frankenstying code from diff jokers togheter
to learn
Put everything in there directly in the return.
i was guessing calculate effect was the function blueprint would look for
okay
No, it doesn't look at anything, it just runs calculate.
what about the pseudorandomness though
should it work now?
nope
i might just be very super duper lucky but it hits on every card
nope set the pseudorandom to 100000 and it still hits every card
unless im like the luckiest person alive
pseudorandom first input needs to be a string
and the second is the max of the output number?
cause i've looked at the vanilla revamped code for 8 ball
and all it gives is a string
No, you need to just do pseudorandom(string)
so the chance is hardcoded to be a max of 4?
i mean like
oh my god im so stupid
thank youuu
wait but
aren't the odds what the oops all 6's changes
like the 1 in "1 in 3 chance"
That's G.GAME.probabilities.normal
oh okay
How do you detect the held cards?
G.hand.cards?
Yes, it's called SMODS.has_enhancement(card, "m_stone")
randomness still dosent work and im not really sure of what to do atp
No your return table is just wrong
The set ability shouldn’t be in it, message shouldn’t be in its own table
where should the set ability be then
Before the return
No
Have you read the calculation guide?
ah i see thanks :-)
what the-? I thought it's make it work.
someohw it's not detecting the cards if the cards haven't played and of course it's meant to convert stone cards to their original state.
Code?
SMODS.Joker{
key = 'stonebreaker',
loc_txt = {
['en-us'] = {
name = "Stonebreaker",
text = {
"Convert held Stone cards",
"into a random Enchancement"
}
}
},
atlas = 'Jokers',
pos = { x = 1, y = 0 },
config = {
extra = {
-- No additional properties required for now
}
},
rarity = 2,
cost = 4,
calculate = function(self, card, context)
if context.cardarea == G.hand then
for k, v in ipairs(context.other_card) do
if SMODS.has_enhancement(card, "m_stone") then
return {
m_stone = false
}
end
end
end
end
}
I had thought about trying to see if I can like make a custom card that I thought that is about unconverting the card into stone
Oh god where to start
You can’t use ipairs on a singular card
Returning an enhancement value as false does absolutely nothing
You’re checking if the joker is a stone card
Your context check isn’t tight enough
Actually a joker checks the held cards, and then converts stone cards to the ones with rank and suit.
if context.individual and context.cardarea == G.hand then
if SMODS.has_enhancement(context.other_card, "m_stone") then
context.other_card:set_ability(G.P_CENTERS.c_base)
end
end
No it doesn’t I’m telling you what your code does
Ah. Well the descriotion was temporary but I at first thought how I can like rephrase it
also
I need to try to see if
I can get the stone card to turn into a base card then try to reincoperate
like I need to know the variables of like each enchancement
or give a random enchancement
sorry if it sounds confusing.
I just told you how to do that?
turn held in hand stone cards into a random enhancement
which yeah is what somethingcom's code does
Ah. I see.
can confirm
Oh?
did know someone already did that.
but yeah.
let me test it out first.
No, it just removes the enhancement.
finally works !1! thanks everyone
i mean yes it just sets it to m_base but that can be changed easily
just pseudorandom the global list of enhancements and put it in
m_base?
Something I tried your code and apperently this happened:
it didn't actually get the hand deck to like turn the stone card into a playing card
not sure why if I did it right but this ia the code I had so far:
SMODS.Joker{
key = 'stonebreaker',
loc_txt = {
['en-us'] = {
name = "Stonebreaker",
text = {
"Convert held Stone cards",
"into a random Enchancement"
}
}
},
atlas = 'Jokers',
pos = { x = 1, y = 0 },
config = {
extra = {
-- No additional properties required for now
}
},
rarity = 2,
cost = 4,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.hand then
if SMODS.has_enhancement(context.other_card, "m_stone") then
context.other_card:set_ability(G.P_CENTERS.c_base)
end
end
end
}
also sorry for the confusions.
Cards in hand are not cards in play?
Try keeping them in your hand.
well yeah I tried even also when the blind started the joker didn't trigger
let me check
yup the removal did work just somehow it didn't trigger upon starting the round.
or starting the blind
but I have an idea
upon starting the round is a different context
card:set_ability(G.P_CENTERS[poll_enhancement()])
ah.
well I got an error but now I'm wondering how can I randomize the enhancement?
this is what poll_enhancement does
it's polling the list of enhancement
s
alright but right now it crashed:
It's SMODS.poll_enhancement
Also you need to do SMODS.poll_enhancement({guaranteed = true})
is it possible to still call shatter/destroy stuff despite blocking destroy through a patch?
Give it conditions.
wdym?
i basically did a destroyed = nil patch if my joker is there
in addition to a hook
Yes, give it more conditions.
wdym by conditions?
tryna make a custom card skin, would this work?
if joker and conditions
but adding conditions will just disable the destruction preventing no?
No?
im not sure to follow; my issue is that cards that are shattered when played but prevented to be destroyed dont call caino stacking, adding conditions to the destroy = nil will just disable the destruction prevention? or am i getting it wrong?
im not sure to get the logic
You want jokers that get called from cards being destroyed to still work when its not being destroyed?
yes, and it is
except for shattered glass
this is the only exception for now and i have no clue why
for now, if i hanged man 2 cards, it prevents their destruction and still calls caino for example
does anyone know why this doesnt work?
but if i play a 6 with 6th sense and pareidolia or if i play shattering glass cards, wont call
its like my patch stops the call at all and my hook doesnt
i honestly have no idea what i need to do with these 2
setting pos_style to collab makes it assume your atlas only contains face cards, i believe
oh
been a while since i made a deckskin but i think thats how it works
yeah mb
so would this work?
--- STEAMODDED HEADER
--- MOD_NAME: Fancy Suits
--- MOD_ID: fancysuits
--- MOD_AUTHOR: [CebeeDrawz]
--- MOD_DESCRIPTION: Y e s
--- PREFIX: fancysuits
SMODS.Atlas {
key = 'FancySuits',
path = 'FancySuits_lc.png',
px = 71,
py = 95
}
SMODS.DeckSkin{
key = "DeckSkin_lc",
suit = "Hearts", --???
loc_txt = "default",
palettes = {
ranks = "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King",
display_ranks = "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King",
atlas = FancySuits,
pos_style = 'suit', --???
},
colour = "f03464",
}
aand what do i put here?
thats still correct i think
(and it also still crashes)
ah
hm?
idk whats going on there
oh the pallette needs a key
try just lc?
welp..
--- STEAMODDED HEADER
--- MOD_NAME: Fancy Suits
--- MOD_ID: fancysuits
--- MOD_AUTHOR: [CebeeDrawz]
--- MOD_DESCRIPTION: Y e s
--- PREFIX: fancysuits
SMODS.Atlas {
key = 'FancySuits',
path = 'FancySuits_lc.png',
px = 71,
py = 95
}
SMODS.DeckSkin{
key = 'DeckSkin',
suit = 'Hearts',
loc_txt = 'default',
palettes = {
key = 'lc',
ranks = '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King',
display_ranks = 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King',
atlas = 'FancySuits',
pos_style = 'deck',
},
colour = 'f03464',
}
https://github.com/nh6574/VanillaRemade/blob/d0e99fb83af5765f200adf2ffeb01ea732e60e6b/src/jokers.lua#L1351 New to modding, is it okay if I just copy the copying playing card function from this code and put it into my mod?
Contribute to nh6574/VanillaRemade development by creating an account on GitHub.
I wanna make sure I don't somehow end up pissing people off that way
let me find my code and see if i can spot any differences
It should be fine.
Okie, cool
might be something with the palette, but cant find what
try taking the numbres out of quotes
its having an issue with "3" somewhere
the ranks?
yes
how do i get the cards in hand?
G.hand.cards
thanks
yes and for display_ranks too
its interpreting
ranks = '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King',
as
ranks = '2',
'3',
'4',
'5',
...
if that makes sense. it thinks 3 is a key without a value
ohh
unless theres any inner lua workings i dont know about that makes this fine. but i cant imagine so
oh ok
theres an api method for destroy_card() but for some reason its a nil value
and put the colour in a HEX('...') maybe
idk if it changes anyting but its in my code
so worth a shot
*delete_card(=)
no those arent numbers
No? Those are for object types?
ah okay i thought it was like the object class in general
also if you want every single rank to be shown on the skin select menu (that's what display_ranks is for btw) then display_ranks should be identical to ranks
whats the method to destroy cards then
--- STEAMODDED HEADER
--- MOD_NAME: Fancy Suits
--- MOD_ID: fancysuits
--- MOD_AUTHOR: [CebeeDrawz]
--- MOD_DESCRIPTION: Y e s
--- PREFIX: fancysuits
SMODS.Atlas {
key = 'FancySuits',
path = 'FancySuits_lc.png',
px = 71,
py = 95
}
SMODS.DeckSkin{
key = 'DeckSkin',
suit = 'Hearts',
loc_txt = 'default',
palettes = {
key = 'lc',
ranks = {
2,
3,
4,
5,
6,
7,
8,
9,
10,
'Jack',
'Queen',
'King'
},
display_ranks = {
2,
3,
4,
5,
6,
7,
8,
9,
10,
'Jack',
'Queen',
'King'
},
atlas = 'FancySuits',
pos_style = 'deck',
colour = ('f03464'),
suit_icon = {
atlas = 'FancySuits',
pos = 0
}
},
}
so like this?
they still dont show up
is a suit icon neccesary?
I personally use fire (I can't remember the actual method)
i use a chainsaw
ok heres my full code for one of my deckskins knock your socks off
SMODS.DeckSkin {
key = "mlp_spades",
suit = "Spades",
palettes = {
{
key = 'lc',
ranks = {2,3,4,5,6,7,8,9,10,"Jack","Queen","King","Ace"},
display_ranks = {"King","Queen","Jack"},
atlas = "mlpgim_mlp_suits_atlas",
pos_style = "deck",
colour = HEX("3C4368"),
suit_icon = {
atlas = "mlpgim_base_suit_icon_atlas",
pos = 0
}
},
{
key = 'lc_con',
ranks = {2,3,4,5,6,7,8,9,10,"Jack","Queen","King","Ace"},
display_ranks = {"King","Queen","Jack"},
atlas = "mlpgim_mlp_suits_2_atlas",
pos_style = "deck",
colour = HEX("3C4368"),
suit_icon = {
atlas = "mlpgim_base_suit_icon_atlas",
pos = 0
}
}
},
loc_txt = "My Little Pony"
}
like on sixth sense it just returns remove = true but what if i wanted to remove all cards in hand
hm?
colour needs to be HEX('f03464') not just ('f03464')
wait yeah what filetype is this??
yeah if you put swift after code in discord it color codes it
oh
and every large programming language
I ended up with this. What do you guys think?
i mean it does it by default for me
.lua
ok
so its not a swift file
good
lol
you arent
you arent prefixing your atlas id
hm?
'FancySuits' and fancysuits
so in the atlas argument for the deckskin you should be putting 'fancysuits_FancySuits'
maybe the message "break" should appear once on the joker
what does your code look like now
--- STEAMODDED HEADER
--- MOD_NAME: Fancy Suits
--- MOD_ID: fancysuits
--- MOD_AUTHOR: [CebeeDrawz]
--- MOD_DESCRIPTION: Y e s
--- PREFIX: fancysuits
SMODS.Atlas {
key = 'FancySuits',
path = 'FancySuits_lc.png',
px = 71,
py = 95
}
SMODS.DeckSkin{
key = 'DeckSkin',
suit = 'Spades',
loc_txt = 'default',
palettes = {
key = 'lc',
ranks = {
2,
3,
4,
5,
6,
7,
8,
9,
10,
'Jack',
'Queen',
'King'
},
display_ranks = {
2,
3,
4,
5,
6,
7,
8,
9,
10,
'Jack',
'Queen',
'King'
},
atlas = 'fancysuits_FancySuits',
pos_style = 'deck',
colour = ('f03464'),
suit_icon = {
atlas = 'fancysuits_FancySuits',
pos = 0
}
},
}
Ah.
I'll try that and see
This might be a dumb question but doesn't malverk have an easier method of implementing skins or did I misunderstand what that mod is for
No.
try wrapping everything in palletes in a second table
idfk
im copying this into my own code to compare them side by side
same
how do i destroy cards?
wait it works 🔥
lets goo
Does it not work for playing cards then? I don't know exactly what malverk can change which is why I was asking
only for spades tho, should i copy this for every suit?
yes
It doesn't.
can it only display 3 cards at a time?
dunno, should display every card you put in display_ranks but im not entirely sure ont hat
yeah it crashed when i tried but i just needed to put 'rank' instead of just rank
strangely it does only show up for the ace tho
i think
i can help you no further
fair
how come removing the tag ui element moves the dark background to be behind the 'or' instead of the skip button?
hang on i think i got it
its an issue with a different part of code
found it
👍
i fixed it but at what cost. it looks kinda uggy now
ive removed the background again bbut that bug was indicative of a slightly larger issue thats fixed now
how could i add compatability for the bunco suits?
Removing the reason to skip? What for?
in rascal the reason for skipping can be to avoid getting ganged up on by a full room of black suit face cards
(rascal is a different game entirely wearing a balatro shaped trenchcoat)
I see
Malverk doesn’t handle suit skins because thunk released the in game version whilst I was still making it and I didn’t feel like it was worth overwriting that method, especially as people had made progress in making thunks system accessible
which joker gave chips based on how many cards you got in your deck?
Yes, I've been using chatgpt for the ffmpeg part of this, well strmm originally wrote it, but Istring replacement and filter workflows and a million different flags spread acrorss a novel-length manpage hurt my head, so I happily let the dumb computer whi thinks it can think hand;e that part when I thought it could do with tweaking, lol.
lol, how dare I even mention generative ai
the ffmpeg manpage is pretty scary
but nice work :-)
idk as long as you're honest about it's usage then it's fine. it's a big spectrum in terms of what's ok and what's less ok.
I've used chatgpt to make regex queries haha
it's not amazing at it but it gives me enough to expand upon
how would i add a high contrast mode for my deck?
so I feel like using it to set ffmpeg flags is not an outrageous thing to do
yeah, it tends to be good at string processing to an extent, like it never messed up the lua string format stuff here
which was already in place by strmnn
tried just duplicating the code but that adds a new deck skin lol
nvm i think i know
To make it clear, the actual mod code wasn't touched by ai, besides me asking it some troybleshooting quesgtions as I wrote
it doesn't understand balatro and i do
lmdao
I spent hours combing through every file in the source, the dumps, and thew smods source
days even
yeah, that's pretty appropriate
it's not something that I would ever personally do but like, it's not a crime or anything
it's not like you're creating AI slop
AI is a reasonably useful programming tool
@next timber the spectrum exists and we as an industry need to figure out our relationship with it, unfortunately.
I rarely ever use genai both because it sucks the fun out of my work and because my wife is a creative impacted by it, but it's here to stay.
Oh I see
Ty for explaining that for me
Also I didn't realise that you made that too
just say LLM or something to ward off the weird ai slop people
somehow this works
i don't know why
Yeah, you definitely shouldn't rely on it to fully write its own balatro mod but for smaller things like troubleshooting and that, it's fine imo
I know I was late but here's how it is so far.
I wish that genai died an expensive death but it's here to stay
sucks but whatever
Yeah that's similar to what I do
If smth isn't working or I need to learn smth I go through ChatGPT first in case there's an easy solution because I don't want to ask in this discord and waste people's time
I always learn from what I'm given tho to reduce the amount I have to go back to smth like ChatGPT in the future
yeah. as a natural language search engine it's pretty great, but don't rely on it any more than to inform you of options. It's terrible at technicals.
But it also should never be a crutch for your ability to formulate research.
yeah, it's also about what's worth learning, for me, it's not so much that I desire to learn how to use ffmpeg properly, especially with 2 different types of string substitution at play
i think movement should be sine based i think
I just wanted to edit the already made ffmpeg commands to do what I wanted
Yeah it's not a ridiculous use case
the linear mouse movement looks better than if it accelerates
anyone know how i can check how many playing cards i got in my deck?
i think it looks a bit stiff
I do know that
I use it sparingly as I'd rather learn it properly, but it's good for when I need an ultra specific solution
Like I had to override pseudorandom and pull the arguments from the function calling it, the documentation fried my brain so I had ChatGPT mockup part of it and explain it in depth to me
Then I wrote everything else myself
It would've been a lot more work just for one joker and for code that I'll probably never have to use again
Yeah
is there a context for when a planet card is used?
I mean I feel like that's reasonable
The issue is when you have people generating entire blocks of code with it, not questioning the output, not learning anything, and then hammering this forum for help when it breaks.
hmm... lemme see
oh wai
Mhm exactly
I wanted to learn how it worked so I could do everything else myself
nevermind i forgot constellation exis
I’ve used ChatGPT to figure out how something in a library worked because I knew it was possible but I couldn’t find an example of someone doing it
After I had the example I could replicate it but I was also able to find a reference (the book explaining the library by the people who made it)
I’m not sure the book had an explicit example for what I wanted, but it was a good reference for other stuff
when calling next(SMODS.find_card('j_prefix_joker)) in another joker's calculate, can i change j_prefix_joker's c.a.e? if so, how?
c.a.e?
card.ability.extra
You can change any table any time anywhere in Lua
let's try this
but how do i call the prefix_joker's abilities?
What do you mean
like is it other_card? context.other_joker? or some thing of the sort?
like for example if i wanted to get its position
SMODS.find_card returns you a list of all cards it found
so this just checks if there is one, w/o further info?
Basically it checks if the table is not empty
does anyone know how i can check for how many cards i got in my deck?
mh okay, sadge
Why
#G.playing_cards ?
but how do i mention it?
What do you mean
how do i call its position for example
How do you call a card’s position?
Save the table of cards and then access them
Oh you don’t want the position of the card
You want the index in the CardArea that corresponds to it
i think? for example, it is not the case but, if i had a joker that made that "oops all 6 instead triple probabilities"
But if you need the index specifically then you need to manually iterate, yes
But do you need the index
Or do you need the card
What are you using the index for
got a bad interaction with a joker and want to manually hard code it, it's a card destruction prevention that sometimes does sometimes doesn't proc caino (doesnt proc when cards destroyed are played ones) so wanted to manually call 'when this joker's context's called, increase caino's stuff'
You’re just not destroying cards correctly then
If you want to make Canio proc, you need to manually pass the destroyed cards to a calculation context
yes probably but i'm not good enough to improve it by myself so im doing what i can
@tall wharf yeah I'll definitely say that's a bit more natural looking
the pause actually makes sense when it's a sin wave, lol
Which shader is that last one
I had a similar one but it wasn’t as shiny
goldrare from ficklefox
can u try with noire shader
what is that from?
my mod
oh yeah I'll just have to dl it real qucik
here
trying to make it so it gives +5 mult for every card in your deck but not sure how to do it lmao
because ithis isn't set up atm to jsut be a shader viewer i'mma need to actually install the mod and have it export based on the edition. There is an edition assicated with it, right?
you could just do your mult * #G.playing_cards i think?
no need for a for
and the return in the for stops it i think?
yes
it's literally called noire so
so probably
if context.joker_main then
return{
mult = card.ability.extra.Plusmult * #G.playing_cards
}
end
and i think instead of mod_mult it would be just mult
Yeah mod_mult isn’t a thing
just to give you an idea of how this thing is currently used, Though strmnn is rewriting the interface and outputted website entirely
@tall wharf
yeah that works thank you
in case, i've re-used jen's almanac's stuff of diplopia (only for playing cards) as a hook, and did an additional patch (jen's stuff does make caino proc but stopped the game from working (not crash) when breaking cards played (like glass or sixth sense), and the patch was to prevent the game stop working but doesnt proc caino on the cards that it fixes)
looks like the right-bottom one of jimbo's neck bobules is glitching out
how can i change the mod icon?
Fwiw, smods will be provided a util function to destroy cards at any point that won’t be jank and broken
oh that happens in game too
so it's not an error in my reproducing the drawing routines
yay
wdym? (the patch is in the util)
As in, wait a day or so and use the smods function rather than whatever jank you’re currently doing
nice
and yes, I did indeed have to ewrite Card:draw and Sprite:draw_self from scratch
ahhh didn't read the will,, thank you, love yall
shader jank 😭
well I mostly used smods version of Card:draw and copied it all anyway with some tweaks, but it took me a long time to figure out how to do that
it means a value is going out of bounds i think. something should be bounded that isn't
oh actualloy it's normal? it just looks off
I think it's a low res thing tbh
yeah 😭
not enough pixels
though ngl I am glad cards are actually rendered, including shader at 71x95
because then the exporter works as expected, lol
or maybe they aren't?
either way it's fine
how do i scale the card like photo or half joker?
just realized i'm missing all the reflections
do you have another shader on top?
@tall wharf
unfortunately I don't think that type of thing can be auto-detected, so it's a limitation of the current approach
unless you added it an an smods.drawstep, then i can probably just drop it in
if it's set up right
does anybody know if its possible to cancel out chicots effect?
like with another joker?
You mean reenable the Blind or prevent Chicot from activating?
The Joker pictured seems unrelated to your question
well this joker would just be made irrelevant if you had chicot, thats why i want to know if its possible to make this joker negate chicot, and keep all boss blinds active
I mean, I think that’s how it should work
This Jokers gives Blinds Boss Blind abilities
Chicot disables Boss Blind abilities
That’s called synergy
you could hook Blind:disable
but yeah i agree with victin, chicot is a legendary for a reason
if you say so...
Because it’s boring
i'll give that a try
exactly
Also it wouldn’t undo the disability
it would prevent it
Undoing the disability is between hard to impossible IMO
Maybe you could set the Blind again, but it’s hard to tell if there would be secondary consequences
🇳🤝🐴
finding Chicot boring
i made some boss negation cards because of the yugioh negate thing and they make the game so boring
i am going to make aiko-like boss blinds to compensate
bump
i found some way, but it doesn't work the way i want it
I made Stheno
It turns all Bosses into The Rock (except Showdown Boss Blinds)
So it’s Chicotn’t
chican't
Do you know Mônica’s Gang
no
oh, damn
thanks
YGO-like design (derogatory)
are there any guides or anything on getting to grips with balatro modding
not many, check the thread pinned in #⚙・modding-general
thanks
How do you bind functions to events that don't have a built in smods context?
I see a lot about hooks but i can't for the life of me find the documentation on how to use them and looking at some example code didn't help either (I promise i tried man)
it's for tracking money earned and lost, but I'll go look at that tutorial first
how do i make jokers in another file in items folder?
something like this probably
local ease_dollars_ref = ease_dollars
function ease_dollars(mod)
ease_dollars_ref(mod)
SMODS.calculate_context{money_changed = mod}
end
surely theres no mod that would alter money by directly changing money instead of using ease_dollars
i mean there probably is
How does one make an enhancement that is just the base enhancement but with an edition on it?
😭
i think you can just replicate both effects in an enhancement and use draw to draw the shader
Good schmorning chat
good afternoon dilly
How is the bepis
the bepis is not
how can i check if scored hands has 5 cards
#context.scoring_hand returns how many cards there are in the scoring hand, i think
don't do context.scoring_hand without a proper context alongside it
lemme try
then waht do i use
always use one of the ones that say if context... not the ones between the {} as the main context check
https://github.com/Steamodded/smods/wiki/Calculate-Functions
like this?
yes
pog
turned out
this doesnt remove all the cards inside it, a
what approach should i go with to remove both the cardarea and all the objects inside it
if you remove a cardarea it should remove all the cards
weird
i had the opposite problem actually where i didnt want it to do that
i get a lot of lag after spamming the inventory button to open and close it rapidly
and the lag seems to increase faster when there r more cards in the delete areas
so im p sure its from the cards not deleting properly
🤔
How are you creating the cards
:3
-# this code was taken from how joyousspring created cards in their mod introduction btw
You need to remove the old back sprite
card.children.back:remove()
I think that should solve it
this worked, tks :3
oh
Doing it there does nothing 😂
No, the remove on the area will clean up the cards properly, the problem is that when you create the card it has a back sprite by default and when you overwrite it it doesn’t get deleted, it just stays in memory
mm so do i put card.children.back:remove() here instead?
underneath the emplace line
wait nvm
underneath local card, right?
how can i make one of these and add it to my joker? since this jokers idea is from a friend
<@&1133519078540185692>
smite him
So many 
thanks egg
Oh THAT'S WHAT THAT WAS FOR
can you send link to that i cant find it
Hey if I click the ban I send the mote
I stopped balatro modding for a while
ah lol
I got exams and scripting commission's to do
I CLICKED THE BUTTON
mm i see i see
while ur gone i managed to make 2 semi-complete mods :p
Gg
I would still prob roam balatro mods related servers to occasionally bring out unofficial hot fixes for bugs I encountered or the bugs sm1 else encountered
oh thats actually really cool
how do i code a changing description of a joker, like popcorn,
erm
I think you would need to add the changing value to config
localize takes a key from a localization file
remove the localize call or add it to a localization file
If you need to just display the "Idea: Boyaka", omit the localize, ye.
Then add "{#1}" (Pls correct me) to description
Oh damn
its #1#
Oh aight
MOD FIGHT MOD FIGHT MOD FIGHT! 🍿
we went from humans watching chickens fight to chickens watching humans fight
what do i have to change to change the selectable amount on the vanilla tarot cards this is setting the number but then i can still only select the normal amount
card.ability.max_highlighted = card.ability.max_highlighted + card.ability.extra.cards
What if we combine Humans and Chickens
:3
you want to change card.ability.consumeable.max_highlighted
card.ability.max_highlighted is only used for loc_vars im p sure
-# i know because my mod changes tarots' max highlight too, its dumb
epic
Also I didn't respond earlier, but thank you this worked perfectly
How can I lock a jokers position until the round ends then it randomizes it's position then it locks again repeat
G.GAME.round_resets.reroll_cost = G.GAME.round_resets.reroll_cost - (amount u need to subtract)
yeah, similar to how Negative works
alr then that line of code should work
when it gets out of the hand uhh i think you would add instead
got a crash, this is the current iteration of this edition's code
ahh, right
is there a place I should report that? or?
yeah it's me
lol, okey, haha
is there a list ingamer for all suits/modded suits
Help, why is it saying nil
text = { --description text. each line is a new line, try to keep to 5 lines.
"When a card is {C:mult}destroyed{}",
"Add the card back to your deck with {C:chips}+#1#{} Chips and {C:mult}+#3#{} Mult",
"and grow this joker by {C:chips}+#2#{} Chips and {C:mult}+#4#{} Mult",
"{C:inactive}(Currently {C:chips}+#1#{C:inactive} Chips and {C:mult}+#3#{C:inactive} Mult)"
},
config = { extra = { chips = 0, chip_mod = 20, mult = 0, mult_mod = 5} },
what does your loc_vars look like?
New to modding, I dont actually see it
loc_def = function(self) --defines variables to use in the UI. you can use #1# for example to show the chips variable
return {self.ability.extra.chips, self.ability.extra.chip_mod}
end
This?
would it be self.ability.extra.mult, self.ability.extra.mult_mod?
yep thats it
ok, so, the thing is, is the #1# and #2# and so on, are actually refrencing this bit here, not the config vars, so you'd want to add the mult and mult_mod in here as well
ty ty
np!
Also is the wording alright? It feels a bit wordy
fun fact here, only learned this recently (as I myself am kinda new to modding too), you can actually put numbers other than config vars in here, that's how jokers that work with chance are able to display oops all sixes effects and such
neat
hmm, a little bit, yeah, though, I'm not entirely sure how I'd fix it, wording descriptions is the thing I'm worst at I think, lol, lmao
loc_def?
defense sob
is there a better way than this
Is there a way to make my Joker increment xyz per skipped blind? I was able to make it trigger on blind skipped, but not for each blind skipped in the run, like Throwback
i want to update the blind hud but this call is very unoptimized and lags the game like shit
Are you asking what that is or are you telling me the location
where did you get it from
Boilerplate code from sample jokers mod
Is this a more consise version?
can you link it please
Uhh
one sec
Welcome to the Balatro Modding 101 tutorial.
In this beginner-friendly guide, I'll walk you through the steps to get started with modding in Balatro. Whether you're looking to install mods created by others or dive into making your very first mod, I've got you covered!
Links!:
https://github.com/Steamodded/smods - Steamodded
https://github.com...
In the description of this video @wintry solar
oh is that a new modding tutorial
oh my god please do not use that
that code is literally over 12 months out of date
hm lol, what do you suggest I use
this and N's vanilla jokers
and then the general smods wiki
Anyone know how to make something like imgui w/ mods?
I really do reccomend vanilla remade, it's awesome, you can see how each base game joker (and more) are made
https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua
also also
if self.debuff then return nil end --if joker is debuffed return nil
if context.destroy_card then
if not context.blueprint then
self.ability.extra.chips = self.ability.extra.chips + self.ability.extra.chip_mod
return {
extra = {focus = self, message = localize('k_upgrade_ex')},
card = self,
colour = G.C.CHIPS
}
end
end
I want the joker to upgrade itself when a card is destroyed, but it doesnt do that
It actually just upgrades itself like 5 timeswhen a card is played
save to G.GAME
oh woops
wait i didjt reply
accidentally deleted it
thx
i suggest following another tutorial
a lot of things here are wrong/outdated
Okay, what tutorial do you suggest?
https://youtu.be/Zp-4U5TlbxY?si=rKWR8jAvFSrnVnD3 still outdated but not as that one i suppose
STEAMODDED 1.0.0
A tutorial on how to make a modded Joker.
https://github.com/art-muncher/Example-Mod -- EXAMPLE MOD
https://github.com/Steamopollys/Steamodded -- STEAMODDED
https://github.com/WilsontheWolf/DebugPlus -- DEBUGPLUS
-----------------------------------------------------...
-# change every "center" you see in that video to "card" btw
Even still, Im looking for the specific, heres the code for the trading card:
-- Trading Card
SMODS.Joker {
key = "trading",
blueprint_compat = false,
rarity = 2,
cost = 6,
pos = { x = 9, y = 14 },
config = { extra = { dollars = 3 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars } }
end,
calculate = function(self, card, context)
if context.first_hand_drawn then
local eval = function() return G.GAME.current_round.discards_used == 0 and not G.RESET_JIGGLES end
juice_card_until(card, eval, true)
end
if context.discard and not context.blueprint and
G.GAME.current_round.discards_used <= 0 and #context.full_hand == 1 then
return {
dollars = card.ability.extra.dollars,
remove = true
}
end
end
}
But it just checks for discards and gives the money
there is a context.destroy_card but im not sre how its used
Oh I know I can look at the legendary joker
Canio
yeah, id suggest checking there
context.remove_playing_card apparently is the right context
I wonder what destroy_card is for then
yess it works
it's for destroying cards
@manic rune You wouldnt know how to get the data of the destroyed card would you?
if context.remove_playing_cards and not context.blueprint then
local face_cards = 0
for _, removed_card in ipairs(context.removed) do
if removed_card:is_face() then face_cards = face_cards + 1 end
end
I found this in canio but it just checks if the card is a face card or not
context.removed is a table of all the destroyed cards
use for loop to go through it and do stuff in there
okay
How do you make a UI mod? Looking for preferrably something that can be moved around like a window.
for _, removed_card in ipairs(context.removed) do
if removed_card:is_() then found = true end
if found then break;
end
``` what would I put in is_x()?
hello it's me again
does the game track jokers obtained this run? if not how do you do that?
well, more like this
local found = 0
local card_id = 0;
for i, removed_card in ipairs(context.removed) do
if removed_card:is_() then found = true card_id = i end
if found then break;
end
what actually are G.TILE_W and G.TILE_H?
ok actually more important question, how do you hide the card count/limit of a cardarea?
why does this not reduce with removed/sold?
i'm trying to add a extra choice to booster packs
remove_from_deck not remove_to_deck
facepalm
Okay so I got this far
axolotl_joker = {
name = "Axolotl Joker",
text = {
"When a card is {C:mult}destroyed{},",
"Return it to the deck with {C:chips}+#1#{} Chips, {C:mult}+#3#{} Mult.",
"This Joker gains {C:chips}+#2#{} Chips, {C:mult}+#4#{} Mult.",
"{C:inactive}(Currently {C:chips}+#1#{C:inactive}, {C:mult}+#3#{C:inactive})"
},
config = { extra = { chips = 0, chip_mod = 20, mult = 0, mult_mod = 5 } },
pos = { x = 0, y = 0 },
rarity = 3,
cost = 8,
blueprint_compat = false,
eternal_compat = true,
unlocked = true,
discovered = true,
calculate = function(self, context)
if self.debuff then return nil end
if context.remove_playing_cards and context.removed then
for _, removed_card in ipairs(context.removed) do
local card_clone = copy_card(removed_card, nil, nil, G.playing_card or 1)
if card_clone then
card_clone:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
-- Axolotl Joker upgrades itself
self.ability.extra.chips = self.ability.extra.chips + self.ability.extra.chip_mod
self.ability.extra.mult = self.ability.extra.mult + self.ability.extra.mult_mod
shakecard(self)
return {
message = localize('k_upgrade_ex'),
colour = G.C.CHIPS,
card = self
}
end
end
end
if context.joker_main and context.cardarea == G.jokers then
return {
chips = self.ability.extra.chips,
mult = self.ability.extra.mult,
colour = G.C.CHIPS
}
end
end,
loc_def = function(self)
return {
self.ability.extra.chips,
self.ability.extra.chip_mod,
self.ability.extra.mult,
self.ability.extra.mult_mod
}
end
But when I destroy a card it kida
Stays on the screen
I can drag it around
but I cant play it
Whats going on?
What's the goal?
Add the card back into the deck when a card is destroyed
Mmm there might be a helper function I'm forgetting, I know how to do it with vanilla code. Gimme a sec
Yeah I don't think there's a better way to do what you're doing. After you copy the card you need to emplace it into a cardarea. Do you want it drawn to hand or put into the discard pile or put directly into the deck?
Actually the answer to that probably depends on where it's destroyed huh
Like during a blind vs in the shop
Well you'll need to context check probably
Unfortunately, the game's UI system is a retained mode GUI. If by IMGUI you actually mean a floating dialogue like you might find in a game using Dear IMGUI, look here
But regardless choose the cardarea you want the card to go (G.hand, G.deck, etc) and call :emplace() passing in the card
(this is from memory, I am on mobile)
It would also be possible to make an immediate mode wrapper around the game's UI but I don't wanna be the person to do that
copy_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, copy_card)
G.hand:emplace(copy_card)
copy_card.states.visible = nil
Like this? (Copied directly from DNA Code)
Actually y'know what, go into the utils.lua file and check out the SMODS.add_card function
It calls SMODS.create_card and then does like two lines of code, those two lines are what you need to do
Nope that crashes
-# If you are making playing cards, SMODS.create_card is not what is needed.
does anyone know how tags remove the blind select screen when booster packs are opened?
No but the two lines after the create_card call should do what they need to get it into a cardarea properly. They're able to create the playing card already
(though maybe there's a better way overall)
right now i have this (should open a pack when the shop after the boss blind is exited)
calculate = function(self,card,context)
if context.end_of_round and G.GAME.blind.boss then
card.ability.extra.active = true
elseif context.ending_shop and card.ability.extra.active then
local booster = SMODS.create_card({set = "Booster", key = "p_para_foodpack"})
G.FUNCS.use_card({ config = { ref_table = booster } })
end
end
but the blind select goes over the cards in the pack
two random questions
- what's the
cardareafor the unscoring part of the played hand? - what's the
#contextfor the number of scoring/unscoring cards?
how do you destroy a random card in hand with a joker?
ive gotten the game to detect which card im talking about but im not sure how to destroy it
- there's no area, but context.cardarea is literally the string
"unscored"in that case - #context.scoring_hand for scoring. For unscoring you need to calculate it yourself with context.scoring_hand and context.full_hand
SMODS.in_scoring is a helper function for that if you need the specific cards, else you can do a simple subtraction
So after learning how the emplace code works
All I had to do was
card_clone:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
G.hand:emplace(card_clone)
And it worked
thanks, don't need the specific cards b/c that's not what the joker is looking for but the rest helps
what?? the fuck??????
hello it's me again
does the game track jokers obtained this run? if not how do you do that?
the game does track that, not sure how tho
looking @ cryptid source code, it tracks sold jokers this run
thats specifically for the cryptid necromancer afaik
wouldn't be in base steammodded
oh ok
does anyone know how tags remove the blind select screen when booster packs are opened?
let me see if i can find how do they do that
so that i can maybe try to do it myself?
small followup question would number 1 be expressed as
context.cardarea == 'unscored'?
actually wait i cant use that
i need to test if
if context.destroy_card and cardarea == 'unscored' then would work
yes
context.cardarea but yes it should
i know this sounds stupid but how do i have a joker only appear when cryptid is installed
i thought the destroy card context wasnt allowed to have any other context in the if statement
no, you actually want to have an area check with destroy_card
does anyone know how tags remove the blind select screen when booster packs are opened?
found the thing i'm looking for, but idk how does this work and i got a few questions
there's card:sell_card() in the source code. does this override or append to the code there?
will it work the same if i write this in my mod's main.lua ?
at the end of this function, it calls sell_card_stuff(self), what does it do here?
jokers_sold is initted earlier in the file
(SMODS.Mods["Cryptid"] or {}).can_load should return true if and only if cryptid is installed
G.GAME.hands["Full House"].played would give me the amount of times full house was played the whole run right
doesnt Cryptid have a function at the start of its main file that sets Cryptid to true?
this is a hook, it basically appends the functionality
sell_card_stuff is the reference to the original function, you need to call it so it does all the vanilla stuff
i think so
because if this is the case you could probably just put the joker inside some kind of if statement where
if Cryptid then
Do anyone know?
cryptid is so big that I actually wouldn't trust that no other mod accidentally creates a Cryptid table
Gah i wish the wiki told you about this kinda stuff
it does. check context.destroy_card
how would i open a booster pack at the end of the shop without the blind select screen going over it?
in my case, the vanilla card_added is add_to_deck (?) so i'll do ```lua
local vanilla_add_to_deck = Card.add_to_deck
function Card:add_to_deck()
-- tracking code idk
vanilla_add_to_deck(self)
end
maybe not the right solution, but give yourself a booster tag on shop exit?
this is a custom booster pack though
so i'd need to make a tag for that
does the booster pack get summoned by a joker upon leaving the shop?
maybe it will come in handy later
yes
does your code to summon the booster pack in the first place work with a different context?
Where
in the wiki with all the other contexts?
just tried skipping_booster and that didn't work
Is there another wiki besides the smods one or am i just dumb and didnt see it
no, it's in calculate functions
calculate = function(self,card,context)
if context.end_of_round and G.GAME.blind.boss then
card.ability.extra.active = true
elseif context.ending_shop and card.ability.extra.active then
local booster = SMODS.create_card({set = "Booster", key = "p_para_foodpack"})
G.FUNCS.use_card({ config = { ref_table = booster } })
card.ability.extra.active = false
end
end
Oh i did not see that mb
seriously wtf is this
hmm
do you know any other mods that create booster packs in the blinds menu (like with tags)?
only cryptid
and cryptid is a mess
yeah i looked through the github for those tags and it doesnt even look like it makes booster packs
like it makes the menu and everything show up manually
just looked through #1209506514763522108
apparently fortnite balatro has booster tags so im going to look through their code
what a landmark find
what is the property of a card that states if it's a joker?
update: fortnite balatro looks to be programmed the same way as cryptid (badly)
card.ability.set == "Joker"
how do i make this target consumables (so it's compatible with something like code cards in cryptid)?
context.card.ability.consumeable iirc
does anyone know a mod other than cryptid or fortnite balatro that has a booster pack tag?
you can search on the modded wiki maybe
How can I lock a jokers position until the round ends then it randomizes it's position then it locks again repeat
newest smods update should let this work now
nice, i don't know what this means and i don't know what caused it :/
you might be accessing pool instead of card.ability.extra.pool
i'm not using pool
balatro rhythm heaven save me
idk
this doesn't seem to be a modded error?
i've played with these mods before and it hasn't crashed on startup
this usually means that you're using a wrong key for card creation or something like that
anyone know?
apparently it was bunco (forgot to uninstall it)
i know cryptid has a sticker that locks position, maybe try looking there?
that being said cryptid is coded horribly
i'm not very good at this :( what does this mean
how do people transfer sprites from aseprite so easily
ooooo yippee! :33
sorry, didn't mean to make that an @ lol
if it doesn't, please let me know
does anyone know how i could make a joker that opens a booster pack at the end of the shop (after boss blind is defeated)
currently i just have
config = {extra = {active = false}},
calculate = function(self,card,context)
if context.end_of_round and G.GAME.blind.boss then
card.ability.extra.active = true
elseif context.ending_shop and card.ability.extra.active then
local booster = SMODS.create_card({set = "Booster", key = "p_para_foodpack"})
G.FUNCS.use_card({ config = { ref_table = booster } })
card.ability.extra.active = false
end
end
but when the pack opens the blind select screen goes over it
maybe make a tag for the booster pack instead
steammodded documentation is wholly unhelpful on doing that and i've never made a tag