#💻・modding-dev
1 messages · Page 241 of 1
It's not released yet, but i'll be part of familiar
it's that in the source code I can't find it, so I'm assuming it's a mod only thing
(pleasedon'tsmitemeforaskingthis)
Anyone know any good tutorials for learning lua?
it's definitely in the source code! but it takes arguments, so if you're searching the codebase with closed brackets, it won't pop up!
IT ACTUALLY TRIGGERED YIIPPPEEEE§§!!!!§§ but know i get this error after playing a hand
NOOO
(I don't know of any good tutorials, but it's an entirely reasonable and worthwhile question to ask 😛 )
if you're willing to snoop around a bit the Lua Manual itself is a nice resource https://www.lua.org/manual/5.4/
read the error message, it explains what and where your code is going wrong
it sorta has the assumption you know a little programming background though
also, the LÖVE wiki! for love-specific things https://love2d.org/wiki/Main_Page
idk wat it means tho
you're not defining a card area
indexing means you're trying to see a specific element in a table or list. Nil means it doesn't exist, so you can't index it
what does calculate_effect do, roughly? so I can get a better idea of what I'm looking for
I haven't ever used it I don't think 😬
you know the tables you return in calculate witht he messages and the chips and stuff? well, you can put that in SMODS.calculate_effect(table, card) to use them outside of calculate
like this?????
so for a message you do SMODS.calculate_effect({message = "hi"}, card)
please just try your code before asking if it's going to work, man
Can I use this to make a trigger happen during the 'joker trigger' and not the initial scoring of the card?
I feel called out, lol
don't 😛
idk the timings so I'd just try it out
I still don't understand the syntax but I'll just brute force it ig
you haven't truly learned until the game has crashed on you 100 times
It took me 2 days to get abductions to work and I still don't understand exactly why it didn't work in my earlier implementations 😛
for example, how would I go about putting this inside a calculate_effect? wouldn't it defeat the point of having it be an event in the first place?
I've already reached that I think
it is working now, but its triggering every turn
no, put calculate_effect after juice_up() like this SMODS.calculate_effect({message = 'Chaos!'}, ocard) and remove the other message
what the, how come for gold seal the ability.seal table is empty
How do I hide custom suits until they have been discovered in game?
no this seems to be the case for every vanilla seal
but then the trigger would happen at the same time as the card's scoring, it would be extremely confusing
i guess i gotta hardcode gold seal support
unless I'm misinterpreting
wdym
like, the "chaos" message and the modifier changes would happen in the same frame as the card scoring its chips
events are queued and don't happen at the same time
because here it does them at the same time (except the text popup)
i mean, try it maybe I'm wrong
I was just following up on what Ice said so I don't know the full context of what was discussed before
yeah sadly it works as I'd anticipated
the animations just happen at the same time
and the joker doesn't even juice up ahah
nw
I'm just gonna smile and wave for now-
hypothetically could you just divide chips by 9999 and have it round up to 1 to achieve setting it to 1 chip
doesnt the flint divide and round up
i tried adding a 1 second delay to the event but it just delays the text too
i definitely used it before but I'm not finding it my code, what's the proper way to get the key for a card?
and if I try to put the text before the event it crashes
center.config.key, I remembered
me, having opened ModdedVanilla.lua and is now trying to modify the Perkeo example but doesn't know where the hell any of these keys are stored:
try putting the event inside the return func I told you about before
what keys
like this?
idk what they're called but like
the context.ending_shop and e_negative
where would I find a list of those
return {
message = ...,
colour = ...,
func = function()
G.E_MANAGER:add_event(...)
end
}
@deft niche
oh sorry didnt realize somethin was goin on
does anyone have any insight as to why my take ownership isn't working as it should? 
for the contexts: https://github.com/Steamodded/smods/wiki/calculate_functions
for the other keys you have to look at the games code
use SMODS.add_card instead https://github.com/Steamodded/smods/wiki/Utility
how many of aure's cat can fit on the screen
OMG IT'S PERFECT
thank you so much
sorry im new to modding I just started this today, where do I add the SMODS.add_card
replace all 3 lines inside the if for that
also use the joker's key instead of the name
I'm still trying to understand why it works
like, it needs to execute the return function all at once, so it requires to wait until the text appears before changing the cards' properties???
or something
it would be something like j_modprefix_key
make the counter something you're storing on the card, not a global!
so in the confix.extra
like any other variable you want to keep consistent!
tht makes sense
so to access it i would do card.ability.extra.counter?
yup 😄
alright chat how do I make a soul-like consumable
Another thing im trying to fix, How do I make this display correctly
it's not +:mult it's just {C:mult}
also is there a context.other_joker for consumables or nah
The card won't trigger after 6 hands or take away money. The money part I get I did wrong. but im not sure why its not activating
give me a sec to figure it out, the indentation is a bit confusing
you're not returning properly
right click and press format document and itll fix indents for you
you're returning a value, but the game doesn't know what it is
ok i got the + and color stuff but its saying nil
what's the code?
Because it has no value
Just make it one
Or zero
i dont know how to set the value
you need to make a loc_vars function to tell it what the values are
sorry to bother yet again but I still don't understand how to give a joker class both the legendary background and the legendary's png
soul_pos for the front layer
assign a location in spritesheet the same as when you declare the pos of the regular joker sprite
I have no mods enabled except SMODS/Lovely, and I encounterd a regular Overstock in the shop after having already redeemed one?
oooohhhh
ok now I got it I feel stupid
thanks
so it needs to be double the normal joker sprite in width?
ok then I don't get it
there is a separate sprite position on the atlas for the second layer
how can the sprite contain both bg and character if i make it normal sized
there is a separate sprite position on the atlas for the second layer
how did you redeem the first one
Just as usual, bought it the ante just prior
so this is incorrect?
no that's correct
the second layer is not in the same position as the first layer
therefore the second layer is in a separate position
oh ok
then we were both saying the same thing without understanding each other
send a bug report in a proper channel then I guess
I'm not certain this is a vanilla bug though
is there a way to override the badge for a consumable's type
I didn't say to report it to thunk. I said to report it to the proper modded channels
i wanna give a particular set of consumables a different badge color and name
but i don't wanna have to make an entire new consumable type for that
I know you can add extra Badges
you can probably remove specific Badges
set_card_type_badge(self, card, badges) would work
can you give an example of how to use this
well if i can hide the original badge and add a new one that works too
set_card_type_badge = function(self, card, badges)
badges[#badges+1] = create_badge(localize('k_spell'), G.C.PURPLE, G.C.WHITE, 1.2 )
end,
is how I use it on a custom game object, but that's directly at the source. I suspect that if you use it on a specific item, it'd overrule it and not create that badge
it would also allow you to just kick things from the badges table, as it's exposed in that function
i will give it a shot
wait but
How would I go about taking away money from the player
if you start it with badges[#badges+1]
couldn't you just do badges[1] to override the first badge
yes
yeah okay this should work
that's what I meant with kicking it, haha
oh isee
ease_dollars(-10)
oh it worked easily thanks a million
😄
all current content for boplatro (name subject to change):
chat do i make the asbestos enhancement or the big edition next
big edition sounds funny
asbestos enhancement: x3 mult, decrease by x0.1 every card played (can reach x0)
big edition: takes up 2 slots, all values doubled
how do I import a file into main?
Lol, somehwo my legendary card has no foreground!
I am finally breaking my content into different files
thank you kindly
what language are shaders written in?
It's love2d shader format, which uses a file / convention called fragment shader
How do I minus from the players chips, but not like the total they have scored so far.
looks like it's based on GLSL
It has a full longer name too, let me look it up
OpenGL has its own shading language: GLSL (openGL Shading Language). GLSL can be a little overwhelming and there are not alot of really basic 'get to know' GLSL out there, this article will help you grasp some of the fundamental concepts of this wonderfull language.
sorry
anyone have a working example of how to do the floating effect like Yorick and co have? I didn't see it listed in the smodded docs!
soul sprite
.
it's there
where
In the ChipsXmult
Ah, I had my floating guy in the background, lol
hi chat
hello sylveon
Joker
when
My first legendary joker!
I think returning {chips = …} should work most of the time
Hatsune Joku!?
does anyone know how to reference the description for negative consumables? i tried but it keeps crashing, and G.P_CENTERS.e_negative just puts the description of negative jokers
there is another key for negative consumeables
negative consumables are a thing ?
but Idk if you can access directy
perkeo
yea
I mean
i can't
ive never went over green stake
it crashes
so perkeo i have never seen
I don't know if you can do it except by accessing them directly
not what I said ;P
info_queue[#1116390750314307698_queue+1] = {key = 'e_negative_consumable', set = 'Edition', config = {extra = 1}}
Is there a way to do something like
SMODS.Joker:take_ownership('baron', {
...
doSomething = function (self)
print("hello cruel world")
return true
end
})
and then in another function do
if self.ability.name == 'Baron' then
self.doSomething()
the function assignment works/doesnt throw any errors, and there is other code that currently runs correctly in the if statement
it throws
attempt to call field 'doSomething'
I said {chips = …} should work
DIdnt see it
is the I in info_queue supposed to be capitalized
I was looking at the message you replied to, this was after it
no, and it wasn't in the code i copied
yeah this is accessing it directly
weird discord thing i guess
Uhh curiosity, I'm working on UI for locked/undiscovered cards, and for whatever reason, my general mod badge doesn't show up on the undiscovered/locked tooltip, but the custom badges I added in addition to the main mod badge do. How do I enable the mod badge on the former or disable the custom badge on the latter?
you can probably check if the card has been discovered (or not) to choose not to add the badge
I'm just more confused why I'd have to manually add the main mod badge back
a } or an end etc.
I think the logic is that you should hide the custom badge
not that you should show the main badge
but whether that should be the logic is a different topic
I'm thinking I'd prefer to show the main mod badge
try an extension that formats Lua code
Since the groups of badges for undiscovered cards makes collection a little more exciting (see: I've completed this group!!)
ok i went for the crazy route of adding a chain of extra to the return of every calculate
lets see if it works
Maybe ask in the SMODS thread or the SMODS server or GitHub then
quick question, what's the {C:color}{} for light gray (the color scaling jokers have for text in brackets)
inactive
thanks
I set up the json metadata for my mod but steamodded still isn't detecting it
nvm, I'm stupid lol
I forgot to rename my .lua file to the correct name 😭
...nevermind again, that didn't fix it
Whelp, I managed to force it by the same way I'm doing the other custom badges, which is technically not the best solution, but it is easier than patching the code
Seems SMODS doesn't do its normal badge code if it's undiscovered
But my custom ones don't check for it shrug
Anyone know why this isn't working?
Code?
Does it not like the version thingy?
try the version without the space
do you want to reduce player's chips by 50?
Didn't fix it
I didn't ask what Chips are, I asked how much you want to reduce it by
yes..
put -50 then
actually, wait a minute
is there a mod limit on Balatro?
because I have 30 mods but only 28 are loading
i dont think so
are u rage baiting
nope, that isn't it then
as I said
wait wait wait, do I need a copy of lovely.toml in my mod's folder, or is that optional?
are you rage baiting? lol
thats optional
OHH
that are returned
does the id have to be lowercase?
are you sure the problem is the json
what's your issue
does it detect your mod
no
do you have python
go to the Steamodded folder and run tk_debug whatever .py
is there an smods parameter for custom undiscovered consumable sprites?
then open the game
I think so
yes, for sure
there's undiscoveredSprite, i think. lm see how i did it for confections
yeah, it's just a this. It will have the standard circle with a question mark in it, though
SMODS.UndiscoveredSprite {
key = "confection",
atlas = "kino_confections",
pos = {x = 0, y = 3}
}
2025-03-16 19:09:29 :: ERROR :: Loader :: Found invalid metadata JSON file at C:\Users\crisp\AppData\Roaming\Balatro\Mods/Galaxia/Galaxia.json, ignoring: [lovely json "libs/json/json.lua"]:185: unexpected character '' at line 15 col 20
oh
another debug script user joins the community
I swear to god if it's the comma
there's threes of us! threes!
thanks! I'll try this out
nope, wasn't the comma
WAIT A MINUTE
it complains that I have a comma on line 15 col 20, then complains that I should have a comma there when I remove it??
make up your damn mind 😭
OHHH
I forgot the brackets
OKAY THE GAME CRASHED, IT DETECTS THE MOD
Where would I start looking if I wanted to setup a joker that only activates when you have a certain other joker.
Most effects based on having a speific joker would now use the condition if next(SMODS.find_card([key])) then
In vanilla, it's if next(find_joker([name])) then
_joker.config.center == G.P_CENTERS.j_splash is how I do it in my code
with _joker just being what I named my variable in the loop this is in
check for next(SMODS.find_card("other_joker_key"))
it's giving me a nil error at this line
i've tried changing the syntax a couple times but same thing happens
how did you declare the new pool/consumable type?
Now I'm getting this error and can't figure out why
I don't remember by heart, but it's in my mod in the consumeables folder under Confections, if you're in a hurry. Can check for you in a few minutes!
(also yes I'm using ModdedVanilla.lua as a base)
thanks! I'll see if I can dig around for it in your mod files then (if I can find your mod)
there's a comma missing here
apparently it gives me an error each time I try to use the prefix 'ability'
oh, thank you!
aaand now it's not detecting my atlas
sigh
use card, not self
yeah
just replace self with card within the entire function
(also remove card = self)
fym failed to collect file data for Atlas GLX_Galaxia 😭
getting a thread error when trying to play a custom sound
trying and failing horribly to make a shader
okok
do I delcare it before the if statement or remove it completely?
thanks fir your help btw
playing it with play_sound() properly and defined it properly but when i try to play the sound it just dies
that line you can just remove
replace all the others
does it pull from assets/1x automatically or do I have to tell it to do that?
do you have the 2x version too? you need both
oh
ok so the example ionized shader just. doesn't work anymore? fun
you have pixel smoothing on, so it looks for the 2x
what's the error message
full log
it just says thread error /shrug
HOLY CRAP IT BOOTED
i did the sound the same way i did my last custom sound and the other one works
have you checked there isn't some mistake in the sound declaration and that the sound file is intact?
yeah windows can play the sound perfectly fine
the sound declaration i'm pretty sure i got right
j_modprefix_redbull
SMODS.Sound({
key = "probability_st",
path = "probability.ogg"
})
and i add the mod prefix before the sound key when playing it
where do i put that
in place of redbull
well something went wrong with getting the data of the sound
idk what would cause that other than incorrect path or malformed file
it might be the file? but idk how i'd check that
can i see the sounds folder
it looks fine to me and hasnt had trouble in any programs ive opened it in
this is the only file in the sounds folder and the sounds folder is in the right place
that being inside assets
did you manage to figure this out?
yeah I found it, thanks!
it still dont work
great!
expected, unless modprefix literally is your mod prefix 🥴
😭
well, I'm nearly there
oh thats my fault im stupid
you're doing the end of round check incorrectly
?
but also you're developing on old calc ...?
ah right, forgot I was on old calc
I play on old calc because Jen's Almanac doesn't support new calc yet
on new calc, the correct check for a single end of round trigger is context.end_of_round and context.main_eval
ok so the example mod for shaders just does not seem to work anymore unless ive royally fucked it somehow. i dont suppose anybody happens to have a perfectly commented shader with full explanations on hand
still i don't recommend developing on it
I'll switch to new calc
this code was slightly wrong but the idea worked 🔥
time to make a joker with a million stacked effects
so do I reinstall both lovely and smods or just smods?
If you create a copy of your Balatro installation somewhere else and rename the exe, you can have two entirely independent versions using different lovely, Steamodded, mods and saves
The folder in appdata uses the name of the exe
both, you should have 0.7.1 with latest smods
clearly I am missing a filed here of some sort
key = "Zodiac",
primary_colour = HEX("C61CBB"),
secondary_colour = HEX("96108D"),
loc_text = {
name = "Zodiac",
collection = "Zodiac Cards"
},
collection_row = {7, 2},
shop_rate = 2,
default = "c_reverse_aquarius",
}```
Doesn’t it need a name
lol
isn't the name in loc_txt?
LMFAO
sorry I eated the name
Don’t you need a “,” after collection “zoldiac cards”
the loc_text in question:
oh shoot
no, because it's the last item in the table
I'll trade the e for an s at the end of collection_row
yeah that would do it
we're back in business
who would have thought spelling would be this hard
hahaha i love that it's zodiac cards
how many zodiac sets does that make
idk, I haven't even checked to see if others exist
8?
Sprite work resumes now
How many zodiac signs there are ?
alright, got newcalc working
ice please learn shaders so i can steal more code from kino 🙏
12, but I'm being quirky and adding in Ophiuchus too
I literally don't understand anything about shaders ❤️
neither do i. which sucks when the error for a faulty shader is a big fat wall of nonsense
that makes 99.96% of us
top 10 reasons to never make a shader
i just want my joker to be big 😭
98% can't read, and 98% of those who can read don't understand shader code
literally thats all i need this shader to do. i need it to make the joker bigger
Haha, I want to get into them, because I want some flair to add to abduction and spellcasting, but they I don't even know how to get started on shaders
shaders aren't real, they can't hurt you
ok what are some good recent mods with shaders i can rummage through the code of
cause im not entirely sure the example mod actually. works
AYY, it works!
Aiko's been playing around with them, that's the only thing I know of that's recent
less of a coding question and more of a logic question. The joker works as intended, except that it still gains 1 mult after being reset...
i don't understand what's making it do that
bunco, paperback, I don't have any in the alpha release but I did reference the examples to make my shaders
-# including Paperback's Dichrome
-# although they put another shader on top of mine
Wait, you're hiding shader knowledge in that noggin, knuckles?
Hahaha
it feels weird talking about someone whose username is stupid
"Who knows shader code?"
"stupid"
"well F you too buddy I'm just asking a question"
"stupxd"
fixed it!
i was making it more complicated for myself than it needed to be
btw, every time I tweak anything in my code the required number of "end" changes, it's making me insane
lua really is the quantum language
ok i have stolen the fluorescent shader code from bunco and it is. not working
the shader does not display in the collection menu and after a few seconds it crashed
is there a way i can get the name of the currently active skin in 'customize deck'? 
this text value at the bottom, basically
I am attempting to make a 1-to-1 copy of the "Raised Fist" joker from vanilla, however, once the blind is won, the round never ends. I am able to use all menus, I see no errors in console. I can provide the code used, but it is just a copy from vanilla, not context.end_of_round added.
I have no idea how this fits into my mods theme now but I love it
really happy that they're working
thanks a lot for the help guys 💝
blursed
i am simply unintelligent
Such a cute and christmasy little stocking
I love the tiled background on it
G.SETTINGS.CUSTOM_DECK
G.collab_credits
man boplatro_big_shader is fun to say
thanks! The christmas colors weren't intentional, actually, I just used the opposite colors of spare trousers (which is blue and yellow)
else if isn't something you should use in lua btw. it's elseif
thank you!
the former works but it makes you need an extra end
the joke is that with socks you can never find the other one, so it scales with everything BUT pairs
its a funny joker effect i like it lol
oh ok, I'll keep that in mind!
thanks
would also like some insight, if anyone has any, as to why my steamodded take_ownership() isn't working as intended 
is it safe to have two objects of different classes with the same key? i'd presume not but idk maybe the prefixes save it or smth
for example, can i have an Edition with the key "big" and then have the corresponding shader's key also be "big"
wait bunco does it so i presume its ok
yeah that's almost always fine
that almost unnerves me
centers are stored in a shared table but have different class prefixes, and anything else usually has its own map
^ this
It's generally fine to do that unless you like, have some really odd edge case
ok the shader's working, now i just gut most of the effect stuff and make the joker 2x bigger lol
Forgot to mention, using new calc
I say almost because of consumables, they all share a class prefix
So you can't have a tarot and a planet with the same key
however they're not fundamentally different objects either
ah great, another random syntax error that I can't find
you could also use speech marks instead of apostrophes
would doing return math.max(math.floor(hand_chips = 1), 1) work?
I do not know if that is possible, if the shader reshades every pixel, I don’t see how it could make the thing bigger
well im trying to write poker hands', poker hands" would be improper lol
also what is the point of the , 1) at the end? is that a boss blind thing or is it needed for math.max
math.max, yes.
right
i meant "poker hands' (...)" lol
anyone know why this is happening? The bracket it's wanting me to close is already closed
transparent is a colour 🤷
there's an image in the docs of a shader changing the shape of a joker making it wavy so
i am indeed struggling though
im having an issue where the +Chips value is copying the +Mult, Im assuming its because the +#1# being the same for the two but i dont know
Here’s some thing weird
I tried making a card partially see through and found you i could not make it transparent with a shader
The cards background texture was still there
each variable has a different #X#
#1# is your Xmult, #2# is Cmult and #3# is Cchips
im not gonna be able to uncrop it am i.
sigh
im so dumb thank you
it's ok, all part of learning
trying to find this stupid syntax error that Balatro is saying it's finding
despite the fact that I can't find it anywhere when I open the file in notepad++
oh
I had an extra end
anyone know where my save file is stored?
I wanna back it up because the card I made works like Gros Michel
Crytpid has a huge joker card
total noob here, but maybe try changing the atlas sprite size?
found it :D
idk how i'd do that in an edition. though truth be told idk how to do much of anything in an edition lmao
Ok, new problem, they are nil now.
ah, fair point
I have a bunch of working editions I made, let me know if you’d like to see them
would i put the code in on_apply and on_load?
...but the value isn't nil? it's 4?
vars is an array, it should be {center.ability.extra.Xmult, center.ability.extra.Cmult, center.ability.extra.Cchips}
ohhh, I forgot about that LOL
tysm
np
gimme a sec to read through the file you sent
could you put a #3# in your joker text and screenshot what shows up in game?
(that refers to your variable that should be card.ability.extra.odds, if it is nil then it should say
Same thing
wait does it crash on loading the game?
1 in nil
I don't know why it's nil, I defined odds = 4
is it possible that it's a bug with smods?
show code
i have no idea, actually
Would it be possible to share the code snippets for the loc_vars
this is a very patchy way of fixing it but if worst comes to worst just stick a card.ability.extra.odds = 4 before you check for it
rather than full file
how can I make this happen? Also, for future reference, is there somewhere I can look to find what to put together because I dont want to be dependent on y'alls help
loc_vars = function(self, info_queue, card)
return {vars = {card.ability.extra.chips, card.ability.extra.chip_gain, card.ability.extra.odds, (G.GAME.probabilities.normal or 1)}}
end,
How do I detect certain suites of playing cards and echancements in my current hand.
Im making a joker that will give a x3 multiplier if you have atleast 3 enchanced clubs in your hand.
dos card.ability.extra.odds have a value at this point ?
like in your config, how do you initialize the variable
wdym
wrong reply
wdym
I just did odds = 4
paste config object
config = {extra = {chips = 0, chip_gain = 1, odds = 4}},
given that chips = 0 and chip_gain = 1 work, I'd assume it'd just set card.ability.extra.odds to 4
yes
you can find a list of example mods at https://github.com/Steamodded/examples, if you don't find what you need you could read the steamodded wiki or search for what you need in the modding channels
gimme a min ill take a look once i get to the computer
.
Likely with a hook wherever it ups the ante
or i wonder if theres a context for boos blind defeated
you could iterate through the played hand and check if each card is a spade and has an enhancement
How do I get the played hand
I know how to iterate through stuff but how do I get the hand and detect suites/enchancements
G.hand.cards for held hand, G.play.cards for played hand
card:is_suit('Hearts') for suit
there's a few ways to get the enhancements
i might not be understanding how math.max works,,, the 4x mult works just fine but the base chips being set to 1 isnt doing anything
math.max chooses the largest number inside its arguments
like?
ahhhh
if v.config.center == G.P_CENTERS.m_steel then
is how i do it, that one does it for steel
so i could just do math.max(1)?
well idk why you would do that
math.max(1) is the same as 1
you can also do G.P.CENTERS["enhancement key"] for this
yeah im trying to set the base chips to 1
so like G.P.CENTERS["m_splat_mammalized"] for the mammalised cards from splatro
if it's a modded enhancement it needs the mod prefix
is there just a general way to see if a card is encahnced, like not caring aobut what enhancement
if not v.config.center == G.P_CENTERS.base or if v.config.center ~= G.P_CENTERS.base
where v is the card to check
damn it doesn't look like i'm gonna be able to make the big edition 😔 i literally just cannot find where a joker stores its display size, if it does at all
ok i completely misunderstood math.max sorry lol
i thought math.max was the command that set what the chips or mult was :P
no math.max is just a base lua thing
it chooses the largest number within its arguments
math.min also exists for the opposite, chooses smallest within its arguments
I FIGURED OUT HOW TO SCALE JOKERS
IT LOOKS GOOFY AF AND IS ALMOST DEFINITELY NOT WHAT YOURE MEANT TO DO
i feel like something as tucked away as card.role.draw_major.T.scale is something i should definitely not be messing with, but we'll just see how it goes
This is wrong and doesn't work, its not spitting any sytnax errors or crashing.
So its def a logic error on my end.
but now im realising. is it actually possible to 'double all values' on a joker
for index, value in ipairs(G.play.cards do
do that
the index/value can be swapped with anything, a lot of people use i, v but i prefer writing them out fully
hmmm, so currently it sets it to 1 chip for a second before adding any number of chips immediately undoes it
was told to put hand_chips before return
both need to be present but the variables can be anything
index is the numbered index you are checking
value is the current thing you are checking
what do i put inplce of value
have you figured it out-
you're only changing the display number i'd assume
like it really doesn't matter?
Of course in the middle of bug fixing my power goes out
as long as it's not a syntax keyword (like print) then yeah make it whatever you want
but you should probably keep it as i,v or index,value for readability
again value is the current thing in the loop so when you're checking cards here use value:is_suit("Hearts") for example
still so confused
i'll break it down
hey, marie, you seem like you know what you're doing
do you know why odds is nil even though I very clearly set it to 4-?
Is it skipping the need for my if statement
i'll get to you
So its just checking for the value on each one automitcally
if theres an issue i cant find it sadly, everything does look fine
what is (G.GAME.probabilities.normal or 1) in your loc_vars for
for index, value in ipairs(G.play.cards) do
will go through every card in G.play.cards in index order from left to right
G.play.cards is an indexed list, so you can refer to values in it with G.play.cards[1], G.play.cards[2], G.play.cards[3], which the loop iterates through with index
value is equal to G.play.cards[index], which is the current card being checked
I got it from the probability example used in the example mod for the gros michel
this is because sometimes G.GAME.probabilities.normal isn't present, like in the collection outside a run
the crash still happens either way, it seems to be unrelated to the crash
the or 1 prevents it from returning nil, it instead returns 1 if that value isn't there
so what needs to be changed here
add and context.main_eval to make the end of round only trigger once
unrelated bug but a bug nonetheless
that bug's actually present in the example mod, funnily enough
it's what broke the first function lol
that is because the example mod was made before that was a problem
ah, fair
and before we had context.main_eval to fix it
change G.hand.cards[i] to v
instead of if v == card:is_suit("Clubs") you need to do v:is_suit("Clubs")
also you need to return the xmult at the end
Yo :3
Hello
return { x_mult = card.ability.extra.Xmult} at the end instead of Xmult = card.ability.extra.Xmult
so this
one more thing
right click and press Format Document to fix indents
it doesn't change the functionality of the code so you don't have to
but it makes your code easier to read
aight
Alternatively, you can do ctrl-A + shift-alt-f
hmm, so odds = 4 seems to be the culprit
if I manually set line 60 (the crashing line) to if pseudorandom('andromeda0') < G.GAME.probabilities.normal/(card.ability.extra.odds or 4) then, the description still says 1 in nil but the actual function itself still works
still doesn't pop
though actually the message doesn't appear properly
oh if it's just the description that is wrong
This is the full code.
then hold on
nonono, I had to manually set the function to 4 in the line itself
oh also probabilities should use {C:green}
the card.ability.extra.odds is still nil
try adding a set_ability function that sets it to 4
a w h a t
you never reset clubcount back to 0 once you're done with it
unrelated bug but bug nonetheless
you wrote card.ability.extra.xmult in the return but the value is x_mult in the config = {}
remove the underscore from the config one
set_ability runs one time when the card is created
it's like your calculate function
doesn't go inside any functions, just goes in the joker
oh, oki
here's an example of one from my rainstorm in tsunami
set_ability = function(self, card, initial, delay_sprites)
card.ability.extra.nines = 0
if G.playing_cards then
for k, v in pairs(G.playing_cards) do
if v:get_id() == 9 then card.ability.extra.nines = card.ability.extra.nines + card.ability.extra.moneys end
end
end
end,
you need to end it with end, and the comma is VERY important it breaks otherwise
so should the first line be set_ability = function(self, card, initial) in this case?
no you still need delay_sprites
the first line should not ever be changed
even if you don't use those values
everything between the first and last line you can do whatever you want in there
alright, I got
card.ability.extra.odds = 4
end,```
yep that should do it
alrighty
i don't know why your value would be nil and someone more experienced can probably explain why
Also, Unrelated but for some reaosn there is copies of my joker showing up in the collection, like 2 of each
but that should solve the problem indirectly
on your mods list are there 2 entries for your mod
it's still nil
lemme try putting it above the text
you could hardcode it
and just write 4 instead of card.ability.extra.odds being used
this will make it incompatible with value modification, like cryptid's oil lamp and betmma's gameplay update
if you see john aure smods around he'll probably know what to do
he's like the god of smods
oh yeah, he was helping me earlier
One last question, How do I make a joker make specific consumbable,
Like a certain tarot card
quick tip for you
balatro is open source modding
go find something that does what you wanna do and borrow their homework
"Yo, what'd you get for number 8?"
Hmm... How do I make it so a booster pack ALWAYS appears after a boss blind?
try looking at riff raft's code
there's a deck in there that forces a void pack to spawn in every shop
that's similar to what you wanna do
Oki, oki got it.
any tips of where to look for what i want
cryptid has almost everything but its code can be kinda confusing to read
as a more simple example for creating a specific consumable, MoreFluff has a joker called Bad Legal Defense which creates a Death tarot when boss blind is selected
ok i figured out the issue, it just doesnt work when the chips are changed at all during context.before
so how would i be able to reduce the chips before scoring then?
check how the flint boss does it
that reduces base chips and mult by half
THE JOKER WORKS WOOOOOO
is there any way to add custom conditions to whether a joker can be purchased/otherwise added to your jokers? i need to make sure Big jokers can't be obtained unless you have at least two free spaces left
you'd have to do a lovely patch
you can either modify the buy button to not work unless you have 2 free slots or you can try making big jokers take up 2 joker slots by default? maybe?
or they could just give -1 joker slot as an edition effect to simulate it
that is the effect it has
which would make you able to take one if you have only 1 slot free, but then you'd be 1 slot in the red
uhhh maybe checkkk
morefluff's philosophical joker
that has code that allows it to be bought when your slots are full
like a negative joker
that might help? idk
my jokers are still making duplicates for some reason
Ive also been loking at the Smod docs and past chat history,
But still no way to just check if a card has ANY enchancement. Not just a specific one
i already gave you that method
this
should be it
if not, i'm misremembering, and the actual code for that should be in vampire's code
if card.config.center.set == 'Enhanced' maybe?
Vampires code is confusing cuz its not in SMODs format
the only thing that changes is changing self to card
¯_(ツ)_/¯
Fair
I also still have my duping problem, I se that its making two mods but Im not sure how to get rid of it
What software do you guys recommend for creating art for the jokers?
aseprite
it's because you have both a metadata.json file and a steamodded header, most likely
remove the steamodded header from your mod's lua file and it'll fix that
bleurgh is there any way i could happen during main.scoring but before any card is scored
setting the chips to 1 after context.before
ahg, the check for enhancements still isn't working
you combined both of my methods and used the wrong one
you are checking for cards that do not have enhancements
either add not or change == to ~=
context.cardarea == G.play doesnt do anything
just crashes the game
buhhh
ok i have a solution, but it crashes saying "attempt to perform arithmetic on global 'hand_chips' [a nil value]"
essentially it triggers before the first card is scored but not on retriggers
Still doesn't work.
It pops with or without any enchancements
i did tell you that you aren't resetting clubcount back to zero after you're done with it
so it's currently counting every club card you will ever play
so once you play 3 it will always give mult forever
how come hand_chips stops working when outside of context.before?
this is a seperate card
Is ^Mult built into smods or would I have to program that myself?
its in talisman i believe
please don't ping me for help, I help out when I'm lurking and I know the problem lol
oh, ty
target = '''=[SMODS _ "src/utils.lua"]'''
is this the proper format to lovely patch into smods? cause it is not working for me
where is hand_chips in the api documentation?
Looking at rift rafts codes didn't help me
in the wha
typo, i meant api documentation :v
,
function CAL.BOSS.bosses_tab()
return {
label = "Bosses",
tab_definition_function = G.UIDEF.settings_tab,
nodes = {
n=G.UIT.T, config={text = "Bosses Completed", colour = G.C.UI.TEXT_LIGHT, align = "tm",
}
}
}
end
can someone tell me why my text injection is not working?
lua
toml:
anyone up lol?
i have discovered a new problem with the black hole enhancement
right now so it doesnt get super op super fast, when it consumes a card with xmult it add's the card's xmult to it's own
however, all cards have 1 xmult by default, so it just. goes up by 1 for every card it consumes no matter what
i dont think i need to say how broken this is. how do i solve this
anyways, I'm gonna do some runs for now. feel free to @ me if you know what I'm doing wrong
subtract the value it adds by 1
I think that works properly
if it doesn't, just checking if the xmult of the consumed card == 1 and not adding it if so should work
just reduce the value it takes by 1 ...
true
oh the other guy already said it
bleh this wouldnt work anyways it happens after the hand plays
AAAA sorry wrong replyu
ijgjgirjgigrjg
imeant to reply to myself imso sorry aaaaaaaa
yeah i need to do it before but like would i need to write a custom script to make chips carry over from context.before to the main scoring
cause i have noooo clue how to translate the way the flint does it to this
(im trying to set the base chips of a hand to 1)
soooo the flint has THIS which is like exactly what i need,,,, only it isnt a hand function but is a blind function
is there no way i could like use a blind function as a jokers ability
sorry for asking so much abt this i just rly wanna know if what i wanna do is feasible,,,,,
and i know very very little about programming ,w,
getting closer I think, any help would be greatly appreciated
dpaste.com is a pastebin site for easily sharing and storing code snippets. Syntax highlighting, clean interface, markup preview, quick sharing options.
I think aure is adding that to smods soon so you might have to wait
@red flower hey joyous, I followed your lead but...well got stuck
ok ty !!!
ill leave this on the shelf for now then hehe
my lead on what
creating a new tab in the run info screen
and then filling it
For tonight I would feel really good to even get a label to show up
live rn if you wanna follow along
trying to do a basic texture pack anyone know what might be wrong with this code of if I need to do something.
this happens on start
Sounds like it's not finding the files. Are they located in YourMod/assets/1x and YourMod/assets/2x?
so yes
You also have standard-size assets in 1x?
compromised .w.
now sets the chips to 1 during joker scoring
probably underpowered but whatevaaaaaaa its in
what do you mean
You need to make two copies of all texture assets.
One at regular 1-to-1 pixel display size, located in /assets/1x, and a second 200% scale version in /assets/2x
I have that yes
Why doesi t show up as nil
Are the file types all .png?
yes they are all edited pngs from the 7z extracted game files
how can I do the description tag that blueprint and the fool have for their respective behaviors?
Just for a sanity check, that's AADeck_lc with a lowercase L, not an uppercase I?
that is a lowercase l
Then i've run out of ideas, sorry
what are your loc_vars?
well, even then, #3# wouldn't pull from config, right? it'd pull from loc_vars
Hello guys, i have this bit of code thats supposed to make my joker juice continuously if it detects a specific card in hand, but with this it just keeps juicing after playing the card too and i have no clue why. I've tried debugging it and it sets potential to false correctly but it still just keeps on juicing anyway
local potential = false
if context.hand_drawn or context.after then
for k, v in ipairs(G.hand.cards) do
if (v:get_id() == G.GAME.current_round.osquo_ext_bountyhunter_card.id and v:is_suit(G.GAME.current_round.osquo_ext_bountyhunter_card.suit)) then
potential = true
break
else potential = false end
end
end
local eval = function() return potential == true end
juice_card_until(card, eval, true)```
My guess is that it's because your eval function is only using whatever the value of potential was when you create it, not a reference to the variable potential.
Try making potential a member of the card config in card.config.extras.potential, then access it through the card argument provided to the eval func when it's called:
local eval = function(card) return card.config.extras.potential end
what do you want current: to be? you're calling for #4# but you only have two variables in your loc vars
is it possible to force a shop open
that can't be it though since it starts juicing correctly when the card appears in hand
the problem is that it will never stop juicing after it leaves the hand
ah ui see nvm
It will juice until that eval function returns false, which it never will if potential is always nil
ok yeah that did fix it actually
i wonder why it starts off not juicing then though but oh well
guys i need help making my deck actually possible to beat
It's to do with values vs references.
When you declare eval as lua local eval = function() return potential == true end it's creating a function that will return (the value of potential when the function was created == true)
If instead you declare it as lua local eval = function(card) return card.config.extras.potential end it's creating a function that will return (the current value of the reference of ...extras.potential == true)
Hope that makes sense
what does it do rn?
start with one card in deck
x0.5 mult
fuck you
create splash after beating each boss blind
for moral support
oh my god I need to make splash give moral support somewhere in tsunami
i'll find a place for it
I love splash
so you literally cannot clear a blind without like a god-tier buffoon pack
whats the small blinds blind at in ante-2
that's where your wrong
you cannot get a buffon skip ante one
so it's literally impossible
🤨
judgement
nopw
I'm seeing the UI code that the fool/blueprint use for their description tags, but I'm not quite sure how to implement it into the smods format?
are there any references I can look at for this, or anyone who knows about this
just released the first public build of my mod :D
ty for the help, everyone! /gen
Hi! I'm new to modding Balatro and I'm attempting to make my first joker. I'm a bit familiar with Lua but not to the point of understanding what's going on in mods :/
I'm just trying to make a joker that checks if the played hand has 4 cards, and if it does, retriggers scoring cards 3 extra times.
I'm currently trying to get the joker to detect a specific number of cards played without any luck
context.scoring_hand is a table of the cards data
what you want is #context.scoring_hand
so it'd be if #context.scoring_hand == 1?
also you want to check context.full_hand if you want the amount of card played regardless of scoring
yes
is it just not possible to take ownership of consumeables?
Nope, amount of scoring cards
ah gotcha
also is that the right way to put a message under a triggering joker?
yes, but it won't retrigger the cards
cause currently not getting anything when i play one card with this updated
i know that much
also what you want is context.individual, not context.joker_main
ah
whats the error?
fixed it
It does do the text now!
now to make it repeat
I've been looking at the script for Neato's Hatsune Joku without much luck
Is there a function for checking if a playing card has an edition, or what edition is has? I've been looking for a bit and can't find anything
card.edition
if it's empty it has nothing, if not it's edition = {negative = true}
so just check if card.edition.negative / anything ==true
to set an edition just use card:set_edition
example
idk what the second arg does
all good, thank you so much
figured it out
So i'm completely new to coding all together. No prior experience. Trying to create my own joker. I understand everything I have down currently, but I'm not sure how to actually implement it from here, any advice? (It's not meant to be balanced, just a first time project)
I think your next step is making the calculate function of the Joker:
https://github.com/Steamodded/smods/wiki/calculate_functions
Also a teeny-tiny typo: I believe unLocked should be unlocked
Do you know if it matters? It shows both variants whenever I type it
but also, thank you!
@mossy ivy Moving the convo here since this is more about "how to make a mod"
Briefly if you wanted to use them, you would make a mod for either Steamodded or Steamodded + Malverk.
For the pure Steamodded approach, you can provide alternative Localization files to overwrite the names - puten-us.lua file within the localization folder containing your new names, using this format:
https://github.com/Steamodded/smods/wiki/Localization
This could be as simple as
return {
descriptions={
Joker={
j_vampire={ name="Werewolf" }
}
}
}
``` if you just wanted to rename the Vampire joker to Werewolf, for example.
Replacing textures with Steamodded is more complex, but you can read through the SMODS documentation here to find out more:
https://github.com/Steamodded/smods/wiki/SMODS.Atlas
Alternatively, Malverk makes things way easier. It can replace both textures and localizations in one go, using something like:
```lua
AltTexture({
key = 'joker',
keys = { 'j_vampire' },
set = 'Joker',
path = 'MyMod_Joker.png',
loc_txt = {
name = 'My Custom Werewolf Joker',
text = { 'Werewolves', 'not swearwolves' }
},
localization = {
j_vampire={ name="Werewolf" }
})
- You can find more on this guide:
https://github.com/Eremel/Malverk?tab=readme-ov-file#using-malverk
and look at any of these for good examples of how to define replacements:
https://discord.com/channels/1116389027176787968/1342187005244866700
https://discord.com/channels/1116389027176787968/1338027978935763055
https://discord.com/channels/1116389027176787968/1323027321825001604
https://discord.com/channels/1116389027176787968/1236675603495653416
Only responding because I'm literally incapable of not answering questions, but for your purposes it's almost definitely easier to just replace the files in the exe and call it a day
Quick question, is there a flag that checks if a Mr. Bones saved the player in the run? If not, is there a way to add events to existing jokers or replace them with a rewritten version of them?
goated
Fr
See the thing is though
I've tried to do the easy way and got an error
Which literally doesn't make any sense
Is this is you opening Balatro.exe as an archive and dragging the replacement files in?
Yup
Balatro definitely isn't running? Ctrl+ESC doesn't show it?
Nothing but peazip and dolphin
Hmm. I haven't tried this myself, but you could~~ try extracting Balatro.exe as an archive into a different folder, making your changes there, then creating a new .zip file from that folder and renaming it to change it's extension back to .exe~~
Making sure that you create a zip archive specifically, not 7z, gzip, tarball or anything wacky
No, this is unlikely to work, there's too much additional header data that gets stripped out when you do this
Try making a copy of Balatro.exe into a different location, double-checking your permissions, and possibly using a different archiver program
Alrighty I'll try that. I honestly don't know of any other good archiver programs(not that the one i was using was even good in the first place)
How to make a joker function where each time an Earth card is used, it scales up?
laziest possible "JOKER" text placement lmao
ways in which i cheated w/ this joker sprite:
- used campfire's darkest color as well as normal black because i couldn't find a nice dark grey and i figured it's a different kind of card and all
- shamelessly and messily copied the card design from seven different svgs (the claw thing has seen better days)
- put the "JOKER" in some random empty space rather than considering how to incorporate it into the design in a more clever way
looks pretty cool as a negative though
just noticed the misplaced pixel in the bottom right. lmao
lazy? here
-# maxwell's notebook not by me
bump
So uhh why is the last one not showing a 10 of diamonds
{'S_2', true},
{'H_2', true},
{'C_6', true},
{'C_8', true},
{'D_T', true},
},```
answer: I needed to start a new run for changes to take effect
Probably with context.using_consumeable and checking if context.consumeable is an earth card
how would i check that? i know i would need the cards ID or something like that
Honestly whatever method you see fit
i love the art i did for the card though, the negative looks amazing
UI
How do you guys make such good art. Mine is tragic 😔
anybody know of a sample custom planet card I could look at?

