#đ»ă»modding-dev
1 messages · Page 408 of 1
so I do SMODS.change_base(suit) right?
oh okay
i hate lua today
say if im making a card that adds/removes an eternal sticker, what do i refer to the sticker as in uhhh
the desc/the info queue
info_queue[#info_queue + 1] = G.P_CENTERS.m_lucky
as opposed to the lucky card center here ofc i copypasted it from another tarot card i made
basically im wondering the G.[etc] that defines Eternal Stickers
You would do info_queue[#info_queue + 1] = {key = "eternal", set = "Other"} I think.
That sounds right
yeah that was it, ty lol :3
afternoon guys 
trying to trigger the mult gain with bloodstone
it doesnt work, as in bloodstone will proc and chud won't gain the xmult
did i patch wrong
in the second patch youre patching after the return so it's not reaching the code
Your second patch wonât go off because the first one changes the pattern lol
oml
That too
im so dumb lmfao
also dont you need to call the context also?
<@&1133519078540185692> get âim
the everyone ping is foul you gotta burn
i just missed it damn
the best part is it doesnât even work
the code and the text dont say the same thing
you killed bro
Anyways
Honestly you could probably patch in a call to you own custom context instead. Something like SMODS.calculate_context({bloodstone_trigger = true})
wait are you serious
Yes
thats so much easier what
This is a thing you can do lmao
Actual game changer learning that function exists
look astra this is like my second ever context đ
if it's for the chud card i would just use the same context you were using before
ofc
just realized i read this wrong and this is literally what im doing already
Oh lmao
i might just be braindead
đ
(im sick)
Ah damn :/
it's fine though it's just why i HATE spring and why the world should SKIP it
the beauty is a LIE and a FALSEHOOD
RAAAH
~~I say as Iâm lounging on my deck in the sun rn
~~
Bit lost currently, any leads of where I should start?
did i fix it

Youâre still resetting the chudhit after the return
is it possible to change the font of the text for certin text?
but it needs to reset after the mult gain đ
so i can trigger it again later
Could you not just handle that in the chud joker code?
<-- the face of a gal who has no idea
oh my god i totally can cant i
lua does not exist outside your computer, it can't hurt you further
thats what the pollen and dust is for <3
I return after beating my head against this wall for a few hours. Can I use smods to draw new objects, particularly a new CardArea? If so, how? For example, there's a separate CardArea below the Consumables in the Balatro Multiplayer mod, but I can't seem to find where in their code they added it.
Also, sorry for interrupting current conversation.
You should probably do a lovely patch for that
you asked if you could after seeing that you can
/lh
Toma what does the chud do and is a +mult for every failed probability check or smthn
Okay. Time to do more due diligent research. Thanks for the redirect.
huge mult gain if you win a probability
here's where i define my cardareas, you need lovely patches for smods to acknowledge them tho. i can send you those if you want
https://github.com/nh6574/JoyousSpring/blob/ba699ffdde89a3bcd438e1111ecff78c1bdd2924/src/extra_deck.lua#L255
Yu-Gi-Oh! Mod for Balatro. Contribute to nh6574/JoyousSpring development by creating an account on GitHub.
i was typing
Ah ok
there is of course a catch
Cuz I have a card that does the inverse
the field spell area is under the consumables
Mult gain for failing a check
i have an unlock condition that does the inverse too
(this is how you get cain)
Part of me is like, "I asked if you can do it with smods, so that's different", but the other part of me is like "You're absolutely right, and that's hilarious." XD
wait is balatro multiplayer not smods am i stupid
balatro multiplayer is smods
wait im in the server i can just look
Good God, yes, that'd be very helpful. (I feel so badly asking for so much help.)
ohhhh ok
Gotta start somewhere man. No shame in it
or at least it has smods for stuff like the h. chad rework
the catch in question that i forgot to attach to the message oml

@sonic cedar Yeah, the ultimate point is that I f#cked up, and you caught me. XD /lh
So I take it G.GAME.probabilities.normal gets divided by 10?
If so thatâs funny asf
all good lmao i was just joking
Yep lol
also it was supposed to multiply by 10
and it does
but for some reason it
triggers twice
so 2->200
đ
How i can make my mod compatible with JokerDisplay?
What a wonderful question
Those lovely patches would be appreciated at your earliest convenience. (I learn better through examples.)
check the toml file
what's wrong with my tooltip?
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.tag_double
return { }
end,```
it's not showing the Double Tag tooltip ^^
Tags arenât in G.P_CENTERS
G.P_TAGS
I think I messed up doing such a large shift in my mod and start doing gamedev at the same time lmao
Perchance
it's this one https://github.com/nh6574/JoyousSpring/blob/ba699ffdde89a3bcd438e1111ecff78c1bdd2924/lovely/zones.toml#L104
you can't just say perchance
chanceper
You get a glimpse
sticker jumpscare
joyouschance
sticker appears for 1 millisecond before getting blasted into oblivion by thunk himself
Keep it up, baby!
i can confirm this i have met localthunk in real life
Biggest thanks to everybody.
(he is local thunk)
Looking cool, Joker!
harhar! beat you to it! :D
OBELISK 
Cool Looking Joker
:}
so if i asked how 
(without screwing everything up
)
with your context you could pass in a value along with the initial context key and use that
like calc_context({key = true, value = 1})
It'd be way easier than tracking it with a global variable
ok nvm im lost again
ok so
instead of the global varible
varaibl
variable
i just only have the calc context thing in there
BUT
i add a comma
and then the vale thinh
value
thing
WHY IS THIS IN MY CARD.LUAAAAA 
LMAOOOOO
im so cooked
wait what about this though
do i just say like
false, value = 0
You wouldn't have to reset it with this method I don't think
Cuz the context is always changing
yay
yay!
and then you can add context.value to Chud's mult within chud itself
same thing with wheel ofc
i was just about to ask let me do that
hooray or off the stage
gulp
you could actually do away with that value stuff entirely and just look for context.chudhit đ
at least,,, it's easy to undo,,,,,,,,,
Anyone know how to fix this?
wait for my smods playing card pr :3
win or lose
seriously, you're probably missing something the other cards that create do
why pregnant man
mine is this one đŽïž
mine is this one âïž
woah did somethingcom get a new account?
it is yeah
as joyous even
i wish i had as much as a spring in my step as them
joyousspring
i miss gifs
Win
are gifs disabled
will the message just get deleted if i try to send one
writing (dot)gif is also banned
stickers,,,, 
.âgif
myth debunked
I think he meant with a link but that was funny
send it yourself
Actual attachments are not
Iâve seen this before
ok so yeah then
The blacklist literally just looks for the (dot)gif link
modding related (rare event) but I had hit the .1 in 2 chance on the first bloodstone hand so I had to double check the probability đ
LMAO
you got fluffed
SOMETHING HAPPENED 
TRUE
the devious zero width non joiner:
â
myth dedebunked
my apologies
...
rebunked , it was right there
_ _
the devious zero width non-joiner:
â
just tested
astra it
it triggered after
8 *hands of
flush five heart kings
đ
LMFAO
oops
Don't look if you wanna do Maximus achievements blind (which you should) but I just made a new one lol
i still gotta do maximus đ
i got so many mods i wanna catch up on
vibes
No but like actually
oh i gotta update my day count
It's 4 card arts I'm waiting on lol
oops should stay as a saving grace actually
Oops should actually work fine out of the box since itâs multiplicative too
yeye
(You now need 5 copies of oops for a guaranteed 2 in 2)
funne
next is hallucination
luckily the orchard should be mad east
what am I SAYING
the PATCH should be mad EASY
LOL
if this is sickness hiding in allergies im gonna be so pissed
oh yeah I just looked this is easy itâs the same setup as wheel
(Naw really?)
oh my god I knew I wasnât crazy
the INTELLISENSE
is turning them into QUOTE MARKS
oh so then do i use SMODS.blueprint_effect and what do i add then?
(sry for late answer i was having dinner :p)
You would have to create a "fake" joker, you could say.
Also I don't think you would use SMODS.blueprint_effect because if it chooses a joker like Wee Joker it will do nothing.
You want a joker to have the ability of seven random jokers?
Definitely not.
doesnât RNJoker do something like this
i want a joker that each round it changes what joker it uses out of 7 different jokers that are in the game, but you dont have to have em in the joker slots
I meant you would just call its calculate instead.
oh
No, it just does a random effect out of set effects I think.
do i use like joker:calculate_joker(context)?
yeah I know but is this similar in execution i mean
No.
No.
You need to create the fake card first.
No.
smods.joker?
Yes.
was confused as to what happened to my game and i started panicking
(i opened the unmodded instance)
Is there a context for a Joker/Consumable being added to Joker/Consumable slots? (Specifically added, not just bought. I want to account for cases with Judgement, Vagabond, Seance, etc)
how do i add a tag to info queue
info_queue[#info_queue+1] = G.P_TAGS["tag_modprefix_key"]?
SMODS.Joker{
key = 'luckiestjoker',
atlas = 'luckiestjoker',
no_collection = true,
discovered = true,
in_pool = function (self, args)
return false
end,
loc_txt = {
name = 'Luckiest Joker',
text = { "Gains 10 {C:attention}Lucky Cards{} " ,
"at end of an ante",}
},
calculate = function (self, card, context)
if context.end_of_round and context.main_eval and G.GAME.blind.boss then
for i = 1, 10, 1 do
local _card = create_playing_card({front = pseudorandom_element(G.P_CARDS, pseudoseed('JNKR_luckiestjoker')), center = G.P_CENTERS.m_lucky}, G.deck, true, nil, { G.C.SECONDARY_SET.Enhanced }, true)
return {
func = function()
G.E_MANAGER:add_event(Event({
func = function()
_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, _card)
G.hand:emplace(_card)
_card:start_materialize()
G.GAME.blind:debuff_card(_card)
G.hand:sort()
return true
end
}))
SMODS.calculate_context({ playing_card_added = true, cards = { _card } })
end
}
end
end
end
}
heres the full code
Why are you adding it to the deck but emplacing it in hand?
I'd say just copy paste the code that certificate uses and modify only the relevant parts
you wouldnât happen to know how to spawn boosters would you
Ctrl c didnt work
thats what i did
cant you just go into collection
then into booster pacs
and then click 3
or someing
you modified so much more stuff tho
oh my god ctrl 3
i'm looking at cert's code and it's not the same at all
cause i added some stuff i was suggested to add
ok i got the function, now what parameters do i give on calculate? (i mean, in the create_fake_joker inside calculate)
i can try doing G.deck:emplace
does anyone know anything about a field index crash when you click on your deck??
i suggest you start from just the base certificate code then
create_fake_joker(card, key, "calculate")
oh ok
tysm
what variable tracks how many hands the player has at the start of a blind
alright
that worked but it doesnt give 10 of them
cus you're returning inside the for loop
once you return you exit the function
so i return it outside the for loop then?
No, you move whats in the return outside of it and also move it out of func
apparently it's the copy card function which i uhhhhhhhhh dont use anywhere? was it just a bug?
huh?
it's trying to render a card in deck and it cant
why đ
idk
i didnt put anything in the- is this because i tried to ctrl c the booster pack
did i yoshiskip (smw ver)
You also need this function: https://github.com/Somethingcom515/SealsOnJokers/blob/allinone/allinone.lua#L318
ill see if it happens again but i dont think it was me
this time
oh no itâs consistent
and where do i use it?
thank you it works now
how do i check if a given joker is in a certain pool?
You use it like get_joker_return(key, context, card, true)
iterate the center pool and find said joker
like, where
im sorry what
In calculate.
ok
G.P_CENTER_POOLS.<pool name> is a list of all the items in that pool
huh
for k, v in pairs(G.P_CENTER_POOLS[poolname]) do
- ...
end
hmm
alright
i have a joker that gains strength depending on how many jokers are in a certain pool
you can also just check for the center's pool value but that doesn't work if a center was injected into a pool somewhere else
hence this
gonna check if it's a mod ig
so k would an instance of a card in that pool
correct
and then V would be the contents of the card table
i have a joker that kinda works like anchient joker but when the card is scoring the mult isnt above the card is below the joker
how do i change this
Code?
@daring fern it aint working đ
can you fix it plz
Why is it called SMODS.get_joker_return?
i need to check for every joker in G.jokers.cards to see if it is matching up with any card in the pool
hmm how bad would it be to have a reference in every center to its objecttypes
could i do v.label?
Remove card = card
k would be a number here, v is the actual center object
k is the index of the center in that pool
v is the actual value
okay thank you
you would be very appreciated 
ty <3
i mean looking at the code it's really easy to do
idk if it has any side effects
assuming i is defined in an upper for loop
center.objecttype[center.key].objecttype[center.key]
True,,

i mean you can do this with card.area
no, cus centers are not cards
if i dont, it is considered as a global instead
G.jokers.cards[i].config.center.key == v.key
center - definition of an object
card - instance of an object as a card
Put local in front of it.
firm reminder
got it
every card has a center but not every center is a child of a card
right?
what is the hotkey to restart the game i forgot :<
i think thunk is really cool for naming them front center and back but that has caused modders a lot of confusion
ALT + F5
hold M or ALT-F5
Hold M or ALT F5
i dont think that's the problem
No, that also works.
centers just define the behavior of cards
yeah i know i i replied to the wrong message my bad
sry :<
Code?
god i sound so rude sorry
where
when you use SMODS.Joker you're making a center, that later on can be applied to a card
okay, this is very informative
genuinely
yeah still it gives an error
Log?
Syntax error
still not
Log?
same as the others before, savedvalues wont work
Remove the create_fake_joker call.
đ
Does anyone know how I would find the value of the current best hand played in a run?
Is 4.11 out of date is it my bad
You mean the most played hand?
is there a way to make a joker return a bunch of things in succession? i want it to be like this:
"-1" (chip; balatro code automatically doesn't specify if it is chips, only mult)
"-1 Mult"
"Ă·1" (ditto)
"Ă·1 Mult"
"quote"
the code that i tried to use is listed below, which just didn't work at all:
return {
{ chip_mod = lenient_bignum(card.ability.extra.chips) * -1, message = "-" .. lenient_bignum(card.ability.extra.chips) * -1, colour = G.C.CHIPS },
{ mult_mod = lenient_bignum(card.ability.extra.mult) * -1, message = "-" .. lenient_bignum(card.ability.extra.mult) * -1 .. " Mult", colour = G.C.MULT },
{ chip_mod = 1 / lenient_bignum(card.ability.extra.Xchips), message = "Ă·" .. lenient_bignum(card.ability.extra.Xchips), colour = G.C.CHIPS },
{ Xmult_mod = 1 / lenient_bignum(card.ability.extra.Xmult), message = "Ă·" .. lenient_bignum(card.ability.extra.Xmult) .. " Mult", colour = G.C.MULT },
{ message = quote, colour = G.C.RARITY["crp_self-insert"] }
}
quote is defined earlier in the joker's code fyi
how do i grab a jokerâs sell value
Yes, use extra
No like the highest chipcount hand
how so?
wait no
is there like an example joker or something that i could use?
You just act like extra is a second return.
return {extra = {extra = {extra = {extra = {}}}}}
return {
mult = 1,
extra = {
chips = 1,
extra = {
xmult = 1.1
}
}
}
etc
ooh ok
not doing it 
indentation is fine
I mean they want to send 5 messages in succession, that's gonna be hard to look at
lua also doesnât care abt indentation iirc
for my brain at least
there's a difference between unavoidable indentation and indentation that's the result of weird code
but yeah, indentation is pretty arbitrary in lua
anyone know?
you could definitely avoid this indentation by adding the ability to send a list of effects instead of extra! extra!
G.GAME.hands has all the hand information
their current level, chip and mult and how much they increae each level
This got buried under a chunk of code so I'll ask again
Is there a context for a Joker/Consumable being added to Joker/Consumable slots? (Specifically added, not just bought. I want to account for cases with Judgement, Vagabond, Seance, etc)
maybe you do something like save values from G.GAME.hanâyeah
No.
i think youre just a hater : (
There is context.card_added though.
it's not bad if you have 3 messages, but what if you wanted to send 10 messages
get ready to read all about it then
why would i want to send 10 messages
like this value?
What does it do?
I mean, yeah, in extreme cases you should probably just write a helper that builds the table for you
god designed extra tables for use in my transfer abilities feature only
oh, I misunderstood, idk how to get that
why limit yourself
It is called everytime card:add_to_deck is called.
that's true actually
Yeah i didnt know how to say it differently other then a screenshot đ
fair enough, i'd definitely do this
i cant find where that value is stored
this is true i was god
Oh, so like with Certificate or Stone Joker. Got it, thanks
you can probably just do SMODS.calculate_effect as well if you're not using repetitions exactly
i wonder if you can make an extra table lead back to itself
No, that is context.playing_card_added
I agree with you otherwise, huge indentation can get pretty awful
actually no thats a terrible idea
I've done my best to keep lovely from turning into indentation hell haha
are you trying to kill someone
you dont want to see my UI code
i will use this when someone attempts to use a joker that retriggers 1e300 times
i will forgive your ui code
not much you can do about it
crab
it fits on my screen, i approve
gulp
return {
chip_mod = -lenient_bignum(card.ability.extra.chips),
message = "-" .. lenient_bignum(card.ability.extra.chips),
colour = G.C.CHIPS,
extra = {
mult_mod = -lenient_bignum(card.ability.extra.mult),
message = "-" .. lenient_bignum(card.ability.extra.mult),
colour = G.C.MULT,
extra = {
Xchip_mod = 1 / lenient_bignum(card.ability.extra.Xchips),
message = "Ă·" .. lenient_bignum(card.ability.extra.Xchips),
colour = G.C.CHIPS,
extra = {
Xmult_mod = 1 / lenient_bignum(card.ability.extra.Xmult),
message = "Ă·" .. lenient_bignum(card.ability.extra.Xmult) .. " Mult",
colour = G.C.MULT,
extra = {
message = quote,
colour = G.C.RARITY["crp_self-insert"]
}
}
}
}
}
not on mine smh
Probably.
i'm just gonna test it
dang time to refactor things so each source file is only 100 lines long
and I need to make everything an interface
and test every line of code
it works
JXL????
looking at the vanilla remade glass enhancement but i do not understand how the probabilities thing works đ
đ€
the fuck is jxl đ
I donât know đ
ok i agree this is terrible
yeah this is just awful
no offense
I admire your tenacity
you can REALLY condense most of the extra tables
if it works it works
how so?
yeah I mean if it works don't change it
me with ownerships
ignore the $0 issue but how can i word this better?
a reminder that xchips_message and xmult_message exists to give xchips and xmult different messages
does simply not doing chips = -lenient_bignum(bla) not work?
or was it xchip_message
i have NEVER seen "xmult_message" before
it exists
i was about to mention undocumented features
this way you can combine these into one single return table
but i guess if it's in the docs then good
could i get an example
Eremel save us 
you could probably improve it with a lovely patch tbh
i've never lovely patched in modding and i don't plan to yet
that's what big lovely wants us to think
return {
chips = fuck,
chip_message = { message = localize('k_shit') },
mult = foo,
mult_message = { message = localize('k_bar') }
}
if anyone was curious it was G.GAME.round_scores.hand.amt finally found itđ
hey if your code works leave it
you WILL use a lovely patch one day
i might try this; if it doesn't work, i'm keeping my code
release your inhibitions, feel the rain on your skin
i will probably but not now
if it aint broke dont fix it
or whatever
hi again ^^
i'd like to make a menu for making things with my resource cards â where can i get started with learning how to make modded menus?
I lasted 3 days
okay but it's like half-broke
smods wiki ui guide
đ
cheers ^^
hey that's 3 days longer than me
then fix it
true!
i'm TRYING đ
fix it fix it fix it fix it or whatever
fix it with a lovely patch
No.
hit the big fix it button on the wall
dang
im proud that jokerdisplay doesn't use any
can confirm I have one of these
if only
dang really? that's sick
nice work
i press the button and my code instantly works
ty â€ïž
doesnt fix much else tho
impossible unless you're writing haskell
Embrace lovely patches, then after you've made a bunch, edit them out because they're unnecessary
how do i spawn tags
How do I set the (card.ability.extra.invis_rounds >= card.ability.extra.total_rounds) true?
nah you PR them to smods
add_tag(Tag('tag_modprefix_key'))
what's happening here
especially if they have a lot of "at" patches
I have been told that is always false and I have no idea to set it to true
would investment tag just be âtag_investmentâ
Bit of column a, bit of column b
was your code a hello world function
no comment
Yes.
it's always false because the values never change, aka it's always evaluating 0 >= 3 which is, not true, just update those values somewhere, depends on how you want your joker to work
i donât know how the comments on your code are relevant rn but alr
anyway I'm going to PR the objecttypes thing and let Eremel and ewju deal with the consequences
Objecttypes thing?
pretty sure they arent
also don't forget to run the lua formatter on your code
makes it easier to read for all of us trying to help you
ive seen multiple people want to either have a look up table for cards in an objecttype or that cards themselves have a reference to their objecttypes
how would i check if the blind defeated is a boss blind
Oh, as in, check on the card if they're a 'food' joker?
if context.end_of_round and not context.game_over and context.main_eval and G.GAME.blind.boss then
yea instead of looping through G.P_CENTER_POOLS
thanks
main issue with this is that it doesn't seem to have a sound; it just plays the normal click sound
-# reply ping intentional
did you make the pr thing already
i just got home from work đ
welcome home
Ah, cool, means I don't have to set that up, haha. It was next on my list of Cryptid compatibility fixes
say that again
welcome home
ok thanks
who was planning on working on 'rates' for individual jokers?
that again
H
I've got that code basically set up
I give blueprint 5 stars
can I see it?
What about stickers on booster packs?
rather than putting a reference to the pool why not just put the name of the objecttype
Just still testing some edge cases before I make it generic enough to PR it
i was gonna put a reference to the objecttype itself but maybe just the key yeah
I can send the git link in a sec, but it's in per_card_rarity in the Kino repo
i'm just gonna leave it for now; thanks chat i'll probably be back later for more ://SPAGHETTI code
you can keep it actually im full
So I have to put invis_rounds = 3, total_rounds = 0 or take some code from the invisible joker (vanillaremade)?
Invisible Joker (VanillaRemade) sounds like the wiki disambiguation
Also it seems that I can't write or erase a single line of code in a afternoon cuz something happens
presumably you want to increase card.ability.extra.invis_rounds by 1 each time it gives mult
@wintry solar https://github.com/icyethics/Kino/blob/main/src/per_card_rarity.lua that's the current set up. It's mostly adapted from N's approach in JoyousSpring, but set up to be work for all objects
Each time a round ends
right
if context.end_of_round and context.main_eval and not context.blueprint then
card.ability.extra.invis_rounds = card.ability.extra.invis_rounds + 1
end
something like that
If I PR'd it I'd wanna set it up with some clear patch targets as well, and ways to alter the weight logic through other objects, but because it's not a Kino feature, I hadn't really given it thought for my specific implementation
how many of you would use regex lookarounds? I've been throwing around the idea of adding support for them in a future release.
my guess is you put a string where a table was meant to go
thatd be my guess too but i have no clue what thatd be unless im blind
I'd use it if other people would convince me it's useful, and I figure out what it is after googling it, haha
Does that go here?
my mod uses a regex look up for hand_chips*mult lmao
it should be a separate if statement, like the two you have already
also don't forget to run the lua formatter
well the issue is that lookarounds can blow up and require an exponential time to compute
like, it's really easy to do so
When I have the time
hell yeah
I have to work, can't code without anything else happening
Why did I think on making the mod frfr
this is the code ive been editing, but whats weird is that deleting this whole mod doesnt do anything
removing my mod DOES let it run so its def an issue with my mod
so weird
maybe it's in the loc_txt
whats the context for when any card gets destroyed
playing cards: remove_playing_cards
anything else: none
can i just hook the dissolve function to calculate a new context
you can
k im doing that then
does it use rarity tags rather than weight tags?
it might be because this shares a name with wild cards?
ooooh lolol
what do you mean by tags?
like it just reads the rarity property of a card, right?
so how does it work to increase the rate of an individual rare joker spawning?
this will trigger when cards are sold i think
You can add a function onto a joker/card that checks for it, which is what I'm currently using it for to make Kino's new planets less common, and I've also got it set up to check if they meet a global spawn rate increase condition (in this case, movie genre, for the genre specific decks)
and it wont work on cards that shatter/are eaten
nom nom
then ill just check if not context.selling_card
basically get_current_pool returns both the keys and the weights now, using the rarity weights as the default if they're not defined
and then another poll function gets it based on the weights
both contexts will never happen at the same time, it's not how contexts work sadly
but the idea is fine, you just need to add some flag in one context
hmm okay
this context im making feels like it would have a good place in base SMODS
a context on dissolving cards is too generic to be useful
does it combine the pools then? Looking at jokers specifically (I'm sure the rarity thing applies on whatever object though), gcp only ever looks at one rarity anyway
in my implementation at least it does
havent read Ice's in detail
so if I call get_current_pool('Joker') I'd get back a table of all rarities of jokers with keys and weights?
yes
hmmm, that's an interesting choice
does that mean if I had a rare joker with an astronomically high weight, it would lower the chances of common/uncommon spawns?
i mean i think we both made a different function just to not mess up with get_current_pool haha
yeah
okay
but it would also lower other rares so i dont think it would break the basic rarity logic
wouldn't you want each joker to have its weight on its respective rarity only
no, i want a rare to be more common than a common sometimes
I don't think that's how a weighting system should function
is this how the kino one works @hushed field ?
why not
oh yeah, that makes sense
Is there a function that runs when a joker is removed? (ex. destroyed or sold)
it doesn't normalize on a per rarity basis, no, so making something more common will make everything else less common, regardless of rarity. But it's one of those things that's definitely possible to account for, due it using a separate function, so you could still just use the regular rarity generation chances before you enter the complex get pool function, just with a rarity key instead of a generic key
yeah if you want it to be relative to its rarity you would use the base rarity weight in your calculation
Because weighting and rarity are two different properties. Weights should only effect the chance of a card spawning once it's spawning criteria is in play. If I set a rare to have a weight of 1000000, that should only take effect when the game has already decided to spawn a rare joker.
I did consider trying to properly normalize it, generally, but to truly minimize the way odds influence each other is a maths challenge that my linguistics-brain isn't capabel of understanding, haha
Like this
For my own implementation it doesn't really matter because I don't want to introduce effects that would shift the odds in noticable ways, due to the size of the general joker pool. But I can definitely see why you'd wanna maintain the rarity selection first, as that's how vanilla does it. But that'd be very easy to set up
I don't understand why that matters other than when the game is forced to spawn something
It will only be messed up when a modder spcifically decides to mess it up, and that should be to modders discretion imo
hey, at least something worked! :D
I mean I can understand why you'd want it your way too, but I'm coming at it from a generic, smods pov
so that we can do this
and it's consistent in it's implementation across all objects
It seems it didn't work
oh right, you want
if context.end_of_round and context.main_eval and not context.blueprint then
-- the increase line
if card.ability.extra.invis_rounds >= card.ability.extra.total_rounds then
-- the destroying and spawning
end
end
What does it mean if the code is darkened?
calculate = function(self,card,context)
if context.individual and context.cardarea == G.play then
if SMODS.has_enhancement(context.other_card, "m_charcuterie_cursed") then
context.other_card:set_ability(nil)
return {
message = "Cleansed!"
}
end
end
I think it depends on what you think spawn chances should affect. I also think it's one of those things that are hard to judge once you've touched the code. The game never states that the rarities are set pools, rather than generic spawn chances, so I think how you visualize what 'this rare joker is twice as common' means is going to depend on what definition you've internalized. But setting it up as a pool shouldn't be hard, you'd just pre-generate the rarity before you call that function
why is this crashing?
cus you're setting the ability to nil
is that not what im supposed to do?
if you want to remove the enhancement you need to :set_ability(G.P_CENTERS.c_base) iirc
ah
out of the last 3 if statements you have keep the last one i sent (replacing the comments with the actual code)
How can I run something (ex; adding to multiplier of round) when a joker is removed? (sold, destroyed by other joker, etc.)
i mean i think both approaches are fine but restricting it to the rarity pool is immensely less useful to me at least
if context.end_of_round and context.main_eval and not context.blueprint then card.ability.extra.invis_rounds = card.ability.extra.invis_rounds + 1 end
This one?
i already implemented it tho so i dont care :3
no, that's not the last one i sent
this
don't worry N I will break your implementation đ
nevermind, found it
for anyone wondering, it's "remove_from_deck"
nuh uh it only does it with a specific set
also it does a bunch of other yugioh things
I need some help, my game won't boot
Oops! The game crashed:
Syntax error: blind.lua:579: unexpected symbol near '+'
Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-0509c-STEAMODDED
LĂVE Version: 11.5.0
Lovely Version: 0.7.1
Platform: Windows
Stack Traceback
(3) C function 'function: 0x1fe6ba90'
(4) global C function 'require'
(5) main chunk of file 'main.lua' at line 886
(6) global C function 'require'
(7) LĂVE function at file 'boot.lua:323' (best guess)
Local variables:
c = table: 0x1fe64798 {identity:false, version:11.5, accelerometerjoystick:true, modules:table: 0x1fe67728, gammacorrect:false, title:Balatro, externalstorage:false (more...)}
openedconsole = boolean: false
confok = boolean: true
conferr = nil
(8) global C function 'xpcall'
(9) LĂVE function at file 'boot.lua:362' (best guess)
Local variables:
result = boolean: true
(10) global C function 'xpcall'
(11) LĂVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '(LĂVE Function)' (defined at line 355 of chunk [love "boot.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"])
damn you got me
Yeah. I think while it makes sense from the code side to treat 'rare' as a pool, the notion of 'Baron is twice as common' feels like it should spawn twice as often as it does normally, not be twice as likely to show up in the rare slot
hi eremel smods
for future reference it's :set_ability("c_base")
There's a reason I didn't steal N's code entirely, but actually had to port it đ
I wouldn't be doing work if a better coder had already done all of it for me, haha
arent both the same?
im bad at math
okay can you copy the last 2 if statements and send them here as text, i'll just send what you have to put
Nvm fixed
-- the increase line
if card.ability.extra.invis_rounds >= card.ability.extra.total_rounds then
-- the destroying and spawning
end
end```
How can I tell when a UI node is hovered over, versus a card?
card.ability.extra.invis_rounds = card.ability.extra.invis_rounds + 1
end
if context.individual and context.cardarea == G.play and
(card.ability.extra.invis_rounds >= card.ability.extra.total_rounds) then
SMODS.destroy_cards(card)
SMODS.add_card { key = 'j_sab_spade_king' }
return { message = "Fusion Queen! Evolution King!" }
end
end,```
I think this were the ones
if context.end_of_round and context.main_eval and not context.blueprint then
card.ability.extra.invis_rounds = card.ability.extra.invis_rounds + 1
if card.ability.extra.invis_rounds >= card.ability.extra.total_rounds then
SMODS.destroy_cards(card)
SMODS.add_card { key = 'j_sab_spade_king' }
return { message = "Fusion Queen! Evolution King!" }
end
end
Maybe I'm getting confused by my own napkin math, but no, right? I think it's easier to grok if you forget about the fact that there are multiple rare cards. If there's a 90% chance of a common, and a 10% of a rare, and each has 2 jokers in there, it'd treat the spawn chances as such:
Common A - 45%
Common B - 45%
Rare A - 5%
Rare B - 5%
if you say 'Rare B is twice as common' and treat that as applying generally, it'd turn into:
Common A - 41%
Common B - 41%
Rare A - 4.5%
Rare B - 9%
while if it's only adjusting odds in pool, it'd turn into:
Common A - 45%
Common B - 45%
Rare A - 3.33%
Rare B - 6.66%
The actual math is fuzzier than that because it involves squashing the odds down, and you can't actually keep odds symmetrical when you change the size of the total pool, but I tried to read an article on it and decided it wasn't going to matter enough for me to truly understand, haha
Honestly the adjusting odds per rarity pool makes more sense to me
hmmmmmm, this is supposed to mark each card with a certain suit, then randomly reset that suit in context.before, then cards with that mark give 2x mult when scored, but it keeps crashing because context.other_card is a nil value
this is something to do with my dissolve hook but im not quite sure what
you're not making rare jokers more common, you're making a specific rare joker more common
function Card.start_dissolve(self,dissolve_colours,silent,dissolve_time_fac,no_juice)
SMODS.calculate_context({card_killed = true})
return sd_ref(self,dissolve_colours,silent,dissolve_time_fac,no_juice)
end
cards dissolve outside of a run
this is how I see it too, the rarity of the card is a different calculation entirely imo
the error here is you don't have a context.individual check in your 2nd if statement
so other card is not always defiend
oh yeah no makes sense
but still, the general implementation would allow you to adjust for both
I do think that's because you two know how rarity works behind the scenes, more so than it being the intuitive option out of those two, but I don't know how true that actually is
yeah specifically itâs crashing during the startup so i was guessing this
i seeeee
Thinking out loud here for a moment; feel free to ignore.
- Extra Deck is not visible unless called.
- Field Spell is where I want my object to be, so I have that reference.
- I only want the object to appear for a certain deck, so I put the calling event in the backs section for that specific deck, and I'll have to have something remove the object when that deck is not in use.
- Extra Deck and Field Spell have an independent Joker limit... how was that obtained?
so how would i check to see if im currently in a run before calculating the context
joyousspring mentioned
knowing how it internally works is important for building a smods feature though, whatever we build in has to match how vanilla spawns work
this specifically is why i didnt PR it myself tho haha
not just because im lazy (i am)
idk when but it's defined outside of a run too
It gives me syntax error
hmm
you forgot a comma right before loc_txt
how can you know it?
actually you're missing an end too
i could check for a variable like G.GAME.Risk that i KNOW FOR A FACT is defined at the start of a run because i defined it myself
experience
Alzheimer kicks in
or alternatively i could set up something in the start_run function so iâm not relying on a random variable i defined there
just like G.GAME.in_run = true or smtn
yeah that makes a lot of sense đ€Ł
yeah, no I do agree from the smods vanilla-esque pov, for sure. I think how a player might interpret 'twice as likely to show up' is also more out of my language interest, as the pools of jokers are large enough for the actual difference not to be noticable
add one more end between those two above loc_txt and just run the formatter, it'll make it look nice for you
and omg please learn lua next time
I think at the vanilla joker pool's size, it's only really going to matter if you make anything have a weight that's multiplied by a few tenfolds. At which point, I think you may have been better off just using the forced_key option đ
yeah i designed this system for my 300+ (soon 400+) jokers mod
I think I'm settling on letting any smods object able to have a weight = X property, where the default value is 5, that will effect it's chance to spawn within whatever pool it finds itself in
oh my god what the peak
If I just put it then it will mark a syntax error
but I guess, in the same way that reducing the pool to 4 jokers for an example, I do think making the phrasing example way extreme also illustrates why it can feel unintuitive. If you read "Baron is one million times as likely to spawn', and you have one reroll, I think most people would be surprised if it turns out baron doesn't show up when they click reroll
nevermind then, you just ignored the code i sent okay
Will do
the 2nd if is meant to be inside the first if
Is there a way to remotely trigger a game over when a function is run?
i think the problem is restricting it to one object, we should combine all pools into one
SMODS.poll_object gives you an edition? put it in the shop
just the edition
if G.STAGE == G.STAGES.RUN then G.STATE = G.STATES.GAME_OVER; G.STATE_COMPLETE = false end
"Baron is one million times more likely to spawn when a Rare Joker is created" vs "Baron is one million times more likely to spawn when a Joker of any rarity is created", in the first case you're increasing only Baron's weight, in the 2nd one you're increasing both the Rare rarity's weight and Baron's weight
that's kinda how I see it
you mean like this?
damn cant have new ideas anymore theyre all taken by ortalab
yeah, that's how I'd phrase it too, but I think people are definitely less likely to use 'Rare jokers are a million times more likely to be Baron' as phrasing, just because it feels a bit technical
{C:attention}baron{} is more {E:2,C:edition}more likely
Thank you so much, just tested it and it works
{C:attention}baron{} is more
add master duel craft points to joyousspring
honestly i might
maybe the phrase "Baron is more likely to spawn" is just ambiguous and shouldn't be used
it's better to be more specific than to save up on some screen space i guess
yeah I think that's the correct conclusion here
Would I be able to have a challenge start you off with just one random playing card?
i shouldve added the j it's over (copium i cant pull for my life)
while i have you here
do you think this is good
the center.object_types part
Would it be too complicated if there's just two weights that can be altered? So the modder can decide which effect they want?
what does it do?
adds a reference to the object types in the center
so you dont have to iterate G.P_CENTER_POOLS.key
(well it just sets the key to true)
I think I do basically that in Kino, for genres
oh this is in SMODS.ObjectType?
yes
srockw i appreciate you
used to check if the center is in a specific object type, right?
idk if that's sarcastic :(
yes
it's not
also would modifying the pools table that centers have cause issues
Nvm the struggles continue
instead of adding a new one
thats why i didnt do it
because i dont know :3
seems reasonably useful
Caught in 4k
could i substitute a blind object for card?
in a calculate function? because im trying to make something like the arm
yeah it's way better than having to loop through a possibly very very long list every time you want to check if a center is in a pool
update smods
pools added in pools only get added when the object is injected
aka once
I have to set the key for this?
oh weightings, I have not missed you
it wont work cuz its not the same type, just realized.
you have an old version of steamodded
you need to update to the latest release
Just realized
ok so the progress with my cursed alchemy - i've found a pretty clean way to remove the quit button from the main menu.
and i've worked out how to add it to options, but i need to... uh, make it not look like this. what do?
It's very helpful for allowing Crossmod pool compatibility to not be as invasive in your own code. You could set up a specific file for Cryptid compat, instead of having to adjust your code to account for it, for example
in that case maybe modifying it is not an issue at all
Every time I properly try to understand the math of how these weights are set up, I just die, honestly
same and I wrote the damn thing đ€Ł
weights,,,,,
...wait, this is just in a G.UIT.ROOT
oh god
Does anyone know how I could make it so this function is called after defeating the boss blind
You have no idea how massively helpful it's been. I appreciate you.
Thank yall... Man I feel demotivated
let me know if you have issues
im practically here all day
get motivated đ
did you look at how arm does it
where would i look
To learn lua
So I can either make better next time or fumble it up less times
How do I edit a card upon drawing it to hand?
return { level_up = -1 }
IT DOESN'T EVEN CLOSE THE GAME 
oh alr
oh itâs literally straight up nvm
unrelated but weâre so back
I wonder if I can change the total in the same way
Like 1 in 2 to 1 in 4
Probably possible
btw im really thankful to wilson for making it so you can move the cursor
oh my god
Itâs peak
no longer need to write evals in a text editor before pasting them ingame
TRUE
damn i need to update
wonât need this notepad anymore 
how would i make it so it does the blueprint effect 2 times?
nope, still weird. no clue what's going on
I assume it's cus your quit button doesn't have the function to call when it's pressed
no, i figured the quit function out the button closes the game if i hit it now
yes
it is
oh uhmm
not in that code it isnt
What are all the suit and rank keys I should be using for cards in a challenge deck?
whwre is it
i see
Small Question! how would i detect if a card is being retriggered or not for a joker?
Yo, sorry if I'm intruding in a conversation, but I'm trying to make a texturepack for my friend and me, and thought it would be nice to use Malverk to be able to turn it on and off. I've already gotten it to work without it, but wanna try to make it toggleable.
I'm using the Seal Seals mod (https://www.nexusmods.com/balatro/mods/438?tab=description) as a start point, but don't know exactly how to get the texture to replace the cards instead of the seals as the seal seal mod does.
Anyone got any quick solutions, or maybe just some better malverk documentation, cuz this line on the github doesnt tell me anything without finding an actual wiki? The wiki I've found is basically just "Malverk is a thing that exists. I'm not gonna tell you how to use it tho" (https://balatromods.miraheze.org/wiki/Malverk)
Malverk is a texture pack manager developed by Eremel_. It was first released on October 29, 2024.
Malverk adds a new UI in the menu that allows seamless management of installed Malverk-compatible texture packs. It also provides an API to add Malverk compatibility for custom textures.
See Category:Malverk-Compatible Texture Packs for supported t...
nvm they literally put col = true lol
i think all you have to do is remove that from the function
@rapid stag
ahhhh, i was wondering about that 
yeah that fixed it
I never made a wiki đ what cards are you trying to change?
is it not context.retrigger_joker
bump bc if i dont get this done ill DIE
Replace the deck cards, like ace, king, queen etc
that's not what malverk is for
ah okay, so im trying to use a hammer to turn a bolt, got it
pretty sure you can just use the suitâs actual name as a string
oooo thank you!!!
aureâs cat is so cute if weâre being fr
i never remove embeds from smods wiki
Why would you
i'd like to add a button between Run Info and Options â how would i go about doing that?
aureâs cat
people are more likely to look at them thanks to the cat
Is this a patch thing you think
That seems to just crash it.
proooobably? i'm unsure if there's a better method that i'm unaware of though
look at how Grim does it maybe? it adds a button there iirc
or at the top but the logic should be the same
the keys on the left


