#💻・modding-dev
1 messages · Page 429 of 1
as a hypothetical example a joker that turns +mult from other jokers into +$
No, because context.post_trigger happens after the joker triggers, you would hook SMODS.calculate_individual_effect for that I think.
Should be gone now
ty, theres still one in modding chat in case you havent seen it yet
nevermind as soon as i wrote that message
@astral zincits in #⚙・modding-general , #🎥・videos-and-streams , #🌱・seed-chat and every other channel with image perms
i see that vanilla remade uses the card:remove() function to delete cards like icecream and popcorn when they run out. Would there be a way for me to detect that?
Yes, you would hook it.
Hello, does anyone know how to fix this? I have created a folder to store sound assets. I have created SMOD sound and its key, and in (sound = (key name)) an error like this occurs.
my mod isn't showing up in the game, anyone knows what I might have done wrong? I tried following documentation closely when making this and the tutorial video by bepis looks about the same too
how do you do that?
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...
this randomly started happening when i boot up the game
ok nvm figured it out
How could I check how many differents suits there is in played hand ?
(Ping me if you answer please)
would anyone know whats causing this?
You would iterate over the full hand and put each suit found in a table.
can we see your assets folder
how do i move a ui element to be in front of everything else? is it a setting of the uibox, root, or is it to do with how its created
hey, im back, and i got a problem, or more of "idk how to this" issue,
i have a legendary card with a texture, but how do i make it show up like the other (perkeo, chicot and ush) mine just shows up as is with the card on top and the char on the bottom
or for exemple like the screen above
it randomly went away, im not really sure what was wrong
You mean the soul is below the main card?
it stopped happening before i could debug
you mean the assets folder is gone?
no the error
yh
soul_pos?
mhm
Swap soul_pos and pos
i can't really test it rn but i'll trust you for sure
so you need to have an atlas with 2 cards
im on a secondary computer, without moded balatro and haven't got the time to mod it
pos is for the background aka your first card
the soul_pos is the thing that will be displayed up on the card
mmmh mhhhhhh
anyways, how would i access this rarity for my joker? putting rarity = "use_uselessrarity" does not work
soul_pos = {x = 0, y = 0},
rarity = 4,
pos = { x = 0, y = 1},
like this ?
rarity = "modprefix_key"
i still can't post photos i think
swap them around
thats what i did
is 0,0 card the thing ytou want to display on top?
Your mod prefix is use?
yes
i forgor to change it 💀
what mod adds r
None
its supposed to be useless
but i wanted to add a synergy with letter deck js for fun
which makes it less useless tho.
ohhhh
Does somebody know how to replace a default sound effect of a joker with a custom one?
nvm the error is not because of that
Is it a crash?
SMODS.Sound
the issue is with hex colors rn
You forgot to put HEX() around the badge colour.
I mean, I tried like this but it still doesn't work.
I can play the sound directly but it doesn't activate at the exact moment when my joker upgrades...
Remove .ogg from replace
aight imma try like this
alr it worked, thx!
OMG IT WORKS... but for some reason that sound also plays when I select a blind.
I want it only to play when the joker upgrades its current value
Yes, because you're replacing the entire sound.
Everytime it is used it will instead be that one.
is... there a way I can fix this?
What is the goal?
what do you mean by that?
I just said that I wanna make the sound play ONLY when the joker upgrades its mult value.
Iirc it’s called possession or something
possession?
sound = 'modprefix_Dodgeball_sfx'
In the return.
Mm maybe not. I’m not finding the wiki page
But it’s something like SMODS.take_over
should I get rid of the replace?
Hey, I tried to use quantum enhancements in smods, but it makes the game quite slow, this is the code I used for it:
if context.check_enhancement and context.other_card:get_id() == 2 then
return {m_wild = true}
end
Yes.
Quantum enhancements does that.
why is it like this T-T
OMG IT WORKS NOW, THANK U!!!
It's because it checks everytime something checks for an enhancement.
thanks for the clarification
it works only when smooting is disabed T-T
and it'll have to calculate for each joker, yh?
You didn’t export your 1x and 2x files properly
i know the error, dumb stuff, i forgot to resize the x2
Lol
but i did on krita i can't resize it freely without losing quality :(
wdym
No, just it being enabled lags the game.
damm
There’s probably a setting for it
i took the perkeo part of the jokers.png from the files of the game, but it was already in 71x190, and with krita when i resize it to x2 it gets all blurry
use Nearest Neighbor not Bicubic
@knotty compass also had that issue. Maybe @chrome widget too. I suggest creating an issue because that had been marked as solved AFAIK
explain this things to me
Use “no interpolation”
when you select image and select scale image to new size, itll ask what resize method to use, itll show up as Auto(Bicubic) but you need to switch it to Nearest Neighbor
oh ok
Is there a function that closes the game
My solution was quite literally just disabling the G.deck and G.discard card areas. In combination with quantum enhancements, the game's performance was piss poor. Don't know if that is still an issue with current versions
I get the same crash I think
ok so i found the function the game uses for food jokers to destroy themselves. its ```lua
G.jokers:remove_card(self)
is that something i can hook onto?
No, it is card:remove()
SMODS had an utility to destroy playing cards maybe it could be used here
Idk
Check the wiki
@tall wharf
That just unemplaces it from the area.
isnt that just vanillaremade? not base game?
No, it's a vanilla function.
hooking card:remove is not viable for their use case because they want to check if a food joker destroyed itself
mhm
yep
i mean yeah you could have things apply a flag and check it in card:remove or whatever but you get the point
Really abusable
i wonder if it's luajit2 moment
im just not sure how exactly i would hook G.jokers:remove_card(self). My guess is that i will need a global flag and then have my joker check if the flag is changed
"food jokers" is not a well defined term and it becomes impossible when you get to cross mod compatibility
thats the problem
when does this happen btw
Lmao
When I click on the Mods button
It is though?
i am looking at the base game code and the food jokers dont use card:remove to destroy themselves
they use G.jokers:remove_card(self)
how do you check a food joker was removed specifically by it expiring
unless i am looking in the wrong place
They do use card:remove()
im 99% sure it ends up getting called somewhere down the line
i am not seeing it in card.lua
is self more or less a pointer in this case then?
self is the card.
even if you hard code to check for specific jokers you have no idea if the popcorn ran out or it got killed by dagger unless you patch every single food joker to set a flag and at that point id consider it triggering a custom context instead
okay dagger was a poor example because you can actually check that
madness?
they both set getting_sliced so you can actually check that
so i would check for card:remove() and not getting_sliced?
youre still gonna hard code things unless you consider mr bones edible
is there a way i can make the game play a custom sound?
Yes.
how do i create a ui?
as opposed to a yui
mr bones uses start_dissolve
Yes.
im pretty sure theres more destruction methods dont set getting_sliced
so i would need to hook onto G.jokers:remove_card(self) since this is only called for food jokers
right?
No.
unless i am completely misunderstanding smth
That is called in card:remove()
i am very new to this
So it would trigger twice.
I still am going to treat this as the place to dump crash logs if i don't know the culprit
i do not see an easy way to implement this
is there a way i can detect messages being sent?
cuz each food item has a special message it sends when it dies
"food joker" is a category that does not exist so trying to handle them specifically is kind of a pain in the ass
Yes, but how would that be better than checking the key?
the simplest way would be patching every food joker to trigger a custom context when it expires but that obv doesnt play well with other mods
@maiden phoenix i know the issue now
fair enough. wait does selling a card also use card:remove?
yes
Awesome
it also gets called when you open your collection and close your collection
these things can be checked for obviously
Every time a card leaves the screen, it is often removed.
ui being schewpid
Can someone explain to me why I have two .lua deck files in the same folder (under the same mod name) and only one of the two decks are loading?
did you ever load the file
Yeah, both should be getting loaded.
smods wont load every single lua file it finds it a folder
you have to tell it to get loaded
How do I do that?
you have the main lua file you set it in your json
that main lua file has to load the others
SMODS.load_file
Main lua file?
"main_file" in your json
only that file gets loaded by smods
that file has to do the job of loading all others
What is the json?
simplest way would be
assert(SMODS.load_file("relativepath/to/luafile"))()
uhhh where are you setting your mod metadata
so am i sorta just screwed? /gen
Uh... metadata?
cuz im not entirely sure how i can implement my idea
i mean it currently scales whenever one of the food jokers is purchased
All of that is in the headers of the lua files.
it just might not have the resetting capabiliteis
What is the goal?
well currently my joker gains X1 mult for each food joker purchased, i want to make it so the scaling resets whevever a food joker naturally dies (it will be like the food is spoiling)
that main file needs to load all the others
only by its own effect (eg. not by something like ceremonial dagger) right?
yes
if so you'd need to manually take ownership of every food joker you want compatible
I can just scrap the resetting concept
is there a guide on making deck texture packs somewhere?
it is kind of a weird concept anyway
i liked it :/
well sure its cute but in terms of gameplay it just says you cant keep gros michel around
not eternal
what am i saying
wait ... "gros michel" is cross-language ? not only in french ?
i knew for vaendish but not for gros michel, go on with your convo sorry
@maiden phoenix
?
i fixed it
nice
does it still crash
Oh the alignement is funky here
it's so beautiful
@tepid crow i fixed it
can't be helped tbh
Would I need an end statement after the assert command?
the text is long
Use maxw for text, game will figure out for you how to scale it
container
Maybe it doesn't work without more advanced technology, I don't remember tbh
what im i doing wrong
can we see the loc_vars
in the joker definition
there should be a property called loc_vars
"#20#" makes it sound like you have 20 vars
do #1#
meaning its looking for the 20th variable currently
but then how much mult is it supposted to know it has
the number between the hashtags isn't actually what the real number is
it's which number to access in loc_vars
britain
oh
it knows if you put #1# because itll put the 1st variable from loc_vars there
the local vars dont have a number that i see tohugh
it does
it just says card.ability orer smth does it not
yeah
yea that IS a variable
card.ability.extra.mult is a number
card.ability.extra.mult corresponds to this
the config of a card is stored in card.ability
it's looking for your cards config table, then the extra table, and it checks for mult then (and it finds 20) so it gives you 20
@primal robin it works i just needlower num
and you usually put all your variables in extra (aka card.ability.extra)
actually hold on go back
how much basic coding experience do you have (doesn't have to be in balatro modding)?
no balatro modding experience
so if you want a different variable (such as chips, money, etc) you can add another variable there (like chips = 10)
I know lua and python though
My hard working on UI have some good results 
k
a little bit of lua but im a python dev
so card.ability.extra.mult is checking for what's in your joker's config table, in the extra table (within the config table), and then it checks for mult
if you know UI stuff can i ask some questions (ik dontasktoask but i dont want to bother you cos i have quite a few questions)
i am going to sleep
where does the card.ability poart come from thoughh
😭 damn
alright who here knows the basics about UIs 😭
im going to sleep idc
card is being passed into loc_vars as a table
ability is an object of card that is the same as config
what's wrong here
Left block obviously bigger than right one
*element
Because title have 2 lines
anything in config is put in card.ability
dont ask why its ability and not config idk either
i need help with textures and things like that
im just going to copy and paste code from vanilla remade together to make it
just ask the question don't be vague
it <orks fine in not smoothing, and <hen smoothing textures it does this, the card is in 142x380
and i was vague to know if i could ask without interrupting
can i see the assets folder
dw about it the point of the channel is to ask questions
the blank one is x2 frogor to mark it
im looking through the source code of various mods, it seems kind of similar to roblox studio which ive done before
which amkes sense they are the same language
huh
dont see any issues?
and it works fine when textures arent smooth?
if needed
yeah when 1x is used
show us the measurements of both images
if i had to guess the x2 version is too small
try doubling the height and width of the image in the x2 folder
x)
I dont get this snippet, why do they need to calculate the driver tally twice
so i put back the old texture and voila i guess
cause its a local variable in both
why does it need to be there twice
oh yeah
theres probably a faster way to do it but im not smart enough to figure that out
this crashes the game why
what is it meant to do?
if the sell value of all jokers is less than $8 gives x 3 mult
seems right?
send the crash report
nvrm i fixed it
ngl balatro modding is easier than i thought
pretty much every idea tyou have is in base game so just copy and paste the code change some stuff and boom
How do I make custom suits?
does anyone know why my hooks don't work? ```lua
local para_extra_slots = function(self)
return self.ability.para_negativesticker or self.config.center_key == "j_para_cooledwater"
end
local para_card_removal_old = Card.remove_from_deck
local para_card_addition_old = Card.add_to_deck
Card.remove_from_deck = function(self, card, from_debuff)
if para_extra_slots(self) and G.jokers ~= nil and self.area == G.jokers then
G.jokers.config.card_limit = G.jokers.config.card_limit - 1
end
return para_card_removal_old(self, card, from_debuff)
end
Card.add_to_deck = function(self, card, from_debuff)
if para_extra_slots(self) and G.jokers ~= nil and self.area == G.jokers then
G.jokers.config.card_limit = G.jokers.config.card_limit + 1
end
return para_card_addition_old(self, card, from_debuff)
end
this is supposed to make cards with negative stickers and cooled water give +1 joker slot but it does nothing
(cooled water will never have the negative sticker)
...i probably shouldve asked if theres like a. template mod thing. like something you should start making a mod with.
like how, for lack of a better example, Psych engine has a template for pack.png and pack.json or whatever
Idk abt templates, but: https://github.com/Steamodded/smods/wiki/Your-First-Mod
there’s a .json file template in the Mod Metadata section on the SMODS wiki
hey anyone here able to help me with this problem? I posted it a while ago but didn't see anyone respond 😭
Ugh fine, I'll break out the programmer socks
Lmfao
Youre a cheater cause you already are a goddess of knowledge
Damn getting called a goddess rules. Thanks dilly
:D
can we see it more in detail (like with a video)?
also can you repaste the images down here
yeah, one second
I'm kinda wiped but I'm getting ever, ever closer to finishing this damn mod
Almost 100% complete programming Stands aside from one that I still want to do in anticipation of Quantum Ranks
Here are the iamges, let me see if I can get a recording
alright, here is a pretty bad steam recording:
SMODS.Joker:take_ownership("abstract",
{
config = {
extra = {
mult = 3
}
},
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult * (G.jokers and #G.jokers.cards or 0)
}
}
end,
calculate = function(self, card, context)
if context.joker_main then
return {
mult = card.ability.extra.mult * #G.jokers.cards
}
end
end
}
)
just hovering over Abstract Joker is causing the game to crash
your video doesnt play
did you manage to fix this btw?
I have no clue why that would be the case, I can play it one my end through steam?
changing the second part of math.min to self.config didnt fix it
i tried downloading it and it says i need to pay a dollar to watch it
upload it to youtube or something
wtf
do you know which one of the 2 numbers turned into a table?
Gosh I'm tired. Been working on this mod for about four months and my enthusiasm isn't really waning but I'm certainly feeling it drag on
heres the full config + where math is
hmm that all seems fine
why is this saying assertation failed?
with a UI element like this, how do i make it like other menu popups? ie its in front of everything, has a transparent backdrop preventing clicking on anything else, and closes with escape
bump
Remove assets/sounds/ in the path and make the M in the key lowercase.
im guessing its to do with the G.jokers bit in the loc_vars, maybe add a check to make sure G.jokers exists first
alright I'll try that, thx
how do i check if a card is being added or removed from the joker slots? (in a hook of Card.remove_from_deck and Card.add_to_deck)
self.area == G.jokers doesnt work
Same error, here's the response code
I made it into a gif instead, does this work?
context.card_added
if context.card_added and context.card.ability.set == "Joker" then to be clearer
yeah that works
idk why that doesnt do anything honestly
check midas mask?
i dont have context im hooking Card.add_to_deck not in a calculate function
ahh ok, idk then. sorry
Code?
Does anyone have any good examples of patching/hooking loc_colour? I'd like to move my colors off of a globals.lua patch and handle them better
local para_extra_slots = function(self)
local slots = 0
if self.ability.para_negativesticker then
slots = slots + 1
end
if self.config.center_key == "j_para_cooledwater" then
slots = slots + 1
end
--print("extra slots:" .. slots)
return slots
end
local para_empty_slots = function(self)
if G.jokers ~= nil then
--print("empty slots?" .. tostring((G.jokers.config.card_limit - #G.jokers.cards + para_extra_slots(self)) > 0))
return (G.jokers.config.card_limit - #G.jokers.cards + para_extra_slots(self)) > 0
else
return false
end
end
local para_card_removal_old = Card.remove_from_deck
local para_card_addition_old = Card.add_to_deck
Card.remove_from_deck = function(self, card, from_debuff)
print("In jokers: " .. tostring(self.area == G.jokers))
print("Joker existence: " .. tostring(G.jokers ~= nil))
print("Space:" .. tostring(para_empty_slots(self)))
if para_empty_slots(self) and G.jokers ~= nil and self.area == G.jokers then
print("Card has been removed.")
G.jokers.config.card_limit = G.jokers.config.card_limit - para_extra_slots(self)
end
return para_card_removal_old(self, card, from_debuff)
end
Card.add_to_deck = function(self, card, from_debuff)
if para_empty_slots(self) and G.jokers ~= nil and self.area == G.jokers then
print("Card has been added.")
G.jokers.config.card_limit = G.jokers.config.card_limit + para_extra_slots(self)
end
return para_card_addition_old(self, card, from_debuff)
end
What is the goal?
to add joker slots when a card with the negative sticker or cooled water is added to joker slots
I can't tell where in my code I'm doing math using the extra table, especially since this is similar to what they have for abstract Joker in Vanilla Remade
and remove those slots when theyre removed
Do local ret = oldfunction(...) at the start then do return ret at the end for both.
this doesnt help whatsoever
make sure you've restarted the run btw
i did
and its not crashing in collection, only in run?
nvm I figured it out 
helloooo new modder here!
send us the assets folder
assets folder of what specifically?
your mod?
because this happens even with my new mod im working on gone 🔥
yeah sure lemme grab it
what mods do u have
besides yours
off the top of my head i think debugplus, nopeus, and the example jokers mod is enabled
plus a couple friends of jimbo additions
its referencing paperback and bunco in the error which is crazy to me because theyre not in my mods folder they havent been for a while 😭
example jokers?
its one of the mods that adds like, smods implementations of a few vanilla jokers, like castle, gros michel, i think runner is in there
great question actually i can remove it
can we get a more exact list of the mods?
(given the crash im inclined to believe one of the friends of jimbo mod is causing the error)
Hey sorry to interupt, but I changed the playing card base art, while maintaining the same file name, and now it renders as blank. Any reason why?
uh yeah sure, is there a way to get the list of enabled mods without having balatro open?
no
yeah any time inside the run, just not in main menu
you can get all mods (enabled or not) though through looking at the mods folder
like any time i view it in collection inside the run
like in the balatro files?
yes
im gonna try removing all the foj first and then ill get back to you then because theres like 3 qol things besides that and no acatual mods on
extracted with 7 zip, replaced and in files it looks fine
dont do it like that
oh how should I?
I don't have smods
bump
oh
I did source code modification
do not modify the source code thats stupid
once you learn smods you should be able to take ownership of SMODS.Rank and SMODS.Suit
I do have lovely installed however
weird... do you have a minimum reproducible example?
wdym
the smallest code possible that still causes a crash
that I can just copy-paste into my machine and make it crash
ok got it to work not sure exactly what i did just kept removing stuff but 👍 thank you friends
you can just binary search every friends of jimbo mod to find the one that crashes if you want to keep some of those mods
how many did you actually have anyways
literally just 3 😭 its fine now that theyre back idk what this was
hi, what's the best way to modify the function of an existing joker?
oh so this was just a curse of the machine spirits then
take ownership
thats what im gathering yeah
how much is left overall
ty ty, ill read up on it
i fucked up hard by writing all the code for my jokers before doing any of the art cause now i gotta draw 12 more jokers 😭😭😭
how do i mod balatro
local para_extra_slots = function(self)
local slots = 0
if self.ability.para_negativesticker then
slots = slots + 1
end
if self.config.center_key == "j_para_cooledwater" then
slots = slots + 1
end
--print("extra slots:" .. slots)
return slots
end
local para_empty_slots = function(self)
if G.jokers ~= nil then
--print("empty slots?" .. tostring((G.jokers.config.card_limit - #G.jokers.cards + para_extra_slots(self)) > 0))
return (G.jokers.config.card_limit - #G.jokers.cards + para_extra_slots(self)) > 0
else
return false
end
end
local para_card_removal_old = Card.remove_from_deck
local para_card_addition_old = Card.add_to_deck
Card.remove_from_deck = function(self, card, from_debuff)
local ret = para_card_removal_old(self, card, from_debuff)
print("In jokers: " .. tostring(self.area == G.jokers)) -- This is always false
print("Joker existence: " .. tostring(G.jokers ~= nil)) -- This works as intended
print("Space:" .. tostring(para_empty_slots(self))) -- This works as intended
if para_empty_slots(self) and G.jokers ~= nil and self.area == G.jokers then
print("Card has been removed.")
G.jokers.config.card_limit = G.jokers.config.card_limit - para_extra_slots(self)
end
return ret
end
Card.add_to_deck = function(self, card, from_debuff)
local ret = para_card_addition_old(self, card, from_debuff)
if para_empty_slots(self) and G.jokers ~= nil and self.area == G.jokers then
print("Card has been added.")
G.jokers.config.card_limit = G.jokers.config.card_limit + para_extra_slots(self)
end
return ret
end
```why doesn't this check if a card is being added or removed from joker slots?
is there a way to trigger a sound when opening a pack
do you want to do it yourself or install other peoples mods
Yes.
make my own
yeah use the balatro modding starter pack then
ok thanks
alright
do i need to use a certain function for boosters?
Programming wise, about 15-20 cards, 6 blinds, and then an undetermined amount of achievements and challenges
What is the goal?
youre getting there for sure
i give you 17 minutes to do it all=]
when a certain pack opens
i want it to play this sound
yes but you gotta gimme a small piece
SMODS.Consumable:take_ownership('temperance',
{
config = { extra = { max = 50, money = 0 } },
loc_vars = function(self, info_queue, card)
local money = 0
if G.jokers then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].ability.set == 'Joker' then
money = money + G.jokers.cards[i].sell_cost
end
end
end
card.ability.extra.money = math.min(money, self.config.extra.max)
return { vars = { card.ability.extra.max, card.ability.extra.money } }
end
}
)```
hello I'm new to modding; and i need a lil help with something
what is it?
dont ask if you can ask just ask the question
i want to playtest my jokers
hold tab
hold tab
OMG TY
how can I check if two or more different face cards played have different suits?
I tried like this by adding the "and context.other_card.suit ~= context.other_card.suit" but it it crashes the game.
Perhaps patch card:explode()?
ahhh
patches
never was good with those
you could maybe hook it instead
No, the play sound is in the middle of the function.
i remember my days as a youngin where i just set my money to 1 trillion and just kept rerolling the shop cause i didnt know abt the tab menu
i could try to work with patches
the soulsborne games would say it's a bad idea though /j
diet beer
lmao yeah
can someone tell me why the function doesn't get called, despite me scoring while the joker's xmult is equal to 0?
yeah it needs a calculate function
if greater than 0
thats what the if statement is doing
my studio code is dumb and cannot locate SMOD
so i cant navigate under .
You are still not returning the func
??? is that not less than equal to
open the whole mods folder in vscode
i literally realized the moment i hit send
that should fix it
i was looking at the wrong spot
alr tyty
i JUST did this on the LAST joker 😭
BTW if you look closely there is a hidden amogus in my sprite
could you please help me with this patch
i'm not sure how to make those
well, "my" sprite
got it
How can I check if two or more different face cards played have different suits?
I tried like this by adding the "and context.other_card.suit ~= context.other_card.suit" but it it crashes the game.
ye >:3
how do i check if a card is being added or removed from the joker slots? (in a hook of Card.remove_from_deck and Card.add_to_deck) self.area == G.jokers doesnt work
thank you
card.suit doesn't exist.
It's card.base.suit
aight, imma try like this
Also card.suit will never not be equal to itself.
its 100% on the github page for calc functions
hold on
its not in a calculate function
its in a hook
Also context.other_card doesn't exist.
Card:
oh, that's why it still crashes
it works fine either way
i thought you just said it didnt work
oh then i have no idea
i fully did not know this game had a hooks system
wait, so then how can I fix this?
it doesnt thats just how lua works
context.other_card would be context.scoring_hand[i] here.
that's just how languages in which functions are full objects work
OMG SMOD IS IN DA HOUSEEE
oh my god I found it I'm an idiot
YAAAAAAAAAHHHH
so both replacing the context.other.card but still keeping the .base.suit , right?
it's crashing on this line self.ability.money = math.min(self.ability.money, self.ability.extra) in card.lua's Card:update
Yes.
what does that mean
how do i check if a card is being added or removed from the joker slots? In a hook of Card.remove_from_deck and Card.add_to_deck. There is no calculate function and I have no context. self.area == G.jokers doesnt work
One message removed from a suspended account.
that you didn't overwrite that code and that's the default behaviour of temperance (in the function I specified)
so temperance is entirely hardcoded?
is that what functional programming is? where you can use functions as variables?
this patch stuff is confusing...
i'm looking at the booster repo
and i gather what i'm supposed to do is:
use pattern target card:explode()
and then the payload needs to check that it is my specific booster pack
and then play the sound?
No.
not really, just... split across multiple functions
because i changed the use behavior of temperance as well but i dont know if thats the problem
javascript does that too, its not functional prog its just functions can be stored
weird, it doesn't upgrade the joker if the face suits are different, but it doesn't crash this time.
It is probably because of the "~=" ?
There's a lot of different running pieces, of which you overwrote one. The other pieces then made assumptions that were no longer true
functional prog is just a philosophy of "not using classes" paradigm
is there a way fo fix that
more or less
Not really? Most languages support using functions as variables though, which has some very nice use cases and is definitely an important part of functional programming
oh, in this case then I should add a "==", right?
Then it would be useless because a variable will always be equal to itself.
oh
Probably. Why are you taking ownership of temperance again?
i am correct, right?
calculate = function(self, card, context)
if context.before and context.main_eval then
card.ability.extra.scored_suits = {}
end
if context.individual and context.cardarea == G.play then
if context.other_card.base.suit
and not card.ability.extra.scored_suits[context.other_card.base.suit]
then
card.ability.extra.scored_suits[context.other_card.base.suit] = true
return {
mult = card.ability.extra.mult
}
end
end
end
end
@signal lotus here you go
Perhaps.
i have a joker thats supposed to double the effect of tarot cards but if i cant get temperance to work then it doesnt have to affect it
absolute cinema
config = { extra = { mult = 4, scored_suits = {} } }, here's what's in config
-# you are not peter griffin bro /j
most of the other code is grab bag-specific and boilerplate stuff
then which prompt should I put to see if a card suit is different from another one?
Hmm... did any other tarots give issues or have you not even looked at other tarots yet?
im def still learning so thanks 🙏
if card1.base.suit ~= card2.base.suit
i'm looking at the repositories and they all use the .toml file type
do i need to create a separate file?
Yes.
for loc var?
no, for the config.ability.extra calls
I'm kinda lost rn, are the card1 and card2 are local variables?
What is the goal?
all of the tarots where the can_use is tied to max_highlighted seem to work in terms of my modifications (ive tested that kind of thing with Death and that worked, havent tested the other ones but theyve been similarly changed in code). WoF was a weird one but i just realized smth else i could do to fix that up a bit. other than that, emperor, high priestess, judgement, and fool have yet to be fully tested
yours would just be return { vars = { card.ability.extra.xmult } } (or Xmult or whatever you use for xmult)
the repo also has this patch
is this acceptable to use?
they have a nice page look:
https://mikaschoenmakers.github.io/MikasBalatro/
their jokers are a lil quirky but design wise i think they are not balanced enough to be fun
or should i stick with just putting the pattern as self:explode()?
hiya! remind me how to check if a playing card has a particular edition?
but they have a very good grip on the modding fr fr
if card.edition and card.edition.key == "e_modprefix_key"
cheers ^^
mm, then why doesn't this work?
local waxed_cards = {}
for i = 1, #context.removed do
if context.removed[i].edition and context.removed[i].edition.key == 'e_phanta_waxed' then waxed_cards[#waxed_cards + 1] = context.removed[i].key end
end```
card.key doesn't exist.
wait i do 'if card.edition and card.edition.prefix_key' ?
ah oops -u-
hold on
wait, but the length of waxed_cards is 0
ep1n is my mod prefix and charred is the edition key
The joker's goal is to check that if two or more face cards (that have different rank and can have the same suit but it must be different rank; for example jack of hearts and queen of hearts is allowed, king of spades and king of diamonds is allowed but jack of clubs and another jack of clubs is NOT allowed ) are played in a poker hand.
If the condition is satisfied, the said joker gains XMult.
Basically faces with same rank and same suit at the same time are not allowed.
wait no, it is working, it's just not returning the message properly -u- sorry to bother!
@daring fern?
this does seem to work @daring fern
No, it needs to be Card:explode()
is it possible for a tag to trigger under two different circumstances? currently trying to add a double tag that triggers like normal when getting a tag but dissapears when a blind is selected
can anyone tell me why this triggers twice? like the "cut off the first trigger to trigger it again" type of double trigger
Yeah it's difficult... some of the tarots like fool or strength are hard and especially modded tarots are difficult. You could do something like this for temperance (you'll have to fill in the if-statement)
SMODS.Consumable:take_ownership('temperance',
{
loc_vars = function(self, info_queue, card)
if ... then
return { vars = { 2*card.ability.extra, 2*card.ability.money } }
end
return { vars = { card.ability.extra, card.ability.money } }
end,
use_consumeable = function(...)
...
end
}
)
if i have a boolean for if a planet card has been used this round
i typed enter too early gonna try that again
in my experience its generally cardarea, if cardarea is not defined there it runs the calc function for every card area
not sure exactly tho
just that?
if i have a boolean for if a planet card has been used this round, would i want that where i have it now or in the bottom variable bit in the screenshot? for reference this is the first joker ive done, ive gotten it to scale by 5 mult each round but the gimmick is that it should reset on not using a planet card
would the area be jokers here
You would want it in the config.
oh so i need a new file for defining variables?
thats the most readable, but like i said it runs for every card area, so you can pick any one of them @sonic cedar
No.
waittt no sorry i see what youre saying 🤭
so how can I check if a face card is NOT ENTIRELY equal to another face card?
this finally fixed it (im not doing the adaptive description thing though, its funnier that way)
if face1.base.name ~= face2.base.name
how could i modify this ui?
into what?
uhh
ok well G.jokers makes it not trigger at all
what would be the right position & payload for this?
like i want to show diffrent decks
just use galdur https://github.com/Eremel/Galdur
oh well then it's not bc of cardarea and i haven't the slightest clue 💔
how do i check if a card is being added or removed from the joker slots? In a hook of Card.remove_from_deck and Card.add_to_deck. There is no calculate function and I have no context. self.area == G.jokers doesnt work
back on the burner it goes 
i think this is the part thats crashing but im not really sure why? its saying to add an extra end but that doesnt actually fix anything it still gives the same error i fear
The pattern would be play_sound('explosion_release1'), the position would be after and the payload would be play_sound('modprefix_key')
hello people
like this?
how would get a joker to make a random consumable IF the card played is a 4,2, or ace
idk how to get the current hand or how to spawn consumables basically
card.base.face.name doesn't exist and any property cannot not be equal to itself
okay, done
anything else?
do i need to reference it anywhere in my lua code?
No.
ok, so how can I make the properties different if they cannot be equal to themselves?
wait
maybe I found the solution
If you want to check 2 different cards you need to check 2 cards and not the same 1 card.
all modified tarots seem to be working as intended (if i can get WoF to work)
this didn't work
Remove the space in the pattern.
I got my first joker made sankiu team im very grateful <3
this seems significantly worse than cola
yes, its a common one
small cola can
next one is going to be wine
i mean thats true but also this is beer so its already significantly worse than cola
which gives you the rare
true
yeah i want to introduce some common beverages first
add a rare that gives you a legendary when you sell it
thats called cocktail
hey how do i get access to balatros source code
and its super duper expesiv but yh
you unzip the .exe
from steam files
thats possible?
ye
Hey guys, how possible do you think this joker would be, the Joker's name is Zalgo
-- Possible Effect: After Boss Blind, Randomly selects 2 non-Zalgo and non-combined jokers and creates a new joker with the
-- same effect as the selected jokers with randomn variation, remove original jokers from poll if in play. ( 3 usages max???)
-- 0.75 to 1.25 range for variation round up for higher then 1, round down for lower then 1. minimum value of 1
-- non-blueprint compatible? only allow blueprint to and brainstorm to only combine with each other?
still no change
do not
Do not modify
99 percent of the time theres a better way to do what ur trying to do
but yes you can read its v cool
readings unhelpful cause it doesnt use smods
modding is safer
What does that line look like in the lovely dump?
its wot we do
WoF finally stopped being a stubborn bastard so now im done with tarots
you can go to this guide first:
https://github.com/Steamodded/smods/wiki
it has a cat
cute
hi aure's cat
is this possible 🥺
theoretically yes
it looks like this
it will take forever to do but yes
with the catch that you'd have to make 22500 jokers
assuming this is the only joker ur adding
so it merges two cards?
wait no not quite
How would I check the id of a joker in the shop?
i'm guessing it being in the lovely dump means that it didn't change
21906 jokers
merge 2 jokers and slgihtly randomize their effects, asusming numbers
meh idk it would make negatives a lil redundant
game design wise i think its better to just have a chance to make negative with debuff
its in most effects the same thing
would this work?
context.other_card:get_id() == "Ace"
maybe you can code like a joker-linking thing or something
where if one gets destroyed they both do
do i put 14 instead?
Yes.
thx
would it be possible to add another joker's effect to an existing joker? like how you can add chips to a card?
thats new features my head would get dizzy coding that
Is the file called lovely.toml or a toml in a lovely folder?
No™️
😂
unless you mean without the fusion (so unconditionally)
there doesn't look to be a toml file
yes but you would need to like, use a lot of queries
what does mean?
No, I mean the file with the lovely patch.
how do i check if a card is being added or removed from the joker slots? In a hook of Card.remove_from_deck and Card.add_to_deck. There is no calculate function and I have no context. self.area == G.jokers doesnt work
pretty much for each value existing if its non default from the cards and then manually pass all as parameter for the new one
bump
no
i'll get around to doing that i guess
so a if cascade thats ugly
I swear to god, I'm trying every command possible but I stil don't know how to check 2 different cards:
or a foreach that captures on a list
card.face.base.name doesn't exist.
welp, it was an idea 😦
thanks for help tho
ideas are cool have more of em
renamed it to lovely.toml
still nothing
the thing is that making a negative with debuff is gameplay wise super similar and implementation wise duper simple
what are you trying to do here?
@vivid grotto so if you are willing to make that smol adjustment you got yourself a new legendary
gg
i renamed the file
still nothing
check if two or more face cards are entirely different.
by that I mean that they cannot be the same suit and rank at the same time (like jack of clubs and another jack of clubs).
Im trying to have it so the soul card does an animation, but its not moving, the soul is there
if card11111111111111111111111111111.base.name ~= card222222222222222222222.base.name
Ya know, I'll look into it my friend, much appreciated
I can put it on my list if you want, i think it sounds like an interesting joker!
but im going to implement some other jokers first
loop through all cards, save all face cards in a table, and if you find a face card not in the table and the table isn't empty, then there are 2 different face cards
get some practice
Sounds good to me 👍
No?
if you just want suit and rank then instead of saving face cards as a whole save the suit and rank of any face cards as a table
then what exactly is the problem here
instead of saying no, tell them why you disagree
If you put all face cards in the table there will be no face cards that are not in the table.
Same with the question mark react
bump
Just saying no or reacting like that without explain at all generally is not helpful
but if I try like this the card1 and card 2 are not defined:
...uuuh
in the loop you check if that card is already in the table
what are collection_rows in consumable types?
That would never work.
card.sort_id is always different.
Also card.playing_card
save suit-rank pairs instead of card objects and check for duplicate suit-rank pairs
considering they wanted to check for suit and rank
if i remember correcly, each number is a row with the number being how many cards are in that row
for example: {2, 1}
x x
x
so like
is it because it's in the src file?
i am not sure to be honest
Yes, it needs to be directly in the mod folder.
probably
then how can I define them?
wow very helpful something
What actually is the goal here?
hold on let me write pseudocode for my solution
so
lovely.toml
assets
sounds
sound.wav
1x
[image files]
2x
[image files
src
[insert lua files]
main.lua
modname.json```
is this the correct file structure?
What does the joker do
Yes.
Check if 2 or more face cards are entirely different on a played poker hand.
By that I mean that they cannot be the same suit and rank at the same time (like jack of clubs and another jack of clubs).
If there are no same face cards then the joker gains an amount of XMult (currently X1)
well
after fixing the "match indent" part
it crashed :]
local faces = {}
local passed
for k, v in pairs(context.full_hand) do
if card:is_face() then
if not faces[v.base.name] then
faces[v.base.name] = true
else
passed = true
break
end
end
end
if passed then
-- gain xmult
end
What could I use in Card:set_cost() to look for a specific joker?
if self.config.center.key == "j_modprefix_key"
Thanks!
how do i check for a card's base suit?
card.base.suit
could use some help here
What does it look like in the lovely dump?
to be clear
are we referring to the dump folder in the lovely mod folder
Yes.
well, now it doesn't crash but it still doesn't upgrade the card If I play 2 or more different face cards.
question for future reference, does context.destroy_card tie all of the playing card's attributes (suit, enhancement, etc) to destroy_card?
local isdifferent = false
local facecard = nil
for i = 1, #context.scoring_hand do
if (context.scoring_hand[i]:is_face()) then
if facecard == nil then
facecard = {context.scoring_hand[i]:get_id(), context.scoring_hand[i].base.suit}
elseif facecard != {context.scoring_hand[i]:get_id(), context.scoring_hand[i].base.suit}
isdifferent = true
end
end
end
Change it to local passed = false and the if to if not passed then
isdifferent will be true if there are two different face cards
!= doesn't exist.
context.destroy_card is the card.
So yes.
well, now there are 2 problems, the joker upgrades even if the face cards don't score and it also upgrades if there's only one.
hold up lemme try the code that SMODS.fool sent.
Change it to context.scoring_hand
how can I, on a blueprint-like joker, detect when it copies another joker to decrease a variable?
Also check if #context.scoring_hand >= 2
I'm specifically working off of the vanilla remade blueprint joker
I had to solve this exact issue gimme a moment to find the code I used
You would check if SMODS.blueprint_effect returns anything.
local blueprint = SMODS.blueprint_effect(card, other_joker, context)
if blueprint then```
The function only returns something when there's a trigger
I think it's kinda important to note that it really is per trigger
So if it's copying a joker that acts per card (eg 3 mult per diamond card), your variable would be changed once for each card
Yes, but it won't always return something if there is a trigger.
theyre beautiful im clicking my heels together
When copying jokers that don't return anything, because they don't return anything.
Nice!
These are banger joker arts
That's not a particularly useful answer
Is this something that occurs with any vanilla jokers because if it does then I might have to write a patch to change that
the tuna is by my friend and atlas is mine :3 very proud of them
If a joker doesn't return anything then SMODS.blueprint_effect wont return anything but it will still copy the card.
No I get that
But I also want to detect when a blueprint style card copies a card
So if there's any jokers that you know of that don't return anything when triggered, I'd like to know so I can change them to return something
Also it really feels like you're patronising me instead of answering my question and you're still doing the question mark react thing which I've asked you before not to do so I'll ask again
Can't answer that but I know yahimod has a subway surfers joker with an animated sprite so you can look at that
Brother what part of my request is that hard to understand 😭
The question mark thing is honestly passive aggressive and counter productive
I'm more than happy to try and answer any questions that you may have
So ask away
well, it works but also on the same face cards with the same rank and same suit unfortunately.
Lmao okay thanks
How do I go about adding the little information bubble to the right 
info_queue
what would I put in there
Print facecard before the joker scores
o
thanks
I'll rephrase my original question, something, in case I worded it wrong
You mentioned that some jokers may return nothing when triggered, so I'd like to ask if this is a purely hypothetical issue or there are some jokers in vanilla that do not return anything
The return when triggered is important to me so I'll fix any that don't return anything, if there are any in vanilla
wait, i'm confused, wdym by that?
I couldn't find any vanilla jokers that do that.
is there a variable for how many slots a card (specifically a consumable) occupies?
Alright that's good to know, thanks
If I wanted like a custom information box that wasn't for a specific Joker or enhancement, how would that go
Replace the center with {key = "keyoflocalization", set = "setoflocalization"}
o I meant more like custom text
Like if I wanted to use it to explain a mechanic or smth
Sorri im bad at explaining things
trying to implement a group of cards which occupy half a slot
You have to put it in the localization.
No.
Oki
I'll see if I can do something
Thank u :3
You would just do area.config.card_limit = area.config.card_limit + 0.5 when added and do the opposite when removed.
ah right
run print(facecard) in context.joker_main
been away from lua for a bit, how can I return SMODS.blueprint_effect alongside other things like messages? is that possible?
I'm forgetting basic syntax...
like this?
I don't think you need to return that, it's a function
However
For returning multiple effects in general
You do need to return it.
BRO stop with that question mark thing I'm so tired of it 😭
Okay looking back at my original code I realise I made a mistake
However
You can do two things to return multiple effects
You can add another return effects table in the extra field
If I knew how to make a discord bot I’d detect Something’s question mark reacts and call him out on it
I don’t tho
local ret = SMODS.blueprint_effect(...)
return recursiveextrafunction({ret, {message = "message"}})
So like in my earlier example where I put the effects in blueprint, you can put it in blueprint.extra
You can also run the function SMODS.calculate_effect
Then retriggers wouldn't work.
Retriggers of what sorry
Retriggers of anything.
Could you expand more on how that would play out in practice
Because I use that function primarily for things like extra messages
as long as you do return nil, true retriggers would work fine
or return a standard effects table of course
No, I'm referring to using SMODS.calculate_effect to add retriggers to a card.
what is recursiveextrafunction?
I personally wouldn't use it for smth as important as that
I've only really used it as a substitute to having a massive nested table
A function that goes down all the extra tables, and when it finds one that doesn't exist it will put the new extras in it.
You need to define it though.
@wind steppe there's still the problem that the joker upgrades with two equal faces with the same suits and ranks (if I play a pair).
you'll be able to use SMODS.merge_effects(...) when the new release is out
how do i get the length of a key-based table?
Iterate and count up with pairs.
i guess that's my only option huh
This is me asking for my own knowledge but why doesn't using # work for counting these?
# finds the highest consecutive index
because # only cares about indexed tables
yeah
What’s in the console when it scores?
it doesn't technically count the size of a table
You should see it if you have DebugPlus
nil
Ah that's good to know
I'm not entirely sure what you mean by this. do you have an implementation of this function?
Replace if facecard == nil then with if not facecard then
...it still prints nil and upgrades the joker
Fix the indentation maybe?
Idk
Can you send the full code again
does anyone know how stuff is cached? Ive changed this config label a couple times and rebooted the game but it isnt reflecting that name change in game
initially i had
get_reps = function(params) dosomething end
which just didnt show in the extra table at all.
repetitions: 1
When i changed the line to
another_label = "another thing"
i get the following. Anyone know how to get the game to recognize the most recent version?
in my joker's config:
extra = {
repetitions = 1,
another_label = "another thing"
}
},
... (later)
logger.log(card.ability.extra)
...```
Log:
```INFO - [G] [Example] Table:
repetitions: 1
get_reps: another thing```
Make facecard start as false instead of nil
Change the if statement to beif ifdifferent == true then
*isdifferent
I'm too tired for this I'm gonna sleep
My main recommendation to you is to do a ton of debugging
Put print statements in each step
Including to print out some of the variables if needed
Did you try my solution but with the changes I said?
yeah and it still has the same result.
I'm gonna go sleep too at this point
gonna work on it tomorrow
thank you guys still
No, I meant these ones:
oh, I haven't tried those, gonna try them tomorrow.
I hope I haven't exhausted your patience.
thank you guys still for the help, really appreciated it.
Ofc, I hope anything I suggested has helped
hey I am trying to make this rat enchantment that acts as both a steel and stone card, but I want it to convert unscoring cards into rat cards, my current implimentation isn't working, any ideas?
I have this Joker that applies a multiplier to other Jokers' mult effects. I want to make it amplify the mult gain on things like Ride the Bus and Obelisk, and the effect seems to work based on the updated description, but the game crashes every time. I took ownership of Ride the Bus to try and fix the problem, but nothing worked
context.held doesn't exist and you should be using quantum enhancements.
Neither does context.scored or card.scored
gonna probably need the full error log and the code for the joker
if context.individual and context.cardarea == "unscored" then
local other_card = context.other_card
G.E_MANAGER:add_event(Event({
func = function()
other_card:juice_up()
other_card:set_ability('m_mbm_rat')
return true
end
}))
return {message = "Ratted", colour = G.C.PURPLE, message_card = other_card}
end
I can hear it in my head
ba bada baaaa
@signal lotus adding a pool to a joker and indexing said pool (your implementation would slightly differ in how you index)
so you could do
pools = { ["Your_Pool"] = true },
shit
how do i add pools to the mod or is there a way i make them before i add them to jokers or does just adding them to the koker make them exist
how would i go about removing chips from scored cards?