#💻・modding-dev
1 messages · Page 320 of 1
jesus wtf was that spelling of mine
if this is the function definition function Card:set_ability(center, initial, delay_sprites) how is this the call cardsetabilityref(self)
regardless, you should probably just use the built-in smods methods of resizing the joker if possible yeah ^
in another hook i did that and it works so uhhhhhhhhhhhhhhhh
i think he's a little big
Absolute unit
big guy
It's been three weeks and I still don't know how this feature works.
At least I know it's not G.P_CENTER_POOLS.Foo.
can you show where? 👀
isfaceref = Card.is_face
function Card:is_face()
local ref = isfaceref(self)
-- blahblah
return ref
end
Thats because it has no inputs.
fair
yeah that's because that's a totally different function signature with no arguments
Also the definition syntax is wrong
instance:method(args) is equivalent to instance.method(instance, args)
bump
I will try and take a look at this tonight but I’m 95% sure you are just doing it wrong

is there a way to check if you have unlocked some deck/stake?
bump
Here's stake's: G.P_STAKES[stake_key].unlock
what about decks?
Found it.
G.P_CENTERS[back_key].unlock
ebin
thanks
weird that decks is just called Backs internally
i mean balatros entire codebase is insane amounts of spaghetti code so not shocking lol
well, it is the card back
calculate = function(self, card, context)
if context.cardarea == G.play and context.individual then
if pseudorandom('instant_replay') < G.GAME.probabilities.normal / card.ability.extra.odds then
return {
message=localize("k_again_ex"),
repititions = card.ability.extra.repititions,
card=card
}
end
end
end
why isn't it repeating properly (chips are not being added)
So I've never worked on a balatro mod, but I'm interested in getting into it, so a quick question: is it possible to replace a card face with an animated sprite, made in aseprite or something similar?
You mean a face card?
In this situation Im intending to alter a spectral card, but I'd assume it's similar for both?
i was trying to convert all the base game balatro cards into json to be used in javascript so i wouldnt need to do it all manually
I'm not sure if malverk supports animated sprites but: https://discord.com/channels/1116389027176787968/1300851004186820690
but after i just decided to use the reddit bot that already did it
bump
Retriggers are at context.repetition not context.individual
You would either have to make the card use an Animated sprite, or do something similar to how cryptid does for pointer and jimball
Cryptid's way is much easier, imo. It can be done patchless
so i should write context.cardarea == G.play and context.repitition?
No, context.repEtition
Awesome, so I'd assume that would involve pointing to a new file, and taking out any references to the old spritesheet. I'd assumed animated sprites are usable, since the fire score anim is a thing, but is it just not easy in base game?
ah shoot sorry yeah
There's 2 sprite classes, Sprite and AnimatedSprite. Which ever one is used, is hard coded. To edit whichever spectral card you want, you would need to take ownership of it, and point it to a new atlas yea
but then, nothing happens..?
did you fix the typo in the return too
how would i make a joker change the values of the glass cards? For example when you have a specific joker mult and odds of glass cards will double
im guessing with a patch?
i need to stop making typos bro
you can take ownership
smods does so you can just copy that code
boo development boo
a
Ok so to do this, you'd wanna check if context.other_card has 'm_stone'
You can do that in a variety of different ways, but the one I'd recommend is via SMODS.has_enhancement, which is a function that takes a card and an enhancement key
/find glass_card
SMODS.has_enhancement(context.other_card, 'm_stone')
get_id usually refers to rank
<@&1133519078540185692> scammer!!
kill this person
Yeah that looks good minus the card = context.other_card bit. You could honestly get rid of it entirely
usually repetitions caused by jokers have messages by the joker itself
also it's spelled "repetition" not "reptition"
oop
Great, thanks! Sorry to ask more, but taking a trawl around the code, it looks like animatedSprite is being included from a larger library? And, forgive my inexperience, the love2d docs don't return anything when I look up animatedSprite. If you know, would you be able to point me towards what library he's pulling from?
Engine/AnimatedSprite.lua
It's in the base game code
how do i pull up the debugplus menu again
Tab
hold tab
Hold alt and press f4
no no he's right
currently no retriggers
Found it! Thank you a ton
any ideas as to why stones arent retriggering?
Your variable is still called "reptitions" lol
motherFUCK
hold alt and press f5, actually
i changed the wrong one
R E P T I T I O N S
hmmmm
did you restart the run
i reset the game like
Oh true
But the run
no, whether you restarted the run
everytime i go to retest a joker i start a new run
👍
That's good, but still weird that it's not working
here hold on
let me uploadf
hi, how do I develop a mod with steammodded instead of just messing with the source code?
Damn barely beat me
I’m working on a mod called Scribble, in which you can make scribbled cards, which are more common, but less powerful
is it a cool concept?
if you want to test
idk why jade doesnt work
scribbled chicot disables of a boss blind after 3 boss blinds
I know I said get rid earlier of it but try adding a card = card to your return table. I truly can't see anything else that'd be wrong
I'm just throwing stuff at the wall here ngl
Bruh 😭
this one seems easy
yeah that's basically just a chain of context.scoring_hand[1]:get_id() checks
I have a huge list of joker concepts if you're wondering
I can see that
how much do rares normally cost
what version of smods do you have lol
Looks like a range of 7 to 10
lemme fix that 😭
3 month old steamodded my beloved
how much does the trio cost?
i wanna learn modding balatro, specifically aiming for a jokers mod for a friend group, where should i start?
can i copy a joker even if it is no longer there?
like this works but if you sell the joker then it no longer copies it
SMODS.Joker{
key = 'bbillyn',
loc_txt = {
['en-us'] = {
name = "Billboard",
text = {
"Copies the last bought Joker",
"Currently: {C:attention}#1#{}"
}
}
},
atlas = 'Jokers',
pos = { x = 3, y = 4 },
config = {
extra = {
copied_key = nil
}
},
rarity = 3,
cost = 12,
blueprint_compat = true,
loc_vars = function(self, info_queue, card)
local name = card.ability.extra.copied_key
return { vars = { name } }
end,
calculate = function(self, card, context)
-- If buying a Joker and it's not Billboard itself
if context.buying_card and context.card ~= card and context.card.ability.set == 'Joker' then
local bought_key = context.card.config.center.key
card.ability.extra.copied_key = bought_key
end
local key = card.ability.extra.copied_key
if not key then return end
-- Find a joker with that key on the board (exclude Billboard itself)
for _, other in ipairs(G.jokers.cards) do
if other ~= card and other.config.center.key == key then
context.blueprint = (context.blueprint and (context.blueprint + 1)) or 1
context.blueprint_card = context.blueprint_card or card
if context.blueprint > #G.jokers.cards + 1 then return end
local result, triggered = other:calculate_joker(context)
if result or triggered then
if not result then result = {} end
result.card = context.blueprint_card or card
result.colour = G.C.GREEN
result.no_callback = true
return result, triggered
end
end
end
end
}
was looking for that thank you
not easily
Oh hey another last bought joker blueprint lol
you need to store a copy of what the card does i think
You could hook sell_card maybe?
i would create a copy of the joker in a hidden cardarea
oh? did you get yours to work?
?
$8
I did yes, and I think even if I sell the card it copies it
Here's the code if you'd like to reference https://github.com/the-Astra/Maximus/blob/main/items/jokers/bootleg.lua
does this work on reload?
oh do you do something else for it to work? i assumed G.GAME.last_bought.card breaks on load
<@&1133519078540185692>
I'm hooking save_run and start_run to repopulate the .card attribute on reload. I actually have two cards that utilize it
oh yeah i think i remember the zombie thing
That's probably still the most in-depth card I've made lol
I’ve been learning too much C i can’t end a sentence without the ;
screwed something up! accidentally made this card trigger on each card instead of if there was a card.
damn
?
You need a and context.scoring_hand[1] == context.other_card
you need to do that in context.joker_main and check context.scoring_hand[1]
I don't think that has to be in joker_main does it?
Hmmm you're right, wording definitely gives that
That sounds like a description rework instead then since they went for individual off rip
Ah lmao
what code
code?
You don't need this anymore actually lol
I was going off of you using context.individual
does this not become consumables cards?
Consumables don't have a blueprint_compat value
also this is kinda technical but you want the general context check before using context.scoring_hand because it doesn't exist in every context
yeah but if you buy a joker then a planet doesnt this do nothing?
No, it would still copy the joker
The stored card doesn't change unless the card being bought is blueprint_compat == true
you need to change other_card for scoring_hand[1]
where?
all of them
yes
oh its a value that you set conditionally, I see
correct
Would blueprint for non-jokers be possible?
It's a lil weird but I think it's more player-friendly since they don't have to worry about buying things that aren't compatible
ok that works
I don't think it would for the use function, but in a case with like observatory and planet cards, maybe???
What about playing cards though?
I’m honestly not sure
playing cards use calculate do they not?
nothing will have blueprint checks though
That’s my line of thought too, but idk how that’d work in a blueprint context
it should work the same
like retriggering
stuff likely isn't designed around it though
so it might need more work
the mod is supposed to be base-game plus so uh... is this too different
Not at all. I have one that does that too and it’s Uncommon LMAO
i think it being legendary might be a bit too small
maybe it should be add a card to both sides?
Both sides?
one to the amount of cards in the pack, one to the amount you can take
one extra card to take, one extra card to see
^
both sides cuz it's left/right on the booster pack description haha
i need it to be legendary so if thats not good enough i need to buff it x3
(the legendaries are all based on important things from vivid/stasis)
I do think that that a version of that effect that's suitably legendary might not feel as base game compatible anymore
Having a ton of pack cards is cool an all but that can backfire pretty easily because of cardarea limits
xchips
hm
none of the other cards do that, but what Xchips amount would be legendary considering
I have a X2 chips card that’s rare so take that how you will
i was joking anyway lol
raghhh
X2 chips as a rare is horrible imo
the Duo:
i was gonna say yea
yeah I guess
how strong is xchips 
should i use the event manager to call stuff like Game:start_run?
Also: does Game:start_run fully initialize the blind info
xchips is roughly equal to xmult
All depends.
i have a charge and swap legendary that flips between xchips and xmult. it's apparently balanced so
#⚙・modding-general message
hmmph
how do you prevent death but continue the same round?
idk how to make this either worth being a legendary or just make some utility joker like this that is a legendary
Try looking at how the normal saved works and try modifying it?
yeah let me see
It's mainly a gimmick anyways since it was made in a vacuum where it's the only one of its kind
I want to iterate trough a List of all Booster Packs, Vouchers, Consumable Cards (Like Tarot, Planet or Spectral) and Jokers...
I thought I'd be cheeky and solve it with this lil' Code-Snippet... But that runs into some problems, so any better Ideas on how to tackle this? :)
is there any documentation of the objects contained in the raw G.GAME object at all?
id like to just read through that rather than having to decipher how the bajillion different fields are used
no
Not really lol
😐
i might be the one documenting this then
for what im working on i need to obtain more or less the entire game state
bump
I guess ease a hand with instant = true?
hmm
i guess i could just do final scoring step on last hand if i cant use end_of_round
Why not just use G.P_CENTERS?
If Card-Sleeves are installed, you pull those from the G.P_CENTERS aswell ^^'
I think the main thing is that we don't have context as to what you're trying to do with this list
then you can check the set
iterate through G.P_CENTER_POOLS.<POOL> for every pool you're interested in
pool names r all caps
iirc
i think theyre not
holy shit this took way too long but here it is (icc profile didn't work because all icc tools are outdated garbage and newer mac screens kinda don't use icc so i had to convert the game shader to a metal shader and put it into a swift app aaaaahhhhhhcsweopscvmwmvgwioerrgwrgweiopjk)
yeah
I like this solution. And to make it even easier, you could do excluding checks (i.e. v.set ~= card_sleeve) instead of including checks (i.e. v.set == joker or etc.)
Basically:
1.) Generate 1 at Random
2.) Have a Pack with any of those as Options
3.) And have a Joker that basically overrides any of those Pools with all of the pools :3
regardless for that initial approach you should do string.sub(key, 1, 2) == "j_"
jimbo:
jimbo in canada:
Not to say that's the proper syntax for the checks, just an example
btw windows users can easily do this with this tool: https://github.com/mausimus/ShaderGlass
i want to poll something: is anyone interested in automated unit testing for balatro mods? i.e. instead of having to repeatedly do the same things in balatro to test your additions, you could write some code that does stuff to the balatro game state and then tests if the results make sense. what i'm working on could feasibly allow this, assuming your mod doesnt do insane things to balatro's codebase
my friend
sorry for the word dump
noooo, see this: https://discord.com/channels/1116389027176787968/1363562105449746452
well we couild both work on this
mine isn't even usable, theres nothing implemented yet
ok so me and @haughty cargo were working on a remoting mod. it uses rust and a tcp socket so you can make remote control interfaces
personally even with my mod having some more complicated mechanics i dont touch them enough to really need to unit test but if it's easy to do then it might be useful anyway
so if we want to collectively pool our efforts into a single project that would be ebin
my holiday just ended so i won't have that much time rn, but feel free to either yank any code from my side (especially the lua socket stuff perhaps? and maybe the state/action philosophy?)
it's all licensed under 0BSD
How can i remove all UI that appears when hovering over a card?
i think cards have a no_ui flag in them but i don't remember the name exactly
i also did this diagram while figuring out states and possible actions: #1349064230825103441 message
i think we might be doing the same thing. we use balatro multiplayers socket. our protocol is roughly trying to model balatro as a finite state machine, so i.e Send(main_menu/action/new_run) will yield Recv(blind_select/info)
it's checked in card:hover
yeah i was afraid to call it finite state machine because i dropped out of school and don't have a single semester of CS under my belt but yeah i guess that's what it's called
Yeah, all of you helped tremendously, Thank you 
lets continue this in dms
aight the other person wrote me
just wondering, how feasible is a joker concept that reverses scoring order? so for all goes right to left. jokers first, then held in hand, then played hand, then base?
someone recently did a joker that makes jokers score first so not impossible
you need to patch the scoring loops i think
sounds like an interesting idea but might be a lot of work lol
oh that's funny observatory would go before jokers
losing my mind
still unsure whats causing this,, im trying to mod for the first time
i need a utility based joker(something that happens like perkeo does) but i cant think of it
this isnt good enough
what would you consider utility, something that doesn't directly make money or contribute to scoring?
the problem is on line 19, i asume that is not in your calculate function
dont really know whats wrong with line 19 either
name = 'yeaboy',
youre missing a comma
np
When making a collab skin you can define additional palettes beyond high and low contrast, but i cant see any way to do this for the default skins of custom suits?
how does one use SMODS.calculate_effect() btw?
for what
I've tried like a dozen different things but I can't get the G.play/scoring_hand check to go through
i think cardarea is not given in before
it's an error in the wiki
or it's bugged or something
like id ideally want to use it for like a blueprint effect or something where a joker copies the effect of a random other joker for a round
that's not what it's for, it's to parse the returns from calculate (and you can use it to return a message outside of calculate or things like that)
there's a helper function for blueprint effects
oh i see
does this helper function require that the player have the other joker in their loadout or no
im pretty sure it does
alright well
the scoring_hand check still doesn't go through
oh weird
wait, I might need to make these not connected ifs
if both conditions can be met at the same time yes
yeah that's what it is then
how do i make the config/calculate for this
(ik config and loc_vars are wrong i copied it)
Yep it all works now
is there any way to define palettes other than lc and hc for a custom suit? i know its possible with deckskins but id like this to be on the default skin
trying to make a joker work like flower pot, but i dont know what an "unexpected symbol" is
add_tag(“iforgetwhatthatkeyis”)
end``` maybe?
dont run code in a return
You can’t return in a return.
So im trying to make it so when youre playing with a certain deck, after every round, theres a 1/[rank] chance of each card in the deck ranking up, how would i do this?
Probably loop through G.playing_cards and get card.base.id I would write it but I’m on phone right now
and how would i check the current deck being used?
whats the voucher tag called 😭
G.GAME.selected_back
tag_voucher is the key
and it returns the key?
Yes, with b_ and with mod prefix
sorry to barge in, but I'm trying to make a mod for the first time and it's not showing up in the list. I followed the example mod in the SModded repo mostly, what's the most likely reason?
question, does card.base.id return a number?
Yes.
Yes.
I don't think it needs a loc_vars or config? right? there's no extra variables that need to be displayed/used/can be tweaked later here, if you were to change it to 2 voucher tags or smth I think it would though?
fair
if G.GAME.selected_back == "b_JCJ_2deck" then
for _, card in pairs(G.playing_cards) do
if not card.base.id == 14 then
number = pseudorandom('deck') -- This just generates a number from 0 to 1
if number <= 1 / card.base.id then
card.base.id = card.base.id + 1
end
end
end
end
would this work?
do you mean I should ask there?
No, you should read the first message.
Did you check if it worked?
i did and i dont think it worked
You should get the lua extension
I don’t think you can just add to the id, try looking at strength
didnt mean to reply
but
idk why it tweaketh so
where would i find that?
I should probably change what program editor I use, which do you guys recommend?
In the source code
For some reason you have two types of quotes here
The lua extension inquires you about these syntax errors
sorry maybe I'm stupid, but do you mean "Remember to download Steamodded and Lovely first." or something else? Other mods work fine, I made a separate copy of Balatro and everything. Mine just doesn't show up in the list in-game
No I meant the whole first message not the first line of the first message
Code?
does anyone here now how to upgrade a card's rank?
probably forgot about a prefix or smthn
Try looking at strength
the source code is too complicated for me 😭
It’s in card.lua just ctrl f strength
Did you get the right Lua extension? Something looks wrong lol
oh i see
Get the one with 1 million downloads
?
vscode
vscode
its tweaking about SMODS rn 😭
if G.GAME.selected_back == "b_JCJ_2deck" then
for _, card in pairs(G.playing_cards) do
if not card.base.id == 14 then
number = pseudorandom('deck') -- This just generates a number from 0 to 1
if number <= (1 / card.base.id) then
local suit_prefix = string.sub(card.base.suit, 1, 1)..'_'
local rank_suffix = card.base.id == 14 and 2 or math.min(card.base.id+1, 14)
if rank_suffix < 10 then rank_suffix = tostring(rank_suffix)
elseif rank_suffix == 10 then rank_suffix = 'T'
elseif rank_suffix == 11 then rank_suffix = 'J'
elseif rank_suffix == 12 then rank_suffix = 'Q'
elseif rank_suffix == 13 then rank_suffix = 'K'
elseif rank_suffix == 14 then rank_suffix = 'A'
end
card:set_base(G.P_CARDS[suit_prefix..rank_suffix])
end
end
end
end
``` i dont think this works
oh wait
im an idiot
but the add_tag errored out
try add_tag(Tag('tag_voucher'))
voucher tags work, jokers dont move at all
wdym
need to give them a message is all
yeah
how would i make something print into debugplus?
print(message)
i dont know what to make it say though
chat it is NOT printing 😭
+1 Tag
message is a placeholder 😭
are you looking in the external console or the ingame debug console
the debugplus mod made by someone else
what
are you referring to debugplus
thats not what i meant 😭
That does not answer my question lmao
That wasn't directed at you 😭
this
what are they trying to do?!?!
so, yes
You need to return {message = “+1 Tag”}
yeah
So nothing is coming up here when you print()?
yeah
Then have you considered the code you're running never actually reaches the line that the print is at

What's the name of the variable for on trigger money effects?
aby ide why this doesnt trigger?
Like on scoring a certain card gain money
And where can I go about learning more stuff like this, like the names of variables I need to use, without needing to look at the example mod or the code of other mods?
@red flower @sturdy compass @daring fern they mean the lovely console.
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:is_face() then first_face = context.scoring_hand[i]; break end
end
you could do this
I’m aware
my confusion is that they were talking about debugplus
thanks
And also the fact that the dbp console is allegedly not showing the prints
my understanding is that the dbp console doesn't output everything that goes to the lovely console
depending on the dbp setting
i forget what the default setting is
yeah thats true but the default should im pretty sure
I definitely didn’t have to change anything for stuff to print 
...i see the confusion now 
any idea why if context.main_scoring and context.cardarea == G.play then
doesnt trigger bc i have logs and they dont show up
Yeah lmao
What are you trying to do
how do i get the current game round?
in generating 4 cards
but none gets generated
and no logs show
how do i check if the card played is an ace of spades? i know to check the played cards rank but is there a way to narrow it down to spades
card:is_suit(“Spades”)
bumop
local is_ace_spades = card.base.suit == 'S' and card.base.rank == 'A'
whould this work?
im asking
card.base.rank doesn’t exist and card.base.suit would be “Spades”
and could you do card.front=="S_A"?
No, it would be if card:get_id() == 14 and card:is_suit(“Spades”) then so it’s compatible with wild cards
If that’s the effect of the deck why did you need to check what deck was being used?
because the round function
i put it into a hook
What?
i had to put it in a hook
so if i didnt do the deck check
it would activate for every deck
You know context.end_of_round exists?
can i use this in jokers too
Yes you can use this in any calculate function
oh my god so peak
thatll make this next joker im making so easy
though how do i check the rarity of a joker
im trying to add my mod to bmm, but for some reason the /archive/refs/heads/main.zip for my repo is a 404? for other repos it gives the source code zip for the latest release so idk why its not working on mine
How would I be able to add my own collab face cards texture with steamodded?
Look into malverk
Thanks! ^^
struggling so hard to word this, need more opinions about it
If played hand has 2 cards
and a spade; destroy all
non-spades, and retrigger all
spades.
how do i check the order of the jokers?
SMODS.Deckskin
two cards and a spade could sound like it needs just two cards and a spade, like 3 cards
your repo uses master instead of main
Ooooo ok! ^^
What do you mean?
like how would i check the order of the jokers you have in your joker bar
What's the context name for skipping a blind and for reaching required score?
You would iterate over G.joker.cards and get its location
context.skip_blind
none for reaching score other than end_of_round
so if it was the second in the bar, it would be G.joker.cards[2]?
skip_blind doesn't work
where and how are you using it
I think I just need to look at how a hypothetical Throwback would be implemented and I can rearrange that into what I need
basically I need something to happen to a scaling value when skipping
and I also need somehting to happen to that scaling value at end of round
if context.skip_blind then
card.ability.extra.value = ...
end
if context.end_of_round and context.main_eval and context.game_over == false then
card.ability.extra.value = ...
end
last question, how do i get the rarity of a joker?
card.config.center.rarity
Can I also return a message in both of these?
yes
ok...
then I don't get how my earlier test didn't work
wait
Does this not go in calculate()?
yes
it does?
yeah
then that is mighty weird how it didn't work with the skip earlier
no idea
Well I'm running the game testing the joker and neither works
how do I factor retriggers into #context.scoring_hand?
can i see the joker code
i dont think you can easily. is there a reason you need to use that over context.individual?
probably not
key = "manualTest",
loc_txt = {
name = "Instruction Manual",
text = {
"At end of round,",
"Gains {C:mult}+Mult{} equal to {C:chips}remaining hands{}",
"Resets if blind is skipped",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)"
}
},
config = {extra = { mult = 0}},
rarity = 2,
atlas = "Jokers",
pos = {x = 3, y = 0},
cost = 4,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult } }
end,
calculate = function(self, card, context)
if context.joker_main and not mult == 0 then
return {
mult_mod = card.ability.extra.mult,
message = "+" .. card.ability.extra.mult,
colour = G.C.MULT
}
end
if context.skip_blind then
card.ability.extra.mult = 0
return {
message = "Reset",
colour = G.C.MULT
}
end
if context.end_of_round and context.main_eval and context.game_over == false then
card.ability.extra.mult = card.ability.extra.mult + G.GAME.current_round.hands_left
return {
message = "Next step!",
colour = G.C.CHIPS
}
end
end
}```
Not at all, and the values don't change
I last updated on sunday
do I really just need to update smods?
nah i just wanted to see if you had a really old one
not mult == 0 isn't correct
I was just gonna delete that anyways and it's not the source of the issue
any idea why this doesnt add the created card to a deck?
does any other context work? like returning a message in joker_main?
The upgrade part somehow works now after updating smods and restarting the run
amazing
And the skip blind too
so im running a chance at the end of each round, but for some reason, it runs once for every single card in my hand
currently trying to decipher how blueprint/brainstorm work
check this
#💻・modding-dev message
is it possible to copy more than one joker at once
and regardless of the jokers position, instead based off its name
currently trying to implement "copies the ability of food jokers"
Maybe use retriggers?
there is definitely a gameplay difference between copy and retrigger though
I've considered nerfing one of my jokers to be copy instead of retrigger
(I just couldn't get it to behave properly)
id rather not because that ignores and not context.blueprint
For some reason my deck skin isn't showing anything for the cards, how could I fix this?
Could you not manually check for that though?
how can i add a created card to the deck?
they* mean for other jokers
pretty sure you should be able to set context.blueprint yourself though
not he/him!!
Yeah I get that, I meant basically what you just said
thankyou
how exactly could this help?
if I understood correctly you're using end_of_round and it's triggering for each card instead of once?
yeah
then use the check i did in that code
I occasionally get this error on startup too,
really basic question but I don't understand what the Smods doc for calculate functions tells me. I understand the context check statements, but I don't understand what the variables below them do. What are they and how do I use them?
my brain is getting so fried, if any1 has documentation on copying/retriggering it would be so appreciated
all the variables are what the context table has inside when the check is true
i know there's SMODS.blueprint_effect but i dont think its documented yet
ouuuuuugh thatd be SO helpful
if theres mods that use it i could certainly peek off of them
is retriggering jokers something i can do in vanilla or does that need to be patched in myself
there are some https://github.com/search?q=SMODS.blueprint_effect&type=code
are context.before and context.individual mutually exclusive?
so they are variables that I can check in that specific context? So for example scoring_name in the relevant context could have the string "Full House" or whatever in it?
Built in if you enable the optional feature
There's an smods api for it
is it possible to make boss blinds skippable
if you add logic to boss blind skipping, maybe
wdym by that
there's no logic for skipping boss blinds because the game never expects you to do so
I remember seeing snippets of conversations about this but, lovely patching another mod like =[SMODS XXX "file.path"] doesnt work on mac, right?
Theres a optional flag with SMODS where you can enable retrigger jokers. Not entirely sure how to implement it
yes
yes
Yes
i hope that's updated soon
Yes
Am doing this right? Trying to have a joker retrigger lucky cards only if theres at least one still held in hand unplayed
what can you pass into the (e) parameter in button fns to make them work?
it cant be nil and its something related to ui elements
local lucky_hand is going to be reset when the context changes so no
either make it a field in card.ability.extra or do a loop on G.hand directly in repetition
Alright, sounds good, thanks a lot!
how will i destroy non-spade cards?
doesnt seem to trigger
the retrigger works fine - destroying doesnt
it needs to be in context.destroy_card
bump
how exactly do i make it work, context.destroy_card == G.play ?
no, it's a separate context
if context.destroy_card and context.cardarea == G.play then
-- check if it's not spades and destroy it
end
bump
what ui element do i pass into functions taking the e argument to avoid a crash
the UIElement of the button im guessing
idk how to find the button lol, its blind select
whats the function?
i made a joker that gives 2 free rerolls if you have $25 or more, but its triggering multiple times as long as i have over $25, does anyone know how to fix it?
unsure if i added it correctly
it should be this, i think you can search it in-game by the id
what function
it's at the top
remove card = self but yes
no how do you find the element by the id
im trying to migrate some hardcoded code into a function for ease of use, what's wrong here?
oh e.UIBox:get_UIE_by_ID('select_blind_button')
seems to work perfectly, thank you!
is it GAME.E or
it's the parent i think
G.blind_select is the main node im pretty sure but idk what's inside exactly
the game uses G.blind_select.UIRoot.children[1].children[1].config.object:get_UIE_by_ID('select_blind_button')
i hate UI
Make and decrement a variable that only resets on a new shop?
But I think that's built in
Idk what is called though
how would i make a consumable/consumable pack only be available when you have a certain deck?
this works G.FUNCS.select_blind({config = {ref_table = G.P_BLINDS[G.GAME.round_resets.blind_choices['Small']]}})
(change small for the type of blind)
In_pool in some capacity I presume
i dont exactly
understand??
looking at what message to have on my joker when it adds mult to itself, and it turns out it's very inconsistent
green joker displays "+1 Mult", Spare Trousers displays a red "Upgraded!" wee displays a yellow "Upgraded", ride the bus displays nothing
is there a way to make the color of the text of card evals a specific color?
like, for example, i would like the bg to be dark_edition and the text to be edition
best to do is red "Upgraded!" usually
that's what I was going to go with but it's odd how it's not consistent
do red or yellow upgraded, whichever one fits the color scheme of your card
if it's chips, blue "Upgraded!", and if it's both or none, yellow "Upgraded!"
what the upgraded
i dont have enough space for 100 so i have to improvise
PEAK
Drawstep
how do i make custom cards using smods?
draw(self, card, layer)?
I don't know how to set that up lol
trying to check if the played hand contains a scored spade card. trying to do it the way superposition does to check if theres a scoring ace. whats causing this?
Bump
Wym cards? Consumables, enhancements, suits?
like normal playing cards
these ones dont have suits
just the respective chip and multiplier upgrades
So like enhancements?
Do you want it programmed as an enhancement?
https://github.com/Steamodded/smods/wiki
In any case check the sidebar here for a lot of info
would it make them separate cards?
Well you can also have them be a custom suitless suit/ rankless rank
what's the rest of the code? you are probably not in the right context
So other enhancements can be applied
bump, then bump again. surely it'll make a splash if i do it just one more time (this is the first bump 💀)
What's this then in SMODS.Seal?
I mean... does it cot work with the c:[whatever] that you use for everything else?
card_eval, not loc
so, like, when a joker scores
you should do that inside both context.repetition and context.destroy_card because context.scoring_hand doesn't always exist
It's a different version of draw step, Draw step is kind of an expanded version of that.
ok. So how do i fix this then?
card instead of self
idk if that check will work never used drawstep for seals
how in the world would i do that here
return {
message = localize({
type = "variable",
key = "a_powmult",
vars = {
number_format(card.ability.extra.ee_mult),
},
}),
ee_mult = card.ability.extra.ee_mult,
colour = G.C.DARK_EDITION,
}
maybe i need to create a "key" that has my attributes?
i don't exactly know how to do that though
the thing is, when youre using the deck these cards will be in, you wont get any enhancements, and/or enhancement-allowing cards, just upgraders, and jokers.
but lemme see if i can do that
Then yeah just making it an enhancement and having the deck set up for it should be fine
The order matters, This is how gold seal does it
alright, i'll try that
oh, now destroy only happens when the non spade is a scoring card too
I'd look at how mods that reimolement xchips choose the color for it maybe?
anyone able to tell me how to combine all my sprites into an atlas
Yes, but that wasn't always the case and some mods iirc still do it themselves
Or they did a couple months ago
could you give me an example?
That page is on the proper Steamodded wiki now, by the way. You can link to https://github.com/Steamodded/smods/wiki/Text-Styling instead
is there a list of contexts documented anywhere i can look at?
things are probably named pretty intuitively but i just dont wanna guess
there are some undocumented ones however
oh
last question, how do i set the starting cards in a deck?
then check full_hand instead of scoring_hand
oh wait no
check cardarea == 'unscored' alongside G.play
https://github.com/Steamodded/smods/wiki/SMODS.Back
Was gonna link this bit geeze the smods deck documentation is lacking
familiar doesn't affect the text of card_evals in xchips sadly...
yeah i already looked at that it does NOT help 😭
Did you figure this out? I can show you what I have once I get my pc on
i don't think it's possible
Did you use the same key?
No, try 2 more than that order, so order 32
im a bit lost right now
so any help with this, the documentation on SMODS.Back isn't helping
how do i check both
(context.cardarea == G.play or context.cardarea == 'unscored')
bump 
Just gonna show the grayscaled template seal i have
oh
You're adding a shader to all seals but yours instead of yours?
I know the issue
the shiny shader modulates itself based on the saturation of the base image
a greyscale seal is going to have a much less noticeable shine than something that's colorful
Your code should look similar to this, though i would use the key instead of the name of the seal
Possibly none of its actually fully grey
otherwise it's going though each seal again
I think there's still something slightly there if it's fully gray, but barely
Also... that's a shitty shader. Makes silver a lot harder than it should be to pull off
Just a side thing, sending the picture makes it difficult for me to put into the program y'know. lol
most likely placed it at the wrong spot
it makes sense, it pulls off a specific effect that was never intended for anything silver
for example, on the gold stake chip, it makes just the gold part shiny
on vouchers, the outlines and stuff not being as reflective retains artwork contrast even when the glare is right on top of it
it is a serious nightmare for my silver stake though, I still need to figure out a workaround for that
yeah remove that unscored part in repetition
also the full_hand thing i said was not correct for your effect i dont think
because right now it's the Grey Stake
i mean it worked when:
higher rank was spade than non spade
spade was equal rank to non spade
but it didnt work when spade was higher rank than non spade
Yeah I see what you mean now about lower saturation = harder to see shiny
ill remove it anyways
oh and the check needs to be in parentheses like i wrote it or it won't work properly
...bump?
works in all cases except when the spade doesnt score, but i guess i can settle on that
thank you for your help
oh then the full_hand thing was correct lol
should I keep this phrased as is to keep in line with acrobat/dusk, or should I change it to "when 0 hands remaining" to make it a little more clear while still kind of being in line with mystic summit?
on the final hand of round, this joker gives 4 mult per hand played
you need two or three things
If its a joker, context.retrigger and a retrigger value in local_vars
I've found this documentation helpful, alongside with the Steamodded example mod for Sock joker!https://github.com/Steamodded/smods/wiki/Calculate-Functions https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua
then a return in the calculate segment
or that lol
or specifically
with 1 hand remaining, this joker gains mult equal to 4*Max hands
I've thought about it, and idk if I really want it to be for every hand played. I'll think of that later, I was just wondering for the phrase "on final hand of round" vs something that could be more clear, but since the game uses this phrasing I think I'm completely fine with this
black deck doesn't need any more nerfs lol
I see you can retrigger jokers but not playing cards. I'm foxed.
no, you can retrigger playing cards
it would just be a consequence of black stake
deck*
how?
try the 2nd link and ctrl+F "sock_and_buskin2": this should show u how to retrigger cards! Just change the is_face() to what u want instead!
^
So I have a weird question: I want to do something like Cryptid where it duplicates the card, but i want it to remove the seal
Is that difficult?
Not really
why specifically the seal?
For reasons
Something like this should work: local card = copy_card(card, nil, nil, G.playing_card) card:set_seal(nil) card:add_to_deck() G.deck.config.card_limit = G.deck.config.card_limit + 1 table.insert(G.playing_cards, card) G.hand:emplace(card) card.states.visible = nil G.E_MANAGER:add_event(Event({ func = function() card:start_materialize() return true end, }))
btw how do you make it one solid code thing
I've got a problem in my code: I'm trying to make it so my joker gains X0.5 mult when a wild card is destroyed, and it works (kind of), but it doesn't register both cards when 2 wild cards are destroyed at once -- it just counts it as 1 card destroyed. Here's my code:
if context.remove_playing_cards then
local wild_cards = 0
for k, val in ipairs(context.removed) do
if val:is_suit() then wild_cards = wild_cards + 1 end
end
if wild_cards > 0 then
card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_mod
return {
message = localize('k_upgrade_ex'),
}
end
elseif context.cardarea == G.jokers and context.joker_main and card.ability.extra.Xmult > 1 then
return{
Xmult_mod = card.ability.extra.Xmult
}
end
end```
I just realized i never set it to check during scoring lol
Caused my game to overflow and almost crash my PC
okay it works now, thanks
hmm
uh
need more context (no pun intended)
how do you make a joker do the shaking thing when its active
juice_card_until
trying to make a seal that stops the card from being destroyed, then removes the seal, and i am making bullshit i think
how do i write the calculate here
What does that even entail 😭
ignore my awful description
basically means beating the hand with a score higher than the requirement increments the joker by 0.5x
🗣️🔥
All fire means is it scores more than the blind requirement
Which is how it's normally phrased
But I see the appeal focusing on the fire ngl
focusing on the fire is cool, wording it is not 😭
Tbh it's the same bullshit I'd have come up with if so, lol
mfw "table index is nil" ???
?
regardless, i dont know what check to do here
oh code?
Oh yeah that's not ideal. Removing seals might be weird because nothing does it in the bese game
@red flower need the code?
OH
you can just set seal to nil
Isn't that what you thought was bullshit? Idk I'm not a modder ngl. I probably shouldn't even run my mouth in this channel
I need to learn though
well before i was using the function set_seal
now im just setting the seal variable directly lol
Ah makes sense
God I wish I kept some working coding knowledge since college
But on the plus side my miniscule python and c++ knowledge is now nuked, so can't interfere Wyeth learning lua
hand_chips * mult > G.GAME.blind.chips (copied from my code on edtions, so there may be some errors)
how would i code a blind that checks for the most common suit in the deck and debuffs it
I'm just waiting.
Find someone else that had the same idea and yoink their code :p
me when godot
G.GAME.current_round.current_hand.chips or something
Specifically Ceres had a pretty similar one
Closest I could find weirdly
Seemed like an obvious idea
what if there is 2 of same amount of different suits?
i don't remember the exact argument but you can dig the game's code
ok i feel like i'm fundamentally misunderstanding context.destroy_card because it's executing the code when i just play a hand with my seal
can i see your seals code?
does anyone know why this doesnt trigger the chips when those ranks are played
remove card = self
how do i take ownership of stuff from the vanilla game
blueprint_compat = true
that is to check if a joker is compatible or not right
i need to run a joker that acts like a blueprint/brainstorm
since the ability of other jokers could run in multiple contexts
what context would a joker like blueprint run in
yea this means it will work with those jokers
you wanna make a joker that has brainstorm or blueprint effect?
they are diff
yeah
calculate = function(self,card,context)
if context.setting_blind then
local jokerList = {}
for i,v in ipairs(G.jokers.cards) do
if v.ability.name ~= 'TenSoon' and v.config.center.blueprint_compat then
jokerList[#jokerList + 1] = v
end
end
if #jokerList > 0 then
card.ability.extra.selectedJoker = pseudorandom_element(jokerList,pseudoseed('tensoon'))
end
end
local other_joker = card.ability.extra.selectedJoker
if other_joker then
context.blueprint = (context.blueprint and (context.blueprint + 1)) or 1
local copy_return = other_joker:calculate_joker(context)
if copy_return then
return other_joker:calculate_joker(context)
end
end
end
i have this so far
but this throws a stackoverflow error since the joker is calculated infinite times
i need it to calculate once and use it in appropriate context
copies a random joker at the start of a blind
its like BP/BS except its not positional
it copies at start of blind and remains constant till end of blind
if v ~= card and v.ability and v.ability.name ~= 'TenSoon' and v.config and v.config.center and v.config.center.blueprint_compat then
table.insert(jokerList, v)
end
first issue i notice
use this
and for the Jokerlist > 0
card.ability.extra = card.ability.extra or {}
card.ability.extra.selectedJoker = pseudorandom_element(jokerList, pseudoseed('tensoon' .. G.GAME.round_resets.blind))
else
card.ability.extra = {}
end
end
whats this
where would i put this
Can someone help me figure out why the foil isnt being scored here? this is in the before context
youre a legend
i did something similar without an event
that would help since events take some time maybe
it worked for my scoring
if context.before and context.scoring_hand and not context.blueprint then
card.ability.extra.flag = true
transform_card(context.scoring_hand[1], 'm_csmr_heightened', card.ability.extra.edition)
return {
message = 'Awakened!',
message_card = context.scoring_hand[1]
}
end
transform card has the following code
function transform_card(old_card, center, edition)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
old_card:flip()
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
if center then
old_card:set_ability(G.P_CENTERS[center])
end
if edition then
old_card:set_edition(edition)
end
play_sound("card1")
old_card:juice_up(0.3, 0.3)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
old_card:flip()
return true
end,
}))
end
no itd be hugely appreciated!!!
God I’m still so down bad for him
.. G.GAME.round_resets.blind)) what purpose does this serve?
tracking blind index
it throws an error
but i removed it and it seems to work
the other issue im running into is
localization of the copied joker
it does the message on the original joker again
oh it might be wrong way of doing but if it works without then shouldnt be nneeded
anyone see why this isnt being loaded in game? doesnt crash but isnt showing up for my collection
can you show your SMODS.ConsumableType?
whats local INSERT_SNACKS?
Snacks :3
Well that’s pretty simple! What effect are you looking for?
This may be stupid but have you added the new one into that list
It’s gonna be that silly little set ability argument :3
Change G.P_CENTERS.m_wild to G.P_CENTERS.m_mult or others.
kinda just all of them, but specifically I'm looking for polychrome
is it basically just m_ followed by the name of the effect?
Polychrome is edition whereas mult is enhancement
Polychrome would be set_edition instead in that case!
So it would be different for polychrome vs mult
ah, that's right
Rather than set ability
thanks :]
Yes. But only for enhancements.
Mhm!
yes
… huh
just name of the consumable
I’ve never thought of gum like that
lol its "close enough"
true
but i rthink it fits the theme of my pack for snack
Valid :3
got the issue too 😝
and your game doesnt crash on launch right? @high sinew
you just dont see it loaded in?
^bubblegum
i got it 🙂
what was the issue?
ah lol
couple more questions about the code in this screenshot:
(for context, I've coded in python, c#, and java. I know how to code for the most part, but I don't know the intricacies of lua yet)
- What does the
localkeyword beforelocal loc_defdo? - what are the
{wildonly = true}and{x=3,y=1}? - I assume the
SMODS.Deck:new{}is instantiating a new deck that this file is deciding to call Wild deck; is the second string"wildDeck"the ID of the deck or something?
thanks in advance
What does the local keyword before local loc_def do?
local variables are only accessible by your code
i thought local is a variable defined within that scope
local variables are only available in the scope you're in
^
