#đ»ă»modding-dev
1 messages · Page 221 of 1
anyone know why this results in 'attempt to index field "colour" (a nil value)'? i am very stupid with balatro modding pls be patient with me đđ
what's the full error log like
one sec i caused another error while trying to do something intentionally wrong
đ
This error is usually caused when a UI element expects to have an args.colour value but nothing was assigned. Could be anywhere
đ
its still on oldcalc
well its not in the description thats all i know
Alright, so in engine/ui.lua when initializing a UIBox, it first calls Moveable.init(), but butchers args.T in a way that means Moveable.init() will never actually use the contents of args.T.
function UIBox:init(args)
--First initialize the moveable
Moveable.init(self,{args.T})
```and
```lua
function Moveable:init(X,Y,W,H)
local args = (type(X) == 'table') and X or {T ={X or 0,Y or 0,W or 0,H or 0}}
Node.init(self, args)
Does anyone forsee any issues if I patch fix this? Is this behaviour that other mods are likely to depend upon?
Or maybe it's better if I entirely write my own init instead
It's not as long as I thought
how can I check If a joker has been triggered.
what are you doing đ
Im trying to make a joker that gains +1 mult every time a joker is scored.
This is what I have so far
Right now it is gaining 1 mult for every joker
I don't know what the context is
do you have any sort of schema or anything set up?
i've been struggling with this too, i was looking at context.post_trigger but there's like virtually no documentation for it cuz it's new so it's not been working
i'll let you know if i find a solution
Nah this is literally all I have
I'll try that
i dont get it
its just not working for me, i'm not even getting autocomplete for toml, I'm just getting syntax highlighting
very weird
did you set up any workspace settings or changes to your plugins that got the toml autocomplete working?
I am so confused
I have this joker and its works well...
But this not fully works with the Oops! joker because its doubles only when adding and removing from joker slot
How can I fix this so that the points from the HUE joker don't conflict with the Oops! joker?
I think your best bet is either to check for the presence of Oops all Sixes, and have a separate counter that doubles the probability gained afterwards, or to write a patch
Change the Joker to multiply the probabilities
how do i make a consumable that generates a specific card
i'm making a mod around the chemical elements
What type of card
another consumable
Not too different from how vanilla does it but SMODS provides add_card as an utility to help
Check the wiki
does anyone know how to detect when a card w/ a seal is destroyed? im trying to make a seal trigger some things when its card is destroyed, but im a fair bit new to balatro modding
hmm, what's G
G.play i think? should it be differnt?
oh oops meant that as a general question
ah lol
you can check the remove_playing_card context, and then check if the card had a seal!
oh! thank you!
I do think you may need to check separately for hanged man destruction đŹ
I came up with something that could be done.
Let Hue golden joker give 2 times more if there are oops all sixes in the hand
And I haven't tested anything like it myself yet, but I also think spectral cards that destroy cards don't trigger it? đ€

i try it out and report back đ«Ą
It's not that difficult and overall it will work.
only issue is that it wouldn't remove that when sixes is sold, right?
If you sell the sixes, then as usual it will decrease by 2 times

Oh wait, you're adding straight to the global, yeah than that works!
clever effective solve!
It will be quite interesting to play when I make at least all the jokers.
The only problem is to balance everything +-
balancing's a skill, and it's impressive that people ever learn it, honestly
I've been considering doing a devlog-esque thingy in my too abundant free time that's just me playing my mod and taking notes on balancing, just so I actually feel motivate to do it, haha
To balance, it is enough to look at the usual jokers and deduce the approximate rate of each type (probability, money, mult, chips, etc.)
Best way to balance things is just to play some rounds with it and see how it feels
some synergies feel stronger than they are, others feel weaker than they are. Make a good guess when you make the joker, and just play around with it
The industry wisdom is that players are good at identifying problems but bad at solving them
report: goal - make a seal do somthing when the card its on is destroyed
using 'context.remove_playing_cards' will trigger in any context where card is destroyed, wether in blind via somthing like trading card / 6th sense or in the hand that apears when using a consumable in a booster pack. like hanged man / immolate. but the condition triggers whenever any card in the displayed hand is destroyed, not just specifically the one w/ the seal, ive tried a few different things to limit it to the destruction of the sealed card, but idk lol
that's any creative field, honestly. Probably outside of it too đ In my dayjob, whenever a client has feedback, their own posed solutions are rarely ever an actually good translation. And in fiction writing, I also generally notice that readers rarely pitch an alternative that's better đ But what they're trying to change probably does need changing
You donât define removed
it apears i am occasionaly stupid - also oop didnt mean to interupt soz
nah you're more on topic, and I really appreciated the report back!
With fiction, I think people usually do both of the following: they suggest how the story could suit their tastes better; and they suggest assuming it would be well-written
because I have some non-coded jokers that I was gonna need that answer for, haha
Game design also has a strong psychological component to it
Sometimes you just need to change the dressing
And people flip their opinion even though in practice everything is the same
Would you rather be taxed for all but 1 option, or to get a discount for 1 option? đ€
part of why Obelisk is a controversial design, honestly. Resets feel bad, so the joker is seen as worse than it is
I mean, I donât use it because I feel like I have to change what Iâm doing only to inevitably pivot away
brb
i don't use it much either, but it's situationally strong, rather than weak, i'd say
I see it has a niche but since you canât guarantee to find it when you need it, Iâd call it weak
yeah, that's fair
I don't think a buff would be bad, but I think the reason a lot of players really dislike it is not because its niche, but because of how it feels punishing.
Well, just in principle anyways. I can also see the argument for it being strong in its niche. It depends on what is trying to be said
Personally I find the design counter-intuitive, so maybe âhard to playâ
-# ||also not a big fan of the art||
How can i get a count of current jokers in the joker hand?
As in, changing how you view your long term strategy and that you can eventually pivot out of it
You could count it manually, but I imagine thereâs some easier way. See Abstract
what do you mean by joker hand?
#G.jokers.cards gives you the count, no?
I think the right way to look at balancing is to look at general strategies than individual Jokers, especially as more Jokers are added
#G.jokers.cards
yeah, for sure. Card games aren't about the cards but about the synergies, after all
One complaint I saw recently is that thereâs only two consistent strategies to go to endless mode: Baron Mime and Perkeo Observatory
How to write this in code inside if?
???
What for?
Yeah, I'd say that is true. But I also think that's misjudging the game as being balanced around endless, rather than ante 8
But for mods, I do think it's something worth solving
Itâs not misjudging the balance, itâs expressing a personal preference
But also itâs not asking for Jokers that break the game harder, itâs asking for more variety in how to do it
Yeah, fair
So the difficult part is introducing new synergies without making them too common
It's a hard line to walk. The more varied endless options there are, the easier beating ante 8 becomes, I reckon
For my joker I need to know how many sixes jokers there are to add the probability correctly #đ»ă»modding-dev message
Thereâs an âeasyâ way to do it without making earlier antes easier
A system identical to Legendary Jokers
You canât find them in the shop, so the entrance point is heavily gated
Which also touches on my opinion that I think Legendary as a rarity is poorly designed for what it is
Flavorfully itâs great, but the juice isnât worth the squeeze necessarily
Whatâs a sixes joker
"Oops! All 6s"
Ah youâre making a Joker that changes probability additively
Donât
Thatâs my suggestion
Do it multiplicatively
That way itâll also work with mods
đ
how can i add a new card type?
Probably doesnât like the
What type
I like the way legendaries work in vanilla. It's not as great a mechanic when mods start increasing the pool, I find. Especially when legendaries are synergy specific, which makes finding it when you're not aiming for that build a feel-bad
Exactly
one similar to a stone card
I think I forgot to say that for vanilla, Legendaries work
Because theyâre heavily curated
I don't want to make a multiplier because then the essence is lost
So you donât see the issues
soooo
yeah like that
What essence
i wanna code my mod but i dont wanna code my mod
ok
depression v_v
Anyways if you just wanna count O!A6s you can use find_card provided by SMODS
I won't be able to explain it clearly, but maybe it will become clearer
Not much
You can try dividing by the current value
I haven't figured out exactly how I wanna do it, but it's why I'm changing the way Legendaries spawn for Kino's legendaries. I want them to be able to spawn if you're meeting certain requirements. I'm thinking of having you match ~3 meta elements of the legendary joker for it to be added to the rare pool. So if your current movie jokers have an actor, director, genre, release decade or so shared.
Then multiplying it back later
I might add keyword to that, to make them easier within synergy, because currently, the spawn conditions for the legendary Rattatouille joker don't really cater towards builds that benefit it
Iâd say maybe make a different Rarity, just for consistency with other mods.
I think in terms of âstronger than rare but nicheâ, it ought to be a Super Rare rarity.
Personally, I try to design Legendaries that change how you play the game
So theyâre always relevant
Yeah, internally at least, they'll for sure be their own rarity. I might make it a config option to allow them into the soul pool
My preferred legendary design is generally good, nichely fucking amazing
Soul Joker
hahaha
I have 1.5 Legendaries so far and a few in the works
The 0.5 is pending a slight rework
The question was how to find out the number of identical specific jokers
I also want to give them unlock conditions
And a Joker that makes finding one of them easier
iterate over G.jokers.cards and just check if they're oops all sixes
I already answered tho
why didn't I think to have a joker for Soul that actually does something with the Soul card??? My current WIP version spawns a negative and quickly perishable version of a joker that's been destroyed this ante
Thereâs a built-in function for that
oh
yes i realized as soon as you said it. I never even do what I suggested myself đ
I need to think twice before giving coding advice đ
But doesn't find_card return a true or false value, rather than a count?
The only legendary I have code for currently is the Indiana Jones one, which is a stacking version of the Idol. Though I haven't tested it enough to know whether it's fun or feels like it's worth it
uh drunkard
My Legendaries so far are:
Jagganoth
After you play a hand, play it again
If you canât, DESTROY IT
And the 0.5 pending a minor rework
Solomon David
Keep remaining Hands
Every Blind is a Boss Blind
Table
Oh, that Solomon David does sound fun
Solomon already kept the remaining hands, Iâll just change the code behind it. The condition is different though
I do think maybe that's better suited for a deck or challenge than a legendary, though đ€
Itâll either be making everything into a Boss, or making every Boss into two Bosses
Well, I do want Legendaries to change how you play the game
what does play it again mean in this context?
âYouâre in my world now, not your worldâ
What do you think it means
-# I prefer asking before responding
I'd say just a really fundamental level of retrigger, basically. But the 'if you can't' implies to me that it'd try and play a hand of the same type from cards in your hand
Hmmm no
It takes the same hand and plays it
Oh, you played a hand, letâs play it again
Oh, you played a hand, letâs play it again
My current planned legendaries are Barbie, Rattatouille, 2001: a space odyssey, Indiana Jones, and The Avengers. I might add Citizen Kane too, but I haven't seen that movie in years, and don't have a good concept for it, but I do want a b&w era representative in the legendary pool.
Oh, you played a hand, letâsâoh, youâve won. Goodbye, cards
Aaah, that makes more sense
Alternatively, you run out of hands and lose
Is winning the only context in which you wouldn't be able to play the hand again đ€
I guess certain modded boss blinds?
The wording would definitely have me confused, currently
As I just said, if you ran out of hands
Well, itâs meant to be interpreted literally
I know people would struggle with it
But I hope theyâll at least recognize the Joker did exactly what it told them itâd do
This card is supposed to gain +4 Mult every time a glass card is played, but ends up getting +8 instead. Anyone know why this is?
âAfter you play a hand, play it againâ
It triggers upon playing a hand, and it itself plays a hand
So each time you play a hand, it costs an additional hand
It costs all hands
The wording does say exactly that, that's true đ
Because it keeps triggering itself
I suppose if you played only Glass they could break and it would stop before all were played
Ah, I guess I interpreted 'you' from a humanist perspective that implies the existence of the soul đ
You can interpret it that way. It says âplay it againâ not âthis Joker plays it againâ, or âthe game plays it againâ
It forces you to play it again
Automatically, but you
Yeah but in that case the wording does run into Balatro using shorthand. But I don't think that's fundamentally an issue
Either way, this Joker should be locked behind a Boss Blind that applies this effect
Context.before is called multiple time in calculate, you need to add more context check but rn I dont remember which one
ok
yeah i've tried a few things and i'm also not sure
Check the SMODS wiki on the github page on the calculate point, see which context refers before
alright
i've noticed that if the played hand contains more than one glass card the mult isn't given
how do i fix this
don't break inside the for loop and also only return after the for loop if has_glass is true
the break I added before was because it stopped when it found 1 glass card, if you need to find all you need to get rid of it
ok
i've also seen that the hand is played before the upgrade is given, which is weird
oh, because you're calling it in final_scoring_step which is... the final scoring step
shit
accidentally pressed undo too many times probably
i remember setting it to joker main
if you put it in joker_main it will not reach the second return
so context.before then?
probably
ok thanks
that is usually when upgrades happen
reading through the way cardareas function, and am I right into thinking that the deck cardarea actually displays and contains all cards in it? That's not a visual trick, but an actual stack of your cards?
it does indeed contain a real stack of cards
fascinating
I fully assumed it'd just be sprites of the back, but then I was surprised by not being able to find where it turned the display for the cards off
how could i test out custom stickers? apply it to what i want anytime preferably ingame?
DebugPlus
for custom stickers you do not to add some code to debugplus yourself to apply them, iirc
cant see sticker in debugplus keybinds
ASD for Eternal/Perishable/Rental
i missed the custom part ;-;
Help. The text isn't vertical idk why aaaaa
assuming you have debugplus you can run eval dp.hovered:add_sticker('sticker_key', true) when you hover a card
still cant wrap my head around destroying cards, can you do it at the end of a round
while doing a check for the card to be destroyed
the UIT.R and UIT.C are reversed
Hello fellas, I need a bit of help. I'm making a consumable that halfs the current blinds chip requirement. However the UI doesn't update, any way of fixing that?
key = 'Bewilder_untarot_uncounter',
set = 'Bewilder_untarot_type',
loc_txt = {
name = "The great uncounter",
text = {
"{C:attention}Half{} the blind's ",
"{C:chips}chip{} requirement",
},
},
discovered = true,
pools = { ["tarot"]=true },
config = { extra = { time_blind_by = 0.5, }, },
cost = 4,
can_use = function(self, card)
if G.GAME.blind.chips then return true end
return false
end,
use = function(self, card, area, copier)
G.GAME.blind.chips = G.GAME.blind.chips * card.ability.extra.time_blind_by
end,
keep_on_use = function(self, card)
return false
end,
}```
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
I'm working on my abduction mechanic, and I know I need to make a new card area to store abducted cards, but I'm trying to figure out specific behaviours of cardareas to see what the best way to go about it. I'm considering either making a general 'G.abduction' that contains all abducted cards, and then just marks each card for its abductor internally, though that'd require that I'd have to iterate and check each abducted card each time I go in there. The other option is to make it so that jokers that can abduct cards create a card area when you buy the joker and have a dictionary of abduction areas with the specific jokers as keys đ€
I'm wondering if giving a card a cardarea as a child (which is as a default set to invisible) is going to create potential issues
It's not going to be saved on reload I'm pretty sure
Aaaah, that's good to know
does time variable in shader not update in real time đ
I should check out how the save function works at some point, because I think Confections run into problems with it too.
I guess making a general cardarea, and then just tying card behaviour to that is probably the best way to go.
how do i check a jokers rarity?
card.config.center.rarity
Thank you, that worked perfectly
The base game declares every cardarea with 0,0 to start with. That's because it's actual position is set later by another function, right?
which variable are you using?
for now i want a texture to do this
but it doesn't rotate in game
like live rotation
yes
are you not using the second property of your shader name variable for time?
i mean i just copied it from debuff as a base
my end goal is to make it look like this
do sliced.y
a
that'll be G.TIMERS.REAL
is that a vsc extension you're using to see a live render of your shader?
glsl.app
the "time" value is this 123.33412*(_draw_major.ID/1.14212 or 12.5123152)%3000
I don't know why this is named time
oooh, sick. Thanks aiko
Not sure if this is going to be a good idea or just another 15th standard thing, but what if we replace G.GAME.probabilities.normal with a function, so that any joker/etc that alters probability in one way or another can just define something like calc_probability = function(self, card, prob) and then define a global function function get_probability() if G.jokers == nil then return 1 end local probabilities = {normal=1} for _,J in ipairs(G.jokers.cards) do if J.config and J.config.center and J.config.center.calc_probability then J.config.center.calc_probability(J,probabilities) end end return probabilities.normal end
Anyway, this is what I'm going to do in my mod.
is it possible to retrigger cards entirely as if it wasn't a retrigger
sounds like the same thing with extra steps
you could probably do that in-place with metatables though
Gotta spend some time learning about metatables, I guess.
What happens if you add more vars to the vanilla probabilities? Will the game break?
I think nothing bad would happen if you stop there, since the game usually only access normal.
If I want to integrate my functionality into a vanilla variable in this way, without touching "normal"

Yeah, I believe you should be able to do that.
Just have to remember the nil check, though.
If I'm moving a playing card out of the deck and into a separate card area, just calling G.deck:remove_card(card) would still keep that card contained in G.playing_cards, right? So I would need to remove it from that table still?
Tell me if you know how to check the availability of a certain joker and its quantity in the hand
Please 
I'm seeing that the Remove() function iterates over G.playing_cards after removing something from the table. Is that to set the indexes right, so instead of a gap at the removed spot, the count is correct?
SMODS.find_card("j_joker_key")
Does this return a boolean or a number?
a list of all the ones you have
why is it so smol?
thx
And how can i get count from the list?
# gets the length of a list
how, I hardly know Lua
#SMODS.find_card(...)
if you put # before a list, it'll return the length instead of the items inside the list
# returns quantity?
yes, it returns a number indicating how many values are in a list
help
try minh and minw maybe idk UI is like sorcery
it's not encouraging to see you say that đ
Problem is that it gets pushed outwards when I have stuff inside.
Like the menu simply gets larger the more stuff I put inside it.
I just copy what worked before
well yeah
still don't know how
is it possible in the first place
I think it sounds interesting 
destroy the leftmost card held in hand at the end of the round
does G.hand.cards[1]:start_dissolve() work
Take a look at the Lobotomy Corp mod, several of the abnormalities destroy cards
Can I make something like this as an edition and not a separate joker? 
take a look at lobotomy corp but because it's rad
And will it be much more difficult?
it works but the effects trigger like 30 times lol
try this
i can't tell how to actually get this to work
i want the card to trigger upon a hand with a 3, 6, and 9
you're checking each individual card, and whether they are a 3, 6 and 9. No single card will be both a 3 and a 6 and a 9
you want or instead of and
Also, "in the same hand" is kinda redundant, to be honest.
Ok.
eh, give or take
without it, one could think 'oh, if i just play a 3, 6, or 9 im getting mult' and not think it required them together
Unless you want them only be triggered if a played hand has more than one card with ranks of 3, 6, or 9.
Yeah, like that.
once again adding niche functions to maybe reduce lines my jokers take up by like 2% :3
oh god I have spent a day working on a cool ass shader for a Risk / Reward style glass card idea for a special edition card. And I just now realized that enhancements don't support shaders without me doing a lot of extra work
yeah so i changed it to "or" and now it triggers if only one of the three is played
So someone could...get by edition applied ontop of a glass card for something truly unhinged
to be fair 2% of your line count is not a small amount lmao
fair â€ïž
i support your efforts
I am in love with utility and guard functions
i am in love with poor practices myself
i have a whole different file for functions :3
no localization file my beloved â„
(one day i will fix this)
ohhh i get it
you don't want context.individual for that effect
đđđđ
meanwhile half of my loc_vars use the weird [0] syntax while the other half use string concatenation
whats going on đ
im gonna need you to speed up your freaking game fam
out here waiting years
Soon you will just be mining meme coins in your jokers
I'm at 4x
this dont feel like no 4x
if the game is running at 4x speed we just need to add 4x the effects, animations and joker popups to compensate
now it crashes if i play a hand with all 3, do i need to change other_card to something?
yes, how does the code look now
it feels so slow still, at 4x my cards score significantly faster
but either way i fw ur ideas
oh you need to add another context still, probably context.joker_main
and you need to iterate through context.scoring_hand like you did with glass cards
ok cool
Im trying to create a random playing card with equal chance for all seals, editions, enhancements and lack thereof but instead of the card being added to the deck it gets created on the screen and it kinda just stays there?
Where is the behavior of where glass cards are handled? I am hunting all over for it
vanilla behaviours aren't really centralized
I am reimplementing it on my own with a twist and wanted to know how it determines it it's going to oof itself
If I had to guess, I would say it has a calculate set to context.after and context.individual where it checks probabilities
You'll need to G.deck:emplace(isocard)
do i replace the context.cardarea with scoring hand or is that wrong
them breaking is done in state_events.lua
remove the cardarea check entirely
aight
thank you!
SMODS, src/utils.lua line:1653
interesting, their behavior isnt in the enhancemet logic at all.
how am i supposed to check for it then? the one i used to check glass cards only looks for enhancements
Oh, considering you're using SMODS, I think it's handled in the SMODS.calculate_destroying_cards calc now
like you were doing with get_id
i wonder if this is even useful đ
(that one function replaces what i turned into comments)
unnecessarily convoluted code đŁïž
this is what i did for glass, should i do this agai
Sweet I have discovered yet another self inflicted problem. I copied something and forgot to change self to card
n
i have a ton of functions that are just one boolean condition
the created card doesnt seem to be permanent
75 lines function
in place of uhhh
6 lines
â€ïž
probably will be worth it on the long run, idfk
you want the same for loop but you need to change the rest
alright
it gets added to the hand but not the actual deck
@frosty dock funky!
hmm, do you see what i am doing wrong here? I am getting this error
(*temporary) = Lua function '?' (defined at line 31 of chunk [SMODS _ "src/logging.lua"])
(*temporary) = string: "Oops! The game crashed\
"
(2) L..VE function at file 'boot.lua:352' (best guess)
Local variables:
errhand = Lua function '?' (defined at line 598 of chunk main.lua)
handler = Lua function '?' (defined at line 598 of chunk main.lua)
(3) global C function 'ipairs'
(4) Lua global 'init_localization' at file 'functions/misc_functions.lua:1695'
Local variables:
(for generator) = C function: next
(for state) = table: 0x16d81a68 {descriptions:table: 0x16d81ac8, tutorial_parsed:table: 0x16fc78e8, quips_parsed:table: 0x170be360 (more...)}
(for control) = number: nan
g_k = string: "descriptions"
group = table: 0x16d81ac8 {Back:table: 0x16dc2508, Tag:table: 0x16928610, Blind:table: 0x16dc3160 (more...)}
(for generator) = C function: next
(for state) = table: 0x16d81ac8 {Back:table: 0x16dc2508, Tag:table: 0x16928610, Blind:table: 0x16dc3160 (more...)}
(for control) = number: nan
_ = string: "Edition"
for this edition code
key = "fragileRelic",
loc_txt = {
name = "Ether Overdrive",
label = "Ether Overdrive",
text = "{X:mult,C:white}X#1#{} Mult",
"{C:green}#2# in #3#{} chance to destroy card"
},
discovered = true,
unlocked = true,
shader = 'etherOverdrive',
config = {
x_mult = 3,
odds = 3
},
in_shop = true,
weight = 80,
extra_cost = 4,
apply_to_float = true,--false,
loc_vars = function(self)
return { vars = { card.config.x_mult, G.GAME.probabilities.normal, card.config.odds } }
end,```
you're gonna wanna send the entire code, instead of just a fragment of it đ
Then I'd recommend you to try use this instead.
Commenting out that edition does let the game load gain, so I think my problem is definitely in here somewhere
key = "fragileRelic",
loc_txt = {
name = "Ether Overdrive",
label = "Ether Overdrive",
text = "{X:mult,C:white}X#1#{} Mult",
"{C:green}#2# in #3#{} chance to destroy card"
},
discovered = true,
unlocked = true,
shader = 'etherOverdrive',
config = {
x_mult = 3,
odds = 3
},
in_shop = true,
weight = 80,
extra_cost = 4,
apply_to_float = true,--false,
loc_vars = function(self, card)
return { vars = { card.config.x_mult, G.GAME.probabilities.normal, card.config.odds } }
end,
sound = {
sound = "Fox_ghostRare",
per = 1,
vol = 0.3,
},
calculate = function(self, card, context)
if
context.joker_triggered
or context.from_consumable
or (
context.from_playing_card
and context.cardarea
and context.cardarea == G.play
)
then
ease_dollars(self.config.dollars)
card_eval_status_text(
card,
"extra",
nil,
nil,
nil,
{ message = localize("$") .. self.config.dollars, colour = G.C.MONEY }
)
return {
message = localize('k_again_ex'),
repetitions = 1,
card = self
}
end
end,
})
so close yet so far
purged
how do i reset card ability to its original value :P
it's surely gone from existence
n vm i think i might figure something out
so cardname:create_playing_card()?
ill look it up on smods, thank you!
your loc_txt has text that should be wrapped in {} brackets
Found my issue
So i add this to my main.lua and call it when necessary?
Ah thank you for looking, I was just coming back to say I saw the issue when I compared this edition to my other editions which work!
that's a thing specific to my mod, you can check if it does what you want
i sent it because i use create_playing_card there
ah, i see
yeah idk
please format your code
the error tells you what went wrong. In this case, it's saying you're attempting to call a field that's nil. That makes sense, because you're trying to call a function. The difference there is that you need to do SMODS:has_card()
what would i do if i want to uhhh add more text in playing cards' description
like how Hiker adds +15 Bonus Chips or something
what do i use then
i told you, what you were using was fine
ok
hahah jeesz, good point, I just assumed
I should think before giving advice, proof #2
not your fault haha
if it was what you said it would have said something like attempting to index self
bit my fault, but luckily not fully mine đ
Is this wrong here?
https://github.com/Steamodded/smods/wiki/calculate_functions
{
cardarea = G.play, -- G.hand, (G.deck and G.discard optionally enabled)
full_hand = G.play.cards,
scoring_hand = scoring_hand,
scoring_name = text,
poker_hands = poker_hands,
destroy_card = card,
destroying_card = card -- only when calculating in G.play
}
I think this section should be changed to
if context.destroying_card and context.cardarea == G.play then
{
what are you wanting to do?
my jokers can inflict debuffs on playing cards, which allow other jokers to have stronger attacks
so uh
the perma values page on the wiki says how to change the localization for the text but i dont think you can add custom text
i want those playing cards to show exactly what debuffs they got
figured it out apparently it's just whatever was in the joker calculation page of the docs
so, it would probably be something like
Queen of Spades
+10 Chips
Affected Debuffs: something something (+ blah blah)
when a debuff is inflicted
im thinking about enhancements, like how lucky cards add a ton of new lines into the description, though im not sure where the code to do that is
Well I have done something weird to myself
My consumable appears but I cannot use it!
did you add code to can_use
this thing
it should always be a function, if it returns true then the consumable can be used
Thanks! I have this function here, I don't remember what I was trying to do with it
can_use = function(self, card)
if G.STATE ~= G.STATES.HAND_PLAYED and G.STATE ~= G.STATES.DRAW_TO_HAND and G.STATE ~= G.STATES.PLAY_TAROT or
any_state then
if next(SMODS.Edition:get_edition_cards(G.jokers, true)) then
return true
end
end
end,
uhhh
im guessing it adds the editions to jokers specifically?
oh, but i thought you can only highlight 1 joker every time?
-# or am i missing something here, i actually dont know how this is supposed to work
I forgot I was even trying to do that! Ok I removed that and am good. Now to see how my logic crashes the game too!
im guessing what your consumable do is applying an edition to a highlighted joker
but two actually doesnt work unless you tweak some other stuffs by increasing the number of jokers you can highlight, which i kinda advise against
after searching for "lucky" through the entire balatro folder
i still cant find it
im probably too dumb for this đ
this MIGHT be it, but im not sure myself
tried this in a couple ways, game crashes and claims it's a nil value
s_card:get_id() is a nil value?
apparently so??
also, you dont have this "do" part
does start_dissolve() always go first before message
i want them to be at the same time
for _,v in ipairs(context.scoring_hand) do
if v:get_id() == blah blah blah
end
and also, unrelated, but fix your indentation â€ïž
return func = function() card:start_dissolve() end
-# at least its not as bad as peak
same error as usual
because you're not checking for a context
you need context.joker_main or something
I recommend heavily to look at the example mod
i keep reading about this kinda stuff but none of it ever stays in my head
yeah i have been
sorry for bothering, but do i need to patch this if i want to do the uhh add new lines to playing cards' description stuff đ
your old code had "context.before", which was correct
all you had to do was just replacing the content inside it
a lot of this is coming to trial and error for me really as there are so many things that have to be changed around and whatnot
you would never bother me
and yeah probably but by that point I think it's better to make an enhancement instead
you will get the hang of it when you get enough errors, you shouldnt be afraid of crashes at all â€ïž
UI will be my fucking death đ„Č
i'm not afraid, just more slightly annoyed
i love UI i wish balatro didn't have gameplay and it was just UI
oh, so like an uhhh, collective enhancement to show the debuffs?
but wouldnt it conflict with pre-existing enhancements, like Glass cards or something
doesn't smods have quantum enhancements
you can also make stickers
oh yeah, forgot about quantum enhancements
do their descriptions stack upon each other though
or its just their effects, while the description has some sort of priority going on
I would guess so, but never used them
welp, its worth a shot i suppose, or alternatively i can just let players blindly calculate the debuffs they inflicted â€ïž
quantum enhancements don't change the descriptions, as far as I'm aware. though I've removed any reliance on quantum enhancements because it caused a lot of bugs for me
đ«
i'm sure the error is an incredibly easy fix i'm just failing to see
welp, fuck me sideways i suppose
i think stickers and info_queues would look better anyway
I'm trying to figure out how to make a display atop of the joker, and god the amount of nodes I need to just display a sprite and some information. And I can't even see how the coordinates impact the placement until I launch the game
remove "SMODS." and change "s_card" for "v"
also you need "or" not "and"
hey so there's this mod called jokerdisplay
haha, I'm browsing your code already
it's basically just adding a UIBox child to the joker
Once Kino is finished, my code will just be your code with some variable names changed. I also checked your graveyard and banishment implementation to check how you did new cardareas, and I'm also quite sure JoyousSpring's got the best example of a toggleable card area, so I'll dive into your code again when I'm implementing the snack pack, haha
hmmm, how do i
add info queue to playing cards?
The main issue with ui is the amount of information that's passed on in shorthand
i think stickers do that by default
idk how you do it without that
if i use "or " instead of and, will it still only trigger if the hand contains a 6 and a 9/
you can Card:loc_vars to check for debuffs on a card, and pass those to an info_queue
damn, but if there were a LOT of debuffs (look at this), can the sticker's info queue dynamically change
yeah, you have to take out the return from there
alright
if it needs to contain all of them then you need booleans for each value
stickers are weird objects, which makes them super versatile, because they're really just a bare bones info queue and sprite
it can probably change yeah
alright im new to balatro modding and all i want to do is change the graphics of a card enhancement, how could i do that
i seeeeee
i can just make the stickers having no sprite right :3
thats very useful, thanks everyone
the only issue I think is that stickers don't have ability fields or anything, but I do think you can have them read out the information that's on the card they're applied to
yes, that's how the pinned sticker works
pinned is a sticker? i guess it makes sense
for my jokers to read
Stickers are weird. They're really a support object that allows you to toggle variables and get a sprite to possible go with it, honestly. I made a custom sticker set for Confections, just because the sticker back end works for it, but their functionality is really largely separate
do yall have any tips on how to code a mod on a mac for someone who knows basically nothing about coding lmao
i have a big idea and am very bored
-# damn it, that was the perfect opportunity to release the copypasta
For jokerdisplay, are you update_joker_display() in card:update() to keep it on the screen, or is it for dynamic text reasons?
for text
damn.
If you want to see an example, Kino has stickers
i am NOT touching cryptid, no offense, it usually only works because of a shit ton of patches and hooks đ
looking at cryptid for references is hard
yup
ah
ah i see, thanks :D
Ah okay. I guess if I want the sprite to jiggle a bit, I'll have to tie it to the update function as well then
yeah so the crashes have stopped but now the mult doesn't get applied
isnt that juice_up
the jokerdisplay movement is tied to the card, so you would need to have a logic for movement in update yeah
can you call juice_up on just anything?
writing this from scratch instead of messing with the walkie talkie code was probably a terrible idea
a balatro mod for movie dorks. Contribute to icyethics/Kino development by creating an account on GitHub.
vanilla code isn't really comparable with how you structure your own jokers, so it's not a bad choice to start from scratch.
yeah ive realised that now
i think adding mult in context.before doesnt work very well
someone told me that before
any moveable apparently
my issue was really stupid actually
hey lads i want to make a mod that changes the sprite of stone cards, how do i do that
i apparently forgot to capitalise something or other
I'm not using the loc_vars on any stickers, btw, but I think you can just pass the parent to it through there
im very inexperienced with stickers so i might post some dumb questions relating to them here đ
that's worth keeping in the backpocket for when I want to shake a cardarea, I guess
i will try that
the most important thing with stickers is that every time you say sticker, you have to follow it up by saying 'sticker? I hardly know 'r!'
i will tag the mods
tag the what
hehe funny
uh
stupid question
how do i do that
make it đ§ everything :3
use = function(self, card, area)
end,
i now have the strong urge to make a mod in which jokers have weight, and they can unbalance the joker cardarea and fall off
ok
and... how do i do the stuff in the comments?
is there some kind of card constructer?
now thats a good đ§
i think its in the Utils function section of smods documentation
i actually think it would be cool if a boss blind has a passive thats so strong it shakes everything like an earthquake đ
vertigo boss blind that makes everything juice up depending on your mouse velocity
is this how i do it (im thinking about removing the badge_color part too)
yeah that should work
im a bit dumb, how do i uhh change what text it should be showing :3
I am now realizing that I'm not sure stickers have access to their parent. Probably, that would seem logical, but let me check
if i can set a variable inside the sticker as the parent, and tell the sticker to check it, it should be fine
which should be simple as i can do that through apply
(i was dumb)
i forgot about this and it jump scared me
this shader tweaking is too slow, I am now just installing Love2d and learning how to do this properly
does this work for stickers
am i doing this correctly? i feel kinda bad
feature request: When I summon an archetype's boss monster, I need everything to shake
You need commas after each parameter
ohh yeah, it would be cool to see the entire game shake when you summon a high level monster
When I use 'Pot of greed' I need to hear Joey's goofy voice saying 'Pot of greed!?!'
create_card doesn't make playing cards
I opened a pack yesterday and actually drew a 'Ash Blossom and Joyous Spring'
headdesk
ok, which function do i need then?
create_playing_card
Is there any way to make a card's soul_pos sprite jiggle like The Soul's gem
...that is easier than this?
it's not an smods function tho
i just realized im not equipped with any knowledge regarding stickers, at all.
how do i apply stickers to cards??
For the unfamiliar, this card is a absolute staple and just another expression of yugioh powercreep
i love ash blossom
My son is little and loves Eldlich and dragons, I can't bring myself to use a card like this against him
if only we got maxx C...
we have the mulcharmy now
isnt it worse maxx C tho
card:add_sticker([sticker_key])
play mtg with him
its simultaniously more and less broken than yugioh
close, close
thanks!
There is a shader I saw on shadertoy of bugs...
uh
where do i find the documentation for that? đ
there's none i don't think
is this it
wait never mind i just realised i still need to add that other thing
actually wait, probably doesnt have the "s_" at the beginning
can jokers have seals
here is a Yugioh referencing shader I was working on. Warning for seizure folks
like if you forced one onto a joker would it work
...doesnt seem to show anything, hm
warning for epilepsy risk, shader is borked
I don't know, I will test it
I know for a fact using debugplus doesn't work but idk what happens if you force it too code wise
im so confused, how do i call the key of a modded sticker, s_modprefix_key?
Just modprefix_key
iirc
create_playing_card({front = G.P_CARDS[suit..'_'..rank], center = G.P_CENTERS.c_base}, G.hand, nil, nil, {G.C.PURPLE})
something from the pokermon mod
this doesnt seem to print anything
exceptionally not helpful lol
what are you confused about
Sorry but I can't figure out how to select a joker to act on
everything lol
that's what worked for me
dont even know what the purple is for
it's the color of the animation when it's created
One normal dev thing I would do is rely on external utility classes but I am still learning how these fragment shaders work. I want to not have this boilerPlate in everything I am working on
ghhh nothings working
boo, Love, the base game engine does not support includes yet đŠ
i hate how much pseudo code i am writing simply because i have no idea where to search
still does burn like a charismas tree
remove all the commas at the end
how do i reset card ability to the base value đ
you know what, giving up on this ui thing for now, and just doing it in the text box for the time being
it looks like you are making a tarot card, and you want it to add a random card to your hand or deck when used?
do i yank it out of the P_CENTERS
you can probably check the values in G.P_CENTERS?
does context.full_hand reference the played cards
something like that, specifically a red card with a red seal
nvm G.play.cards
both work
How to use degree in Lua?
math.rad() or something
:3
im actually not sure myself, did a lot of degree-related stuff back in roblox but idk about 2d
I was wrong, I was talking about the power of the number
oh
^
so like, 6^3 or something?
oh.
so its not card:add_sticker
this cat gif shall fully represent my emotions right now.
same
how do you start modding balatro? i couldn't find any guides
this should be applying x_chips on new calc but is only applying the x_mult what did i do wrong?
if config.newcalccompat ~= false then
Cubic = SMODS.Enhancement({
object_type = "Enhancement",
key = "Cubic",
loc_txt = {
name = "Cubic",
text = {
"{X:chips,C:white}X#1#{} Chips {X:mult,C:white}X#2#{} Mult",
"Idea: BoiRowan",
},
},
atlas = "Jokers",
pos = { x = 1, y = 17 },
config = { extra = { x_chips = 3, x_mult = 0.6 } },
weight = 0,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.x_chips,
card.ability.extra.x_mult
}
}
end,
calculate = function(self, card, context)
if context.main_scoring and context.cardarea == G.play then
return {
x_chips = card.ability.extra.x_chips,
x_mult = card.ability.extra.x_mult
}
end
end
})
end
STEAMODDED 1.0.0
A tutorial on how to make a modded Joker.
https://github.com/art-muncher/Example-Mod -- EXAMPLE MOD
https://github.com/Steamopollys/Steamodded -- STEAMODDED
https://github.com/WilsontheWolf/DebugPlus -- DEBUGPLUS
-----------------------------------------------------...
Balatro Modding Starter Pack, the copypasta :3
If you are new to modding, make sure that you understand the basics of LUA first before proceeding. There are a lot of good tutorials out there, so I won't link one here :)
For beginners, here are some links you should check out in order to familiarize yourself with what you are getting into:
- https://github.com/Steamodded/smods/wiki/Your-First-Mod
⊠This should give you some instructions, and it also serves as Steamodded's Documentation. Please read it :) - https://www.youtube.com/watch?v=Zp-4U5TlbxY&t=7s
⊠A Modding Tutorial video. It is a bit outdated, but generally does well at telling you what to do.
-# (Note: There are some parts in the video where they called cards "center". Don't do that, it's bad practice, they are cards.) - https://github.com/Steamodded/examples/blob/master/Mods/EditionExamples/EditionExamples.lua
⊠It's good practice to check out the example mods, as well as other mods too for reference.
Once again, remember to read the Documentation. There also other links which you might find useful, such as:
- https://github.com/ethangreen-dev/lovely-injector?tab=readme-ov-file#patches
⊠Patches. - https://discord.com/channels/1116389027176787968/1228149931257237664
⊠DebugPlus, a very useful tool for modding.
-# Sent: 7 times
LOL, I gave it a try and look what happened
im incredibly sorry, but im still lost đ
how's the code
what
lol
i initially thought what i needed to do was just finding the sticker object, and use :apply() onto the card, which is conceptually easy enough
where do find it
and i think im dumb for actually thinking thats how it works
SMODS.Stickers["key"]
Ok, I have a fully working tarot for you. Just mod it to suit your needs. One thing I did not handle was contraining the suit. So you could just write some little function to randomly give you either Hearts or Diamonds, then change the suit
that sounds good đ
wait i dont know how card comparisons work
how do you know if a card in hand was played
isnt that just checking for when a hand is played
if thats the case, context.before should suffice
context is already at end of round
actually
if my theory is correct and "card" here means the card the sticker is applied to
do i have to add info queue...
hm
go to sleep
i need to at least get them show text first...
i think this isn't enough i need the leftmost held card
no you don't
no i do
i NEED to get this working
else i will have nightmares about stickers
i cant be hunted by white stickers man
G.hand.cards[1] ?
at the end of round
yeah
apparently it doesn't do anything
oh i get it, you might need to do your own context
not looking bad so far
how do i refer to a modded sticker again...
-# now that i think about it, its the first time i used this
wait no i dont get it
we have collectively fried our brains i see
can i see your code
this
if you want to get 7h, i think you can do context.after
and uhhh
G.hand.cards[1]
like N' said
im going mildly insane
idek if this is right 
no
nope
anddd nope, thats not how you add a new info_queue box to the playing card either
ghghghghghghghghgh
calculate = function(self, card, context)
if context.end_of_round and context.game_over == false and not context.individual and not context.repetition then
local leftmost = G.hand.cards[1]
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
local copied = copy_card(G.hand.cards[#G.hand.cards], nil, nil, G.playing_card)
copied:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, copied)
G.hand:emplace(copied)
copied.states.visible = nil
G.E_MANAGER:add_event(Event({
func = function()
copied:start_materialize()
return true
end
}))
return {
func = function () leftmost:start_dissolve() end,
message = "Converted"
}
end
end
oh thats not it lol
the way you read the docs is that everything inside the brackets is what context has inside
I would suggest rereading the first part of the page
...welp
i guess it really comes down to this after all
im gonna read cryptid code đ
-# please dont be complex, for god sake
and what does this do?
like, what does it do wrong
When using Debug plus, how does the watch command work? I can't figure out the path syntax
Ah, I got it, it wants front slashes in the path! It would be cool if it swapped slashes so it would work the same in windows as mac
hi chat
so
i'm trying to make a suitless suit
what's the best way to go about this?
should i make a suit and then somehow assign the suitless property to it?
or should i use enhancements instead?
hook SMODS.has_no_suit to check for your suit as the base suit
maybe but still doubting
nevermind, that was the wrong place to look at
oh hmmm start_dissolve didnt work again
Good afternoon fr!
does anyone know how to do this? im horrendous at coding
returning func does nothing
for some reason
this is the sticker, just how did they add the info_queue
the info_queue is automatically generated based on the info in loc_text and loc_vars
yeah this is how it should be
I think hide_badge turns of the info_queue, no?
...it does???
oh my đŠing god i will go punch my fumos if thats the case
Any of you guys know how turn a joker into another joker?
like after it triggers
ADsadASKL IT IS
I'd have to check, but I have the info queue turned off for the confection stickers, which hide it, and turned on for the award sticker, which doesn't hide it
jonkler assimilatione
do any of u guys know how to do this please help
more like transformation

i have the perfect piece of code for this, wait
Iâm going to turn into a truck now
Smoking
W
Gotta build that smoke stack
he shlonkin' the buffoon pack
holddddd- what does this do actually? does it just change the ability or does it actually change the whole guy
joker:set_ability(G.P_CENTERS["j_other_joker"])
it changes the entire guy, i think
it does
here we go then
fun fact: the reason why cherry knows that (probably) is because of the exact message i took a ss of đ
Should I make the rats just chips or mult or both?
you could make it give either chips or mult, 50/50
yes
Yeaaa I donât think i should make it both
Maybe just chips
And money
Gotta sell those gutsđ„
its now this
That sounds so wrong without context
PLEASE HELP ME I DONT KNOW SHIT FROM FUCK
huh?
I'm quite sure that's from errors in your loc_text
yeah it is, i just realized in the localizations file i just put it:
key = {"text"}
without the name =, text = thingies
đ
SDASKLDMSADLSAMKL IT WORKSSSSSSSSSSS
a hook is done by storing the original function in a variable, first
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
that's probably better as a tutorial, haha
How can i change the chips?
rate the stone card sprite
From the joker
đ„
like, directly changing the Chips x Mult
^?
Maybe
:3 uhh its related to G.GAME something
ok so i got this
but like
I need to multiply the number of chips counted by the number
oh, so x_chips
what code destroys a joker?
return{
x_chips = number,
}
i want to understand how to make SMODS.has_no_suit look for my suit and recognize it
hi aiko
G.jokers:remove_card(card)
card:remove()
Can an edition completely change the behavior of a joker, card, or anything else?
Oke
i feel like im committing a crime haha
im not a fan of lua syntax so im compiling typescript to lua for a mod
oh, thats really cool
blursed
thats really nice
ty
but the bad thing about coding in an entirely different language compared to others is that asking for help can be significantly harder lol
true true
but thats super cool, i didnt know you can do that :D
me neither until now hahaha
Iâm going to eat a gros michel

aAAAAAAAAAAAAAAA
Bro is imploding
okay so i got this.
SMODS.has_no_suit = function(card)
end```
and now im lost
what now
dont worry aiko, ive been stuck on one singular sticker for the past few hours now
im as insane as you if anything :3
like how does this help with making the function check for my custom suit
i actually never used that function before, so i cant provide any help further than that
what are you doing
you can try reading the og function code and see if you can make sense out of it
dont do that
where could that be
just return x_chips
i think has_no_suit automatically checks if the card has NO suit at all
im trying to make a suitless suit
a birthday suit?
sticker man, how do you remove this :3
(it will be the LAST question i ask about stickers, i promise)
the error?
did you give up on the shader aiko
let me check, i'm not sure which badge funcs stickers have
There is no error, but nothing happens either
what version is your smods
1421a
â€ïž
i know
Mmmm gros michel


