#💻・modding-dev
1 messages · Page 207 of 1
The one that can help me
.
I can give you life advice
this looks even more ass
Can you give me LSP advice
the john balatro himself
hmmph
what do you think LSP is
can you give me advice on how to pay taxes
well in this country it’s mostly automatic
language silencer protocol
@gaunt thistle same exact patch on PC
Silencer?
_ _
give me your log 🦫
It works because it’s the Window not the Apple

🪟 🍎
\
log
are lovely logs supposed to look like that
i don't think so
no lmao
PC
christ why did discord display the wyhole file
Okay, might just give up, this guide is not super for someone who has no idea what they are doing
Ill just uplaod my JPeg and tell people to replace it in thier game files lmao
Where do you see hands
I saw it
🗿
🗿
🗿
are you sure you're fit for coding
🖐️ here
Thats a hand
oh, my bad
no
🖐️ 🖐️
Where did you get two right hands
dont question.
from jimbo
or i will be adding a third one.
@gaunt thistle if you need anything else lmk
add above_hand i guess
info
Me? or aiko
professional help
idk your problem but put your two logs into the lovely channel
I cannot repro because I'm not a fancy Mac users but maybe I can discern something from the 🦫
Anyone
yall how do i check how many cards have been played?
i want to make a joker that triggers only when 5 cards are played
not necessarily scored just played
oops nvm just found it
context.fullhand
#G.play.cards returns a int
i'm trying to find that one github link that has the definitions for each SMODS function for autocomplete but i can't find it, can someone help me and give me that link
thanks!
You can have your text editor provide them to you now
well if you'd be kind to me, can you tell me how on vs code or show me a tutorial to it?
So like
SMODS.Joker {
...
calculate = function(self, card, context)
if #G.play.cards == 5 then
-- Your code
end
end
}
thank you so much!
yeah so
Can youi help me with this
cards don't have a rank
What do they have then?
you should look at the base Xoak hands for reference
Xoak?
(you can just return get_X_same(6, hand, true))
So like this?
please no lmao
why are you checking if it's exactly 6 cards
can i not play another unscored card with it?
My other method wouldnt work
How would it be unscored if its the same as everything else
if I play 5 cards of the same rank and then another card, that's still a 5oak
so why would it be different for a 6oak?
what if i make it worse
Idk, someone told me to make it a PokerHandPart
can you make the text change colour too please, that'd really help the attention being drawn to it
I feel like that would be a bit nauseating
Should i do it?
just double the screenshake while you're at it too
i mean you can make a poker hand part that returns the same get_X_same result
i think thats the point, N'
this but on the crash screen
well let's not forget about accessibility lol
but there's not much of a point unless you reuse it elsewhere
crash screen should have solitaire cards bouncing around
YES
with hall of mirrors
this is better because it grabs the user's attention
surprisingly still readable
looks christmas theme
yeah the reds are fully out of phase with each other
add siren
I know this is really basic, but how do I go about spawning in a joker with debugplus?
How would i use it in the six of a kind? Like the poker hand. (Yes, i will reuse it)
hover it in the collection and press 3
press 3 on the collection
thanks
merry christmas everyone
bro really brought up the on-touch keyboard 😭
SMODS.PokerHandPart {
key = '6'
func = function(hand) return get_X_same(6, hand, true) end
}
then return parts.yourmodprefix_6 in the poker hand eval
Thankies
does get straight support arbitrary number of cards in a row
meh how do i do that
and multiple sets
shaders?
you mentioned something about quantum enhancements
if they're on separate ranks, yes
i think make the sprites global and you can put them in an update func
if they are on the same rank i guess god help me
i don't feel like just animating the sprite
Is there an easy way to create a straight? Kinda like the get_X_same() function of ... of a kind?
get_straight
So get_straight(6)?
get_straight(hand, min_length, skip, wrap)
Whats skip and wrap?
skip is shortcut
wrap is.. well, wraparound straights
both are bools and can be omitted
rq, what do i return here to get money again
doll_hairs uhh dollars
doll_hairs, got it
Do i need the steammodded header in ever file in my mod?
no
actually you don't need it ever
What about the mod prefix?
okay need someone to explain to me how can i exactly access context.post_trigger's other_ret
so far this is how i'm trying to access it but i do think that i'm doing it completely wrong, as the only other reference i can find is being inside eval_card function
Uhh, how do i include another file?
Like i have main.lua and pokerHands. Pokerhands.lua isn't included and "Run"
you can load it yourself from the main file with something like
assert(SMODS.load_file("path/to/file.lua"))()
yeah that
lua is case sensitive
I forgot
Hi guys, for some reason this card is apply xMult to each card when it is scored.
It's actually supposed to look at the hand when the hand is played, then when the joker itself is scored, apply the xMult if it matches the condition
Do you see what I am doing wrong here?
if context.cardarea == G.jokers and context.full_hand and not context.before then
--blah
end
yes, you need to restrict it to a context
you want to check if context.joker_main is true in your case
you're just checking what context you're not in (context.before), not which one you actually are in
ahh, thanks folks 🙂
it respects reduced motion now
what is your smods version
yeah there's your issue
One of my family members was getting dizzy from the intro screen before, that's good to know that the accessibility stuff works
the new get_straight wasn't merged until <2 days ago
I can test this if no one knows offhan, but I was wondering if it is normal for a blueprint to trigger an upgrade for a joker?
For instance when runner is played with a blueprint, would the runner card upgrade two times, or would instead the blueprint just play the earned upgrade on the runner?
the game setting is there, least i can do is respect it
(i take accessibility quite seriously, i literally made a screenreader mod)
huh did I just break something
yes
Thunk uses Color?
Revert it so i can git pull xD
this is usually explicitly excluded
nah
bruh
When i press play
oh
same
I have started probably cuz of the smods version popup thing
I'll try deleting the saved run
nope i can't repro at all
this fixed it
and yes i have an outdated run
hihi! Teardrop has a bug where playing a Gold Seal will cause the money part of her ability to give $9, instead of $6
code:
if context.joker_main then
local outcome = {}
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
outcome.chips = card.ability.extra.given_chips
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
outcome.mult = card.ability.extra.given_mult
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
outcome.x_mult = card.ability.extra.given_xmult
end
if pseudorandom('teardrop') < G.GAME.probabilities.normal / card.ability.extra.odds then
ease_dollars(card.ability.extra.given_money)
G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.given_money
outcome.dollars = G.GAME.dollar_buffer
G.E_MANAGER:add_event(Event({func = (function() G.GAME.dollar_buffer = 0; return true end)}))
end
return outcome
end```
i can't see why, though. ideas?
From which version??
you don't need to use dollar_buffer, just returning the dollars suffices
im pretty sure you only need to use ease_dollars
0301f
How do you delete the saved run
Is there an uniform way I can check if a card isn't real? (for ex. preview in the view deck menu/poker hand menu preview)
will try that, thanks :D
That is either later or newer then me...
it's the version right before this commit
I had 301f too
I accounted for older version not having th version info yet and that shouldn't mess with any colors
in roaming/balatro there are folders numbered depending on your profiles, delete save.jkr
tbh I don't see where this is coming from at all
do you want the log or the save?
yes
didn't work :(
maybe check card.added_to_deck? (possibly also card.ability.joker_added_to_deck_but_debuffed too, not sure if that's needed)
oh no wait two seconds, i see what i did wrong
Will try, but I think it's still gonna consider the view deck menu cards as still added to deck
Tell me/us if you can reproduce it.
I tried that and it doesn't seem like actual cards have that
ahhh, huh
I was thinking this was way too strong
I'm away from my PC rn, I'll check later
Bruh
just delete the save
Also if you’re a part of steammodded I opened an issue about the links in the wiki, I think their order is swapped which causes a startup problem
"bruh" I was about to have dinner and I already wasn't able to repro
What do you think would be a safe way to destroy Consumeables during scoring calculation
You should be able to destroy consumables by just calling start dissolve on them just fine
Same with jokers
I already replied
But it's not safe because they can apply effects
Like Observatory
Or Baseball Card applying effects on other Jokers
or even a Joker applying an effect on itself, but in an Event
Have you tried?
If anything else is trying to access a card without checking nil in an event then it's on them imo
No, but I'm also trying to code the effect to not cause its issue with itself
In case you repeat it somehow
Or even just have two copies thanks to Invisible
So part of the questioning is how I should write it
If SMODS already handles their part somehow, that's good
this is what I have at the moment
“How do I do this?” “Try it like this” “I don’t think that’ll work” okay
That's not what's happening
destroy_cards calls start_dissolve
and by your account, I don't need to worry about SMODS
good morning everyone
now I'm wondering if my own code makes sense
the candidate.debuff = true part seems unnecessary based on what you said
But I'm trying to understand how
Are you like, allergic to getting crashes or something? Why must your code be perfect every time? Just try stuff and if it doesn’t work it doesn’t work
i suggest reading this, and the one above
I don't understand what's the issue with me trying to figure out how to make it work without needing to see it crash first
mods in here should give you the general idea of how to get stuff work
STEAMODDED 1.0.0
A tutorial on how to make a modded Joker.
https://github.com/art-muncher/Example-Mod -- EXAMPLE MOD
https://github.com/Steamopollys/Steamodded -- STEAMODDED
https://github.com/WilsontheWolf/DebugPlus -- DEBUGPLUS
-----------------------------------------------------...
outdated tutorial, but still good in telling you what to do
alright
This isn't even the first version of the Joker. The first version didn't do anything because it tried to use a context combination that didn't exist
is there any way to tell in a can_use function whether you're in a round? like round vs shop vs blind selection etc
i think you can use context for that
can_use doesn't have a context
yeah
you can check the state with G.STATE == G.STATES.BLIND_SELECT Or smt
hold on let me try that
all the states are in globals.lua probably
G.GAME.blind.in_blind tells you if you're in a blind
why is splash a state
DO NOT CHANGE
Splash screen
DO NOT CHANGE 🗣️
DO NOT CHANGE
This version works. Now to try without messing with debuff
is there a template joker sprite i could use?
By the way, does anyone know if NFS.load(SMODS.current_mod.path .. "etc")() works in Lovely patches?
I feel like SMODS.current_mod would be wrong by the time the patched code runs
there are some here (plus an extension for it if you use aseprite) https://github.com/balamod/aseprite-balamod-extension
SMODS.Mods.<your_mod_id>.path
you can also pass the mod id to SMODS.load_file iirc
Ok, if I don't mess with debuff, it doesn't crash, but it doesn't work as intended either
I guess it would also not work if you created Consumeables mid-round
Hold on. If I return func = … I might be able to make everything happen instantaneously, except I might need to manipulate the score directly
shouldn't afaik
What's the SMODS function to evaluate effects nowadays?
Just to be sure, this will make it so it says X2 blind size?
SMODS.Joker {
key = 'Malformed',
loc_txt = {
name = 'Malformed',
text = {
"A being of suffering. It shares it's pain with you.",
"{C:red}X#1#{} Blind size, "
}
},
config = { extra = { worth = 2 } },
Hiii, does anyone know if you can use blindexpander to summon a random blind rather than a specific one somehow? I'm trying to modify the small blind so that it changes to a random blind from a pool once you start it (which I also have to figure out how to instantly win the blind to summon the next one but that's a separate issue)
ohh right
Based on what I asked Myst recently, no
you can use debug plus for this one
.
oh wait nvm
its random blind
I think this should be it
SMODS.Joker {
key = 'Malformed',
loc_txt = {
name = 'Malformed',
text = {
"A being of suffering. It shares it's pain with you.",
"{C:red}X#1#{} Blind size, "
}
},
config = { BlindSize = { Size = 2} },
loc_vars = function(self, info_queue, card)
return { vars = { card.ablity.BlindSize.Size } }
end,
That's okay haha
kinda
is it the BlindSize
yes, use extra
should it be called Extra
BlindSize should be named extra so it's properly saved
okay
extra not Extra
Hmmm okay, it'll probably require something more complicated then huh
config = { extra = { BlindSize = 2 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.BlindSize } }
end,
I spent last night figuring out how to make stuff like jokers and blinds, but I don't really know how to just make functions that do stuff yet so
wait, can you change how much Ante's scaling amount mid game? with a joker too maybe
how so, do you want to just multiply the base blind size like plasma deck?
like how green stake makes the score amount higher per blind
you can change G.GAME.modifiers.scaling
thank you
is the plural version of ante Antes or anties, neither of them look right to me lol.
Antes scale {}{X:mult,C:white}X#1#{} {C:dark_edition}faster
You can write it as "Each Ante scales" if you don't like it
thank you
Well that isn't quite the scaling that this modifier does
It's more of a "Required score scales faster for each Ante"
if it's just a multiplier like plasma deck, that's X blind size
oh
how do i add a joker that removes stone cards?
when running, is this needed every ante or just once?
G.GAME.modifiers.scaling
and also, i know in cryptid, the cube is always Eternal, how can i also do that
just once. but if you're looking to directly multiply required blind score there's another param used by e.g. plasma deck
idr off the top of my head what it's called though
i know im asking a lot of questions but how are ablities defined and how are they diffrent from making the loc_vars
Does anyone have an example of doing a 'Credits' tag in loc_vars? I have seen it done before but I forget where. I was trying to place it here
I tried adding a custom consumable within the info_queue of a Joker.
It seems to recognize the Name of the consumable but the Text is empty.
General not possible or does it need some extra steps?
That's a popup via info_queue[#info_queue + 1] = ... bit.
basically the ability table is initialized when a card changes center (card prototype, e.g. joker, enhancement) and includes its config values among other things. See Card:set_ability for how exactly that happens
loc_vars then uses those ability values to pass variables to the description
this isnt working for me for some reason (crash on startup)
generally you do that like info_queue[#info_queue+1] = G.P_CENTERS.c_modprefix_key
Can anyone else that understands Event timing help me here? I think the only missing piece is timing SMODS.calculate_effect
where would i put Card:set_ability, and i hate to ask, is there a wiki page for Card
oh here it is
I just mean you should look at the code for it
we can't document the entire base game haha
fair, i thought it was an Smods thing tbh
and tbh i forgot i can just look at the games code
you don't need assets/1x in your file path, smods adds it automatically
Wow this is weird! I am calling 'card_eval_text' forone of my jokers and the animation plays under the score?
This is how I'm calling it
card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
looking through the code, it seems i call for self.ablity.name = 'Name here lol'
the sprite isnt showing
( if you need the sprite itself here it is
what is it you need?
im looking to make the abilty as i saw that cryptid needs the ablity name to set the card etenral
replace self with card. But there is no need to call card_eval_status_text manually like ever
Why not return the message?
oh right
using names is discouraged
eternal, not negative, mb
Why am I doing it this way? well...I am often asking myself that question 😄
Ermel, would you recommend I instead just do return{message="Upgrade} or something along those lines
Yes
you should use keys, like card.config.center.key == 'j_modprefix_key'
i always find my self somehow always doing the defunked way of doing it lol
Well, localize(“k_upgrade_ex”) is the localised upgrade message iirc
WAIT OH MY GOD I THINK I KNOW WHY MY JOKER ISNT SHOWING
do you need the .png in the path?
yes
is the wiki for SMODs, i see set_ability, but when i put it into VSC with it hooked up with smod, it just doesnt see it as a thing
i had it as a capital J before
i need this mod
oh, its self.set_ability
thank youuu
Is there a list of currently owned vouchers that I can iterate through, or a list of every voucher?
i tried to make the atlas all lower case and it gave me this when i went to the joker
Thanks for the advize, Eremel (fellow fox fan!)
I tried this code and am not getting a message sadly
if is_palindrome then
card.ability.needToReview = false
if not context.blueprint_card then
-- card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
card.ability.extra = card.ability.extra + card.ability.extraGrowthRate
sendInfoMessage("Palindrome detected and original, upgrading! Earned extra now: " .. card.ability.extra, "TacoCatPalindromeJoker")
return {
message = localize('k_upgrade_ex'),
card = card,
colour = G.C.CHIPS
}
I do see the log message but don't see an Upgrade prompt appearing
it works noww!!!
G.GAME.used_vouchers ig?
Are you using a jank ass smods build
Im getting a crash when i try to make it eternal, im not sure how to fix it
SMODS.Joker {
key = 'Malformed',
loc_txt = {
name = '{C:dark_edition}Malformed{}',
text = {
"{C:dark_edition}A being of suffering. It shares its pain with you.{}",
"{X:mult,C:white}X#1#{} {C:dark_edition}Blind Size{}",
"{C:dark_edition}gains {}{X:mult,C:white}X#2#{}{C:dark_edition} mult per Boss Blind beaten{}",
"{C:inactive}(Currently {X:mult,C:white}X#3#{C:inactive} Mult)"
}
},
config = { extra = { BlindSize = 2, ScalingAmount = .5, AntesBeaten = 1} },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.BlindSize, card.ability.extra.ScalingAmount, card.ability.extra.AntesBeaten } }
end,
rarity = 3,
atlas = 'JokerSheet',
pos = { x = 0, y = 1 },
cost = 5,
calculate = function(self, card, context)
card.set_eternal(true)
end
}
crash log ^
Revised question: how do i get the actual voucher object from its key, used_vouchers just contains key bool pairs
alright so it let me buy the joker, but when i went into a blind it crashed and gave me this
What do you want to do with the Voucher
G.P_CENTERS[key] ?
create a calculate_dollar_bonus in the voucher, and then call it
Why do you want to create it mid-run?
card.ability.extra.AlwaysEternal instead of card.ability.AlwaysEternal?
I meant have that function in the actual voucher so vouchers can add bonus dollars during money calculation at round-evaluation
Can’t you create it at the start of the game?
I do, i just need to call the function during that period
yea, that worked, thanks
So you don’t want to create the function, it’s already there
but now i want to see if im able to make it eternal in the collection
You can use set_ability to make it Eternal
Whenever the card is created anywhere
how do i check if its created anywhere
You don’t need to check
so just remove if card.ability.extra.AlwaysEternal then
I’d look at how SMODS calculates Vouchers then see how to extend the end of round calculation to them
No
You have to use set_ability
Check the wiki
I'm using the newest steammodded
Weirld if I add 'upgrade=true', then the text does appear, but it appears over the first scored card, and not under the joker itself
like this?
set_ablity = function(self, card)
card:set_eternal(true)
end
Probably yes
it doesnt work but it also doesnt crash
Check the wiki to see what’s the utility function for applying Stickers
yea, i honestly cant find anything
i could only find this in cryptid
card:set_eternal(true)
end```
It’s in SMODS.Sticker in the wiki IIRC
fixed it.. i mispelt ability
{C:orange(or attention i forgot)}text goes here{} // these colors may or may not work as i am not sure
Attention
but what i am sure about is that the text in the area will be colored
Can you screenshot the full code?
how do i get the current played hand and type
oh phuck i see what happened to the warning
i forgot that git commit -a doesn't stage new files
rip
how do i check for how many stone cards in deck
You can do card:add_sticker(“eternal”, true) to force eternal sticker
I made some cool stickers
there's no way to have something like https://github.com/Steamodded/smods/archive/refs/tags/1.0.0-beta-0301a.zip but have it dynamically point to the latest release, right? it seems to only exist for additional assets uploaded to the release
I thought you could get a “latest release” link, isn’t that what the mod manager uses?
is this ran when ever a boss blind is beaten, i see that Campfire does it and i know campfire resets every ante
if G.GAME.blind.boss then
BossesBeaten = BossesBeaten + 1
end
Where are you putting this code
calculate = function(self, card, context)
if context.joker_main then
return{
xmult = (BossesBeaten * card.ability.extra.ScalingAmount
}
end
if G.GAME.blind.boss then
BossesBeaten = BossesBeaten + 1
end
end
end,
im working on xmult rn so ignore that
sorry for asking again, but is it possible to get the current specific hand type (as in not pair if 3oak was scored), and the current played had?
methinks it uses the api for that?
okay, ive gotten this"
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.BlindSize, card.ability.extra.ScalingAmount, card.ability.extra.BossesBeaten, card.ability.extra.AlwaysEternal } }
end,
rarity = 3,
atlas = 'JokerSheet',
pos = { x = 0, y = 1 },
cost = 5,
calculate = function(self, card, context)
if context.joker_main then
return{
xmult = (card.ability.extra.BossesBeaten * card.ability.extra.ScalingAmount)
}
end
if G.GAME.blind.boss then
card.ability.extra.BossesBeaten = card.ability.extra.BossesBeaten + 1
end
im getting a crash log
im not sure how to make it so it applies an extra .5 xmult every ante
Unfortunately not with GitHub, even the support for releases/latest was a surprise that happened because a GH dev stumbled into a StackOverflow question and implemented it in an afternoon. You might be able to use a custom URL redirect/shortening service though?
Oh for a download link
Or attach a .zip named "latest" or "smods" and use /releases/latest/download/asset-name.zip
^ probably the best solution
But not with source alone
You could build a custom GH Action to package the repo, strip out the .git files, zip and attach it to a release automatically
yeah this is probably what I'll end up doing. I don't quite like the inconsistency of having the release link take an extra step over the dev version's
Oh goody more Saturn crash reports
I am so sorry for being incessant, but I'm not sure how to get the entire played hand and which exact hand has been scored in the joker context
context.full_hand is the entire set of played cards, context.scoring_name is the played hand type
ah, thanks!
would I do context.scoring_name == "High Card" to check if the hand is a HC?
yes
ok thanks
how do you add an enhancement to a card
do i just copy from midas mask
That's how I learned 🙂
do card:set_ability('key of enhancement')
is there any way to update the rank of a card?
strength tarot.
strength tarot looks really poorly implemented
there has to be a better way
which version of the strength tarot are you looking at?
steamodded changes its on-use code
I guys, I have an event that turns my jokers card.ability.ready value from false to true
When ready is true, I would like the card to jiggle so the player knows whats going to happen
Does anyone have a good idea of how to use the juice_until function?
the second argument to juice_card_until has to be a function that returns true as long as you want the card to animate
kinda counterintuitive with the name
Something along the lines of
local eval = function()
return card.ability.ready and not G.RESET_JIGGLES
end
juice_card_until(card, eval, true)
yeah the function should probably be named juice_card_while
i still need help with this
Something like this?
@paper zealot
eval won't be called with any arguments so i think you'll want eval = function()
i do not believe this to be the case
no it is not
But i don't have the game code handy to double check
Ever get Deja Vu?
then you are wrong. https://github.com/Steamodded/smods/blob/26d20fe5dfeee60313a5ca928a7fe9d990d08822/src/game_object.lua#L2045
oh i was looking at the lovely dump that time
It's literally John smods
ah ok so its SMODS.change_base
Whoops, just checked the game code, I was wrong - eval is called with card as the argument, so that should be correct
function juice_card_until(card, eval_func, first, delay)
G.E_MANAGER:add_event(Event({
trigger = 'after',delay = delay or 0.1, blocking = false, blockable = false, timer = 'REAL',
func = (function() if eval_func(card) then if not first or first then card:juice_up(0.1, 0.1) end;juice_card_until(card, eval_func, nil, 0.8) end return true end)
}))
end
For reference
As long as self is the card being referred to, this is fine
pretty sure that would be card
I'm not ignoring you sorry, i just don't know the best way to do this. I'm sure someone here who's done Joker stuff can tell you
somehow i managed to get a rendering error when hovering over an undiscovered item?
Is it possible to show the soul pos of a joker on the unlock popup when unlocked
the side popup? or the full overlay menu when you exit the run
the side one
haven't looked at how those work tbh
oh i see, it's just a sprite
it should work if you make it a proper card
i was just wondering if there was already a way to do it, not a big deal if not
So SMODS essentially reformats a lot of vanilla objects to work like the structure it gives to end users. Are the resulting calculate functions basically just the entirety of the vanilla Card:calculate_joker or are they somehow broken down?
this is not something steamodded does. the original Card:calculate_joker is still used, albeit patched a little
no one would want to maintain something like that
I'm basically just trying to work around how editions are calculated because it's giving me a headache
I point it out because I don't see calculate_edition in the base game code
Card:get_edition() is the equivalent calculate function I suppose
Which is just a lot less robust and only supports the base 3 versus the way SMODS uses return tables for a bunch of stuff
Thanks for taking a look, I am getting a crash when it gets to this line
What I was trying to do is when the joker calculate runs and a condition is true, card.ability.ready becomes true. Then when my joker gets to the end of the round, this card.ability.ready value is turned back to false.
I wanted it to jiggle while it's ready to be use
editions run entirely through smods now
@wintry solar I made a PR. Is there anything I can do to make the lives of people who're going to review it easier?
Oh yes, exactly like that! I will check it out
That should work, might need a broader look at your code.
your lovely patches look a bit jank but the premise of it seems to make sense
Do you think there's a better way to do it? I didn't want to think about regex so I just did manual overwrites
can they not be combined?
oh actually looking at it the self.debuff lines are always different
thanks thunk 🙃
Are they?
The function name is different
The next line seemed similar enough
There may be some false positives, if you don't want to match the whole line that is
yeye that's what I'm attempting to figure out. I'm looking to (somewhat hackily) create a simplified equivalent to the Quantum Enhancements thing for editions because I have a joker effect requested that does something similar, but I'm struggling to see where the values are actually scored
So this:
function Card:calculate_edition(context)
if self.debuff then return end
if self.edition then
local edition = G.P_CENTERS[self.edition.key]
if edition.calculate and type(edition.calculate) == 'function' then
local o = edition:calculate(self, context)
if o then
if not o.card then o.card = self end
return o
end
end
end
end```
is the equivalent to this:
```-- vanilla
function Card:get_edition()
if self.debuff then return end
if self.edition then
local ret = {card = self}
if self.edition.x_mult then
ret.x_mult_mod = self.edition.x_mult
end
if self.edition.mult then
ret.mult_mod = self.edition.mult
end
if self.edition.chips then
ret.chip_mod = self.edition.chips
end
return ret
end
end```
The former calls a calculate function rather than just checking values directly on edition (that are set by Card:set_edition()), and I have no idea what that calculate function actually is. Since editions don't really do that in the vanilla game in the same way, I'm not sure what Holo, Foil, and Poly are using here to score their values
card has two separate definitions here and it might be causing issues. Try:
card.ability.handsTillReady = card.ability.handsTillReady - 1
if card.ability.handsTilReady <= 0 then
card.ability.handsTillReady = 0
card.ability.ready = true
sendInfoMessage("Joker is now READY!", "ratOfDeath")
local eval = function(arg_card)
return arg_card.ability.ready and not G.RESET_JIGGLES
end
juice_card_until(card, eval, true)
else
they're in game_objcet.lua
objcet
yeah I see it now, thanks
Okay now I understand why this doesn't work lmaoooooo
Ill have to do the same thing quantum enhancements does and set the edition manually before they're calculated, because it takes values currently on card.edition to match up with vanilla, or just overwrite them to check where I've been storing the extra editions, which is on card.edition.others
There's always the gambiarra way to do it
Which is?
Create an invisible Joker that handles whatever effect you want to do
not a bad solution all things considered, I've seen weirder stuff
I'm doing that to add special effects to poker hands
The Steamodded way is to check SMODS.has_enhancement(card, 'm_stone')
The vanilla way is to check if card.ability.name == 'Stone Card'.
You should probably use the Steamodded function unless you have a good reason not to
trying to make it so the amount of stone cards in deck is added to mult
isnt that already a thing?
wellll it removes half of the stone cards and add the amount removed to mult
so like this: 10 stone cards > X5 mult
There's one that counts stone cards for chips
ill have to just look at that in the source code
the real kasane tato
looks inside
mario
Looked into this a bit more. You'll want to define x_mult as a member of card.ability, and rename your extra.BlindSize, extra.ScalingAmount variables with lower_snake_case for clarity - UpperPascalCase is usually reserved for global classes.
Then wherever you're defining your joker, it needs a calculate function containing:
calculate = function(self, card, context)
if `context.end_of_round and G.GAME.blind.boss and not context.individual and not context.repetition and not context.blueprint then
`card.ability.x_mult = card.ability.x_mult + card.ability.extra.scaling_amount`
...
end
That worked great, thank you, @paper zealot
local eval = function(card) return (card.ability.ready == true) end
juice_card_until(card, eval, true)
Sounds like self is not card in your situation
Thanks a lot! I’ll definitely try it when I finish dinner!
By the way, the language more commonly used is "when Boss Blind is defeated" if you're looking for other similar effects
two of the best characters in all of fiction let's be real
you mean one of the best character in all of fiction
mario and teto are both cool as hell. teto is pretty and silly and mario is brave and heroic
i fuck with both of them
-# I'm continuing the joke of them being one person
fr tho 🔥
i didn't realize that was the bit? my bad
wanna see a new Joker
sure why not
let's see it
is it a one-time thing
What do you think?
-# I prefer asking before answering to evaluate the text
its cool actually, first time seeing that kind of mechanic
Weird, I am getting crashes now on jokers that worked before, after upgrading lovely and steammodded
that certainly is cool, would say that's balanced well enough for a common joker
||One Consumeable per hand per trigger, yes||
mhm, agreed
That was the goal ^^
I wonder if it's a bit too weak tho
Compared to Photograph the timing is better, but the condition is a bit harder
its fine imo, the xmult is good
likely loc_vars issue
...it was that hard?
Vanilla doesn't expect cards to be destroyed at arbitrary times
So it's tricky
Less tricky if you don't care about mod compatibility
I think SMODS also seems to handle it better now if a card ceases to exist compared to the past
oh, i see
For this, I just updated the UI, but I can probably update the code too now
You haven't defined ability.x_mult or renamed extra.ScalingAmount
can i cook it :3
i just realised i need to edit the art as it will always have the eternal will cover it
if you can stomach the clown meat sure
nice
Also send us your localization for the joker
im surprised there hasn't been a cooking-related mod yet
considering how many mods that add food to balatro
the what, im sorry
localization is where you store like, keys to call for text
loc_txt
Oh, sorry, i'm running on autopilot. You've defined the loc_txt directly instead of in a separate file, it's all good
its fine lol
Am I supposed to update dollar_buffer myself? I have this in an enhancement for now but this allows me go into debt
calculate = function(self, card, context)
if
context.main_scoring
and context.cardarea == G.play
and (G.GAME.dollars + (G.GAME.dollar_buffer or 0)) - card.ability.extra.cost > G.GAME.bankrupt_at
then
ease_dollars(-card.ability.extra.cost)
return {
xmult = card.ability.extra.xmult,
card = card,
}
end
end,
i dont think so
ease_dollars handle all of the dollars stuff
ease_dollars(a) gives you a more money
if its a negative number then it will reduce your money by that much
To be clear, card.ability.Xmult is not card.ability.x_mult and card.ability.extra.ScalingAmount is not card.ability.extra.scaling_amount. Gotta clean up the mix of naming styles
G.GAME.dollars >= card.ability.extra.cost is fine
i dont think theres a need for dollar buffer
this works as expected when I play with a hand with zero dollars
G.GAME.dollars should be how much money you have anyways
but if I play this I end up with $-3
when the expected behavior is spend the $2 only and stop triggering
I haven't fully bothered to understand what all the different buffer things are but I assumed they exist to keep track of addition/removal of things in a single calculation step
jimbo's harvestcraft
yeah uh, i dunno honestly, seems very weird that happens
you would need to use dollar buffer here, but you should also just return dollars = whatever instead of using ease_dollars
oh, does that make a difference?
i genenuinely dont know where to go from here, i know yall are telling me but i just cant seem to grasp it.
it should be card.ability.extra.x_mult, not card.ability.x_mult
is it still extra. i thought x_mult was a built in this
and you shouldn't return that either
you are calling it from the defined variable in the card config extra, no?
???
its > G.GAME.bankrupt_at, which i assume is 0
uhhhh
smt smt, try put it to >= ❤️
ohh
calculate = function(self, card, context)
if context.end_of_round and context.main_eval and G.GAME.blind.boss and not context.blueprint then
card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.ScalingAmount
return {message = localize('k_upgrade_ex')}
end
if context.joker_main then
return { xmult = card.ability.extra.x_mult }
end
end,
your calculate function should be like this
Hi friendos, today I am seeing this fun error with a joker who worked previously
functions/common_events.lua:1241: attempt to call method 'juice_up' (a nil value).
It is happening when my joker proc's for a counted card and when we are getting ready to return our message and mult
show code
sendInfoMessage("Counted " .. tenCounted .. " tens, mult: " .. thisMult, self.key)
return {
message = "MULT",
colour = G.C.RED,
mult_mod = thisMult,
chip_mod = card.ability.chips or 0,
card = card
}
The log message appears and then it throws right after that
what context are you in?
Oh good question, context.joker_main
also you should probably just return mult = X, chips = Y
Thank you, I’ll try this after my shower, I truly can’t thank you enough
uhhh dollar_buffer never gets reset to 0??
oh I have to do that myself too??
forgot to return true in an event again award
how would i make a joker proc its ability by checking for an enhancement / edition?
I gotchu man
@solid surge
if context.cardarea == G.play and context.other_card and context.other_card.edition and context.other_card.edition.holo == true and not context.repetition then
--other card was holo here
end
omg, thank you so much, you have saved hours of my life, and thanks everyone else who helped
For the get id thing when referring to specific ranks, what would the thing for Kings be?
yep
Alrighty, thanks mate!
thanks m8
New question, how would I make it where each played king gives +3$?
Does anyone have a really basic template for blinds? Mine shows up fine in the collection but shows up blank when you play it so I'm trying to figure out where I went wrong
I've got a sample of that
:(
if context.individual and context.cardarea == G.play then
local otherCard = context.other_card
if othercard.base.id == 13 then
ease_dollars(3)
end
end
Thank you :D
Ease dollars has no message right?
how do legendaries have the floating heads again?
yoink
they are wild! Cryptid has some of their own they've added
soul_pos is the var
soul_pos = {x=1, y=2}
maybe i should check out the Cryptid mod
Hey all, I've been on a huge break from work on my mod, and I have dumped all knowledge on the subject 
I am struggling to find how to destroy a card when it is scored (If it has a specific enhancement)
are you able to change the scale of the soul
soul uses the legendary cards code
Oh apparently it does work, just doesn't show up when I make it the summon for another blind
well... that's weird
Maybe I broke the code when I was tinkering with it
relateble
i have a sample of that, i implemented it today give me a couple mins
Awesome, thank you. Just trying to get back into the swing of things.
Well I switched to an unmodified version of blindexpander and it's still wrong, so I have no idea what the problem is
if context.full_hand and context.cardarea == G.jokers then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 1.0,
func = function()
local card = context.other_card
if card.ability.name == 'Glass Card' then
card:shatter()
else
card:start_dissolve({HEX("57ecab")}, nil, 1.6)
end
return true end }))
end
I'll have to come back to this later
Hmm, where would I implement this. I don't want it tied to a joker, just the card itself (The card enhancement is marked as single-use)
Unless if I inject it into the card scoring section 
For some reason I can't explain, this doesn't make it give money, it does nothing
almost done
Congrats :D
@gusty sequoia if you want to dm me your whole joker card I can debug it an about an hour or so
make it like glass but it always breaks every time?
Gladly
Okay so
I changed the small blind so that it summons a blind after. Initially, just to see if it would work, I tried having it summon the big blind, which worked, but then when I tried with a custom blind it didn't work. And I checked that the custom blind does indeed work when it appears as the boss blind, so I'm not sure what's causing the issue unless there is some fundemental difference between boss and non-boss blinds that makes them not work with the summon thing from blindexpander
I mean if that's the issue I could just make it a non-boss blind, but I'm not really sure how to aside from just omitting the boss parameter, which I don't think makes it a non-boss blind
Cause I think they are boss blinds by default if I'm not mistaken
Okay nope, I tried swapping it with a regular boss blind like Ox and it worked so it's just a problem with how I made the custom blind I guess
key = 'bl_test',
loc_txt = {
name = 'Test',
text = {
'Test'
}
},
dollars = 3,
mult = 1,
boss = {min = 1, max = 10},
boss_colour = HEX('FF0000'),
atlas = 'TestBlind',
pos = { x = 0, y = 0 },
vars = {},
config = {}
}```
Dunno what I'm missing here
What's the best way to increase the joker_rate?
hooray to the polychrome (and newly added foil) jokers working! (just gotta figure out how to stop it from going after the total)
@paper zealot
line 19
has the closing }
at least vscode says it does
amiblind lol
You have spaces in Boss Blinds Beat
That's a dictionary key string, no spaces allowed
is there a way for stickers to have a random value upon generation?
Might be more clear if you format it like this:
return {
["descriptions"] = {
["Mod"] = {
["BossBlindsBeat"] = {
name = "Boss Blinds Beat",
text = {
"Adds completed boss blinds tab to run info screen.",
"Follow on {C:purple}twitch.tv/calexil{} to support!", -- the "twitch.tv/calexil" is turned into a clickable link
" ",
" ",
" ",
" ",
"Programming and implementation by {C:calexil}Calexil{}.",
}
}
}
}
}
Make sure that matches your mod id defined in the .json file
nvm im a dumbass
I suspect you might also have multiple .json files by accident based on the error in #⚙・modding-general , could you send a screenshot of your mod's folder?
I got it down to a single instance
@paper zealot not sure if it's easier for you or not but im live rn t.tv/calexil
if string.match(key, "j_type") then
return true
else
return false
end
end
calculate = function(self, card, context)
if context.other_joker then
if is_type(context.other_joker.key) then
return {
Xmult = card.ability.extra.Xmult
}
end
end
end`
am i doing this wrong?
in your return block, make Xmult become xmult (the first one, not the second one)
Can I get a second opinion on this, I'm completely stumped
It works as a boss blind, and having a blind summon a base game blind works, but having it summon this custom blind doesn't work
and I can't for the life of me figure out why that is
the match function is failing
What would I put in here for a high card poker hand, and what would I do for identifying if it's the first hand?
if context.before and next(context.poker_hands['']) and not context.blueprint then
"High Card"
Okay, thanks. Wasn't sure on the capitalization or if there was an underscore or something.
Now I just need to check for the first hand of the round.
Edit: Found it, G.GAME.current_round.hands_played == 0
Exactly like this.
I'm going to have to modify the scoring code with a toml I fear...
and I don't know where to begin
sesbian lex
SEBBIN LEGZ
is this
AN ENTIRE BOOK
OF BLEUPRINT/BRAINSTORM YURI
AS A JOKER
...
i need
what are the game stats
whats the var for accessing the the joker pool?
sesbian lex in balatro??
comedy
WHY IS IT 6 AND 9 AGAIN
is there a way to count played cards as a different rank?
i can't get over this
this is absolutely hilarious
ainttt no wayy
oh boy there's an entire github issue about this that never got resolved
if i had a nickel for every time someone made a joker involving number 6 and 9 i would have 3 nickel
(they all have different effect at least)
https://github.com/Steamodded/smods/issues/449 tl;dr you're gonna need to do it yourself
why would it create a Death though?
it's some weeb gacha game reference don't mind it
gotcha :3
BLUE ARCHIVE THEMED BALATRO MOD
real
is that why it's called contraband
What does the sob joker do.
it's like shitty opposite of Smiley Face I can't think of anything funnier
😭
finally managed to get quantum editions working 😔 this took a lot longer than I thought
inb4 gives X1.3 chips for every face card played
and some others
empty
this is a tragedy
tragedeigh
problem seems to be that officially supporting quantum rank cards + current feature where ranks can have multiple successors is a massive pain in the ass because they also want it to support sick and twisted people trying to play a 52-long straight
I'M SORRY
I'M SORRY
I'M SORRY
i really do not want to even bother trying to procure a fix for that lmao, so into the "get to it later" bin the joker goes
are you sick and twisted
I'M THAT ONE PERSON
yoo that is peak
how to add negative edition to consumables when using SMODS.add_card(t)? no highways
52 card long straight is the stuff of nightmares
local _card = SMODS.add_card(table)
_card:set_edition('e_negative')
absolutely awful. just abhorrent frankly
what's wrong
joking that the 52 card straight is horrifying
This is amazing, I hate it
the code for this was already removed a while ago
yeah straights dont loop, ace can be a 1 or a 14 but you cant make a straight like 3 2 A K Q. so max is a 13 strait
create mod just had an update 2 days ago
actually if it's A 2 3 ... Q K A that's fourteen isn't it?
Who has the Read The Fucking Docs gif
so it's a quadruple fourteen straight
No
For that you'd need eight aces
goober. a straight with all cards in a suit is a straight of length 14 using 13 cards
Unfortunately not something I can help with, I'm here as an observer and an ideas guy
ah heck
because the ace would count as both the predecessor to 2 and the successor to king
It can't count as both at the same time
says who?
You'd need two aces for that
i have some ideas but i have to learn to mod because im sure no one will ever take them as suggestions
You can't score a card as two things at once.
I mean you could toss down a thread as a request but you're probably right.
What's the idea
i see no precedent for that in the base game
like if you play a 2 2 4 4 7 flush it scores as a flush and not as two pair
that is base game
how are jokers made with custom sizes?
It already does that
Straight flush
yeah cuz straight flush exist
That's one hand
and if you play a flush and a five of a kind?
That's literally one thing
but two pair flush doesnt
YOU'RE NOT HELPING YOUR CASE
wait how does bonus mult with smods work now
the ace simply fills in two gaps in the straight
Five-card hands can also be flushes.
Four-card hands can't (without four fingers).
cause i can't see it in the card's description but it's still adding mult to the card ;-;
i want to make a mod called Hanged Man
to be the exact opposite of Cryptid
otherwise isn't it ambiguous whether it's a royal 13 flush or a straight 13 flush?
You can't just say that, you gotta give details.
Cryptid adds busted overpowered cards
and i want Hanged Man to add questionable to outright bad cards
but you know, not like bad bad
Example: I want to be part of the making of a mod that adds the Super Smash Bros Ultimate Extended Roster as a new kind of Jokers along with a new set of items.
still workable in a run bad
like Odd Todd kind of bad
not useful in most cases except for like seven reallty specific builds
YOU TAKE THAT BACK RIGHT THE FUCK NOW ODD TODD IS BABY
i had a fun run with odd todd recently
HE DIDN'T EVER DO ANYTHING TO YOU
i think i ditched him for scholar tho cuz it was an aces run
also the funny
odd todd is alright
i think i like him better than even steven
i gotta say word puzzles in balatro is such an insane concept but i kinda love it
i thought it's a good name
the (seemingly) sideways 8 for infinite discards is smart lmao
anyway the idea is i want the jokers to force you to do weird setups and otherwise unusual/bad plays
another 100 copies of loyalty card
joker in hanged man mod: +1 chip
example
Glass House
Glass Cards give x4 mult if a Stone Card is scored in the same hand,
destroy all Glass Cards scored that hand
just discovered the sprite I was painstakingly working on was accidentally sized 142x190
You should add ™️ after every "Balatro" in that card description.
so it makes you build a Glass and Stone deck
is balatro trademarked
also is this too cruel
I would assume so
keep cooking with ideas like this and you can make balatro an average zachtronics game
Only if that ends you up with X12 Blind Size
is that a good or bad thing
another idea i had
If it only brings you up to x6 blind size, you should be fine.
the wall and violet vessel
Reroll and Retcon
😔
Colour Change
When discarding a Wild Card with 1 other card,
change the rest of your hand to that suit
so this is really good for flush build
Plasma Deck still has Wall and VV
i think the back and the sleeve look ok now
i really need to up my game of being against big numbers
Pay To Win
Rental Jokers each give x2 mult
Rental Jokers cost $3 more per round
good thing you need to reach a point where every hand is a logic puzzle
pog
keep cooking and nobody wins
Annoying Fly: +1 Mult, gains +1 Mult per card played or Discarded, -10 Joker Slots
Eternal.
keep cooking
anyway yeah that's basivally the vibe im going for
and that is what i mean by i need to learn to mod myself
we are turning Balatro into Zachtronics Solitaire
because no one would pick them up
Can't sell it, can't escape it, can't make it better by force, you just have to keep burning cards to make it good.
so is there a docs
yes
theres documentation technically
wrong reply mb
are you ok
thank u :3
just because of that message I'm adding sliding puzzle to balatro
LOL
The Secret
+9 mult
Gain +9 mult if all scored cards rank adds up to 45
Jokers cannot be moved. Whenever a card is scored, move this Joker to the right by its base chip value (wraps around). If this is the rightmost Joker, X5 Mult
oo
modular arithmetics
my beloved
you could make it reference the Bell Ringer card from Inscryption
I'm adding Impostor cards
that'd fit the mechanic
and also be a neat reference
(Bell Ringer deals damage equal to how close it is placed to the End Turn bell)
(so from left to right it goes 4, 3, 2, then 1 damage)
making it go x1 x2 x3 x4 x5 based on the slot would be a little more kind while still keeping the gimmick
also question
What
do i need to have specifically steammodded or can i use like, r2modman
i already have it for modded webfishing and it can mod balatro
but i don't know if it will work for creating mod
Use Steamodded, the community will thank you.
r2modman also uses Lovely and Steamodded, but that version hasn't been updated for a long time
😭

