#💻・modding-dev
1 messages · Page 412 of 1
Is it being done on a new run?
It’s probably an instance of the joker with a different config
when i hover over the pack in game it crashes, what did i do wrong?
what does the crash say
also do you have a TheSeals objecttype?
and G.C.JOY.NORMAL and stuff are colors from my mod lol
yes
wdym
now that i look at the names, yeah its u haha
this
you can delete the ease_background_color function for now
and what do u mean by objecttype?
thought kind is just name?
or is it for set?
btw is my localization for boosters correct?
i think it is
for the set of create_card
??
well it depends on what you want the booster to give
i want it to give specific spectral cards
then yes
oh uhh i wouldn't copy the objecttypes from my mod i do weird things there
and i dont use them :3
yeah you can put all the spectral keys directly in cards
like this?
and now i add spectral keys?
this key?
as is?
wish to help, but struggling as is
do the same thing you did in context.repetition but in context.individual
do u by any chance know the keys for normal seal spectrals, "red,blue,gold,purple" their spectrals key
yes
and well, the return for xmult
change SMODS.individual to context.other_card
wait
nvm
nvm
wrong
remove .individual from SMODS.individual
lmao
hehehehe
try capitalizing Seals in the localization
make it 3 braindead people
thats a can of , not dr pepper
yea yea
will try
that somehow worked
now i repeat 3 more times for 3 more boosters
shouldnt cause issues
Trying to permanently upgrade cards held in hand and it doesnt seem to be working
There, now it's illegal substance 2
local faces always get reseted to 0 because it's outside of context scope
cheers
why does seals give 0/3
shouldnt it be 3/3?
I have the same problem lol
not sure tbh
because they're undiscovered/locked prob
I like the idea of this adding 1 to your game speed when used lol
which parts
show code?
You have two calculate function, so it triggers the last one
Put both context check into one calculate function
You have to remove those two things
Do you have a lua extension on vscode btw? i'm surprised it wasn't highlighted
In VSCode, you have those 4 square symbol to get extension, you can type "lua" and get Sumneko's lua extension
Still not upgrading those cards. am I being foolish? Did I fix it wrong
you could have it return both xmult and repititions but sure
can you
I think, not sure if there's one too many end or sum
horrendous indentation
Because your local value only exists in a specific block or lower
for i = 0, 1 do
local x = 5
for j = 0, 1 do
print(x) -- x == 5
end
end
print(x) -- x doesn't exist
Does checking for faces in context.after not work?
probably does work, just didnt know it would
dont think it really matters
it doesnt, its just a bad practice to have bad indentation
sorry I spose
Is this better?
no
okay wait, whats indentation
it not only helps you but other people as well when troubleshooting your code :3
-# also, remove card = self
you probably want to do, if my guess on your joker's functionality is right
return{
message = localize('k_upgrade_ex'),
colour = G.C.CHIPS,
message_card = context.other_card
}
Sorry, reall caught up on the indentation thing. what should I be doing instead of what I am currently
Like I often need help so if it helps make it easier to look at and read I wanna do the best I can
well uh, a lot of things need to be fixed in your code
-# i dont even know where to begin actually
can you tell me what you want to do and i will write you an example of that rq
might be faster to do so instead
When a face card is scored, cards below rank 7 held in hand permanently gain +1 chip.
shift+alt+f allows you to format your file
Awesome I didnt know that
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if context.other_card:is_face() then
for _,v in ipairs(G.hand.cards) do
if v:get_id() < 7 then
SMODS.calculate_effect({message = localize("k_upgrade_ex"), colour = G.C.CHIPS}, v)
v.ability.perma_bonus = (v.ability.perma_bonus or 0) + 1
end
end
end
end
maybe smt like that?
you overcomplicated it too much sob
If they're learning it's bound to happen
fair
Sob as as in upset sounds or are you calling be an SoB
Son of a
Son of a Bi I assume
Smh bepis so rude
IM SORRY
Trust me its not just Balatro
I'll try to code ina sec just making coffee
The*
yeah i understand, my advice for coding jokers is to dissect your effect into multiple parts so that you know what to do, like:
"When a face card is scored" -> needs context.individual and context.cardarea == G.play
"cards below rank 7 held in hand permanently gain +1 chip":
cards in hand -> you want to use G.hand.cards
below rank 7 -> use :get_id() < 7
permanently gain +1 chip -> perma_bonus stuff
i think its just muscle memory to remember what context you need for what effect though, so it will take time for you to get used to this
amazing
This is super helpful!!!!!!!!!
is this your mod
or
is this waffle's wip mod
i remember them saying they will work on smt like that a few weeks ago
I made some of this.
holy shit
super impressive, wow
but for 200 bloodstones aint that too little X1.5 triggers 🤔
i would assume you didnt code in the calculate yet, but some cards give 2 X1.5 Mult, so
I added an oops and they triggered all 200 times but I split them without the oops and they triggered more reasonably.
I'd specifically advise into breaking down specific parts of the effect into timing triggers and other things
Timing triggers are context checks
the rest isn't
I have coded it in, most jokers work.
also e.g. if your effect has a beginning and an end, even if not explicitly stated, it might need two context checks
huh, but 5/200 triggers is still pretty weird, considering the chance of bloodstone is 1/2
🤔
Chances seem to be broken sometimes for some reason.
How does one remove a joker without calling its remove_from_deck function?
Yeah that clip did not feel normal
Also, how does one check if 2 playing cards are the same?
By being the same do you mean same rank, enhancements, seals, suit, and other stuff
Yes.
I don't think there's a vanilla function for that, you'd have to make your own
Maybe you can compare the centers, the base and other stuff like that
I love juicing my cards 🤤
Most original joke
lol
what do i put on SMODS.Consumeables to know that i sold that consumeable
SMODS.Consumeables doesn't exist?
this? (im assuming you are talking about SMODS.Consumable)
what do you want to do exactly?
but what's making the joker
wdym
if context.selling_self then
SMODS.add_card({key = "j_modprefix_key"})
end
```?
ok thanks
something triggers when a consumable is sold to create a joker
what's that something?
if it's the consumable itself then use something's code
ok then yeah
Okay so i tried to make the use of pseudorandom in order to establish a 1/3 chance that my joker would trigger two additional times like a blue print, i think the problems comes from the code for the luck itself because it definitely shouldn't always trigger, i may have got the rest to work now but this part bugs me, i never used pseudorandom before, just math.random
local stupidblue = function(card, other_joker, context)
if pseudorandom('cymbal_dprinter') < G.GAME.probabilities.normal / card.ability.extra.odds then
local blue1 = SMODS.blueprint_effect(card, other_joker, context)
local blue2 = SMODS.blueprint_effect(card, other_joker, context)
return SMODS.merge_effects({blue1}, {blue2})
end
-- returns nil if condition fails
end```
I should also precise i also used the function SMODS.merge_effects that did in the end worked out for me to do both effects but i'm pretty sure i shouldn't be that 'lucky'
it always triggers?
where are you using the return from that function
I don't think that's how you call merge_effects
i'll just share the code of my joker to make it easier
But that's a diff problem
what key name has gros michel
iirc how i coded it then it works like that
i mean the nicer way would be {blue1, blue2} but it takes any number of arrays
j_gros_michel
key = "dprinter",
loc_txt= {
name = 'Dream Printer',
text = { "Copy the abbilities of the joker on the {C:attention}right",
"{C:green}#1# in 3 Chances{} to trigger it 2 more times",
"{C:inactive} (How can this exist ?)"
},},
atlas = 'dprinter',
pos = { x = 0, y = 0 },
rarity = 3,
cost = 15,
pools = {["pseudoregamod"] = true},
unlocked = true,
discovered = false,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
config = { extra = { odds = 1}},
--return { vars = { center.ability.extra.mainodds, center.ability.extra.totalodds} }
--create the 'other_joker' vallue as well of adding the 1/3 chance, normally
loc_vars = function(self, info_queue, card)
if card.area and card.area == G.jokers then
local other_joker
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card and G.jokers.cards[i + 1] then
other_joker = G.jokers.cards[i + 1]
end
end
end
return { vars = { (G.GAME and G.GAME.probabilities.normal or 1), card.ability.extra.odds } }
end,
--gotta re-add the function of before
calculate = function(self, card, context)
local other_joker
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card and G.jokers.cards[i + 1] then
other_joker = G.jokers.cards[i + 1]
end
end
if other_joker then
local defaultblue = SMODS.blueprint_effect(card, other_joker, context)
local stupidblue_effect = stupidblue(card, other_joker, context)
return SMODS.merge_effects({defaultblue}, {stupidblue_effect})
end
end
}```
the code on itself work as it does a unique blueprint effect and then does the extra
ones i set but, it seems to do it no matter what
oh
i was thinking it was this variable you had to set
since 'oops all 6's' will change the value of the 1 in X chances i was thinking i had to set the odds for that one
i guess this make sense now, feel kinda dumb
But thanks a lot
you do change the X in there
G.GAME.probabilities.normal is the 1 in X
odds is the X in 1
or backwards
depending on how you interpret my stupid message
Oh i see, wait so how i then set up the the text to dynamically change if the odds are increased with oops all 6s ?
Bumperoony
G.GAME.probabilities.normal in loc_vars would handle that
so no need to change my code outside of the odd then right ?
yeah it should work fine
Idk why you have the other joker stuff in loc vars
Alright, i'm not use still with everything but now it should make the work easier (hopefully), also the SMods.merge_effect is very useful
i would recommend keeping an eye out for when the function is merged so you dont override it lol
or change the name
could you create a button with a sprite node
or maybe just copy how an UIBox_button is defined
I think as long i use smods merge with different names for my locals i should be alright but i'll keep that in mind
how can i know if a gros michel (or a cavendish) got destroyed?
do SMODS.merge_effects = SMODS.merge_effects or function blah blah end where you define it instead
So if it's already defined it won't override
directly defining the smods effects in my code instead ? i mean i guess it's safer, but if i keep different dynamic names it shouldn't break right ?
whats the best way to set the enhancement of a card? for context, im making a joker that has a 1 in 5 chance when a card is scored to change the enhancement to a new enhancement i made
well I'm making an assumption on how you defined it
idk what you have done tbh
card:set_ability("m_key")
oh for Smods.merge i just definied it outside of the joker, like a separate function, N' did told me to copy paste the code of the function
why are enhancements m
is that a cryptid reference
yeah if there's something that changes in the SMODS one and someone downloads your mod you will override it
so you can do what srockw said or make it a local
it's not really a good idea to add things to the SMODS namespace
That reminds me of another idea
is there a reason it stops jiggling when I play a hand?
set_ability is funny
m for mnhancement
so should i set the function itself as a local ?
like for exemple local mergeeffect = function SMODS.merge_effects(...) and use it as
return mergeeffect({defaultblue}, {stupidblue_effect})
yeah
Without the SMODS.merge_effects part
but like this local mergeeffect = function(...)
i think i got it, i'll try to do right away, i'm already thankfully my code works as it is
thanks again
I figured out how to merge playing cards, now I just need to figure this out.
I am cheering for you
how would i get this to trigger on the played card instead of the joker itself?
instead of card use the variable where the playing card is stored
like context.other_card but it depends on where youre using it
(sorry for my terrible ineptitude at programming, but)
what would be the variable where the playing card is stored for this situation? (ignore how there's nothing before set_ability i just emptied it out for the sake of the screenshot)
context.other_card
this code is on the higher end of quality in this channel
its because im heavily referencing the code from VanillaRemade ackackack
:3
most people have their hands on VanillaRemade too and fail to comprehend anything in there
so yeah, id say you are smart too :3
well thank you :3
me spending 12+ hours nonstop adding random bullsh*t to Balatro
i do feel a little dumb right now though because context.other_card:set_ability("m_votd_celestial") just causes a game crash so im clearly misunderstanding something or doing something wrong
is votd your mod prefix
yes
oh yeah you don't want to use context in an event, you want to save the card locally first
<@&1133519078540185692>
ty mods
thank you moderators of this community
i was talking about balatro mods btw to not cause a misundertanding
I have no clue how I would do this lol
gotta say it was really funny the first time i messed up the application of the enahncement and i just watched my joker turn into a celestial card lmao
for some reason using local would crash saying merge_effect is a nil value, yet without the 'local' and just using function merge_effect(...), it does work, the function is also set at the bottom of my code, and i know that when i set stupidblue as a local, putting it before my joker code did made it work, is it just fine to keepfunction merge_effect(...), or local is must need ?
if you have it as a global it might also cause conflicts with another mod, the name is too generic
i would just put it at the top
so just local function merge_effect and then put at top ?
yeah
Sure thing then 👍 (could have come up with an originaly long name but yeah taking le easier path)
most of the time you can just use modprefix_name for most stuff
or make your own global table
I’m not seeing anything like this on the wiki after a quick skim thru the UI page 
I should probably think of that, the use of my mod prefix could prevent conflicts for global effect sets (if the prefix is long enough and original or anything else)
Oh nvm it’s G.UIT.O
Still doesn’t change the fact idk how to make it do what I want it to do 
Alongside G.UIT.O
is what I was thinking of
yall please help me...(sry if this is unrelated)
Maybe you didn't install lovely properly
I'm not sure tho
What can be reason of this error?
-# Oops! The game crashed: functions/misc_functions.lua:1695: bad argument #1 to 'ipairs' (table expected, got string)
When I remove consumable code it doesn't appear (atlas and set are defined)
-# SMODS.Consumable{
-# key = 'c_gamba',
-# set = 'FunCards',
-# atlas = 'c_gamba',
-# pos = {x = 0, y = 0},
-# loc_txt = {
-# name = 'Gamba',
-# text = '{C:green}#1# in 2{}
-# chance to gain {C:money}#2#${}'},
-# config = {extra = {money = 10}},
-# unlocked = true,
-# discovered = true,
-# cost = 4,
-# loc_vars == function(self, -# info_queue, center)
-# return {vars = {G.GAME.probabilities.normal, center.ability.extra.money}}
-# end,
-# can_use = function(self, card)
-# return true
-# end,
-# use = function(self, card, area, copier)
-# if pseudorandom('c_gamba') < G.GAME.probabilities.normal/2 then
-# ease_dollars(10, true)
-# end
-# end
-# }
(Tabulation got removed by discord I don't know how to keep it sorry)
loc_txt.text needs to be a table of strings
is there a way to modify the values given from editions? (foil, holo, poly)
Yes, but those are editions.
yeah my bad
is it possible to have the return "message" appear before the method finishes?
does anyone know how to help me with modding balatro in here having some trouble currently
cause right now I have a message that appears 8 seconds after it was supposed to appear
Thanks!!!
it depends on the event timings, you might want to change your effect into an event instead
sad
i fixed it if anyone cares
what was the issue
would make things a bit easier tho
the problem is that messages are always events
so they always get queued until animation timing
but i would need to see the code to tell you if thats the problem exactly
Honestly anything UI is pretty much gibberish to me lmao
It's spaghetti lmao
Ui in balatro is just tables in tables in tables
eh ive seen really bad code here
calculate = function(self, card, context)
local food_card = nil
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
food_card = G.jokers.cards[i + 1]
break
end
end
if food_card then
local eval = function()
return G.GAME.current_round.discards_used == 0 and not G.RESET_JIGGLES
end
juice_card_until(food_card, eval, true)
end
if context.setting_blind and (#G.jokers.cards + G.GAME.joker_buffer) < G.jokers.config.card_limit then
card.ability.extra.food = card.ability.extra.food - 1
play_sound('mvan_hunger', 1, 0.55)
return {
message = "Starving!",
colour = G.C.RED,
}
end
if context.after and food_card then
play_sound('mvan_chomp', 1, 0.55)
food_card:start_dissolve({ G.C.RED }, nil, 1.6)
card.ability.extra.food = card.ability.extra.food + 1
if card.ability.extra.food > 3 then
G.STATE = G.STATES.GAME_OVER
G.STATE_COMPLETE = false
return {
message = "Overfed!",
colour = G.C.RED,
}
end
return {
message = "Devoured!",
}
end
if card.ability.extra.food < 1 then
local eval = function()
return G.GAME.current_round.discards_used == 0 and not G.RESET_JIGGLES
end
juice_card_until(card, eval, true)
if card.ability.extra.food < 0 then
play_sound('mvan_ah', 1, 0.55)
G.STATE = G.STATES.GAME_OVER
G.STATE_COMPLETE = false
return {
message = "Starved!",
colour = G.C.RED,
}
end
end
end
I'd love to help you but I'm not at my pc right now
I’m aware of that at least. I just can never piece together how it all is supposed to make sense
which message do you want to happen at the same time
return {
message = "Devoured!",
}
That makes two of us
I think to add an UI element to the screen you just call
local element = UIBox {
definition = { ui stuff here }
}
try
if context.after and food_card then
G.E_MANAGER:add_event(Event({
func = (function()
play_sound('mvan_chomp', 1, 0.55)
food_card:start_dissolve({ G.C.RED }, nil, 1.6)
card.ability.extra.food = card.ability.extra.food + 1
return true
end)
}))
if card.ability.extra.food > 3 then
G.STATE = G.STATES.GAME_OVER
G.STATE_COMPLETE = false
return {
message = "Overfed!",
colour = G.C.RED,
}
end
return {
message = "Devoured!",
}
end
ok!
And then element:remove() at some point
Unless it's meant to be there forever
It worked!
Thanks a bunch <3
❤️
now me and the creature can live out our days of devouring random jokers
I should make it blueprint compatible

what is too much?
You'll find out
no i won't
its 3!!!
wanna bet?
It's over 3 yea
🤯
wanted to make it random but that seems cruel
too cruel
3!!! = 6!! = 2 * 4 * 6 = 48
I'll make a pure RNG one later
sorry for spoiling it
it was me actually
i don't think that's correct
6! is 720
So 720! would be a very big number
Really quick lemme try to lay out what I’m trying to do with my inquiry:
Basically I’m rendering a new Love2D Sprite object on the Main Menu in basically the exact same way as the Balatro logo (as seen in this video). I want it to open my mod’s config menu when clicked. I found the function that does that, I just need to make it clickable
this guy doesn't know about double factorials
if this is a card then you can hook to Card:click
btw i forgot to ask but
- what does return ret do here
- where would i put the math/message to upgrade my joker in here
what if you do
local controller_queue_L_cursor_press_ref = Controller.queue_L_cursor_press
function Controller:queue_L_cursor_press(x, y)
controller_queue_L_cursor_press_ref(self, x, y)
local press_node = self.hovering.target or self.focused.target
if press_node and press_node == [your sprite] then
[your sprite].states.visible = false
end
end
okay so, asking a question that i know is probably complex, but how would i go about adding a new tab to the collections menu for a new consumable group?
also, expect to see me around here more often as i delve into trying to make my own complex consumable type lol
they're in brackets so i know i can replace them
also this doesnt answer my questions
SMODS.ConsumableType?
SMODS.ConsumableType should do that automatically
,, im realizing now that i completely forgot to load the new lua file lmao
good that i discovered that now instead of later
I’ll give that a go once I get the chance. Unfortunately gonna take some time tho
Looks very promising tho
ret is basically running the function again, and contains everything the function should return, so you want to return ret again in cases when other pieces of code needs whatever is in ret, like:
function somethingHere()
return "idk"
end
print(somethingHere())
local smtRef = somethingHere
function somethingHere()
local ret = smtRef()
print("wawa")
--you didnt return ret here, so "idk" is completely gone now
end
local smtRef = somethingHere
function somethingHere()
local ret = smtRef()
print("wawa")
return ret --"idk" is still properly returned, which is the correct hook
end
if you were to hook to somethingHere() without returning, then print(somethingHere()) wont have anything to print
as for your second question, in the if statement
ah, ok
I think I've mostly done this.
I’m wanting to try and run cryptid but I keep getting this
True statement
I didn't know about it until now
But for some reason if I split it debug plus can't copy it anymore?
show me your mods folder pls
also, #⚙・modding-general
ive put into the chat
wait did you want me to post it in here or modding chat
i did
What happens if you print card.area on one of those split cards
It seems to print G.hand
Damn, no idea then
"Would you rather have-"
if you choose unlimited bacon but no more games it crashes
IT STARTS GIVING YOU INFINITE BACON JOKER CARDS AND CRASHES 💀
crash card:
I was thinking about like the minecraft error texture being an error joker
but it seems someone beat me to the punch
would it be possible to get the amount of seconds since you played your hand?
Probably.
you could have a var that goes up every tick
yea
and set it to zero when the hand is played
on that note
how do i get when you play the hand
just in general? You can hook into calculate_context and listen for the usual contexts or maybe when the button is pressed
if context.press_play?
do i context.main_eval that?
speaking of press_play, i need to do blinds for vanillaremade
I don't think so.
how often do update functions run?
every frame
is dt the time since the last frame?
yes
so would doing card.ability.extra.seconds = card.ability.extra.seconds + dt in an update function make seconds be going up like actual time?
probably
i think its affected by gamespeed
there's also G.TIMERS
if it is then you can hook to love.update instead
im fine with that tho
iirc G.REAL_DT exists
id suggest trying Game.update first though
or G.real_dt
its G.real_dt yeah
and thats the dt unaffected by gamespeed
i think so
is there a way to have a custom crash screen?
How custom?
so it would say goofy text instead of "something something nil value something something"
error("goofy text",0)
wait actually
wait really
for it to be fair across gamespeeds
shouldnt it be affected by gamespeed?
4x does the actual scoring 4x faster, so the seconds should be 4x as much (to make it fair)
if its connected to a negative effect and you want your players to absolutely suffer, why not
its a good effect
i see
its a joker that gains more XMult the longer it takes before it gets triggered
whipping out nopeus then
is there a way to stop XMult from being calculated until right before it actually adds it
currently its just giving XMult equal to the frame after you click play hand
No.
Hello active mod developers (looking at N, something and bepis mainly here), do you think if I do some smods merges tonight we can get them tested before Friday/Saturday for a new release? I’d like to get rid of that deck view crash but feel a new release for just that is a bit of a waste of time
its not a ❓ just because its not possible
its a reasonable thing to ask given its what my joker needs in order to work
i mean most of the PRs are mine so yeah lol
you mean you want to count the frames it takes until the joker's effects are actually displayed?
it works in that sense
but it acts as if its the frame after you click play hand
because joker_main calculates the effects values right then but doesnt display them until later
but i want it to use the time as if it was just then
That’s not possible
damn
oh oof, i have school tomorrow so i cant be on pc for too long, doubling and giving it to N' and something :p
I double it and also give it to N’
do u like my blind names
1/6 to give player lupus
why can't we send gifs?
stricter moderation
thunk doesnt like em
1984
because they personally hate all of us :(
is it the long house gif where they parody an episode
whats the context for after all cards fully score
and after the animations play too
something
i want to make it so the joker i am making
doesnt do something until after the hand visually ends
hand_drawn apparently happens whenever you discard and draw new cards too
makes sense
amazing
small blind
how do non-boss blinds work with smods? do they just not show up?
no clue, only example I can think of is ortalab’s small blinds, that may help
yeah I will check if that does anything custom
i just don't want to implement small/big blind in vanilla remade if it's going to confuse people
ok yeah
SMODS.add_card{key = "c_modprefix_key"}
oh
jeez
thanks
ok now it doesn't randomly spawn 60 planet cards lol
(I say randomly even though I know why it happened)
great work
okay, so probably complex question: how would i go about making the name and description of a card (in this case, specifically a consumable) change? my new consumable type is supposed to have the name and description effectively hidden until you beat a round with it in your posession
Does this actually work for cards that have differing values?
i did try reverse engineering the functionality from the lobotomy corporation mod but uh, failed
Not yet.
Makes sense
guys how would i make a function that sets the mouse position to 0,0
return a key to the new description in loc_vars
:3
is it necessary to set blind.triggered
i assume its for matador
cz for some some reason love.mouse.setPosition(0,0) isnt working nor any variations i have tried
oh i will change the dollars to a return too
or not, that doesnt let you pass instant
clean
okay im going to sound very silly for this potentially, but i cannot find an example of someone using it so:
how do you localize the name and description for a card (specifically in this case a consumable)
i have my localization file with the name and description in it but uh for everything else ive been using loc_text so far which i know probably isnt best practice and i should probably learn how to do it properly now
alright it finally clicked for me how localization actually works, but im still struggling to understand this part
im sorry to ask for this, but could someone write up a very quick and plain example as to what changing the localization like this would be like? i work best with examples
if not, you can just try to explain it to me more thoroughly and that'll probably work as well
hey n is there any plans to add blinds and tags to vanillaremade? not pinging you so if you don't see this whatever but it would be helpful
blinds: #💻・modding-dev message
tags no unless someone else like Astra wants to add them
Only slightly related, I wonder if it'd be worthwhile to port tags to the same general calc pipeline, or if that'd be wasted effort 🤔
wow oops! can't believe i missed that
greetings, tis i, i want to know if i can drop my code here to know if i messed somehing up
yes you can
Easier if you post the crash log or the error
(ripping another mod as always)
It's quite hard to run code mentally
yeah ur computer likely won't explode if you just try it out, no matter how broken your code is
its to know if im doing stuff right to make it malverk compatible
you just need to add the key to the correct table
so for example if you have a Tarot with key new_tarot you would have
return {
descriptions = {
Tarot = {
c_modprefix_new_tarot = {
name = "Name",
text = { "desc" }
}
}
}
}
probably i think, it would at least be cool for tags to get the same contexts
your mod likely won't get recognized since your metadata is misformatted
take a look at https://github.com/Steamodded/smods/wiki/Mod-Metadata, and please scrap the file header and use a separate json file
any fix?
okye
i understand how the localization works now, i just dont understand how im meant to change the localization on the fly like i want to
make a loc var containing text
for example [Steamodded>=1.0.0~ALPHA-0812d], [malverk] wouldn't work i think, just not the right format
I guess that's something I could try and adding. I know that when Confections worked as tag spawners, they were very awkward to make work. I'll add it to the my list
You are trying to add a joker that has the key of a table also you can't store cards in other cards.
oh i forgot that was the issue lol
return {
descriptions = {
Tarot = {
c_modprefix_new_tarot = {
name = "Name",
text = { "desc" }
},
c_modprefix_new_tarot2 = {
name = "Name2",
text = { "desc2" }
},
}
}
}
and in loc_vars
return { key = condition and "c_modprefix_new_tarot2" or nil } -- nil keeps default key
wdym i cant store cards in other cards? i thought i could use a var for that
If you just want a Malverk mod to change the images of, just use the hd one and change the sprite sheets to start with
do i discard the idea
thats what im doing, but i want to do more
eg, my own mod
Then just copy the Malverk part into your own mod
i remove the smods [] thing ?
You can’t store a card object in another card object.
yeah i think i do, hd wasnt using it
thank you, that worked! if i were to want to do multiple different keys would i just add another or and a new condition and "c_modprefix_new_tarot3"
condition and "c_modprefix_new_tarot2" or condition2 and "c_modprefix_new_tarot3" or nil would be the logic
im pretty sure
got it
does any1 have an example for a blind script?
i wanna see how it should look
apart from docs
You can store a cards key though.
well that was smhow what i wanted to do
k ty
Set the variable to G.jokers.highlighted[1].config.center.key and dissolve the card directly not from the variable.
ok
ok so then how do i make it so it creates from that key? it wont work yet
also it simply wont spawn the joker, there are no crashes
is there a way to check if you're currently looking at a card from the collection? my consumable type hides what it is on the first round of having it, but i dont want them to not be able to see it in the collection
You need to use keep_on_use you're currently creating a new one without that variable being set.
like do i add it as a parameter on SMODS.addcard()?
No, remove the add_card in use.
oh
does anyone know how to ease love.mouse.setX so it doesnt just teleport ur mouse there?
ok
IT WORKS TYSM!
also how can i make so if on max jokers it wont let me sell the consumable?
Probably by hooking Card:can_sell_card
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
does smods:has_mod use mod id?
SMODS:has_mod doesn't exist.
find_mod*
Yes.
alr thx
how would i get the graphic on a card to change? not a different atlas, just a different position on the atlas
card.children.center:set_sprite_pos({x = number, y = number})
thank you, ill make sure to implement this
sorry for late reply got busy with something and then forgot i asked that question lmao
where do i put the mod prefix when playing a sound?
modprefix_soundkey
ah i see
How would I draw the buttons drawn on the bottom of the screen when using a controller?
I want to draw them on an arbitrary point
how would I load the files of my mod if they were split up from the main script?
Tysm
I think the challenge is that Tags don't use a CardArea
blinds dont use a cardarea
Hey! I am also interested in this and found a C++ rewrite branch of immolate on his github page. It looks like the DLL used in brainstorm is probably based on that branch though that branch is definitely missing some things. I would be down to look into this with others and try to figure it out
blind calculate runs even when disabled?? tragic
https://github.com/OceanRamen/Immolate check the branch for converting to c++ I believe this is the base for that DLL though it is clearly not fully up to date to the DLL that is used in the brainstorm mod
does anyone have a good example of what booster pack code should look like? like from a mod or something that i can reference
Isn't a booster pack just a card object with an open function
There is an SMODS.Booster wiki page
Kinda
I've always been a bit uncomfortable with that latest Brainstorm release including a non-open-source compiled library. I'm sure it's probably fine, but always felt a bit sketchy to me
I went down a similar rabbit hole when i wanted to recompile it as a dylib for Mac users, then gave up when i realised the source just wasn't available
added blinds :3 https://github.com/nh6574/VanillaRemade/blob/main/src/blinds.lua
what do all the arguments on create_card do?
the regular create_card
use this one
hi, I can't figure out how to set up lsp to recognizing smods stuff, I'm on vscode btw
are there any base game cards that do anything when you play a hand?
thanks
Fuegoooo
upon opening my new booster pack and it being about to spawn cards, this crash occurs, and i dont really know where to start with this exactly so i thought id ask for help
it means the key or set returned in create card is wrong
okay, fixed the set i think, but now im getting this crash
i wish i was better at this whole programming thing instead of mostly thriving off examples
can i see the code
key = 'signal_normal_1',
atlas = 'votdboosters',
pos = {x = 0, y = 4},
group_key = "k_votd_signal_pack",
cost = 4,
weight = 999,
kind = 'votd_Signal',
select_card = G.consumeables,
create_card = function(self, card, i)
return {
SMODS.create_card {
set = 'k_votd_Signal',
area = G.pack_cards,
no_edition = true
}
}
end
}```
apologies if it sucks
and dont mind the weight, thats just for testing
the key is probably votd_Signal
but id like to see the definition for the consumabletype/objecttype
it wasn't working before so i tried adding the k, which made the crash different
key = 'votd_Signal',
default = 'c_votd_rozital_wormhole',
primary_colour = HEX("74EDE7"),
secondary_colour = HEX("45EFEC"),
collection_rows = { 7, 7 }
}```
heres the consumable type
yeah try just 'votd_Signal'
you can also just return { set = 'votd_Signal', area = G.pack_cards, no_edition = true }
okay, didnt crash that time, but now i have some new problems:
- i thought the function of
select_card = G.consumeables,would make it so i could just take it into my consumeables slot, but it doesnt seem to be the case. these cards cant be used immediately, and need to be taken into the consumable slot somehow - there were strange green particles floating around the cards for some reason? i have no clue what thats about
- it created three cards and i want it to create one. how can i go about making it only create one card?
how do you get a joker to add mult when you press a certain key
this function can tell which key you press so i just need this function to somehow tell the joker to gain mult but idk how id do that
- I think it needs to be the string "consumeables"
- no idea, I see that a lot and idk the cause
- see image
SMODS.Keybind({
key_pressed = "e", -- or the key you want
action = function(self)
local selected = G.CONTROLLER and
(G.CONTROLLER.focused.target or G.CONTROLLER.hovering.target)
if not selected or not selected.config or not selected.config.center or selected.config.center.key ~= "j_modprefix_key" then
return
end
selected.ability.extra.mult = selected.ability.extra.mult + 1
end
})
use = function(self, card, area)
local jokersyuh = {}
for k, v in pairs(G.jokers.cards) do
if v.ability.eternal or v.ability.perishable or v.ability.rental then
table.insert(jokersyuh, v)
end
local randomjoker = pseudorandom_element(jokersyuh, pseudoseed('YUH'))
randomjoker.ability.eternal = nil
randomjoker.ability.perishable = nil
randomjoker.ability.rental = nil
G.GAME.dollars = 0
end
end,
can someone help me with this? its saying randomjoker is nil
hi chat, its better using smods or vanilla functions to code mods? I'm just starting out, so I want to know if it's a good idea to prioritize one over the other.
always smods over vanilla if possible
crashes or is it due to a deeper reason?
you have a joker with one of the stickers right?
yeah
they're usually designed to be simpler to use and fix common issues
oh makes sense
but its saying its nil for some odd reasoin
thx
your nesting is wrong
how would I have a joker sense if a certain enhancement has been played
yeah i just realized that
iterate through context.scoring_hand (or full_hand) and check if any has the enhancement?
depends, do you want to do something for each enhancement played or just if a certain enhanced card is in the played hand?
im working on my first mod and going through the example jokers given by smods. in the calculate function for the sock and buskin remake theres a comment saying youd have to iterate over the hand to see more than 1 card at a time. How would i do this? Where can i see the structure of the context object so i dont have to ask every time?
Example code:
if context.cardarea == G.play and context.repetition and not context.repetition_only then
-- context.other_card is something that's used when either context.individual or context.repetition is true
-- It is each card 1 by 1, but in other cases, you'd need to iterate over the scoring hand to check which cards are there.
if context.other_card:is_face() then
return {
message = 'Again!',
repetitions = card.ability.extra.repetitions,
-- The card the repetitions are applying to is context.other_card
card = context.other_card
}
end
end```
the structure is here https://github.com/Steamodded/smods/wiki/Calculate-Functions
to loop through a hand, you'd do a for index, playing_card in ipairs(context.scoring_hand) do, likely in context.before
you can also loop through context.full_hand or whatever other table you need, most of the contexts and their parameters are in here
thank you both this is very helpful
thank you, that all worked n helped n such, ill definitely need to find a way to get rid of those damn green particles though because theyre bothering me a ton
would this be the right line?
np, also vanillaremade is basically all i use for code referencing nowadays. if you know the basegame really well you can instantly track down any vanilla joker effect (or vanilla anything) with a simple ctrl+f
no, you need to check for a specific timing
always use one of the ones here that are in the if condition https://github.com/Steamodded/smods/wiki/Calculate-Functions
also, if you need to iterate over scoring_hand then you don't use other_card
and to check for gold you do SMODS.has_enhancement(playing_card, "m_gold")
how would i change the player's dollars without returning in a calculate
ok, so how do I disable the joker, and re-enable it after a boss blind
ease_dollars
just like ease_dollars(20)
yes
should i do the message before or after the ease_dollars
You could also do SMODS.calculate_effect({dollars = number, message = "message"})
ye i am
how would i get 3 random poker hands that arent the same as any other one of themselves
what if i made a joker that made you play congregation
Just gave this ago and it gave no results
nvm
For reference, G.SPLASH_MAXIMUS_LOGO is a pure Love2D Sprite object, just like the main Balatro SPLASH_LOGO
How could I make a challenge deck start off with a different random card each run?
does anyone know where the vanilla jokers' code is?
i want to make some jokers that interact with them so i figured i'd start there
most of them are in card.lua
but i recommend checking https://github.com/nh6574/VanillaRemade/ instead
ty!
not sure what's wrong, but the game crashed after a blind going into the shop
Hi there! I don't know very much about programming and even less about Lua, and my searching has not been successful, so I thought I would ask here:
Does anyone know of a way to change the name of the suits in text? I'm making an Inscryption deck theme and I think it would be fun if, for example, The Sun said "Blood" instead of "Hearts" for the suit. Thanks!
i think you could try making a language?
like make a new translation of english
thats just with that instead
i know the ref
Makes sense, I will see if I can get that to work, ty!
Why is there an empty table in banned_cards?
Yes, but there is an empty table in banned_cards?
yeah what about it
cryptid does that all the time in challenge.lua
am i not supposed to?
No it doesn't?
...
banned_cards = {
{ id = "c_cry_delete" },
},
banned_other = {},
},
is this not the same?
That is not an empty table.
I'm referring to this:
whats the context for getting into the shop
i don't really see how { {} } is different from just {}, they're both empty right??
i mean ok
good night :)
what's the opposite of the no_rank found in the stone card and can I have more than one at the same time?
No.
is it just rank?
context.starting_shop
yeah weird, removing the brackets fixed my issue
bumpp
n are there tags in vremade?
no
tags, boosters and planets are missing
how do i get the first card in shop and discount it
G.shop_jokers.cards[1]?
That's just the area were Jokers/Tarots/Planets spawn.
like making it free
card.ability.couponed = true?
so
if context.starting_shop then
G.shop_jokers.cards[1].ability.couponed = true
end
would make the first shop card free when you open the shop?
It might.
Does it crash?
What's the goal?
on what type of object is that code on?
Yes, is this for a joker?
yea
try doing :set_cost() after
how would i randomize key_pressed here
what i was planning to do was have the key you press determined by the joker and then you can just copy the value off of the joker
oh then you might need the other function
but idk
couponed to stop other coupon-ers from doubling up effects, set_cost to make it do something?
the other function messes with debugplus
i dont understand the first part
idk why youd keep the coupon-ing part if it doesnt work
because that's what tells set_cost to make it free
what
read the set_cost function
Welp, since N’s suggestion didn’t work, back to bumping 
G.shop_jokers.cards[1].ability.couponed = true
G.shop_jokers.cards[1]:set_cost(0)
am i doing this?
set_cost doesn't take an argument
well you should try reading the function definition before trying it
(sorry if this sounds rude)
its called :set_cost() so i assumed you use it to set the cost
it should be called :update_cost if thats what it does
idk complain to thunk not me
isn't setting the same as updating
in this context
i mean it does set the cost
It sets the cost to the updated cost right
is there somewhere i can see the structure of a playing card object?
i agree that it can be confusing tho but idk balatro wasn't designed to be an API
so update cost makes more sense then
I think set cost makes more sense
this function disables debugplus keybinds such as / for console and holding m for quick restart
how do i make it so it doesnt
i assume i have to add a blacklist or smth? idk
no other than looking at the code, you should try printing one
although this might not be strictly a setter method
if im doing set i expect to be able to choose what to set it to
You are overwriting the love.keypressed function.
and if set is a normal thing, you shouldnt use it unless it does the normal thing
what normal thing
setting a value based on an arg
i installed debugplus to print it and its a mess
how do i not do this
do i have to do the same thing as i would do with a hook or smth?
edit: ok it is
yeah
dont call it a normalized naming convention if its not apart of that convention that youre naming
i am going to PR smods for set_cost to take a value
then i guess ill just ask, how can i get the SMODS.Rank of a card object? or better yet where to look this up myself
id prefer the Rank object so i can access the next() method
SMODS.Ranks[card.base.value]? idk what you need it for
okokok im misunderstanding the smods modules. thank you
bump
the problem is probably something within this file
i have my jokers my blinds and my vouchers all in different files
how do i load them with the main.lua file
what's line 820 in UI_definitions?
You can assert them
Prob vanilla remade shows that I'd imagine
hi dilly
Hi N!
Hi dilly
I hope you fair well this day
Hi victin, I hope you are doing awesomely (or at least adequately)
where do i find vanilla remade
im sorry im still trying to learn lua

@granite nymph
tysm!
not something I wrote
No problem, thank N because he's a genius awesome goat
okay yeah this makes this like 1000x easier
What is in there is great to see how to do things in a proper way
I am doing ok. How about you
of course, i just wanted to see what it was in your dumps
that's weird tho
I could be doing better :<
Tired but I'm okay
My lady flew in today so ive been hanging with her
I didn't sleep well last night so I'm exhausted but can't fall asleep rn plus If I could I wouldn't want to cause it'd be too early
I hope you feel better soon and things work out :(
Sounds good for the two of you
Except for the sleep
Which reminds me I should go to sleep
My sleep is always wack, I wish I had a more consistent ability to sleep
Also yes get some rest
Also I assume I could probably check for Back but what would be an ideal way to check for specific decks being played for blinds? I have a blind that requires a specific suit for it to count but if you play checkered for example its a 50% chance to be unwinnable
But i haven't seen what the backs are called to check which one is played
you can iterate over every playing card and see what suit they are
Man, I can't do anything with challenges. This sucks.
Read that in Bill's voice
Well, its moreso making it so if the blind checks and sees its a checkered deck instead of randomized between 4 suits, its just the 2 the player has for checkered
Cause when blind is selected it picks 1 suit for the entire blind
So ideally just setting it to only pick between the 2 present would be ideal
But what if a player starts the run on Checkered then turns all their cards into Clubs
Hmm thats a fair point, I only noticed it when I didn't change anything card wise in the deck and came across the issue
Would I just tally all suits present in the back then and whatever is returned can be a valid choice?
bump
Yes
Much obliged
my mod isnt wshowing up in the mod menu :(
You could also do like Idol
Maybe yea, I figure if i can just launch through a tally in g.deck.cards should be good
what is priority in the json file?
Where is your not_jokers atlas, as defined in your SMODS.Joker object?
actually wait yeah i should get that in
it isnt related to the crash but i should
Mmh
Also, can't read the message.txt file on phone
Screenshot would be easier to read
0
Could you screenshot your error message please
ok thanks, but what is it for?
basically im trying to add a new rarity
and im wondering why it isnt Working.
oh
im trying to make my own and im wondering what it is lol
Uh, talking past each other here. Priority determines what order mods load in
Higher priority loads in first
oh ok thanks
anyone know a solve for this
when i go in game my mod doesnt pop up in the menu
Hm... Does it need a comma after Steamodded, in the dependencies list
Forgot the syntax for JSON files
maybe?
Give it a try
nope still no luck
Not sure if that needs to be an array either
Hey guys!
I tried to mod Balatro tonight, but it just doesn't want to work at all. Tried basically all troubleshooting advice available, even other people on the discord here couldn't help out.
Basically my issue is that no matter what I do, when I try to put the version.dll for lovely into my game directory, the game just refuses to launch. My Antivirus is off, its the correct size, I uninstalled the game and verified integrity 200 times, BMM is not installed etc etc.
Anyone willing to try to figure this out with me? I heard some other people had a similar issue already but also weren't able to fix it.
Hm... What's that 'Nothing' mod?
You'll probably want to wait for the person who was pinged earlier to get back to you. They're best equipped to help you with your problem, but they're offline atm.
okey dokey. Probably best for me to go to sleep anyways
Guessing it's your mod, but just double checking
Rest well!
Could you post your mod's JSON file, just for us to be sure that not is the correct prefix?
Mod dependencies should be in an array using square brackets
is there a function in smod that destroys a specific card?
card:start_dissolve(), or something else?
if you want to destroy a playing card during scoring use context.destroy_card
for anything else SMODS.destroy_cards(card)
ok thx
Ah right, new SMODS function
im actyually stupid i have the dependencies formatted wrong\
Did it work now or
yeah
are you sure its destroy_cards? It's returning an error for me
lemme get it
update
disable each mod to see which stops the crash
update your mods
or that, yeah
not is the prefix i have checked
since smods is truncating the exact file path, i have no idea where this crash occurred...anyone has an idea?
search for chekhov
Is there a good resource for the colors in balatro? I may be stupid but i can't find them in the smods api
By colors i mean C:MULT etc
look for the text styling guide on the wiki
Ah, where is your localization file located, in your mods folder?
thanks...turns out it is kino again with the new rarity system :/
yeah
hellow, i wanna create a mod that changes the image and text of an existing boss blind, can someone teach me on how to do it (i have 0 experience on modding)
its in the nothing (the mod that im using) file
actually i already deleted it anyway
Put it in a localization/default.lua file
Where localization is the folder path, relative to your mod
just make an altas with the same key as a base game resource and with raw_key on, check the atlas docs
i dont understand anything that you said
like i said, i dont know anything of modding balatro
Then read the wiki for making your first mod
For blind stuff, look at SMODS.Blind, but that's an eventual thing
Bump
how do i get the current blind's requirement
How would I make it hide the poker hand and name?
G.GAME.blind.chips
also is it possible to get the chips that a hand is going to score
and if not, how do i get the current blue chips value
hand_chips
is that chips before or after mult
hand_chips*mult
it's like the flipped card
How do i get the current jokers? G.Jokers isnt working
bump
Sounds like a hook of CardArea:parse_highlighted().
Thanks
that's correct as far as i know, what's the issue?
how do i check if youre in a game or not
i just wanted to make sure is all 
if G.GAME
im pretty sure G.GAME exists outside of a run
you need to check G.STAGE or something someone asked that yesterday
it does
Oh yeah, G.STAGE == G.STAGES.RUN...
I use it as G.STAGE == G.STAGES.RUN and not G.screenwipe to prevent add_to_deck & remove_from_deck from executing stuff when entering/exiting runs.
How do you detect when any card (consumables, jokers, or playing cards) are removed from the game? (whether that be by destroying, being sold, food joker running out,e tc)
hook into Card:remove
How exactly do you hook into that? I'm newish to lua
How would you hide a poker hand like the flipped cards do?
local remove_ref = Card.remove
function Card.remove(self)
-- your custom code here, for example, creating a new context:
SMODS.calculate_context { card_removed = true, card = self }
return remove_ref(self)
end
also when you open the collection and close it, remove will be called on each card for example
oh I didn't see that, thanks
you probably want a more specific set of conditions
Bump
would that affect things inside the game though?
I'm trying to make a joker that disappears when any card is removed
with the hook that i sent yes it would
also when exiting the shop or rerolling I bet remove is called too
and many many more scenarios i imagine
how do you have the description text update while youre hovering over it
because rn it only updates when you take your mouse off of it and put it back on it
you mean like misprint?
cus if not, the updating only when you hover over it again is normal
oh yeahhh misprint does do that i forgort
if the values are static then do it in a dynatext like misprint, if not then use a ref_table in a G.UIT.T node
(or a dynatext also)
would it be better to just manually code cases for selling, cards being removed from deck and jokers expiring?
what's the difference between name and display_name in the json file for a mod?
i think you can get away with a Card.remove hook if you only make it happen when the card is being removed from certain card areas
idk how you'd handle playing cards tho
isnt there a remove_from_deck thing?
or whateveri ts called
that happens when a card is removed from deck
that could work yeah, you'd have to test it out tho
the wiki says that display_name is for the mod badge only
and when not specified it is the same as your mod's name
how do i get a floating sprite to constantly juice like the soul does?
look in card.lua and search for "the soul" until you're in the card:draw function
seems to just apply some scale and rotation to it when drawing it
if that's what you were referring to
it is. i didn't think we didn't have an easier way of doing it, though
