#💻・modding-dev
1 messages · Page 394 of 1
bump
Destroy the played card if it has a modifier and create two copies.
ok, i added brackets to the text too, but it's still crashing my game, telling me that my loc_txt isn't closed
new code?
key = 'tarot24',
set = 'Tarot'
loc_txt = {
name = 'Carnival of Shadows'
text = {
'Creates 3 random {V:1}Negative{}'
'{C:attention}Tarot{} cards.'
},
},
}```
oh wait, it says the first bracket isn't closed
notepad
SMODS.Consumable {
key = 'tarot24',
set = 'Tarot',
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random {V:1}Negative{}',
'{C:attention}Tarot{} cards.'
},
},
}
.
oh, lol
return {
message_card = context.other_card,
xmult = card.ability.extra.mult,
extra = {
message_card = context.other_card,
message = "Cured!",
colour = G.C.BLUE,
func = function()
G.E_MANAGER:add_event(Event({
blockable = false,
func = function()
print("setting to base")
context.other_card:set_ability(G.P_CENTERS.c_base, nil, true)
return true
end
}))
end,
}
}
(tried this with the :set_ability being to both context.other_card and another variable that is context.other_card)
why doesnt this set the enhancement to base
still crashing
hmm
SMODS.Consumable {
key = 'tarot24',
set = 'Tarot',
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random {V:1}Negative{}',
'{C:attention}Tarot{} cards.'
},
},
}
SMODS.Consumable {
key = 'tarot24',
set = 'Tarot',
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random {V:1}Negative{}',
'{C:attention}Tarot{} cards.'
},
},
}
turns out you were missing even more commas
this seems to only check if the card exists in the mod, not if i have it in my deck
oh, so every line break needs a comma
yes and no
what youre working in is a lua table
each new entry needs a comma
Still can't get this to work properly with hologram.
but it can
generally i do
is the text style tagging the same as vanilla's system
yeah
@red flower can you help me with somthing
do you know if i can make a bp die when it copies a joker
im reading trough documentaion (smod and vanillaremade) but i still cant figure out how to destroy a specific rank of cards after they are scored
is there an easy way to make a joker check if a specific joker is in your deck?
SMODS.find_card just seems to check if the joker exists in the mod itself, instead of your current deck
Use context.destroy_card:get_id() ==
e.g
if context.destroy_card:get_id() == 2 then
return
{
remove = true
}
end
thanks bill cipher
why is this not setting the enhancement to base
i keep on getting this error when booting up the game, did i fuck somthing up in the code? because it keeps on saying "attempt to indext globsl 'card' [a nil value]"
SMODS.Joker{
key = 'gamexplain',
loc_txt = {
name = 'GAMEXPLAIN',
text = {
'When a King and Jack is in a scored hand,',
'gain a {C:mult}+#2#{} Mult'
}
},
atlas = 'Jokers',
pos = { x = 0, y = 0 },
config = { extra = { mult = 6.9 } },
loc_vars = function(self,info_queue,center)
return { vars = { card.ability.extra.mult } }
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if context.othercard:get_id() == 13 and context.othercard:get_id() == 11 then
return {
mult = card.ability.extra.mult
}
end
end
end
}
othercard is just a local var that = context.other_card btw
card instead of center in loc_vars
alr it booted up thanks
wokrs now
alr now i have this error and i think its because it changed 'or' to 'and' from the example i was using
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if context.othercard:get_id() == 13 and context.othercard:get_id() == 11 then
return {
mult = card.ability.extra.mult
}
end
end
end
}
uhhh maybe
if context.blueprint then
context.bluepring_card:start_dissolve()
end
i figured it out
thanks tho
oh fuck im stupid
i forgot the underscore in other_card
ok so now the game loads the card and i can put in into play without crashing
but its not applying the mult
i cant get it to work
im not smart enough
😭
how do you add the description of "negative" when viewing the card's description?
what's the problem
basically
info_queue
the joker is supposed to destroy queens and kings after being scored
but
im dumb
can i see the code
this is so bad that i dont want to show it
it's just
if context.destroy_card and (context.destroy_card:get_id() == 12 or context.destroy_card:get_id() == 13) then
return { remove = true }
end
ohhhh
now i see what i did wrong
thanks
i got (context.destroy_card:get_id() == 12 or context.destroy_card:get_id() == 13) this part wrong
probably due to my non existent lua skills
Ok guys uhm I'm using score_card() to score a card in Balatro (I have no other way), but it ignores all jokers, it just scores the card without the joker abilities. How do I calculate the jokers?
Is it just something like calculate_joker()?
so... like this?
key = 'tarot24',
set = 'Tarot',
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random {C:dark_edition}Negative{}',
'{C:tarot}Tarot{} cards.'
},
},
atlas = 'smtarot',
pos = {x = 0, y = 0},
loc_vars = function(self, info_queue, card),
info_queue[#info_queue+1] = G.P_CENTERS.m_dark_edition,
}```
G.P_CENTERS.e_negative
can you put regular code inside of the func of a return
but also thats not the correct formatting
wdym
yes it's just going to be run at the same time as the previous stuff
so can i put it in an event to wait?
yeah
How do I take joker abilities in consideration when using score_card()?
let's goo
what the hell have i done
Well it is a joker that retriggers a lucky card until it triggers (Gives Mult or Money)
I wish I could use return repetitions but I can't, because that way I can't know if the retrigger was lucky this time or not (When I use context.repetition, because it doesn't go through it twice)
While not context.lucky_trigger (or something like that) is unusable as well because it would only base around the context of the first scoring of the card (Which means it's an infinite loop)
is that a legendary
it better be
No, it's uncommon, because the lucky cards have a 50% chance to be destroyed after that
So practically a glass cannon, but it's not glass lol
glass cards are also glass cannons
I have heard that one way to do it is to somehow copy the seed and then predict when the next lucky trigger will be, and then do the return repetitions based on the number of retriggers required but that's way too complicated for me and I think there's an easier way, which I found, with score_card()
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if context.other_card:get_id() == 13 or context.other_card:get_id() == 11 then
return {
mult = card.ability.extra.mult
}
end
end
end
}
alright so ive gotten the card effect to work but it only applies when its '...== 13 or context... ' but i want it to trigger specifically when its both a king and jack. is there any way to make it like that or am i just stuck here
I would hook/patch into SMODS.calculate_repetitions
Just use and instead of or?
A card cannot be 2 ranks at the same time?
so i assume it has to be or
But he wants a card to be 2 ranks at the same time no?
Or do I miss something?
you want it to give mult once if both are played OR do you watch each card to give mult when both are played?
the forbidden jing
i want it to give mult once both are played
not individually
Ah ok nvm
i did try other contexts
use joker_main and loop through context.scoring_hand
Oooh sounds like something interesting I've never heard of, thanks!
ill go do that rq
my text isn't shrinking
'Creates 3 random',
'{C:dark_edition}Negative{} {C:tarot}Tarot{}',
'cards.',
'{s:0.8}{C:tarot}Carnival of Shadows{} excluded{}'
}```
{s:0.8,C:tarot}
bump
sorry im a bit lost, im looking at the wiki and i dont see a context for scoring hand. would it be in the line with Joker_main or under it?
can u screenshot this for me so i can see it well on mobile pls :3
Yes
the tarot color is applying to "excluded" word too
what's the difference between the before and after sections?
ok i thought that was what you were referring to cause it kept on popping up there when i was looking
one applies before everything in update and the other one after
alr
ok, now "excluded" seems to appear in normal size instead of small
nvm, i think i got it
for the after scoring part just move the calculate_context call outside the event i think
i don't understand the other problem
looks like a name soundalike
ok going off the example you gave me it should look something like this right?
calculate = function(self, card, context)
if context.joker_main then
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 13
yes, you probably want to set a flag when you find one of them and a flag for the other
right
That's helped with the scoring, but now the other issue persists. The hologram shows x2.75, x3, x3.25, etc, instead of just showing the final number, I'll get a recording if that helps.
oh then you can save all the cards to a list and then call the calculate_context function with all the cards in one list
i'm reading the documentation, and i can't figure out what lines to add to make the tarot card spawn cards
playing cards?
what do yall think a madeline (food) would do as a balatro joker? i cant think of any ideas but i have to have one for consistency
it's tarot card that spawns 3 random negative tarots (excluding itself)
oh
SMODS.add_card{set="Tarot", edition="e_negative"} 3 times
excluding itself is kinda hard tho
i don't want to make it spawn itself for obvious reasons
its funny if it spawns itself though
infinite tarots
since what i'm trying to do is make all shop jokers have an edition, would i pick before or after?
you would probably have to grab all the tarots from G.P_CENTER_POOLS.Tarot except yours and use pseudorandom_element on that
Either is fine.
ok so would something like this work? (sorry if its scuffed as fuck im new to coding as a whole)
calculate = function(self, card, context)
if context.joker_main then
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 13 or context.scoring_hand[i]:get_id() == 11 then
if context.scoring_hand[i]:get_id() == 11 or context.scoring_hand[i]:get_id() == 13 then
return {
mult = card.ability.extra.mult
}
i did the ...or... statement again bc i remembered earlier you guys said that the game was looking for a card that was both a king and jack when i had it set to 'and'
no
i figured
i tried but it was too complicated and no one could really give me any definitive help
Isn't that already what I'm doing? adding the cards to new_cards and then using that in the calculate_context?
oh you don't even need to patch
local ccfs = create_card_for_shop
function create_card_for_shop(area)
local card = ccfs(area)
if next(SMODS.find_card("your joker key) and card.ability.set == "Joker" then
card:set_edition(...) -- put the edition or poll_edition here
end
return card
end
lineup so far
lancer mentioned
no you're doing it once for each card in scoring_hand that has the requirements
also you should probably do cards = new_cards directly
man, i hate that the documentation is kinda vague
i agree there
local king = false
local jack = false
for _, pcard in ipairs(context.scoring_hand) do
if pcard:get_id() == 13 then king = true end
if pcard:get_id() == 11 then jack = true end
end
if king and jack then return { mult = 10 } end
i am reading it several times and can't find anything about creating other cards
he's the goat
it's in utility functions
what does lancer deltarune do
found it
ok, but it's still pretty vague about the formatting here
yeah
i usually just search examples of it in the discord if im doubting smthn im not gonna lie
what's the vague part
every scored card's suit turns into spade
peak
alright so should this work?
calculate = function(self, card, context)
if context.joker_main then
for i = 1, #context.scoring_hand do
local king = false
local jack = false
for _, pcard in ipairs(context.scoring_hand) do
if pcard:get_id() == 13 then king = true end
if pcard:get_id() == 13 then king = true end
end
if king and jack then return {mult = 10 } end
end
end
end
}
(im gonna assume i replace the mult = 10 with the value i want)
take out the for i = 1, #context... loop
like... where to put it. does it goes inside or outside SMODS.Consumable?
i replaced it with ipairs
how do i iterate over each card in a played hand
ok that's not it being vague, that's a problem with you understanding how a function works
ah thanks
like I'm sorry I agree that the docs have problems but a lot of times I wish people would just admit they don't know what the terms mean instead of saying that the docs are wrong or that they're bad
👀
SMODS.Joker{
key = 'gamexplain',
loc_txt = {
name = 'GAMEXPLAIN',
text = {
'When a {C:attention}King and Jack{} is in a scored hand,',
'gain a {C:mult}+#2#{} Mult'
}
},
atlas = 'Jokers',
pos = { x = 0, y = 0 },
config = { extra = { mult = 6.9 } },
loc_vars = function(self,info_queue,card)
return { vars = { card.ability.extra.mult } }
end,
calculate = function(self, card, context)
if context.joker_main then
local king = false
local jack = false
for _, pcard in ipairs(context.scoring_hand) do
if pcard:get_id() == 13 then king = true end
if pcard:get_id() == 13 then king = true end
end
if king and jack then return { mult = 10 } end
end
end
}
alr if everything here is correct then im gonna test it rq
(you all should test it and find bugs)
this is amazing
Sorry, but I just do not understand what I should be doing.
you have a king check twice
hmm you kinda have to change multiple things
but the problem is that you're calling calculate_context multiple times so hologram scales in increments, you need to compile all the cards you create in a list and call it then, you're kinda doing that but you have an outer loop that you're not accounting for
sorry i would mock up the code if i was on my pc lol
all i gotta do now is fix the nil on the tooltip
switch #2# with #1# in the desc to fix that
it's currently looking for the 2nd thing in loc_vars to put there, but nothings there, so it gives you nil
key = "bruhiosr",
blueprint_compat = false,
loc_txt = {
name = 'testm',
text = {"{C:red}+#1#{} hand size,",
"Earn {C:money}$#3#{} at",
"end of round.",
"If {C:red}testfire{}",
"is in your deck,",
"{C:red}+#2#{} hand size,",
"Earn {C:money}$#9#{} at",
"end of round."}
},
pos = { x = 0, y = 0 },
rarity = 2,
atlas = 'mindaexperiment',
blueprint_compat = false,
cost = 6,
config = { extra = { h_size = 1, money = 3 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.h_size, card.ability.extra.money, card.ability.extra.money_test} }
end,
add_to_deck = function(self, card, from_debuff)
if context.other_joker.ability.name == 'testfire' then G.hand:change_size(card.ability.extra.h_size+1)
else G.hand:change_size(card.ability.extra.h_size) end
end,
remove_from_deck = function(self, card, from_debuff)
if context.other_joker.ability.name == 'testfire' then G.hand:change_size(-card.ability.extra.h_size+1)
else G.hand:change_size(-card.ability.extra.h_size) end
end,
calc_dollar_bonus = function(self, card)
local bonus = 0
if context.other_joker.ability.name == 'testfire' then
bonus = bonus + card.ability.extra.money+6
else
bonus = bonus + card.ability.extra.money
end
if bonus > 0 then return bonus end
end
}```
is there something wrong with how i'm checking for the specific joker? (in this case "testfire")
when i write it like this, it crashes saying that context is a nil value
You don't use context checks in add_to_deck/remove_from_deck
how do i do the additional check to change the base values, then?
not relevant to the question but loc_vars is only returning 3 values not 9
You don't need to check for the joker name
the idea is that "bruhiosr" gives +1 hand size and $3 at the end of round on its own, but with "testfire" in your deck it gives +2 hand size and $9 at the end of round
i've tried other ways to check for the specific joker, but they either also crash or don't detect the joker at all
Then you'd use SMODS.find_card()
you specify a string in that call that is the joker's key (being 'j_[MOD PREFIX]_[JOKER NAME]')
this didn't work, but maybe it was because i tried to use it on add_to_deck/remove_from_deck?
It should work
it applied the bonus effect without the second joker being in my deck
That's because that function returns an array of cards matching that type, and since it's an array it will always be true
You should wrap the function call in a next() wrapper, which checks if the array has contents or not and returns a boolean accordingly
yeah, i just can't figure out this thing, man:
key = 'tarot24',
set = 'Tarot',
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random',
'{C:dark_edition}Negative{} {C:tarot}Tarot{} cards.',
'{s:0.8,C:tarot}Carnival of Shadows{}{s:0.8} excluded{}'
},
},
atlas = 'smtarot',
pos = {x = 0, y = 0},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = G.P_CENTERS.e_negative
end
for i = 0, 2 do
SMODS.add_card{set="Tarot", edition="e_negative"}
end
}```
i'm likely doing something really wrong here
back to this question. how would i change the hand size without creating a "if" argument inside add/remove from deck?
You'd do exactly what you're doing inside the if. Unlike vanilla where the game checks for a card's type on calculate, SMODs card objects work on a per-object basis and thus don't need a check like that
i was not using that because the doc didn't mention anything about triggering when you use a consumable
is it formatted like how calculate is used?
Another thing I just noticed: Lua indexes at 1 and not 0
more approachable for people that know less coding but god i hate it
how do i do ^chips with talisman?
Similarly but not exactly. It looks like this:
use = function(self, card, area, copier)
yeah, that's what was confusing me, because in the doc's consumables page, it is written as use(self, card, area, copier)
You'll also need a can_use function which returns a boolean
can_use = function(self, card)
It's written like that to be a bit more legible but I get the confusion. Any sort of function documentation will be written in that sort of name = function(args) format in-code
You return {echips = number}
yeah, i think i still don't get it
use = function(self, card, area, copier)
if can_use
for i = 1, 3 do
SMODS.add_card{set="Tarot", edition="e_negative"}
end```
how would i return two messages on one joker?
return {
message = "msg",
extra = {
message = "msg2"
}
}
funcName = function(args)
--whatever
end
is the same as
function funcName(args)
--whatever
end
docs like this are sort of leaning on the second one to keep it short
-# i might have something slightly off there cause I'm typing this from memory on a phone but the basic idea is that functions have two formats
if im applying custom music during a boss blind, how do i make it turn back off afterwards
Is there a way to prevent playing cards from giving chips? I was gonna use card.debuff but im not really happy with that solution.
I guess really the question is should I be using :take_ownership
does anyone have the keybinds for debug+?
they seemingly got rid of the ingame menu showing all the usable keybinds
holding tab doesnt show them?
im intrigued
crashing again
key = 'tarot24',
set = 'Tarot',
atlas = 'smtarot',
pos = {x = 0, y = 0},
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random',
'{C:dark_edition}Negative{} {C:tarot}Tarot{} cards.',
'{s:0.8,C:tarot}Carnival of Shadows{}{s:0.8} excluded{}'
},
},
config = {
extra = {
tarots = 3
},
},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = G.P_CENTERS.e_negative
return { vars = { card.ability.extra.tarots } }
end,
use = function(self, card, area, copier)
for i = 1, math.abs(card.ability.extra.tarots) do
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
SMODS.add_card({set = 'Tarot',edition="e_negative"})
end
return true
end
}))
end
delay(0.6)
end
can_use = function(self, card)
return true
end
}```
bumping
context.end_of_round?
i dont know how to actually stop the sound
it keeps playing
for as long as the game is open
hey gang- im working on my first mod and i keep getting this error. im checking my code against another mod and everything seems to work in theory but when i try running my mod it crashes.
Def show your code
Cryptid 
cryptid does that with jimball
oh alright
still confused
You'd prolly need a patch for that. The function that provides the chips is Card:get_chip_bonus() in card.lua
you could hook it instead
That's probably better
idk why but I'm like hardwired to consider patches faster than hooks and it's a problem 😭
i mean ive never used a patch so we're both biased
um... i don't think it was supposed to be an endless, loop, lol
What does your file structure in your assets folder look like?
rename jokersLarge to just jokers and remove your atlas pointing to jokersLarge
is there anywhere I can readup on patches and hooks
OH
i see how the game does it
cryptid checks IN the sound
it checs for the joker
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...
so i could in theory check for Mafioso and Debt collector
^ For hooks
This is for patches https://github.com/ethangreen-dev/lovely-injector?tab=readme-ov-file#patches
still getting the error
thaaaank you
Is it the same one?
hmm
key = "twotestsr",
blueprint_compat = false,
loc_txt = {
name = 'testm',
text = {"{C:red}+#1#{} hand size,",
"Earn {C:money}$#3#{} at",
"end of round.",
"If {C:red}bruhiosr{}",
"is in your deck,",
"{C:red}+#2#{} hand size,",
"Earn {C:money}$#9#{} at",
"end of round."}
},
pos = { x = 0, y = 0 },
rarity = 2,
atlas = 'mindatest',
blueprint_compat = false,
cost = 6,
config = { extra = { h_size = 1, dollars = 3, h_sizetest = 2, dollarstest = 9 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.h_size, card.ability.extra.dollars, card.ability.extra.h_sizetest, card.ability.extra.dollarstest } }
end,
calculate = function(self, card, context)
if next( SMODS.find_card("j_bruh_bruhiosr") ) then
card.ability.extra.h_size = card.ability.extra.h_sizetest
card.ability.extra.dollars = card.ability.extra.dollarstest
end
end,
add_to_deck = function(self, card, from_debuff)
G.hand:change_size(card.ability.extra.h_size)
end,
remove_from_deck = function(self, card, from_debuff)
G.hand:change_size(-card.ability.extra.h_size)
end,
calc_dollar_bonus = function(self, card)
return card.ability.extra.dollars
end
}```
i managed to get it to detect when the second joker is in hand, but it doesn't seem to detect when it gets *removed* from the deck (to reset the bonus back to normal). and for some reason, the bonus for adding hand size doesn't work, just the -2 hands from selling the joker while the second joker is active
it basically gives a permanent bonus instead of a conditional one (and it doesn't add extra hand size because ????????)
Ah you're not asserting the file load call
Your SMODS.load_file call should look like this
assert(SMODS.load_file('path'))()
ok, so my code works, but instead of 3 negative tarots, it's spawning infinitely
key = 'tarot24',
set = 'Tarot',
atlas = 'smtarot',
pos = {x = 0, y = 0},
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random',
'{C:dark_edition}Negative{} {C:tarot}Tarot{} cards.',
'{s:0.8,C:tarot}Carnival of Shadows{}{s:0.8} excluded{}'
},
},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = G.P_CENTERS.e_negative
end,
use = function(self, card, area, copier)
for i = 1, 3, 1 do
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
SMODS.add_card({set = 'Tarot',edition="e_negative"})
end
}))
end
delay(0.6)
end,
can_use = function(self, card)
return true
end
}```
anyone have any idea why my game refuses to show scoring animations now even though i have the setting disabled in talisman?
like its really confusing me
alright
I think your loop definition should just be for i = 1, 3 do
still disables scoring animations
i did that, the infinite spawn is still happening
if you reinstall it you have to turn it off again btw
i did
or do you mean like
uninstall, open without talisman, close, reinstall, then try it?
is that what you mean?
oop i got it
1,3,1 is the same as 1,3
for some reason saturn was disabling them
the last one is the increment, which defaults to 1 if not specified
awesome, thank you so much!!
how do you add those side things
info_queue
Yo, uh... how? How do i even make mods o-o
Your calculate is very messed up. The way you have it now is every time a context is called, if you have the other joker, the values of this joker change. You don't have any checks to reset it if the other joker gets removed
id line drop the description
Glad it worked 
Ah I see the problem now. You're not returning out of your event
Put a return true on the line after your add_card
feels good to figure out how to add button to shop😅
huh?
oh the name lol
is there an infoqueue description for boss blinds?
it gives $100 😭
i dont think so, no
how would i pull up the infoqueue of an enhancement?
infoqueue[#1116390750314307698queue+1] = G.P_CENTERS['enhancement key']
finally, it works as intended. now, is it possible to make this tarot card not spawn itself?
anyone know why this is giving this error?
yeah i'm well aware, lol. i don't really know how to complete the function properly
i tried doing this, but all it seems to accomplish is that the bonus effect isn't triggered unless the second joker is already in my deck
if next( SMODS.find_card("j_bruh_bruhiosr") ) then
card.ability.extra.h_size = card.ability.extra.h_sizetest
card.ability.extra.dollars = card.ability.extra.dollarstest
end
if not next( SMODS.find_card("j_bruh_bruhiosr") ) then
card.ability.extra.h_sizetest = card.ability.extra.h_size
card.ability.extra.dollarstest = card.ability.extra.dollars
end
end,```
your not conditional wouldn't do anything because you're just changing the modifier variables into whatever your main variables are
Dynamically changing hand size with presence of a second joker the way you want I can see getting hairy very quickly
I'm not necessarily saying it can't be done, it just won't be fun
do tarots that change an enhancement have the infoqueue of said enhancement?
They should
i mean base game
yes
specific synergies within vanilla confines is what i'm trying to go for, if that's not for you then that's ok lol
it still doesn't really explain why the modifier variable is only affecting the decreasing hand size and not the increasing one, let alone how i'd get a conditional to actually work
ok so where exactly do you want this to happen
setting a blind?
playing a hand?
as soon as the second joker is bought
and removed when sold
I'm not saying fun gameplay-wise, I meant fun "actually making it work"-wise LOL
ah lmao
i mean i've been at this for 6 hours i can already feel it 
Oof understandable
is this balanced
I was gonna suggest this, but I don't think there's a context for removing one (outside of selling)
yeah you'll probably have to hook onto card:remove
true my coding is very bad but it works sometimes
or just make the joker thats required for that check for it on their side instead
wtf that was from eight days ago
yes i mod balatro now
haya kinda cracked at it I cannot lie
i got sick of ring racer after dynamite derby for a bit
lol
working on a joker that gives x.1 mult if hand is the same as the last played hand but it doesn't seem to be working bc it always goes to "if context.scoring_name ~= G.last_hand_played"
i gave up trying to open booster packs directly
its through a tag now anyways
have you checked if G.last_hand_played is only the name of the played hand?
attempting to make a joker that gains xmult when a holo card/joker triggers, but so far it's not working. it just refuses to gain the xmult
G.last_hand_played is a little deceptive in the sense that I believe that gets set at the beginning of a hand being played (rather than at the end). I'd recommend storing the hand in your card as opposed to relying on that and base your scoring off of that
anyway hi chat any ideas for my shitty fortnite mod
AI Darth Vader 
i wonder how i can make a pool for a certain type of joker
i wanna make a group for a very specific, yet small pool
💀 what would he even do lol
50% chance to say something obscene
be racist
i might be stupid but wdym by storing the hand in your card
I mean store the hand name as a variable in your card's ability config
1 in 2 chance to say something obscene and destroy itself
ohh
save the hand's name to card.ability.lastPlayedHand for example
I def could've worded that better originally, my bad lol
In what context? Vanilla?
you can add an SMODS.ObjectType in your main.lua and then add it into the pools paramater of your jokers
ideally yeah
ok, i can't figure out a way to make the tarot card not spawn itself, so i might add a condition to spawn 1 tarot when it's negative
maybe a little stronger than vanilla but for the most part i want to keep vanilla balance
wh
I don’t think exponential mult will ever be “balanced” in the context of vanilla
oh i see
fair enough
rate the balance from 1 to 10 where 1 is "worse than jens almanac" and 10 is "vanilla"
Exponential mult multiplies your es
add something similar to the first image in your main lua file and then you can add it to the pools section
would there even be like any benefit to having him? besides he destroys himself if he says something obscene lol
he increases investor value by being ai
(translation: temperance value)
He AI's all over the place
off topic but is your pfp two time
how do i add a condition for when the self card is negative?
Haven’t played Jen’s, tho it’s probably closer to vanilla. It’s just hard to rate because the nature of exponential mult is it can break endless
updated but now i'm getting this error (i'm trying to make a joker that gains x.1 mult if the current hand is the same as the previous hand)
it is also a food joker though so its probably not an endless staple
use context.post_trigger instead of context.other_joker
yes!
its a two time joker
that i made
for my mod
download Lua extension
sry when i see someone in a fandom i'm in my 2 braincells start cheering
no its ok
relatable
Yeah it’s a food joker, but anything that can dupe it or copy it will exponentially increase your exponent
real
you may like my mod when it releases then 😭
forsaken jokers
whats a roblox
for highscore runs itd be useful then
how would i fix the playing cards issue then
dunno about that, theres no context about playing cards being triggered afaik
context.individual and context.cardarea == G.play probably works tho?
need more fortnite fans to play my horrible creation fr
very small intersection of fandoms
so when i SMODS.add_card() do i say 'set = "charcuterie_mafia"'
i have another joker that does the same thing but it's foil instead of holo, and instead of gaining xmult it gives you $1
oh, but also
the prefix isn't needed
okie
forgot to explain the joker but i'm trying to make a joker that gains x.1 mult if the current hand is the same as the previous hand
i would probably check editions by using edition.key == "e_holo" instead
antiobelisk
-# i find keys more reliable personally
whar
true but its also like one of the only things im really know enough to make a full balatro mod about lol
how do i check if the self card is negative or not?
obelisk rewards you for playing different hands and this joker rewards you for playing the same ones
yeah it's a high score engine rather than a permanent thing
so that's the balance side
yeah and it resets if you play a different hand
probably dont balance around naneinf runs then
in terms of mechanics, there's too many numbers and I had to reread the thing 3 times to understand it
baron is balanced in the context of ante 8
in the context of ante 8 picking up that food joker wins the next two blinds easy
yeah but its rare
yeah so what's the point of it exactly?
cant just roll for it with 30 bucks to your name
idk i was hoping you'd figure that out
i needed to add it for consistency
XD you're the designer
with what?
im adding jokers based around the foods bonnie (from in stars and time) gives you and i may as well commit
pizza consumable can technically beat naneinf if you get there but it also degrades over time so a perkeo build wouldn't keep you in forever
did it need to be designed as a rare?
there are no rare food jokers in vanilla because that 5% chance is too low to be worth throwing effectively a consumable in the pool
in an average run, you wouldn't see it until you have a full joker roster
and the version you designed is powerful, yes, but it also burns itself after 2 rounds
true
probably lower the decreases
if you want a rare food joker, focus on a unique effect other than scoring that can serve as a slow burn
rather than just boom, high score, oh it's gone already
Hi, I am somewhat new to modding and I am starting to learn how to make a joker. I have a couple questions to ask. First off, how do I set the code to scale with chips instead of mult?
What coding software is best when coding with SMODS?
Thank you
SMODS.ObjectType = {
key = "mafia",
cards = {
["j_charcuterie_made_man"] = true,
["j_charcuterie_britalian"] = true,
["j_charcuterie_debt_collector"] = true,
["j_charcuterie_bunny"] = true,
}
}```
- in return, change mult to chips
- preferably vsc (visual studio code)
what could i have possibly done wrong
trying to add a condition where it'll spawn 1 normal tarot if it's negative, but it's crashing
key = 'tarot24',
set = 'Tarot',
atlas = 'smtarot',
pos = {x = 0, y = 0},
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random',
'{C:dark_edition}Negative{} {C:tarot}Tarot{} cards.',
'{s:0.8,C:tarot}Carnival of Shadows{}{s:0.8} excluded{}'
},
},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = G.P_CENTERS.e_negative
end,
use = function(self, card, area, copier)
for i = 1, j = 3 do
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
if self.edition = "e_negative" then {
SMODS.add_card({set = 'Tarot'})
j = 3
} else {
SMODS.add_card({set = 'Tarot',edition="e_negative"})
}
return true
end
}))
end
delay(0.6)
end,
can_use = function(self, card)
return true
end
}```
dont put them in cards , use the pools param
do you not have lua extension installed
Okay. I have vsc. But it's underlines smods
huh
I do have the Lua extension on.
does notepad++ counts?
:3
no
anyone know what's causing it to crash?
Is there a way to put SMODS into vsc?
how would i do that?
open the entire mods folder in vsc
i see no documentation
but also, i wouldnt recommend using uppercase in your keys
for various reasons
-# that i cant remember
Ok I ended up doing it like this since returning the old function in the hook crashed because it didn't like Self. Is this alright to do lol ```lua
if context.before then
function Card:get_chip_bonus()
return 0
end
end
if context.after then
function Card:get_chip_bonus()
if Card.debuff then return 0 end
if Card.ability.effect == "Stone Card" then
return Card.ability.bonus + (Card.ability.perma_bonus or 0)
end
return Card.base.nominal + Card.ability.bonus + (Card.ability.perma_bonus or 0)
end
end
please don't do that
What in the world
gulp!
what the shitting fuck
😨
Also I know how to fix that crash. Along with the regular args in the reference function, you can also just pass in self
local gcb_ref = Card.get_chip_bonus
function Card:get_chip_bonus()
if #SMODS.find_card("joker key") then
return 0
end
local ret = gcb_ref(self)
return ret
end
Oh this is more sane
put that outside of everything else, btw
should I be passing in self anyway even if it doesn't have parameters
yes
gotchya
dont define it like this
the correct way is Card.get_chip_bonus()
...no?
its Card.get_chip_bonus, not Card:get_chip_bonus
Oh. The documentation. I'm learning as I go. As of right now I'm just following along with the YT video on how to make a joker.
?
Card.get_chip_bonus wont call the function, you are just grabbing it
yes thats how hooking works
yeah im an idiot sorry
i think both . and : work here, if yours works
its fine :p
how do i define this objectype ughghg
(i'm trying to make a joker that gains x.1 mult if the current hand is the same as the previous hand) mult is updating properly, resets when the hand is different, but it doesn't actually multiply the score
what am i doing ???
what are you trying to do for context.joker_main
i changed it to "Xmult = card.ability.extra.Xmult" but it still does nothing
can anyone help?
Is there anything I can do to fix this issue?
The reason it does nothing is because your Xmult currently equals 1 lol
Actually no wait
function Card:func(args) = function Card.func(self, args)
that's when resetting
what are you doing 😭
My bad I see the actual issue. Change it to x_mult = card.ability.extra.Xmult
do you have an example of card:remove being hooked? i can't find a good example to work with 
i finally got the effect addition to work properly, so this is the last step i need
still isn't doing anything
local remove_ref = Card.remove
function Card:remove()
local ret = remove_ref(self)
--code
return ret
end
have you saved the .lua file and started a new run
are there any mods that implement object types
In your other contexts where you’re changing your Xmult value you’re forgetting an ‘extra’ lol
how would i go about converting that into an "if" statement?
if remove_ref(joker key)?
if self.config.center.key == "jokey_key" then
no way 😭 thank u sm
does talisman add ^ mult support?
yes
how
Epic coding moment lmfao
like how do i use it
We all have ‘em, dw about it
emult = ...
ok
HOW DO I MAKE AN OBJECT TYPE THAT CONTAINS CERTAIN JOKERS!!!! AUGGGGHHHHH
im this close
no clue, never used it before
Is there a way to put smods into vsc?
what, like open it with visual studio code?
roster so far (again)
can anyone explain why is it crashing?
key = 'tarot24',
set = 'Tarot',
atlas = 'smtarot',
pos = {x = 0, y = 0},
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random',
'{C:dark_edition}Negative{} {C:tarot}Tarot{} cards.',
'{s:0.8,C:tarot}Carnival of Shadows{}{s:0.8} excluded{}'
},
},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = G.P_CENTERS.e_negative
end,
use = function(self, card, area, copier)
for i = 1, 3 do
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
if self.edition == "e_negative" then
SMODS.add_card({set = 'Tarot'})
else
SMODS.add_card({set = 'Tarot',edition="e_negative"})
return true
end
}))
end
delay(0.6)
end
can_use = function(self, card)
return true
end
}```
is that Lancer
yeah lmao
extension for what? vsc?
yes
The lebanon
me !

also you cant really tell which line is 123 here lol
y'all know how The Fool has that text box that shows the last used tarot/planet card? How is that special text box done?
info_queue
does anyone know how to get the length of a value stored in omeganum
Um, why is it not loading?
Sorry for image quality
I dont know how to screen shot on my pc after i broke the prnt screen key
i got it working
windows shift s
i downloaded it like you've said, and it's not helping much
what is this based on
the extension should show missing symbols and such
no prefix
When I search for that, it said that there was no results found.
?
try restarting vsc, and which lua extension did you fownload
Frozen Soul, but in this context its closer related to Forsaken
download*
we got forsaken in balatro before GTA 6
in smods metadata guide
"prefix": "prefix", // [required] ! Must be unique. This prefix is added to the keys of all objects your mod registers. UNLIKE LEGACY HEADERS, THERE IS NO DEFAULT VALUE.
https://github.com/Steamodded/smods/wiki/Mod-Metadata
the first one after i search lua in extensions
but theres more
should be made by sumneko
yeah that
restart your vsc then
two time is a whole ass legendary ngl
bepis
you know stuff about talisman right
I have a Joker that's meant to retrigger certain cards, but whenever the retrigger is about to take place the game crashes, saying "attempt to call 'juice_up' (a nil value)"
so do I need to redefine 'juice_up' for my Joker
Aight, added it. But where do i put the prefix that i just made, or is it just a thing needed that isnt added to jokers
give me a sec to look over the code
Also how do i even give myself jokers with debugplus
hit 3 while hovering over in collection
Alright, im sorry for the image quality so good luck
if by "length" you mean number of digits then num:log(10) (or num:log10() idk if one or both work
Oooooh
i forgot about log
i also forgot uh
how it works
so ima look that up
log() is the opposite of exponents. Exponents = repeated multiplication, log = repeated division
not needed for smods.joker as far as i can tell
Oh. I've had the one by Sumneko
Alright, ill see if it works
log may be a very interesting thing for jokers
yeah, log the chips and X the mult by the same amount or something
It didnt work
actually wait
like a cursed Plasma deck almost
Uhh @signal rose let me get some better images
are you able to send the lovely console messages, might have a message saying what the issue is in there
it should say something like metadata issue if memory serves
if context.repetition and context.cardarea == G.play then
if context.other_card:is_suit(card.ability.extra.current_suit) then
return {
message = localize("k_again_ex"),
repetitions = card.ability.extra.triggers,
card = self
}
end
end
this retrigger code keeps throwing errors, saying its trying to call 'juice_up' which is nil
the errors aren't being thrown by my code directly, just as a result of trying to retrigger I think
yeah the message should say Found invalid metadata JSON file at [PATH], ignoring: [SMODS _ "src/loader.lua"]:226: id in the lovely injector if its a metadata issue
This was from loading up the mods
ok, it fixed the crashing, but the card is not working as intended
can you copy paste what the metadata file has?
You mean the .json?
yeah
comma on the end of prefix
And ill try to copy paste
missing
God dammit...
lmao happens to us all
if I had a nickel for every forgotten comma I might be as loaded as LocalThunk after making this game
Ok it should be fixed... unless idk how to spell prefix or smthin idk anymore
load it up and see if its working
i made it so if the tarot card itself is negative, it'll create one normal tarot instead of 3 negative tarots, but it's not working
key = 'tarot24',
set = 'Tarot',
atlas = 'smtarot',
pos = {x = 0, y = 0},
loc_txt = {
name = 'Carnival of Shadows',
text = {
'Creates 3 random',
'{C:dark_edition}Negative{} {C:tarot}Tarot{} cards.',
'{s:0.8,C:tarot}Carnival of Shadows{}{s:0.8} excluded{}'
},
},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = G.P_CENTERS.e_negative
end,
use = function(self, card, area, copier)
for i = 1, 3 do
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
if self.edition == "e_negative" then
SMODS.add_card({set = 'Tarot'})
else
SMODS.add_card({set = 'Tarot',edition="e_negative"})
end
return true
end
}))
end
delay(0.6)
end,
can_use = function(self, card)
return true
end
}```
Uhhh
Kinda?
Text broke
DOOOR STUCK
DO- DOORS STUCK
Type stuff
The numbersr between the hashtags work as arguments, so it should be the corresponding number listed in loc_vars
It is
so change it to #1# and put 69420 as the first argument in vars in your loc_vars function
Same number
Oooh
can anyone please help on why is my if statement isn't working?
Funny argument
self.edition is a table
should be if self.edition.negative if im remembering correctly
Thanks guys
nice, sorry i havent worked with smods.joker so was quickly trying to check the docs lol
can someone help me with this
lemme read the prior messages quickly
Idk, smod is simple i thought so i used it
Also in uh
Required mods
How do i make it require smod
I put steammodded
should just be setting it as a dependancy
This was before prefix
Is it just auto?
I've been using SMODS.Joker and all that stuff for my Jokers without the dependency, it's definitely more secure that way but if you just want to test the Jokers rn I don't think you need it
"Steamodded (>=1.*)"
]```
that will make it require some version of steamodded at least
Yeah, this was just my test joker
Alright then, ima add that then figure other stuff out
wait that will allow stable builds but not beta lol
Eh, stabel is better anyways right?
that would straight up disallow beta as far as i can tell, probably a bad idea, just use this
"Steamodded (>=1.0.0~ALPHA-0321b)"
],```
allows basically any usable version of steamodded
better to make it work for any version, rather than making you redo work later potentially
garbshit
just good practice
sorry, whats the actual error calling?
I'll get the exact error message one sec
all gd
functions/common_events.lua:1017: attempt to call method 'juice_up' (a nil value)
not my code, so something must be written wrong that makes the game think 'juice_up' is nil
whats the full smods.joker code? (if thats what you're using)
SMODS.Joker {
key = "checkered_joker",
loc_txt = {
name = "Checkered Deck Joker",
text = {
"Retrigger each",
"played {V:1}#1#{} card",
"{s:0.8}suit swaps at end of round"
},
unlock = {
"Win a run with the",
"{C:attention}Checkered Deck"
}
},
config = {
extra = {
triggers = 1,
current_suit = "Spades"
}
},
rarity = 3,
pos = { x = 4, y = 1 },
atlas = "jokers",
cost = 8,
unlocked = false,
unlock_condition = {type = "win_deck", deck = "b_checkered"},
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
loc_vars = function(self, info_queue, card)
return {
vars = {
localize(card.ability.extra.current_suit, "suits_singular"),
colours = {
G.C.SUITS[card.ability.extra.current_suit]
}
}
}
end,
calculate = function(self, card, context)
if context.end_of_round then
if card.ability.extra.current_suit == "Spades" then
card.ability.extra.current_suit = "Hearts"
else
card.ability.extra.current_suit = "Spades"
end
end
if self.debuff then return end
if context.repetition and context.cardarea == G.play then
if context.other_card:is_suit(card.ability.extra.current_suit) then
return {
message = localize("k_again_ex"),
repetitions = card.ability.extra.triggers,
card = self
}
end
end
end
}
its alot lol
everything else works perfect, just the retrigger causing crashes
it's crashing when trying to use the card
whats the error
can you take a ss of your code
-# im on phone so i cant read pasted code :3
i added a new condition
took out the again message and card = self, works now lol
it does the retriggers without a card variable?
I copied the retrigger code from Hack, but I guess I should be copying from the SMODS rebuilt version instead which doesn't have that
oh yeah definitely
no the card variable is still there, just removed the two lines surrounding the repetitions line
wait, i think i got the issue?
oh okay yeah that makes sense with smods method
bepis you want a screenshot of code or pasted?
not sure how to get the input_text box and the paste button to go inline with the text
i know the issues stems from the fact that create_text_input returns a column but i cant figure out how to get it to line up
i tried how it does it in the seeded run section but im pretty sure that only functions because its an object
nvm, i didn't fix the issue 💔
the game crashes if i click the card during gameplay
i can see why
in can_use, dont use self, use card
and card.edition wont exist if it doesn't have an edition, trying to check .negative from which will crash
if not card.edition or card.edition.key ~= "e_negative" then
but also, you should be returning false or true
bepis you got any idea on this?
to make custom unlocks for things, we use the check_for_unlock function right
now i can't use it when it's not a negative card
and it's crashing
Just started learning about modding.
Is there a way to test features real-time because I've been doing code edit and open the game and exit the game and repeat.
no
we all just exit and reload
be happy you dont have to wait 5 minutes per update with balatro like with some games
just to find out
you have
a
syntax error
and you dont even have a console
to find out what happened
I see, so I'm not insane for doing it this way, thanks a lot
modding literally any other game made me realize just how ass pavlov is to mod
it takes 5 minutes per update, with no console, an entirely different device you have to test on, and all you have as feedback is the effects ingame
if you're manually restarting the game instead of using the hotkeys, then you are slightly insane
theres a hotkey?
ALT + F5
trying another method
is there any way i can change this for the check to work?
press alt + f5 (holding "m" also works)
m
Alright thank you
I do code edit using Notepad++ in a Google Drive folder
j_modprefix_key when checking the key.
whats the goal of it
oh yea i'm a dumbass
joker buffed when a specific joker is bought, when that same joker is sold it goes back to normal
whats the joker with the buff's base and buffed effects?
my game is crashing whenever i try to use the card
is the one that buffs the other's only effect to buff that joker
and do you have an in_pool function if so?
Log?
the other joker has its own effect, but it also buffs this joker
i do not have an in_pool function though, no
its fine then
only need in_pool if a joker NEEDS another to work
what are the effects tho
+1 hand size $3 at end of round at base
if second joker is in hand, +2 hand size $9 at end of round
like what is it before buff and after buff
is this meant to be double handsize and $^2 or $*3
whatever works lol (if using exponent or multiplying), but essentially yeah that's the goal
if card.edition and card.edition.key ...
this tarot card creates 3 negative tarots, but 1 normal tarot if it's negative itself
use an update function to change the vars of the first joker if the other is found
It would create 3 normal tarots if it was negative.
so you can get the first joker after the second and still get the buffs
(also its simpler)
have like a base value and a changed value for each var
base never changes
here's what the full calculate function looks like right now
i'm guessing i have to change the if condition for the joker to be detected regardless of whether its obtained first?
changed = base * 2 if joker found
it's currently crashing on use
Log?
well
uh
all you need in calc is the adding of $ and handsize
dude, i already posted a few seconds ago #💻・modding-dev message
If the problem is the same then you haven't changed that.
Also you need to change the one at the bottom.
if i write it like this instead it crashes expecting a =
if i do card.ability.extra.dollars = card.ability.extra.dollars*3 it's the same i think?
(or maybe the solution is obvious and i'm just bad)
at the end of the round
you want it to work like Golden Joker then? where the money received happens at the end of the round?
yeah basically
haven't changed what? you just repeated what i already wrote in the code
right now it only works if the second joker is bought after the first joker, but not in the opposite
and it's not properly debuffed if the second joker is sold or destroyed
if you want it to work like Golden Joker use calc_dollar_bonus instead of calculate
calc_dollar_bonus = function(self, card)
local dollar_bonus = card.ability.extra
return dollar_bonus
end
I have this for one of my Jokers and it works perfectly
that's not the issue i have, the money generation itself works as intended
it's the value increase/reduction based on the ownership of the supporting joker that i'm having issues with
ok i replaced "or" with "and". now instead of crashing on use, it crashes on clicking the card. same error
Did you change the one in can_use?
how would I get a joker to trigger whenever a card is retriggered
yes, in both
yea i just ran into a problem
i was gonna try to code the joker youre trying to make
but you actually cant do update
bc change hand size is changing not setting
G.hand:change_size((-G.hand.config.card_limit)+numbertosetitto)
ye bc i needed to know if what i was about to suggest was gonna blow up or not
ok, i just need to remove "not"
yea you do have to do it whenever you sell or buy the other joker
No, I think it would be not (card.edition and card.edition.key == "e_negative")
but also do a check when you buy the first if the other already exists


so the way i'm doing it, i'm stuck with not being able to trigger it the other way around?
the decreasing checks do work if the conditional also works, but i haven't found a way to make a conditional related to selling or destroying work yet
lets say joker1 is the guy that gets buffed
joker2 is the guy that buffs him
ok, now how would i make it to spawn 1 normal tarot if it's negative?
yea idk i need to sleep youre on your own
Before the loop you would do ```lua
if card.edition and card.edition.key == "e_negative" then
G.E_MANAGER:add_event(Event({
func = function()
SMODS.add_card({set = "Tarot"})
return true
end
}))
return nil
end
trying to replicate the behavior of Observatory in a Joker, so I pretty much copy-pasted the code:
calculate = function(self, card, context)
if self.debuff then return end
if context.consumeable and context.other_consumable.ability.set == "Planet" and context.other_consumable.ability.consumeable.hand_type == context.scoring_name then
return {
x_mult = card.ability.extra.Xmult,
message_card = context.other_consumable
}
end
end
but it only procs once, even if multiple planet cards of the specified poker hand are held
key = "testfiresr",
blueprint_compat = false,
loc_txt = {
name = 'testm',
text = {"{C:red}+#1#{} hand size,",
"Earn {C:money}$#3#{} at",
"end of round.",
"If {C:red}bruhio{}",
"is in your deck,",
"{C:red}+#2#{} hand size,",
"Earn {C:money}$#9#{} at",
"end of round."}
},
pos = { x = 0, y = 0 },
rarity = 2,
atlas = 'mindatest',
blueprint_compat = false,
cost = 6,
config = { extra = { h_size = 1, dollars = 3, h_sizetest = 2, dollarstest = 9, h_sizereset = 1, dollarsreset = 3 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.h_size, card.ability.extra.dollars, card.ability.extra.h_sizetest, card.ability.extra.dollarstest, card.ability.extra.h_sizereset, card.ability.extra.dollarsreset } }
end,
calculate = function(self, card, context)
if context.card_added and table.contains(bruhio, context.card.config.center.key) then
G.hand:change_size(1)
card.ability.extra.h_size = card.ability.extra.h_sizetest
card.ability.extra.dollars = card.ability.extra.dollarstest
if context.selling_card and not context.blueprint and context.card.config.center.key == "j_bruh_bruhio" then
G.hand:change_size(-1)
card.ability.extra.h_size = card.ability.extra.h_sizereset
card.ability.extra.dollars = card.ability.extra.dollarsreset
end
end
end,
add_to_deck = function(self, card, from_debuff)
G.hand:change_size(card.ability.extra.h_size)
end,
remove_from_deck = function(self, card, from_debuff)
G.hand:change_size(-card.ability.extra.h_size)
end,
calc_dollar_bonus = function(self, card)
return card.ability.extra.dollars
end
}```
i'll repost my code in case anyone can figure out the solution to this 
currently the "bruhio" buff works only if "bruhio" is bought second, but not if "bruhio" is already owned. when "bruhio" is sold, the conditional to reduce the buffs back to normal doesn't get applied (debuffing itself already works, it just doesn't have a proper conditional)
it's meant to be +1 hand size $3 at the end of round at base, and +2 hand size $9 at the end of round when buffed
Try doing if context.other_consumable and context.other_consumable.ability.set == "Planet" and context.other_consumable.ability.hand_type == context.scoring_name
thanks, it's now working as intended
Somethingcom you got any idea for this?
I don't know much about UI.
fair
if someone can help it would be much appreciated 🙏
"attempt to index field 'other_consumable' (a nil value)"
so I think I need the first check to say context.consumeable
If you are checking if context.other_consumable then that shouldn't happen?
hang on I mispelled it lmao
now its telling me I have an error in my loc_vars when it worked perfectly before 😭
What does your loc_vars look like?
"Candy Cane" from Cryptid has an effect like that, I think you can reference how it does it
ooo
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.Xmult
}
}
end,
corresponding config:
config = {
extra = {
Xmult = 1.5
}
},
What's the log?
if more is need lmk
Not sure if there's a simpler way to do it in vanilla
line 330 is the "card.ability.extra.Xmult" line btw
I'm going to assume card.candy_caned isn't a vanilla property
is lua like python where you can just make up properties and as long as it's consistent then it's fine
I fixed this bug, but the Joker is still only being proc'd once
What is the full calculate code?
this is it, except I changed context.consumeable to context.other_consumable as suggested
like if I just say like context.other_card.abracadabra without defining it previously does it just assign it as false by default
No, it would be nil.
you can do this to any table value, I believe it gets set to nil by default. Just make sure what you're indexing is a table
o
You didn't change context.other_consumable.ability.consumeable.hand_type to context.other_consumable.ability.hand_type?
was just wondering if i would literally just have to swap the name of the property here
new if:
if context.other_consumable and context.other_consumable.ability.set == "Planet" and context.other_consumable.ability.hand_type == context.scoring_name then
same issue as before
full joker code:
SMODS.Joker {
key = "nebula_joker",
loc_txt = {
name = "Nebula Deck Joker",
text = {
"{C:planet}Planet{} cards in your",
"{C:attention}consumable{} area give",
"{X:red,C:white} X#1# {} Mult for their",
"specified {C:attention}poker hand"
},
unlock = {
"Win a run with the",
"{C:attention}Nebula Deck"
}
},
config = {
Xmult = 1.5
},
rarity = 3,
pos = { x = 1, y = 1 },
atlas = "jokers",
cost = 8,
unlocked = false,
unlock_condition = {type = "win_deck", deck = "b_nebula"},
blueprint_compat = true,
eternal_compat = true,
perishable_compat = false,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.Xmult
}
}
end,
calculate = function(self, card, context)
if self.debuff then return end
if context.other_consumable and context.other_consumable.ability.set == "Planet" and context.other_consumable.ability.hand_type == context.scoring_name then
return {
x_mult = card.ability.Xmult,
message_card = context.other_consumable
}
end
end
}
Try changing the Xmult variable name to PlanetXmult temporarily.
so rename the variable in config or create a local variable PlanetXmult in calculate
Rename the config variable.
same problem unfortunately
It still only triggers once?
yeah one sec
Try removing the if self.debuff then return end
situation:
playing a Pair only gives 1.5X mult when I should be getting 2.25x (1.5 * 1.5)
if I can't get it to work I'll just scrap the idea, I'm kinda upset that I can't get it to work though
im assuming this is the right way to check if cavendish is extinct... right?
No, because cavendish_extinct doesn't exist.
You would have to add it manually.
how would i do that?
You would patch or you would take ownership.
which one is easier?
also... does this mean that if cavendish goes extinct, you could still rebuy it in shop?
Yes.
huh... i didnt know that
I think Thunk didn't bother since 1/1000 is ridiculous odds anyway
i guess
Your check is wrong. The Xmult you’re getting is from the joker during joker main. You need to change your config to config = {extra = {xmult = 1.5}}, update your return accordingly, and then change the line that checks the hand type to context.other_consumeable.ability.consumeable.hand_type == context.scoring_name
How would you go about making code run at the end of your played hand
I wanted to reset the xmult my joker gained after each hand is played
oh yeah... your right.... i guess now i know how to patch it, but how do i make my mod effect vanilla jokers?
i see what i have to add, i just have no clue how to add it
Context.after
would i just add cavendish to my mod, but make it linked to the key for vanilla cavendish? im just assumming if i do that it will override the old cavendish code
thank u :3
No, because it would have your prefix at the start.
this seems to have disabled the joker entirely. Keeping the first part of the statement as either context.consumeable or context.other_consumable keeps the game from crashing but the joker does nothing, and switching it to context.joker_main causes the game to crash
What I mean is you would patch here: Then add this line if self.ability.name == 'Cavendish' then G.GAME.pool_flags.modprefix_cavendish_extinct = true
SMODS.Joker {
key = "nebula_joker",
loc_txt = {
name = "Nebula Deck Joker",
text = {
"{C:planet}Planet{} cards in your",
"{C:attention}consumable{} area give",
"{X:red,C:white} X#1# {} Mult for their",
"specified {C:attention}poker hand"
},
unlock = {
"Win a run with the",
"{C:attention}Nebula Deck"
}
},
config = {
extra = {
xmult = 1.5
}
},
rarity = 3,
pos = { x = 1, y = 1 },
atlas = "jokers",
cost = 8,
unlocked = false,
unlock_condition = {type = "win_deck", deck = "b_nebula"},
blueprint_compat = true,
eternal_compat = true,
perishable_compat = false,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.xmult
}
}
end,
calculate = function(self, card, context)
if self.debuff then return end
if context.joker_main and context.other_consumable.ability.set == "Planet" and context.other_consumable.ability.consumeable.hand_type == context.scoring_name then
return {
x_mult = card.ability.extra.xmult,
message_card = context.other_consumable
}
end
end
}
modified code
Remove the if self.debuff then return end
same crash:
attempt to index field 'other_consumable' (a nil value)
occurs on the line containing context.joker_main
and im assuming i just re-create cavendish in my mod like this, and it should override the vanilla cavendish behaviour?
No, I said you should patch or take ownership.
That’s not what I told you to replace, sorry for the misunderstanding, let me grab the entire check for you
what do these mean then? i have no clue how to do either of these
alr my bad, just lmk what the correct thing is if you don't mind
if
context.other_consumeable and
context.other_consumeable.ability.set == 'Planet' and
context.other_consumeable.ability.consumeable.hand_type == context.scoring_name
then```
awesomeee it worked
thank you all so much for the help, this Joker was a nightmare lol
Does anyone know how to create a custom booster pack? I am having trouble understanding the wiki
I don't want to add custom cards or anything to it
It would be like a standard pack but beefier
Is there a way to give a random amount of money between -20 and 20 after a round (with a joker)? I am having trouble understanding the example mods from the guide
This is my Function that crashes the game: SMODS.Joker { key = 'joker2', loc_txt = { name = 'Gold Gold Gold', text = { "Gain any Value between {C:money}-20${} and {C:money}20${}" } }, config = { extra = { money = 4 } }, rarity = 1, atlas = 'FunnyMod', pos = { x = 0, y = 0 }, cost = 6, calc_dollar_bonus = function(self, info_queue, card) return { vars = { math.Random(-20, 20)} } end, }
And the crash error log is in the txt
pseudorandom("seed", -20, 20)
Also you just do return pseudorandom("seed", -20, 20) in calc_dollar_bonus
i feel like the game is gaslighting me at this point
Okay, I'll try that
is it possible to change the rarity colors and names?
That worked! thx for helping me with that
Yes.
cool
Does broken_record = { have an ending }?
it should
lemme triple check
time to count the amount of brackets my thing is using
it seems to have an ending yea
one sec lemme kill the whitespace
broken_record = {
name = "Broken Record",
text = {
"This Joker gains",
"{X:mult, C:white} X#1# {} Mult each",
"time a scored card is retriggered",
"Resets at the end of hand",
"{C:inactive}(Currently {X:mult, C:white} X#2# {C:inactive} Mult)"
},
config = { extra = { x_mult = 1, x_mult_gain = 0.1 } },
pos = { x = 0, y = 0 },
rarity = 2,
cost = 1,
blueprint_compat=true,
eternal_compat=true,
unlocked = true,
discovered = true,
effect=nil,
soul_pos=nil,
calculate = function(self, context)
if self.debuff then return nil end
if context.joker_main then
return {
Xmult = self.ability.extra.x_mult
}
end
if context.individual and context.cardarea == G.play then
if not context.blueprint then
if not context.other_card.retriggered then
context.other_card.retriggered = true
else
self.ability.extra.x_mult = self.ability.extra.x_mult + 0.1
return {
extra = {focus = self, message = localize('k_upgrade_ex')},
card = self,
colour = G.C.RED
}
end
end
if context.after and self.ability.extra.x_mult > 1.0 then
self.ability.x_mult = 1
return {
card = self,
message = localize('k_reset')
}
end
end
end,
loc_def = function(self)
return { self.ability.extra.x_mult_gain, self.ability.extra.x_mult }
end
}
Hey guys, what kind do I use if I want to make a booster pack act like a standard one?
Or does it not matter?
why is the color not changing?
key = 'cr_common',
loc_txt = {
name = 'Common',
},
badge_colour = "#78412F",
pools = {
["brave"] = true
}
}```
could I set earned money from a round to 0?
try badge_color instead of badge_colour
they use 'colour' all over the game
It needs to be HEX("78412F")
ahh, ok didn't know that thought it was color also in balatro 😭
still doesn't work
Code?
?
nvm, i didn't set the rarity to the card itself
You mean there no blind reward money?
apparently the problem was random whitespace I didn't see
yes
Try looking at how Mr. Bones works.
Hey guys, I am trying to make a custom booster pack, and I got this error:
oh wait I don't think I included loc_vars
oh I don't need them for a booster
Mr.Bones, doesn't have anything to do, with reward money? I meant the money that isn't Gold Gold Gold in this case
Mr bones definitely does.
When you die you get no rewards when mr bones saves you.
in the code it just saves you, there isn't anything about money, atleast not anything I see
Yes, look at how saved works.


