if randomeffect == 8 then
for i = 1, card.ability.immutable.rnpjokers do
local neojokers = pseudorandom_element(G.P_CENTER_POOLS.Joker, pseudoseed('neo2')).key
SMODS.add_card({ key = neojokers, edition = 'e_negative', stickers = {"perishable"} })
end
end```
#💻・modding-dev
1 messages · Page 556 of 1
Add force_stickers = true
In add card table?
Yes.
What do you do to make a poker hand level up when played?
if context.before then
return {level_up = true}
end
How about multiplying played poker hand’s level
How about multiplying played poker hand’s level
if context.before then
return {level_up = G.GAME.hands[context.scoring_name].level*(number-1)}
end
Number can be replaced with Config key?
Yes.
i've been meaning to simplify this joker's level up code, but idk how
calculate = function(self, card, context)
if context.before and next(context.poker_hands["Flush"]) and not context.blueprint then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('busterb_makudonarudo')
card:juice_up(0.3, 0.5)
update_hand_text({ sound = 'button', volume = 0.7, pitch = 0.9, delay = 0 },
{ level = 'x' .. to_big(card.ability.extra.multiplier) })
for poker_hand_key, hand in pairs(G.GAME.hands) do
local current_level = hand.level or 1
local levels_to_add = math.max(0, math.floor(current_level * (to_big(card.ability.extra.multiplier) - 1)))
if levels_to_add > to_big(0) then
level_up_hand(card, poker_hand_key, true, levels_to_add)
end
end
update_hand_text({ sound = 'button', volume = 0.7, pitch = 1.1, delay = 0 },
{ mult = 0, chips = 0, handname = '', level = '' })
return true
end
}))
(Levels up all poker hands by x2)
Is there a way to increase the interest earned to 2 per 5 bucks instead of 1 per 5? Need this for a deck
@daring fern have you got a simpler way to level up all poker hands by x2?
if context.before and next(context.poker_hands["Flush"]) and not context.blueprint then
return {func = function()
for k, v in pairs(G.GAME.hands) do
SMODS.smart_level_up_hand(card, k, false, v.level)
end
end}
end
look at to the moon
wait
OHH
I thought to the moon was separate from regular interest
mb
thank you
alright it's G.GAME.interest_amount
if randomeffect == 6 then
print("Effect 6")
if context.final_scoring_step then
return {
echips = math.min(card.ability.extra.echipsemult, card.ability.immutable.echipemultincreaseprevention),
emult = math.min(card.ability.extra.echipsemult, card.ability.immutable.echipemultincreaseprevention),
print("Success")
}
end
end
does not print success
"level" in v.level is a custom value?
No, level is the level of the poker hand.
How do you multiply it by Config value?
v.level*number
Ah
how can i get the amount of chips that a playing card will give?
eg. a regular 9 would give 9 chips, a bonus 3 would give 33, a hiked 5 may give 10, a stone card will give 50
card:get_chip_bonus() iirc
does that include the chips it gives normally?
i think so
ah gotcha ^u^ thanks!
G.P_TAGS
okay one more question
suppose i have two of the same joker, and i sell one of them
and it has a remove_from_deck
in that function, does it still consider itself to be a card?
like, would SMODS.find_card count it?
yes
grand ^^ thanks
how do i check if the nominal ranks of all scored cards in played hand adds up to 21
sum their .base.nominals iirc
how would i do that
your_card.base.nominal gives a card's base chips
so 2 for 2s, 10 for face cards, 11 for aces
at least, iirc ^^ correct me if i'm wrong
Me when aces could count as 1
Sounds correct
mm, this isn't correctly handling cards added by Standard Packs
OH wait no hold on
Enhanced too
default is for base playing cards
is there a way to make so a certain rank equals itself AND another one at the same time ? (ping me)
ex: modified ace that also counts as a two will trigger both wee joker and scholar
is there? yes. is it easy? no
wait until this gets merged https://github.com/Steamodded/smods/pull/838
quantum ranks are in the works??? siiick
Can you slow down the rate at which a Card gets removed by
if context.discard then
return {
message = 'removed',
colour = G.C.RED
remove = true -- This is too fast!
}
end
```?
modified a bit, but it still crashes the games
SMODS.Joker {
key = "helpy",
blueprint_compat = true,
rarity = 1,
cost = 5,
atlas = 'Joker',
pos = { x = 9, y = 0 },
config = { extra = { broke = 40 } },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = { key = "fnaf_sprite_WIP", set = "Other" }
info_queue[#info_queue + 1] = { key = "fnaf_code_WIP", set = "Other" }
return { vars = { card.ability.extra.broke } }
end,
calculate = function(self, card, context)
if G.GAME.dollars < 0 and context.end_of_round and G.GAME.blind.boss then
G.STATE = G.STATES.GAME_OVER
G.STATE_COMPLETE = false
end
end,
add_to_deck = function(self, card, from_debuff)
G.GAME.bankrupt_at = G.GAME.bankrupt_at - card.ability.extra.broke
end,
remove_from_deck = function(self, card, from_debuff)
G.GAME.bankrupt_at = G.GAME.bankrupt_at + card.ability.extra.broke
end
}
does not print "success"
if randomeffect == 3 then
print("Effect 3")
if context.cardarea == G.play and context.retrigger_check then
return {
repetitions = math.min(card.ability.extra.retriggerallplayed, card.ability.immutable.totalretriggerlimit),
print("Success")
}
end
where do you want to print?
oh no it just does not trigger repetition
oh ok
wdym
Yes, context.retrigger_check doesn't exist.
Yes.
whats the crash
ok, but what about effect 2?
if randomeffect == 2 then
print("Effect 2")
if context.retrigger_joker_check and context.other_card == G.jokers[1] or context.other_card == G.jokers[#G.jokers] then
return {
repetitions = math.min(card.ability.extra.leftmostrightmostjokers, card.ability.immutable.totalretriggerlimit),
message = localize("k_again_ex"),
print("Success")
}
end
end
also doesn't work
It's G.jokers.cards
to_big(x) yourself, now ⛈️
like this?```lua
if context.retrigger_joker_check and context.other_card == G.jokers.cards[1] or context.other_card == G.jokers.cards[#G.jokers] then
No, it's G.jokers.cards[#G.jokers.cards]
ok so I might have to rework a bit of the code for talisman support them
I want my Card to say "Target", then wait half a second before my Joker destroys the card.
Full code as Example:
-- I removed other Conditions for Simplicity
if context.discard and not (context.blueprint) then
G.E_MANAGER:add_event(Event({
trigger = 'after',
func = function()
attention_text({
text = 'Target',
scale = 0.8,
hold = 1.0,
major = context.other_card,
colour = G.C.RED,
align = 'cm',
offset = { x = 0, y = 0 },
silent = true
})
return true
end
}))
delay(0.5)
--SMODS.destroy_cards(context.other_card) -- Doesn't actually destroy the card :))
return {
message = 'Acquired!',
colour = G.C.RED,
remove = true -- is too fast.
}
end
Using the "remove" destroyes it Immidiatly, using SMODS.destroy_cards doesn't actually destroy the card :)
does this work
local other_card = context.other_card
SMODS.destroy_cards(other_card)
Lemme try, one sec
i don't actually know how to use this.
if randomeffect == 7 then
print("Effect 7")
if context.before and context.scoring_name then
return {
level_up = G.GAME.hands[context.scoring_name].level*(card.ability.extra.lvl-1),
message = localize("k_upgrade_ex"),
print("Success")
}
end
Same issue
oh so it creates ghost cards ok
Oh-
Sorry I should've mentioned that x'3
I'm supposed to make this effect level up the played hand.
how do i make this happen
does anyone know if it's possible to interface with the bsky/atproto api in lua?
i wanna make smtn similar to membership card but for my bsky acc
i've found the thing in the bsky api docs for getting the acc data (eg: follower count) but idk how to get it using the smods http api
hello?
hmm i cant think of a way to do it without patching the discard function
but i would need to test
have you tried adding remove = true to the return table?
it lets the game know you're destroying cards
wait i can't read
you did that already

maybe you can do it in pre_discard idk
Maybe Print your Result before the Return to see if it reaches and if the value is valid,
Usually I'd also just return a number in that place, so;
local num_val = G.GAME.hands[context.scoring_name].level*(card.ability.extra.lvl-1)
print(num_val)
return {
level_up = num_val,
message = localize("k_upgrade_ex"),
print("Success")
}
no because it precomputes the discarded number damn
Yeah I was about to say.. That kinda leads to it's own problems x'3
I remember I tried to do something like this before and Just gave up
That was months ago and I tought;
Surely, now it'll be easier!
how can i change this patch, so that it replaces all instances of the pattern with the payload?
what i would do is use SMODS.destroy_cards and set a flag on the card so then you can patch this in G.FUNCS.discard_cards_from_highlighted and do removed = G.hand.highlighted[i].removed or removed before the condition
It should do that already
mm, weird
You’re not cutting off a times argument are you?
Is that the entire line?
it's not, strangely
Ahhh that’s why
pattern only works with the entire line I think.
yeah i think you need regex for that
oh?
do not ask me what the pattern would be
do i just change pattern to regex, and replace all the special characters with escaped ones?
i mean, try it but i think you need to make the pattern match the line
I have found this site to be extremely useful for regex stuff https://regex-generator.olafneumann.org/?sampleText=&flags=i
A tool to generate simple regular expressions from sample text. Enable less experienced developers to create regex smoothly.
Very much recommend
That is... Pretty Smart, but
, What a Load of Work 
If it ends up being a Problem with other Mods, I'll just update the Keyword from the normal "removed" to some custom one x3
no wait im stupid that wont work either
i was thinking of something different and then i got distracted lol
I feel like this joker is a big waste of time simply because it has 1 of 8 effects it gives when triggered.
you would need to patch this part so it doesnt draw if it is removed
It randomly gives consumables, randomly retriggers jokers, randomly retriggers cards, doubles your money, gives square mult and chips, creates 7 random negative perishable jokers, randomly removes your stickers, and levels up your played poker hand.
How are you supposed to fit all of these in one joker
I made One with with 12 Effects, Oh boy felt it great to have it working 
It might also be an Order Issue depending on what Kind effects go before it ^^'
i managed to find this, which seems to be what i need
https://docs.bsky.app/docs/api/app-bsky-actor-get-profile
*This endpoint is part of the Bluesky application Lexicon APIs (app.bsky.*). Public endpoints which don't require authentication can be made directly against the public Bluesky AppView API: https://public.api.bsky.app. Authenticated requests are usually made to the user's PDS, with automatic service proxying. Authenticated requests can be used...
Can I share to you my progress and tell me what to change?
why is this happening?
i guess this is my cue to just patch the relevant lines individually 😭
Yep, that worked Purrfectly :3
Annoying for the Patch but hey.. it works!~ 
omg it worksss
bump
this hook is apparently relevant to everything going to shit when i look at the editions in the collection
context.starting_shop is not a tag context
try context.type == 'store_joker_modify'
update smods
oh right
i think that will stop the crashing but viewing the collection will still trigger the context
does anyone know if it is possible to bump the amount of consumables the user can select at once up to 2, and when 2 are selected, grab the id or name of them??
what FPS do Blind chips animate at?
G.consumeables.config.highlighted_limit = 2
mm
lemme think
i might need to add additional contexts to prevent it from triggering with the editions there
it's okay, i found that it's 10FPS
Actually, this brings it's own Problems:
When you have another Joker using
context.other_card == context.full_hand[#context.full_hand]
It doesn't trigger if the Last (or Specified Card) gets Removed :')
-# Patch in Screenshot
thanks
<@&1133519078540185692>
💔

thats weird
How do I check how many of a certain joker you have? (I'm trying to make a joker that gives chips for each copy of itself you have)
maybe try another flag name
#SMODS.find_card("j_modprefix_key")
wait actually
it doesn't
i just needed to update smods :]
it's not working it's just using the fallback valueee
Already tried that and it didn't fix it 
idk what the problem isss
it's definitely getting the right follower count so why isn't it using it
Is there a way to straight up just remove vouchers from the shop on each re-entry?
I have a card that's meant to spawn vouchers in but they just persist between shops until an ante is cleared and i cant find a workaround
ohhhhhh
it's bc the http call is asynchronous
i'm dumbb
how do i make the joker's value updated when the value updates?
i'd imagine you use the update function for a joker since thats for stuff that runs every frame
-# I'd actually suggest to only get the value at the start of each run-
or if you really want to update it then just do it at the end of round or smth
Honestly yeahhhhh
I agree with this
You could save the Value in a G.GAME global and call it from there? 
That’s not a bad idea
doesnt G.GAME only exist in runs tho
Did I live in lies this entire time
yes
if it gets reset in runs how do i make sure it exists at the start of the run
function SMODS.current_mod.reset_game_globals(run_start)
if run_start then
--code
end
end
You can hook either start_run or init_game_objects
i'm trying to make a copy of lines 487-489 that subtract hand size when a negative joker gets it's edition removed
how would i check for that?
And init_game to get it at the very start i guess x3

i'm still confusedd
What about exactly?
hii! could someone help me understand how to create stickers 3:
Read the wiki and vanilla remade examples and you’ll understand
It should be like other game objects
yeah thanks i already looked there
both places
i have it enabled on a stake but it seems to be applying to every card (tarots and planets) and also not performing the behavior i want
You should find parameters to fix that
yes that's why i'm asking for help here because i've already spent a couple hours reading the wiki and look at vre and bunco sticker examples
Code?
you need a sets parameter on the sticker for the first issue
as that determines what card types it goes on
thank you i'll do that first
get_sell_cost doesn't exist
got it
Trying to create a consumable that can create a booster pack but either bugs and the screen gets all messed up or it crashes, any help?
SMODS.Consumable{
key = 'boost',
set = 'fnaf_item',
atlas = 'TarotFnaf',
pos = {x = 7, y = 1},
config = { extra = { cards = 2 } },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = {key = "fnaf_sprite_WIP", set = "Other"}
info_queue[#info_queue + 1] = { key = "fnaf_code_WIP", set = "Other" }
return { vars = { card.ability.extra.cards } }
end,
use = function(self, card, area, copier)
SMODS.create_card { key = 'p_standard_mega_1', area = G.play }
G.FUNCS.use_card({ config = { ref_table = booster } })
end,
can_use = function(self, card)
return #G.deck.cards >= 3 -- placeholder
end
}
booster doesn't exist.
oh wait
can you remove a voucher after it has already been redeemed
wrong code
SMODS.Consumable{
key = 'boost',
set = 'fnaf_item',
atlas = 'TarotFnaf',
pos = {x = 7, y = 1},
config = { extra = { cards = 2 } },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = {key = "fnaf_sprite_WIP", set = "Other"}
info_queue[#info_queue + 1] = { key = "fnaf_code_WIP", set = "Other" }
return { vars = { card.ability.extra.cards } }
end,
use = function(self, card, area, copier)
local booster = SMODS.create_card { key = 'p_standard_mega_1', area = G.play }
G.FUNCS.use_card({ config = { ref_table = booster } })
booster:start_materialize()
end,
can_use = function(self, card)
return #G.deck.cards >= 3 -- placeholder
end
}
opening boosters is wonky, i would recommend restricting the usage to the shop only
Just curious lets say you wanna remove a certain voucher from pool for a deck whats the easiest way to do this?
them I just make so that the card adds 2 playing cards to the deck them
like I should have done to begin with
that's easy yeah
Okay so.. Oh my god that took so long and I cannot fathom why this works now--
The final Puzzle-Piece:, is to:
Call SMODS.destroy_cards with the immediate Parameter set to true BUT
Then putting that into an G.E_MANAGER:add_event set to trigger = 'after'
So, why not just call card:start_dissolve() in a Event?
Because then other Jokers listening for a Destruction Event won't trigger!
And don't get funny ideas, calling SMODS.calculate_context in this Situation also Crashes the Game!
YIPPEEEEE!! 
Update for anyone Stumbling into this:
First of all, Hi! :3 - I hope you're not going as mad as I did :3
You might notice that the Game doesn't draw Back enough cards!
You can always just put the Hand-Draw event into your Return or;
Use best of both worlds! (Get a Custom Color and all SMODS Advantages!)
context.other_card:start_dissolve({{1, 0, 0, 1}, {1, 0.5, 0.5, 1}}, false, nil, false)
SMODS.destroy_cards(context.other_card, nil, true, true)
The order, surprisingly, matters owo'
yayyy :D
amazing
But I have discovered a Bug with another Joker using SMODS.calculate_context,
so while the amount of my gray hair has increased... So has the amount of my Bugs to fix :')
In the Deck register, add the following property:
apply = function(self)
-- Other code...
G.GAME.banned_keys[<voucher key>] = true
-- More code...
end,
Okay I'm gonna start packing for an upcoming convention now, that sounds MUCH more pleasant after all of those shenanigans

Ping me when there's an Answer ... Or if you're patient enough I'll look into it more next week owo'
I wanna start learning ui except im not sure if the smods thing has everything i need to know. Does it have everything i need to know for basics?
its the only resource so
Aw ok
hii! could i ask if i'm doing smthn wrong? i added the sets but it still seems to be spawning on all types
also it spawns on literally every card and i'm not sure how to fix that, i don't see anything in the docs but in vre i see rate=0 for the pinned sticker?
okay thank you
i think should_apply overrides everything
so you would need to check the set and make a pseudorandom call in there
but i never made a sticker so i might be wrong
aghhh this is so confusing
im trying to make so a custom joker appears on the main menu but it crashes, what do i do wrong ?
:create_joker doesnt exist
You should hook Game:main_menu if you want to add a card to the title.
you want to add a card or replace the existing ace?
add one (yeah it says replace i just wanted to know how it works before modifying it) code from talisman
wherever you want
it basically never matters where you put any code as long as you load it
hum
well it works..halfy
theres indeed 2 cards but the one thats not the ace of spade is invisible
show code
surely
oh i also forgot to highlight the next part that makes it visible below hah
you need this part too
https://github.com/nh6574/JoyousSpring/blob/a929a8410b7ec9e43d52796505730112510dfe11/src/general_ui.lua#L793
the timing on that is kinda bad tho i never got around to fix it
i need the whole spash part in between ?
no that's for the background
like this so
wait i didn't read it if i need to get rid of undefined things
uh should be good
it works !!
is there a bug with the floating sprites of custom legendaries ?
ah yeah that you need to resize as well
try
newcard.children.floating_sprite.T.w = newcard.children.floating_sprite.T.w * 1.1 * 1.2
newcard.children.floating_sprite.T.h = newcard.children.floating_sprite.T.h * 1.1 * 1.2
as new lines or i replace those newcard lines in there
new
nvm ill try both way
kai
nope, no effect
i mean its fine lol ill just get another card instead of that one with the floating sprite
its not like my life depends on that one sprite resize xd
you can also check aiko's mod
👌
it has the legendary in the title
i see
How do i add talisman compat ?
last question on the vanillaremade faq
Much love
N': "Don't make me tap the sign."
Sign: *is just a mirror reflecting N'*
mmm what's the G.jokers.highlighted equivelent for consumables?
This doesn't work, any idea what I'm doing wrong?
what isnt working
also you should use SMODS.pseudorandom_probability and SMODS.get_probability_vars
so what would that look like?
the other way around
SMODS.pseudorandom_probability(card, 'unnamed'', 1, card.ability.extra.odds)
we love the fact that this is technically outdated (they added a 6th parameter to the function)
main_scoring doeswork with jokers
*doesnt
uhhhh is there a way to make it so the consumable doesn't get deselected when you try to select another one or is that too niche
you need to modify the highlight limit
G.consumeables.config.max_highlighted i think
What should I use then?
i was about to ask what was the easiest way to debuff a playing card with debugplus because i couldnt figure it out how to not mispell G.hand.highlighted[4].debuff = true
i kept doing shit like g.hand.highlighted[4].debuff = true and G.hang.highlighted[4].debuff = true 😭
with debugplus dp.hovered is a way to get the card youre currently hovering over with your mouse
you can also highlight a card and do dp.hovered.debuff = true or use SMODS.debuff_card
^
@red flower Do probability modification effects apply if you don't own a card?
wdym
absolutely goated
thank you <3
If you own the card, I know it applies to the UI, but I suppose it doesn't work if you don't own it
if you hover it in the collection it should work too for example
Mostly because I have a card that would apply to itself if you owned it, but you wouldn't see the modified UI in the collection or shop I assume
ah yeah
Not sure how I want to handle that
Unsure if im being blind or stupid but are there any resources or documentation for starting off making a balatro mod?
https://github.com/Steamodded/smods/wiki there very much is
how do I make a joker effect not work If It's being retriggered by another joker
will this legendary troll joker do anything since it return nil at the end and have no config or a return vars
key = 'nichts',
loc_txt = {
name = 'Nichts',
text = {
''
}
},
atlas = 'Jokers',
rarity = 4,
cost = 12,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
config = {}
loc_vars = function(self, info_queue, card)
return {vars = {}}
end,
calculate = function(self, card, context)
return {
nil
}
end,
}```
and what should the troll text description be for it
also you could leave out config and loc_vars too
but what should the troll text description of the joker be
{100}100 mult (real) (not clickbait)
the only two things is to make sure it cannot apply for egg or rental jokers and only set the sell cost to zero if it has the sticker which is what i was asking here
yup...
ooh i see why this happens
tf does this mean
Take a look at the pinned message in the other channel
i needed a comma
my brain is empty right now is there a way i can have a blind influence data on the cash out screen? i have blinds which give rewards during it and i want those to appear visually at the cash out screen even if the rewards are given mid blind
and not context.retrigger iirc
thanks
Wouldn't it need a special description too?
don't think that's supposed to happen
in which sense are you meaning?
as in the blinds actual desc or a specific section in the cashout
now i get this
should_apply = function(self, card, center, area, bypass_roll)
-- G.GAME.modifiers['enable_'..self.key] and
return not card.ability.rental
end,
key = 'blankjoker',
loc_txt = {
name = 'Nichts',
text = {
'{100} mult (real) (not clickbait)'
}
},
atlas = 'Jokers',
rarity = 4,
cost = 12,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
config = {},
loc_vars = function(self, info_queue, card)
return {vars = {}}
end
}``` this is the code
Cashout
Did you save?
i saved
I've asked this before, but I don't think I ever really got an answer. Is it possible to hotswap an atlas on the fly based on a condition? I have my own deckskin, and I wanna make the atlas for the deckskin swap to a different image if the player currently has the Smeared Joker, because the new image is the deckskin with hearts and diamonds using an averaged color, and spades and clubs using an averaged color
but everything else works looks like it all i have left is to:
- fix this
- make a stake later on which enables it
- make jokers like egg incompatible with duff
yea, i was thinking it would just pull the key of the blind or whatever and then under that just have normal text that says the rewards
in this case i give joker slots, dollars, and perma mult
so itd be like
Blind Name
+x joker slots
+x dollars
+x mult
I think L Corp might swap between vanilla and a modified atlas for bald Jokers. @crisp coral
is there a reason why not card.ability.rental isn't working?
I think if you want custom UI then you'll need to hook or patch stuff regardless
i did look at the vanillaremade and that's what it said for stickers https://github.com/nh6574/VanillaRemade/wiki#how-do-i-get-if-a-card-has-a-specific-editionenhancementsealsticker
yes i saved but how to fix
also I think it might be confusing if it recalls stuff you've already gained without extra context
Is this your only joker?
no i have a few other jokers and they work perfectly fine
You pinged her
Then I have no idea why it's crashing saying the key is missing
im assuming you will also change the sticker pos? or maybe make it so cards that have duff dont ever have rental? rlly cool
Though it was not a reply, so
yea im not sure how to do it for clarity... with the new scoring calculation stuff i could probably just add a new scoring area with the value always there.. idk though
its the latter but clearly i am doing something wrong
It was a reply to you ;P
Should I talk to Hatred specifically or go find her mod and check out the code there?
unless rental and duff together is fine and i can just move duff to the side
oh okay, gl lmao
like would a joker that takes three dollars away but selling it gives you back nothing is balanced or something?
I think it would need some extra text, but also the proximity with the cashout screen might confuse Balatro players
Just because the cashout screen is meant for new winnings not to recapitulate old winnings
well the thing is there isnt really information about what you earned in that blind besides you just see values change
like you see suddenly you ahve more joker slots, you see and hear dollar change, and you just suddenly see when you play hands in the future its more mult, so its specific to the one blind to show you what you won
You said it happens mid-Blind
yes
meaning when you win the blind, the cashout would reflect what youve won
okay another problem
I don't know the name of the mod and it didn't show up in #1209506514763522108 for "lobotomy corp" / "l corp" with or without the space
have no idea why either are happening like i read the docs right?
return not card.ability.rental and sets is joker = true
i was about to say
discord is bad you need to write whole words
Discord's forums search function sucks
same thing with planet and tarot cards
I have no idea what to look for in the code
anyone know the missing parameter decleration key thing
take a look at the images
find the name of the bald atlas
i don't get this i don't get this
where is Card:redeem even called? i see that it gets used in G.FUNCS.use_card, though that isnt ever called on a voucher anywhere from what i see
in apply_to_run
so i set the value to self.ability.Farceur_Duff because of this and but now its not working i think i am going insane
AND I DON'T KNOW HOW TO NOT HAVE IT APPEAR ON CARDS OTHER THAN JOKERS AH
id help you out if i knew how lol
maybe if i make a stake that enables it maybe it solve it
The way that mod does it is by hijacking the set_sprites function, is there a way to detect which deckskin is currently being used and whether it's low contrast or high contrast?
The latter yes
what's your code
Card:apply_to_run is already called inside Card:redeem tho
gimme a moment
the stake works part works
feel free to look at it @red flower but honestly i am running out of ideas to solve it
have you had the idea of looking at the games code
no?
then you didn't run out :3
the thing about applying to everything is because the should apply always returns true when it meets the condition, you need to check for the set and make a pseudorandom call
what was the other problem? the cost not updating?
the cost was updating but i only want it to only do that when you have the sticker but it isn't working anymore
it worked when it was true but that meant every cards even without the sticker has its value set to zero
you need to call set_cost when the sticker is applied
so the self.sell_cost = 0 or function Card:set_cost()
just card:set_cost()
Maybe the rental is applied after your sticker
Would be annoying
it would but ugh
i don't like doing this like i like making up concepts but actually programming it in and just spending several hours debuging isnt fun
but i guess that's part of the deal idk
Sometimes I wonder if I'm weird for liking coding the mods more than playing them
if that is the case how could i make it not do that or at least have my sticker not apply because clearing not
No idea
is the compat_exceptions meant to be what i am supposed to use so only jokers (outside of egg) can have it?
compat_exceptions is for well, exceptions to the compatibility
it would just let you exclude specific cards from getting the sticker
well i mean it would prevent planet and tarot cards and egg from getting it but that won't prevent modded stuff from getting it that can't or won't need it
so it has to be like the other way
but again ugh
me
this is probably why i get no where with this kind of stuff and i am not having fun doing this but i don't like just outsourcing the work to someone else
like i spent a hour or two JUST for this sticker and debugging it
Literally everyone here, honestly, haha
for entire sets youre supposed to use sets
this is a hard skill to teach but the reason i almost never asked a question is because i am good at just reading the code instead
maybe this kind of stuff aint for me
that's probably why i stopped programming as much as i used to as a kid
i don't have the time or energy to waste
Nah you're just all knowing
I've got it working, however, it only actually updates the cards in your hand / deck when the run is reloaded
https://dl.dropboxusercontent.com/scl/fi/s23jufm9gpmn97w0d1v5j/2025-09-01-14-02-37.mp4?rlkey=r9qcp2wzm03unpvsay10xragz&dl=0
like i have a five hour shift in a hour but with everything like ugh
my coworkers say i have really good memory because i remember a lot of stuff about our codebase haha
i do like computers and i am interested by how they work but i guess i am more of a designer than programmer
i hate computers
i mean is it normal for someone to like make the concepts and art and have someone else do the programming or something like a team effort?
but i am not much of an artist either i just feel like a dj khalid
it is normal in the sense that people do it, but many don't have the luxury to have the coder/artist to pair with haha
I'm a game designer but not a game developer, and a worldbuilder but not a writer, I feel your pain
i see
i mean i could just work on concepts and such in my free time and if anyone wants a crack at it idk
This is my code, extremely simple
If Smeared Joker is there, and you're using my deckskin, then it just makes it use the Smeared version
but i mean yeah i think this is something i won't work on i got other things to do
was fun and good luck
I touch my mod once in a blue moon and then work on it for 3 days, periodically working on your mod is pretty normal
You can take a break and tackle the problem later if that works for you
I've been trying to get my thing working for weeks
it's more that i just don't have the time in the long run i have a job, got other hobbies, and school
you can probably force the sprites to update
and i rather spend my free time doing something i can enjoy short and long term
How would I go about doing that?
welp gotta get ready for work by eating dinner and such
idk
Good luck
B r u h
Since you can change card sprites mid-run, try to see how vanilla does that
how can i use set to specify multiple consumable types? like if i want to generate a random consumable thats not just confined to one set how might i do that
you would need to randomly pick between those yourself
so just like generate a random number and have the number determine which it creates
it's easier to use pseudorandom_element
Pseudorandom preferably
why
Imagine you play seeded and each time you restart, the (insert what he's using it for) has different results
But pseudorandom_element keeps the same results
I wasn't saying that to N 😭
It's unclear especially towards a beginner
they posted it just after me give them a break 😭
I mean, that's why I asked for clarification
the key needs to have music in it somewhere
so like "pack_test_music" would work for a music track
Oh
btw spectral set auto ignores soul & black hole and planet set auto ignores locked hands right?
yes
Yeah steamodded doesn’t load sprites on Monday evenings
Try changing your atlas key
And make sure it load before the deck
that makes sense, i load the files first in my main file
How do i have a joker detect if you have another specific joker in hand?
if next(SMODS.find_card('j_modprefix_key'))
try changing the context to press_play
also #G.hand is not correct which doesn't matter here because you want that number to be 0 anyway but it's weird
also on_draw doesn't exist
unless you added it of course
also index doesn't exist lol
and calculate is missing an argument
i will come back in 20 minutes with more
can somoene explain pools to me
they have water and you swim in then
pools are tables of objects, usually to pick from for a random spawning effect
ok but what do i do to make one and how do i use it
say if i wanted to make a pack that contains jokers from x pool
i was going to link to ali's repo lol im going to let them explain
Define an ObjectType. Then either add cards inside of definition or as pools = ['namehere'] = true in definition of a Joker or whatever item.
ah
where would i return that
in create_card
you need the area as well i think
question
create_card = function(self, card)
return SMODS.create_card({ set = 'TOGAJKR', area = G.pack_cards, key_append = 'toga'})
end,
I just use it like so myself.
if i put a card key in the pool that doesnt exist
and it gets spawned by the pack
what happens
does it crash or does it go to default
If the pool doesn't exist, it'll crash on startup when trying to add items iirc?
i think it crashes on startup yeah
It should use the fallback one.
You should probably define the cards in the ObjectType to include those that are for sure to exist, then use pools = for conditionally registered items.
i think it might crash too
I can access it like a table right
I got my smeared joker deckskin swapper working [=
Yeah...
I might do the same with jokers, making the color relevant jokers neutral colored as well
But that might be a little bit too much work, and it'd conflict with mods that replace joker sprites
thats a lot of words
this wont have anything in the cards pools however
you want G.P_CENTER_POOLS.objecttypekey
Where would be the best place in the code to alter the G.deck.cards card order
Where does it shuffle the deck at the beginning of each blind?
I'm creating a custom context here in card.setability so I can alter what type of planet card spawns. How can I make the spawning planet card accessible to a joker in calculate using the custom context?
I have this one enhancement which sends the card to the back of the deck
search for G.deck:shuffle
i have a patch for that part in my mod because i disable shuffling for an effect
"G.deck:shuffle('nr'..G.GAME.round_resets.ante)"
add a , givl_card = self to the context
Thx!
this is a very silly question to ask and im guessing the answer is no but
is there a way to add images to a card description
-# like if i hovered over a joker to see the effect all i get is an image LOL
i think the answer might be yes actually
i don't know even the first step of how you'd go about that, but i feel pretty confident that the answer is not a firm no
hmmmm
Gradients doesn’t work idk why
line 80 is if e.config.ref_table.ref_value == "unfiltered" then
and i dont know why this crashes
val is true e is nil
...for UI, isn't it optimal to have e first like vanilla? And to just prevent crashes, check if e is valid and a table.
i dont know
this would make it not crash but also not function surely
¯_(ツ)_/¯
and i do like my ui to do things
probably not the direct issue, but don't use G.GAME.probabilities.normal in your pseudorandom probability calls. the function handles that already
i don't see anything else overtly wrong, it might be an issue with your context in that case. what happens if you always do the thing without the probability part?
Still does nothing so it's probably not the probability. Here's what I'm doing
Custom context, sets planet card to be a black hole as it spawns
i see
throw a print statement in the calculate to see if the context is running at all
I know it is because it's just adding a custom context to something I was doing before
I had this doing what the joker does, inside the hook, I just added the context as a proxy
oh you know what
you're setting [card].center in the calculate function when you should be setting [card].config.center
Is there any way to get context in update?
What is the goal?
Removed pseudorandom and tested with print statements. This line is running but it's not replacing the card.
I'm trying to make takingtoolong become true after spending too much time idling (it all works I'm just trying to make sure it only happens in a blind)
Yes, you would have to use Card:set_ability
That's what I'm doing. See a few messages up.
G.GAME.blind.in_blind
No, you're directly setting the center.
oh sick thanks!
So it's only possible to change the spawning of a card from inside the hook even if I use a custom context?
No, I'm saying to change the card, you have to use the function Card:set_ability
nevermind
context.givl_card:set_ability('c_black_hole')
I'm replacing it with black hole so it won't loop anyways
Nothing happens
Yes, you need to call the context after the original Card:set_ability runs.
Hey it works
The RNG works too, and the joker is finally copyable
Hello friends, I have two tweaks i'd like to make for a joker of mine
Rayquaza here eats played stone cards, and gains 0.1x mult for every stone card eaten
however, it doesn't show the current mult in the joker's description
i'd like it to show the mult
Okay so like technically
But like my mod uses like. one function from cryptlib at the moment, which exists in Cryptid (which i DO have activated rn)
So it shouldnt cause any problems right
Or would it be better to just have cryptid and cryptlib enabled
so with the new context.money_altered, can I see how much the money was changed by and if it is more or less than the previous money value?
context.amount and checking if it's negative or positive.
The deck forgets itself
if it's positive does that mean it was gained or lost
It means the amount of money has increased.
if im blocking the players screen with an overlay, is there a way i can make it so they cannot select buttons by clicking? ive been blindly clicking things which is not ideal while blind and id like to prevent that
specifically this is in blind
i will need help from someone who knows about LSP
why do these definitions not show up in language server when i try to do stuff with it
Hey so i have a joker that sometimes creates a negative RANDOM joker everytime shop is entered
Why does it say that it spawns SPECIFICALLY a Jimbo with i want the joker created to be random?
Because that's what you're telling it to display.
ok but how do i tell it not to?
remove the part where you're appending to info_queue
in loc_vars
like, you actively put in code that looks something like info_queue[#info_queue+1] = G.P_CENTERS.j_joker, this isn't a default feature that you have to turn off when you're not using it
Hey, y'all. Just messing around with Joker Forge to familiarize myself and experiment. Is there any way for me to obtain this in the site, or would I have better luck trying to code it directly?
Essentially turns each Discard into 2 Hands at the start of a round, then when a hand plays, the joker has XMult equal to the hands left (Kinda like Bunco's Righthook Joker retriggering cards an amount equal to hands remaining)
yo bro great news
so you basically wanna set discardslost to the base discards the player has then minus round discards by the amount of discardslost
make sure duration is this round
then you wanna set addhands to discardslost
then double the value of addhands
then add the hands with the new value of addhands
also make sure that's also the duration of this round
then when you play a hand, set xmult to hands remaining
then multiply mult by the value of xmult
done
Hell yea, thanks. I used to mess with this stuff for Civ VI modding, but it's all left my head 💀
no problem
i swear, i dont know why but jokerforge looks more complicated than doing it by hand
i never used it so ig thats why lmao
I'm a visual learner, so I either gotta think about functions as blocks of code, or literally see them like that
yeah it's like scratch but balatro
people have different preferences
hello chat what causes this
i've been trying to figure out
@daring fern are you available right now
Yes.
alright, so i need some help understanding something
i looked at the globals.lua and i want to grab the value of the music's volume
this is for the name right
if i wanted to grab the vol instead
what do i change
G.SETTINGS.SOUND.music_volume
so i dont need the PROFILES
?
can you explain like, each one of them and what do they do if you can?
Yes.
G is the game, SETTINGS is the settings, SOUND is the sound settings, music_volume is the music volume.
ahhhh okay okay
i see now
which lua is responsible for saving the player's data again
i.e best hand, win streak, etc.
functions/state_events.lua?
thanks
okay so i got into a bit of problem right now
G.PROFILES[G.SETTINGS.profile].high_scores.current_streak.amt
ahhh
right
thanks
nxkoo, pro tip: use console to see value of stuff
you are much better at joker forge than i am lol
small question: how can I check if a card is held in hand at the end of the round?
if context.end_of_round and context.cardarea == G.hand and context.playing_card_end_of_round
aight, thx
Is there a table for cards that are in scoring right now?
context.scoring_hand
But is that a table?
Yes.
hello, i never modded Balatro before, is there some guide i can follow to code? all i wanna do is add few Jokers.
thx
@daring fern about the volume mult thing
it doesnt update like immediately
i think its per instance
what to do with it to make it update in real time
You put it in update
Nevermind, I need a table with all cards, not just the scoring ones
context.full_hand
update = function(self, card, dt)
card.ability.variable = G.SETTINGS.SOUND.music_volume
end
so i put this inside of the Joker?
Yes.
alrighty
like this i presume
Yes, but what is musicvol?
oh its the hook for the music volume
wait a second, if i dont have a config, what do i put in the card ability
Why isn't the variable in the config?
i figured if its local, i put it outside of the joker
Yes, but it should also be a value in the joker.
hmmm
fair
so like
config starts at 0?
Yes.
how to check for a specific group of jokers?
I just started making one joker, just for testing and i can't seem to load it in the game..
i am following a tutorial
Do you have a json file ?
nope
but in the tutorial video, the guy did not had a json file and yet they got their joker in the game!
It should load without it but you need a json file anyways
It’s outdated
Probably outdated
ahh
Metadata is now stored in a json file instead of header
alright, thx
the header works but it's just a lot messier compared to a json
This is a simple joker mod example
omfg it worked
question
how would i make the "select_card" variable on a booster pack vary depending on consumable type?
because if i have the "select_card" in use then i can't have it so that some cards are used immediately
is there a way to make all consumables usable unconditionally
wdym?

Hook Card:can_use_consumeable and return true always.
Also G.FUNCS.can_use_consumeable
No, that calls Card:can_use_consumeable
No, that's in Card:can_use_consumeable
I see, ok
so say for instance
you wanted tarots and planet cards to be used immediately
but you wanted a different consumable type to always be drawn straight to your consumable slots
in the same pack
how would you do that
How do I make a hand not count in a boss blind, like psychic but with different conditions?
how do i get current blind score
uhh, does this actually remove stickers?
if randomeffect == 5 then
print("Effect 5")
local total = 0
for i, v in pairs(SMODS.Sticker.obj_table) do
for i2, v2 in pairs(G.jokers.cards) do
if v2.ability and v2.ability[i] then
total = total + 1
print("Success")
end
end
end
return total,
end
it just counts the sticker it seems?
do you know how to make it so that it removes stickers
Card:remove_sticker(sticker)
This is all stickers?
in your case v2:remove_sticker(sticker) i believe
i dont recommend it because consumables have checks to not crash sometimes
you have to specify
It has to be all stickers though
(Sticker)?
v2:remove_sticker(v) i think?
like this?
if randomeffect == 5 then
print("Effect 5")
local total = 0
for i, v in pairs(SMODS.Sticker.obj_table) do
for i2, v2 in pairs(G.jokers.cards) do
if v2.ability and v2.ability[i] then
v2:remove_sticker(v)
total = total + 1
print("Success")
end
end
end
return total
end
did you check psychic's code
the eye is maybe more useful https://github.com/nh6574/VanillaRemade/blob/7fb17004f6be392a71ff8f4d0de0a3a5d1e9a725/src/blinds.lua#L352
?
Why?
does it matter if their effects can't trigger anyway? Currently the way my code works, whenever a consumable is used it just never does anything regardless so if that's the case it is probably safe to make them usable at all times?
because of reasons you would understand if you read the code for both
is this for your own consumable because the earlier responses made it seem like it was for all of them
Mmhm, the consumable works similarly to Abyss from t. Apollyon if you ever played isaac. When used, the next consumable's effect is cancelled out immediately and instead a "locust joker" is spawned based on which consumable was used.
I actually did read the code for both. The psychic uses debuff = { h_size_ge = 5 } while the eye uses context.debuff and debuff = true in return
oh then if it blocks the use effect it's fine
yeah, thats why the eye is better because it doesnt use a config option
gotcha
I was wondering why that doesn't work for me but uniqueRanks always gets set back to 0, doesn't it?
local ranks = {}
local seen = {}
local uniqueRanks = 0
if context.scoring_hand then
for _, card in ipairs(context.full_hand) do
table.insert(ranks, card:get_id())
if not seen[card:get_id()] then
seen[card:get_id()] = true
uniqueRanks = uniqueRanks + 1
end
end
print("All Cards: ", ranks)
print("-----------------------------------------------------")
print("Unique Ranks: ", uniqueRanks)
print("-----------------------------------------------------")
end
if context.debuff_hand then
if uniqueRanks > self.config.maxRanks then
blind.triggered = true
return {
debuff = true
}
end
end
end```
Damn... Where should I put the local uniqueRanks = 0 instead?
what does uniqueRanks print
The amount of unique ranks selected
try putting the vars outside the calculate
then its weird it doesnt work
In config?
Wait, it's randomly working now. I changed literally nothing and I did save it before testing
yeah as far as i see it it should have worked haha
But why didn't it before TwT
what am i doing wrong?```lua
SMODS.Gradient{
key = "Epileptic",
colours = {
HEX('FF0000'),
HEX('FF7F00'),
HEX('FFFF00'),
HEX('00FF00'),
HEX('00FFFF'),
HEX('0000FF'),
HEX('8B00FF'),
HEX('FF00FF')
},
cycle = 0.1,
interpolation = 'trig',
}
🤷
what are you trying to do and whats not working
you probably set it wrong in the rarity not in the gradient
i think white is the default
is there a easy way to disable all vanilla jokers for a challenge rather than typing out every single id
badge_colour = SMODS.Gradients["busterb_epileptic"]
are you defining the gradient before the rarity
key = "Grandiose",
loc_txt = {
name = "Grandiose",
},
default_weight = 0,
pools = { ["Grandiose"] = true },
-- badge_colour = HEX('f7b4c6'),
badge_colour = SMODS.Gradients["busterb_epileptic"],
get_weight = function(self, weight, object_type)
return weight
end,
}```
banned keys can now have a function so you can loop through the jokers and check if any of them is vanilla
they're in separate lua files
which one loads first
rarities.lua
how would i do this?
then thats the problem
loop though G.P_CENTER_POOLS.Joker and check for if not value.original_mod then table.insert(list, value.key) end and return the list
ok that's too epileptic
hello, about custom decks, how can i change the base hand size ?
have you checked painted deck
Is there a context for taking a card from a booster pack?
actually found a diff idea instead
how can i add text styling to a gui node
manually
theres a function for it but most of the time its easier to do it yourself
i couldnt find what the function was called lol, its loc_parse_string
this should work fine, no?
no, locals are reset between calls
yeah
nice
whats the effect tho
Is there any tutorial on shaders?
ha 
Convert text to parsed variant, and then localize it
:trole:
While first part is relatively easy, actual localizing is problematic
Unless your mod for SMODS of course
🫡
Shader making is the worst part
nooooo
i don't wanna localize
That's what I've heard
wanted to learn anyways
im trying to ban all vannila jokers for a challenge
this doesnt work but it also doesnt crash
1.0.0-beta-0827c
hmm, let me see how this feature works its pretty new
ok, it has to be banned_cards and it actually has to return a table in this format like normal
Not what I was looking for but I like it
so i have to do it manually?
no, the function works
You can make a function that returns that table
but the return has to be in that format
and it has to be banned_cards instead of banned_keys
so how would i do that
im a bit confused
restrictions = {
banned_cards = {
local banned = {}
for k, value in pairs(G.P_CENTER_POOLS.Joker) do
if not value.nimsi then
table.insert(banned, value.key)
end
end
return banned
end,
}
}
you just made a table but with function code inside it
should be banned_cards = function() ... end
banned_cards = (function()
local banned = {}
for k, value in pairs(G.P_CENTER_POOLS.Joker) do
if not value.nimsi then
local temp = { id = value.key }
table.insert(banned, temp)
end
end
return banned
end)(),
banned_cards is supposed to be a table
the way the function works is pretty clever, it runs code that creates a table in place where the function code is
oh i see
that way it can be automated based on a value stored in the joker instead of having to manually write out a fuckton of cards
like this
restrictions = {
banned_cards = function()
local banned = {}
for k, value in pairs(G.P_CENTER_POOLS.Joker) do
if not value.nimsi then
table.insert(banned, {id = value.key})
end
end
return banned
end
}
oh right you can just make banned_cards a function too
yes, if you call it it's not going to work for other modded jokers
how can i hide certain modded hands unless the player play a specific deck ?
how would i target the card that is the view deck button?
visible can now take a function
alright
steamhappy
wait is it G.deck.cards[1]
im pretty sure G.deck.cards[1] is the bottom of the deck iirc
i think the card at the top is G.deck.cards[1]
buh
not the top of the deck but the top of the area
like the one that shows up at the top, not the actual card that is drawn
yeah i need the one that shows up specifically
i have a dumb idea on how i want to display my permanent buffs
its what smods uses to display messages
attempt to call function "cards" (a table value)
okay nvm that's optimal
:3
how can i check the value of a card ability ingame? tried doing an eval dp.hovered but im not seeing anything
blame the telephone device
that should just work?
wouldnt it just be in card.ability
you should do dp.hovered.ability
oh wait yeah mb .ability
if it's nothing then uh you're not hovering anything
thank you 😭
no i meant nothing as in no ability info
mb
why did that freeze my game 
balatro please
deck?
deck
elaborate
changed to the card.ability version since this image but this what its for
idk if it's causing the issue but you should remove deck from where it is in this screenshot
idfk what the other issue is
probably nothing that can be ascertained from what you've given
but then i dont have a card.ability.deck
you don't in the first place
if you really want to you can do like deck = 0
as it is rn it causes a hole in the table
which doesn't do anything necessarily
oh lmao
Hi there! Is there a context for checking if THIS joker was destroyed? In every documentation I've seen there's only checking for selling it or destroying playing cards
Like I'd like to check if this joker was sold OR destroyed and then do something
another joker or itself only?
itself
So should I do
if context.selling_self or context.remove_from_deck then
or simply
if context.remove_from_deck then?
I see
so just write whatever I wanna do in remove_from_deck just like I'd do in calculate?
yeah
anyone know why there are these white pixels on the edge if you have pixel smoothing enabled?
is it just a balatro thing or something on my part?
the atlas doesnt have anything there its just transparent
This may be a stupid question, but to make sure... Does "G.GAME.round_resets.ante" does what it sounds like it does? That is Changes ante to 1? I don't want to reset the whole game or anything. Just go back to 1 with all the jokers and stuff
G.GAME.round_resets.ante stores the current ante
Ooooh ok
So it wasn't that stupid question
Can I just... G.GAME.round_resets.ante = 1?
use ease_ante() instead
just that? just if SOMETHING then ease_ante() end?