#💻・modding-dev
1 messages · Page 620 of 1
card.ability.extra.Xmult = card.ability.extra.Xmult + 2 needs to be taken out of there
What is the goal?
How do I like, link a sound file to the "erupt" string?
how does the game make the legendary jokers unable to show in the shop? i cant find it anywhere
I want it to give x2 mult per each negative joker
What is the goal?
make a joker that is only spawned by another joker
so it wont show up in the shop
in_pool = function() return false end
in_pool needs to always return false then
Yeah I'm stumped on where/how I should set this up
SMODS.Sound({
key = 'key'
path = 'file.ogg'
})
By chance, are there any Modifier APIs that let me easily add modifier objects to the run with calculate functions and (possibly) other effects as well?
You mean like seals, editions, enhancements and stickers?
Not quite, I'm looking for something more akin to things like decks and G.GAME.modifiers
No, but you can use the mod calculate.
I think I'll need to set up a new object type
Effectively, I want to have a deck that randomly applies certain modifiers to your run from a selection
Is it possible to have a voucher appear in the shop again after redeeming it?
if #context.full_hand > 5 and context.after and not context.blueprint and context.joker_main then
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
return {
message = 'Upgraded!',
}
end
if context.joker_main then
return {
mult_mod = card.ability.extra.mult,
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
}
end
end```
im trying to make a joker wich benefits you for playing hands with more than 5 cards but i get an error because #context.full_hand = nil. I think i forgot a context in the if but i dont know wich one, can anyone help?
is it a single deck
if context.after and #context.full_hand > 5 and not context.blueprint
Yeah, I'm planning to make it a single deck (at least for now)
then why not do it in the decks calculate
No, that doesn't seem to work for vouchers.
The list of modifiers is quite long and I want it to be easily expandable, so I think introducing a modifier object type would be the most elegant solution
I did try that earlier, but no results
voucher spawn checks are wierd so that doesnt work
it has a check for G.GAME.used_vouchers instead which takes priority over everything else afaik
i love documentation
well
this isnt inaccurate
its just that vouchers are wierd
and have things that override normal spawn rules
it is incomplete then
fair
Have you tried G.GAME.used_vouchers[self.key] = nil in redeem?
Wouldn't this technically fall under "A card can spawn if in_pool returns true and all other checks are met."?
Best cause is to basically make the voucher "unredeem" itself after use?
I would document all functions with "does stuff" and it would always be technically correct then
I'll have to give that an attempt later, thanks
Fair point, perhaps it would be better to list the specific checks
i mean a PR to allow that and SMODS.Showman to work for vouchers would be cool
though it would require also changing showman to not affect vouchers
hmm good point i think it would be better for it to be a different value
SMODS.Voucherman
!!
is ts peak
How do you make a joker that disables the joker to the right?
why does it allow showman but then check the vouchers in the shop
why is the voucher logic in this condition at all
is it literally just for the unlock check
if context.debuff_card then
local my_pos = 0
for k, v in pairs(G.jokers.cards) do
if v == card then
my_pos = k
end
end
if G.jokers.cards[my_pos+1] and context.debuff_card == G.jokers.cards[my_pos+1] then
return {debuff = true}
end
end
Thank you! :)
Thx!
How do you detect when the joker tries to trigger when disabled?
Cos I wanna make it so the joker gains mult if the disabled joker tries to trigger
Is there any documentation on SMODS.GameObject?
no
because its just the very basic love2d game object that every SMODS object is an extension from
and theres no reason to use it over anything else
also there is just nothing to document because it has nothing
is there a way to get rid of the padding on the left and right of a cardarea?
not without patching CardArea:draw afaik
cardareas are not very customizable
wow i just found a typo
paddin
would it be the same thing for cards tilting or is that just not possible
So I created a custom object type by extending SMODS.GameObject, now how do I create an instance of it?
if not next(SMODS.find_mod("Talisman")) then function to_big(...) return ... end end
function get_inverse_blind_amount(score)
local score = to_big(score) / to_big(blind_amt(8))
if score < to_big(10) then -- Less than 10x ante 8's size
for i = 1, 12 do
if score < to_big(blind_amt(i)) then return i end
end
end
if score < to_big(50) then
return math.floor(1.728 * (math.log(score) ^ 0.458) - 0.595) + 8
elseif score < to_big(1e6) then
return math.floor(1.877 * (math.log(score) ^ 0.4235) - 0.701) + 8
elseif score < to_big(1e20) then
return math.floor(1.688 * (math.log(score) ^ 0.433) - 0.386) + 8
else
return math.floor(1.0205 * math.sqrt(10 * math.log(score) / math.log(math.log(score))) - 2.425) + 8
end
end
made an approximation for an inverse of balatro's scaling
Balt????
Didn't expect to see you here lol
is there a way to make probability stuff retrigger
No, it's to_big = to_big or function(x) return x end
what does the extension look like?
lol
did you not see my mods
eh, same thing
its safer
ig
and cdataman isnt talisman but it also adds to_big
I did, I just didn't expect to see you here in the dev chat
i'll just check if not to_big then
why wouldn't i be here
also if this is the modifiers thing you were mentioning earlier then youre likely better off just putting stuff in G.GAME.modifiers
hey guys is there a way to retrigger probability based cards
I have no idea what I'm doing, I just copied EventStep from HotPot and modified it a bit and hoped for the best
calculate = function (self, card, context)
if (context.repetition or context.retrigger_joker_check) and SMODS.post_prob and next(SMODS.post_prob) then
local passed = false
for k, v in pairs(SMODS.post_prob) do
if v.trigger_obj == context.other_card then
passed = true
end
end
if passed then
return {repetitions = 1}
end
end
end
yea i would really just
if youre creating something that has no visual sprite or anything like a calculate its probably not worth extending for
just use G.GAME.modifiers like normal you're overcomplicating things
It does have a calculate()
also if its tied to the deck
just save the enabled modifiers
and do everything in the deck calculate
Ok sure I'll do that I guess
you could also look at one of the a lot of other mods that extend tags to have an indicator for stuff on the top right that also has a calculate
it doesnt work
Are you testing with jokers?
yes
What is your SMODS version?
1.0.0-beta-1016c
Wdym?
like ortalab or entropy
Do you have joker retriggers enabled?
oh wait i was testin it on cards
also yes i do
Yes, it only works with jokers because SMODS.post_prob is cleared before playing cards retriggers are calculated.
Retriggering successful probabilities I intent to include jokers, consumables, card enhancements/editions, blinds, etc.
...
Basically if it's a probability and gets a hit it happens again
yeah
Or at least has the chance to happen again if that's easier
also feel like adding a silly little buff to it
this is why i needed the inverse
Like what
You would have to patch SMODS.score_card
1 in 10^n (n being the number of retriggers) chance to increase retriggers by 1
Or hook eval_card
....

wow it’s VallKarri!
i have never done that
i havent even "patched" anything yet
Also for consumables, editions and enhancements you would have to hook Card:use_consumeable and eval_card
Why isn't this printing anything? It doesn't work even if I call the function manually with DebugPlus. I have a feeling I'm doing something obviously wrong but idk what
You need to use pairs
Ok
okay so i released my mod and i have a joker that replaces the language to dutch, however he got this error
He got this error from buying it with a negative icrecream
idk how or why
ive been trying to replicate it
but i just cannot
does anyone have any ideas?
okay finally its something to do with pulling it from a pack\
game crashes at the end of each boss blind when trying to fetch a new voucher to add to the shop, restarting the game fixes it... why the fuck is there a boolean in the voucher pool
wait it says debugplus
what
oh thats just the error handler nvm
i know you told me to hook card eval
but like
how is that supposed to help with balatrue?
Because you can't retrigger enhancements or editions by themselves normally, and this: #💻・modding-dev message
okay so how do i delay add_to_deck to after the joker is obtained (or add a little delay or smth)
Put it in an event.
When im hooking something
And if its card_eval
Do i need to add any additional code or nah?
G.E_MANAGER:add_event(Event{
func = function()
return true
end
})
so like this?
Okay, I went to try this, but no luck. My guess is the voucher gets marked as redeemed after the redeem code goes off, so setting it as nil in the redeem itself does nothing.
Code?
source and my custom voucher
Try adding G.GAME.used_jokers[self.key] = nil
That seemed to have done something. The voucher is appearing over and over again, with the tier 2 voucher not appering (but I don't plan on making a voucher like this with a tier above, so that's no issue)
Is there a way to add/set specific cards to a new deck in the apply script?
SMODS.add_card({key = 'classprefix_modprefix_key'})
Can it do tables of cards?
hey guys so how would i make a 3d environment in balatro? /srs
No.
So I just realized that this won't work because I can't use the return values properly... is there a better way to do this or do I need to patch get_card_areas() to add my modifiers in there?
No, you can, SMODS.merge_effects
Is this how it works?
Yes, but remove the mod,
This was just a test, I'll be reworking this anyway and it'll make more sense
It's working now, thanks for your help!! :D
is there a better way to understand lovely patch stuff without just looking at code for balatro or other mods?
only thing i can find is https://github.com/ethangreen-dev/lovely-injector?tab=readme-ov-file#patches but theres only a few examples and idk where i would inject stuff if i wanted to add a variable or run a function when the round ends or smth
if you want to do something when the round ends, i'd reccomend using a mod calculate function
how to get the current voucher limit?
You mean the limit on how many vouchers can show up in the shop?
(G.GAME.modifiers.extra_vouchers or 0)+1
ok thx
does this help https://github.com/nh6574/VanillaRemade/wiki#whats-a-patch
but if you only want to do that it's better to do what digitaldetective said
ty both
I want to make something with a similar effect to observatory, which is phrased as "Planet cards in your consumable area", do you think if I had it phrased as "Held consumables" it would be fine?
sounds good to me
wow this wiki is awesome 🐐
local chips_scored = G.GAME.chips
if chips_scored > 100000 then
...
why is this crashing? it says its attempting to compare number with table but both of them seem like numbers to me
to_big(chips_scored) > to_big(1e5)
talisman makes numbers into tables to increase their capacity; as somethingcom said, if you want to compare the two, you are best to do to_big(x) to both numbers before comparing them
ok ty
note that if you do this, you should also include to_big = to_big or function(x) return x end in your main file, or you should make your mod require talisman
otherwise your mod will crash when you don't have talisman
what that line does is make sure to_big is always a function in case you don't have talisman
this tal guy is quite the man
tal is man, good for him 🏳️⚧️
meow
when i get home im making a debugplus command for tmj
not for any particular reason
sorry if im asking too many questions but is there any way to set the player back to the small blind (i swear this is less devious than it sounds)
Is there a way I can give consumables the spectral shader without adding them to the spectral set?
for 1 consumable or many
Either idm
well theyre slightly different solutions
im asking because if you only want one then you can just add it to the card itself, if you want multiple then you should use a drawstep which is barely different
SMODS.DrawStep
for individual card, add ```
draw = function(self, card, layer)
if (layer == 'card' or layer == 'both') and card.sprite_facing == 'front' then
card.children.center:draw_shader('booster', nil, card.ARGS.send_to_shader)
end
end
Tysm
for a whole set itd be something like this ```lua
SMODS.DrawStep {
key = "spectral_shader",
order = 11,
func = function(card, layer)
if (layer == 'card' or layer == 'both') and card.sprite_facing == 'front' then
if SHOULD_DRAW_SHADER then --replace with whats relevant to you
card.children.center:draw_shader('booster', nil, card.ARGS.send_to_shader)
end
end
end
}
Why does pseudorandom_element() sort its pool before choosing an entry?
for consistency of course
it adds the keys to another table with pairs so the order of that isnt guaranteed
why does opening this pack from the tag crash the game? the tag appears fine and i can open the pack by itself fine but if i open it from a tag it just crashes
-# yes i used jokerforge im not good at this
the booster key is wrong
what's the best way to debug achievements? like they dont reset on profile reset and stuff, just generally annoying to develop
how does get_straight work again? does it only give you the first straight it finds, or does it give you all possible straights within the hand? (with giving it a smaller value than 5)
not seeing any documentation on it on the wiki
got no clue what it returns
im pretty sure it returns all straights
is there a get_flush like get_straight? searching smods, i see one call to it, but i can't find the function anywhere in smods or vanillaremade
does it exist?
have you searched the balatro source
we really should have a tutorial on that in the pins
no i have not, is there a way to import that into my IDE
extract balatro.exe as a zip
The lovely dump.
huh?
%appdata%/Balatro/Mods/lovely/dump contains a dump of the source with any lovely patches made by mods applied
when you run any mods with SMODS, a lovely folder gets added to your mods folder. this contains a dump folder, which dumps the patched source code of all the vanilla files that are patched by any mods you ran (including SMODS). there's a good chance the code for get_flush is in there somewhere
(if mod files are patched, they appear here too)
fuck
ok get_flush is not modified by smods to have the same min_length parameter as get_straight
guess its time to reimplement it
smods hasnt been updated in 10 days…
hrrm…
remember that four fingers exists
check SMODS.four_fingers
can you tooltip stickers (not as in the sticker being actually applied more like something akin to a consumable referring to another consumable)
Im guessing you cant
oh thats a weird looking function
is it like that because its intended to be hooked into?
yes
stuff like that and SMODS.showman(?)
in the loc_vars function of the card you want to have the sticker tooltip, do this
info_queue[#info_queue + 1] = { set = "Other", key = "modprefix_stickerkey" }
(where modprefix is the sticker's mod's prefix, and stickerkey is the sticker's key)
its not a custom sticker though
in that case you can just do key = "eternal" (or rental or perishable) in the line i gave you
you mean the opposite?
okay i guess it was actually that simple
anyone know what function generates the blind description ui in the collection?
okay
is SMODS.Suits not a table with every suit?
if ur using ipairs on it that wont work
ipairs only traverses numeric keys of a table
SMODS.Suit's keys are the suit key
im doing a for loop based on #SMODS.Suits and it seems to be 0????
# implies numeric keys
yeah, # also only counts numeric keys
use pairs()
in fact i would get in the habit of just using pairs most of the time unless you have a reason not to
its worked out fine for me
so #pairs(SMODS.Suits)?
no
evil and fucked up
or do i skip the #
for key, value in pairs(SMODS.Suits)
how do i get a number out of it though
what do you want to do with the number
thats the neat part, you dont
run code that many times?
^
run for each suit
#SMODS.Suit.obj_buffer
if you do it the way N' said you dont have to do an numeric for loop since value will just be the suit object
you use ipairs to convey that the intention of the for-loop is to iterate through integer keys (readibility convention)
also order
yeah
i just feel like
90% of the time for balatro purposes its not integer keys
like p_centers and stuff like that
i almost never loop through something that isnt number indexed
i forgot, am i just able to do for _,suit if i dont care about the key
and save a table lookup
how do you scroll the debugplus log without the scroll wheel mine's broken and does not like to work
ah its in the lovely terminal
okay now im really confused
because i take a straight from that table
and i try to get the cards from it
but doing for i in pairs(straight) or any other way of getting things out of that table just gives a "bad argument table expected got number"????
but when i try and print straight it's. a table with a bunch of very long values inside of it (presumably the cards)?????
for k, v in pairs(straight) and use v
elseif link < 1 and #G.jokers.cards == G.jokers.config.card_limit then G.GAME.joker_buffer = G.GAME.joker_buffer G.E_MANAGER:add_event(Event({ func = function() SMODS.add_card { set = 'Joker', key = 'j_gros_michel', edition = "e_negative", eternal = true, rental = true, key_append = 'pnr_pplus_gross_michelle' } G.GAME.joker_buffer = 0 return true end })) return { message = localize('k_plus_joker'), colour = G.C.BLUE, } end
So I have this function to add a joker (Gros Michel) but I'm failing to have them be eternal and rental, is it possible to add those qualities from spawning them from a joker?
force_stickers = true
Also it's stickers = {'eternal', 'rental'}
Thank you tons!
Sorry one last thing, for some reason despite having an eternal sticker the spawned joker can be sold?
Yes, eternal jokers that shouldn't have eternal are not counted as eternal.
Ah. Is there a way around that or should I reimagine the idea?
if context.check_eternal and context.other_card.ability.eternal then return {no_destroy = {override_compat = true}} end
And then would I just put that within the function to spawn the joker?
No, you would put it in the calculate function.
Thank you a bunch for the assistance, it is now perfect... Until I come back because I find out that when I sneeze my computer explodes
1 clock cycle on a 1GHz cpu is 1e−9 seconds
https://discord.com/channels/1116389027176787968/1434311755928047749 playtest the mod 🤤🤤🤤
Why it doesnt increase the blind size
needs to be updated probably
like text and chip requirement
sure you add the mult, but the chips wont change since it was already calculated
also ur modifying the blind object table
so all future encounters will have that changed until the game is restarted
actually i made a mod that lets u dynamially alter blind sizes
#1338044836087070740 (https://github.com/DigitalDetective47/strange-library/wiki/dynablind)
i mean its 3 lines to fix it
I am trying that ?
you can do set_blind = function(self, blind)
get_blind_amount(G.GAME.round_resets.ante)*blind.mult*G.GAME.starting_params.ante_scaling
i think this is the line for the chips
i think
this doesn't work because the text object fetches its value when its created
recalculating the uibox doesn't update it
you could also see how multiplayer does it
G.GAME.blind.mult = G.GAME.blind.mult + 2;
G.GAME.blind.chips = get_blind_amount(G.GAME.round_resets.ante)*G.GAME.blind.mult*G.GAME.starting_params.ante_scaling
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)```
this works tho
this is how a mod i helped with does it atleast
alr
never worked for me
odd
well I did it in a calculate function
still dont understand how, the blind size text isnt a dynatext object
maybe the mod u helped with changed that
but is 0.25 for each upgraded card strong or weak
no idea this is happening whilst in the blind though
hm maybe thats it
is it when you upgrade a card? or just all upgraded cards
cus what i had done was trying to modify it in the blind select menu
for all upgraded card in deck
ah probably, there was a thing i was gonna help with but i nope'd outta there
say i have 32 cards, 8 upgraded (so x4 more) by default its 53000 (say a small blind for this) and having it x4 more so it'll be 212000 now
which is more than showdown boss blind
-# in ante 8
it really depends on the jokers you added, and how easy they are to get
if theres alot of op ones, then yea probably, but if not maybe do x0.1
just try calculating it and see if its a large amount
its more like + 2X if you have upgraded card
x4 as in there is x4 more
people will either have alot of modified cards or none though
oh upgraded card are not normal enhance one btw
could someone help me understand why G.P_CENTER_POOLS.Joker only has vanilla jokers when i try to use it in my code :p thought it should have all
ohh,
how easy are they to get?
and how many would an alright deck have?
https://github.com/nh6574/VanillaRemade/wiki#whats-a-poolset
no idea but heres all the pools if it helps
Because modded jokers aren't injected yet.
like a blind with 10k required would bel 30k with 8 upgraded card
ah okay
You have to use SMODS.Centers for the modded jokers.
its like you can upgrade enhancement and seal with certain consumeable so they are stronger its like the main gimmic of my mod with mini-tarot
-# consumeable is the internal name consumable is the correct spelling sorry
ah i see
thats pretty good idea
oh mb
i've mixed them up alot
I alway taught it was 'ea' so I learn something from u
SMODS.Centers doesnt have vanilla jokers
it does! but i ran eval G.P_CENTERS["j_crafty"] so maybe im wrong
I think since this is a blind that appear at min ante4 It should be 0.25
SMODS.add_card { set = 'Joker', key = 'j_cavendish', edition = "e_negative", force_stickers = true, stickers = {'perishable'}, key_append = 'pnr_pplus_gross_michelle', cost = 2 }
I was curious if there was a way to change the cost of a spawned in joker and if so what that would look like
thats G.P_CENTERS. i was talking about SMODS.Centers
That's an upgraded red btw
ooh
oh oopsie ya :3
seals has usualy 2 upgrade + and ++ and enhancement has one
Yes, I meant for the modded jokers.
also no you dont G.P_CENTERS also has modded jokers
Not on load.
oh ok
So where would this be put in the function to spawn in the joker, egg uses a function in its calculate:
if context.end_of_round and context.game_over == false and context.main_eval and not context.blueprint then -- See note about SMODS Scaling Manipulation on the wiki card.ability.extra_value = card.ability.extra_value + card.ability.extra.price card:set_cost() return { message = localize('k_val_up'), colour = G.C.MONEY } end
And I'm not sure how to implement that into the spawning joker function:
SMODS.add_card { set = 'Joker', key = 'j_cavendish', edition = "e_negative", force_stickers = true, stickers = {'perishable'}, key_append = 'pnr_pplus_gross_michelle', card.ability.extra_value = 2, card:set_cost(), }
you set the value after creating the joker
SMODS.add_card returns the card just created
are the seal keys just red blue purple gold or like red_seal or something else
No, it's Red, Blue, Purple and Gold
tnx
I'm still a little confused as I don't believe I understand where the change sell value goes, I've put it here but it doesn't change the sell value of 5:
G.GAME.joker_buffer = G.GAME.joker_buffer
G.E_MANAGER:add_event(Event({
func = function()
SMODS.add_card {
set = 'Joker',
key = 'j_cavendish',
edition = "e_negative",
force_stickers = true,
stickers = {'perishable'},
key_append = 'pnr_pplus_gross_michelle',
}
G.GAME.joker_buffer = 0
return true
end
}))
card.ability.extra_value = card.ability.extra_value + 2
card:set_cost()
return {
message = localize('k_plus_joker'),
colour = G.C.BLUE,
}```
pls use
```lua
```
for formatting
ah I missed one
also you're changing the cost of the card that is doing the effect not the card that you add, is that intended?
Nope I am foolish, basically I want this to create a joker but I find that the sell value it comes in at is too powerful for the purpose
well right now ur increasing is sell value even further
Just trying to understand it, then I'm gonna have it lowered
you should save the added card ( local added_card = SMODS.add_card{...} ) and then change the value of that inside the event (so before return true)
Likely just inputting it wrong but it hasn't seemed to change the value, sorry I'm having such trouble with this I'm going straight to sleep after this from being awake for like 23 hours
G.GAME.joker_buffer = G.GAME.joker_buffer
G.E_MANAGER:add_event(Event({
func = function()
local added_card = SMODS.add_card {
set = 'Joker',
key = 'j_cavendish',
edition = "e_negative",
force_stickers = true,
stickers = {'perishable'},
key_append = 'pnr_pplus_gross_michelle',
}
G.GAME.joker_buffer = 0
card.ability.extra_value = card.ability.extra_value + 2
card:set_cost()
return true
end
}))
return {
message = localize('k_plus_joker'),
colour = G.C.BLUE,
}```
ty heavenly n'
it should be added_card instead of card
card is the one doing the effect
how do I implement tho
dunno havent seen that code lol
🙏
Oh my god it finally works, thank you a very great amount more than necessary
but to animate a joker what i do is use update or a drawstep to change the sprite position
i mean should i just ask thunder?
probably
i can do that
seems viable
how would I go about finding 3 random cards held in hand
yart
damn i was writing the exact same thing lmao
how tf do i change that
where is the variable or wht ever
found it
[[Joker]].config.center.pos
nope
does stuff like enhancements and seals always apply at the end of an event
joker.children.center:set_sprite_pos({ x = num, y= num })
wdym
wait
waiting
ive been jabbing at it by switching the events that apply the seal and unhighlight it
i want the seal to apply while its highlighted
I did it the otherway around to where the seal application was under the highlight event it was basically the same
set_seal has an event i think yeah
the one i did worked?
dont put that in an event
oh
I don't believe you
it would change the prototype but not the sprite itself
🤷♂️
Have been trying to like do the jpeg thing but somehow it ended up like this
It's almost close to being done
okay how do I fix this?
I'm so close but for some reason it showing the texture of the jokers
calculate = function(slef, card, context)
local results = {}
local other_joker = nil
for i, other_joker in pairs(G.jokers.cards) do
if other_joker == card then other_joker = G.jokers.cards[i-1] end
end
if other_joker then
table.insert(results, SMODS.blueprint_effect(other_joker, card, context))
table.insert(results, SMODS.blueprint_effect(other_joker, card, context)) -- mitosis
end
return SMODS.merge_effects(results)
end
why no work :(
log everything and you will see where its going wrong and then it will be way easier to figure out the solution
it cant find the joker :(
wait does it need ipairs?
theoretically no but probably try it
wait no its finding the joker
like i can see it
fuck me
the variable name
ihml
oops lmao
close enough but still need to manage about how the texture can be scaled correctly.
wait it still no work
also whaty
@umbral zodiac pretty please js recode this, why doesnt it work
im just gonna check vremade
i've js stolen it so hope it works
:(
why does nothing work
calculate = function(self, card, context)
local other_joker = nil
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i - 1] end
end
return {SMODS.blueprint_effect(card, other_joker, context), SMODS.blueprint_effect(card, other_joker, context)}
end,
wawawawawawawa
I wonder if I should make blueprint effect accept a table of cards similar to destroy cards 🤔
How do you check for debuffed cards
card.debuff
I have logic that I want to have some jokers debuffed and the debuff stay pass the end of round, but I think the game automatically removes any debuffs at end of round (the custom joker only applies debuffs and has no end of round logic). I looked into the end of round function, but I cannot find out at which point the debuff is removed (that's why I provide video footage, you can also see how these jokers don't trigger)
debuffs are definitely not removed at end of round, see smods documentation on how to properly set debuffs
oh no
thx for absolving me of making that by doing it first
what does JPEG edition do btw?
I think it compresses your mult
what does that even do
Its to check if a Gros michel went extinct to allow Cavendish to appear in the joker pool
oh yeah that makes sense
perma_debuff
thanks, that helped
No problem
I want to make a joker gain xmult when a spectral card is used, how do i do that?
step 1: copy constellation
step 2: change the set check from "Planet" to "Spectral"
🤯
i forgot vouchers exist-
does UIBox_button support passing args to the button function?
no
😭
With UIBox_button you cannot define own variables in element's config
I forgot Constellation exists, is what i meant 
Unless you want to do mth like r.nodes[1].config.your_var = 1
Hello, any idea why this crashes the game?
local card_ui_ref = generate_card_ui
function generate_card_ui(_c, full_UI_table, specific_vars, card_type, badges, hide_desc, main_start, main_end)
return card_ui_ref(_c, full_UI_table, specific_vars, card_type, badges, hide_desc, main_start, main_end)
end
you're missing one argument
which one?
at the end, called card
where is that?
the function definition I found doesnt have that
is there another place where it's defined?
oh ok
I wasn't are lovely changed this function
what does that card arg do?
it might be pretty useful for me right now
and I haven't messed with the UI yet in my mod so this is new territory for me
It's the card that the function is generating the ui of.
damn thanks
also SMODS already does exactly what I wanted to do by default xD
So I was just reiventing the wheel
the power of reading documentation
is there a context variable or a method to detect cards that are played but not used in scoring?
i'm assuming you'd probably subtract array elements or something but i don't know how to do this (it's been a while since i did lua)
probably would cycle through each card played and check if it's a member of the scored hand
if context.individual and context.cardarea == "unscored" then
if you ever need to do the latter thing, SMODS.in_scoring(playing_card, context.scoring_hand) works
feeling like im not returning the right thing in this hand part because while it does seem to recognize when its this hand... no cards score
so uh. how do i get the cards to actually be scoring
--eject early if hand is too small
if #hand < (SMODS.four_fingers('straight') -1) then return {} end
straightsTable = get_straight(hand, SMODS.four_fingers('straight') -1, SMODS.shortcut(), SMODS.wrap_around_straight())
if next(straightsTable) == nil then return {} end
bobtails = {}
for _,straight in pairs(straightsTable) do
--have to reimplement the flush calc because unlike get_straight, smods doesn't modify it
for suit,_ in pairs(SMODS.Suits) do
local t = {}
local flush_count = 0
for i,_ in pairs(straight) do
if straight[i]:is_suit(suit, nil, true) then flush_count = flush_count + 1; t[#t+1] = straight[i] end
end
if flush_count >= (#straight) then
table.insert(bobtails, t)
end
end
end
if next(bobtails) == nil then return {} end
return { bobtails }
end```
straight flush but with only four cards (but the four cards have to both be part of the straight and the flush, having cards only part of one of the two doesnt count)
right now it.. works except none of the cards actually score
so im guessing the bobtails table doesnt contain the right things its looking for or something?
they're all played but unscoring, it only gives the hand's base score
what?
oh wait
but like. thats not the question i was asking?
what should i have returned instead
why arent any of the cards scoring
dont just give me completely different code that does work i want to understand why what i did isn't working
also im looking at this code and i dont think itd do what i want?
wouldn't this make say, H_9 H_10 C_J H_Q H_K count?
i explicitly dont want something like that to count
isnt that syntaxically equivalent?
because you were returning a table of a table of tables of cards
it was nested too deep
ty
np
How are Lovely patch files targetted by Lovely? Do they need to be in a specific folder, or they just need to be a properly formatted TOML file that can be placed in a folder that's fairly nested
if im not mistaken right now they need to be in a lovely.toml in the root folder or in a lovely folder without nesting
i think they plan to allow nesting in the next version
gotcha, thank you
yeah i’m p sure that’s correct
mainly because i was going to say the same thing and then i lost my phone in my bed
is there a simple way to check if a scored card counts for more than one suit? I see has_any_suit, but i think that's just for wild cards
I don't think there's api support for anything that's not wild cards
you could check all suits one by one
yeah, i was hoping it'd be simpler than that but oh well, thanks
how does set_cost work? ive tried looking through vanillaremade but im not getting at all
It recalculates the cost and sell value of a card.
yeah but how do i use it
card:set_cost()
do i literally just put the number in the parentheses
No.
Are you trying to modify the cost of a card?
yea
Folks, is there a quick guide how to make a new color for text that color shifts like dark edition?
card.ability.extra_value = (card.ability.extra_value or 0) + number
card:set_cost()
Check SMODS.Gradient
I dont understand it
oh i see set_cost() is like an update thing right
There's no example
Yes, it recalculates the cost and sell value.
yeeaah stuff like this way outta my league as someone frankensteining code together
thanks for your help
What is the goal?
<3
to change the joker's sprite when it's highlighted, and to change it back when it's not
Hook Card:highlight
ello ^^
been using the "Dark And Colorful" texturepack from daluigi (https://www.nexusmods.com/balatro/mods/393?tab=images)
I've noticed it breaks hologram's floating effects for some reason
dark and colorful does reimplement a bunch of how the game renders cards, but I'm not sure how its exactly breaking because the implementation seems almost identical to how it is in the example steamodded implementation of vanilla objects
any idea why its breaking like this?
How do you retexture small blinds and big blinds?
I will one day learn how functions function, but today is not that day

cheers
how do I check owned jokers for editions? I want to make a joker that gives x2 mult per each negative jokers, kinda like baseball card with uncommons
I tried to come up with a context check but I dont understand how to build a proper logic
if context.other_joker and context.other_joker.edition and context.other_joker.edition.negative then return { xmult = 2 } end
is simplest.
thanks, I'll try it
Is the owner of https://github.com/Steamodded/smods/pull/1058 here? I have a relatively elegant solution to the logic in G.UIDEF.stake_option and I don't want to create a PR for basically the same thing
why it doing nothing :(
Just PR your version
Firstly, extra_value starts at 0, Secondly, it only works for sell value not cost it seems.
It seems you have to modify card.extra_cost instead.
@wintry solar, I thinked a little bit, and if you need help with reviewing SMODS PRs in theory I can help, at least with filtering
So if someone requests review in PR, I can review first and if it "lgfm" then pass to you + aura
im trying to make this retrigger cards after they had a success in their pseudorandom
and someone told me to hook eval card
nope
Yes, (card.extra_cost or 0)
No, it's v.extra_cost
oh ok
bump
This code doesn't work
im trying to remake card arts with the take ownership thing, can someone just send an image of the code for it here cuz im clueless lol
Nvm I had to replace context.other_card with context.debuff_card
where is the primary_colour field of a consumable type used again?
the secondary is used for the badge color, but.. wheres the primary used?
pretty much nowhere
as far as i know it's actually nowhere
when i opened the PR for the text colour field, i actually tried replacing the primary colour field, but smods undid that when they implemented it
incredible
so fucking funny that the one called primary is the one that doesnt do shit
tysm, it's working now
btw ik no one cares but I'm working on Handy 2 
the worst part about coding a consumable is having to do all the juice fx stuff 
couldn't be me (my silly ass wants to make an entire new consumable type)
like somehow for me the visual fx for when the consumable does things is like. 10 times harder to wrap my head around than the actual effect
are vouchers not included in G.I.CARD?
i think only while theyre on screen
vouchers arent actively loaded they just have apply functions and they set something in a table to true
Yes, if they don't exist.
ah gotcha
how can i get the localized name of a joker from its key
localize({type = 'name_text', key = 'j_modprefix_key', set = 'Joker'})
okay, i've got three selected cards and want to sort them based on the order they're in the hand
this feels stupid there's gotta be a better way than this
if(G.hand.highlighted[1].T.x > G.hand.highlighted[2].T.x) then
if(G.hand.highlighted[1].T.x > G.hand.highlighted[3].T.x) then
rightmost = G.hand.highlighted[1]
if(G.hand.highlighted[2].T.x > G.hand.highlighted[3].T.x) then
middle = G.hand.highlighted[2].T.x
leftmost = G.hand.highlighted[3].T.x
else
middle = G.hand.highlighted[3].T.x
leftmost = G.hand.highlighted[2].T.x
end
else
rightmost = G.hand.highlighted[3]
middle = G.hand.highlighted[1]
leftmost = G.hand.highlighted[2]
end
else
if(G.hand.highlighted[2].T.x > G.hand.highlighted[3].T.x) then
rightmost = G.hand.highlighted[2]
if(G.hand.highlighted[1].T.x > G.hand.highlighted[3].T.x) then
middle = G.hand.highlighted[1].T.x
leftmost = G.hand.highlighted[3].T.x
else
middle = G.hand.highlighted[3].T.x
leftmost = G.hand.highlighted[1].T.x
end
else
rightmost = G.hand.highlighted[3]
middle = G.hand.highlighted[2]
leftmost = G.hand.highlighted[1]
end
end```
is there?
I think. I think G.hand.highlighted automatically sorts itself based on that
nope, it doesn't!
do a death-like effect that depends on the order of the cards, so i need to know which ones leftmost, which ones in the middle, and which ones rightmost
the code i have works, but. look at it
i just have a gut feeling theres some function i could use instead
looking at vanillaremade this looks like the way they do it so you might be stuck with this
Yes, table.sort
table.sort(G.hand.highlighted, function(a,b) return a.T.x < b.T.x end)
ok i cannot figure out how to alter the price of items this is driving me insane
Code?
Are you in the shop when adding it to deck?
yes
How do you figure out how to make jokers do things if the joker area changes?
Like if a joker was added, sold, destroyed, order was changed, everything.
ermmmm what the scallop
wait im stupid nvm
well im even more stupid cos the thing i thought doesnt make sense
i suck with cardareas its crazy
how do i stop the return table from being nil
context.card_added, context.selling_card, context.joker_type_destroyed, Hook Card:stop_drag
How do you hook Card:stop_drag?
Aight got the hook set up, any chance I could make the game call a context event with the reordering set to true?
or have the value be the card being reordered?
is there a way to put a default cost into a consumable type, or do i have to add the cost to each one manually?
hëlp
SMODS.calculate_context({modprefix_stop_drag = true, other_card = self})
ty!
hello, im trying to change the main menu on balatro, i want to change the card that you can play with in the middle of the screen to a polychrome, red seal, lucky king of hearts, how would i go about this?
feel free to dm me or so on, if needed
calculate = function(self,card,context)
if not context.blueprint then
if
(context.discard and context.other_card == context.full_hand[#context.full_hand]) or
context.after
then
if G.GAME.blind.boss and (G.GAME.chips + SMODS.calculate_round_score()) >= G.GAME.blind.chips then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod
return {
message = localize('k_awake_ex'),
colour = G.C.CHIPS
}
else
if card.ability.extra.chips > 0 then
if card.ability.extra.chips - card.ability.extra.chip_penalty > 0 then
card.ability.extra.chips = card.ability.extra.chips - card.ability.extra.chip_penalty
else
card.ability.extra.chips = 0
end
return {
message = localize('k_sleep_ex'),
colour = G.C.CHIPS
}
end
end
end
end
if context.joker_main then
return {
chips = card.ability.extra.chips
}
end
end,```
Anyone know how to fix the G.Game.chips bit?
It returns false if you beat a boss blind without the hand being on fire
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "replace_card.states.visible = false"
position = "before"
payload = '''
replace_card:set_edition('e_polychrome', true, true)
replace_card:set_seal('Red', true, true)
replace_card:set_ability('m_lucky')
SMODS.change_base(replace_card, 'Hearts', 'King')
'''
match_indent = true
where do i put this, sorry im a bit dumb 🙁
@daring fern
In a lovely.toml file or a toml file in a lovely folder.
i might need more help, sorry
whats that
do i just need to make it a file and add .toml at the end of it?
@daring fern
Sorry if this is a silly question, but I was hoping to find a way to make my mod compatible with another mod. I made PolyLatro a couple days ago, but I realized after making it it doesn't stack with BalaGay. Is there any way for me to do that?
Yes, don't rewrite the entire localization.
Yes, but it needs to be called lovely.toml or be in a lovely folder.
I tried to only rewrite certain sections, but it didn't run afterwards, it immediately crashed my game.
Log?
how do i name it lovely.toml, or put it in a lovely folder, i dont code or anything so i have no clue
Right click the file and click Rename
i cant for some reason on mine lol
damn
does the button not work?
try win-shift-s
omg, thank you
wo
ah you need a header for your lovely file
gimme a second to pull that up
^ just put that at the very top of lovely.toml, above the [[patches]] line
yerp
You're missing a } or you have an extra { or your missing a ,
not the triple tick marks
come on meta
i was trying to type that except putting them in a block like this to look cool
but they are the character that does that so i was failing 🥀
lolll sorry
local created_card = create_card("golden_spectral", G.pack_cards, nil, nil, true, true, pseudorandom_element(golden_spectral_keys, pseudoseed('match')), nil)```
trying desperately to make this booster pack code work but running this line is crashing because its passing center as "nil". ive tried passing all sorts of things through center though and it still says that and also im looking at code from the Pokermon mod and it passes nil same spot but works fine, does anyone know what I'm doing wrong?
you dont have to do the pseudorandom_element shuffle
if you don't provide a forced key & golden_spectral is a pool then it will pick one itself
how would I do it with out, I've basically just been taking apart other peoples mods and trying to learn from that
is golden_spectral a consumable type
SMODS.create_card({set = 'golden_spectral', area = G.pack_cards, skip_materialize = true)}
yes
it has a card registered to it too
then you can just do what somethingcom said
alright ty!
you don't need to provide a specific key if its a valid pool and consumabletypes do have pools
you need to actually make a mod rather than editing files directly
so put it in my mods folder?
put it in a folder inside your mods folder; but yes
thank you
like C:\Users\YOUR_NAME\AppData\Roaming\Balatro\Mods\MOD_NAME\lovely.toml
ill show u where i put it, one sec
Thank you so so much, this was amazing help!!
yes
you need to return it probably
just put return before the smods.create_card
...well, it was-- The game runs now but now the text isn't edited.
ahh yeah that makes sense lol. stopped crashing but im not sure whats going on now
so like priority 10?
yea try that
Meow
im sooo happy
i assume this happens because it can't find anything in the pool, right?
what is your consumable type called
consumable type is called "golden_spectral"
like did you use the exact same key as its defined
ok good just making sure
are the available options perhaps not in the pool
@umbral zodiac may i dm you if i need help with other things?
for sure
look forward to doing some other cool stuff soon
are pools autodefined by the contents of the type or do i have to define them manually
for consumable types they should be automatically made
but i mean like
for the cards that are there, have you defined in_pool functions which would specify that they shouldnt spawn
is there a way i can make the card a steel card instead of a lucky card?
local pack2 = SMODS.Booster{
name = "Golden Spectral Pack",
loc_txt = {
name = "Golden Spectral Pack",
text = {"Choose up to {C:attention}1{} of",
"{C:attention}3{} {C:gold}Golden Spectral{} cards",
"to be used immediately"}
},
key = "gs_booster_1",
kind = "golden_spectral",
atlas = "gs_booster_atlas",
pos = { x = 0, y = 0 },
config = { extra = 1, choose = 1, c_keys = {} },
cost = 1,
order = 2,
weight = 10,
draw_hand = true,
unlocked = true,
discovered = true,
create_card = function(self, card, i)
return SMODS.create_card({set = 'golden_spectral', area = G.pack_cards, skip_materialize = true})
end,
loc_vars = function(self, info_queue, card)
return { vars = { card.config.center.config.choose, card.ability.extra - 1, 1 } }
end,
group_key = "golden_spectral_pack",
}```
m_steel instead of m_lucky
ohhh so juust m_ and whatever enchancment i want
pretty much
name = "empower",
key = "gs_empower",
set = "golden_spectral",
loc_txt = {
name = "Empower",
text = {
"{C:attention}+2{} joker slots",
}
},
pos = { x = 0, y = 0 },
soul_pos = {x = 1, y = 0},
atlas = "empower_atlas",
cost = 3,
unlocked = true,
discovered = true,
hidden = false, -- In regular packs
draw = function(self, card, layer) -- Apply shader to card
if (layer == 'card' or layer == 'both') and card.sprite_facing == 'front' then
card.children.center:draw_shader('booster', nil, card.ARGS.send_to_shader)
end
end,
can_use = function(self, card)
return true
end,
use = function(self, card, area)
-- Play the card’s sound and animation
play_sound('generic1')
card:juice_up(0.6, 0.6) -- makes the card “pop” visually
-- Increase the max Joker slots by 2
G.jokers.config.card_limit = G.jokers.config.card_limit + 2
-- Persist it for the whole run
-- (This ensures it stays after restarts/round transitions)
G.P_JOKER_SLOTS = G.jokers.config.card_limit
-- Optional visual confirmation
local msg = "+2 Joker Slots"
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.3,
func = function()
create_floating_text(msg, G.C.WHITE, card, 0, -2)
play_sound('tarot1')
return true
end
}))
return true
end
})```
this is the only thing ive put in
yeah sry i dont know what the issue here is then
hopefully someone else is less light headed than i am
what's the goal with this, some of it doesn't make sense
im just trying to make a booster pack that randomly generateds cards from my consumable type
its just generating jokers and saying error
im talking about the consumable itself tho
can i see the code for the consumable type
local item = SMODS.ConsumableType{
key = "golden_spectral",
primary_colour = HEX("F2BB1D"),
secondary_colour = HEX("FCCC3F"),
loc_txt = {
name = 'Golden Spectral', -- used on card type badges
collection = 'Golden Spectral Cards', -- label for the button to access the collection
},
collection_row = {6, 6},
shop_rate = 4,
default = "t_fool"
}```
the card itself is supposed to give +2 joker slots when used but im not focused on making that work rn
the default should be c_fool
well thats a start thanks, its now giving 3 fools but i want it to randomly choose cards from the set
do you have debugplus
no whats that
it helps with testing
https://discord.com/channels/1116389027176787968/1228149931257237664
i was going to ask you to run something in the console to see if the pool is loaded
I'm trying to understand how generate_card_ui works.. is there any documentation of it anywhere?
sure, i installed it
open the console with / and run eval G.P_CENTER_POOLS.golden_spectral
nope
what are you trying to do
weird
yeah i just want to add a dynamic tooltip onto a card
the description should be easy, its just a table of strings
lemme make a mockup of what im talking about
i have this patch that runs a custom generate_ui function in a patch to that function
https://github.com/nh6574/JoyousSpring/blob/0a5c0f6951f7f3073acb7f06ee1fafed950eef16/lovely/monsters.toml#L6
here's the function
https://github.com/nh6574/JoyousSpring/blob/0a5c0f6951f7f3073acb7f06ee1fafed950eef16/src/card_ui.lua#L255
the relevant part of the function is at the end where it adds stuff to info_queue
you don't need to make a function like me you can just put the code in the patch directly
oh, perfect! thanks!
do you know where i could find a working example
vanillaremade!
This mod is driving me crazy, and I don't know what's wrong with it. Can anyone help with this error? I can provide my lua too if needed, but it's mainly just edits to the localization.
although i dont think the booster use the consumabletype actually
looks like a syntax error
if you want to do localization look at the SMODS documentation
i made the mistake of clicking update all
I'm following the docs to a t, and I'm still getting errors. After finally fixing all my syntax errors, I'm now getting this error, any help?
Wait, I think I figured it out!
...okay, I have one final question, and I think the mod is fixed. The only thing that isn't being edited is the actual Polychrome label under the Joker description. What part of my code is missing?
local other_joker = nil
if G.jokers and G.jokers.cards then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
other_joker = G.jokers.cards[i - 1]
end
end
end
card.ability.extra.target = other_joker
-- Update sprite
if G.GAME.playing and other_joker then
print("wawa")
card.config.center.pos = other_joker.config.center.pos```
why tf does this change other_joker
just what????
im changing the bloody card not other_joker
This doesn't look like the entire code block
ill send it rq (sorryfor late respo nce
its an update func in a joker
This code confuses me a lot, there’s a lot of inconsistency in variable usage
actual?
istg
if its the same issue i had yesterday where i had two of the same variable
oh i do card.config should just be config
but then why does it change the joker to the right of this one
how can i make text pop up like the wheel of fortune's "nope!"
the cool thing about vanillaremade is that you can just check how wheel of fortune does it :)
https://github.com/nh6574/VanillaRemade/blob/main/src/tarots.lua#L619
(it's a lot of event stuff, but it ultimately boils down to a function call to attention_text and then a few sfx)
a
no??
oh it actually is #1#?
yeah??? heres a snippet
loc_txt = {
name = 'Penny',
text = {
"{C:attention}Flip a coin{}",
"If heads,",
"{C:chips}+#1#{} Chips"
}
},
config = { extra = { chips = 50 } },
wheres your loc_vars function
are the loc_vars registered
oh my god i left it unchanged
LOL
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult } }
end,
ill fix that rq
there we go! :3
now i wanna test it but i cant seem to get it in normal play
ill check if theres a sandbox mode-like mod in the forum
debugplus
ty
okay the debuff sound effect is NOT debuffed.ogg
figured it out
how do i create a joker directly with debugplus
I'm making a retrigger joker, is it possible to add the sound effect when actual card is scored? it only plays at the start when I am playing my hand ! thanks in advance!
figured that out too
specify the sound in your return table
Currently working on a music pack framework for my API mod
Isn’t there already a music pack mod?
No clue. I'm doing what I was tasked to
how would I go about making a card forcefully selected
would looking at cerulean bell help
yeah
thought I want to ask about this, is there anything that can be possible to make an edition that render the card into how the profency panel from chapter 4?
also I still have some issues with the texture coords part for when I was developing the jpg shader so I went instead of trying to make something new after discovering the shadertoy shader of the Deltarune Chapter 4 Prophency panel
would it be something like this?
local geomelatro = SMODS.current_mod
function geomelatro.Load_Dir(directory)
local files = NFS.getDirectoryItems(geomelatro.path .. "/" .. directory)
local regular_files = {}
for _, filename in ipairs(files) do -- iterate over all files in the directory
local file_path = directory .. "/" .. filename
if file_path:match(".lua$") then -- check if its lua
if filename:match("^_") then -- i dont even know
SMODS.load_file(file_path)
print("loaded ", filename)
else
table.insert(regular_files, file_path) -- add non lua to other table
end
end
end
for _, file_path in ipairs(regular_files) do
SMODS.load_file(file_path, "geomelatro")
print('wawa')
end
end
geomelatro.Load_Dir("Objects")
geomelatro.Load_Dir("Objects/jokers")
why doesnt it load
its all wawa
no loaded ...
yeah
Tried to import the profency shader into balatro and I had to make it so that it would load in the two noise images as a test to see how it would owkr but it turned out to be this now.
I did my best about it
Thanks !
i once again am here to ask if anyone here has worked with custom cardareas before, and if so, do you know why my cardarea returns a null table while setting up a new run?
If i want to use a different sound for context.end_of_round, do I have to call the play_sound function? im testing with multiple of the same jokers, and i want the sound to play at a different time
hello. do anyone here help me how to make Balatro mods?
just use a different return
I tried doing something like this but the end of round sound still doesn't play, got any suggestions?
oh i think playing sounds like that requires a message
calling play_sound directly might work there
im trying to make a booster pack that randomly picks cards from my custom consumable type but i cant get it to work, it always picks the default card of my consumable type not actual cards registered to it. can anyone help? ive tried looking at vremade and i cant get it to work properly
its saying error and giving me the default card (i just set it to vanilla fool)
what?
I haven2T gotten to boosters yet and I saw this
Anyone have any knowladge on balatro shaders?
cause I have 2 issues with the two shaders.
give me the code for the consumabletype and booster
key = "golden_spectral",
primary_colour = HEX("F2BB1D"),
secondary_colour = HEX("FCCC3F"),
loc_txt = {
name = 'Golden Spectral', -- used on card type badges
collection = 'Golden Spectral Cards', -- label for the button to access the collection
},
collection_rows = {4, 5},
shop_rate = 0,
default = "c_fool"
}```
local pack2 = SMODS.Booster{
name = "Golden Spectral Pack",
loc_txt = {
name = "Golden Spectral Pack",
text = {"Choose up to {C:attention}1{} of",
"{C:attention}3{} {C:gold}Golden Spectral{} cards",
"to be used immediately"}
},
draw_hand = true, -- Draw some cards to use them on
key = "gs_booster_1",
kind = "golden_spectral",
atlas = "gs_booster_atlas",
pos = { x = 0, y = 0 },
config = { extra = 1, choose = 1, c_keys = {} },
cost = 1,
order = 2,
weight = 25,
draw_hand = true,
unlocked = true,
discovered = true,
create_card = function(self, card, i)
local _card
_card = {
set = "golden_spectral",
area = G.pack_cards,
skip_materialize = true,
soulable = false
}
return _card
end,
loc_vars = function(self, info_queue, card)
return { vars = { card.config.center.config.choose, card.ability.extra - 1, 1 } }
end
}```
its clearly recognizing the consumable type because its using the default card but thats as far as i got
have you tried setting a default from golden_spectral specifically?
you also only have one card because extra = 1
extra 1 was intentional
i couldnt get that to work actually
name = "empower",
key = "gs_empower",
set = "golden_spectral",
loc_txt = {
name = "Empower",
text = {
"{C:attention}+2{} joker slots",
}
},
pos = { x = 0, y = 0 },
soul_pos = {x = 1, y = 0},
atlas = "empower_atlas",
cost = 69420,
unlocked = true,
discovered = true,
hidden = true, -- Not visible in the shop on its own
draw = function(self, card, layer) -- Apply shader to card
if (layer == 'card' or layer == 'both') and card.sprite_facing == 'front' then
card.children.center:draw_shader('booster', nil, card.ARGS.send_to_shader)
end
end,
can_use = function(self, card)
return true
end,
use = function(self, card, area)
-- Play the card’s sound and animation
play_sound('generic1')
card:juice_up(0.6, 0.6) -- makes the card “pop” visually
-- Increase the max Joker slots by 2
G.jokers.config.card_limit = G.jokers.config.card_limit + 2
-- Persist it for the whole run
-- (This ensures it stays after restarts/round transitions)
G.P_JOKER_SLOTS = G.jokers.config.card_limit
-- Optional visual confirmation
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
attention_text({
text = "+2 Joker Slots",
scale = 1.3,
hold = 1.4,
major = card,
backdrop_colour = G.C.SECONDARY_SET.Tarot,
align = (G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK or G.STATE == G.STATES.SMODS_BOOSTER_OPENED) and
'tm' or 'cm',
offset = { x = 0, y = (G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK or G.STATE == G.STATES.SMODS_BOOSTER_OPENED) and -0.2 or 0 },
silent = true
})
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.06 * G.SETTINGS.GAMESPEED,
blockable = false,
blocking = false,
func = function()
play_sound('tarot2', 0.76, 0.4)
return true
end
}))
play_sound('tarot2', 1, 0.4)
card:juice_up(0.3, 0.5)
return true
end
}))
return true
end
})```
i tried to set it to this but it didnt work it just had the regular joker place holder
but this card can be found in the shop when i set it to not hidden and works fine
its also recognized in the collection
weird, do you want my consumable code, see if it works for you
sure thanks
SMODS.ConsumableType {
key = 'gspectral',
collection_rows = {5, 5},
primary_colour = G.C.CHIPS,
secondary_colour = HEX('FCCC3F'),
loc_txt = {
collection = 'Gilded Spectrals',
name = 'Gilded Spectral'
},
shop_rate = 0
}
SMODS.Consumable {
key = 'empower',
set = 'gspectral',
pos = { x = 0, y = 0 },
config = { extra = {
joker_slots_value = 2
} },
loc_txt = {
name = 'Empower',
text = {
[1] = '{C:attention}+#1#{} Joker Slots'
}
},
cost = 3,
unlocked = true,
discovered = true,
hidden = false,
can_repeat_soul = false,
atlas = 'Consumable',use = function(self, card, area, copier)
local used_card = copier or card
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
card_eval_status_text(used_card, 'extra', nil, nil, nil, {message = "+"..tostring(2).." Joker Slot", colour = G.C.DARK_EDITION})
G.jokers.config.card_limit = G.jokers.config.card_limit + 2
return true
end
}))
delay(0.6)
end,
can_use = function(self, card)
return true
end
}
just saying i used jokerforge for the base of the consumable but this should work if you modify some values
it works for me so it should work for you
i also gave myself the leisure to rename it a bit (gilded sounds more cool than golden, im sorry 😭)
Does anyone know how to check if a rare joker was sold?
in jokerforge itd look something like this :)
I dont wanna use forge :(
hold on let me get it in codeform
wait jokerforge is dumb
😭
balrightttt
im just coding it for a friend anyway
riddle me this, what tf is the difference
one is meant to be for commons, one is rares
yeah i dont know how to make it work, but this happens to make the most sense
i can make a when card sold condition but making it go with jokers is a different story
would Jokerforge let you to make custom shaders?
no
cause I checked there and well.
Oops! The game crashed:
Duplicate installation of Steamodded detected! Please remove the duplicate steamodded/smods folder in your mods folder.
A bad lovely patch has resulted in this crash.
Additional Context:
Balatro Version: 1.0.1o-FULL (best guess)
Modded Version: 1.0.0~BETA-1016c-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.8.0
Platform: Windows
Stack Traceback
(3) C function 'function: 0x0974fbc8'
(4) global C function 'require'
(5) main chunk of file 'main.lua' at line 1758
(6) global C function 'require'
(7) LÖVE function at file 'boot.lua:323' (best guess)
Local variables:
c = table: 0x097eb558 {identity:false, version:11.5, accelerometerjoystick:true, modules:table: 0x097eb730, 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"])
i dont have 2 steammodeds installed
show mods folder
yes there are duplicate steamoddeds
you remove the 0827c one then
then just delete the other one?

