#💻・modding-dev
1 messages · Page 300 of 1
use ability.name instead of .key
lsdfkghksdf my mod is jazzy, and your mod is azzy so your jokers are j_azzy. this is mildly funny
I'm once again asking for the method to destroy unscoring cards.
I recall there's a smods optional feature but I forgot what's its name.
there we go
im doing something wrong here could i get some help
isnt upgrading the card or adding the chips
replace all self with card inside the calculate (so don't replace the function(self one)
wonderful thank you
Figured it out, modeled it after what the Lobotomy Corporation mod does for the pebble enhancement. i put this in my main.lua (EDIT: this runs on EVERY hand draw, not just inital hand draw, i need to tweak this)
sry to ping but its still not working and im not sure why
is it maybe cuz im checking the suit wrong or is that fine
it doesnt run the upgrade or anything and doesnt even add to the card
just inactive
is there a way to hard set the sell price of a joker? i want a joker to cost money to sell but by default it floors at 1
i know patching is an option but if theres an easier way that would be neat
I can probably further adapt it for my needs.
ty
how do i make a joker never appear in the shop?
hooking
in_pool
i tried that but it still appeared
why are there jokers
What is the return key for adding retriggers when context.repetition?
I thought it was retriggers but it doesn't work now.
And I don't remember why I thought it was retriggers, either.
how
Fallback
idk my gf was streaming their gameplay of my wip mod and got a joker that wasn't supposed to appear in shop
repetitions
Weird question, vanilla Balatro doesn't have anything for calculating Poker Hands when you play 8 cards at once right?
I asked how you did it
Not how it was obtained
in_pool = function(self, args) return false end
It crashed.
Wait this runs on EVERY card draw not just the inital draw of each hand, i need to tweak it a bit more
That should stop the Joker from appearing. Either there was something else going on or it's a SMODS bug
i'll do some more testing :p
was she playing any modded deck or anything or was it just a normal deck and it showed up normally in the shop
yeah doe/balanced sleeve doesnt check for inpool
you can do no_doe = true on the cards center though
Did it hard crash?
if my mod isnt known for anything else it WILL be known for cool soul sprite custom animations
i have 2 now
i plan on continuing the trend
managed to get my laptop to actually record some footage for once
its choppy but its better than nothing
fixed
Is that missingno?
hi, quick question — what's the syntax for getting the key of a consumable card?
would it be card.ability.key?
card.config.center.key works
indeed
awesome, thanks :D
Is it a retexture or is it a custom joker?
custom joker
What does it do?
Under if context.repetition and context.cardarea == G.hand then, is it possible that context.poker_hands is nil?
Asking this because I was under impression that context.poker_hands is always there during eval_play.
Bad EGG is the one on the right in the video, right now im not 100% sure on the specifics but its basically a near useless joker that costs money to get rid of
That must've been a pain to code, but that might just be because I'm new to modding so seeing that one joker does all of that is interesting
im trying to have an enhancement add permamult and chips to other scored cards
how can i make sure it happens before theyre scored?
Try changing trigger to before
the calculate function is only about 30 lines long actually, though i haven't actually made it turn into bad egg yet, right now it destroys all of the copies because thats its old effect before i decided on Bad Egg
thatll probably reduce the lines of code if anything
what are the base weights of common/uncommon/rare jokers
ill give it a try
nope, they still dont count during scoring
Try context.main_scoring instead of context.before
pretty sure that doesnt work either
ill check
bump
bump
happens even later
isnt before the earliest context thats applicable here?
not "joker my soul"?
how would i make a joker transform into a different joker? i need missingno to become Bad EGG if its chance fails
from what I've seen, couldn't you remove the missingno and just create a Bad EGG? (Idk the specific code sorry)
It has to be spelled "JDON", them's the rule.
set_ability
It has to have "Joker" them's the rule
isnt there like 1 non-legendary that breaks that rule or smth
No
I've been meaning to make a mod, but idk what I'd add, any ideas?
the closest thing is to do list which has it as an acronym instead of an actual word but it doesnt really count since joker is still in it
ok this works but it transforms instantly, how would i have it do the flip animation that death does? im looking at the code for death and i cant see what does it
events
getting this error:
in the line:
if context.destroy_card and context.cardarea == G.hand and context.destroying_card.ability.name == 'Wild Card' and pseudorandom('badhairday') < G.GAME.probabilities.normal / card.ability.extra.odds then
well yes that part was obvious
ideas? :P
refer to context.destroy_card, not context.destroying_card
is there a context that is called when the joker is added to the joker area?
context.destroying_card only exists some of the time [when the card checked is a card that was played and scored] due to being used by vanilla
ahhhh icicic
context.card_added
Aura
should i change that everywhere, then?
check out terraforming in the dev branch of my mod
you can use context.destroying_card where only destroying played and scored cards, but context.destroy_card always works
great. thanks! :D
i see no aura in this chat
perfecto, it worked! thanks ^^

Bro you’re john aure(a)himself
Is there a way to make consumables:
A. Give money
B. Destroy cards in the deck
where's the jdon, you missed it
Uhhh yes but they already do that
inside Jimbo's heart
he needs to have it surgically removed
does anyone know the best way to do a texture replacement on the newest version of steamodded? Been trying to replace the 8BitDeck texture for awhile now, but it keep crashing when I try the outdated method, and Maverick (texture loader) doesn't have support for the front designs it seems
Nvm then, look at me asking redundant questions
doesn't work
what is your smods version
Utility joker idea
Mr. Mrs.: Kings and Queens count as the same rank
and nothing was output in the lovely console either, so the condition was never entered
SMODS.DeckSkins
I figured it out, m just using SMODS.Atlas and replacing the default texture
I don't recommend doing that
why's this not working?
card = self wouldnt work
change it with card = card
ohhh
also self.config.extra
What is the optional feature named if I want to use context.cardarea == 'unscored'?
i think its not optional anymore
how do i create a joker from a custom pool instead of from all jokers?
if you dont care about rarities use pseudorandom_element on a list of keys and pass the key to SMODS.add_card
if you do, make an SMODS.ObjectType and pass it's name as a set to SMODS.add_card
ok
This doesn't remove unscored cards. Please help.
in add_card's key value?
yes
the game crashes when i play a hand
I thought it should be key = "j_elle_residents".
Oops, I didn't look upward, sorry.
oh, if you want to use an ObjectType it should be in set, without a key. also area is not a string
oh ok
ty
yeah the area thing may be a slight problem lmao
thanks for pointing that out
im not sure to understand the difference between the contexts cards_destroyed and remove_playing_cards even with the doc
i see the glass and caino jokers have their code in both context but i dont quite get why and what does it change
the first is used to destroy cards and the second is called when a playing card has been destroyed
it's just making jimbos
yeah i was going to say, i think the cards field on objecttype doesnt work with modded jokers
you need to inject them after
sorry i was trying to see if i could fine some nicer code than mine lol
ok lol
key = "Twisted",
default = "j_entr_memory_leak",
cards = {},
inject = function(self)
SMODS.ObjectType.inject(self)
for i, v in pairs(Entropy.FlipsidePureInversions) do
self:inject_card(G.P_CENTERS[v])
end
end,
})
SMODS.ObjectTypes.Twisted:inject()```
heres an okay example
ty
game's crashing on startup,,
SMODS.ObjectType {
key = "Residents_Base",
cards = {},
inject = function(self)
local jokers = { "elle_chloe", "elle_sophie" }
SMODS.ObjectType.inject(self)
for i, v in pairs(jokers) do
self:inject_card(G.P_CENTERS[v])
end
end
}
SMODS.ObjectTypes.Residents_Base:inject()```
wait i think i see the problem
i think it needs to be in the same indexing formatting as before
it needs to be j_modprefix_key
i have a crash on card destruction (wether played or not) about "juice_up" and got no clue what it is
whats the code?
ty
(i ended up using only remove_playing_cards as i didn't find further info on the context.destroyed_cards)
still nope,,
local jokers = { "j_ellejokers_elle_chloe", "j_ellejokers_elle_sophie" }
wait that isn't the prefix
😶🌫️ How safe is using such...
try this
return {
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.Spectral,
func = function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.0,
func = (function()
SMODS.add_card({
set = "Spectral"
})
G.GAME.consumeable_buffer = 0
return true
end)
}))
end
}
whats the crash
how do i get a list of all legendaries? i thought i could use SMODS.Consumable.legendaries but its an empty table
works!! thank you
@red flower hello N' how are you
G.P_JOKER_RARITY_POOLS[4] i think
I just spent ~1h making a Joker compatible with perhaps the objectively worse effects in the game, Magic Trick and Illusion
hiii im doing well and you
i think the keys are wrong yeah
also there are bug reports about Illusion going back almost a whole year
which I found out about while reading the code then testing it
i've tried elle_chloe, j_elle_chloe, j_elle_elle_chloe, and it's not working
why does magic trick exist
can you show me the joker definition and your json/mod header
thunk somehow had an idea worse than skipping v_v
maybe inject doesnt work either lol

i dont use this anymore but i did it like this
?
obviously mine is more complicated but the idea is that you hook SMODS.injectItems
and then you do SMODS.ObjectTypes["modprefix_key"]:inject_card
can you give a simpler code example pls,, 😭
j_elle_elle_chloe would be the right key idk why its not working though
local SMODS_injectItems_ref = SMODS.injectItems
function SMODS.injectItems()
SMODS_injectItems_ref()
for i, v in ipairs(G.P_CENTER_POOLS.Joker) do
if v.key == "j_elle_chloe" then
SMODS.ObjectTypes["elle_Residents_Base"]:inject_card(v)
end
end
end
ty
its actually simpler to look in P_CENTERS directly but im stupid and didnt write that 🙂
do i need to add a SMODS.injectItems() later in the code?
the way i have it listed here works perfectly
dont worry about LoadCompatibilities and Entropy.ReverseFlipsideInversions though they are irrelevant
ok
this is making me feel rly dumb ngl
pls can i see your Entropy.FlipsideInversions table
What are you even doing?
Why do you need to hook SMODS.injectItems?
because apparently i can't use modded jokers in cards
huh?
I thought the issue with cards was that it would work with only modded cards, and then I fixed that.
And the code to handle this has been the same for the past 6 months.
oh ok
ok i fixed it
that was much simpler than all that inject stuff
i feel less dumb looking at this simple code

bump.
The SMODS wiki says "saved - used during context.end_of_round to prevent game over", but the message is hardcoded for Mr. Bone . Can we customize the saved message with smods instead?
I think the message is already automated for modded Jokers
I just thought of a joker that does 25 different things based on what its current ability is but i dont think i have the mental capacity to do that
chloe joker isn't appearing at all,, marie joker (legendary) appeared once (out of 25 tries) tho
Really? Like message = ... ,, that easy?
I meant that I think SMODs uses the Joker's name
Let me tell you, it didn't.
this is not true. i was able to confirm this last night
the localisation var for it is stored at G.localization.descriptions.misc.dictionary.ph_mr_bones - there are multiple routes you can take to change it such as with SMODS.process_loc_text(), or the generally better and more compatible way, with a localisation file
from my dump of functions\common_events.lua, on the current release version of SMODS
to make this dynamically use whatever name mr bones would be changed to, you could replace localize('ph_mr_bones') with "Saved by "..G.localization.descriptions.Joker.j_mr_bones.name
...to handle additional jokers that return saved = true, would probably have to rewrite this to get the name of whatever joker that returned saved, which i believe is possible in this event chain
wait i'm dumb it's bc it's the fallback and all the listed jokers were already held
it works fine if i just add showman lol
I remember someone had modified it
But maybe that was before new calc
and it didn't get ported
or they didn't make a PR
I think if people want this feature they should request it
i'm getting the legendary joker quite often,, is it using the card's rarity correctly?
hey is there a way to move card's position on screen?
....do you have your rarity set to 4?
Are you playing on the Equilibrium Deck or using the Equilibrium Sleeve?
I just pull up a copy of the games eng locale then steal keys from it with localize()
Hang on, is your Joker both a Base Resident and a Legendary?
That MIGHT explain why.
yea?
Yeah, that may be the cause.
how so?
Because you defined the Joker as a Base Resident in its ObjectType, which means regardless of it being a Legendary, it'll still be a possibility via Resident Spectral.
ok
i thought using objecttype meant it'd account for card rarity
how do i use the rarity in the objecttype?
I can suggest making Base Resident a Rarity instead of ObjectType.
i'd rather not make it a rarity
...good question, I don't know if you can.
chat what did i messup
it needs to be in quotes
thats weird cause i have another joker with its key not in quotes
ok it lauches now
smh
that should be in quotes too what
that should also be in quotes
yeah idk why it works then
anyway
how do i make a joker
uhh how do i make this pg uhh sodoku itself
destroy itself
anyway dosnt matter
basicly want this joker to start at like 3$ and then if u have less that 3$ it goes to 4 but if u have more than 3 it destroys itself
Wholelottalatro
how do i get a rarity's rate?
trying to add a deck to jens almanac
is this right?
does anyone have an example of a modded joker that functions like blueprint or brainstorm? im trying to add another version of blueprint called redprint to my mod, but im way out of my league with jokers that take on abilities of other jokers
just an example i could look through and learn from would be great
I am once again begging you to format your code indentation (Shift+Alt+F), for your own sanity and ours.
The common wisdom is that code is read 10 times more often than code is written, so making it as readable as possible is really important.
We are constantly reading old code as part of the effort to write new code. ...making [code] easy to read makes it easier to write.
This also means it's 10 times more important to develop your ability to read code than your ability to write it. Read through other people's mods to get a sense of how things are written, and you'll find you'll get a lot better at writing code in the process.
This style guide also offers some good tips on good and bad practice, though many people will disagree on the exact details. Consistency is the most important thing.
While you're learning, it's good to not develop bad habits early that are hard to shake off later on
:<
...can I actually hide normal poker hands and let them become unlockable?
Huh, yes.
-# The order gets kinda fucked up, though... or it might be just the idea of it actually throwing me off.
thats actually a really cool idea
this makes something always able to appear even when you have it right? am I just getting astronomically unlucky with my mass Rare Tag spawning?
hey does anyone know what defines where a card can and cant be?
i don't have anything, but i know that if you have a either a lovely dump of the card.lua or the game's original card.lua to check through
just from thumbing through those to see how blueprint & brainstorm work nomally, i know that to do the compatibility check, you'll need to use a main_end which is something you return as part of your loc_vars table, which involves UI code, so have fun with that 
and in card.lua's Card:calculate_joker(context) function, blueprint and brainstorm are right at the top, at the start of the function. basically what blueprint does there is it sets up a holder var for the other joker, then iterates through all of the present jokers in G.jokers.cards until it finds itself, then identifies the next one in sequence as the joker to its right (the joker to the left being the previous one in sequence). it then checks to make sure the thing it's trying to work with exists (since if blueprint is at the far right of the jokers area for some reason, the next joker in sequence is always going to be invalid). imo one minor nitpick about the vanilla blueprint is that it doesn't break the loop after other_joker = G.jokers.cards[i+1], which means that loop will just continue to iterate even after its achieved its purpose, which probably doesn't really mean much in terms of inefficiency and performance, but is probably a good habit in this kind of "iterate through the whole list to get one thing" kind of method of doing things, to do.
i don't fully understand what's happening from that point onwards other than:
- it creates and populates the blueprint child in context, which is vital to ensure that what it does next works properly and as intended - this is probably something you should mimic exactly to ensure maximum compatibility with both vanilla jokers and jokers from other mods, for things like
context.blueprint == nilto keep blueprint from blueprinting that part of a joker's function if it's designed that way - it calls the calculate function of the other joker and puts the returned table into a var. this is what blueprint itself returns.
- it removes the blueprint child in context that it created afterward (but not before putting the reference to itself into a var for later) - this is just as important as creating the context, because there will always be more jokers in sequence on from blueprint that have yet to calculate, but since the context it's editing is the context that was passed into function in the first place, if this isn't done, the blueprint child will persist into the next
calculate()call, making that nextcalculate()think it's being called by blueprint.
a different way to do this could be to instead copy_table(context) into a variable, then create the blueprint child in that, but this is probably more memory efficient since doing it that way declares a new variable.
- it then sets the
cardchild of the table that returned from the other joker'scalculate()to itself, overriding any value that was there - which is mostly just determining where the message appear. it also forces thecolourchild toG.C.BLUE, mostly just an aesthetic choice for blueprint specifically. then it returns that table.
i'm sorry
i'd been writing that for like 10 minutes 
What do you even imply by "can and cant be" on cards... and what cards, even... suit, rank, rarity?
like, consumable zone, joker zone, hand zone, and by cards i meant objects like jokers and consumables and playing cards :3
i think they mean the kind of cardareas where jokers, consumables and cards can be
yur!
how do i fw that >:3
the thing about Showman is it doesn't "work", from a code standpoint it does nothing, but its presence enables duplicates of cards to appear
oh you want to make changes to the existing ones - i was under the impression you wanted to make new ones 
oh ok,, i see
but the docs never use anything in a sentence so I'm not sure how to write it
oh no, i have a crack cocaine idea :3
behold my WIP joker that will take me months to code hopefully not
... one second my games opening
supposedly but I ain't got a clue how to use it
here :3
I just posted that
this is what im trying to code X3
right here
return true, {allow_duplicates = true}
that's all you need to do i believe
inside the in pool function
looky joker :3
@shell timber mentioned
oh shit is someone also making a joker that does that
no
i see 
oh
just virtual insanity
real
i cant wait to crash my game YAAAAAAAAAAY
iirc x5 mult but does the amber acorn thing
idek how to begin so im not gonna implement it rn, but i did the art :3
the background isnt done yet tho
-# Now I need to alter the text of the Psychic boss blind...
just got an idea for new boss blind
which is honestly very diabolical
should just be ultima blinds
Thank you, i had little clue where to start and was hoping there was already a structure in place in modding, but this is still a large step in the right direction, ill might be able to work out the rest from here. i should also mention, this is my first modded joker lol. I already do know how to make regular jokers thanks to the smods docs and i was making compatibility between modded jokers and JokerDisplay, but i only started 2 days ago so any help is greatly appreciated.
Yep!
what's the default cost of a rare joker 
4 billion :3
i think 10?
i think blueprint and brainstorm are both 10
the dumbass rares are 8
i think most are 8, uncommon are 6, and common are 4
and then credit card is a special guy and is 1
oh nope, could you tell me a bit about card areas and how they're implemented :3
i don't know anything about those, sorry 
there are a lot of modders that work with cardareas though
what do you need to know
Well, where to get started trying to make this happen
^
hey n
all cardareas take all kinds of cards so rather than looking at how cardareas work you need to check which functions emplace cards in them, like this part in buy_from_shop
hii go to sleep
i have class in half an hour
also i actually did the solitaire part using cardareas
I wondered what the constant "NopeTooFast {Cirno_TV & Friends} is typing..." notice was going to result in
Oh! So like, if I were to make it so that you could drag them over a zone and put it in there like how you’d rearrange your stuff, would emplacement be used for that?
i use draw_card
oh if you want to be able to drag and drop them its a bit more complicated
you should probably actually look at aiko's code for the solitaire stuff lol
i, like many others, have a fondness for blueprint
especially since it is friend-shaped
Oh, word!
why chiruno so smol
..,, aiko could I see that code?
what on earth is causing this? i checked over all my atlases and couldn't find anything wrong.

wee joker
show your atlas
...well, i have a different atlast for all 7 of my jokers.
SMODS.Atlas requires px and py to be defined when you call it
how do i add a joker unlock?
do people just put each joker in different atlases?????
all of my atlases are formatted like this, with one having the soul_pos.
that's like the whole point of having an atlas
Check for check_for_unlock in source code.
in SMODS.Atlas{}, X needs to be px
and Y needs to be py
ah, right. i forgot for that specific joker.
or, that specific atlas.
hehe.
i hope people didn't miss the whole point of having an atlas
what do u think of mine
I do :3
that being...?
at least they are in sets
you put a bunch of joker textures in one file so the game only has to load one file
ah, right.
4 billion files >:3
atlases are for doing this with https://cdn.discordapp.com/attachments/1233186615086813277/1359433411919347722/Balatro_7hT8tspJtV.gif
i'll cross that bridge when i get to it. for now, it's much easier to throw everything in a spritesheet.
i also need to add localization, too.
animation atlases go brrrr
weeps
kinda wish you could make jokers have animated textures
it's not even an animation atlas. animation atlases don't work in main_ends for whatever reason.
this is manually animated 
you can, i've seen it
oh, you certainly can. see cardauce's granny cream joker.
Aura or manually update the current "frame".
This is a bit faster in-game, quite an in-dev GIF.
i can hear the music now
i was about to write the lyrics but i don't speak japanese yet
What kind of impact does this have on performance and memory? I'd be curious to see how it's all handled by the engine
only 77 more to go
wait i forget how is the texture for hologram handled? is that just a shader?
i honestly have no idea, how can i check?
the filesizes of both bad apple atlases are 196 kb
do you have a blank 10x10 template of cards on hand?
I'm trying to grab the value of G.GAME.tags's key string, but when I do print(G.GAME.tags.key) it comes up nil,
Am I selecting the right table?
no
ah.
development resumes tomorrow
real
someone help me with my solitaire thank you
Do you experience any drop to fps while it's playing? For memory, i don't know of any memory profilers, but you could check how much the Balatro.exe process is using when the atlas isn't loaded and when it is
gib solitaire code for drag and move pls ty 10000 years
well for one you start by putting aces in first
GET OU-
holy shit
i have problems with double clicking part
oh you have double clicking? awesome
do yall know how to scale a joker's values (like red card or green joker)
may i ask if solitaire is gonna have any impact on balatro runs or if its just a for fun thing
if ... then -- context check
card.ability.extra.mult = card.ability.extra.mult + 1
end
It will be a boss blind.
none that i noticed
it's probably well-optimised especially since the graphic uses only 3 colours. could probably reduce it to two if i wanted to optmise it further
carefully
...hm...
SMODS.Blind:take_ownership('psychic',
{ debuff_hand = function(self, cards, hand, handname, check)
return #cards ~= G.hand.config.highlighted_limit
end},
true
)
...that's a hardcoded string, even worse!
handydydyshdhd
hi aiko
Hi bepis
Store double_click_position and click_time and check them on click and click release
- On click:
- If
double_click_positionhas been set previously, and is equal to the current position, and (current_time-click_time<double_click_time_threshold), it's a double click! - Else if
double_click_positionnil, storedouble_click_positionandclick_time.
- If
- On click release:
- If cursor position is changed, reset
double_click_positionandclick_time
Ideally you'd also invalidate if it the cursor had moved in the meantime, but that's probably hard to do within the Balatro controller and might be excessive
- If cursor position is changed, reset
i mean i got the double click part but i don't have the stacking part
how do people do double click
You can probably forgive me for misinterpreting your question
I'm very tired and that got a cackle out of me
i have card double_click working
but i just dont have stack moving on double click working
it's insane
LMAO
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.e_negative
end,
calculate = function(self, card, context)
local my_pos = nil
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then my_pos = i; break end
end
if context.setting_blind and not card.getting_sliced then
if my_pos and G.jokers.cards[my_pos+1] and not card.getting_sliced and not G.jokers.cards[my_pos+1].ability.eternal and not G.jokers.cards[my_pos+1].getting_sliced then
local sliced_card = G.jokers.cards[my_pos+1]
sliced_card.getting_sliced = true
G.GAME.joker_buffer = G.GAME.joker_buffer - 1
G.E_MANAGER:add_event(Event({func = function()
G.GAME.joker_buffer = 0
G.jokers.cards[my_pos-1]:set_ability(G.P_CENTERS.e_negative, nil, true)
card:juice_up(0.8, 0.8)
sliced_card:start_dissolve({HEX("57ecab")}, nil, 1.6)
play_sound('slice1', 0.96+math.random()*0.08)
return true end }))
end
end
end
}
having some issues. Card kills the card on the right but when it goes to convert the left to a negative, it crashes
i wish
use :set_edition instead of :set_ability
you can't keep getting away with this
still crashes
sad
:3
oh that's fun actually
does anyone know why the joker isn't scoring? (also how would I make both the total chips and the chips it gains changeable with one line)
SMODS.Joker{
key = 'Blue Card',
loc_txt = {
name = 'Blue Card',
text = {
'This Joker gains {C:blue}+30{} Chips when any',
'{C:attention}Booster Pack{} is opened.',
'{C:inactive}(Currently {}{C:blue}#1#{} {C:inactive}Chips){}'
}
},
atlas = 'Jokers',
pos = {x = 0, y = 0},
config = { extra = {
chips = 0
}
},
rarity = 1,
blueprint_compat = true,
loc_vars = function(self,info_queue,card)
return {vars = {card.ability.extra.chips}}
end,
calculate = function(self,card,context)
if context.open_booster and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 30
elseif context.joker_main then
chip_mod = card.ability.extra.chips
end
end
}
wait this is so cute :3
elseif context.joker_main then
return {
chips = card.ability.extra.chips
}
end
i think i found the issue: I believe its the G.jokers.cards[my_pos-1]:set_ability(G.P_CENTERS.e_negative, nil, true) part but idk how to fix it. documentation says it should be Card:set_ability... but that would make it the card itself, not the card to the left
I'm still pretty sure it's set_edition
u#BCIWeeeeflme
G.jokers.cards[my_pos-1]:set_edition(G.P_CENTERS.e_negative, nil, true)
i think set_edition doesn't take a center, it takes a string like "e_negative" or a table like {negative = true}
i might be wrong on one of those
took out centre and it gave me the same resuklt
Anyone got a clue why blueprint says incompatible even though its working?
blueprint_compat = true
add that in your joker's code
Is there a way to make new suits?
Yeah, it can be done. You'll have to look around for a mod that does it, though.
Where would I pit {negative = true}?
A mod that adds the ability to make new suits or a mod that adds one
adds one
What if I wanted to make one?
I don't know how to make a custom suit, so you'd have to ask someone else
Alright then, thanks
set_edition({negative = true})
set_edition("e_negative") should work too
Aiko how can i make that “example” label
if context.setting_blind and not card.getting_sliced then
if my_pos and G.jokers.cards[my_pos+1] and not card.getting_sliced and not G.jokers.cards[my_pos+1].ability.eternal and not G.jokers.cards[my_pos+1].getting_sliced then
local sliced_card = G.jokers.cards[my_pos+1]
local left_card = G.jokers.cards[my_pos-1]
sliced_card.getting_sliced = true
G.GAME.joker_buffer = G.GAME.joker_buffer - 1
G.E_MANAGER:add_event(Event({func = function()
G.GAME.joker_buffer = 0
left_card:set_edition(e_negative, true)
card:juice_up(0.8, 0.8)
sliced_card:start_dissolve({HEX("57ecab")}, true, 1.6)
play_sound('slice1', 0.96+math.random()*0.08)
return true end }))
end
end
end
}
doesnt crash now but doesnt apply negative
'e_negative'
a lot ogf insanity
thank you both, now works
-# UI wizardry.
Aiko could probably code my new joker in 5 minutes XP
Cheers
im a genius
bump
Something like this?
...actually, is that a retexture of the vanilla Wild Card enhancement, even?
feel like this is probably too powerful as an uncommon joker
-# A solid Rare imo. Though, what do I know about appropriate rarity assignment.
how could i manipulate blinds for a deck? i'd like to make sure every boss is a showdown boss but can't seem to figure out how
Probably hooking or Lovely patching of get_new_boss() for your deck.
See common_events.lua at line 2338.
Or you could slap your own gathering of the Showdown blinds and letting pseudorandom_element choose the boss for you in calculate of the deck, after which you assign it to G.GAME.round_resets.blind_choices.Boss.
thanks for these ideas on how to do it!
i might just patch
but adding a little thing in the calculate function may be easy enough too
aaa
Well, for what I needed
while G.GAME.round_resets.blind_choices.Boss == 'bl_psychic' do
G.GAME.round_resets.blind_choices.Boss = get_new_boss()
end
was enough.
How would you detect how many of a specific card are in your deck (like the way Steel Joker and Cloud 9 do it)? The Steammodded documentation is my best friend but I'm having a hard time finding this one
funny
can someone help me fix this, my lovely keeps telling me theres an unknown key and wont load my mods

You can ignore the unknown key. Not sure about the not loading mods cpart. Maybe hit enter when in that console screen incase you paused the program.
i love
💀 Now imagine all those conditions compressed into one return...
It loads the game, but unmodded. I have steammodded and lovely installed it doesnt load anything
Yeah you just added me as well lol
can you send the log from Balatro\Mods\lovely\log?
For sure!
then when it boots it looks like this
Lets move to #⚙・modding-general , but I need to see the lovely log, not bmm
Trying to check if a played hand contains a scoring King and Jack. Tried setting to values to be true and then returning the effect if bothe those values are true but its not working and theres probably a better way to do it
if you know a way please ping me, many thanks
whenever a joker is checking for an enhancement from the modpack do i just need to give the key of that enhancement or does smods require the mods key the enhancement is from
if context.cardarea == G.play and context.individual and context.scoring_hand then
if SMODS.has_enhancement(context.other_card, 'm_rose') then```
The key would be m_modprefix_rose
thank you
chat how balanced is this
i got it working but this keeps appearing in the log whenever i finish a round? (i may have set the logic up weirdly but this was the way i structured it)
nevermind, apparently this does not work lol
...why the returns?
just a sort of last ditch effort to get rid of that warning lol
You could limit when that goes of by putting it under a context of sorts, be it .leaving_shop or something.
calculate return should be a table not a boolean?
yes. but it's not related to my problem. it would exist with or without it
i removed those and it seemed to fix both the crash and the warning lol! just added a break (just in case) and removed the return
only problem is that the boss background seems to be incorrect but i think i've seen that be an issue for people before
...IT PROCCED WHEN I BOUGHT A CONSUMABLE.
i don't understand. it must just be broken for jokers, then
This context is used for effects when a (non-playing) card is added to the deck (Card:add_to_deck).
https://github.com/Steamodded/smods/wiki/Calculate-Functions
What specifically are you trying to do?
Showing the current code where you use card_added would also help
please see the second screenshot of the message i replied to.
and the rest of that conversation
Exactly what I meant with the "current code" statement. using context.card_added in the way you did would not give (shouldnt) the attempt to indexerror that you complained about.
i did not complain about the error.
i complained about context.card_added not working for jokers.
loc_vars is run whenever you hover over the card, but if you want code to be run at the very end of scoring, you could use context.final_scoring_step in the calculate function
Worked for me.
Im trying to get a booster pack I want in the game to work but line 77 on cookbook is returing nil for booster can anyone help?
SMODS.BOOSTER and SMODS.CONSUMBALE are not to be fully capitalized.
SMODS.Booster and SMODS.Consumable
Though, with what you're doing with the imports and SMODS confuses me. I havent seen anyone do that yet, is it truly necessary?
bump
you can just edit io_queue in the loc_vars function
i'd like to avoid taking ownership if possible
ik the top seemed very wrong took it out
Are you trying to add this to a vanilla/other mod joker?
ill try uncapping
not a joker. wild card enhancement
If you've already modified generate_card_ui(), just replace it with loc_vars
however you're doing that
...wait, loc_vars in vanilla items is just a table
is it safe to be making those functions instead
Fair point. You probably will need to take ownership.
does balatro not have a way of determining if a played hand contains other hands
I'm really confused as to how to move the Ace on the main menu; We've tried replacing the title_top definition to change the x position and that doesn't change anything, and we've tried replacing the replace_card definition to append the x position and that doesn't change its position either
next(context.poker_hands['handname'])
Struggling to get this to work
It's get_id()
after following the wiki on something and struggling to work out why a if context.before and context.cardarea == G.play then wasn't being entered when i played a hand, i print(tprint(context))ed when context.before. why does context.cardarea not exist?
oh whoops, the print(tprint(context)) was print(tprint(context.cardarea)) 
For anyone wondering, the position of the title screen Ace card if you want to change it is in functions/common_events.lua in the function set_screen_positions
is it possible to make it polychrome 
However, assuming this is a joker, context.before won’t have a cardarea value of G.play ever
so why is this like this
Because for modifiers it can be
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "replace_card.states.visible = false"
position = "before"
payload = "replace_card:set_edition('e_polychrome')"
match_indent = true
overwrite = false

can i use pseudorandom() shenanigans to give it a chance of being polychrome
Probably.
i just noticed something about the way blueprint & brainstorm work.
is there a way i could make blueprint and brainstorm not overwrite the return table's .card and .colour if .card is a playing card? 
i mean, i guess i'd have to SMODS.take_ownership() of them, but i'd still need to know how i'd identify .card as a playing card
Fixed the crash but now its just not doing anything
im so close to having 2 pages of jokers
im trying to have a chance to create a spectral card on each card destroyed while holding the joker, although it only procs once even when two cards are destroyed by the hanged man, or more by the glass shattering, any clue?
local destruction = 0
for k, val in ipairs(context.removed) do
destruction = destruction + 1
end
while destruction > 0 do
if (pseudorandom('goon') < G.GAME.probabilities.normal/card.ability.extra.odds) then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
return {
message = localize('k_plus_spectral'),
colour = G.C.SECONDARY_SET.Spectral,
func = function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.0,
func = (function()
SMODS.add_card({
set = "Spectral"
})
G.GAME.consumeable_buffer = 0
return true
end)
}))
end
}
end
destruction = destruction - 1
end
end```
also i don't quite understand the difference between context.remove_playing_cards and context.cards_destroyed, aside from maybe cards destroyed would affect all cards type? i dont find info on it so i dont know how important it would be to do both just as caino and glass jokers
ong
What is the best context timing to check if the score is on fire?
bump
i guess after?
Remove :new
Remove sounds/
same thing happened when removed from the path
heres the code from when it activates from joker
Where is your sound?
It needs to be in assets/sounds
ohhhh
lol
thanks bro
does it need to be in folder called resources?
crashed again
where?
cards_destroyed isn’t a thing, it’s a remnant from old thunk code. The reason it’s only doing one is that you return within your loop, so it can only happen once
okok
so the move was indeed to your remove_playing_cards
although i have no clue why it only procs once for me whereas the same call makes it multiple times for caino and shattered glass
i'd guess it's for the context.individual, but adding it stops the joker from having any effect
They told you why at the end.
should i vanish the return then? i'm really a newbie
How to make sure a card.ability.extra[some_key] value is always an integer?
if type(card.ability.extra[some_key]) == 'number' and math.floor(card.ability.extra[some_key]) == card.ability.extra[some_key]
Sorry, I forgot math.floor was a thing.
Does anyone have any idea why a combo of mods would cause all hands to be lvl0 at the start of a round and be unable to score at all?
I have a modpack built, I was wondering if anyone had knowledge that could save me the task of testing each mod.
You can test half of all mods at a time
I mean I was just asking why it might be possible within the code... Not to magically cure my issue
What possible code logic might have caused that. So I might have an idea of where to look. No one was asking for a magic bullet
sorry anyway uhm i think you might want to look in game start run
sorry i am wrong
the original values are in Game:init_game_object()
any mods that mess with how hand levels work could be the cause. Aurinko, Cryptid + any add-ons, etc.
does smods have card getting destroyed context yet
yes
context.remove_playing_cards
with the destroyed cards listed in context.removed
is there one for jokers
hi anshy
-# yes im putting you a new name
what does anshy even mean
dunno
oh yeah, one of my friend's name :3
thought it would be funny if i decided to just call my friends names of my other friends
would anyone know why the FileHandler running would cause a crash?
game.lua:2798: bad argument #1 to 'push' (boolean, number, string, love type, or table expected)
this is the part of the code where it's breaking:
if G.FILE_HANDLER.run then
print("FILE HANDLER RUN")
G.SAVE_MANAGER.channel:push({
type = 'save_run',
save_table = G.ARGS.save_run,
profile_num = G.SETTINGS.profile})
G.SAVED_GAME = nil
end
only changes i've made to G are adding a new UI object to reference and updating the G.orbital_choices
i had this happen recently because i saved a function inside a card's ability table
probably saving something where you shouldn't
ooo interesting, i'll check that. thank you
you can now use the game as your desktop backgrounr
fuck it i made custom context for when jokers get removed
3
I mean there’s probably more than 3
i don't see one
Paperback and Bunco do it
At least
Oops
Not Bunco
Betmma’s
Why haven’t they PR’d SMODS IDK
lovely patch bros ,,,,,
no lovely patches
Lovely Patch Bros.: The Movie
i actually had to lovely patch the mechanics for multiplier and i still need to figure out how to properly change the messages
i tried hooking into localize
but message comes first
so the very first mention of + Mult or + Chips isn't modified
return {
message = localize('a_mult'),
mult_mod = 5,
}
-- Message is created first here, currently the global toggle for this is off as it gets toggled when marketplier activates
-- mult_mod triggers the toggle change
-- Subsequent mult changes have X Mult as the message, but not this one
these codes are written while I'm half asleep please do not mind the bugs and glitches that will occur
i need to predict the future
What would be a good way to have an enhancement store a value for each individual card with the enhancement, and not just across the board (e.g. a stone joker that loses a chip from it's bonus each time it's played. Changing the config value changes the bonus across all cards with the enhancement)
I could use perma bonuses i suppose but then i'd have to handle removing the bonus if the enhancement is removed and keeping track of that... just wondering if im missing something obvious before hiking down that path
card.ability...
am i cooking
wtf is this
My morning starts from fixing a bug with multiplayer mod 
I'm not entirely sure what your intended effect is. Is it an enhancement that gives score based on the number of cards with that enhancement in the deck?
doing that changes the value for all cards that have the enhancement
😔
i NEED to make better art
Meawhile, my arts:
i think card.ability is unique per card
it doesn't
it is finished
me doing ten 10s was enough of a motivation
what did they do
normally you just { mult = 5 }, no need for message shenanigans?
shenanigans...
vanilla jokers
vanilla jokers use message together with mult_mod or whatever
with Steamodded you don't need to do that
From 3 out of 11 options, chat should decide what we gonna do, and some jokers consumables will be given accoring to choice
nah, independent from one another, the enhancement starts at +10 chips, loses one chip from itself when played, and then remove the enhancement once it hits zero
Am I missing context or how does that matter
chat is this true
card.ability should just work for that. .ability is unique per card object
For example
you should be able to do that with post_trigger
it lets you modify the return value of the reiggered joker
If you're having the issue that it sets the value for every card with that enhancement, I'd assume you're accidentally setting it somewhere else
it's not really retriggering though
yeahhh ill poke around. I had assumed as much when i started using it but came here when i couldnt isolate the issue further, I'll shake it out
im basically hooking into calculate_individual_effect to change mult to x mult and chips to x chips
via a lovely patch
feel free to show the code. I'm increasing, not decreasing, but the Sci-fi enhancement in Kino changes value every time it's scored
# Multiplier effects
[[patches]]
[patches.pattern]
target = '''=[SMODS _ "src/utils.lua"]'''
pattern = "mult = mod_mult(mult + amount)"
position = "after"
payload = '''
local old_mult = mod_mult(mult - amount)
local prob = G.GAME and G.GAME.probabilities.normal or 1
if G and G.GAME and ((G.GAME.markiplier_prob_xmult_chance and G.GAME.markiplier_prob_xmult_odds and G.GAME.markiplier_prob_xmult_chance > 0 and G.GAME.markiplier_prob_xmult_odds > 0
and pseudorandom("payasaka_multiplier_xmult") < G.GAME.markiplier_prob_xmult_odds*prob / G.GAME.markiplier_prob_xmult_chance) or G.GAME.markiplier_prob_rigged) then
mult = mod_mult(old_mult * amount)
--G.GAME.payasaka_markiplier_multiplied = true
if next(SMODS.find_card("j_payasaka_markiplier_punch_gif")) then
card_eval_status_text(pseudorandom_element(SMODS.find_card("j_payasaka_markiplier_punch_gif"), pseudoseed('payasaka_multiplier')), 'extra', nil, nil, nil,
{ message = "Multiplied!", colour = G.C.DARK_EDITION, extrafunc = function() play_sound("payasaka_markiplier_ngahh", 1.0, 0.5) end })
end
end
'''
match_indent = true
times = 1
it's shitty i know
That's how Balatro game code was made
Initialize cards for shop in UI function? Maybe I shouldn't, but it gets the job done for now
iiiii figured it out and it was dumb... forgot the cardarea check in the -1 block and so it was removing one from all of them regardless of where they were, which sure looked a whole lot like it was changing it globally🤦
Appreciate the help y'all
😭😭😭😭😭
anyway i still need to figure out how exactly to patch the message field
unless i could just make the calculate_effects function prioritize mult_mod and chips_mod first before doing that
which would probably solve the problem
do I have the Taken joker interact with the abduction mechanic, even though it's explicitely themed after alien abduction 🤔
triggered* mobile moment
<@&1133519078540185692>

Going to set up quests to be simpler because I've written a spider-web that's going to catch way too many bugs otherwise
Yes
I've opted to make Taken a simple mult joker that turns John Taken's distrust of women's ability to do literally anything into a fun mechanic of giving 5 mult if you draw a queen, and losing 5 mult if you play one.
Roffel would do great with that joker
Turning misogyny into score
That's why Roffle would pop off
Bro is not beating the misogyny allegations
...what?
got damn!!!!
is it possible to set a sell value indedently from the cost?
like to make a joker's sell value to absolute zero and not changeable
How to know the hand type of the last played hand of round under context.end_of_round and context.repetition?
G.GAME.last_hand_played
self.ability.extra_value = 0
self:set_cost()
ease_dollars(-G.GAME.dollars, true)
end```
it tried this but it crashes on sell
Do you have talisman installed?
what is it?
Would the game crash if return {repetitions = 0, ...} under context.repetition?
If not crash, would message still pop up even when repetition is 0?
A mod that messes with how numbers were stored in game such that big numbers can go even bigger, yet in the meantime introduces a couple of other issues include but not limited to attempts at comparing numbers with tables.
how do i make a joker that gives chips and mult give 2 messages?
how do i get seperate joker files to work on mac?
i tried copypasting some code and its experiencing issues so i think i should just rebuild from the ground up
Return {message = 'message', extra = {message = 'message'}}
the extra table ,,,,
TIL that under if context.repetition ... if your return table doesn't have card = ... the game will crash.
This sounds unintended
does anyone know how to set up files for separate jokers?
any idea of why it makes the game crash on sell?
self > card?
Change self to card and context.debuff doesnt exist.
It's card.ability.cost I think.
doesnt change either when i replace extra value by cost
It’s something like sell_cost iirc
You update it after
It's in my code hold on I gotta boot my computer up
sell_cost doesnt work either
perhaps the issue would be me putting it into context.selling_self?
card.sell_cost
sell_cost is definitely correct,
ahhh left the ability
oop, yea he got it
ok it works now, had to take off the self:set_cost ()
the animation is a bit wacky but it does work
@cursive sentinel this i know works its a copy of my code
card.ability.extra_value = card.ability.extra_value + 5 card:set_cost()
you change the value and then update it with set_cost()
They are trying to set the cost to 0
Not add extra cost.
could i do it with this formula by substracting by self?
x)
then they can just set thre value to 0 instead of doing the addition, yea
it was what i had at first i think?
card.ability.extra_value = 0 should work
here had tried with self and card
with self it crash
with card the sell value didn't change
can we see the crash?
with the self? sure
i do this with one of my cards
card.sell_cost = to_big(0)
you can igore the to_big because thats for talisman
replacing self with card for sell_cost and extra_value should work, so i have a feeling its a problem with the context
card with extra value had no effect
can i see line 402? like can you screenshot your main.lua with the line numbers
sell cost had though, it does work
it just seems to update the dollars an additional time before getting to zero
Extra value as 0 won’t change the sell cost
set.ability.extra_value = 0
ok sanity check: replace the context with if context.before and context.cardarea == G.jokers then
You could set it to -card.sell_cost though I think
it does tho? this is the calculate code for my joker and it works fully as intended
calculate = function(self,card,context)
if context.end_of_round and context.game_over == false and context.main_eval then
card.ability.extra.money = card.ability.extra.money - 5
card.ability.extra_value = card.ability.extra_value + 5
card:set_cost()
ease_dollars(-5)
if card.ability.extra.money <= 0 then
end
end
end```
its compatible with selling_self?
but double check
see if its the code inside the context or the context itself by changing the context to one that we know works
because it seems everything should work, and yet it doesnt, so its something we're missing
ohhhh is it like scale where it doesnt like to be set as a base number and instead a change in number?
Extra value is cost added to the sell cost.
yeah but its still changing the sell value
ik, its sell value starts negative and goes to 0
but the dollars bar seems to go up and then down
it's a bit weird but it ends up at zero
with the different context or same context?
with the context i previously had
ok
context.selling_self
do you have a way to clip it? like can ur computer handle the steam clips function?
or do you have another way to record?
i can, 2sec
how would i destroy cards?
What’s the actual intended effect?
for it to destroy all played cards
if context.destroy_card and context.cardarea == G.play then
return {remove = true}
end
cheers
Please please put an area check in this @thin anchor
It will destroy every card you have otherwise
even better!
i suspect the additional effect is due to the sell cost modified which must have its own sounds
lol /j
is there a context for the current atlas of a card?
or should i make an atlas with two sprites if i want them to swap
i didnt know you were changing the dollar number i thought it was just the sell value
or is that unintentional
it comes after
if context.selling_self then
card.sell_cost = 0
if G.GAME.dollars ~= 0 then
ease_dollars(-G.GAME.dollars, true)
end
end
No
basically a sell joker with same counterparts as wraith spectral
Probably
do you know why this isn't working? :3
try changing ~= to >= mayhaps?
You could just add the sell cost to the money that your deducting.
ill prob do that if this doesn't work
its the way it is in wraith
it can make it up to 0
if you're in negative
just having an extra sprite isnt that bad, its a pretty easy swap
Does SMODS handles returned atlii?
oooo hadn't thing of that,,, smart!
i mean sure but thats un-preferable because it doesnt translate that with the sell value being different
will try
i dont think so? idk im just trying what i know :3
ideally the ui says its 0
Then why are you returning it
It’s not magic
hi vic :D
Hello dilly
-(G.GAME.dollars + card.sell_cost + card.ability.extra_value)
i hope you are well this fine thursday
Could be better
ohhhh, that makes sense
OH SO I MAKE IT NOT IN THE RETURN
will put it in like that
Just set the sell cost to negative game dollars
is there an smods page with all of the area checks?
ok this one does the same in sound effects, but now i just think it's basically because i sell it, thus i hear the sell and the money set subsequently
it's not too bad,,, thank you all for your help!! very kind!
Is it all played cards you want to destroy?
yes
damn i thought i had it
Just do if context.destroying_card then
k
yeah afaik unless you make the sell price the money you own * -1 its gonna do that no matter what
it would just be easier to add another sprite to the same atlas and change it that way, idk why youre doin all this
so like this?
cuz it does the sell which does the sound, and then activates everything under context.selling_self which eases dollars and that makes a sound
im learning and tryin things, s'why i need help to know where im going wrong!
would i change it using pos?
You need to check context.cardarea == G.play
its funny that you even copied the typo
eep
if you want it to be just one movement you could try setting the sell price to -(G.GAME.dollars + card.sell_cost + card.ability.extra_value) instead of easing dollars to that? tho idk how well thatll work
still worth a try tho
i am so ignorant
i hate extra_value, i just made a lovely patch to set_cost so i could set it directly
it did the same
and im not sure of it working that much on negative dollar values
hm
how do you add hyperoperational mult? I've got talisman in here
i dont know then thats really strange
local desiredx, desiredy = 1, 1 -- sets new points of atlas for new texture on neglection.
if card.children and card.children.center then
card.children.center:set_sprite_pos({ x = desiredx, y = desiredy })
else
print("Error: Unable to update Tamagotchi sprite.")
end
i do this for mine,m uses the sme atlas and uses desired x/y for the new pos
i did just realize however the atlas doesnt save if you leave and re-enter the run so ill need to do a check for that eventually
i just threw this in where i set my card to be debuffed
ill keep what i have for now and move on the next i planned,,, thank you a lot
ok so
Return {emult_mod or eemult_mod or eeemult_mod = number}
Remove checking for context.individual
No
thats complex
i only need it to change when it triggers during joker main :3
then set the context and put that in there
I've done the emult, thing is tho, I'm not doing exponential mult here, I'm doing pentational (that's ^^^)
eeemult_mod



