#💻・modding-dev
1 messages · Page 372 of 1
oml
since yggdrasil uses patches, heavily
bump
like literally why i paused ijiraq to go to isaac is cause none of the ijiraq patches are doing their damn job 😭 (thank you delirium for helping with those if you're out there)
but i have ONE isaac patch and it works perfectly like i cant win or lose
ref_table is objet read from, ref_value is key to read
So if you display config.name then
{
ref_table = config,
ref_value = "name"
}
Ui will automatically insert and update value
line 777 of overrides.lua (cryptid) makes me crash but like how do i avoid that
what is that line
a
idk, it seems whatever forced_key is, thats not a valid object type for G.P_CENTERS
you're creating a card with the wrong key basically
how do i change the chances on a lucky card?
there's mult and money in G.P_CENTERS, but where are chances?
they're hard coded!?

fuck-
or you can do what i did and accidentally guarantee the 20 mult every time
:3 idk patching seems cleaner
tell that to my 1k line patch file
is it like these fucking things?
yup
ono
how does one make a level DOWN ? I'd like this joker to REDUCE the level instead of raise it
I don't know where I'd find that :<
is there a variable that counts how many cards of a certain enhancement you have in your deck? would be really useful for a joker im making
open balatro.exe with 7zip and open blind.lua
Change true to -1
you will want to code that on your own
run through G.playing_cards, use SMODS.has_enhancement
gotcha
The code used in the source code for the Arm boss:
if G.GAME.hands[handname].level > 1 then
self.triggered = true
if not check then
level_up_hand(self.children.animatedSprite, handname, nil, -1)
self:wiggle()
end
end
hmm, okey, I'll see, hehehe
Should be something like this. The enhancement argument is the key for the enhancement you're checking
function count_enhanced_cards(enhancement)
local count = 0
for k,v in ipairs(G.playing_cards) do
if SMODS.has_enhancement(v, enhancement) then
count = count + 1
end
end
return count
end
how do i add plus mult because for some reason config = { mult = 4 } does not work
you need to return it
what config does is just creating variables for code to read from
they dont do anything on their own
I think it would work automatically with mult_bonus or something similar? But better to return it
e.g.
calculate = function(blabla)
if context.joker_main then
return {
mult = card.ability.extra.mult
}
end
end
p sure you returned xmult in calculate
naw you can set x_mult in config and itll automatically apply
oh, actually?
yeah just like vanilla jokers
oh wow that's totally not confusing
its one of the values copied from the card config table besides extra
maybe its not x_mult id have to test but it def happened w a joker i was working on
hey so does anyone know where would be a good start to making a mod?
hi i'm back :P
i was told to check the extra credit mod for reference on stuff and it's worked out great so far but now something doesn't work
calculate = function(self, card, context)
if context.check_enhancement then
if context.other_card.config.center.key == "m_stone" then
return {m_gold = true}
end
end
end
it's supposed to calculate all stone cards as gold but currently does nothing. am i doing something wrong?
can confirm this auto applies
is this quantum enhancement
yes
if so, its broken as hell rn even if you got the code correct :3
-# which isnt btw
???
i'm pretty new myself, i'd recommend starting w steamodded and lovely
quantum enhancement is currently broken/unstable, p sure
dang
but the steamodded docs can be a bit overwhelming so u can dm me if you need any further advice
idek what a quantum enhancement is and atp im scared to ask
two enhancements on the same card
it basically allows cards to have more than one enhancement
❤️ yeah
No it’s not
i wanted to start working on the jokers for my mod but i have other matters to attend to
i never used quantum enhancements myself so im just basing on what i heard from everyone :p
i think the assumption primarily came from extra credit(?) (the joker that makes it so all cards are lucky cards or smt)
It just crashes if you aren’t careful with your context checks sometimes
ominous to drop this and not elaborate
🔥
you know what mod has fusions that let you select which cards to use directly?
is... is there one?
JoyousSpring :3
hmmmmmm, I guess I'll check it out then maybe, hehehe
i guess you are still in time to turn your mod into a YGO mod 


oh 💀 I get it now, lol
joyous spring is a ygo mod, lmao
yeah
question where does the game set G.P_CENTERS?
game.lua
is there I way I can check out the fusion stuff without all the other stuff 😭 sorry lol asbjhdbfsjb
idek what I'm doing here waaaah dbhfjsbjhsf
lol
if you have debugplus give yourself 3 "Lady's Dragonmaid" (should be in the first collection page)
that should be enough to check how the fusion interface works
ok, I shall see how this works, lol
alright, now where are the descriptions?
the localization files
how would i make a joker like cloud nine which awards money for each card with specific parameters that you have
didnt find anything about it in the wiki
Excuse me but does anyone know how I would do compatability between mods specifically to both make a joker only appear when the mod is active and make the joker use a modded suit
next(SMODS.find_mod("modid")) tells you if a mod is installed
since you used my mod for reference, it actually has something inside it that helps with this, you had a bit in your code as well from what I saw that looks like this?
I did see that when looking through the code
am i doing this right?
i don't think that will be saved in between loads
the games saves some specific keys
you want to put those in extra
self.ability.extra you mean
yes
in the last patch it should be extra.*_chance instead of extra_*_chance
modified it a little bit to try and make it work for enhancements but it's outputting an error :[
yeah i noticed that
thanks again
it doesn't work like that, use
SMODS.has_enhancement(playing_card, "m_gold")
can someone help me creating the sprays of jokers for my mod please?
this is probably more of a lua question but how would i define global variables and tables that can be accessed from any lua script in the mod? can i just do that in my main file?
yeah, just declare the variable normally outside any code block
you mean G.GAME. variables?
here
do i need to do anything extra to use that lovely patch?
destroying a joker is the same as destroying a card, right?
as in they both use return {remove = true}
then why does this not work 😭
it does print the text, but doesn't destroy the joker
no
for jokers do
joker.getting_sliced = true
joker:start_dissolve()
inside the return func?
no, outside
alr thx
do i need anything else to make this work?
wait, it crashed
something about indexing joker (a nil value)
do i have to replace joker with something else?
joker is the card you want to destroy, yes
Unless you literally have a joker variable, yeah you'll need to use the actual variable that has the joker
in this case, self is the right choice i guess
Not if you're in a calculate function
Never use self in calculate
If you want a joker to destroy itself you can use card
(but also I just jumped in so I'm missing context)
(no pun intended)
why?
Because it doesn't refer to what you think it refers to
I think it's the center of the card? But tbh idk what it even represents because I have never needed to use it
ok thanks
A better naming system would probably be (proto, object, context) for calculate functions, I think that’s more clear what things actually are
it's the same as card.config.center
hello, quick question, trying to call a joker hand_drawn although when you have more cards than handsize it doesn't get called at all (the purpose being to draw more cards than handsize), is there another context i can use?
(also dont know why but not blueprintable but if 2 sample of the joker, both activate)
hand_drawn is when a hand is drawn, it doesn't let you draw more cards
you need to manually call draw_card for that
I forgor 💀 I'll try it now lmaoooo
or draw_from_deck_to_hand or whatever that's called
if you want to let you draw cards even if the hand is full you need to patch* this
although i did propose a context for just that :3 you can copy from this
https://github.com/Steamodded/smods/pull/675
N stop carrying balala modding you'll break your back
i need something to do while i dont work on my mod
ohhhh
when context.buying_card, using card refers to the joker reading the context. which object refers to the card bought?
so as a patch? is it blueprintable?
documentation says self apparently, but yeah
wait i think i'm stupid, it says below that the one i want is c1
nevermind
it's not that
Currently attempting to make a deck where my modded Jokers appear more frequently, similar to this, how would I go about doing that?
yes, no
it's not blueprintable because it sets the hand_size to a value but you can probably change the logic to be a modifier instead
context.card
how do i give money when a joker is triggered sob
try card.ability.extra.dollars
Hmm..... I'm trying to replace G.SPLASH_BACK in the middle of the game and for whatever reason it gets a white streak through it?
Like??? why are you white?
I honestly wouldn't mind it if only I knew what caused it
still wants me to close the parenthesis
its a syntax error i just dont rly know where
do you have the Lua extension installed
found it
nevermind :D
middle line trying to index 'card' but its nil (probably has to do with G.GAME.probabilities.normal)
whoops, forgot to destroy the card before copying 
I... am so confused 😭 lmao
idk what's going on w this mod installed, lmao
you name it center in the arguments instead of card
OH makes sense actually
yugioh!
classic cryptid code styling
but yeah, idk if I am smart enough to be able to do anything like this fusion page thing 😭 lol
ok that wasn't it... why does the game call context.buying_card approximately 1200 times after buying and how do i stop it?!?!
(I'd also need changes to it, as the whole "summon" thing kind of works in reverse from what I was wanting, lol, with the joker being found first then being, like, activated? idek what's going on lmaooo)
oo? it is? hmmm :3333
(this is making me wanna make an "api" mod bsajhbfueb)
(if I got the term right, lol)
why does this happen help ;-;
Yu-Gi-Oh! Mod for Balatro. Contribute to nh6574/JoyousSpring development by creating an account on GitHub.
😭 😭 😭
i like formatting my ui like that : (
adhsajknakj that's 14 lines 😭
(I don't know if it's formatting or not that's the issue, my brain's just confused af msakfnshdbj idk anything idk)
this situation is making me say "I don't know" a lot lmao
I feel like ui might be a whole seperate coding type lol, sadbjhbfsj I'm already learning joker code, shader code, now ui code I guess, abnsdhbjhsjhsd
I am headache
why this patch no workie?
there's a nice tutorial in the smods docs
is your patch patching
(is it in the lovely/dumps?)
if it crashes then it should be in the lovely/dump
ooo? where would this be? :3
it's called building ui or something like that
hmm
I... don't think I have the energy for this rn 😭 this ui stuff on top of the other 2 coding styles is 70% of the way towards maddening
whats the "match_indent = true" in patches mean? is it always necessary?
using this code makes the game give way too many copies and idk why. am I doing somehting wrong?
OH NO WAIT
brainstorm is copying the effects i'm so dumb
uh oh
ok so only the paperback partner is loading now i think i messed up somewhere in this file
ok so how do you stop blueprint/brainstorm from copying this?
it says that blueprint_compat is purely cosmetic
not context.blueprint
i think i've totally misunderstood how this works..
pasted your patch but didn't change stuff :c
how do you know if a joker came from a booster pack?
if you return { hand_space = 1 } it should always make you draw a card, unless i did something wrong
oh wait im completely idiotic
i didn't call you context- at all
so ofc it doesn't change
yeah
gripping my head and my hands why is there a white stripe why is this happening I don't understand
did you drop white paint accidentally
i hope notttttt
wait it might end up playing Seven Nation Army if you make more /j
this doesnt seem to show the message , am i doing something wrong?
Okay I figured out why the white stripe happens
what's the correct way to reference a joker by name/key?
color me intrigued (pun intended)
hehehehehe
Basically I copied the code that does the intro screen flash, and it adds a modifier to the return color. The main issue is that it ever slightly doesn't return the modifier completely tozero
I have to figure out how to do the intro screen flash fade out while also eventually receding to the original return color for the shader
that sounds so annoying xd
functions, although i have no idea why but my calculate wont be blueprint despite it working twice if i have my joker twice
if card.ability.extra.flag == 1 and context.hand_space then
card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('k_safe_ex'), colour = G.C.CHIPS})
for i=1, card.ability.extra.draw do
draw_card(G.deck,G.hand, i*100/(card.ability.extra.draw), 'up', true)
end
card.ability.extra.flag = 0
end
(and thank you very much for your patch)
no idea
ah so should swipe the card eval for a return in the same process?
or that might just be for retriggers, I dont remember
you can just put return nil, true at the end
i mean you're setting the flag to 0 immediately after
i did it as a card.ability.extra bcs i wanted to change it on next(poker_hands) although i dont seem to be allowed to call it without before/after stuff
if context.cardarea == G.jokers then
if context.after and next(context.poker_hands['Straight']) and not context.blueprint then
card.ability.extra.flag = 1
end
print(card.ability.extra.flag)
if card.ability.extra.flag == 1 and context.hand_space then
card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('k_safe_ex'), colour = G.C.CHIPS})
for i=1, card.ability.extra.draw do
draw_card(G.deck,G.hand, i*100/(card.ability.extra.draw), 'up', true)
end
card.ability.extra.flag = 0
return nil, true
end
if card.ability.extra.flag == 1 and context.end_of_round then
card.ability.extra.flag = 0
end
end
perhaps is it the area joker?
no it's because you set the flag to 0
ah i should reset it before playing the hand
where do localized messages go in the localization file? do they just go in dictionary?
bad logic from me, sorry for disturbance
How would I use a different mods custom suit
not sure how i can play a sound since it gives me an error
modprefix_key
yeah
thank you
what's the best way to get what chips a played card scored? 
thx
also these messages dont appear when the cards score
i dont really see why
Should've appeared like yahi's mod
But not sure why it doesn't appear like his
anyone know why the cards are permanently stuck at +2 mult?
not working :[ i may be stupid
can you show the full function?
joker_main, individual and after are separate contexts that are not true at the same time
because you're basically setting the value to card.ability.extra.perma_mult*2
oh i see
how can i know if a joker comes from a booster pack?
?
try checking if G.STATE == G.STATES.SMODS_BOOSTER_OPENED in the joker's add_to_deck() function
assuming its checking itself, otherwise im not sure
general order of loc vars' vars are indexed from 1
so
vars = { 1, 3, 4 }
would correspond to for example in the localization as
#1#, #2#, #3#
which would show up in game as
1, 3, 4
basically if it shows nil that means the game cannot find a corresponding value for that index in the returned vars table
and i doubt you have 23 entries on that vars table lmao
just to check does your joker actually have a loc_vars() function in it
yep
config = { extra = { funny_value = 3 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.funny_value } }
end
in localization file: "X#1# Mult"
in game: "X3 Mult"
just remember the index of the thing you want to show
bwoah that is so cool
In playing cards' calculate function, what context is for when this card is removed or about to be removed?
this is so cool??
wait what does it do tho
OH IT CHANGED THE JOKERS?
Not only that
does it drop you in a new random timeline
that is a sick effect holy
Me: Why isn't my enhancment picking up the seal that's on my card???
The Sealless card i'm selecting: 
hey, does anyone know if I can make a joker affect the blind scaling directly?
It specifically sets you back to the ante you purchased the lower level voucher on in a new "timeline" as it were
Least cool @chrome widget Joker
hii, how do i check if i discard for example this hand, only the queens destroy?
Ghfjsjdhdhdhd
thanks Victin
:3
winter that is cool as hell it gives me a sick idea
I was talking about the Consumeables
can i do something similar
how can i make the moeny sign for my joker description?
I mean I imagined it would be relevant for [REDACTED]
you tyoe the dollar sign
not sure about the scaling directly, but you can change a blind's size in round by changing G.GAME.blind.chips, so you could make all blinds 1.5x as big or something
theres also some other stuff with events to make it actually display right too
how do i write pseudorandom logic!!! do i just type a table of values or!!!
just $
that should work for what I'm trying to do, thanks.
heres the code i used to do this
G.GAME.blind.chips = math.floor(G.GAME.blind.chips*<some multiplier>)
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
local chips_UI = G.hand_text_area.blind_chips
G.FUNCS.blind_chip_UI_scale(G.hand_text_area.blind_chips)
G.HUD_blind:recalculate()
chips_UI:juice_up()
if not silent then play_sound('chips2') end
return true end}))```
I assume <some multiplier> you'd replace with the value
yup
can be a config or whatever
dope, I'll give it a shot
how can i make text yellow?
{C:attention}text{}
and orange?
{C:money} is yellow, {C:attention} is orange
C:green
oh lmao
theres also C:mult, C:chips, C:inactive (for grey), and probably more
definitely more
where can i find all of them?
good question
probably in the source code somewhere
idk if its documented
hey so i need some help, I'm making a(n Un)Planet that basically just ups a random hand, but for some reason the code im using is, instead of being normal isn't showing what hand it's upgrading?
Said Code:
use=function (self, card, area)
local leveling_hand = G.handlist[pseudorandom("justspace",1,#G.handlist)]
level_up_hand(card, leveling_hand, nil, 1)
end```
im 50% sure that has to be done manually
text styling on the wiki
ah so indeed
anyone know how i would visually remove the suits
i already have a spritesheet for suitless ranks but idk how i would apply the sprite
How can I score consumables because currently they are only scored when no context is used in calculate?
You'd have to hook or overwrite the drawstep that draws ranks and suits
this is perfect
Also how do I keep consumable data saved between saves
take a look at the code that checks for stone enhancement and hook/patch it to check for your thing too
I think it's in smods/card_draw.lua or something like that
how do i make a card locked behind using multiple consumables
because much like in yo-kai watch, the legendaries in balatro-kai will be locked behind obtaining the medals of specific yo-kai
ok i'm back
this didn't work for the purpose i wanted to (identify whether a joker comes from a pack) bc it only checks if a booster pack is open, which isn't what i want. is there any other alternative?
how would i make it so that the joker always has a poker hand set, even when he isnt present, or it is the start of the run? like to do list
hm
i assume youre trying to check if another joker came from a pack then
i dont think the game actually tracks that
hmmm
what about checking if a joker came from another joker? (e.g. invis copy)
maybe set a variable inside the joker to track this?
i know that is a thing that’s possible
ok but how do you declare a new variable inside a joker
SMODS.add_card({stickers = {"eternal"}})
ohcool
how can i add a specific joker? like egg
SMODS.add_card({key = "j_egg", stickers = {"eternal"}})
take a look at add_card and create_card
thank you
how would i make a joker that changes what hand it requires at the end of the round, even when its not present or it is the start of a run
like to do list
the line that says config = { extra = {} } you can put stuff inside the {} for extra, like extra = { var = 5 }
mod.reset_game_globals(run_start)?
what does this mean in laymans terms?
I'm making my first ever true function here and it's supposed to input 2 numbers and output one
Can you show the code?
you did arch.something but arch is a number
hmm, ok, that makes sense, hmm, guess I can't use the same name for my mod id and for my local, thanks, I'll try this, thank you for telling me this 👍
That should be fine to do... hmm
I'm hoping to get better at code here, and like, truly understand WHY my things aren't working
here's the code, for better analysis
I can also show the function itself if that helps
first off you're defining arch as a global variable. Should definitely be local
ok, that's probably it lol, hehhe
second off you're assigning card.ability.extra.mult to arch, which is a number value and not a table. All you really need to do is remove any '.mult' from all 'arch.mult' usages for it to work
poor spelling/memory strikes again, lmao
I'm so dumb 😭
I didn't mean to put the .mult into the local lmao
ok, thank you lol
that'll do it. doing that change will make it work as well
now i need to add them to the tribes
it's funny, got a crash while making my first ever function and the issue wasn't even related, lol
which are all seperate object types
i know you can add modded jokers to an object type by specifying their key
For future reference, your crash reports should tell you the exact line where the crash is happening
Hey, new to the modding community, is there any resources to write and create mods that work with the balatro mod manager?
To add a mod to BMM you need to fork it and add your own directory
so i think you need the mod key and then the joker key
in this case it would be like
mymodid_j_myjokerkey
Thank you
i'm having some trouble with this :( how do you append stuff into extra?
can you explain in more detail what you're trying to do
I might've missed it
ok
oh my swirls.
j_yokai_snartle
i have a joker that copies another joker when it is purchased. there are two parts to it: from shop and from packs. the copying of jokers from the shop works perfectly, but copying jokers from booster packs is harder because a) the game apparently doesn't track the source of [free] jokers and b) my joker tries to copy every other joker when acquired before dying , so it stack overflows trying to copy the new jokers. and don't even get me started on multiple copies of it (but that is for later and i might have the solution)
how and where should i use this
Is there any way to load a font into Trance without putting the ttf & lua into the Trance/fonts directory? Would like to avoid having to set that up manually if possible
No.
alright, thanks
that sounds super complicated, but what does that have to do with storing a variable in extra?
not necessarily, but some way for me to know the procedence of a joker so that it doesn't try to copy the same joker several times. as it stands now, context.card_added is called for every copy of the copied joker (i.e. get blueprint > new blueprint, function called > new blueprint, function called, new blueprint, ad nauseum) and obviously this is really bad
can't you make it not blueprint compatible
maybe blueprint was a bad example...
blueprint isn't the problem, it's the fact that the joker itself triggers its effect
can you show me the code, it would be easier to get
adding a new joker triggers context.card_added, which makes a new joker and yeah
so something like card.ability.extra.copied_joker = other_joker_variable
yeah kinda
oh i get it
but i'm lua skill issued and idk how to do that ._ .
it's a
honestly what I would do is add copy.copied_by_waiting = true and then you check if the added card has that
that's what i thought
doing it like that will just throw "attempt to call a nil value"
🔥
i tried something similar earlier but maybe i did something wrong
anyways thanks :)
how would i make a joker that changes what hand it requires at the end of the round, even when its not present or it is the start of a run like to do list
maybe using mod.reset_game_globals(run_start) but i have no idea how
very helpful, thank you!
does the game track if a card is queued for deletion?
as in, after you return {remove = true} , can you do like if remove or something
wait i kinda answered my own question didn't i
i dont think it does in an easily accessible way
Kinda
card.ability.getting_sliced
But currently it needs to be put on cards manually
You can use Card.can_calculate(true)
To test for it or other things that would prevent it from being calculated
The boolean controls if you test for debuffs or not
final thing for rumpus cards how do i remove the text that says what suit it is
so it would just be "Jack"
whats the var that goes with context.after for checking how many chips a hand will score?
i don't understand.... you can:
if card.ability.getting_sliced then <do if card is removed>,
or use if card.can_calculate then <do if card is removed> and also works for debuffs
but it needs to be done manually, how?
hand_chips, it's a global
hand_chips * mult if you mean the total
When you remove a card, currently you should also set getting_sliced to true to allow other things to know the card is being destroyed
Card.can_calculate is a method that evaluates to true if the card can be calculated
Card:can_calculate(true) does that but ignores the debuff status of the card
@red flower do you think this should use . or :? Card is the class not an instance but I’m calling the function, so the call needs an instance
a :
anyway vanilla doesn't do any of that for playing cards so i dont think this will help them
What’s the logic? Since there’s still no instance 🤔
But this is for a mod
Most mods use SMODS
you'd always have a card object when you're wanting to use this function anyway
but smods doesn't do this, we talked about it lol
Yes but not in this explanation
SMODS does do it
so I'd just type card:can_calculate(true) when helping people
because people are dumb
But as I said, the variable in the card needs to be assigned manually right now
Card.can_calculate is called for playing cards though
We’ve been over this
but it doesn't check if it's being destroyed because getting_sliced is not set with { remove = true }
that's what the question was
It checks if it’s being destroyed if the effect destroying it was implemented correctly
well the vanilla cards don't
The correct implementation is to manually set getting_sliced
I would imagine that the only mods that do that are ones you've worked on
I also tell people to do it
When I explain it to them
Which is how we ended up in this conversation last time and this time
ok but where do i put it? inside or outside the return?
It’s the same thing with Card.is_rank or the context for removing playing cards
currently inside crashes my game
Vanilla doesn’t handle it automatically so mods need to handle it manually
Put what where
but also, having looked at the code, I don't think it's required at all, and is actually probably detrimental
where does card.ability.getting_sliced go?
and since i'm doing it from a joker i should probably use context.card, no?
what's the effect you want?
set a card for destruction and be able to reference it later
Also my bad there’s no ability
Just card.getting_sliced
playing card or joker or
playing card
the only calc step that adding the flag to cards that are destroyed in sequence would miss is remove_playing_cards, and you could feasibly want effects that happen in that context coming from destroyed cards
i know this is wrong, but how do suit colors?
You set it when you select the card for destruction
so I think adding getting_sliced to playing cards is actually incorrect
i tried referring to the style guide, but its not working
is there a reason why remove_playing_cards doesn't work?
I’m not sure what you mean
{C:hearts} iirc
because i didn't know about it xd
adding getting_sliced would mean the carsd don't calculate themselves in context.remove_playing_cards
basically you're adding the flag too soon
I think that’s an issue with context.remove_playing_cards
Not with the flag
no it's not
doesnt seem like it
it's an issue with adding the flag in the wrong palce
The flag needs to be applied immediately to prevent other effects from trying to calculate with the card
At a time the card wouldn’t exist
the flag should be added in time with when the card is actually destroyed, just not in an event
that's a syntax error
also it should be lowercase
I disagree. The flag needs to be added before the card is destroyed
After the card is destroyed it’s easy to know it’s destroyed
But destruction happens inside Events
So after calculation has happened
Hence it needs to be flagged immediately
no
the destruction events aren't added immediately
there are other calculations that happen between checking for destruction and carrying out destruction
and adding the flag manually bypasses those incorrectly
yep, that did it... i missed the ' at the end of the text lol
thx
I mean if you’re using the automatic SMODS feature to remove cards, I suppose so. But it’s currently not handling that flag automatically
I think that’s just an argument in favor of SMODS needing to handle it
wait i got lost... remove_playing_cards is a function that takes parameters, which ones?, do i have to set the getting_sliced flag or not?, what is the difference between this and using return {removed = true}?
I've never said smods shouldn't handle it
my point is that adding it manually is wrong
I never said you said it shouldn’t
is there a nice and quick way to temporarily disable some played cards while scoring
ignore the getting_sliced thing
context.remove_playing_cards is called when a playing card is getting destroyed
I mean, SMODS doesn’t automatically handle it, so not adding it is also wrong
Maybe it’s not a big issue if you use SMODS’ feature to remove cards
yeah because whoever added the functionality didn't do it properly 🙃
it's like a one line change I think, I can test it now if you have an example of when it would be an issue
I added the functionality I wanted to. Other people edited it. No one raised those issues
I mostly wanted to track destroy effects outside of the automatic one, but the automatic one should be included for consistency
When would I think it’s an issue?
when not having getting_sliced would be an issue
When you create an Event to destroy a card at an arbitrary time
wait that's not it.
i want my joker to delete random playing cards, but multiple copies of it try to destroy the same card twice. so i want a way to check if a card is getting destroyed before setting it for deletion again.
that's not what this conversation was about though
Ah wait actually
What’s the order of operations
Do all Jokers get calculated before setting the destruction?
card destruction always confused me
you can do the same thing as the copy one and just mark them with card.getting_destroyed_by_x or something
Balatro doesn’t have a robust system
ok
they do
@wintry solar this is what I’m trying to avoid too
If you set the flag immediately you can avoid this
does smods ignore anything w/ getting_sliced set when calculating things?
If you wait then you can’t
I think most people would prefer that destroy effects don’t stack
yes
Hence the immediate flag shared by all mods
Instead of different mods using different flags and being incompatible
i dont like that the flag also disables calculations
Check Card.can_calculate
yeah if we're looking for a unique destruction flag it should be something else
There does need to be a flag to disable calculations, but maybe there should be two flags
adding getting_sliced would stop an effect such as "this card gives $3 when it is destroyed" from an enhancments
I agree it’s a logic error, but it could just manually check for debuff and not use Card.can_calculate
I made it a function so mods can add other checks
Like maybe if they move cards around, so cards don’t activate in the wrong zone
huh either guess my things happen to work by accident or I forgot to test my joker with dagger
Vanilla automatically sets the flag
And SMODS automatically checks for it
yeah and my joker's supposed to proc when destroyed
so dagger slicing it might not call its calculate function if im following
dagger and madness are the only ones afaik
If you or @red flower want to propose splitting the flag into two, I suggest responding to the issue I created last time we talked
i make my mod to be standalone to not deal with these things : )
Does it need SMODS
no joyousspring is lovely only
could there be a dedicated context thats called when the card itself is destroyed (even if its getting_sliced)
I think getting_sliced shouldn’t stop effects that respond to destruction from triggering
yeah i think a lot of mods have their own patches for that
But Eremel suggested having two flags
whatd the flag be?
And none of them PRed SMODS
[Mushu shaming Mulan GIF]
I made an issue!
i already pr'd all the things i want to smods
wha can i not do gifs here
getting_sliced is fine on jokers with disabling calculations, it's just on playing cards that it's not clean
not anymore
😔
from PC
It should be consistent across cards
?
So if we want the flags to mean different things, there should be an immediate one and a slightly delayed one
Maybe
Try uploading a GIF directly
is there a reason can_calculate isn't passed the entire context?
I know there’s some way to do it
I asked that in my PR and no one commented on it
whats the usecase for "destroy but later" thats not "this thing needs to do something when destroyed"
I don’t understand your question
you said a flag for delayed destruction
animations mostly
you set getting _sliced before the event and destroy inside the event
how do you make custom functions? this doesnt want to work because JJOK isnt valid
add JJOK = {} at the beginning of the file
So, I was using getting_sliced to stop multiple effects from trying to destroy the same card, but also to stop effects from targeting a card when it wouldn’t exist (because destruction is done in Events)
The former needs to be done immediately
The latter should be done just alongside the destruction Event
hmm
I’m not sure this is the best approach, but it might bridge both goals
I forgor but does destroying a card reallt need to be in an event?
Alternatively you can just have effects that respond to destruction ignore the (unique) flag
😐 🫥
it's weird that there's no helper function for a food joker getting eaten
i wanted to make one for vanillaremade but i thought it would be confusing
How so
they all use the same code
and annoyingly long
hmmm, there are some bugs with this can_calculate check
why isn't there a :start_dissolve equivalent
I mean by that metric I think there’s a lot of weirder things
I think a util function to generally destroy a card might be useful to have too
good thing this is not a contest but a conversation
I don’t know how to reply to that
say im funny
im funny
thank you
Hi dad
this has been mildly amusing to read but i need more help xdd
i agree btw
im funny
how do you trigger something every time a card is destroyed
any card in general?
Take a look at Canio
workshopping
including jokers and stuff?
I think it just needs to be something like SMODS.destroy_card(card) right?
or playing cards specifically
good idea
I have one to destroy one or more cards and automatically calculate effects of Jokers on them
oh it could accept a table too
It should be able to handle a set
i think most people would still use start_dissolve or shatter so as long as those call that
People will reimplement scoring because they didn’t read the wiki
i will make everyone copy my bad code patterns now
you mean people will ask on this channel how to reimplement scoring necauze theh didnt read the wiki
No
I mean people will reimplement scoring because they didn’t read the wiki
I’d rather they ask here first
But they won’t
This is about someone who IIRC implemented a function to poll Editions
oh so you mean people will reimplement scoring because they didnt read the wiki and not people will ask on this channel how to reimplement scoring becaude theh didnt read the wiki
I think it was polling something at least
i mean tbf i take_ownership'ed m_mult to use a calculate function to make it dynamic (although the answer for m_bonus is different because this game's code Sucks)
And it wasn’t even the first time I saw people reimplement existing features because they didn’t read
Though most of the other instances are private
i read the entire wiki before starting my content mod
i read the entire manual before doing anything tbh
When I don’t know how to do something I check the wiki first
I like when people reimplement searching for editionless cards because that util function is buried in completely the wrong place and is entirely undocumented iirc
It’s easier to read the manual when you know it exists
That kind of thing also doesn’t help
I think part of the reason one person reimplemented a lot of stuff is because it’s undocumented
But also
i made the vanilla remade thing to understand how SMODS.blueprint_effect works tbh
hi i have a error with my joker when destroy the cards in the next round the hand bug an looks weird
are you using context.destroy_card?
Are you using the context to remove playing cards?
To be fair not my favorite utility function from SMODS
i used this function to destroy the cards
It overwrites the original color and doesn’t handle multiple Blueprint effects
use context.destroy_card and return { remove = true } instead
I think the first part is minor but it’s personally my bigger issue with it
The latter part is more relevant for a general modding audience
a helper function to combine effects would be very cool
But I can understand it being out of scope
wdym it doesnt handle multiple blueprint effects
It doesn’t nest them in extra for a single return table
@turbid maple another example of people reimplementing stuff
you can also use SMODS.calculate_effect
true..
I’ve struggled to use that before
Though not for a Blueprint-like
But for custom context handling
sorry but where i use the context.destroy_card?
check this example from sixth sense https://github.com/nh6574/VanillaRemade/blob/591b7129f30d2ab2ea4b47782d004294fd94b440/src/jokers.lua#L1442
what is the context for exiting a blind?
cool, thanks
@nova eagle you can do something for the cash out screen
It’s a great modding tool
i like helping
no worries, the card triggers when i want it to with end_of_round
We
N’
I’ve mostly used this trick to reset some values IIRC
IIRC what I did was define a custom calc_dollar_bonus and return nil
We 🐸 chase the cheese @shut crater
im not making a money based joker
im working on a sort of riff raff type joker, where at the end of each blind it creates an egg
I’m aware
incredible
That’s what the nil is for
whys this called reddit jokers
You’re not calculating a dollar bonus
You’re just using it to execute some code at that time
because im making every joker suggestion i get on reddit
i see lots of good ideas there, and wanted to start putting them in game
ah
anyways,,, how come the joker isnt stopping at one joker?
also wow this is cursed i hate it but i will use it
something about not having a repitition count, but riff raff works fine with this code, so im confused
You made it create as many as possible
Wait no
My bad I misread
I should go to sleep
end_of_round is called multiple times add and context.main_eval
As someone who actually reads the utils.lua, i'm ashamed I didn't find it sooner 😔
why are people shooting fireworks
the shop utils should get documented too
All the utils are mine I'll eat all the yummy utils
noooo
what’s up with the French
In fact I shall promote them w my name
where here would i set it to only ever create eggs?
Just pass Egg’s key instead of telling it to create a common joker
SMODS.add_card{
key = "j_egg"
}
i made that addition, and it went back to completely filling all joker slots with eggs
You want to create a single egg right?
well you are calculating jokers_to_create as G.jokers.config.card_limit - (#G.jokers.cards - G.GAME.joker_buffer))
- You don't need jokers_to_create
- G.GAME.joker_buffer should be incremented by 1 only
- You don't need a for loop in your event, just SMODS func and the buffer
which would be a way of finding the maximum number of jokers you could fit in the joker cardarea
if I want to make a joker that that triggers like two jokers (for example, add +4 mult, then add +10 chips in separate messages) how could I do that?
or can I even
sorry but i put the context.destroy_card and the return remove = true and now doesnt enter in the function
return {
mult = 4,
extra = {
chips = 10
}
}
oops don't forget the ,
context.destroy_card and context.pre_discard are not true at the same time
context.discard is however
so how exactly would i implement this?
Oops that wasn't a question mb
so i change the pre_discard to discard no?
probably, i didnt read the whole thing
remove the line that calculates jokers_to_create
only increase G.GAME.joker_buffer by 1
remove the for loop from your event
^
okk thanks!
sweet, that did the trick, thank you!
i'm def doing something wrong here
honestly because I'm not really sure on the different between blueprint_effect and calculate_effect
question - this is going to sound completely pointless, but would it be possible to make the main menu card regularly cycle through random objects instead of picking one or two and sitting on those?
like if you kept sitting on the main menu, it would just endlessly cycle through every card object that isn't a playing card. although i guess i'd like to include face cards in that lineup, too
how do i do this correctly
yea
why i gotta manually do it 😭
excellent question
copying the way vanilla tarots define enhancments doesnt work
i think tarots should have a config to do it automatically
but i didn't check because ive never done it before : )
and this can do multiple cards at once?
Every time I try it just returns one effect
you want to put the returns from SMODS.blueprint_effect into SMODS.calculate_effect
seperately
eremal quick question
?
why doesnt this make my tarot card work
I think you don't return
even if I don't it doesn't work
thats how the vanilla tarot's work
🤷♂️ I don't use vanilla automatic stuff
grah
you don't need the return
Well removing it didn't change anything so :/
crash says it expected <name> near function?
does your second target definitely have a return?
func = function()
I mean I'm just testing joker and cavendish
idk why i didnt catch that earlier tbh, thx
can you show the entire function?
you only blueprint joker2 if joker1 doesnt exist
i got it!
and iirc does this not work on retriggers?
config = {max_highlighted = 2,mod_conv = "m_sgbs_rumpus"}
thats all you need lol
dont need an effect = "enhanced"
just put return nil, true at the end
???
wait what is the effect of your joker?
1 in 4 chance to copy the effect of both adjacent jokers
oh lmao I'm making a joker very simmilar to that, also having problems with it
I'm guessing context.joker_main should be replaced with something else when giving the tag (it currently doesn't give the tag), but what?
calculate = function(self, card, context)
local queens = 0
local twos = 0
local tag = false
if context.cardarea == G.play then
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 2 then twos = twos + 1 end
if context.scoring_hand[i]:get_id() == 12 then queens = queens + 1 end
end
end
if twos > 0 and twos < 2 and queens > 0 and queens < 2 then
tag = true
end
if context.joker_main and tag == true then
return
{
func = function()
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag('tag_ethereal'))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end)
}))
end
}
end
if context.cardarea == G.play and not context.blueprint then
for i = 1, #context.scoring_hand do
if context.destroy_card and tag == true then
if context.scoring_hand[i]:get_id() == 2 and context.destroy_card:get_id() == 2 then
return
{
remove = true
}
end
end
end
end
end
with jokers that return stuff like chips and mult, mine works fine but when it tries to copy effects like sock and buskin, it seems to "retrigger" it instead of copying it lmao
functionally it's fine, it just doesn't look right at all
Yeah it's the same thing just very weird
oh you would need to return it if it's copying repetition effects
not use calc effect
is there a way to check whether a pack wasn't skipped?
And if I do return then I can't do multiple at once
Yeah it would be better to return them, you can just nest extra ones in extra tables
Unless there's something I'm missing
Could I do like a for loop with a return in it?
Or would it just end after it reaches the first effect
it would end in the first return yes
crash says extra here is nil
i have a problem here i use the context.pre_discard to know if a pair of cards is discarded to later destroy them, so when i use context.discard then doesn't checks the pair and destroy all the selected discarted hand
but in the pre_discard doesnt update fine the numbers of card in my deck
i destroy the cards here
Anyone have some insight?
...what about "marking" cards in pre_discard and, when discard is called, do remove = true for the cards?
removed the limit part of it and it's still not working properly
could I have a joker that operates like blueprint get the sell value of the joker it's copying?
if so, how would I do that
let me check
genuinely how do I do this
card.sell_cost
bump
Anyone know why this code doesn't give an ethereal tag? Something with the context? Also, tag does in fact == true.
if context.after and context.cardarea == G.play and tag == true then
return
{
func = function()
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag('tag_ethereal'))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end)
}))
end
}
end
idk whats wrong with this tbh
Pretty sure stickers don't have config or ability the way that cards do
how would you go about making a joker disable a suit like in the boss blinds
(if this is too complex for me ill just make them give 0 chips ig)
fixed it, the major issue is that stickers aren't a card. config still works, but the loc_var requires self.config.extra.limit rather than card.ability.extra.limit
random question but how do i test my vouchers to see if they work
wouldya look at that
nice
is it not possible to add multiple lines to a joker name?
It definitely is.
i tried using the same formatting as descriptions but that didn't work
Wait, I'm thinking description.
did you change the name to a table when doing so?
yeah
Doesn't Kino mess with the "name" to include additional stuff before description?
yes, copied from the one and only joyousspring
yeah that doesn't work
well rats joker that's supposed to proc when destroyed really doesn't work with dagger slicing it
rip
hm
btw instead of {C:black} another thing that works is just closing the previous stylizing with {}
yeah i figured that out late in development
this is an old joker i made that im currently changing
ah
the idea is to have runic text (with a custom font, that im not dealing with right now) be on line one of the name, with an alphabetic translation under it
for the custom font you should wait for aikoyori's smods pr
i dont know of any commands in debugplus that work for this, at least not any that I can see from the help command
you can add it to the shop and buy it
you can probably redeem it with commands but idk how
Or do eval dp.hovered:redeem() when hovering it in collection
the font wont be done for a bit anyways, someone else is helping with that
so chances are it wont be done anyways by the time its merged
bump
im still not quite clear on how to implement this though
remove the cardarea check
calculate = function(self, card, context)
local queens = 0
local twos = 0
local tag = false
if context.cardarea == G.play then
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 2 then twos = twos + 1 end
if context.scoring_hand[i]:get_id() == 12 then queens = queens + 1 end
end
end
if twos > 0 and twos < 2 and queens > 0 and queens < 2 then
tag = true
end
if context.after and context.cardarea == G.play and tag == true then
return
{
func = function()
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag('tag_ethereal'))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end)
}))
end
}
end
if context.cardarea == G.play and not context.blueprint then
for i = 1, #context.scoring_hand do
if context.destroy_card and tag == true then
if context.scoring_hand[i]:get_id() == 2 and context.destroy_card:get_id() == 2 then
return
{
remove = true
}
end
end
end
end
end
generate_ui = function(self, info_queue, card, desc_nodes, specific_vars, full_UI_table)
SMODS.Center.generate_ui(self, info_queue, card, desc_nodes, specific_vars, full_UI_table)
if desc_nodes == full_UI_table.main then
full_UI_table.name = {
{
n = G.UIT.C,
config = { align = "cm", padding = 0.05 },
nodes = {
{
n = G.UIT.R,
config = { align = "cm" },
nodes = full_UI_table.name
},
{
n = G.UIT.R,
config = { align = "cm" },
nodes = {{
n = G.UIT.T,
config = { text = "second line here", colour = G.C.UI.TEXT_LIGHT, scale = (0.4 - 0.004 * #"second line here") } }
}},
}
}
}
end
end
That didn't change anything.
This is a joker?
Yes.
Tag is in fact, not true
Wouldn't tag have to be true for the removal of the card though? Because that still happens.
You set it to false every calculation step, context after will never call a joker with cardarea being g.play
So what should I do then?
any idea why the loc_vars for this voucher ends up giving a table in the description?
Do your check once in context before and save it to the card instead of a local variable
And then you don’t recalculate it dozens of times
something like this ?
calculate = function(self, card, context)
if context.joker_main then
local queens = 0
local twos = 0
local tag = false
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 2 then twos = twos + 1 end
if context.scoring_hand[i]:get_id() == 12 then queens = queens + 1 end
end
if twos > 0 and twos < 2 and queens > 0 and queens < 2 then
tag = true
end
if tag then
card.ability.extra.created_tag = true
return
{
func = function()
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag('tag_ethereal'))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end)
}))
end
}
end
end
if context.destroy_card and context.cardarea == G.play and not context.blueprint and card.ability.extra.created_tag then
if context.destroy_card:get_id() == 2 then
return
{
remove = true
}
end
end
if context.after then
card.ability.extra.created_tag = false
end
end
because extra is a table?
i am so lost 😭
lemme grab a screenshot rq, its showing smth like 0x02571table
where
oh i forgot some {}s here
how would i prevent the ante from going up with a joker?
i.e. when the boss blind is defeated how would i make the ante not go up
it looks like a function that can be put under a joker, am i misunderstanding? when i paste it, it seems like the formatting is off, and i crash when i open the game
hook ease_ante and return nil?
alr how do i call for a custom rarity's weight in a function
is it G.GAME.[prefix_rarity].weight?
tysm!! works great
this will be amazing
just have to wait for that smods pr for the font now
is this a good place to ask wiki page questions or wrong channel
i believe so
for the modded wiki?
yeah im trying to make a table bigger
oh shit real
oh i thought you meant smods wiki
is there a way to make a joker create a joker with a sticker?
something like this #💻・modding-dev message
i have a problem i use the context pre_discard to search pair with the same rank, then i mark then to in a context_discard destroy them, but they dont destroy well
i try some hours and didn't find solution
oh its just assets/fonts
I've been struggling to make this enhancement have a center, so I can't put it into a loc_vars nor convert a card to a vintage card by tarot (the tarot card being named greed). I've admittedly used chatgpt to get the code working due to my lack of prior coding experience, so it may be weird, but the vintage card works correctly ingame. I just can't seem to access it.
Trying to get fonts working ingame, copied the code for handling it from aikoyori's shenanigans temporarily until it's added to smods, but i'm getting an error
bunp
Yo how do I prevent this from triggering for every copy of the joker at the same time
Currently if I have more than one copy that's ready for triggering they all destroy the same consumable
Could I like, put them in queue somehow or smth
does anyone know the event for the little "-$(amount of money)" that appears whenever you spend money?
