#💻・modding-dev
1 messages · Page 307 of 1
the color for Xmult is {C:Xmult} right?
{X:mult,C:white}
that works
still trying to get the joker to add a spectral after a boss blind but still stuck.
SMODS.add_card it?
no way in hell is that a dr disrespect joker
theres probably grammatical error in there
will turn
for Dark Age?
will turns 
will smith in shambles
so its supposed to be add instead of create?
Does he? :3
oh boy
SMODS.add_card is SMODS.create_card, but it automatically emplaces and calls the add_to_deck effects.
Dark Age and Golden Hope
should that be it or is there more i'm missing
does never forget retrigger once or twice
Oh, you also are not giving it a table...
Just SMODS.add_card({ set = 'Spectral' }).
twice
i reworded it because
you know
they hit the second retrigger

😭
*retrigger a second time
that works too
thanks @iron haven @twin dagger
fuck
FUCK
@sonic cedar
Hold on, what did I do
i am SO sorry
you utter fool
No worries
no
Now we just need a ros I guess
okay. did that
🙏
can you use "context"s like you have for jokers in hook functions?
am i cooking
no, context is only passed to calculate functions
this is crazy broken
first time tryna draw 3d heavy stuff like this
hmm okay how would i do something like thi s
--Function to alter Joker effects
local old = Card.calculate_joker
function Card:calculate_joker(context)
local m = 2
local ret = old(self, context)
if not ret then return ret end
-- Dollars
if ret.dollars then
if not self.ability.base_dollars then
self.ability.base_dollars = ret.dollars
end
ret.dollars = self.ability.base_dollars * m
end
-- Mult: Xmult_mod, mult_mod, x_mult, h_mult, and mult
if ret.Xmult_mod then
if not self.ability.base_Xmult_mod then
self.ability.base_Xmult_mod = ret.Xmult_mod
end
ret.Xmult_mod = self.ability.base_Xmult_mod * m
end
if ret.mult_mod then
if not self.ability.base_mult_mod then
self.ability.base_mult_mod = ret.mult_mod
end
ret.mult_mod = self.ability.base_mult_mod * m
end
if ret.x_mult then
if not self.ability.base_x_mult then
self.ability.base_x_mult = ret.x_mult
end
ret.x_mult = self.ability.base_x_mult * m
end
if ret.h_mult then
if not self.ability.base_h_mult then
self.ability.base_h_mult = ret.h_mult
end
ret.h_mult = self.ability.base_h_mult * m
end
if ret.mult then
if not self.ability.base_mult then
self.ability.base_mult = ret.mult
end
ret.mult = self.ability.base_mult * m
end
-- Chips: chip_mod and chips
if ret.chip_mod then
if not self.ability.base_chip_mod then
self.ability.base_chip_mod = ret.chip_mod
end
ret.chip_mod = self.ability.base_chip_mod * m
end
if ret.chips then
if not self.ability.base_chips then
self.ability.base_chips = ret.chips
end
ret.chips = self.ability.base_chips * m
end
return ret
end
I am trying to
use a multiplier for each joker values
inspired from the Astral edition from Cryptid, since it was purple
but
i need to change the multiplier each hand played
and at the end i need to set values back to base
ok, but you can use context in the function that has context as an argument lol
i feel like thats obvious
i mean you said i couldnt...
hm.. still not working
cool though thanks
you asked if you can use it in a hook, i didnt know you were specifically trying to hook a calculate function lmao
ah okay that makes sense, i should have clarified, i didnt know if smod contexts worked directly with calculate joker functions like that
thanks
all the ones that go to jokers should work at least
makes sense
bump.
using this to try replace the shop sign but im an idiot and dont know if this is right or not coz it wont work lol
key has to be the same as the name of the file you're trying to replace, which is ShopSignAnimation
bear in mind that as this is normally instantiated as an animationsprite, you may encounter issues if trying to replace it with something non-animated
unless it's erroring
if it's an animation then shouldnt it have a thing for frame amount or am i dumb
How would I go about making a consumable add three random playing cards to the hand, with random enhancements and other stuff
See how "Familiar" and "Grim" spectral cards do it.
did you figure it out yet?
no 😭 i kept breaking it
How can I replace in-game localizations?
Are they located in card.lua
I think it's if pseudorandom(...) < G.GAME.probabilities.normal/(self.ability.extra*(next(SMODS.find_card("insert your joker key")) and 2 or 1)) (if I got those brackets right)
huhhhh...
Should.
what's the and 2 or 1 here
Look for elseif self.ability.name == 'Familiar' or self.ability.name == 'Grim' or self.ability.name == 'Incantation' then ...
I found it, but it's kind of confusing me on what is doing what
is there such thing as context.using_consumable.edition? im trying to check if the consumable used is negative or not
context.consumeable is passed as the consumable card.
my shop sign replacer wont work, can someone help lol
any idea how i can check to see if that card is negative?
if context.consumeable.edition and context.consumeable.edition.negative?
Okay reading this I can kind of understand it, but idk how to incorporate it into my consumable
is there a way to check what boss blind the player is currently facing?
hey, I'm trying to make an joker that, when a non-face card is scored, it gains + 1 on the value N, but it's gaining +1 for every card held in hand(like baron does), what am I doing wrong, sorry for interrupting you guys
if context.main_scoring and context.cardarea == G.play then
if not context.other_card:is_face() then
card.ability.extra.N = card.ability.extra.N + 1
return {message = 'Upgraded!',colour = G.C.PURPLE,card = card}
end
end
G.GAME.blind:get_type() == 'Boss' i know you can check for Boss blind like this
but how do i do it for a specific boss
this does not work
please help lol
G.GAME.round_resets.blind_choices.Boss is a string.
use context.individual
thank you, that string would have "modprefix_bossname" correct?
bl_modprefix_name
hey is this similar to ride the bus joker card?
awesome ty
yes but w/o the reseting stuff
Anyone got more info on this?
TL;DR TOML file is successfully pattern matching but not printing out debug statements
[patches.pattern]
target = "button_callbacks.lua"
pattern = "G.jokers:emplace(c1)"
position = "after"
payload = """
print("JOKER PURCHASED")
for key, username in pairs(TTB.SHOP_USERS) do
if key == c1.ID then
TTB.move_shop_user_to_joker_list(c1.ID)
print("JOKER PURCHASED")
break -- Exit the loop once the transfer is done
end
end
"""
match_indent = true```
you can try context.scoring_hand
chat, remind me how i get the length of a table that's key-based and not indexed
thx hero and harmonious joker
is it crashing or not replacing? 
Does anyone know why the line local lan = SMODS.Language("test", "Test Language") is crashing the game?
what is the error it gives
no crashes, just not replacing
this is how ride the bus checks it if that helps
try atlas_table = 'ANIMATION_ATLAS' in your SMODS.Atlas then
how do you see that
is there a localisation file sharing its name with the key of test language in your [mod name]/localization/ folder?
yes
still not working
this what i got so far
isn't the key the first input?
that might be the problem; maybe I should switch them
do you have 7zip?
try it
yes
is it the original graphic, blank or a glitchy mess
wait are u brazilian?
still the base game graphic
same error
beyond my knowledge, then
would need to consult someone that knows what's causing your error.
se eh br?
sim
carai engracado
how would I do that?
This channel seems to be the only modding help available
yep. i guess just keep asking from time to time and hope someone that knows how to fix your issue is around and able to help
so u open up steam, go to gamefiles, then right click on balatro.exe and open archive with 7zip
it will reveal the game's source source code
se em ingles ficar dificil de entender so falar
Could the problem be that the actual translation doesn't have every key/value possible?
oh, try adding prefix_config = { key = false } to your SMODS.Atlas
either one of two things will happen from this point, either it still won't replace or it replaces wrong. the result i expect is that it replaces wrong
which one
is the crash on startup or when you try to hover something
on startup
all of these are the games source code, but almost every joker card is on card.lua
that's probably not your issue, then
you can search other files to look for other stuff
thanks
still dont replace
either im missing something or im dumb
or both
...you're restarting balatro each time, right 
yep
same result ;-;
ok show me your SMODS.Atlas code again 
i am probably doing something wrong and im prepared for it
the thing you're doing wrong is using notepad
is the lua file this is in being run when you start the game?
yes coz its with a bunch of other textures that are infact being replaced
try switching key back to shop_sign then 
ok, so it has to be key, not filename
confusing since the balatro logo shares filename with key 
my bad
its fine lol
i dont know shit about lua so basically everything in the texture pack im making has taken ages to implement so
it's part of the process lol
saaaaaame 
local old = Card.calculate_joker
function Card.calculate_joker(self,context)
local m = 1
local ret = old(self, context)
if G.GAME.round_resets.blind_choices.Boss == 'bl_csmr_lordruler' then
m = m * 0.75
if context.end_of_round then
m = 1
if self.ability.name == 'Mail-In Rebate' then
self.ability.extra = self.ability.base_extra
end
return true
end
just a sanity check here, the return true should just end the calculate function yes?
return ret is the desired return in the end.
okay let me try
wait
that might fix my error actually tysm
...are seals stored under G.P_CENTERS?
they definitely are not
Wheremst, then?
I believe it's G.P_SEALS??? Lemme check rq
yeah
G.P_SEALS is a thing, yeah.
yeppers
just out of curiosity, using steamodded, is it possible to change the background to an image or a solid color?
it is but i couldn't tell you how to do it
ease_background_colour_blind try looking for this function?
im not sure
just came across it
I'm struggling here, I want to not load a mod if another mod is present (because this mod is basically a subset of a larger mod, and I don't want to locate duplicates), and the SMODS code refers to a mod table having either a should_enable or disabled flag but neither works as I expected. How can I determine on load that another mod is active and loaded?
next(SMODS.find_mod(...)).can_load I believe
how the hell does context.modify_scoring_hand work
you might even be able to skip the can_load if you're using find_mod
find_mod seems to find any mod in the directory even if it's unloaded
uuhh I'll have to test that then 1 sec
for example this is what I've got rn
Hey quick question, how feasible would it be to implement a modded joker that only shows up after certain conditions are met? Like Cavendish only showing up after Gros Michel dies by its own effect
The condition I'm thinking would be another (vanilla) joker being sold previously during the run
Is the issue here just that it returns an empty table rather than nil if the mod isn't active?
oh you might need to do
local cardsauce = next(SMODS.find_mod("Cardsauce"))
if cardsauce and cardsauce.can_load then
...
find_mod returns a table of mods
SORRY i had a huge family thing going on but i believe this should be set up properly?
Okay yeah it seems I can just use next and I don't need the can_load check (though I'll keep it for error checking purposes). I just misinterpreted that it was returning a table
Mostly because I guess I just didn't inherently see the use case to have multiple instances of one mod in the directory
Which I see is technically possible, and you could have multiple versions
that joker key should be a string actually but other than that
oh sorry I didn't see this question, the <statement> and 2 or 1 is kinda shorthand for (if <statement> then 2 else 1 end)
ohhhhh ok ok i figuredd
💀
your brackets are messed up
i tried your brackets and it gave me an error though
mine's the same as yours but i removed that last one at the end
this is it with it
yeah you have 1 too many )s after find_card
M = 1
--Function to alter Joker effects
local base_calculate_joker = Card.calculate_joker
function Card.calculate_joker(self,context)
local ret = base_calculate_joker(self, context)
if G.GAME.round_resets.blind_choices.Boss == 'bl_csmr_lordruler' then
if context.change_multiplier then
M = M * 0.75
end
if i wanted to trigger "context.change_multiplier" every time a hand is played within that blind, how would i do it from my SMODS.Blind? (for example in SMODS.Joker i would do it within the calculate function, whats the equivalent for the SMODS.Blind)
it's because of the existence of provides in smods json metadata
ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
off to test then! i dont need to do anything else to the joker itself now do i?
not really
I also looked at the code again and I might've fucked up my math
but you'll probably see that in-game 🤣
i know about SMODS.calculate_context, my question is what is function that is "equivalent" of "calculate" within SMODS.Joker
actually, thinking about it more, I don't think you'll see it in-game 🤔
like the numbers wont change?
not with this approach no
good 
though I think you want to change the 2 or 1 to 0.5 or 1 if I did my math correctly this time
okily doke
since 1/(4*(2 or 1)) => 1/8 or 1/4 instead of the 1/2 or 1/4 you wanted
oooh yeah thatd be bad
how would i visually change the numbers though? just so i can make sure its working
like 1 in 4 would say 2 in 4 you get it
uhh with this approach that's not really possible since you're basically directly editing the code that looks at the chance
i seeeeee
can i print check then?
so anything that visually changes the number would work, but be completely independent from the statistical chance
how do i check the level of a played hand?
yeah you should be able to
bump
my wording is a little confusing,
if this was a joker, i could do SMODS.calculate_context(change_multiplier = true) in a context.before for each hand played
how would i do the same within SMODS.Blind
omg
goated
thank you
idk how i missed that in the wiki
id been staring at it for far too long
like theres no way this isnt a function already
sendDebugMessage(G.GAME.probabilites.normal, "Logger") should work right (i dont do a lot of printing forgive me)
no, because that number never gets modified
but you could take the whole G.GAME.probabilities.normal/(self.ability.extra*(next(SMODS.find_card("insert your joker key")) and 0.5 or 1)) out and store it in a variable, then print that
oh sick
bump
G.GAME.hands[context.scoring_name].level
But watch out for Talisman.
right when i was about to paste that lmao
what does talisman do...
Convert a bunch of values into tables to be able to store much larger numbers.
ah
My summary of Talisman that I made some days ago☝️
for some reason everytime i play a hand, the SMODS.calculate_context is being called 4 times, anyone know why?
so i did this and it crashed me for calling a nil value
jippie thank yuo
cool joker idea!
full crash?
thanks!! this is in a pack of jokers im making
Maybe change it to "gain chips as many as the level of played hand"?
Or "gain chips per level of played hand"?
maybe mult instead of chips? early game this would never be picked since hand levels are so low
it goes well with another joker i have, as uh
Oh. Where did you define the variable
fair, couple thoughts:
Jokers should (mostly) be self sufficient
This is a Rare joker so even then the chips is quite weak(?)
Maybe playtesting will give a better answer
"Every time a {C:attention}hand{} is played,",
"gain {C:chips}+1{} Chip per{C:attention}level{} of the hand",
liek this?
it can only be defined within the use function
anyway, cool idea nonetheless
oh lmao
i forgot to change the rarity </3
its common, costing 3
okay works then, maybe thats broken lol
bump
just realized you were talking about wehttam, yeah hes rare as uh
one time i leveled my high card up +10 in one turn
both with and without the joker
the same thing you just did it the debug console 😂
OH i thought you meant like
filter it in the debug to the use function
but no i can do that lmao
show?
where we're going, we don't need showman
two wheels and no jokers its so over
true... but hey it's essentially an eternal negative showman as a deck so still a win
cool deck design
does this not work?
@stray terrace is the idea guy here!
nothing happened
do you guys have a mod link?
you started a new run?
of course always
still fully in development, but we've got a thread at #1342484578236895274
alright send the code
SMODS.Consumable:take_ownership('c_wheel', {
use = function(self, area, copier)
local testvar = G.GAME.probabilities.normal/(self.ability.extra*(next(SMODS.find_card('j_hpfx_farmer')) and 0.5 or 1))
local used_tarot = copier or card
local temp_pool = (self.ability.name == 'The Wheel of Fortune' and self.eligible_strength_jokers) or {}
if pseudorandom('wheel_of_fortune') < testvar then
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function ()
local over = false
local eligible_card = pseudorandom_element(temp_pool, pseudoseed(
(self.ability.name == 'The Wheel of Fortune' and 'wheel_of_fortune')
))
local edition = nil
if self.ability.name == 'The Wheel of Fortune' then
edition = poll_edition('wheel_of_fortune', nil, true, true)
end
eligible_card:set_edition(edition, true)
if self.ability.name == 'The Wheel of Fortune' then check_for_unlock({type = 'have_edition'}) end
used_tarot:juice_up(0.3, 0.5)
return true end}))
end
sendDebugMessage(testvar, "Logger")
end,
}, true) --farmer
so far we've got 12 vouchers, 4 decks, 4 tags, 16 blinds, 22 consumables, and 36 jokers planned!
plus an entirely new type of card modifier in sort of the same vein as paperback's paperclips
following along :)
cool mod
it's c_wheel_of_fortune
oh my god
Don't forget I made the art -w-
that too!
your function still isn't consistent with the one from smods
oh so i just have to smods update it
like change card to self
i mean self to card
or is there another thing
also, but your function signature is wrong too
is there a simple way to change the rate at which items appear?
as in, with a variable or something similar
to set a new global variable, you would just do G.GAME["variable_name"] = some_value
yes?
that's probably the path, but how would you affect the weight at which jokers appear in the shop or in packs, for example, regardless of rarity?
ok no crash or anything but still no print
sorry, my question was not an answer to yours
the idea is that with a certain deck from this mod, jokers of this same mod would appear 3x more but i can't seem to find anything super simple
oh lol, all good
i was confirming it for my own implementation of something 😅😅
i mean it did work with my question anyways LMAO
perfect lol
if you do figure this out, lmk pls i need to implement something similar as well
i made sure to replace all the selfs with card which is why it doesnt crash, but it still wont print the thing
INFO - [G] 2025-04-14 09:39:31 :: DEBUG :: Logger :: 0.25
works for me
oh my god im on the wrong console
yeah theres the 0.5
but it WORKS 
cannot thank you enough oh my god lars
how do make the badge in set_badge() not show if card locked or discovered
I'm not sure that's a built-in thing, might need to patch into some stuff to achieve that? 🤔

Is this not the right way to define a global variable G.GAME["LordRulerMultiplier"] = 1
where are you making this assignment
in my main mod file
oh wait, this is a function you defined
before anything else is loaded
you should be able to look at the card argument
yeah, G.GAME isn't defined until a certain point in runtime, like at main menu i think
G.GAME gets defined once you're actually in a run
are card.locked and card.discovered things?
if G.STAGE == G.STAGES.RUN then
G.GAME["LordRulerMultiplier"] = 1
end
this would fix it right
no clue! print it out and see I'd say
(but yeah you're looking for something like that; my guess is card.config.center.unlocked?)
hey guys? What should I replace in part of my code for a joker I am making?
What if you set the badge to nil if it's not discovered with set_badges?
set_badges(self, card, badges)
if not self.discovered then badges[#badges] = nil end
end
I can give the code if you want.
it cant find the variable even though im in the blind?
i tprinted it, but am confused as to whether these are strings or booleans 
how...are we supposed to help you without code
I doubt thunk uses strings for booleans haha, but you can print the type using type
oh true
SMODS.Joker{
key = 'juliett',
loc_txt = {
name = 'J',
text = {
"all played {C:attention}jacks{} give {X:mult,C:white}x#1#{}.",
}
},
atlas = "Jokers",
pos = {x = 1, y = 1},
config = { extra = {
Xmult = 1.5,
}
},
unlocked = true,
discovered = true,
rarity = 3,
cost = 10,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.Xmult,
}
}
end,
calculate = function(self,card,context)
if context.individual and context.other_card:get_id() == 11 and context.cardarea == G.jokers then
card.ability.extra.mult = card.ability.extra.Xmult + 5
return {
message = 'Upgrade!',
}
end
if context.joker_main and context.cardarea == G.jokers then
return {
Xmult = card.ability.extra.Xmult,
card = card
}
end
end
}
you want the joker to give x1.5 mult for each jack played?
card.ability.extra.mult = card.ability.extra.Xmult + 5
return {
message = 'Upgrade!',
}
what is this part?
It was from I's code, ok.
you want to loop through G.play.cards and see if each card has id of 11 and add 1.5 each time to a mult variable in your config
then return xmult = mult
calculate = function(self,card,context)
if context.individual and context.other_card:get_id() == 11 and context.cardarea == G.jokers then
card.ability.extra.mult = card.ability.extra.Xmult + 5
return {
message = 'Upgrade!',
}
end
if context.joker_main and context.cardarea == G.jokers then
return {
Xmult = card.ability.extra.Xmult,
card = card
}
end
``` So I have to change this.
ok.
i figured it out! check out how paperback does this with their paper deck (essentially, they simply triple the amount of times jokers from their mod show up using a lovely patch, but you can substitute checking the presence of the deck for basically anything) https://github.com/Balatro-Paperback/paperback/blob/main/lovely/paper_deck.toml
so what do I change this to? hm...
oo cool thank you :)
if context.before then
card.ability.number_jack = 1
for k, v in G.play.cards do
if v:get_id() == 11 then
card.ability.number_jack = card.ability.number_jack + 1
end
end
if context.joker_main then
return {
Xmult = card.ability.extra.Xmult * card.ability.number_jack
}
end
very rough
youd have to create a number_jack variable in your config
Ok, what do I set it to and also I have 5 errors.
you can set it to whatever really, i have a default value set to 1 in context.before anyway but you can keep it at 0
what are your errors
you can format code text like this, btw:
print("example lua code")
here's what you would type to get this:
```lua
print("example lua code")
```
indents are preserved
yeah ik i was just lazy
lol
fair lmao
spent a loooong time trying to figure out joker multiplier effect today
can you implelement my changes then send your code
is that it?
you forgor to wrap your if statement inside calculate = function(self, card, context)
yes, everything i said just replaces what you have inside your calcualte
yes
what does the joker do
?
you're trying to code something, I need the context
theyre giving 1.5x mult for each joker played
sorry
jack
not joker
lol
but yeah their initial goal was for the joker to gain that mult for each jack played
so i gave them the implementation for that
whats line 431
for k, v in G.play.cards do
it should be
for k, v in pairs(G.play) do
but I'm suggesting
for i = 1, #context.full_hand do
if context.full_hand[i]:get_id() == 11 then ... end
Line 432
if v:get_id() == 11 then
why is v still there
didn't I tell you to use context.full_hand[i]? 💀
?
this guy is helpless 💀
the ... is meant to represent whatever you're trying to do within the if statement
yes
may I get the full joker description
since there might be some unexpected behavior with your code
line 433
card.ability.number_jack = card.ability.number_jack + 1
card.ability.extra.number_jack
Honestly, if each Jack is to give X1.5 Mult individually, it all could've been just one large if check.
if you're trying to trigger X1.5 Mult on individual Jacks, use this instead
if context.individual and context.cardarea == G.play then
if context.other_card:get_id() == 11 then
return {
x_mult = card.ability.extra.Xmult
card = card
}
end
end
there's no need for number_jack
yes
taking an L
track how many losses you have
save it to a global variable
and use it as Xmult

This is what L's text will be. +30 Mult if last hand scored under 25% of the blind requirement
i will be adding this as a joker
is there a way to track the last destroyed card in the game?
uh. I have no idea if you are asking me.
it's not too hard to implement one
well, that is until you can't decide how it would work with Hanged Man and Immolate
yeah thats what i was wondering tbh so was curious if the game had an implementation already
probably not
makes sense
since vanilla doesn't have any objects that rely on that
true
if those tarots/spectrals destroy cards one by one
it might be possible
let me see how they are implemented
yep
I guess I'll stop at K for now.
okay
it does technically
because its stored in a table
so i could implement something similar
so, always take the last element in the table?
where i just take the last value
yeah although
i could randomize it?
probably
to add in the rng element of the game
hmm
yeah shouldnt be too hard to implement at all
Immolate could be a bit different
still stored in a table but
it chooses 5 at random instead of from highlighted
Does SMODS have any alternative method for not_enhanced?
true
i dont think i understand this even, whats the destroyed_cards table
like its not defined?
you want to store last destroyed card's rank and suit?
Anyone have any ideas on how I would get this to work? The intended function is to add 15% of last hand's chips and mult to the following hand's, but Talisman is making this less than pleasant to work with, as it's crashing within the before context. stg = card.ability.extra
that could probably be done easily
not next(SMODS.has_enhancement(card,key))
is this correct for a rank card key?
i dont think it wants a table but idk what to put
huh
yeah i could just create a table for each aspect of the card and update it
i think you'll need bignum:gt(another) to compare stuff
the challenge is jsut determining which is the card that should be selected for immolate
gt is greater than
The comparison works fine believe it or not, it's the calc_effects that are tripping the crash
what i do is just make my mod not compatible with Talisman /j
I wish lmao
just do to_big = to_big or function(x) return x end
then use to_big in any of related comparisons in your code
not looking forward to making my mod talisman compatible 😔😔
attempt to compare number with table:
the game should take Talisman's to_big if it's installed or use your own fallback if not
which makes your mod functional with or without Talisman
Oh how nice that would be
Anyways
It's crashing here cuz stg.chips/stg.mult are tables and are what's being passed in as amt
does talisman not patch that 😭
apparently not
In other news
check out this really cool joker I came up with
Good stone build synergy 
indeed
What line is crashing?
This
Lmfao
Because turning numbers into things that can’t be used in comparisons is dumb
As much as I’d love to not have Talisman compat I kinda need to, both for popularity reasons and to handle very large numbers from one of my features 
Then badger the talisman devs to fix their shit
Can I access the G.P_CENTER_POOL['Consumeables'] from create_card at all or do I need to define a new pool of my own and inject all the cards from it into said pool? 💀

...guess I'll need to use inject_card for the custom pool, but how do I use such again?
i think i already published that as an issue in their github already
not sure why they didn't patch it yet
probably because card_eval_status_text is hardly used for Chips/Mult displaying stuff
return {chips/mult = value, etc.} already does the job well 💀
@wintry solar Apologies pinging you like this, but does the G.P_CENTER_POOLS['Consumeables'] not have all the varying types of consumables in it, including modded ones?
does anyone know why my example cards are showing blank? the king of hearts shows correctly and the custom cards show properly in the deck as well.
heres the rank code
Every message runs through that function
Is that even a pool? I thought they were separated by type
are Chips/Mult value displays also?
I imagine most people have animations off
G.P_CENTER_POOLS['Consumeables'] is a valid pool, yeah.
INFO - [G] > eval G.P_CENTER_POOLS['Consumeables']
INFO - [G] Table:
1: Table:
order: 1
_d: false
unlocked: true
set: Tarot
consumeable: true
_saved_d_u: true
cost: 3
discovered: true
effect: Disable Blind Effect
pos: table: 0x2284cb70
cost_mult: 1
name: The Fool
config: table: 0x2284cbd0
alerted: true
key: c_fool
_discovered_unlocked_overwritten: true
2: Table:
alerted: true
_saved_d_u: true
unlocked: true
freq: 1
effect: Hand Upgrade
cost: 3
order: 1
_d: false
set: Planet
consumeable: true
discovered: true
pos: table: 0x228500d0
cost_mult: 1
_discovered_unlocked_overwritten: true
name: Mercury
key: c_mercury
config: table: 0x22850130
3: Table:
alerted: true
_saved_d_u: true
original_key: familiar
_u: true
name: Familiar
_discovered_unlocked_overwritten: true
order: 1
_d: false
atlas: Tarot
set: Spectral
consumeable: true
registered: true
taken_ownership: true
discovered: true
use: function: 0x226822a8
prefix_config: table: 0x22640a50
pos: table: 0x22851d50
generate_ui: 0
type: table: 0x2266c080
cost: 4
key: c_familiar
config: table: 0x22851db0
...
Alright, what’s the question? Whether modded consumables are added to this?
Looking at the smods code, it should have all consumables including modded ones
At this point, the question is if we ever could just have a pool that we can access of all the consumables to be put directly into create_card?
Like SMODS.add_card({ set = 'Consumeables' }), unless I am missing something.
Youd have to select the key yourself I think
I think you could use get_current_pool(“Consumeable”) too
I need a function that, for example, input "m_glass" and output localized string for "Glass card".
That’s what localize is for
I mean, just localize('m_glass') feels not enough for me.
Unless it's really just that simple.
localize({key='m_glass', type=???})
um. big problem. I got D (my joker) and it works if it doesn't score or in your hand.
And I don't want that.
What is it supposed to do?
What does it do currently?
-# Don't forget to share code!
Your not checking the card area.
You need to check context.cardarea == G.play if you only want it to be scored cards.
Your checking context.individual and context.cardarea == G.jokers which never happen at the same time.
so I have to add it to all 11 jokers? ok
??
so I have to replace all G.jokers with G.play?
If you are upgrading when a straight is played, why not if context.before and context.cardarea == G.jokers? (Similiar to how Space Joekr does it.)
what's the different between play and played?
You don’t need area checks on jokers like that
Unless it’s an edition you shouldn’t ever need to check it’s in G.jokers
if context.before and context.scoring_name == 'Straight', oop.
I’d do next(context.poker_hands[“Straight”])
I think I have to change A, B, C, D, E, F, H, J, and K now.
-# I'm very much outta fumes, gonna hit the hay.
Im getting an error here telling me something wants a table but is getting a string instead. does anyone know where that would be?
SMODS.Stake{
key = 'royal',
-- unlocked_stake = 'ocho_stake',
applied_stakes = {'gold'},
above_stake = 'gold',
--[[
modifiers = function()
G.GAME.modifiers.enable_scattering_in_shop = true
end,
]]
colour = HEX('f9d041'),
pos = {x = 0, y = 0},
sticker_pos = {x = 0, y = 0},
atlas = 'stakes',
sticker_atlas = 'stake_stickers',
loc_txt = {
name = 'Royal',
text = 'Royal Description!',
sticker = {
name = 'Royal',
text = 'Royal Stake wowee',
},
},
}
I'll take a break today..
Thank ya
fixed, i forgot that text needs to be a table
How do you change a Joker with a fancy flip animation like Death, Strength, etc does?
G.C.HAND_LEVELS
ty ill check
whats the function to set a cards rank? set_ranks() isnt it
Try SMODS.change_base
im trying to put it here
set_ranks isn't used for that, it doesn't even take parameters
thats fine, what can i use instead to change the selected card into another rank, i tried using SMODS.change_base with no luck
assert(SMODS.change_base(card, nil, rank))
oh i see
the rank has to be the card base value
set_ranks is the function that properly places cards inside their cardarea arrays, iirc, but the name's a bit misleading 😛
is there a place i can read abt all the functions
Yea in the utils file of SMODS' code
nope! The source code isn't documented in that way. Though the functions you'll wanna use are documented on the SMODS wiki, with a lot of info on the utility page https://github.com/Steamodded/smods/wiki/Utility
How does one make a poker hand example contain enhancements?
thats what ive been going through, pretty helpful but it misses some stuff
Check Steamodded\src\utils
alr
For vanilla functions it's slightly harder since they're scattered around
o yea i see the utils, ty 🫡
btw that did work
btw is there a way to have custom ranks not appear in every deck by default? i dont see anything on it in the documentation
oh i missed that on the docs
Yea it should look like (taken from Bunco)
in_pool = function(self, args)
if args and args.initial_deck then
return false
end
end
So Im making a mod called Bun Co. (definitely not Bunco) and I was wondering if my joker ideas headed in the right direction. Here they are atm:
Bun
When fused with another Bun, create a Sandwich
Sandwich
Gains +5 Mult per enhanced card played and scored, self destructs at 100 Mult
Toaster
Creates a Toast each Ante
Toast
When fused with another Toast, create an Endless Sandwich
Endless Sandwich
Gains +5 Mult per enhanced card played and scored,
1 in 100 chance that this card self destructs at the end of round
I might change the Toaster to destroy a bun for a toast each ante but idk let me know
how do i make it so it goes through each card rather than instantly changing every card to a suit...
ah...
i see where i was wrong
is there a way to move an object using code? Only the offset code isnt working, the rest is perfectly fine
context.shop_card.config.center = G.P_CENTERS[packselect]
context.shop_card:set_ability(context.shop_card.config.center)
context.shop_card.children.center.scale.x = 71 * 0.8059
context.shop_card.children.center.scale.y = 95 * 0.8059
context.shop_card.children.center.offset.x = context.shop_card.children.center.offset.x * -2
context.shop_card.children.center.offset.y = context.shop_card.children.center.offset.y * -2
context.shop_card:set_cost(G.P_CENTERS[packselect].cost)```
would this be correct for giving custom rarities values?
hoi, new to modding - I'm currently trying to get a joker effect working but for some reason I seemed to have not done it properly
the intended effect is to create a negative spectral if your played hand has Foil and an Ace, and as far as I'm aware, the check is correct, but... not the "making a consumable" part
You would have to iterate through context.full_hand
And you would have to check separately.
how do i add cards to the playing card deck? i tried G.playing_cards:emplace(card) but "playing_cards" doesnt seem to be right
G.deck
Use the create_playing_card function.
I think this should make a stone card and put it in your deck.
create_playing_card({front = 'S_A', center = G.P_CENTERS['m_stone']}, G.deck)
how do i use context.repetition to retrigger enhanced cards?
if context.repetition and next(SMODS.get_enhancements()) then I think
My mistake it's SMODS.get_enhancements(context.other_card)
does G.play.cards base every card suit in your hand?
What do you mean?
like
well not necessarily suits
just its values n stuff
like enhancements suits rank etc
if i have something that checks if its hearts does it check every card played in that hand
G.play.cards are the cards that were played, it has everything about the cards.
context.scoring_hand
is there a list of all of the custom rarities people have made
You mean over all mods?
yes
I don't think there is.
doh
quick follow-up question: does it automatically iterate, or would I have to make it myself? currently tried via this implementation and it still doesn't work.
one more thing... how do you make it so it changes the suit of each card individually rather than instantly turning them into spades
First, you would have to do it manually with a for loop, Second, No.
use a delayed event
You would do it in context.individual and context.cardarea and use an event.
for that explore the event manager and event queue, if you haven't already/
rah..
you can probably reference card.lua for more info about events
probably reference how tarots do the funny animation
...or you can check the SMODS documentation...
Half of the times checking the source code isn't useful because the game makes half of the stuff work via a completely different way.
Or that's what I found so far.
How would you detect how many of a specific card are in your deck (like the way Steel Joker and Cloud 9 do it)? The Steammodded documentation is my best friend but I'm having a hard time finding this one
look at steel jokers code
card.lua
ctrl+f Steel Joker
local num = 0
for i, v in pairs(G.playing_cards) do
if SMODS.has_enhancement(v, "m_steel") then
num = num + 1
end
end
Change the has_enhancement to the requirement you are looking for.
Is it possible to have a permanent effect on cards like the hiker but on something else than chips?
I am trying to make a joker that has the splash effect (all cards score) but I can't seem to figure it out (I've tried looking through the pokermon code but couldn't find anything) Does anybody know how to make this work?
look at splash's code \
genuinely source code is a savior 🙏
Splash doesn't have code, it's hard-coded into the hand eval function (which I can't get an override to work on)
lovely patch ,,,,,
context.modify_scoring_hand
return { add_to_hand = true }
evil splash: no cards are scored
for some reason this code doesnt work when i have cryptid installed
can anyone tell me why?
ease_dollars
cryptid patches it to do smth and that breaks shit
oh
i had this issue too 😔
how would i make it compatable
is there a crash
no it just doesnt do anything
are you sure
fuck nvrm
Is G.deck enabled in optional features?
try having it print the rarity it gets
and what that rarity is from the table
so
print(J.config.center.rarity)
print(rarities[J.config.center.rarity])
well uh now it just makes the first card a spade..
i know its probably in the upper part but im too stupid to actually know what to change it with
are there all four prints?
whar..
what's the return false for?
when the played card isnt a heart...
It should be context.cardarea
returning false in an event just makes it repeat again iirc
you already check for that
no none nothing
oh..
no put it in the loop lol
OOOH wait is this a deck
guys 👆 idk you've been using it a lot for the past 10 minutes
yes
ah
sorry
one might even say neato-
feel free to steal tmd's code if needed
i did not spend that long figuring out how to do stuff just for it to be used for my mod exclusively
imagine asserting
assert?
assert(SMODS.load_file('versions/0.8.6.lua')()
ok
ok it works now, thanks
HEX('hexvalue')
Also question: Is it possible for me to unlock and lock cards just by having a specific config?
unlocked = true or false?
elaborate
Yeah, I want to make it so that one of the requirements to unlock the jokers from a version is to, y'know, turn it on in the config
yeah, but i don't want to REMOVE the joker from the collection
ah
extremely new to modding but i'm following that one tutorial by artmuncher
right now i'm just trying to make a simple joker that adds 30 chips when hand is played but the end goal for this joker is to add 30 chips for each face card in hand, i tried setting that up yesterday but it was crashing the game on load, i've tried pulling back stuff from it since, but it's still crashing on load. if anyone has any advice i'd really appreciate it. sorry this is basic stuff i am just lost here
is this how i would give a custon rarity to a joker
You would have to define it first.
Also you need your prefix.
modprefix_raritykey
also need an SMODS.Rarity for the rarity
when doing basically the hikers with perma_p_dollars instead, it does work but it doesnt proc dollars on the round it is added to it, is there a reason, or smth i misunderstood?
Perma bonuses don't trigger on the current hand unless the card is triggered again.
it first counts its gold, then upgrade it, even though i have the same temporality as hiker, or am i crazy and hiker actually doesnt count the chip added on the round its added on?
okok im crazy then ,thank you
@daring fern please can you help me with only 1 joker it's a very small bug,
This one joker I am getting an issue with this error
Oops! The game crashed:
[SMODS _ "src/utils.lua"]:347: bad argument #1 to 'pairs' (table expected, got nil)
whenever I press New Run after the Game over screen or from the Options, It's happening just after the cards get burnt/destroyed
What is your code?
is this how to make a new playing card?
SMODS.Joker {
key = 'j_TeamRWBY_Yang_yang',
loc_txt = {
name = 'Yang',
text = {
"First hand each round is {C:attention}burned{}",
"{C:mult}+{} Mult per burned card",
"added to {C:attention}final played card{}"
}
},
rarity = 2,
cost = 8,
atlas = 'j_TeamRWBY_Yang_yang',
pos = { x = 0, y = 0 },
config = {mult_bonus = 0},
calculate = function(self, card, context)
card.ability.config = card.ability.config or {
mult_bonus = 0,
marked_for_burn = false,
cards_to_burn = {}
}
local config = card.ability.config
if context.end_of_round then
config.marked_for_burn = false
config.cards_to_burn = {}
return {}
end
if context.before and not context.blueprint then
if G.GAME.current_round and G.GAME.current_round.hands_played == 0 then
config.marked_for_burn = true
config.cards_to_burn = {}
for _, c in ipairs(G.play.cards) do
table.insert(config.cards_to_burn, {
card = c,
pos = {x = c.T.x, y = c.T.y}
})
end
end
end
There is more
Use create_playing_card
if context.after and config.marked_for_burn then
if #config.cards_to_burn > 0 then
config.mult_bonus = (config.mult_bonus or 0) + #config.cards_to_burn
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
for _, data in ipairs(config.cards_to_burn) do
local c = data.card
if c and not c.removed then
c.vel_x = 0
c.vel_y = 0
c.rot = 0
c.rot_vel = 0
c.T.x = data.pos.x
c.T.y = data.pos.y
There is more
What should I put in the paratheses
c.states.visible = true
c.children.phantom = nil
c:start_dissolve(nil, true)
end
end
return true
end
}))
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.8,
func = function()
for _, data in ipairs(config.cards_to_burn) do
if data.card and not data.card.removed then
data.card:remove_from_deck('destroyed')
G.deck.config.card_limit = G.deck.config.card_limit - 1
end
end
config.cards_to_burn = {}
card_eval_status_text(card, 'extra', nil, nil, nil, {
message = config.mult_bonus .. ' Total Burned!',
colour = G.C.FILTER
})
return true
end
}))
config.marked_for_burn = false
end
end
if context.joker_main and config.mult_bonus > 0 then
return {
mult = config.mult_bonus,
card_end = true
}
end
return {}
end
}
@daring fern ☝️
@worldly thicket
what about for a random suit and rank?
always an ace of spades though
do I do pseudorandom, as I was looking at how the Grim spectral does it
@daring fern I sent u Lua file on dms
Also someone told me earlier to get Intellisense I need to add SMODS to my project but how do I do that in VSCode
I add the "Steammodded" folder right?
It should be called smods
I'm not finding it
What version of steamodded do you have?
So another weird question:
if _center.name == 'Half Joker' and (_center.discovered or self.bypass_discovery_center) then
self.children.center.scale.y = self.children.center.scale.y/1.7
end
If Let's say I don't wanna use the Center's name but its key, is that possible?
card.config.center.key
ty
strange, it didn't work
self.children.center.scale.y = self.children.center.scale.y/1.7
end```
Where are you putting this?
card.lua as a lovely patch?
_center is the card and its located at card.ability so I'm not sure how to acquire the key.
Well the problem is that i can't use the name, it's already half joker in the localization so that it doesn't break the original
I used the Balatro Mod Manager
The name is different from the local name.
You would put the steamodded folder in your workspace.
So what, I can add Name = "Half086" into my joker code in this case and load that instead?
Yes.
is this what it should look like?
Yes.
huh... didn't think about that. might make porting code a bit easier
if it WORKED, smh game
Is there anything else I need to do?
You also want to put the lovely folder in your workspace if you want the intellisense
i know there's code missing in the screenshot, that's on purpose
But did i do the name thing right?
what's the context for checking the number of jokers you have?
I did this but I don't think the Intellisense is working
What lovely folder did your put in your workspace?
sorry if I'm annoying you btw
Does the dump have files in it?
Yes
Do things like this show up?
Nope
omg this exists
hmmmmmm i also added lovely and smods to my workspace and i still don't get intellisense D:
What about opening your mods folder as a folder in a new workspace?
Also did not do anything
Do you have the lua extension?
this worked for me
I do not but which one is it, there is a lot just called "lua"
how do you check for the current number of jokers you have?
Thank you for all your help
Now back to my original question, do I do a pseudorandom for the cards' suits and ranks?
Get a pseudorandom_element of G.P_CARDS
Did u see it? :(
I think i already have my answer, but would there be a way to make a pareidolia like effect on a specific rank instead of is_face?
wdym?
in this, where is the enhancement set?
basically i would like to make card count as kings (so not contradictory with pareidolia)
but the way pareidolia is done is weird asf
and I'm saying you can make every card a King
has someone re-made smeared joker with steamodded?
hooking the function that gets the id I think
what's weird about it
You would hook get_id and if the joker is present return the id you want.
i want to see how they make cards count as other suits
hook is_suit
I made Chimera
With playing cards do I need to do newcard:add_to_deck or is that what G.deck is for in the create function
gotcha
i'm not sure i understand ^^; get id on card played and then i return (i dont know how) the id i want (without changing the card)?
tyty!!
@hard needle
is ur mod open source :trol:
All Balatro mods are open source.
if i have an enhancement list, what would i put instead of "m_stone"?
the way Smeared and Pareidolia work is that instead of the game accessing the desired value directly, it sends a courrier to retrieve it. Smeared/Pareidolia kill the courier and replace it with their own insider agent
yes
send me the link 🤔
the enhancement list
i have no idea
I tried using my consumable and got this crash
It's G.P_CENTERS
Also you don't emplace it you would change it from G.deck to G.hand
I'm just testing it right now, but when I do add the pseudorandom, do I do front = pseudorandom(something)
I just got this crash now
What does your joker supposed to do?
It burns/destroys the first hand cards, let's say I burnt/destroyed 4 cards in the first hand of the blind, I would get 4x mults and it keeps on growing too
But I am getting this error
(whenever I burn/destroy the cards and press new run either on game over menu or options menu) @daring fern
im not sure on how to get the id (like context.before and context.individual and context.cardarea == G.play) and even less sure on how to return an id at all ^^;
Try replacing everything in calculate with this ```lua
if context.destroy_card and G.GAME.current_round.hands_played == 0 and context.cardarea == G.play then
card.ability.mult_bonus = card.ability.mult_bonus + 1
return {remove = true}
end
if context.joker_main then
return {
mult = card.ability.mult_bonus
}
end
What could've caused this as it isn't my file
Is there a way to put a poker hand above all other hands?
am i missing something?
trying to do like a bonus enhancement
but with +80 chips
Return chips = …
OH CHIPS, thought it was bonus
are you trying to do a hiker effect?
not really, just regular enhancement that always gives +80 when scored
if i want to return both chips and mult i just add a comma then mult = card.ability.extra.mult?
Yes
Does this look right,
im trying to find where the code for the joker maximized of cryptid is, i dont seem to find it, since it has something similar to pareidolia
thank you!
although is it not in calculate? i haven't done a joker whose effect wasn't in the calculate function before, is that any different?
but i dont know what a hook is :c
ive not put the code of a joker outside of its smods.joker yet
you could overwrite the function to make it work like you want it to, but that would conflict with any other mod trying to do the same
instead, you save the original function, then you overwrite it, but you include the saved copy inside
I got this crash again, it started after I removed the G.hand:emplace(newcard)
i really try to but i dont understand half the words, perhaps i should try doing smth else x)
hello besties
get_id sends a courier to delive a message, but if you hook them, you interrupt the courier which you can replace with your own courier or you can let them keep going
like a member of the mafia taking control of the courier trade
and the get id doesnt work in calculate?
hello bestilly the bester
they do different things
hi vic :D
G.P_CARDS['H_Q']?
hope you are well
where do i call the get id then?
what about you
you don't
looking at pareidolia and maximized, they're in totally different places
im don alright, took a nice lil shower so im hanging out now
and not in the same structure as smods im used to
I'm going to imagine they hung you on a string to dry
In the reference someone sent me it wasn't like that
and I get the same crash when I add the emplace back
Merely referencing how Familiar, Incantation and Grim do it.
i still put it in the smods.joker ? i think im starting to get it
no
cryptid puts it in there because they do some weird stuff when loading objects
That worked, however they were drawn face down
in where should i put it in then? and if somewhere else, does the structure need to change too?
they don't put it in SMODS.Joker I believe
they just put it next to it
but outside
it seems in "local maximized"
whoever keeps pointing at me
in misc_joker.lua
@daring fern
...any chance you are in the 'cards are drawn face down' blind or something?
but the whole way it is written looks like none of the mods ive lurked over before, thats why i struggle understanding it
it's their custom loading system table
A hook can go just about anywhere where the main body of code is
I was on the small blind
If you wish to mess with overriding is_face and get_id, I have done some stuff with the two functions if you want to take a look?
me too
🤷
would love to!
so i can just put it outside my smods.joker
not needing anything to surround it?
And when I hover over one of the face down cards it does this
ok will try like this
your hook is a completely other file, is that necessary?
No
I do it to organize them
By removing the emplace I got it to work, however the cards are random despite me putting the front = ['H_Q']
I could also choose to only add some hooks
But I have sorta changed my mind about implementing a system where that would make sense
okok
will try smth based on cryptid, toga and yours
if i use the base of 3mods thats work, that should be fine...Eventually
How do you add new hands on balatro?
tried this but it doesn't do anything, i have totally misunderstood it?
local getidref = Card.get_id
function Card:get_id()
local id = getidref(self)
if id == nil then
id = 13
end
if next(SMODS.find_card('j_dauphine')) then
if id <= 12 or id == 14 then
id = 13
end
end
return id
end```
You need your modprefix_ between j_ and dauphine
also i ask this now, but can i add a suit condition in this same piece? (id guess yes)
within the string?
Yes.