#💻・modding-dev
1 messages · Page 557 of 1
how do people upscale it to have it not do that
people are mentioning aseprite causes that but im not using aseprite im using krita
ive never had problems with aseprite doing that anyway
when you upscale it, make sure the interpolation method is set to none
i dunno if that's even an option in krita, but i use gimp and the upscale always looks perfectly fine
Is it possible to have a blind detect when a joker is triggered?
its on nearest neighbour
i thiiink i fixed it?
messed around with some export settings
yea because it's pixel art, you don't want any interpolation at all
theres no option for "none"
but shouldnt nearest neighbor effectively do nothing if the new resolution is a multiple of the previous one?
hooray
now check if it works with cardsleeves
i forgot that exists :clueless:
hey
is it possible to call a function when a certain card is clicked on? if so how would one do so
you can hook card:click
oh wow i sure do wonder why the card is mysteriously floating outside the sleeve :clueless:
time to go back to the drawing board anyway because i wanted to make it a pseudosticker so that i could have info queue when hovered
but thats not how info queue works :clueless:
how does one info queue outside of loc_vars
i think you need to patch the generate ui function
i dont think it's called on facedown cards tho
oh dont worry i did make it a pseudosticker i actually succeeded in that
its just, indeed, info queue isnt called on facedown cards
i dont remember how i did it in my mod
i was going to nuke this anyway because this is slop
but it has descriptions on facedowns
brb invading joyousspring github
(i assume?)
quality code
its called experimenting with evil jank
i ❤️ using drawstep for the wrong purposes
im tryna make a config ui, where would i write the code?
i am massively blind apparently
ill keep looking but damn am i a slow reader
i finished my lunch break so let me see if i can find it
it's card:hover sorry
in card_ui.lua
yeah just found it lmao
hi N
hi
did you have a good lunch?
it was ok, i always bring the same thing to work
he didnt give me any
hi dilly
hello
ive been in the mines creating silly fun things
and then losing to my own creation
wdym where
the code
with the power of N' wonderful code this jank actually has a purpose now guess im keeping it 😔
tbf i only want this one how would i hide the main thing
hm
you probably need to either make the popup yourself or patch the main box out
currently looking into patching the mainbox out
Hey, could somebody tell me what's wrong with my code? It changes the game speed to nil in settings and changes nothing in-game:
key = 'madeinheaven',
atlas = 'madeinheaven',
loc_txt = {
name = 'Made in Heaven',
text = {
"Adds {C:attention}X1.2{} to game speed,",
"for every played hand",
"{C:inactive}(Currently {C:attention}X#1#{})"
},
},
config = { extra = { currentspeed = G.SETTINGS.GAMESPEED } },
loc_vars = function(self, info_queue, center)
return { vars = { center.ability.extra.currentspeed} }
end,
rarity = 2,
cost = 3,
unlocked = true,
discovered = true,
blueprint_compat = false,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
add_to_deck = function(self, card, from_debuff)
card._normalspeed = G.SETTINGS.GAMESPEED
end,
calculate = function(self, card, context)
if context.joker_main then
currentspeed = G.SETTINGS.GAMESPEED
G.SETTINGS.GAMESPEED = G.SETTINGS.GAMESPEED + 0.2
if G.SETTINGS.GAMESPEED > 17 then
ease_ante(-G.GAME.round_resets.ante + 1)
card:start_dissolve({G.C.RED})
card = nil
end
return {}
end
end,
remove_from_deck = function(self, card, from_debuff)
G.SETTINGS.GAMESPEED = card._normalspeed
end
}
its because if the game speed is something that isnt an option for the setting it displays as nil in settings
as for it not doing anything i have no idea
my shit crashed
I believe you have to use an animation atlas for the blinds
i hover over the blind and
maybe you need boss_colour
that i do oopsies
i have currently patched the main box out
now to refine this
yeah baby thats what im talking about
holy shit its deck stickers
its only minor amounts of jank
aside from the sticker it would actually be nice to be able to hover a deck to see the effect
specially for modded
to be fair it does show the effect when you click the deck
but yea an info_queue for it would be nice too
next mod for N to make
can't wait for the RngDisplay mod
time to dejankify :clueless:
Have fun
Batrocities = {config_file = {disable_tarotM = false, disable_planetM = false}}
SMODS.current_mod.config_tab = function()
return {
n = G.UIT.ROOT,
config = {
align = "cm",
minh = 6,
minw = 10,
padding = 0.2,
r = 0.1,
colour = G.C.BLACK
},
nodes = {
{
n = G.UIT.R,
config = { align = "cm", },
nodes = {
{
n=G.UIT.O,
config={
object = DynaText({
string = localize("btct_string_A"),
colours = {G.C.WHITE},
shadow = true,
scale = 0.4
})
}
},
}
},
create_toggle({
label = localize("btct_string_B"),
ref_table = Batrocities.config_file,
ref_value = "disable_tarotM",
}),
create_toggle({
label = localize("btct_string_C"),
ref_table = Batrocities.config_file,
ref_value = "disable_planetM",
})
}
}
end
i know i have to add a way to access loc files, idk how to do that tho... what would i put to access en-us?
localize does that
you just need to put the keys in the loc file
like misc.dictionary.btct_string_C
i have this, is this right?
no they have to be in misc dictionary
why this return 0?
ah
joker.config.center.rarity
there's also joker:is_rarity(4) now
ok it works now thanks
i just see this on vanilla remade wiki
well i havent updated that :p
oh you mean the center
thats wrong then lol
im just want to count leg jokers you have
yo! how can i make a tarot thats like judgement but just for the jokers in my mod specifically?
fixed
make an objecttype containing all the jokers from your mod
okie dokie
and then use that as the set in SMODS.add_card or whatever you use i think
okay i gotcha
Will if G.jokers and G.jokers.card.ability.name == 'j_prefix_key' then work? Is that even valid way of checking it or do I use some different properties?
what are you trying to do?
its .config.center.key, name is only used in vanilla
G.jokers.cards is a table
also that
I'm trying to make a specific music play if player has specific joker, plus some other variable but I'm trying to make it work at all
you can use SMODS.find_card('j_joker_key')
Cause I'd want to do something like
key = "key",
path = "music.ogg",
pitch = 1,
volume = 0.6,
select_music_track = function()
if HAS THIS SPECIFIC JOKER == 'j_prefix_key' then
return true end
end,
})
but I have no idea how to formulate this "if"
yeah find_card would work there
so how would I do that?
if next(SMODS.find_card('j_joker_key')) then afaik
lmk if it doesnt work so i can punch myself as punishment
yeah
lmao all things with an even cost just become campfire fodder with this
where can i find how to make config work? like what the configs are supposed to do cause i only have the ui and not what it does
you have toggles right
yuh
you need to use ref_table and ref_value to point to the config
Batrocities = {config_file = {disable_tarotM = false, disable_planetM = false, disable_malfunctionFlash = false, nerfHim = false}}
i have this but like how do i connect this to what its supposed to do
somewhere else i have JokerDisplay.config = SMODS.current_mod.config
ill try reading the code and try to figure out how to disable the voucher
to disable it just put the config in in_pool
Batrocities = {}
Batrocities.config = SMODS.current_mod.config
And then the old table put into config.lua in the root directory
would i like... make an if statement or smth?
as
return {
...
}
ok thanks
return not Balatrocities.config.no_voucher something like that
but the table i have is in the config.lua
would i also put this in config?
smods saves the player's somewhere else
no in another file
ui.lua?
anywhere you want that's not the config
ok
same for this?
This should go into the config.lua
oh ok
JokerDisplay as an example https://github.com/nh6574/JokerDisplay/blob/main/config.lua
oh
oh
oh
yeah just check how i do it in jokerdisplay it was made by eremel so it's good
ok thanks
thats slightly annoying
i've never seen so messed up ui at once
Worked just fine! The joker is complete! Thanks!
the consequences of pretending a consumable is also a booster pack
but i think i found the culprit line
im guessing the effect is mr bones
just modify the odds variable you have saved
i did not infact find trhe culprit line
yes
it prevents death
welp time to stare at code until it makes sense
how would i have a calculate_effect target a card added with SMODS.add_card?
The beauty of modding
what do you want to do exactly
returning a message
so you add a card and you want that card to have a message?
yes
its somehow better? kind of?
local added = SMODS.add_card{...}
SMODS.calculate_effect({message = ""}, added)
what are you trying to do
i cant see the other video
oh ok thanks
having this in the calculate function:
return {
denominator = context.denominator * 2
}
end```
would double the denominator of any roll with `"(your identifier)"`
Is there any way on a "variety" booster pack to make it so that some cards can be used immediately
but some cards have to be pulled into your consumeable slots?
opening a booster pack from using a consumable
or well "booster pack" its not actually a booster pack
it pretends to be
is identifier like [modtag]_[joker]
for this you would need to use gloval calculate or something
i think saving it to a variable is better
like G.GAME.modprefix_mrbones_oods
heres what the current code looks like
use card.ability.extra.odds * (G.GAME.modprefix_times_used or 1)
and then before you return do G.GAME.modprefix_times_used = (G.GAME.modprefix_times_used or 1) + 1
in local_vars?
no in calculate
kk
in loc_vars put the first part for the odds to show correctly in the description
it crashed and i wondered where i fucked up
i forgot the fucking image atlas
is this in
why does this play in the main menu
i only want it to play on specific blinds
and it overwrites every song too
your condition logic is wrong
a == 'string1' or 'string2' doesn't work in lua
(it returns true because the string is truthy)
explode
?
ur so mean 2 me
okay
though i remember allowing the functionality to be added to cards being discussed at some point
mmm sorta like how Cryptid does the code cards, maybe?
as an example i just added an extra button to a card that you cant use and instead needs to be put in the consumable area
so you could do something similar to that
for packs specifically
"i sure do wonder why my patch isnt working"
the devious and obscured spelling mistake in the path:
wow and now everything works :clueless:
almost*
"The Beauty of Modding"
hm this tweak did not improve things
ok so i haven't tried to create a new UI element
how would I go about adding a button like that
and how would I go about applying that to a specific consumable type?
ok so the problem is G.hand shows up again
after skipping/selecting a joker
its empty
but its also there
i'm confused on why this doesn't work when there are loads of jokers with the bulgoe set
SMODS.Joker {
key = "bulgoe_candy",
name = "Bulgoe Candy",
config = { extra = { jokers = 2, money = 7 } },
rarity = "cry_candy",
atlas = "crp_placeholder",
pos = { x = 2, y = 1 },
cost = 3,
blueprint_compat = true,
demicoloncompat = true,
eternal_compat = false,
pools = { Bulgoe = true, Food = true },
loc_vars = function(self, info_queue, card)
return { vars = { lenient_bignum(card.ability.extra.jokers), lenient_bignum(card.ability.extra.money) } }
end,
calculate = function(self, card, context)
if (context.selling_self or context.forcetrigger) then
for i = 1, lenient_bignum(card.ability.extra.jokers) do
SMODS.add_card({ set = "Bulgoe" })
end
ease_dollars(lenient_bignum(card.ability.extra.money))
end
end,
crp_credits = {
idea = { "wilfredlam0418" },
code = { "wilfredlm0418" }
}
}
like is this not a part of the bulgoe set
SMODS.Joker {
key = "bulgoe", -- my sweet little pumpkin
name = "Bulgoe",
config = { extra = { chips = 2.7 } },
rarity = 1,
atlas = "crp_joker",
blueprint_compat = true,
demicoloncompat = true,
pos = { x = 0, y = 0 },
cost = 1,
pools = { Bulgoe = true },
loc_vars = function(self, info_queue, card)
return { vars = { lenient_bignum(card.ability.extra.chips) } }
end,
calculate = function(self, card, context)
if (context.joker_main) or context.forcetrigger then
return {
chips = lenient_bignum(card.ability.extra.chips) -- most overpowered shit you've ever seen
}
end
end,
crp_credits = {
idea = { "Poker The Poker" },
art = { "Poker The Poker" },
code = { "Glitchkat10" },
custom = { key = "everything", text = "Bulgoe" } -- everything is bulgoe
}
}
Are there variables somewhere for the current mult and chips of a poker hand?
hand_chips and mult globals.
example of such:
...
local current_mult = lenient_bignum(mult)
return {
xmult = 0,
extra = { -- altered to be kinda like chibidoki's return bc of some weird shit
mult= 2 ^ current_mult,
remove_default_message = true,
message = "=2^" .. current_mult .. " Mult",
colour = G.C.DARK_EDITION,
sound = "talisman_emult"
}
}
...
but erm yeah i don't like crashes guys
i can not be bothered to figure this out rn
wait a second yes i can actually
add another janky hack on top of it mate but that works now
oh my god i focvused too hard on this dumb idiot that i forgot how to use consumables
"why is use greyed out?!" as i am trying to use the devil in the shop 💀
Did i do this right? Also im confused on how to make the stuff activate. would i make a code in config_tab.lua?
no, remove the first line
and put this in another file Balatrocities = SMODS.current_mod
How do I make a custom color for in the loc files I want to make a {C:Giga_Food} that has the color F7070BFF
blublub i'm a fish i say bump the water make a splash
How do I make this talisman compatible? Seems to be just the return that it doesn't like.
calculate = function(self, card, context)
card.ability.extra.chips = G.GAME.hands["Straight"].chips
card.ability.extra.mult = G.GAME.hands["Straight"].mult
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
return {
chips = card.ability.extra.chips,
mult = card.ability.extra.mult
}
end
end
What's your talisman version
2.2.0b
i have that
what do i do after
lmao, haven't actually used talisman in a while. Just going for cryptid compat now.
I'm on steamodded 0731a, probably need that updated as well.
just update everything 😭
That's not even a release 🥺
use dev versions at your own risk, but at least update them regularly lmao
imo pretty much always use dev versions
if you get a crash or bug with that version, update
if that doesn't work, get release
if it still doesn't work... uhhhh
If you get a crash or bug report it *
if you're actively developing a mod, sure
well yeah if you're on latest
even then releases only make sense if they fit together and mods don't randomly depend on dev versions or not
it's kinda iffy
for players, the easiest option is to use releases
and that's what should always work
like take polterworx when it was still a thing it needed kinda specific mod versions and it was a bit hard to play with other more updated mods
breaking changes aren't that common, using a newer version is unlikely to cause you trouble for most mods
yea
it's just unfortunate when mods depend on dev versions
it makes players get the current dev version but then they'll forget about it
i think it makes sense if dev versions of mods require dev versions of other mods, but the release version should almost never
how do i make these actually work?
of course
This should be enough
For this file at least
ok
would i do the actual code in config_tab?
You can
The rest is just organisation
Just remembered that one of my smaller mods has a config tab
https://github.com/EasternFarmer/WeLoveTalisman-Balatro-Mod
how would i start? is there a section in the wiki that talks about how to make it work?
ill check it out thanks
Not sure
I stole borrowed code from N
real
dont we all
:clueless:
:clueless:
Ignore the ---@diagnostic comments it's just for the lsp
ah ok thanks, i didnt steal borrow it anyways
i do that too
How would I prevent a joker from being debuffed or flipped?
SMODS.debuff_card(card, "prevent_debuff", "source") for the first, hook Card:flip for the second
Why is local idol_card = G.GAME.current_round.vremade_idol_card or { rank = 'Ace', suit = 'Spades' } in the loc_vars of the idol and what does it do?
if the first table is nil it defaults to the second table
How would I choose a random card like it does? I don't really understand the code of it right now
Go through the playing cards with a for loop
Pick a card
You can do this without a for loop
did you look at the function below
Yes
which part is the problem
I don't know what G.GAME.round_resets.ante is/does. The same goes for
G.GAME.current_round.vremade_idol_card.suit = idol_card.base.suit
G.GAME.current_round.vremade_idol_card.id = idol_card.base.id```
the first where the current ante is stored
the other ones are just storing a global variable with the card's data
you can't store the card directly because balatro doesn't like saving objects
Okay, idol changes every round, right? How would I make it every ante instead?
if you want the card to be shared between copies then you would need to use the global calculate probably. if you don't care about that you can just put the logic in your joker's calculate and use the new ante changed context
How do i make a function for config to disable a specific voucher 😭 either im really stupid and im missing where im supposed to read or its just really wierd and needs elite knowledge to figure out
-# its prob the first one
Does the config menu work?
It exists
I can't figure out how to properly add support to Joker Display for jokers with the new probability functions added to SMODS, anyone here done it before?
ah it was a jokerdisplay thing?
And what i mean by that is it has the selecting things yeah
To use the newer version of Steamodded, I just need to replace the old folder with the new one, right?
remove the old one
do you have debugplus
Oh thanks!
Yeah
can you eval Balatrocities.config in the console before and after selecting the option?
can i see the code for the UI
--Config Tab
SMODS.current_mod.config_tab = function()
return {
n = G.UIT.ROOT,
config = {
align = "cm",
minh = 6,
minw = 10,
padding = 0.2,
r = 0.1,
colour = G.C.BLACK
},
nodes = {
{
n = G.UIT.R,
config = { align = "cm", },
nodes = {
{
n=G.UIT.O,
config={
object = DynaText({
string = localize("btct_string_A"),
colours = {G.C.WHITE},
shadow = true,
scale = 0.4
})
}
},
}
},
create_toggle({
label = localize("btct_string_B"),
ref_table = Batrocities.config_file,
ref_value = "disable_tarotM",
}),
create_toggle({
label = localize("btct_string_C"),
ref_table = Batrocities.config_file,
ref_value = "disable_planetM",
}),
create_toggle({
label = localize("btct_string_D"),
ref_table = Batrocities.config_file,
ref_value = "disable_malfunctionFlash",
})
}
}
end
or do you want the full thing?
can i see where you define Balatrocities.config_file
ok then add this to the voucher
in_pool = function(self, args)
return not Balatrocities.config.disable_malfunctionFlash
end
if that's the config for the voucher of course
Oh ok thanks
If i was to activate it before a new run, and then activate it during a run, will it still spawn?
how does one modify the blind requirements
key = 'shop_sign',
px = 226,
py = 57,
path = "pvz_store_sign.png",
prefix_config = {key = false},
}```
I'm trying to change the shop sign texture but for some reason this doesn't appear to be working. Anyone know what I'm doing wrong?
this just creates a new atlas with the key shop_sign
you have to actually change the atlas of the shop sign (no idea how)
This is the kind of code that I use to replace the ui elements.
key = 'ui_1',
px = 18,
py = 18,
path = "ui_assets.png",
prefix_config = {key = false},
}``` Like this one works.
My only thoughts are maybe the key is wrong but as far as I can tell it's the right code?
Or maybe the code needs to be different since it's an animation
i think it works now, gon let tester test it for sure tho thanks
Why do I keep getting this error? I can't figure it out...
nice
Is there a way to tell balatro to recalculate the hand to display before actually playing it?
Here's the error
engine/ui.lua:693: attempt to index field 'colour' (a nil value)```
bump
ok this code causes the hand to still appear on the round evaluation screen
any way to fix it?
Pay dirt.
key = 'shop_sign',
atlas_table = 'ANIMATION_ATLAS',
px = 113,
py = 57,
path = "pvz_store_sign.png",
prefix_config = {key = false},
frames = 4,
}``` Here's the code if anyone wants it. I was missing the atlas table
Maybe its the localize...
to clarify
when i use the consumable this is attached to
it ends up ending the round as normal
but it has the odd side-effect of drawing more cards to your hand after the previous cards have re-entered the deck.
i think it might be tied to it being a used consumable since this doesn't happen with the DebugPlus "win this blind" button.
Is there a better way to look through balatro's source code than just searching through each file individually?
Guys i've been checking the smods docs about booster packs creation, and im not sure if its intended that way, but first example is wrong?
Should be newcard instead of getcard right?
Sorry im pretty new at modding this game so i'm trying to get used to the enviroment, lmao
It’s alright feel free to ask
You sometimes get late response due to either your questions being hard or time zones
But feel free to also bump it
your text table is too nested
bump2
Add a nil check for your values before calling them
Where and how?
create_option_cycle({
label = localize("btct_string_B"),
scale = 0.8,
w = 6,
ref_table = Batrocities.config,
ref_value = "tarotM_rateChange",
options = { 1, 2, 3, 4, 5, 6 },
current_option = Batrocities.config.tarotM_rateChange,
}),
how do i make the option stay what they picked? it just restarts...
Local variable = value
— rest of code
end```
I used the example code for card faces on steammodded and it doesn't seem to be working when I launch it but it also hasn't crashed anything
You mean deck skin ?
Does steamodded load your mod ?
yes
Can you find your deck skin in the customize tab ?
oh I see now ty, do I just copy and paste the hearts suit and change them to like spades diamonds and spades?
Change the 1x assets and then double it size and save it to 2x for each suit
I mean the lua so that it exists for all suits
like copy this but change the suit to say the other suits
Yes
alrighty tysm
You make the thing call a function.
hold on, let me grab some code
Here.
You need like, a table, a number and a string. The table is for the options, the number is for the current selected option, and the string is for the value of the selected option.
how much do I have to copy and paste of them to define all suits?
How many suits are there
is there any way to forcibly draw cards into hand (e.g. like the Serpent?)
Hook card draw function
all 4
Do that 4 times then
what determines the amount of times a consumable does the juice up animation in the middle
noting how planet cards do it like 3 times and i was wondering if i could tie that amount to a variable
Why does it not run this part of the code?
G.GAME.current_round.cstorm_captcha_card and
context.other_card:get_id() == G.GAME.current_round.cstorm_captcha_card.id and
context.other_card:is_suit(G.GAME.current_round.cstorm_captcha_card.suit) then
print("Works")
return {
repetitions = card.ability.extra.repetitions
}
end```
ok uhh
what do i do with the hook to immediately draw
Oh ok thanks
actually better question
what parameters would i need to mess with?
nvm i figured it out lol
what should i put in the SMODS.calculate_context{} bracket?
what do you want to do exactly?
this is not how you would draw extra cards btw
oh
what i want is to draw 3 additional cards into the player hand regardless of their hand size, a la The Serpent through using a consumable
just do SMODS.draw_cards(3)
hey so doing this now causes a stack overflow
-# also leaving this as a note for @chrome widget since it was her i originally did it with, but here's the code in case someone else can figure it
-# but here's the log anyway
it's in the update function
do you want me to just send the whole function
It being in the update function is the reason why
You probably had/removed some form of check
But if it's determining it simply by game states, then it's going to send one of those events every single frame that the transformation is valid
and im guessing a flag wont help here cause i tried that and got the same crash
I mean you could flag it as card.hpfx_transforming or smth
oh so not as like a card.ability
Yeah card.ability is gonna get reset by the transform itself (I assume)
cause before i just did a (quick mockup since i reverted it)
Regardless more than anything I'd just recommend never using update for anything that's not purely visual
It basically just transforms whenever something is to the right of it?
Does it transform back when that's also not true?
nope when it's not true it just doesnt transform
but its supposed to be a troll type thing
"oh let me rearrange my blueprint targeting"
"oh"
transforming mid drag is really funny but id understand if that wont be possible
It's entirely possible yeah
hooray!
when coding a challenge where do I put the name? I've got a en-us.lua under a localization folder that just has
return {
misc = {
challenge_names = {
bccp_commoners = 'Commoners Deck',
}
}
}
but I'm just getting an error for the challenge name in game, do I need to explicitly load the en-us file somewhere?
then yeah just put a flag on it like card.hpfx_[joker_name]_transformed or smth like that
but i still need to move it out of the update fucntion?
no
If you have multiple jokers doing gameplay shit in update, it's probably preferrable you set up a custom context for card order changed
But it's not strictly necessary
oh ok let me do that
I made one for this already before lemme find it
....do you happen to know where that det--oh my goodness
What would be the best way to prevent cards from flipping? I've got this hooked in Card:flip() to put the cards in a table, but idk where to go from here.
if G.jokers then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].config.center.key == "j_willatro_skin" then
immune[#immune+1] = G.jokers.cards[i]
if i > 1 then
immune[#immune+1] = G.jokers.cards[i-1]
end
if i < #G.jokers.cards then
immune[#immune+1] = G.jokers.cards[i+1]
end
end
end
end
Oh wait......
you were the one I wrote this code for
I wrote a generic context one that you could use for multiple jokers and a joker specific one. If you actually have multiple jokers that the generic context one would benefit from, use that one instead. It's in your DMs
local ref_card_update = Card.update
function Card:update(dt)
local ret = ref_card_update(self, dt)
if type(self.ability.current_area) ~= 'table' then
self.ability.current_area = self.area
end
if not self.area then
self.ability.current_area = nil
return
end
local joker_idx = 1
if not self.ability.current_cards then self.ability.current_cards = {} end
local size_changed = #self.area.cards ~= #self.ability.current_cards
local order_changed = false
for i, v in ipairs(self.area.cards) do
if v == self then
joker_idx = i
if order_changed then
return
end
end
if not order_changed and v.ID ~= self.ability.current_cards[i] then
order_changed = true
end
end
-- don't do potentially expensive sprite creation if nothing has changed
if not size_changed and not order_changed and self.ability.current_area == self.area and joker_idx == self.ability.last_index then
return
end
local eval = eval_card(self, {card_pos_changed = true, new_pos = joker_idx, order_changed = true, size_changed = true})
SMODS.trigger_effects({eval}, self)
self.ability.current_cards = {}
for _, v in ipairs(self.ability.current_area.cards) do
self.ability.current_area.cards[#self.ability.current_area.cards+1] = v.ID
end
self.ability.current_area = self.area
self.ability.last_index = joker_idx
return ret
end```
Based on that DM you chose the per-joker one under the assumption that you only needed one use case and that was more performant (not sending the context to every card if i wasn't necessary)
But in general I discourage using update for non-visual behaviors, especially when using a scripting language. Discrete function calls are IMO a lot easier to debug and more performant compared to unique update code for every object
i see i see okay
what syntax does it expect?
wait but isnt that the one im using already--
i might not be actually
yeah let me uh... add that
Is there a way to check if you beat a blind on your first hand?
(to clarify: last_hand_oneshot doesn't necessarily mean you beat the blind on your first hand, but if it's true and current_round.hands_played == 1, then you have what you're looking for)
is it normal for my consumable to lose its name
Not really!
it only happens sometimes but when it does happen its not fixed by re-hovering over it, it's consistent for that one card
bump
What is the goal?
Prevent all adjacent cards as well as this joker from being flipped.
what is the syntax for including all the suits?
Then you check if self in the hook, is one of those cards, and return nil
how does one prevent a specific card from being dragged (assuming i have direct access to the card in a variable)?
Just search in messages before asking lmao
ah got it
My wifi still won’t connect
lmao im tired
should go to bed soon but i wanna keep on programmin shit lol
I’m tired but i wanna code this shader first
I've got this to prevent cards adjacent to this joker from being debuffed, but it seems like they maintain that protection after they are no longer adjacent; how do I take away that protection?
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
if i > 1 then
SMODS.debuff_card(G.jokers.cards[i-1], "prevent_debuff", "j_willatro_skin")
end
if i < #G.jokers.cards then
SMODS.debuff_card(G.jokers.cards[i+1], "prevent_debuff", "j_willatro_skin")
end
end
end
Use context.debuff_card
And return {prevent_debuff = true}
Hey so I got the pictures from https://discord.com/channels/1116389027176787968/1341113854482059458 and I was trying to figure out if I would take each of those pics and try to crop them or so
I have never done anything like this so that's why Im super confused lol sorry bout the messages Im just trying to figure this out
What went wrong?
I borrowed some code from that Half Life SFX Tonsmith port, the json of it.
Here's the files.
you forgot a comma
Slowdown is enabled
1 hour countdown
Make an image circling where.
hey guys, i got a problem with this code
Meanwhile in #🕹・game-discussion
what an unfortunate time to ask once again why this joker ain't creating a joker of the bulgoe pool and instead just crashes
SMODS.Joker {
key = "bulgoe_candy",
name = "Bulgoe Candy",
config = { extra = { jokers = 2, money = 7 } },
rarity = "cry_candy",
atlas = "crp_placeholder",
pos = { x = 2, y = 1 },
cost = 3,
blueprint_compat = true,
demicoloncompat = true,
eternal_compat = false,
pools = { Bulgoe = true, Food = true },
loc_vars = function(self, info_queue, card)
return { vars = { lenient_bignum(card.ability.extra.jokers), lenient_bignum(card.ability.extra.money) } }
end,
calculate = function(self, card, context)
if (context.selling_self) or context.forcetrigger then
for i = 1, math.ceil(lenient_bignum(card.ability.extra.jokers)) do
SMODS.add_card({ set = "Bulgoe" })
end
ease_dollars(lenient_bignum(card.ability.extra.money))
end
end,
crp_credits = {
idea = { "wilfredlam0418" },
code = { "wilfredlm0418", "Glitchkat10" }
}
}
im suffering in #⚙・modding-general slowmode was reduced but im still annihilated
How do I add the "(Currently # <value> )" in the text of a joker? EDIT: why is there 1 hour slow mod in this chat
x2
https://github.com/Steamodded/smods/wiki/Localization read the docs
Same here :(
THE TIMER IS STILL 1 HOUR HERE AUGH
test
EGG WE'RE STILL STUCK TO 50 MINS IN THE OTHER CHAT 🙏
https://discord.com/channels/1116389027176787968/1380211377213542561
for free will
@grand violet we're all stuck in #⚙・modding-general slowmode...
no one will hear your screams clueless
go to modding threads for free will
ill miss this when i get my free will back eventually
what happened to thunk chat by the way i was too busy drawing for ortalab at that time
mm well i can just wait for someone who still has their free pass to answer
#⚙・modding-general is suffering regardless; literally try to talk about anything without "STOP USING TALISMAN" or "STOP USING CRYPTID" being posted every 0.2 ms
#⚙・modding-general try to have a meaningful discussion challenge (impossible 100)
5 seconds
the conch has spoken
all good
Don’t worry only coding nerds speak here
lois this reminds me of that time i was in the chernobyl disaster and the reactor broke down when a mod pinged @everyone
(insert hard cut to peter griffin dead pose here)
i feel like a fucking schizophrenic right now
Is it possible to use a hex color in place of say C:attention in a text string?
I have a joker border with some custom joker text I wanna apply to a joker and it's the right size at 1x
but when i double its size, it's 1 pixel too tall for 2x??????????????
aseprite doubling the sprite size doesn't change the result it's still 1 pixel too tall after that
hey aikoyori!
Thanks
so
it turns out my Jimbo for Scale was 1 pixel too big
is there any way of making a joker give mult even if they're not designed to do that?
what
oh i know what you want but
the way it was described was very funny
you mean like baseball card (right?)
you would need to hook calculate_joker or something like that to add more effects
you can always do it like baseball card yeah
😭
...yeah idk how to phrase this question i'm kinda stupid 😭
say i want to add mult to a card like blueprint-- how would i do that :P
i think so?
is it coming from a joker's effect
what are the conditions?
actually no-- i'm trying to add permanent mult to a joker
why
in the same way you would add permanent bonus chips to a normal playing card
...because that's what the joker i'm working on does? 🥲
then you would need to hook calculate_joker yes
you are the first person to answer this
out of the many people I have asked
and that is strangely impressive
idk what to tell you man, i'm just trying to implement this joker lmao
laset
good think i'm already hooking it so that's step one of that done :P
i STILL have to fix it fuckkkk 😭
your description generally should be more concise methinks
depends what vibe your mod is going for
you dont need the flavour text of "fires a laser"
my mod's purely for funsies-- it's not trying to go vanilla nor is it really trying to be unbalanced as all hell
kinda like aikoyori's shenanigans, the only difference being that a lot of the jokers have a lot to do with my closest online friend group that i have
with that being said there are still some cool things imo that are worth checking out 😅
so it's like jokebox I seee
yeah you could say so! :)
do you know what jokebox is without me telling you
i took a glimpse at it but i think it's just a collection of fun jokers right? without any particular rhyme or reason for each one?
i could be wrong on that though 🥲
My body is machine that turns sprite art into shader effect
that's so cool
woahhhhh :O
the rhyme and reason is that i fuck around and find out what happens when I make a joker that charges through your joker slots from left to right
ah wait i didn't realize you made the mod 🥲 me stupid 
jesus christ btw that is uh DAMN 😭
it's really funny thats what it is
you should do stuff like that
make a joker spin around solely because you can
the mod i'm working on has markiplier reacting to your gameplay
that's fucking amazing I love it
hold on i can grab a clip lmaoooo
i voice acted that shit horribly and everything 😭
he will casually ramble on until the joker gets triggered
that's amazing
LMFAO?
(ignore the bug at the end, that's been long fixed :))
https://cdn.discordapp.com/attachments/1409397955202387999/1410702808239443989/Balatro_-_2025-08-28_3-08-27_PM.mp4?ex=68b93b1f&is=68b7e99f&hm=f64e2536ad3d22031140a9ce11536acf105e72bb8d7f16bba81df8779111cc0b&
ah whoopsies
how in the fuck
can you help me with something
sure, what's up?
(editing it here because the slowdown bumped up :( )
well if you want it to look fancy i have no tbh... if that doesn't matter though you can just try to print text on the screen using love.graphics.print
I want text to appear in the top left of the screen when a condition is met
a second hour-long slowmode has hit the chatrooms
yeah it doesnt need to look fancy I just need there to be text
Alright guess we’re moving here
Or not
we highkey do not need a one hour long slowmode 💔 @grand violet if you could fix this that'd be appreciated
Love that I got 🇭 🇴 🇼 reacted
Did you create an SMODS.ObjectType?
nothing they can do
i mean it works for a sec but if you dont type fast enough it just doesnt work
if you get hit with 1 hour and it changes you still have to go through the entire hour
the check is server side
discord problem, nothing mods can do
i would guess so
client sometimes does desync
This channel is modding-chat-2 for hour
and i find that funny
i cant read
do these boss blinds seem too op or are they fine (these are regular boss blinds)
(for a ror2 based mod)
They are fine
nah these are good as hell
And they are well designed.
I hate boss blinds that do nothing unless you have certain build, then you die.
if anything imp overlord might be a little underwhelming
should i make it remove all chips from scored cards? or like -10?
I mean my thought was -5 but they can go into negatives (really funny) but I don't know if that's technically feasible
every boss blind should be Scary on any build and Really scary for a few specific builds
oh its feasible
negative chips 🥰
my thought is just that this makes it more interesting with like. scoring multiple times (i.e. with hanging chad)
it's so funny
me doing my gimmick retrigger build and not paying attention to boss blinds so my polychrome red seal king now has -100 chips
elusive
(I hate to keep asking but) why isn't this working? when I run this only one set works at once
switch off light mode and it will work
also i have this list of jokers if yall would like to have a little looksie
these are all based on risk of rain 2 items, which you can look at their abilities here: https://riskofrain2.fandom.com/wiki/Items#Common
yeah its fire
tougher times + oops all 6s (x3) funniest build ever
its true!
Is it possible to make a joker cause a discovered joker to be undiscovered again?
score out of any blind if you're willing to wait for it
Don't you fear react me the card's gimmick is that you forget about it xD
oh okay it triggers on itself
Yes, set center.discovered to false
fuck you (uncompletes your collection)
One way or another I will figure out how to jam that into my code
I guess in that respect the only way to complete your collection with that card is if you don't let it trigger.
joker that has some benefit but locks a bunch of random collection jokers
actually fuck you removes brainstorm from the game all together
fire honestly
Deletes the file xD
locks jimbo 😢
Deserved
I've had jimbo banned for like months tbh
opinion retconned
WHAT!!!!
What's wrong with my server
poor jimbo 😢
lets see uhhhh
would you like me to email you this thesis?
balatro but I have every joker banned except jimbo (I lose in ante 4)
hiiii
@vital crown is this fire
Spinel Tonic - 1/2 chance to debuff all cards or give 2x mult for each (uneffect by oa6s) - lunar
lunar jokers btw cannot be sold
alcoholism 🥰
hey does anyone have a link to the wiki i could bookmark?
this one? https://github.com/Steamodded/smods/wiki
if target_joker then
set center.discovered == false
else
end``` Gonna take a wild guess I'm doing this wrong
yep thanks
what are you trying to do?
I'm trying to make j_mor_nanafuse set itself to undiscovered
Quick random question: Why is there 1x and 2x by assets and does it make a difference if the image is the same size in both of them?
Thank you I'll give that a try!
for pixel smoothing, and yes one will look wrong
Wrong how?
It's expecting a bigger picture so it'll show it wrong.
if both are 1x sized then the 2x one will include multiple sprites per card
if both are 2x sized then the 1x one will show part of the card
Hi! Is there a way to reset the joker pool mid-game? I'd want to make to be able for jokers to reappear in shop even if bought earlier or are in deck
you can hook SMODS.showman to recreate showman's effect or set G.GAME.used_jokers to an empty table
thanks
Okay that worked but I broke something on it in the process so just gonna get that fixed and then I can sleep.
why do I have a 23 hours cooldown post 😭
I was offline
ah, but in this channel is only 5 seconds
If someone sees this post, please tell the mods or someone to fix the time limit 🥲
really bad news.
if you have a slowmode cooldown, mods can't do anything about that
before it was just 1hr cooldown but after the cooldown ended someone put it on 23hr cooldown
even if they change the time limit you'll still have to wait out whatever cooldown you had stocked up </3
.
you will need to wait
nvm got it working
(small update they fixed the cooldown lol)
How do I make a joker not spawn but still spawn from judgment
Okay somehow ended up with the card deleting itself and then saying his goodbye message but I think that actually might be more fitting so it stays.
But otherwise I now have a card that forgets itself let's go
Fuck yeah
I was actually looking at the wiki before you sent that so
Thank you tho my goat
I should really read the wikis
They might actually help
can someone help me again with sticker issues? https://github.com/Steamodded/smods/wiki/SMODS.Sticker says i can just add rate for the chance of applying a sticker and sets for it to only be applied to jokers but it is not working :c
do you have a should_apply?
yeah
it overrides them
i dont think you can, you need to check manually for the set and the rate in should_apply
but never worked with stickers
do we fw this deck art (left) , based on this character (right)
better look at the deck art
looks good :)
Put and SMODS.Sticker.should_apply(self, card, center, area, bypass_roll) in the return of should_apply?
mmm captain deck,.,.
he's cool :)
Actually how would I do this, do I just list all of them or
should it just be something like this?
return SMODS.Sticker.should_apply(self, card, center, area, bypass_roll)
end,```
literally just invert the condition on the second example lol
Man
No, add it to your current return
wdym
I have a joker (the top) turn into 1 of 4 random jokers, but I want those 4 jokers to not spawn anywhere but that
okay! it doesn't spawn whatsoever now, do i need to configure something else or?
Code?
pseudorandom_element ignores in_pool so you would only need to return false
Like this?
Cause it's giving me this
are you sure the object type has things in it
yes
ok not to reply hella late but I've been monitoring like 5 channels so I didn't see this til now. anyways looks really good I like it :3
hi :3
fuck man
i mean you can set it to animated and make it 1 frame
Pretty sure
i mean i see that but you should check if it's loaded correctly in-game
Unless this is not how you do it
idk objecttypes are weird
Yeah
you're so smart
maybe you need to put the ObjectType after all the jokers not before
My cookies
slowmode is very annoying..
egg plz fix
Probably
Still crashes
do you have debugplus
can you eval G.P_CENTER_POOLS.Dalgona in the console in the main menu
huh weird then
5s is fine
maybe pseudorandom element respects in_pool?
Lmao
Again it's saying this is the problem
-# ik you know but I just wanna say words
But yeah idk
oh yeah it does
So how would a birdbrain like me go around this
Make the third input {in_pool = function() return true end}?
i thought it was only for ranks and suits... maybe i can use this actually
You're welcome? 😭
teto referenc
Yes
peak
Boom
TETO JOKERS,.
So like this?
No, of pseudorandom_element
Soon you'll be able to play it
after 'dalgona'
Can't wait
Like this
Yes.
wat does AT in an uibox mean 🤔
attention text i think
AT?
Use wiki.gg instead, it's the most up-to-date/community-supported one: https://riskofrain2.wiki.gg/wiki/Items#Common
SMODS.ConsumableType {
key = "Powerup",
primary_colour = HEX("14b341"),
secondary_colour = HEX("12f254"),
collection_rows = { 4, 4 }, -- 4 pages for all code cards
shop_rate = 99,
default = "c_mush_mushroom",
loc_txt = {
-- The simplest option: use a single table
label = 'Label',
name = 'Name',
text = { 'A moderately long', 'description of', 'your effect.' },
},
can_stack = true,
can_divide = true,
}
SMODS.Consumable({
key = "mushroom",
set = "Powerup",
object_type = "Consumable",
name = "mushroom",
loc_txt = {
name = "Mushroom",
text={
"test",
},
},
config = {},
pos = {x=0, y= 0},
order = 99,
atlas = "mushpowerups",
unlocked = true,
cost = 4,
hidden = false,
use = function(self, card, area, copier)
print("Hello worl")
end,
can_use = function(self, card)
return true
end,
check_for_unlock = function(self, args)
if args.type == "test" then
unlock_card(self)
else
unlock_card(self)
end
end,
})
Morning guys, i'm not really sure what i'm doing wrong, i'm trying to create a new consumabletype and a consumable of the same type but it shows this instead 🫠
No, because that doesn't exist.
No, object types don't have prefixes.
oh

i forgot how to consumable mb
it is undiscovered because you didnt put discovered = true and im willing to bet you dont have an undiscovered powerup description defined in localization
loc_txt wants a "collection" entry
What function would i hook into so that levels had a 1 in 2 chance of not happening (for a stake im making)
wdym?
i did a mistake there?
Well, here it is, awesome
for the consumabletype
thats why the collection shows ERROR
loc_txt wants a "collection" entry
next to label and name etc
So, i just add collection = "name"?
level_up_hand
why does it does nothing?
Yeah i figured it out after digging through the game files a bit
A main issue im having is the function doesnt seem to be hooking after i reload the game
how might I select a random common joker
I don't want to spawn it I just want to pick one
i figured it out
damn i was too slow to @ mods 😔
Why does this just not get done? Not even the print goes through
G.GAME.current_round.cstorm_captcha_card and
context.other_card:get_id() == G.GAME.current_round.cstorm_captcha_card.id and
context.other_card:is_suit(G.GAME.current_round.cstorm_captcha_card.suit) then
print("Works")
return {
repetitions = card.ability.extra.repetitions
}
end```
i want to ensure that the consumable can only be used when the hand is visible (e.g. in a blind and in a tarot pack), but this code allows it to be used at any time
check the code for the spectrals that add cards to hand
i think they check if the hand has a card
i see
so basically since only in those two scenarios does the hand have cards in it
limiting it so that there has to be at least 1 card in hand ensures it only happens in those scenarios
Hello friends! I'm having trouble with a joker for my mod
yveltal here is supposed to display an xmult value in its description, but right now the value is just "nil", and whenever it tries to score the game crashes
so there's something missing and i don't know what it is
bump (And another quick question: Do Jokers need to be 71x95 or can they also be different sizes, like wider and smaller?)
...so should i remove the other two
yes
this is why we use a good code editor
it makes it darker to let you know it's not used
holy
vscode my beloved
ho-oh detects if you discard exactly three cards, destroy them, and replace them with three randomly enhanced face cards
How's the shader guide going, if I may ask? :3
i was playing around yesterday and made a glass shader
you can find it in fanart if you search my messages
it's still incomplete
small question, does SMODS change is so that for every pack you open G.STATE becomes 999?
but right now it's only destroying the first card
Yes.
bump2
noted, thank you
ill probably have to rework this mess into a more general function but for now this works hooray
bump
anyone have a tutorial on how to make a balatro mod?
check the pins in #⚙・modding-general
Do Jokers need to be 71x95 or can they also be different sizes, like wider and smaller?
how do you alter the effect of enhancement with Joker
i.e Mult card gives +8 instead of +4 Mult
hello, is there a way to make like "folders" of hands in the run info section of the game ? i plan on adding new hands, but theres quite some and i want it to look clean
i made a rarity and it simply displays as ERROR textwise
Did you add it into your localization?
71x95 for 1x asset AND the double for 2x asset
you need both
But does it have to be in that range or could I also do 100x100 for 1x and 200x200 for 2x on a joker?
oh shit i need a localization
can i just peut a loc_txt in the rarity
i have no idea what you're talking about
its pretty clear, 71x95 for the 1x asset and the double for the 2x asset
I don't use loc_txt so I don't know how to do it there, sorry
you can put several jokers on 1 image asset, you just need to extend the image abd separate them by a pixel
not from the API
that sucks, is there no dependecy type mod that could make that possible ?
On the left is a regular size, on the right an example of a joker sprite I want to do. So I'm asking if it is possible to do the right one instead of the left one or if I have to use the left one
its possible, but you need a seperate atlas for it and need to specify the size in the joker
yes there is
Okay, thank you
bump, joker is only destroying first discarded card when it's supposed to destroy all three
oh like, 'hide' vanilla/custom hands is possible ?
doesnt context.discard trigger once for each discarded card?
yes, visible can be a function and you can hook SMODS.is_poker_hand_visible
i have a set of 18 pokerhands in my mod that i hide if you dont have an enhancement in your deck
idk, i didn't code it
hmmm now that i think about it this might be causing problems with quantum enhancements lol
oh pretty nice, whats the name of your mod ?
quantum enchancements my behated
well you need to modify your if context.discard code to only set extra.activated to false on the last discard card
i think
Quantum ranks...
If nobody's making quantum enhancements I'll fucking do it. I'm crazy like that. I'm straight up deranged
quantum enhancements exist but i hate them because having a stone quantum enhancement just fucks the card up
and i want a stone quantum enhancement but also have the damn front visible
how would i do that?
if your stuff only happens on three cards, you could do
card.ability.extra.ad = false
end
instead of the current check
probably not the cleanest way but since the rest only triggers on 3 cards discarded i think its fine?
couldnt you just check if #context.full_hand == 3 in the conext.discard check? i imagine it also exists in context.discard
that would mean only the third card gets deleted no?
wait no sorry hold up
card.ability.extra.added = false
return {
remove = true,
}
end```
yeah this would work
im not braining rn
so i replace the current context.discard function at the very end?
is it possible to use that on vanilla hands ?
Using pixel_size?
yeah
hook SMODS.is_poker_hand_visible
keep in mind they can still be played
IT WORKS TYSM
youre thanking the wrong person
thank both of you :3
It doesn't show it right...
what did you put in?
pixel_size = { h = 50, w = 175 },, the same as the 1x image is
what about the atlas definition?
im highkey ass at this, what does hook means, sry keeping you with this
key = "human_captcha",
path = "human_captcha.png",
px = 175,
py = 50
})```
i think you need to set the display_size on the joker to the same as the pixel_size
Hooking is a redeclaration of an existing function, using the stored original function declaration as a primitive form of inheritance. Essentially, store the value of a function in a local variable, then declare it again, and inside the new function declaration, call the local value as a function. Then you can essentially add to that code in the new function declaration
Changes nothing
oh okay right
SMODS.is_poker_hand_visible would be the function i have to redeclare if i understand well
lets gooo i can do this stuff way cleaner now 🥳
I don't understand it. Why does it do that TwT
and then i pressed skip and my shop aint coming back 😭
you can set certain sizes in atlas defining too
alright i've come with another tweak
forget it anyway, i think itll be way easier to disable/debuff them
Someone help me make a talisman fix(there's only one thing missing but I'm having trouble figuring it out)
how the [[FUCK]] do i define xchips
Return xchips = number?
return xchips=number
``` will error
OH WAIT I FIGURED IT OUT
this guy does x2 chips and some other stuff if that helps
transformed code: local create_number(h) =create_number(2)local create_number(x) =h+g
nvm 😔
ok i did that then it didnt work then i retried it and it works now
thanks
I made an enhancement called "Dirt card" that should become a "Bloom card" if held in hand at the end of the round.
The problem is that it still doesn't do that, it doesn't do anything, how do I fix this?
Why does my Joker look like this? It doesn't use the whole png but I've set it to the size of it
Remove context.main_eval
display_size = {
px = 71 * ???,
py = 95 * ???
},
i think
two jokers i'm working on, Koraidon and Miraidon, apply red and purple seals to played wild and steel cards respectively, but if you play the same cards it just applies again, without changing anything. can we make it check if there's already a red or purple seal and not apply it if there is?
Why * ?
if card.seal ~= "Red" then card:set_seal("Red") end
will that prevent the seal being placed if there's already a red seal?
at what point is it okey to put our own mod on the modding forum ?
it still doesn't turn into a bloom card
Yes.
Remove local card = self
Still doesn't work
sadly still nothing
where should i put it in the code?
Wait, doesn't cryptid have a joker that is bigger than normal?
Remove context.game_over == false
How do I go about starting to mod for balatro ?
Replace temp_card:set_seal("Red", true)
cool, thanks