#đ»ă»modding-dev
1 messages · Page 511 of 1
refer to this note regarding talisman
how would I retransform it into tables values If talisman is enabled?
It works fine with Cryptid probably because Cryptid does something like that
but I want it to work without Cryptid installed too
that is what the note tells you
oh got it
so the transform_operations should do return to_big(val) instead?
I'mma try that and give result
yeah its working
not sure if the perishable should be included
also @rocky plaza i'd love if you could help me code something
sure, what do you want to code?
so right now this joker creates 1 negative death card each time a hand is played
and i want it to gain +0.1x mult for every death card you have
in extra, put x_mult = 1
in loc_txt["text"], put [3] = "Gains {X:mult,C:white}X0.1{} Mult for every"
and [4] = "{C:tarot}Death{} held in consumable slots"
hold on
so this code will count the number of deaths in consumable slots
local death_count = 0
if G.consumeables then
for _, c in ipairs(G.consumeables.cards) do
if c.config.center.key == "c_death" then
death_count = death_count + 1
end
end
end
alright thanks, where should i put it?
gimme a moment
i'm back ^^; i still need to figure out how to save something to the profile
lemme know if anything is confusing
tysm!!!!
calculate = function(self, card, context)
if context.before and context.main_eval then
local text, _ = G.FUNCS.get_poker_hand_info(G.hand.highlighted)
return {
level_up = true,
level_up_hand = text
}
end
end,
context.scoring_name
same error after adding it as additional argument in the if statement unless that's not what you meant
context.scoring_name is the name of the scored hand
oh
no card is highlighted in G.hand during context.before
so level_up_hand = context.scoring_name?
try it, remove the call to get_poker_hand_info tho
yeah according to vscode it doesn't get used
what could I put under a tarot's can_use that would check if the player has a certain joker?
next(SMODS.find_card('[YOUR JOKER'S KEY HERE]'))
thanks
so for example, for Mail-In Rebate, it's:
next(SMODS.find_card('j_mail'))
and this value needs to be returned
so something like this?
return true```
oh ok ty
npnp!
calculate = function(self, card, context)
if context.setting_blind then
G.E_MANAGER:add_event(Event({
func = function()
SMODS.add_card {
set = 'Joker',
rarity = {1, 2, 3},
edition = 'e_negative',
key_append = 'vremade_riff_raff'
}
return true
end
}))
return {
message = localize('k_plus_joker'),
colour = G.C.BLUE,
}
end
end
any way to have the rarity from one to three, as according to vscode rarity cannot be set by a table
Would really appreciate some help on this one
everything else works and currently, it gives me just rare jokers
If you just want a random one of the three do pseudorandom("seed", 1, 3), tho idk if it takes numbers
Tho itâs not recommended
might have to do pseudorandom_element({"Common", "Uncommon", "Rare"}, "seed")
i'll try the numbers first
It'll probably give you rare jokers every time
yo, im trying to set up the lua lsp as seen here https://github.com/nh6574/VanillaRemade/wiki#how-do-i-start-making-balatro-mods
and i made the .luarc.json with this
{
"workspace.library": ["C:\Users\osgha\AppData\Roaming\Balatro\Mods\smods-1.0.0-beta-0711a", "C:\Users\osgha\AppData\Roaming\Balatro\Mods\lovely\dump"]
}
and its giving me this error
hi srock
hi dilly
hi dilly
hello ken
It will really take time to find someone sho know ui lol
Whenever you put , make it \
Uh
Whenever you put \ make it \\
ok so you were kinda wrong i needed to make all the \ into /
My bad
poeple ! i need help ! why isn't my code updating the sprite ? (actually it's ThunderEdges code)
but i specified it in the loc_txt???
for context, i put crash = 1/0 to see if update() would run
and it didn't
What's the warning when hovering over update
nothing
i wanna use Thunder's anilation code, but yeah sure
What's your full code
wait is it unicode shenanegans
like in the debug thing it didn't show anything am i right ?
or am i already lost
... can u send me the mod in dms?
@red flower can i get some help on this one
No one better to ask than the joyous spring
Can't just ping the guy when he ain't here
Gotta wait for him to be here
so i want my joker to play a sound effect once you obtain it, but it's not playing at all and i have no idea why
Heâs online so i figured thereâs no issue on pinging him
I tried not to
But i couldnât find any help anywhere else sadly
i figured out saving things to the profile ^u^
So what's the issue
Cards donât flip + no button color
Who is this people who don't use monospace font in programming, crazy
Make the first ui element a root, not a row
For the color
And the flip
Make sure your path is correct and your folders aswell
And your SMODS.sound
the sound is already allocated and defined
Dunno, does everything in the event happen except the flip
Play_sound() takes 3 arguments but idk if theyâre optional or not
Iâll try printing
they are
did you put your mod prefix?
pretty sure that is the prefix
Nevermind, do local card = ref.config.ref_table
add_to_deck shouldn't be inside calculate
oh my god i just realized that after looking at supercell's code which i borrowed the add_to_deck part of it
How do you pick a random Joker from your held ones?
like in the crimson heart boss
I saw that it has a crimson_heart_chosen function but couldn't find the origin, but that maybe has the answer
local selected_joker = nil
if G.jokers and G.jokers.cards and #G.jokers.cards >= 1 then
selected_joker = G.jokers.cards[math.random(#G.jokers.cards)]
end
oops
Isnât math.random inconvenient
what about pseudorandom?
yeah
oh does SMODS have a random func?
Pseudorandom is the most commonly used
oh
pseudorandom("selection", 1, 5) i think according to how the function is defined would do it?
i mean is there really any significant reason to use pseudorandom over math.random?
oh i guess maybe seeded runs?
ah
wait, there's a little bit of a problem
what if the joker selects itself?
how do you exclude it from the random pool
i know about the hacky solution of looping over the rng but that is most certainly not it XD
local selected_joker = nil
if G.jokers and G.jokers.cards and #G.jokers.cards >= 1 then
local pool = {}
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] ~= card then
pool[#pool + 1] = i
end
end
selected_joker = G.jokers.cards[pool[pseudorandom("insert description of source here", 1, #pool)]]
end
yeah just get a pool of all the indices of jokers that are not itself
then pick a random element from that pool of indices
avoids the hacky solution that is technically not guaranteed to terminate
cool, thanks đ
yes, it's generally recommended to use pseudorandom instead of math.random for the sake of keeping seeds intact
How would I go about testing out a certain stake
(Under the assumption I haven't unlocked it yet)
so like testing the unlock condition?
testing the stake itself to make sure it works
It's more I just don't wanna have to beat like 10 stakes
switch to a second profile and unlock all
profiles are in the very bottom left of the main menu, switch to a fresh profile and there should be an "unlock all" button. if there isn't, you should reset that profile first
its on the profile screen once you've made it
oh wow it's the profile I was supposed to use for modding before forgetting I had it and using my main
yeah dont ruin your main when u test modded unless ur fine with that
this is bothersome
ah yes invisible stake, my favorite stake to play on
Is there an easy way to turn a known reference to a table into its string key? I.E. I want to get a card's area, however, rather than getting the reference to G.jokers or G.consumables, I want to get the string 'jokers' or 'consumeables' which could be used to index the global table. Is there a simpler way to do that that doesn't involve just iterating through the global table and getting the key when the table reference matches?
hi winter
Hi Dilly!!
how are you
doing decent ish?
why the ish
ehh just not my best day I guess. Most days aren't my best days but I don't have any strong, significant feeling about today
well, i hope you know youre awesome and epic
i did some looking online, it appears that there is not a convenient way to get "jokers" from G.jokers without iterating through the global table
If you only care about vanilla areas then you can handle each one individually
Shucks, but that's kinda what I expected
Otherwise, you can create a table when the run starts/loads that contains references to each existing cardarea, and loop through that table rather than G
Assuming no mod creates cardareas after a run starts
Too risky an assumption to make
I don't have to worry too much since this is something that seemingly will only ever need to run once when it needs to
(I'm doing an SMODS pr to update the save_with_action function that's kind of underbaked in vanilla)
Actually maybe you can do something with metatables, using __newindex
Not worth the hassle if it's only ever gonna run once
Yeah
Anyway all of this is for a niche as fuck use case where I have a challenge that saves after you use any consumeable, which the base game actively avoids
ok, quick question
is there a way to manipulate the on-screen position of a joker with code?
Couldn't you do something like:
function findStringFromRef( ref )
for k, v in pairs(G) do
if ref == v then
return k
end
end
end
Ahh, I guess I missed the last part of it, yes.
anyway
is it possible to alter the amount of chips cards score?
without using the perma_bones
You can directly change card.base.nominal if you need, but it'll reset the next time Card:set_base() or related helper functions are called to the rank default
Or hook Card:get_chip_bonus().
I ended up doing both for a blind effect that makes chips score 0 base chips for the blind duration
(yes, the d100 genuinely did roll a 9 with advantage there. i reloaded the save with some debug prints to check that, the other roll was a 6)
basically i want cards to score a random amount of chips. i know how to do the random amount but i just dont know how to put it together.
cataclysmically bad luck on that seed lol
function Card:get_chip_bonus()
if (-- condition whenever this should apply vs default behavior) then
local old_nom = self.base.nominal
self.base.nominal = -- put whatever your random generation is here
local ret = ref_card_bonus(self)
self.base.nominal = old_nom
return ret
end
return ref_card_bonus(self)
end```
That said the description you showed doesn't reflect this
It says earning chips before your hand scores, which wouldn't be per card. Is this something completely different?
im guessing that goes in the calculate function, right
No, this is a function hook. It goes wherever it can be loaded for your mod
yeah i want the cards themselves to score randomly. i guess i could just have every card cause the joker to score a random amount of chips if thats not possible
If that's what you want, make sure whatever causes this effect is phrased as each card scores +n base chips or w/e
how do you make a random select joker start with a joker selected?
like how rebate does it but for jokers
the problem is that rebate's thing does it every round and mine should be every hand, so just copying the rebate function won't help
the specific problem is that at the start of a run, the selected joker is nil, so it kinda crashes when doing logic with it. Ideally, it changes in the background so that when you find it, it doesn't have a default value
what do u want to happen if u have no jokers and this joker appears?
unless this joker cant appear if u dont have a joker
how could i make this enchancement give money based on the amount of chips this card scored? ```local diamond = SMODS.Enhancement{
key = "diamond",
loc_txt = {
name = "Diamond",
text = {
"Gives {C:money}Money{} equal to the",
"amount of {C:chips}Chips{} this card scores"
}
},
atlas = "diamond",
config = {
p_dollars = 1,
}
}```
@daring fern I pushed a commit with the current safe_set_ability setup and patch. Maybe it'll be easier to work through and figure out the problem if you can see it directly?
Get back to me when you can ofc
maybe something with card.ability.nominal + card.ability.perma_bonus, but not exactly sure how
try p_dollars = card.ability.nominal + card.ability.perma_bonus although idk what is the pointer to the card inside of that context
maybe look at vanillaremade and the code for ancient joker
oh
i guess mail in rebate is the same kinda reset
hm
fundamentally the random selection should work the same no matter where u put it
idea: implement my own reset_game_globals() that is called every hand instead
that sounds like a chore though
another lazy fix is to do the random selection when bought
as well
but u dont get foresight on which joker its copying
also u can do a check to see if the selected joker is nil and return "None"
but that would only fix the display text issue and not the nil crash as a whole
yeah
i'm currently looking into this btw
so does it crash when it appears in shop?
haven't seen it in the shop, but presumably yes
it only crashes when trying to choose a joker for the first time, since it tries to get the name and all the other stuff but gets nil back
does the crash involve trying to index a nil value?
hmm which line of code is causing the crash? is the crash-causing line in your mod?
How can i add an effect to every deck ingame ?
attempt to index local 'selected_joker' (a nil value)
it's kind of weird
because the actual variable gets updated the line before that
so i'm a little confused as to why it's throwing back nil
were u able to access the info of the selected joker right after it was selected (printing the name of the copied joker or something)?
nvm
hook one of the Back functions
printing returns nil, unsurprisingly
when u tested this, did you have another joker to copy?
no, it always was only with no jokers
tested it with more jokers and it did work so that's most likely the culprit
yeah u need to have a nil check then
Iâve added a flip and a flip all button based on how many cards highlighted, problem is i want to make it into an enhancement now and idk how to code it to update LOL
or rather, don't run that part if there are no jokers
that sounds more efficient probably
so like
get random joker
see if it is nil
if it is nil then return early
else
do everything else
Thread error (Thread: 0x0209b3f97040)
engine/sound_manager.lua:62: Could not read Ogg bitstream
stack traceback:
[C]: in function 'newDecoder'
engine/sound_manager.lua:62: in function 'PLAY_SOUND'
engine/sound_manager.lua:197: in main chunk
Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-0706c-STEAMODDED
LĂVE Version: 11.5.0
Lovely Version: 0.8.0
Platform: Windows
Steamodded Mods:
1: Talisman by MathIsFun_, Mathguy24, jenwalter666, cg-223 [ID: Talisman, Version: 2.2.0c, Uses Lovely]
Break Infinity: omeganum
2: Galdur by Eremel_ [ID: galdur, Priority: -10000, Version: 1.2, Uses Lovely]
3: Mod of Theseus by Mothball [ID: Mod_of_Theseus, Version: 0.0.3-alpha]
4: Handy by SleepyG11 [ID: Handy, Version: 1.4.1a, Uses Lovely]
5: DebugPlus by WilsontheWolf [ID: DebugPlus, Version: 1.5.0~dev, Uses Lovely]
6: Blueprint by stupxd aka stupid, Jonathan [ID: blueprint, Priority: 69, Version: 3.2, Uses Lovely]
Lovely Mods:
1: Trance
Stack Traceback
===============
(3) LĂVE function at file 'boot.lua:352' (best guess)
Local variables:
errhand = Lua function '(LĂVE Function)' (defined at line 579 of chunk [lovely debugplus.console "debugplus/console.lua"])
handler = Lua function '(LĂVE Function)' (defined at line 579 of chunk [lovely debugplus.console "debugplus/console.lua"])
(4) upvalue C function 'error'
(5) LĂVE function at file 'callbacks.lua:181' (best guess)
Local variables:
t = Thread: 0x0209b3f97040
err = string: "engine/sound_manager.lua:62: Could not read Ogg bitstream\
stack traceback:\
\9[C]: in function 'newDecoder'\
\9engine/sound_manager.lua:62: in function 'PLAY_SOUND'\
\9engine/sound_manager.lua:197: in main chunk"
(6) Lua function '?' at file 'main.lua:926' (best guess)
Local variables:
_n = nil
_a = nil
_b = nil
_c = nil
_d = nil
_e = nil
_f = nil
touched = nil
(for generator) = C function: 0x2c3f7438
(for state) = nil
(for control) = string: "threaderror"
name = string: "threaderror"
a = Thread: 0x0209b3f97040
b = string: "engine/sound_manager.lua:62: Could not read Ogg bitstream\
stack traceback:\
\9[C]: in function 'newDecoder'\
\9engine/sound_manager.lua:62: in function 'PLAY_SOUND'\
\9engine/sound_manager.lua:197: in main chunk"
c = nil
d = nil
e = nil
f = nil
(7) global C function 'xpcall'
(8) LĂVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 909 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(LĂVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LĂVE Function)' (defined at line 355 of chunk [love "boot.lua"])
Any ideas?
I was hoping that would turn into a text file, oof
bump
I think handy has plenty
can i see the place where the sound is defined?
you wanna know something funny?
hm?
no more crashes now yes
i think we would still need to account for when you have 2 of these and only two of these
hold on show me a place where the sound is played
We may have got it working
oh
Nope
different crash message or the same one?
randomHit() is a function that pulls a random hit sound effect from our files
so ur sure that randomHit() returns a string like "strong1"
also is that the only sound that doesnt work or do all custom sounds not work
It works
so its not crashing anymore?
Yup
Hello chat o/
idk i just linked to what @cursive gazelle said ||(sorry for ping xd)||
real quick, what are you trying to do with the keybind?
How do i destroy all played face cards after scoring? I'm new to modding balatro so I feel i will be asking a lot of questions here
Card:is_face() checks if a card is a face card
SMODS.destroy_cards(cards) destroys the given cards
How do you do a mod config option?
Pretty complicated
is it like the UI stuff? oof
very shrimple
create a config.lua file in which you return a table, like return { my_setting = true }
then you can access it in the code by doing SMODS.current_mod.config.my_setting (if during loading stage) or SMODS.Mods.your_mod_id.config.my_setting (outside of loading)
many people make a global variable that's just their mod id to access it more easily
like CardSleeves = SMODS.current_mod during loading
then you'd do CardSleeves.config.my_setting
for the ui you can do
SMODS.current_mod.config_tab = function()
return {
n = G.UIT.ROOT,
nodes = {
create_toggle {
label = "hi",
ref_table = YourGlobalVariable.config,
ref_value = 'my_setting'
}
}
}
end
assuming you went with the global variable way
How do you make something run only immediately after the game finishes loading?
i mean the UI code is scary (for me at least)
ui looks scary cus there are a lot of config values to make it look good
the ui code I sent won't look good I imagine
but at least it's simple to understand
what are the placeholder names here?
label is the text that would be shown next to the toggle
YourGlobalVariable refers to doing YourGlobalVariable = SMODS.current_mod near the top of your main file
'my_setting' is the key of a setting returned from config.lua
also there are other ui elements for configs, not just toggles for booleans, i'm not familiar with the others tho
sorry for the late reply but putting that inside the config just straigth up crashes the game, and i tried doing ```config = {
p_dollars = 1,
},
calculate = function(self, card)
p_dollars = card.ability.nominal
end``` but that does nothing
idk then. i was kinda just guessing bc i haven't done anything with enhancements
what do you want the enhancement to do
basically it's suposed to get the amount of chips the card scores, and give the amount of money based on that
when the card with the enhancement scores?
yeah
calculate = function(self, card, context)
if context.main_scoring and context.cardarea == G.play and not SMODS.has_no_rank(card) then
return { dollars = card.base.nominal }
end
end
should be smt like this, without your config
that works perfectly, thank you!
you forgot to account for hiker !!!!
return {dollars = card.base.nominal + card.ability.perma_bonus}
if you want that, replace card.base.nominal with card:get_chip_bonus()
i made a dastardly misread there which made me do a violent double take
huh
oh no
lets walk through it together, what else could start with 'hi' and end with 'er' that someone who only glanced could see
i just realized that đ
i was just sitting ehre listening to music and playing and then glanced over cause i saw a message appear and saw that lmao
Higher ?
so true
what is that even SUPPOSED to mean
Working on something
??? is this supposed to be like an effect that lets you preview the next reroll or something?
I would say better
Iâm not sure what effect i should associate with them
My ideas arenât organized yet
Hi, today I installed the Balatro Mod Manager and it keeps loading mods all the time. Why could that be?
I've already reinstalled it 3 times
I wish i was good at art as i am in coding
Ask in #âă»modding-general
quick question, what do you mean by them?
The cards
i was told a while ago that quantum enhancements are broken, is that still the case?
joker cards, tarot cards, spectrals, or a new kind of consumable?
in what way are they broken
don't work
I can technically either make a shader and make it an enhancement or make it an enhancement (which i already did for testing )
to my knowledge they work
I can apply it to any card currently
where did you hear this
yea as far as ive known they havent been broken
someone told me this here
oh, an edition-like enhancement, hmmm
but it was a bit long ago already
âThis card perceives what lies beyond your vision.â
I feel like this is a little vague
hmm ur gonna have to clarify what it can see
otherwise it feels like flavor text
Anyways iâll post a video of the mechanics tomorrow since its mind night i might aswell post a documentation on how to add buttons to cards and hook functions to them
what's wrong with this here then? it currently does nothing
Because peopleâs codes are kinda lacking
When it comes to comments
use SMODS.has_enhancement(context.other_card, "m_stone"
Absolutely don't do that, it will cause an infinite loop and crash the game
Do you have the optional feature of quantum enhancements enabled?
It's likely you just never set it to be enabled yeah
where do you do that?
SMODS.optional_features.quantum_enhancements = true
I just put it at the top of my main file
hold on what exactly does quantum_enhancements do?
it should be on by default....
It makes enhancements count as others
It's very ressource-heavy
The more cards you have the laggier it gets for some
I think they keep their value
(or that was fixed idk)
two (or more) enhancements for the same card
in this case, gold and stone
Quantum enhancements are temporarily given enhancements for the duration of scoring steps and then returned to their original values, essentially. So it acts like having multiple enhancements that only exist at the time of scoring
That explains it better đ
so like if a steel face card was played and u had a midas' mask, it would be temporarily treated as having both?
You could make a Joker do that, but it doesn't impact vanilla Jokers
No
what do u mean by temporary enhancements
That's how it works under the hood
It's mostly used for jokers that goes "Steel cards counts as Gold cards"
for example
With quantum enhancements enabled, whenever enhancements would score, it sends a context to all valid receivers (context.check_enhancement) which can then send back keys of enhancements for the current card to also be counted as. Then, during the scoring step, it saves the card's actual enhancement and values, then temporarily uses set_ability with each of the provided keys, scores it as that new enhancement, and then returns the original enhancement and values
So cards do not have permanent values set by their quantum enhancements. The others only exist as long as they're needed for scoring, then removed
is there documentation available for quantum enhancements that i can read?
it's really cool :D
It's on the wiki, in the current calculate functions page. It has a thing for check_enhancements though a better version of it is on the way
why did it record like that :(
real quick, how would i use context.check_enhancement to treat all played mult cards as bonus cards for instance?
Take this but swap the keys
Add +40 chips manually with context.individual
ah
Don't forget to enable that feature too
You can tho
you can with quantum enhancements
It's what we've been talking about for the last 5 mins lol
You can do anything if you can spare the time and effort
what??
an actual doc?
its a built-in smods feature
Literally the backbone of this deck.
Really?
yeah??
Is it documented?
yeah that was JUST sent
what is reading
balatro fans cant read..
who is reading
I wish I had eyes
A noun
no?
Twice in a row too đ
ldksnjfkjihaew LMAOF đ
Iâm sorry i didnât pay attention
is this page accessible from the steamodded wiki? i cant find a link to the page in the imagr
it's eremels secret docs he doesn't want to share because he's hoarding all the information to himself
/j
secret stash
You have to pay him 25âŹ
Gatekeeping the smods docs
hi dilly i just finished stray
how was it
being a cat is very stressful
would you become a cat after now experiencing its life
it was very cool i really liked it
that shit seems scary
how do i make tooltips like these appear?
info_queue, it's in the localization docs
im surprised you beat it so soon, is it a short game?
Slowpoke 
annapurna games are nice
i like when games are 6 hours at most
now i need to start a 70 hour rpg
i just like games idrc about length most times as long as its engaging
preach
you say that because you havent played hundred line
i could consume you
vore?
im a spectral
no in the friendly way
đ€š
How do you consume someone in the friendly way?
carefully
with consent
little nibbles
70 hours you say....
sorry im so confused, something like this?
im leaving e33 until i finish all the final fantasies
it's crashing tho
youve got so many games on this wl ive never heard of
If i recall thereâs 17
i said all
there's like 50 something in my list where i exclude only mobile and chocobo games
have you played to the moon, n?
im waiting for the fftactics remake to continue
yeah but i dont remember anything about it lol
when i try to use Cryptlib it doesnt work
it crashes when i start a run
is this just something with the mod
yeah cryptlib seems to be broken rn
đ
who on earth could that be from
we'll never know


i got u deluxe also
so dont forget about whatever bonuses they talk about in some options or whatever
im going to cry
when it drops
toma hasnt even played the game i got them yet i dont think
crying in the club
thank you for the birthday gift
u will get many more but u are welcome
Very wholesome modding chat
N has been a nice pal for awhile in here it feels like
at least since ive been in here
and i like seein him and consider us buddy pal friends so why not treat him
sorry this is unrelated but how should i go about adding a standard card with an enhancement to any area?
i'm seeing alot of different ways so i'm a tad confused
i'll see if i can find anything else on create card
SMODS.add_card({set = "Base", enhancement = "m_modprefix_key", area = area})
Happy birth
N reached a whole 4 years old today
i was going to repeat that as a funny haha but im worried about discord banning me
Free from discord hell
in this context what does set mean? asking because when i last used this it was indexing nil for center and i'm usure if that has to do with the area or set
set is the category the card belongs to, like "Tarot" or "Planet"
How can i test if context.other_card has an enhancement?
A specific enhancement or any enhancement?
is there a context for after a consumable is used?
Specific (modded)
context.using_consumeable
context.consumeable is the card used
Added a force save for consumables for the purposes of a challenge. Now it records consumables as an action the same way that opening booster packs does so you can't save scum them
oh! so is "Base" referring to standard cards or is there a list of proper calls for them all
well now how do i break this
i'm trying to rewrite jokers that debuff every card in a suit but the debuff doesn't appear to work after a consumable is used
Base is for default cards yes
set can be any pool, also allows "Base", "Playing Card" or "Enhanced" for playing cards
You can find all set easily in game.lua
SMODS.has_enhancement(context.other_card, "m_modprefix_key")
base is for unenhanced playing cards specifically
you can do enhanced to get one with a random enhancement or just "playing card" to roll an enhancement or not based on the default standard pack enhancement rate
Thanks , thatâs what i was using i had the mod prefix and m flipped
ahh alright tysm ! writing this down for future
i am recieving this error and i don't exactly understand why
I've noticed something a bit strange with one of my scripts
For some reason, when the context triggers for the Joker, it triggers the effects twice
The context is just skip_blind
Should i be adding a second context
Did not work
Sadly
Code?
Print "context" see what's the other one triggered
if context.individual and cardarea==G.play and SMODS.has_enhancement(context.other_card,"m_aao_p_flip_card") == true then
return {
xmult = 2
}
end
end,```
oki
context.cardarea, not just cardarea
i see
also == true is unnecessary
I know i added it just because it didnât work first time
hm
Printing it only triggers once
what's your code?
Very spaghetti
Hold on
It doesn't use context the way you normally do because it has specifics to it
for action_name, action_list in pairs(ALLOY.actions) do
for _, entry in ipairs(action_list) do
local ok = true
for _, clause in ipairs(entry.context) do
if type(clause) == "string" then
if not context[clause] then
ok = false
break
end
elseif type(clause) == "table" then
if context[clause.key] ~= clause.value then
ok = false
break
end
else
print("[ALLOY] Invalid context clause:", tostring(clause))
end
end
if not ok then
goto continue_entry
end
if action_name == "health_drain" then ALLOY.ease_health(entry.value)
elseif action_name == "shield_drain" then ALLOY.ease_shield(entry.value)
elseif action_name == "dot" then ALLOY.ease_damage(entry.value)
end
print(context)
::continue_entry::
end
end
Is there a way to remove the xmult display ?
I want to replace it with something else
So you want it to say something other than Xnumber Mult?
Yes
if the case how does stuff like this work in Vremade jokers?
the context for this is just
ALLOY.set_action = function(action, context_tbl, val)
table.insert(ALLOY.actions[action], { context = context_tbl, value = val })
end
Then you would use xmult_message
<@&1133519078540185692>
đ«
Goodnight modding dev
Too late
What even was it
mrbeast
mrbeast scam
slow
What does can_repeat_soul mean?
MrBeast crypto scam
it allows soul-type cards to repeat without showman iirc
Ah
do we finally have gif perms again :o
no thats a webp
oh
I don't check the GitHub page often.
well you should
Yeah, I should.
Make a project and test everything in the wiki
Is it possible to check if a card has a perma bonus
Anyway, how would I go about giving a card a percent chance to appear in place of The Soul, and nowhere else?
wili
yeah just check for card.ability.perma_whatever
Make it legendary?
Wait no I read that wrong
Lol
ahp figured out the issue , what am i doing wrong with this? i can call "m_stone" fine with add_card but i can't called m_bubble which means i'm missing something
if its in place of the soul then you would need to patch/hook create_card i think
i dont think the player will notice if you just make it a rarer the soul tho
i think this might be too niche of a usage for me to get help :/
Uhh
Does context.skip_blind and context.cardarea = G.jokers work as a valid context do you think
like if I specify it
why would you need a cardarea check in skip_blind
Yes, you're missing your mod prefix.
because skip_blind triggers twice
idk
wierd
oh shoot i really should stop taking reference from Vremade in that case i missed that part
I suppose I could try that, at least until I get the intended way working.
i mean it is good reference still
its just that it doesnt use the vanillaremade card modifiers when applying modifiers
because apparently it confused people when trying to apply vanilla stuff to cards
yeah, i will clarify that on the wiki tho
gosh get the wiki done by yesterday already
I figured it out
context.main_eval
didnt even kno u needed that here but it works
i was busy being a cat
I mean yea
I read context.main_evil
wallahi im cooked 9600 blind requirement ante 2
bump
Comedy
alright, so question
let's say i have a locked joker that appears in collections.
if i open up collections to the page where that joker is, if i do SMODS.find_card() with that joker's key, will that return the joker?
no, i dont think so
or does it only look at the run cardareas
im pretty sure its only cardareas
hmmm. so how can i tell if a specific locked card object is present either on the main menu or in collections
what's the goal
i want to have something that's unlocked by pressing alt + f4 with it onscreen (whether via it appearing on main menu or looking at it in collections)
i have capturing the alt + f4 worked out in theory, but i'm stumped on how to determine whether the object in question is present
you can do the unlock in that card's update function
that's always run if it's on screen
i dont know if it reaches there before the game closes tho

what's proper syntax for setting prefix under an enhancement? i'm finding very little on it
m_?
hm?
enhancement prefix is m_
modded enhancements are m_<mod prefix>_
i feel like we need a bit more context for this
sure! i think just saying m_ or m_prefix confuses me quite abit because like how do write that with something is it m-('name') or is there something before it,
just trying to set prefix to this
oh, when you use SMODS.Enhancement, the prefixes are automatically added
For none modded
m_prefix
For modded
m_mod prefix_enhencementkey
Prefixes are automatically done you donât need to set them up
so as written there, the item's prefix in-game will be m_<your mod prefix>_bubble
No, it's your mod prefix.
i was just going to say, should be calling it like that?
oop 
This is what you should be calling it
when referring to it yes
Make sure its a string tho
the prefixes are automatically added in the enhancement def though
Np
if you have debugplus, you can check this for yourself - with what you've shown, you could launch balatro and do eval G.P_CENTERS.m_<your mod prefix>_bubble and it should return your enhancement
i found this in button_callbacks
idk if alt f4 calls it though
I think love has it
Event.quit() should have alt+f4 integrated not just the âXâ in window ui and quit button
what is the default pixel size for boosters because mine look blurry, is it just the standard card size (91x75)
although even if i hook quit, how do i distinguish between alt f4 and quitting any other way
I think its bigger
would that be where the keybind comes in
71x95
also how would i go about generating boosters mid game, idk if debug plus can do this but it seems like it cant and i need to spawn them in
it's made bigger ingame
same difference haha
wdym
There should be and event for clicked keys
Look for
key down alt
Key down f4
love.keyboard.isDown()?
i see where i all went wrong it's the fact my json file was updating WRONG! it was updating to a seperate folder when i updated the prefix
Iâm not sure i havenât used love
Check for keyboard input capturing in love 2d documentation
yeah, i'm looking at it
i hooked love.event.quit and it got called when quitting from the menu but not alt+f4
Strange
Since the game closes when you press alt f4
it might be some other OS api stuff
now, my thoughts are at doing something likelua love.keyboard.isDown{ 'lalt', 'ralt' } and love.keyboard.isDown{ 'f4' }in the card's update func
love.quit does get called
does anyone know
you could prob prevent it by returning true on it as well cant you
:3
it can in the shop
oh, this was with the card in collections/on the main menu?
no, in-game
ah
but it means it can find the card at least so you should be able to do what you want
you can just spawn them in when youre in the shop?
ye
idk how safe it is to save when the game is quitting tho
Would their achievement be saved tho
cant you just delay the quit to save
it would need to save manually in the hook
I see
i think so
I donât think that would work of be efficient
i can't just set a var in mod config inside the quit hook and hope it saves that way?
let us know how it goes :3

I hate UI
I have a joker mechanism, but the description crashes on the second hover
why the second one đ
I get this
I think it's because I'm not saving the metadata, but if I do save it, continuing the run will remove the mechanism
Hovering it
i mean in the description
No
I'm trying to get a joker's desc into a multibox
I think generate_UIBox is adding something the game doesn't like after the first exec
oh then it might be what i thought
i think the uibox gets destroyed after unhovering
you need to recreate it every time
Interesting, how do I tie it to a card tho? Since I do all the generating during a consumable use
cant you save the key on the card or something
thats what i do for my transfer ability mechanic
true maybe, I'll try đ
Wait you can generate an UIBox from the key alone?
Or like do you want me to do it from G.P_CENTERS? (if it exists but I doubt)
you would probably need to make a new card to do it like you're doing
Creating a card just to show a desc then remove it?
yeah
i dont know enough about what you're doing haha
let me show you how i do mine which might be better
something like this, basically I generate the description box from the center
i did some changes because i dont actually use the main joker description
doesn't work, i need to force a mod config save before actually calling the quit function 
it looks like this
it allll turned out nicely
anyone know how to force the mod config to save
wait
what if i put the quit call in an event 
p sure theres a function to save mod config
Anybody know of any examples of custom card areas implementing negative edition functionality?
I donât think thereâs room to add more Cardareas
yeah its SMOODS.save_mod_config(mod)
I have the card area made, I'm just trying to make it work properly with negatives
odd, i had the opposite issue lmfao
wanted negative editions to not increase the area's card limit
Huh
WHAT THE FUCK, A YUGIOH MOD?
You got fans N
Can I use localize instead of desc_from_rows for multiboxes?
Ok shit just got weird
It's incrementing G.consumeables instead
Just now noticed that
yeah, it's missing a bit just after the screenshot where I save the nodes after the first one in full_UI.table.multi_box
you might want to make sure card.area(?) is not G.consumeables lol
i would link you to what i do but it's in a lot of hooks and patches lol
oh does negative edition not just increase card limit of card.area??
I think it boils down to my emplace hook but I'm not sure why
no, it's hardcoded i think
question for yall: making a joker that gains XMult when a king of spades or clubs is played. Weird bug where if blueprint/brainstorm is copying it, it gains twice the mult its supposed to. Wrote a bit to check if the xmult increase has already been applied but that'll stop it gaining with retriggers like hanging chad or if more than one was played in that hand, anyone have any other ideas to solve?
if not context.blueprint
that is certainly one of the codes of all time
you don't need to check that context exists, within context.repetition context.other_card always exists too
and it will always be a Card object, so you don't need to check that it's a table, or has the get_id function or has a suit
ok thanks. first mod so still figuring stuff out
card = self is not crashing?
oh yeah
What does the colour crash mean again in UI?
local is_clubs_or_spades = card:is_suit('Clubs') or card:is_suit('Spades') to simplify and not need local is_wild_card_effect.
your node layout is wrong i think
too nested
context.blueprint vs context.blueprint_card who's winning the twerk off
someone should update the calccontext lsp docs
i dont use either because i disable blueprint:3
Hey thank you so much for your help. I figured out the issue and it was totally my fault.
I neglected to test the parts piece-by-piece and it turns out that Malverk wasn't installed correctly. I fixed that up and all of a sudden, everything started working as expected.
Huh lmfao
funny alignment
I'm trying stuff up but I should look at desc_from_rows again
Never made my own UI nodes before
Oh thats why it's HARDCODED đ
yeah
What do you prefer?
1
1
2
Jokers' Galore
is there a way to check how many cards discarded when you do something on context.discard
#context.full_hand
should i make a patch/hook pr to have it increase the card limit of its actual cardarea instead...
do i have to have a return with card = card in it to save a value into the card
Evening evening, Is there a way to make a joker spin like when a card gets affected by a tarot card? please
-# actually anyone can do it, it just sounds annoying for it to not do that
:flip() twice
thx! but does it has any arguments?
no
what does this mean
sob
And there's a way to make it spin faster?
some of the examples in smods have
return
{
(stuff for the message thing below the joker)
card = card
}
it's done through events, i would recommend looking at the tarot code
old examples
you never need card = whatever
you dont need card = card brav
ok ty
the smods examples of jokers should just be changed to point towards vanilla remade at this point
I'll do, thanks!
That would be fantastic
does this apply for brainstorm or do i need a separate check
it does
sweet thanks
or any other blueprint like
i dont say this because i would be biased : )
its True... though
I'm not, play VanillaRemade đ«Ą
Ugh I hate making invasive patches like that
At least it works now
hi, how do you guys do glass visuals?
What do you mean?
Search the SMODS document
I'm pretty sure the sprite just has to be transparent.
I'm trying to track and understand the functionality of Boosters when they're opened through close. I see the UI being created using something like G.booster_pack = UIBox {...} The cards are put into a cardArea of G.pack_cards. And I see how if you skip the booster then G.FUNCS.skip_booster runs a calculate context that you can hook into and then calls G.FUNCS.end_consumeable(e) which seems to remove the UI - G.booster_pack:remove()
What I can't seem to find is how the UI is removed if cards are actually chosen? I'm trying to do something when a booster closes.
if my_pos and G.jokers.cards[my_pos + 1] and not SMODS.is_eternal(G.jokers.cards[my_pos + 1], card) 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 -- Make sure to do this on destruction effects
G.GAME.joker_buffer = G.GAME.joker_buffer - 1
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.joker_buffer = 0
card.ability.extra.mult = card.ability.extra.mult + sliced_card.sell_cost * 2
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
would inserting this into my code cause it to work like ceremonial dagger (im just confused because i dont know how add_event works and i wanna make sure (assuming we have all the variables required and stuffszsd))
if this is just the code from vremade then yes
ok yeah it pretty much is but i changed the position of the end to not make the message happen
ty
How do you change blind to a specified one in DebugPlus?
Press 3 over the blind in the collection while in the blind select screen
oh, sweet, thanks
hey, is there a way to directly manipulate the onscreen position of a joker?
return { vars = { card.ability.extra.xchips, card.ability.extra.xmult, card.ability.extra.xmultup, card.ability.extra.route, ((card.ability.extra.route == 0 and 'Neutral') or card.ability.extra.route == 1 and 'Pacifist') or card.ability.extra.route == 2 and 'Genocide' } }
this line is in my local vars
what is casuing this crash
you're sure it's that joker specifically?
what's the entire loc_vars function
ok specifically: it happens on card.ability.extra.xchips
i think it happens on all of them tbh but thats the first one
loc_vars = function(self, card, contexts)
return {
vars = {
card.ability.extra.xchips,
card.ability.extra.xmult,
card.ability.extra.xmultup,
card.ability.extra.route,
((card.ability.extra.route == 0 and 'Neutral') or card.ability.extra.route == 1 and 'Pacifist') or
card.ability.extra.route == 2 and 'Genocide'
}
}
end
oh
wait
(self, info_queue, card)
i used calculate
are the parameters
common instance of me being stupid and thats the problem:
i have no idea what im doing wrong
idk man
if context.discard and card.ability.extra.route == 0 then -- gets here print('in genocide set') if my_pos and G.jokers.cards[my_pos + 1] and not SMODS.is_eternal(G.jokers.cards[my_pos + 1], card) and not G.jokers.cards[my_pos + 1].getting_sliced then print('in kill script') local sliced_card = G.jokers.cards[my_pos + 1] sliced_card.getting_sliced = true -- Make sure to do this on destruction effects print('route:') card.ability.extra.route = 2 print(card.ability.extra.route) G.GAME.joker_buffer = G.GAME.joker_buffer - 1 G.E_MANAGER:add_event(Event({ func = function() print('in xmult edit') G.GAME.joker_buffer = 0 card.ability.extra.xmult = card.ability.extra.xmult + #context.full_hand * card.ability.extra.xmultup print('xmult:') print(card.ability.extra.xmult) 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
why doesnt it go into the card killing script (there is a card to the right of it which can be killed)
where'd you define my_pos
There's no easy way to modify the return table of another Joker from a Joker effect right
This is lovely territory
No, there is an easy way.
Do I just modify other_ret
Yes.
its always been like that afaik
I do end up needing to patch because I have to interact with shit triggering at the cashout screen
gaah!
:3
i have a joker that changes a value (doesnt let blueprint do it) then uses it in the very same if statement as the next if statement (its weird)
i also have another if statement
my problem is that blueprint isn't working if i havent already set that value outside
if i swap the two if statements, will that fix it? or do i need to do smth else
this is probably very confusing im gonna send some code for it
if card.ability.extra.route == 0 and not context.blueprint then
card.ability.extra.route = 1
end
if card.ability.extra.route == 1 then
return {
xchips = 2,
xmult = card.ability.extra.xmult
}
end
if card.ability.extra.route == 2 then
return {
xmult = card.ability.extra.xmult
}
end
end
Can I have a text input in my Config section? I'm working on a debugging mod and I want to allow the user to customize the filename pattern.
If so, does anyone know of any mods that do this?
just brute forced it lol
Hey does anyone know how to run balatro programatically with proton on linux?
#!/usr/bin/env bash
export STEAM_COMPAT_DATA_PATH="$HOME/.steam/steam/steamapps/compatdata/2379780"
export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.steam/steam/steamapps/compatdata"
"$HOME/.steam/steam/steamapps/common/Proton 9.0 (Beta)/proton" run "$HOME/.steam/steam/steamapps/compatdata/2379780/pfx/drive_c/users/steamuser/AppData/Roaming/Balatro"
I am trying to start it up from the terminal with proton but it fails to start. I assume the balatro.exe directory is incorrect?
folks, is there a context for using a certain consumable type?
if context.using_consumeable and context.consumeable.ability.set == "consumable type here" then
gotcha
one last thing: is it possible to manage arrays inside SMODS.(type) using dot syntax? (like creating a table and referencing a specific field of it in calculate later)
You would do card.config.center.(insert field to get here)
so like card.config.center.pos would get the table for its position in the atlas
oh gotcha
Add a limit to the memory card joker
2
3
2
No.
i was trying my best to not use that word in my mod and here it is đ
soul_pos
woah is that john debug
no
Like this?
what the fuck is that key
The background does not appear
did you do soul_pos
soul sprite is on the same atlas, you dont need to define anything else except for key, path, px and py
It's for a Chilean YouTuber
also ngl you should really rename the joker
Said John Debug with a funny face mask (googly eyes and all)
questionable
but anyways, your joker should have both pos and soul_pos
pos for the bg, soul for the fg
Not sure if modify_hand function is the one for blinds if you want after scoring for cards/jokers is there a diff function?
what r u trying to do
also really change the jokers name
Sorry
I second this
But if there are two images
i third that
I just want the boss blind to be after everything scoring
How will you recognize the two?
i forth it
the sprites are all in the same image file, no?
No
omg do tou have every joker in a different image
Yes
:3 make them into one image file like an atlas then
you are beyond saving
đ¶
true
What do you mean by that emoji?
you misunderstand the purpose of an atlas
its meant to be a big image of alot of different smaller images
Blank of emotions, you're beyond cooked đ„
yes
YES
yes đ
hi dil
but if I need to put in a new joker
hi bepper the bepser
THEN ADD IT TO THE IMAGE
or do what nxkoo is doing and have like, a gazillion small atlases
Don't yell at me, I know I'm stupid.
super inefficient but kind of works
Don't do that đ
i mean not even kinda works, it does work
shrug
its just not as smooth
yeah, no reason to do that at all
asides from you being lazy as hell
to bother compiling all the sprites into one image
which should only take like 30s top
really the only reason to have separate atlas is if they have different sprite sizes or if its like jokers compared to tarots
time is money, we save all the time we can
no we spend it all the second we get it
Ah
i hate this sistem
i hate coding
then dont do it
we all hate coding sometimes
it isnt so bad, you grow use to it
:3
thanks
i think discouraging someone isnt the way to go here really
everyone starts somewhere
I don't mean it, I'm just venting.
dont do this btw
even the twink agrees
twinkoo
im a living example of the broken condom and went hell on the documentation
i wholly agree
I Holy agree
Iâ â â â â â â â â â â â â â â agree
I e
Ă«
also dont call me this
we collecting every somethingcom's letter reactions with this one
like fr or part of the bit
fuck em pokedex, gotta find them allâą
false
there are 2 types of people
those who know how to shader and those who dont
-# there are people
the people with too many decks and the people without
la passion
Can modify hand for blinds only apps before jokers and cards calculation?
