#💻・modding-dev
1 messages · Page 324 of 1
Wikipedia just says an index is a key in an associative array. I don't think CS keys have their own page, although in mathematics there are pages for indexed sets and stuff
how are yall so fast at that
which makes me wonder, if you have a table with indexes 1-8 being normal, and you nil 5, does that relocate 6/7/8 to the hashmap or what
i don't know how that works
people ask about it all the time and we use this as reference all the time
well I just had the page open 😭
it's handy
i mean yeah that also complies with what I said that they imply order lol
ipairs stops when there are breaks AFAIK
not really in either CS or mathematics
ipairs iirc starts at 1 and stops if theres a gap
they just need to identify another member of the pair
ya im aware but it probably only operates on the array section
wait this was just there 😭
Wikipedia doesn't say anything about order, and I know it's true for mathematics
also if you have the lua language engine in your ide and you point it towards the smods folder the contexts have autocomplete
so like, ipairs might loosely not follow the convention there
labyrinth ass wiki
its all there but god knows im not getting there myself
every day I become more like sam
sam reich jumpscare
well it's on the sidebar 😭
Wikipedia also says this in the Associative Array page
its called calculate functions not list of context functions 😭
yeah thats a dictionary
well calculate is pretty much the only time you're using context anyway
yeah I was about to say that
but I agree, the wording is a little confusing at first glance
Dictionary indices don't require order
the great lua table debate of 2025
as someone who doesnt know what calculate is. its a lottle confusing at most of the other glances as well
its not very beginner friendly 
tbf it did take me some time to come to grips with how balatros code works
I do wish the example mods covered a few more jokers
There's a page to get started that explains what calculate is
but looking through the examples cleared up a bunch
nvm i forgot luajit code is unreadable ill never know
like sixth sense/trading card and pareidolia
or smth like golden joker
oh wait golden's in there nvm
im pretty sure it- yeah
i would imagine that relocating at worst case an entire array into a hashmap is slow so he doesn't do that but meh
another nice one would be steel joker, to show better ways to display numbers that can change at any time
i don't think a gap in the array is a big deal
now that i think about it those exist anyways
actually this so much
i have a problem with numbers on my card lagging behind sometimes
(psa: just do it in the loc_vars function)
cuz it's not updating frequently enough
what the heck are you people doing @_@
teleporting 6 months into the future to when i know all this and fixing the documentation myself 
use the Blind context
it's run every time you hover over the joker
just make sure you check that whatever you're counting isn't nil first
context setting blind?
i want to do it for a joker
no
well it's hard to "fix the docs" because there's not really a specified level of information that needs to be there, as of yet
all you can really do is add the info people ask for
true
like I'd like a lot more information on localization stuff
im just moody cause im confused 
i get it
context.stay_flipped
then
ah
wait it's dave strider
I'm fine with making more guides and stuff but please don't tutorialize the docs I'd like things to be easy to find lol
It's called GitHub /s
huh 😭
clicking on your site and seeing "boyfriend named john" was extremely funny
whose site?
arizonas
can anyone diagnose the issue here? my tarot doesnt do anything upon use
ITS CRAZY RIGHT
its case sensitive so you need to do use and not Use
does anyone know how to retrigger cards in areas that aren't the played hand
I need to retrigger a card in a custom area
I mean, if context.repetitions is called there
did you register that custom area with a patch?
if so then it should be sent to repetitions
yeah
nothing's happening tho
lemme send the actual code
is this for playing cards or joker-like stuff
That's Joker evaluation not playing cards
yeah it's not a playing card
joker-like, I suppose? technically it's a consumable card
the one on the right
Jokers can't retrigger in vanilla, but maybe if you enable Joker retriggers it should work?
is that a friends vs friends mod 
banger?
indeed
it would be more banger if I could figure this out 😭
now I need to figure out how to turn on the joker retrigger thing
curse you, docs
looking at https://github.com/Steamodded/smods/wiki/Calculate-Functions it does not seem to mention context.scoring_hand
scoring_hand isn't available all the time, so it's under all the contexts where it is
.
all you really need is scoring_hand =
it's not a "main context" is more like a field inside the context table
i do think the way that's structured is confusing, but I think it's being rewritten
cause im looking at #💻・modding-dev message trying to derive what im meant to be doing for myself and. it uses a context.scoring_hand
and alledgedly does what its meant to just fine
the way that you read this is
if context.joker_main then -- if this condition is true
---then the context table contains this information
context = {
cardarea = G.jokers,
full_hand = G.play.cards,
scoring_hand = scoring_hand,
scoring_name = text,
poker_hands = poker_hands,
joker_main = true,
}
ookay
then for for index, _card in ipairs(context.scoring_hand) do, context.scoring_hand refers to a table of card keys and the ipairs is iterating through it
is there a reason to use context.scoring_hand and not just scoring_hand
not card keys but card objects
scoring_hand doesn't exist as a global variable (as far as i know)
nope it does not
if you go to the source code, you can perform Ctrl + Shift + F and search scoring_hand =
that will give you an idea how that is being calculated & used
mostly the install is intimidating 
I usually disable as much as I can
then install whatever is necessary whenever it is necessary
but uh state_events.lua
🫡
i think what im gonna do is scour through #💻・modding-dev message and comment it to hell until i know how it works
They wouldn't be alone in using N++ for developing stuff. 😛
all my python gets written in n++
whenever i read n++ i think of the hit platforming game for the nintendo ds
same
if im making a joker that does something like: "if played hand is a straight, all face cards held in hand give +10 mult", would the best context to trigger the face cards be context.individual? Idk why but my head is having a hard time wrapping around this one
the ds game i mean, if i had to program in notepad++ i would die
shouldn't it be held in hand context if you want held in hand effect?
oh
I guess it is
context.individual and context.cardarea == G.hand
Thats what i figured, does that only trigger before scoring?
My very few small cracks at modding have been done in my Linux distro's default text editor, xed (a fork of gedit) which I think is a step below n++ in pretty much every way
What distro do you use?
Linux Mint
can someone help me import some textures we've drawn into my balatro modpack, I have no idea how to do it even though its simple mb
Cool!
I've never used it but I've heard nice things
It's like Ubuntu but without Canonical's nonsense
the game crashes when i use joker and it says attempt to call table value. the error is on line 56 idk whats wrong
It's literally built on Ubuntu
im yet to find a reason to switch from windows 🙂↕️
you got the answer in the other channel
didnt work
yeah
well thats the problem
The vast availability of .deb packages and things like ppas make Ubuntu and to a lesser extent Debian based distros the obvious choice to me, even compared to other 'it just works' distros
can you post the crash log
when youre asking for help its generally a good idea to give as much information as possible
It really shouldn't be
Also do you ever put anything in seen_ranks before you try using pairs anyway
I'm probably smart enough to f with arch but I don't hate myself enough
Just found out Seals don't have an in_pool function. Day ruined
(Or at the very least it isn't documented if it exists)
Either t o fuck or fuck w i t h is a banned string, weird
what would be the code to make a specific joker spawn as often as a common whilst being another rarity?
Technically it wouldn't matter, but still
It's just not documented. Day saved 
I used to use EndeavourOS, which is arch-based, but without a lot of the headache
We love undocumented functions
The pairs thing reminded me of when I was writing a nested loop and my teacher wanted me to use i twice instead of i and j
???
me trying not to be egocentric:
lmao
bump
there was a double space before "do"
i hope you get an answer to this someday
bump... 👉 👈
Rq, can I have y'alls thoughts on a joker idea I had for my mod?
id love to hear!!
The winning hand of a blind upgrades the ranks of all scored cards
hmm i like that, but considering you cant choose a minimal amount of cards to upgrade it could be a risk to pick up
bump
So it's good?
personally id make it something more like it only changes the two most left cards but that could work yeah
yeah sure
When you play any hand, the lowest ranked scored card ranks up
How's the idea?
i like that more yeah
sure
All played hands get the Jelly enhancement, the Jelly enhancement causes played cards to retrigger once for every joker, there is only a limited number of cards this joker can affect before it destroys itself though
How is the joker idea? As well as the enhancement idea
@sturdy compass COSPLAY JOKER WORKS I PATCHED IT THANK YOU SO MUCH
Yahoo!
and YES it stacks with smeared
Enjoy your free flushes and total destruction during suit bosses lol
the trollker
How is this idea?
Yo mr white someone’s at the door
eremel told me they would look into it, so i am still waiting on them, but i don't understand why i'm the only one experiencing this - this literally just happens when i'm adding to the info_queue of certain enhancements. i can't be the only person that wants to do or has run into this 
i have seen stuff like that asked before but i dont know if they got an answer
why the FUCK doesnt this work
i purposefully dont touch vanilla stuff in my mod so idk the answer
it just like doesnt change the fucking function
shouldnt most of those be ret:method() not ccr:method()
is it printing the over here part?
yes
then your file is cursed im sorry
yea that makes sense
even when i run the create_card manually it still doesnt work 😭
try create_card = function(yadda yadda) instead
How is this joker and enhancement idea also?
Same as the other person?
yeah 5x red seal for multiple cards is more cryptid level
NOPE!!!!!
is any of your mods overriding create_card maybe??
i am going to commit war crimes
cryptid!! !!!!!!!
i love cryptid
stank
Any other ideas for what to make the enhancement do?
I still wanna keep the theme of having more jokers makes it stronger
i forgot cryptid just says fuck you and rewrites the entirety of create_card
how's your generate_ui looking
What about Xchips equivilant to how many jokers you have?
info_queue works by recursively calling generate_card_ui and adding it to the info table of the full_UI_table
Does Xchips work in base balatro?
no
yo you play grace rifght
but with smods it does
yea
It does with SMODS now
damn
you know what slugfish is right
Do I need talisman for it?
nope
hhhhhhhhhhhhh bro the art looks so shit but i dont know how to draw slugfish
if you don't have a check for desc_nodes checking for full_UI_table.main then its always gonna go to the description
what do You think of This>>>>
gimmick is cool
do you mean ranks 3 and 5
art is eh
does this have any benefit or is it just limiting you for no gain
Then how do I do Xchips?
xchips = value
no i mean if the length of the played hand is 3 or 5 cards
deckfixing
deck thinning
also maybe do if hand has an odd amount of cards
when i had it on, it looked like this.
but my first port of call is a lovely patch i have that appends to info_queue in the vanilla generate_card_ui() based on conditions
and each time, without fail, with the exception of stone cards, for enhancements, it merges the tooltip info into the description
and somehow work in greater than 1 card
How's this version of the enhancement also?
actually no
it's +0.1x chips per joker btw
i feel like its a pretty Good joker
for this and when i tried in loc_vars, it did the tooltip correctly, but it broke the normal description
the mechanic Even symbolizes what slugfish does in grace
because gold card's description expects a var for its dollar value that it gets from generate_card_ui(), and you can't feed it in via a take_ownership() so it breaks
maybe use the peer pressure badge for reference in terms of art
i tried to use the note as a reference
Where do I learn to code lovely lua? Preferably free…
but the note is so weird
so i looked for fanart
and tried to use that as a reference
but eremel says i should be able to just append to info_queue via lovely patch
which is and has always been my first method
which is what results in the tooltip merging when i do it for enhancements other than stone 
so i don't know what's going wrong
have you tried putting the info_queue insert before you call SMODS.Center.generate_ui
i don't see how it could have fixed it, but i tried and it is as i said,
same result. the tooltip is added correctly, but as i said is what happens when i do this, the var in the description is broken
it just works
actually i think i know the problem
SMODS.Enhancement has its own override for generate_ui
maybe call that instead of SMODS.Centers.generate_ui
question is there something like SMODS.poll_seal for editions?
no change
poll_edition (no SMODS)
thanks
How do I make it so the game detects the cards with the lowest rank?
getting an error
pretty sure you can just go into the game's source and find Raised Fist for that
Idk how
open Balatro.exe with 7Zip
why does this code (modified so it always trigges and always produces chicot, shown in screenshot) lead to the first egg not flipping back properly?
do I need to copy the exe?
There are two open archive options
first one
K, thx
Thx
ur welcome
I mean it's recommended to copy it to have a backup
But you can probably just redownload it from Steam
I found and copied the code for Raised Fist's ability
bump? please this is like the last thing before i can post an alpha
maybe do the second flip in another G.E_MANAGER?
you mean, seperate to the set_ability?
how do i make a joker trigger after scoring? to, for example, delete a playing card
didnt work
looking closer it looks like it's actually flipping 3 times??
maybe try to print something to track how often it's flipping
well, the extent of my knowledge end here
bump
Same
how do I make a joker that effects base chips like same timing as the flint?
i'd say context.before but i think that triggers before the hand gets calculated
how do I make it so a card activates when ANYTHING is bought, not just a card
yeah this is the issue
fhat only works for cards
i want it to be when anything is bought
like vouchers or booster packs
safe bet is to go into the game source and look at the flint
already have, blind contexts work differently than joker contexts from what I can tell
unless I can use those some how
what context does the flint use?
hi, uh... how do i make a texture pack? (for jokers specifically if that means anything)
it doesn't even really use contexts, tbh I don't even really get it
it's just not the same format as how jokers work
.
isnt that what they wanted tho?
i put prints in all the events and theyre printing the expected amount of times
or am I misunderstanding
whenever I modify chips during context.before, whenever any new chips are added it goes to what it would be otherwise
aaaah
mult works fine from what I can tell
I think I've tried but I'll try again to show what happens
sometimes it just doesn't like recognizing that chips have changed without that
so worth a shot
no return chips = 0
like this
inside of the before context
if context.before then
-- other stuff here
return {
chips = 0
}
end
for example
but don't just copy that
yeah ok
is there a way to make emplace() happen instantly instead of having tweening?
like G.play:emplace(_card)
Ngl I am so confused with what I am doing with this joker
I don't know why this worked but tysm
localthunk
the Joker ranks up the lowest ranked scored card after you play a hand
I have no idea what I am doing with this one
bump
Check for buying cards, boosters, and vouchers? Pretty sure that's all you can buy
HOW??????
and no context.buying_card doesnt work because that only applies to cards not boosters or vouchers
It does apply to vouchers
for boosters it's context.open_booster
Is there a way to separate boosters purchased from those from tags and whatnot?
I presume they'd wanna
Could maybe check for G.STATE == G.STATES.SHOP
who is a modding pro?
please don't do this
why are you telling us 😭
They just do this man 
creates a voucher tag if last hand contains a 5. How am I going to make this into code?
That shouldn't be too hard if you have any experience
when you use a comsumable from an arcana pack, what position does it get moved to? like, usually it gets moved to play, but from an arcana pack it gets moved down lower since cards are in the way
Considering they've gone through most of the alphabet I'd hope so
or even just using a consumable while in an arcana pack
actually easier question
is there a way to make the hand displayed while in a pack opening screen disappear temporarily?
Sharing the thing I was trying to do yesterday and failed miserably (but this time, it's done and I'm proud of it)
It's an enhancement that copies rank, suit and enhancement of the card on its left
that fucking rhythm heaven megamix alien i hate
xDDD
cool tho
How do I make make tags?
Hope it's OP enough to change your mind :>
look at the source code
please 🙏
learn from already existing content rather than immediately going to us for help
what's a badge mean in code?
It has been hell to make work honestly
that is not at all related to tags those are the things the rarities of jokers show up on
these
@iron haven think of any already exsisting vanilla joker that does what you are looking for (creating tags in this case)
Diet Cola.
yes!
now look at it's code in card.lau
lua
(source code is dumped into mods/lovely/dump fyi)
card.lua?
the source code file
oh
found here
oh yes. NOTHING.
I really hate being harsh like this but we've told you we cannot handhold you for the entire development cycle of a mod. You've gotta learn how to do things yourself man
oh that's the text file.
play_sound('generic1', 0.9 + math.random()*0.1, 0.8) play_sound('holo1', 1.2 + math.random()*0.1, 0.4) what's this?
no way bro 
please use some basic observation skills and read what you sent
what do you think play_sound could possibly do
whats the key that diet cola uses
Can someone please help me with this? I am confused
what does that even mean
I am trying to figure out how to make a joker, I am quite confused
ah I see
The lowest ranked card in the hand you played ranks up
how do you want to handle multiple of the same rank?
hey gang is there a mod that does the thing where there's like a button to discover all
in the config i mean
They all rank up
just use the normal discover all button
ok in that case I'd say look at how raised fist checks for the lowest rank and then apply strengths code to all of the cards of that rank
bump
I looked at it earlier and am quite confused
I feel so bad for not being able to help every time you bump this 
in profile
I've added tooltips to my modded Enhancement without issues, so idk
NTF's have some complicated mumbo jumbo to 'em that I barely understand
yes, but i'm just trying to add a tooltip to a vanilla enhancement. and so far it's been straightforward for literally only stone
stone you can just append to the info_queue in generate_card_ui() and it works as you'd expect
everything else has so far been an uphill battle and i'm left hanging with gold because either i do it that way and it merges the text into the description, or i try taking ownership and it breaks the var
Uhhhhhh
Might have already been suggested but I know Pokermon has like a thousand infoboxes, surely there's something there right...?
for vanilla items?
back
yea thats it
I feel so confused
Yeah nevermind, my bad
Trying to think about a mod that would add to vanilla infoboxes
ok now I have a logic error for V.
It doesn't spawn the tag when last hand contains a 5.
we can't know what the issue is if you don't show the code
also we arent gonna hold your hand throughout the entire development of your mod
that is the entirety of your code we did not need that
only the one jokers snippet
Well the code for SMODS does generate_card_ui for each item in the info_queue so at this point I'm not sure
for _, v in ipairs(info_queue) do
generate_card_ui(v, full_UI_table)
end
Can I see how you add to the info queue?
SMODS.Joker{
key = 'victor',
loc_txt = {
name = 'V',
text = {
"Creates a {C:attention}Voucher Tag{} if last hand contains a {C:attention}5{}."
}
},
atlas = "Jokers",
pos = {x = 5, y = 2},
config = { extra = {
}
},
unlocked = true,
discovered = true,
rarity = 2,
cost = 7,
loc_vars = function(self, info_queue, card)
calculate = function(self, card, context)
if context.final_scoring_step and G.GAME.current_round.hands_left == 0 and ( context.cardarea == G.play and context.other_card:get_id() == 5 ) then
add_tag(Tag('tag_voucher'))
play_sound('generic1', 0.9 + math.random()*0.1, 0.8)
play_sound('holo1', 1.2 + math.random()*0.1, 0.4)
return true
end
end
end
}
why is that one part of the if in parenthesis
also final scoring step doesnt have a other_card i think
really?
I guess it doesn't. So how do I fix that?
figure it out
youve gone through more than half the alphabet surely you can figure stuff out on your own 😭
I don't know...
if context.final_scoring_step and G.GAME.current_round.hands_left == 0 and context.cardarea == G.play and context.other_card:get_id() == 5 then
``` Has to be about this line?
you're going to want to loop through G.play.cards and check if any of them equal 5
final scoring step doesn't have an other_card because that refers to contexts where cards are evaluated individually (like context.individual, context.repetitions, etc)
YEAH I NEVER WANNA DANCE AGAIN
how do I make a for loop in lua?
is it just for?
why are there %'s?
alright well, it's a complex pipeline i've worked out that just basically lets me specify tooltip keys (defined in my localization file) in a table based on item key - it looks overly complex, but basically the lovely patch basically just puts in a call to my mod's function, which looks for the key of the thing in my table (works a little differently for playing cards) and returns the correct tooltip key if there is one.
boiled down, literally all that's happening is that it's doing info_queue[#info_queue+1] = { key = [key of item in my localization file], set = 'Other' } there isn't really much point going into the nuance of this system, especially since i can show that it works for every other case i have where i use this. the point of the system is to just enable convenience of being able to specify "hey, for this item, append this tooltip to it, here's the key, go"
right before that loop from generate_card_ui() that you showed
{% for i in range(11) %}
{{ i }}
{% endfor %}
what?
that's definitely not lua yeah
This is python bro
This is if python and c had a child
this seems to be a good introduction to for loops in lua
wtf is Jinja?
Ninja but with j
definitely NOT lua
it's just ```lua
for
yes like i said
What do I do?
here's an example of it working
fix it?????
How?
read the error
error is at line 571, you showed completely unrelated code
But there is no bracketing issues I can see
this error is actually not intuitive - it doesn't like what you're trying to set the variable to and thinks you should be ending the table there instead
Oh it needs to be a string
It thinks it's just another variable which confuses it
also there isnt a self in the context so
(From what I can pull out of my ass)
wait, why are you trying to set anything inside self.ability inside the config.extra definition
Idk, I only started with lua yesterday
nop
AHA
boosters have a "from_tag" attribute!
now then how do i force a reroll
your kidding me.
its that easy?????
What now?
why are you returning code
Idk, I am using the strength and raised fist code
you shouldnt return code
and I only started using LUA yesterday, so I am still quite unsure of how to do stuff
you should only return values
So what should I do?
Do I just delete the return text?
yea
The error code thing is still the same
with the unexpected symbol near the {
What's wrong?
you still have the curly brackets
the ones that were part of the return
and #G.hand.cards > 0?
Now what
you forgot the curly brackets for the event
This works ty
at line 120?
yea
What do I put the brackets around?
the entire event
the entirety of line 120?
like this
Now what?
I recommend installing the Lua extension and then running the auto-formatter with Shift+Alt+F first, it might help you recognise problems for yourself
The issue is on line 132 you're not returning true
You just have true.
But yeah Lua extension tells you about syntax errors like these.
Now what?
how would i implement a check that occurs over an entire run, like tarot merchant tracking the number of tarots used in a whole game?
Store it in a G.game variable? But in just talking our of my ass tbh
that should work
I did possibly think of a possible alternate solution that doesn't require taking ownership, if you're interested at all. Maybe you could have the variable with the offset and do a check on every gold card to see if the pay got set back up the default and if it did, add it?
how would i store a game variable? would i just do "G.game.[var] = [value]"?
G.GAME.var = value yea
First hit Shift+Alt+F to auto-format the code and indentation.
The first issue is the trailing comma on line 132, which is marked as an error by the red squiggly line, and by the red highlights on the right side.
Second issue is that there are mismatched statements or braces somewhere, which that final red squiggle is indicating. If you hover over the red squiggle, it'll explain the issue.
Lua doesn't allow trailing commas. The reason they're included in the SMODS.Joker initialisation is that each named parameter is being passed as a member of a table in a function call to SMODS.Joker init:
SMODS.Joker( --calling function
{ --start of table being passed to function
key = 'balloon', -- table member named "key"
rarity = 2, -- table member named "rarity"
--etc...
} --end of table
)
```Anything outside of that table is code to be run, not a member of a table, and shouldn't have trailing commas
This is slightly hidden by the usage of the syntax SMODS.Joker{ ... } which is just a "convenient" shorthand for SMODS.Joker( { ... } ), but in my opinion makes it less obvious what's actually going on
bump
You say only the first additional info_queue entry gets merged to the tooltip - have you tried adding just an empty placeholder entry first, then adding your other desired tooltips afterwards?
whats the context for when any joker is destroyed? i'm not sure if remove_from_deck would work here
yes - what happens is it overrides the badge text with the set name
attempting to create a new blank one in a set with the correct name just causes it to say 'ERROR' instead.
im trying to make a global function that tracks when food jokers are destroyed
hihi!! quick question
how do i mark a boss blind as a finisher?
or
showdown
or whatever theyre called
Try adding a member replace_base_card = true to your table that you're adding onto info_queue
trying to make a joker that makes a card when a glass heart card is destroyed, but its not sensing the context I think (testing using print functions) I'm using the code from glass joker
oh i found cards_destroyed in the code!!! does that apply to jokers?
To follow onto this, it seems like this section in generate_card_ui() is what's responsible for the oddness around enhancements and Stone Cards being specifically excluded
So replace_base_card might work as a substitute
Well the cards that are already gold retain their value, it’s just the ones made after reloading won’t be set to the new value, they get set to 3 like vanilla.
But I did realize while taking a shower that the idol works exactly how I need this to work, and that hooking is absolutely the right method for this.
..As I was told previously lol. I just didn’t realize how it was the right method.
My only confusion is how to setup the hook
Looking at the SMODS.Blind wiki page, it should just be boss.showdown = true
If you get this working, does it also retain that value through reloading?
well currently im trying to find the context for when ANY joker is destroyed
would i have to like. create a new context for that?
no change 😔
Mmm I don't think jokers get destroyed, just sold or debuffed
Unless I'm forgetting something
FOOD jokers get destroyed
Ah
Is your code up on GitHub, or do you have a minimum reproducible example somewhere?
i dont see anything in the docs for it, but there might be a a destroy context if you search this chat
Have you searched through the balatro source code or the lovely dump folder to see how vanilla food jokers handle that?
yes and i can't find any reference for a context that activates when other jokers are destroyed, only remove_from_deck which only applies to one specific joker
Hmm, my thought is that you could hook into remove_from_deck and check if the card being removed is a joker and if the cardarea is G.jokers
yeah you might be onto somethin there!!
If that's the function that is consistently used for those jokers
does it have to be in your hand for the joker to increment, or does it work like fortune teller
made something i think might be really useful for making animated jokers
it converts video files to spritesheets
you can specify the desired tile size, number of columns, and even the fps to process into the output
https://github.com/TheBearodactyl/vid2ss
fortune teller
hm, im hoping youve got a way to store that value somewhere so its not wiped when the game reloads, like continuing a run
are G.game values like that not normally stored? it should only be reset upon starting a new run
they should, that gives me an idea
i was gonna take a break from coding today, but i gotta get this to work lmao
is there documentation for hooks on steamodded wiki
all i have is this and im having trouble understanding it and applying it to my situation
thats all i could find as well, and im stumped on the same step
bluh
hi im back again
i wanna try figuring this out myself b4 i ask for people to write my code for me if thats what youre doing devdelta
woah davestrider from homes hi
i want this joker to destroy a random face card in your hand on your first hand but for some reason if your score exceeds the blind it just. skips that
it's more of a lua thing
https://forums.kleientertainment.com/forums/topic/129557-tutorial-function-hooking-and-you/
Hooks are a feature of Lua, not of Steamodded, so it's more about understanding the general principle.
- you store a copy of the original function
- you replace the original function with your own version
- you call the original function that you copied within your own new version
- you return the value that the original function returned
ive tried figuring it out myself, for most of yesterday, for too many hours to justify lol. I also want to learn this for myself, otherwise ill always keep coming back here, but this has really confused me since i dont know lua well at all.
this is perfect, i know it wasnt sent for me but its exactly what im looking for, thank you
god my brain is getting scrambled
i sent it for both 🙂
ive been looking for the syntax error for like 20 minutes, any ideas?
this comma
attempt at a minimum reproducible example, but for some reason all it does is cause stack overflow when hovering any card?
figured it out, it was the brackets in the if statements
oh right
duh, i know why. it keeps constantly adding the tooltip to the new thing it's looking at
Thanks, i'll do some digging
lemme fix that first
there. one functioning minimum reproducible example
how do i write this correctly?
the card.ability.extra.score part
i'm trying to make it not occur if score in the config is equal to 0
i have a custom consumable that creates cards by adding them to play then drawing them to your deck, but if used in a pack opening they show up here and overlap hand cards, how can I move play down or adjust their position specifically in this case?
Hi, I'm new to modding and I have something to ask
I want to create an event to delete all cards with certain suits in the deck(because I added custom suits and that made vanilla decks have hundreds of cards I just want to avoid that) but I got no idea to do that
You can just change your suit's in_poil
i understand it now
to initialize the variable a hook is used, hooking init_game_object (igo) where a bunch of the game's global values are stored like skips and shop spectral rates and whatnot
local ret = igo(self) makes sure the base game's function runs normally, and then the ret.current_round.castle2_card creates the var
Then, the next section is just to change it each round like it says, by looking through the entire deck to see what cards you have, selecting a valid one to use the suit of, and then setting the suit of the new G.GAME.current_round.castle2_card.suit to the card's suit.
(i never knew castle was deck based lol, i never use it)
so if im understanding correctlu, this'd be how i'd hook in the check for if it's a food joker being destroyed?
should G.game be G.GAME? or no
i think it should yeah
sorry i was a bit dialed in but could you post ur code?
i'm trying to set the joker's values to 0 after a hand has been played, but when i use context.after, it sets it to 0 while the joker scores, meaning it only scores 0, and context.after is the ONLY context that works for the joker's main scoring, and i'm pretty sure context.after is the latest context when you score a hand, so i'm not sure what to do here
The game no longer crashes when I load it, but now the game crashes when I attempt to score a hand, what do I do?
its ok i fixed it
that's not working
should it be card.ability.name? (idk)
cant you just pit the first context.after after the first context.after?
Then you're doing something wrong. I strongly recommend against letting it create the cards and then deleting them
wdym
like, have it set the score to 0 AFTER adding the score rather than before
that's what i'm trying to do
the code that sets it to 0 is after the code that scores
but it still executes simultaneously
i had this issue before, having two of the same contexts is going to cause it to ignore the second one i believe
id try putting them under the same context
rather than under two contexts like you currently have
ill try that
though my issue isnt that it's ignoring one of them
both are happening
#1298894429159166043 this is one of the very very few things I actually have done myself modding-wise. I'm pretty sure I detailed it somewhere in that theead
it's just not executing in the right order
Code isn't released and is on my laptop (I'm on my phone) so can't share now
you were right, it does work now
i was looking through paperback code to see how they made certain jokers more likely and found this toml file. I was wondering if its possible to do the same with a deck sleeve (from the deck sleeves mod)
like idk if people have worked with deck sleeves, im basically wondering how to check what sleeve is selected
yeahhhh idk where i should create G.GAME.food_eaten that wont reset on startup
yea im working through that rn, seeing what resets what
fun fact, function SMODS.current_mod.reset_game_globals(run_start) runs every round blind select (at least from testing it does)
guh
yeah idek where to define it in the first place
this crashes on line 12
this is probably just a not understanding game variables moment
how do i do a lovely patch
i defined mine like this
it doesnt save, but it doesnt crash
This was all that was necessary for the hook i think, at least to make the variable in the first place.
ig i should find out how the game normally stores the value for castle
Ok so hi, I wanna mod Balatro, but when I watched a tutorial it said that I had to extract the .exe file which
i couldn't figure out how to do
I don't get it
aren't I supposed to type in_pool = false in my custom suits? I did that and it simply doesn't work for me
I have Windows 11 btw
if its a feature that was removed in the new windows version
guys how does priority work with mods
and with lovely patches
i think im fucking something up because the priority of a lovely patch i have is incorrect
Anyone know what to do?
wait, the normal game uses another function to load from a save,
winrar
or 7zip
idk if winrar works
bump
i get a stack overflow when this tag tries to create a joker, any ideas?
SMODS.Tag {
key = "mythic_tag",
atlas = "crp_tags",
pos = { x = 7, y = 0 },
min_ante = 5,
config = { type = "store_joker_create" },
apply = function(self, tag, context)
if context.type == "store_joker_create" then
local rares_in_posession = { 0 }
for k, v in ipairs(G.jokers.cards) do
if v.config.center.rarity == "crp_mythic" and not rares_in_posession[v.config.center.key] then
rares_in_posession[1] = rares_in_posession[1] + 1
rares_in_posession[v.config.center.key] = true
end
end
local card
if #G.P_JOKER_RARITY_POOLS.crp_mythic > rares_in_posession[1] then
card = create_card("Joker", context.area, nil, "crp_mythic", nil, nil, nil, "cry_eta")
create_shop_card_ui(card, "Joker", context.area)
card.states.visible = false
tag:yep("+", G.C.RARITY.crp_mythic, function()
card:start_materialize()
card.misprint_cost_fac = 2
card:set_cost()
return true
end)
else
tag:nope()
end
tag.triggered = true
return card
end
end,
}
nvm that might be something else
It worked
can someone explain how this hook could possibly be causing this error
commenting out my hook prevents the crash
stack overflow sounds like infinite recursion
but idk anything about tags
(the answer was to pass self as the first argument to the reference function)
What would be a good place to start for making a balatro mod?
(be warned, the documentation is a little rough)
yeah, but i have no idea why that's happening
if you can read code then other mods' source code is probably better
Is Steamodded the same as the Balatro Mod Manager, or is it a separate thing?
separate
i am gonna explode i think
mood
How do I fix this?
card.ability
how do I use it?
on line 112 you write self.ability.name, but you should use card.ability.name
this was meant to be easier than "copies the ability of food jokers" and ended up significantly harder
yeah it be like that
"eaten" can really be many things which is a problem
could be it self destructs could be its sold
etc
hard to write code that expects a standardized way of doing things when there is no standard
id like it NOT to be sold but
idk how to do that
and atp i think id have to hard code in the contexts in which jokers are destroyed
so
yeah this ideas dead
surely there is a context for selling a joker?
context.selling_card i think
how do i make this, sufferin
Thanks, anything else?
idk, test it and post if you get a new error
It didn't give an error, but the card didn't rank up
can you screenshot your whole calculate function
?
Try looking at cryptids reroll exchange?
i dont have cryptid installed :/
I ripped the code from Raised Fist and Strength
I wasn't here for the whole conversation, what's the goal of this joker
is there a way for me to make my joker epic rarity if cryptid is installed, else rare?
Rank up the lowest ranked scored card after all cards are scored
Maybe set G.GAME.current_round.reroll_cost = number every frame?
when the response is google it, it's because no one in chat knows how to do what you're doing
that sounds so laggy, couldnt i just do an on reroll trigger
we all learn as much as we need to make the mod we're making
why not just look at cryptid code
when it works 🙏
u dont need to download it github search works fine
im trying to not look at any other mods so that i dont copy their ideas
If you're only changing a variable its not going to lag the game?
ig thats fair enough
Alrighty, I have a possible solution for you that involves patching the problematic line in the vanilla generate_card_ui code to allow all enhanced cards to have added tooltips.
It will break any mods that rely on the arguably bugged vanilla behaviour of overwriting the original tooltip of non-stone enhanced cards instead of adding new ones, but I've tested it with all the big dogs and haven't found any immediately obvious issues. There are much cleaner ways to change existing tooltips than info_queue, so it's probably not ever desired behaviour.
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''
elseif specific_vars and (card_type == 'Default' or card_type == 'Enhanced') then
if _c.name == 'Stone Card' or _c.replace_base_card then full_UI_table.name = true
'''
position = "at"
payload = '''
elseif specific_vars and (card_type == 'Enhanced') then
full_UI_table.name = true
elseif specific_vars and (card_type == 'Default') then
if _c.replace_base_card then full_UI_table.name = true
'''
times = 1
match_indent = true
``` Valid for SMODS 0323b - 0423c at least.
This is probably the simplest solution, and could probably be included in SMODS by being added onto the existing SMODS patch (that adds the `or _c.replace_base_card` check) if there are no other obvious conflicts
thats the worst way to learn
wish lua was more straightforward
99% of my issues coding this are not knowing keywords
fwiw i can just tell u what cryptid did
they hooked calculate_reroll_cost to get it to work
Rank up the lowest ranked scored card
that doesn't seem too bad
Hey quick question. Can anyone tell me the mod that ya can gain xp and level up as you play?
you sohuld be able to check if ur voucher was redeemed
not a voucher, its a joker
No, they overwrited it.
while held it sets the value of rerolls to a flat 7$
well yea
ah i see
is hooking not a similar process
its literdally just redefining the function. hooking just means u also have the original function called
from what i know from other languages i think its relatively similar
eg run ur code before a fucntion
Lua 5.1 has only 21 keywords, and the syntax is usually pretty straightforward (imo)
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while
```The trickier part of Lua is that it includes a lot of syntactic sugar that overly simplifies what's actually going on, which can make it kinda odd on a first read
and its not strongly typed
which can make problems sometimes not apparent
if ur not familiar
there's lua, and then there's Steamodded 🤮
eg i remember an issue where what was done was setting G.GAME.banned_keys (a vanilla array fyi) indexes = true to remove certain cards
and there was an option to make the cards u banned inverted (eg a blacklist and not a whitelist)
That sounds like https://discord.com/channels/1116389027176787968/1279275441009459222
but it didnt work right because they checked like array_allowed_cards[i], and not array_allowed_cards[i] == false
and it got all fucked up cause nil evaluates to false
i mean nil evaluating to false is not that weird
most stuff being truthy maybe is
i caught it after like 5-10 mins of trying to figure it out
ok well, I technically found a way to for a joker to modify base mult before cards are scored, but there has to be a better way to do this calculate = function(self,card,context) if context.before then G.GAME.hands[context.scoring_name].mult = G.GAME.hands[context.scoring_name].mult*card.ability.extra.x_mult G.GAME.hands[context.scoring_name].chips = G.GAME.hands[context.scoring_name].chips*card.ability.extra.x_chips return { mult = 0, chips = 0 } elseif context.after then G.GAME.hands[G.GAME.last_hand_played].mult = G.GAME.hands[G.GAME.last_hand_played].mult/card.ability.extra.x_mult G.GAME.hands[G.GAME.last_hand_played].chips = G.GAME.hands[G.GAME.last_hand_played].chips/card.ability.extra.x_chips end end
I'm pretty sure context.modify_hand is made for that but it's not documented yet and I've never used it
as a context? what
yeah I've checked that out but I don't think blind contexts can be used for jokers?
they can
😶
that's good to know actually
yeah uh... no
SMODS.calculate_context calculates for all cards, that's wild
yes
classic case of complete fumble
how? do I just use it as a regular context or do I use it as the function itself or?
I think you just modify mult and hand_chips in that context and maybe you need to return calculated = true?
Ok I'm struggling a bit with installing the Lovely Injector
that one is kinda confusing but i think that's it
Mainly this part
that means that you put the mod's folder into %appdata%/Balatro/Mods (or the equivalent for your OS)
(create it if you don't have it)
How do I get to there?
windows key + R
or that
Isn't the mods folder outdated or something?
Because like, Balatro Mod Manager tells you to delete the Mods Folder before installing (i think)
no
i think thats because BMM reinstalls everything so it tells you to delete it to not cause conflicts
i dont think so
Do I need to put mods into the mod folder before running balatro?
yes
unless what you mean is if you can run it without mods which yes you can
but if you add a mod you need to restart the game
Do I need to run it with mods in the folder to install the injector thing?
Is that the Zodiac cipher??
yeah
How would one do blueprint for non-jokers?
Yes, but I was thinking all things that are not jokers.
so playing cards and consumables?
Yes, but I was thinking all things that are not jokers.
what is there that you're trying to copy that isn't a joker, playing card, or consumable?
I'm confused about your goal so I'm not sure how you would implement it
what is included in "all things"?
blinds? decks? the play button?
Everything here:
is the thing doing this a joker?
what is triggering the effect
A blueprint of the respective type.
For example, a blueprint voucher.
I imagine you would have to write a custom version of each thing you are trying to copy
how would i remove an UI
and the implementation would probably vary for each one
Is there a way to make score card score from a specific card?
Is this right for the mods folder?
You can call :remove() on the UIElement, or otherwise remove it from the relevant table in G.I (#💻・modding-dev message), but if you're removing a UI that's referenced elsewhere in the code, then you'll just end up causing crashes unless you also patch out those accesses
hm
ah yes. a blank button
don't underestimate the blank button blueprint
it lets you open the joker collection twice
ok i THINK i understand it now, thanks breeze :3
14 jokers!!
anyone know the best place to check if a joker is being hovered?
I can think of 2 and there are probably more
I hate that but it's probably great with Bunco
(lovingly hate)
(very neat concept)
(but it would infuriate me)
loved spriting it
Rise.
it;s the great milenko
It's a bit of wesk rare tbh. Saying that hologram is an uncommon, isn't hard to get to 4x, abd doesn't have a downside like that
hologram is an outlier and should not be counted in the statistic
but yeah maybe a 1 in 2 chance?
hologram is uncommon for some fucking random ass reason
i mean base balatro has some weak rares
Lol that may well be fair
Also very true
burnt joker has no business being a rare
same with like hit the road that shit sucks
does CardArea:move just not work? it seems like exactly what i need but trying it with G.play doesn't seem to do anything
you probably want to modify the cardarea's T instead
what is the broader goal?
^ this
would x5 be better
been looking for something for awhile but haven't found anything that works, even changing the cards' T.y
for some reason clicking on the reply doesn't take me to your message
here's a copy:
i have a custom consumable that creates cards by adding them to play then drawing them to your deck, but if used in a pack opening they show up here and overlap hand cards, how can I move play down or adjust their position specifically in this case?
have you tried creating your own cardarea?
i have no idea how to do that and it feels super niche for something like this, this seems like it should be easy and i just don't know how to do it
my guess is that G.play is having its transform manually set
thus why it won't let you move it
Tbh my playstyle (flush ad infinitum) isn't compatible with all face down cards, so I'm probably not the one to ask
changing G.play's T directly does seem to work though
dunno how i didn't try that at first lol
just gotta remember to change it back after
oh cool lol
i tested by accidentally shifting it up like 10x the amount i wanted to at first and it shifted the background too fsr? but doesn't seem to be doing that now
I genuinely think making it a percent chance to draw facedown fixes it
i assume it was just trying to make the background stay behind the 'in focus' area
ill consult w my mod partner
i do like it conceptually but it is def underpowered given the downside and rarity
x5 and 1 in 2 cards drawn face down (and affected by oops) i think would be more balanced
but would be a playtesting thing
i am now a bit confused
hi bepis
this is out of my area of expertise i wish you luck
:3
what is create_progress_bar
for some reason I don't see that when I search the source
thats something i made myself
does exactly what you think it does
I've barely touched UI but it seems like you're using G.UIT.C on the overall box but not the text
can you not just use create_progress_box? which is used for collection menu bars
Or is there a way to make a card be the same as card next to it?
i think its use is really limited, not sure myself - and i didnt know that even existed :p
thats fair
nop, doesnt seem to be it
wat do u want to do
Install whichever mods you like, by extracting them into their own non-nested folders within %AppData%/Balatro/Mods.
Plenty of people will make recommendations if you ask, #1209506514763522108 has a bunch
did a little digging and found this, could be useful?
I want to make mods of my own
That's for jokers.
gahhh i hate event ordering
yep, but it sure does seem like a great starting point
mmm i see
:3
I HATE UIS
WHY ARE THEY SO CONFUSING
😭
blame the existence of css
What would be a good thing to start with when making a mod? New jokers?
like, it should align vertically but WHY is it horizontallyadsdma
litereally shooting in the dark but what is the G.UIT.T doing on the line below
why in the world does this last event always trigger before the first event(s) no matter how i change the delays
adding text next to the box
i mean
