#💻・modding-dev
1 messages · Page 537 of 1
ohhh i didnt know there was a context for debuffing cards, i shouldve looked for that, thank you!
whats the best mods for balatro
edward robinson
I like bunco, paperback, buffonery, cardsauce and lost edition (mine lmao)
but every time I explore I find more good and fun mods
If you like high points, Cryptid might be interesting.
uh and can i all these mods togehter
Opinions vary wildly and a lot of people will just say their mod
If you're willing to deal with cryptid:
Entropy
Vallkarri
If not:
Paperback
Ortalab
HouseRules
Grab Bag
TheAutumnCircus
Tangents
Quality of Life mods:
Handy
DebugPlus
(I can't overstate how good these two mods are)
or they wont work togeter
You should be able to
Unless the mod specifically says "conflicts with [mod]"
ohk
I didn't declare conflicts in my mod but it conflicts with everything 😎

joking, or not..
How the fuck did I forget Maximus 😭
so this line is crashing:
G.shared_stickers[v.key].role.draw_major = self
When trying to change
local main_menu = Game.main_menu
function Game:main_menu(context)
self.shared_stickers = {
White = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 1, y = 0 }),
Red = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 2, y = 0 }),
Green = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 3, y = 0 }),
Black = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 0, y = 1 }),
Blue = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 4, y = 0 }),
Purple = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 1, y = 1 }),
Orange = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 2, y = 1 }),
Gold = Sprite(0, 0, self.CARD_W, self.CARD_H, self.ASSET_ATLAS["ina_stake_stickers"], { x = 3, y = 1 })
}
main_menu(self, context)
end
Don't really understand what's happening
huhhh
got this
i have like 13 mods enebed
and tried to run the game
what to do
if i have multiple lovely files what order do their patches load in?
disable half your mods
it's a cardsauce issue
you can try that, yea
k
if you don't know what the issue is its the best way to find out
dont do that now though
how do i make it so that boss blinds award no money outside of challenges? G.GAME.modifiers.no_blind_reward gives the first crash for some reason (if i append .Small, .Big, and .Boss to three different lines it's the second crash)
Yoo its working, i disabled card sauce
Yeah ig thats true
hello hi, this big guy keeps crashing my game, can anyone help me figure out what's happening ?
you're missing an end
if i had to guess it'd load by priority first then by file order?
i may have found it
line 48 according to the crash
Do you have VSCode, by chance?
nvm i didnt
positive or negative priority if i wanted it to load later
i putted it indeed in 48
yes vscode
also a new error shoed up wait
"dependencies": [
"Steamodded (>=1.0.0~BETA-0323a)",
"Talisman (>=2.3.0)",
"Lovely (>=0.6)",
"Malverk (>=1.0.0)"
]
}
Why is malverk dependency always throwing error if I have latest release?
how
you click the link
...
click the link
im going to say negative, but i don't have much experience with toml priority so you may want to double check
what does it does ?
it lets you know where things went wrong in your code before you try playing it
is it not all colorful now
ok wait
look for the red lines and it tells you smth like this when hovering over it
then you just
look
did you actually install it
send a screenshot of your vscode
yeah
the issues are in red
and it says what the issues are
you just need to
yk, fix them
okay well if you prefer not seeing errors you can do that then
if it's about the theme colors you can get a different theme
not what im saying
(these are 3 different links, 2 of which are wikis, please use all of them as they are all useful)
ok nvm this joker ill redo everything from the start
bump
G.GAME.modifiers.no_blind_reward = G.GAME.modifiers.no_blind_reward or {}
that worked (i need to remember to look through the SMODS src more), ty!
inspect(table) or, for depth, inspectDepth(table).
For malverk, how do I define new textures for perishable, rental...
does anyone know the demension of the tarot cards
i think its 63x93
but i not sure
Thank you!!
71x95 including 1px of padding on all sides, 69x93 of actual size
Oh okay
not 63, 69 but ya
i was running 63 x 93
and the outer box was okay
the internal art looked all fucked up
yeha if you were using 63x93 then itd be wrong, its 69x93 when you dont include the padding
did you just stretch it out to be wider
na its 69 by 93 if u count the pixels there
oh wait im sorry im a fucking idiot
is the default can_use behavior (involving max_highlighted) implemented in vanilla or smods
consumables have way more padding than jokers
i feel accomplished
yeah doxy that was my fault you were right about the resolution
on the spritesheet they take up 71x95 but their actual size (including padding) is 65x95
please do help im as useful as stone when it comes to coding im tryna re-skin all tarots to resemble stands in jos cuz the names are similair to some
ohhhh oks
this is a placeholder tarot as an example
thank you
wtf is mod_num
i think thats supposed to be like an equivalent of min_highlighted?
i guess death just uses a wierd name for it
I wonder if this definity is okay.
--[[ Flush Mansion ]]--
SMODS.PokerHand({
key = 'flush_mansion',
-- visible = false,
mult = 28,
chips = 240,
l_mult = 8,
l_chips = 80,
above_hand = 'cpp_six_of_a_kind',
example = {
{ 'S_J', true },
{ 'S_J', true },
{ 'S_J', true },
{ 'S_J', true },
{ 'S_4', true },
{ 'S_4', true },
},
evaluate = function(parts, hand)
if #parts._4 < 1 or #parts._2 < 2 or not next(parts._flusher) then
return {}
end
return { SMODS.merge_lists(parts._4, parts._2, parts.cpp_flusher) }
end
})
With the flusher coming from:
SMODS.PokerHandPart({
key = '_flusher',
func = function(hand)
return get_flusher(hand)
end
})
Oh, looks like I don't need the _ at it is added to the poker hand part
Can you create custom stickers (rental and so) on malverk?
How to increase max number of played cards to six? D:
can i place an effect twice in the same return to have that effect happen twice in one go or will there be overrides happening if i do that
yeah you can
I'm trying to
But I don't find the way
I've managed to create stake stickers
but not rental or perishable
uh try asking the malverk thread? im not too experienced with malverk
Increasing the highlight limit maybe?
So I place it at the main.lua file?
whenever you want to change it
I want to allow six cards play, highlight (selection?) and discard
So I guess using:
SMODS.change_play_limit(6)
SMODS.change_discard_limit(6)
Is fine?
like as long as you have a joker?
No, always (no matter if voucher, joker, etc)
so basically if your mod is loaded?
Yup yup
That'd be increasing the play and discard limits by 6...
tables cant have duplicate entry keys as far as i know so it will probably override? but idk why you would ever need to return the same value multiple times
you'd have to hook the function that starts a run and do
SMODS.change_play_limit(1)
the number parameter is how much to increase th limit by
So 1 is the argument for my case?
doing smth twice
Which hook function is that?
I made contexts manipulate
gasp oh no, hooks! Faints from fear
couldnt u just have the joker retrigger itself
or card
hook G.start_run()
for any scoring effects you can just add/multiply the values depending on what it is for the same effect, same with any money effects. though you could probably also use SMODS.merge_effects or whatever its called maybe
idk if thatll let it happen twice visually tho
you could use SMODS.calculate_effect multiple times instead then maybe?
maybe
-- CelestialPlus.lua
function G.start_run()
SMODS.change_play_limit(1)
SMODS.change_discard_limit(1)
end
Like this?
does anyone know what function passes loc_vars to the joker description
Honestly closer than some other attempts I've seen
nonono
so you need to save G.start_run in a variable first
local start_run_hook = G.start_run
function G:start_run(args)
SMODS.change_play_limit(1)
SMODS.change_discard_limit(1)
start_run_hook(args)
end
That's just overriding it
Ah... hooking like Lua, I am dumb
Imagine if I ran the build and started the game 💀
What
what line is line 22
G.start_run hooks need (self, args), at least from what i gathered from another mod's hook of it
Gotcha
G:start_run(args) is the same as G.start_run(self, args)
oh, good to know
hmm maybe start_run is not the right time to adjust the size
If the increased selection limit is for a deck, do it in an event under apply of it instead.
my only idea left as to what's wrong is that one of these variables don't exist in start_run
Hmmmmm
oh no
maybe you can check other mods to see when they do it?
Cryptid does inside a voucher AFAIK
I was checking it :/
hold on, wait a second
i want you to try smth
local start_run_hook = G.start_run
function G:start_run(args)
start_run_hook(args)
SMODS.change_play_limit(1)
SMODS.change_discard_limit(1)
end
Okay uwu
thanks for the image
im trying to juggle 3 different things excuse me for fucking up once
its funny tho
@mossy orbit try that
Death
start_run_hook(args)
Let me pass the self this time
local start_run_hook = G.start_run
function G.start_run(self, args)
ret = start_run_hook(self, args)
SMODS.change_play_limit(1)
SMODS.change_discard_limit(1)
return ret
end
try that
On it
Okay, game didn't crash at the start but
When I tried to pick the six card, it went oooof
But now it is a different error at my custom poker hand
shouldnt it be Game:start_run
probably doesnt matter if G is never remade
Okay, looks like I missed the mod prefix when using the parts inside the evaluate of my PokerHand
Oh wow, it works!
cat kiss gif
I was just going off of house rules
Wait a minute....
uhhh..
Why I can select 7 cards lol
Exactly lol
how do i implement a custom challenge rule?
rules.custom, probably (idk ive never done custom challenges before)
why does the hook i have (right) work on some jokers, but not others (left)? shouldn't it always set the joker to perishable no matter what?
Well, I will keep the 7 discard and play card in the meantime as no clue why that happened. Thank you creature uwu
perishable incompatiblity
runner can't be perishable because it's a scaling joker so it doesn't get the sticker
i see that now
-# what if, to be extra evil, i patched it to make an exception if this rule is active :3

That would be too much evilness
or just ban everything that is incompatible like in the all eternal challenge
these are supposed to be difficult challenges
Gotcha 🙂
i don't want to ban any cards that the player doesn't choose to ban through selling, destroying or exiting shop :3
wait i could just do this lmao
My last issue before oaths are done:
For some reason, this doesn't destroy cards that have been played twice this ante, but idk why. I dont want to use SMODS.destroy_cards because that tends to mess things up when destroying playing cards
-# (before you may ask, yes this is in a calculate)
remove = true only works on context.destroy_card or context.discard
local create_args = {
set = 'Joker',
key = 'j_ina_Shadow',
edition = 'e_negative',
loc_vars = function(self, info_queue, center)
return {
key = 'j_ina_Shadow_clone',
vars = {}
}
end
}
local _card = SMODS.create_card(create_args)
So the loc_vars attribute does not work here right?
no
So Is there any way to change the text of the newly generated card?
it's your own joker so you can just put that in its own loc_vars and set a flag when you create it to use that key
how would one go about changing the background colors on the title screen
how would a close a UI i created? i have a consumable that pops a ui up on use, and id like it to close after a button in the ui was clicked
i may be doing dumb stuff :clueless:
G.FUNCS.exit_overlay_menu()
well at least the back button is usually bound to it
iirc
yo im trying to make a tarot card to use my new enhacement. i know the enhancement works fine, but when i use the tarot to make the cards into that enhancement it crashes with this:
maybe the key is wrong
shall i send the tarot and enhancement code?
go ahead
-- Tarot Cards
SMODS.Consumable {
key = 'miner',
loc_txt = {
name = {
'Miner'
},
text = {
"Enhances {C:attention}#1#{} selected",
"card into a",
"{C:attention}Diamond Card",
}
},
set = 'Tarot',
atlas = 'jam_tarot',
pos = { x = 0, y = 0 },
discovered = true,
config = { max_highlighted = 3, mod_conv = 'jammbo_diamond' },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS[card.ability.mod_conv]
return { vars = { card.ability.max_highlighted, 'Diamond Card' } }
end,
}
--Enhanced Cards
SMODS.Enhancement {
key = 'diamond',
loc_txt = {
name = "Diamond Card",
text = {
"{X:chips,C:white} X#1# {} Mult",
"while this card",
"stays in hand",
}
},
atlas = 'jam_enhancements',
pos = { x = 0, y = 0 },
config = { h_x_chips = 1.7 },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.h_x_chips } }
end,
}
here ya go
is the prefix of your mod jammbo?
yup
you're missing the m_
where
the enhacement
m_jammbo_diamond
yes
mod_conv = "m_jammbo_diamond"
ahh okay
yep
so j for joker and m for enhancement and t for tarot got it
should be the only thing
c for consumable
oh
theres no t prefix for tarots
close enough
^^
planets, spectrals, and tarots all have a c_ as a prefix
what are you trying to do
it took a lot of messing around but i got it working! Ty!
Iterate through a card's extra table and add or subtract to each value
for what reason
That's what the joker does!
the joker is designed to crash the game?
or is adding one to extra supposed to do something
No uhm the joker is supposed to add 1 or subtract 1 to each of the joker's values
does anyone just have like an example of an SMODS.deckskin the wiki just gives me a list and im very confused
the smods examples repo
personally I wouldn't recommend adding to values indiscriminately but if you want to do it anyway you would need to first check if extra exists and it's a table, # won't work because extra is usually not integer-indexed so the length is 0 (it will crash if it's not a table as well)
then you need to iterate extra using pairs for the aforementioned reason and for each value in extra you need to check if it's a number and then add one to it
keep in mind most vanilla jokers and many modded jokers don't exclusively use extra to store values and not all values stored in extra are score related
this is the joker effect :3
i be multiplying
its actually where i discovered joker had a base 1 for xmult and xchips
i think that's heresy personally
then make me a better way to do it smh
i believe modifying jokers values without consent is bad
they consent by the edition existing
im going to turn u polychrome
i would evolve
if the joker of the left has like 0.05 chips it becomes -1.05?
Yes
correct
What do vanilla jokers use instead of extra tables I'm actually curious
SMODS.Joker {
key = "hermit_joker",
config = { extra = { Xmult = 2, mult = 20 } },
rarity = 1,
atlas = "pok_jokers",
pos = { x = 0, y = 0 },
cost = 5,
blueprint_compat = true,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.Xmult, card.ability.extra.mult } }
end,
calculate = function(self, card, context)
if context.joker_main and mult * card.ability.extra.Xmult <= ( card.ability.extra.mult * 2 ) then
return {
mult = card.ability.extra.Xmult
}
else
return {
mult = card.ability.extra.mult
}
end
end,
}
this crashed when i selected the blind with a failed attempt to perform arithmetic on "mult" (or something like that), how do i fix this
the whole ability table
on center config and otherwise ability
the reason modded is recommended to use extra is not to clash with the ability table
you can restricts the values you're gonna increase by looping through the values in the config center when increasing vanilla joker values
a good friend is helping with the russian localisation and their translation of the mod name made me wonder if that is a possiblity or it is tied to the folder or metadata name
and if anyone is curious
you can do this
https://github.com/nh6574/JoyousSpring/blob/fccf9b31877fad1003c1f9ff959d4f58f66aab22/localization/default/00_00ModInfo.lua#L4
idk if it affects the badge
i am talking about the mod name itself
any documention on G.PROFILES[G.SETTINGS.profile].career_stats?
Only thing i can think of is joyous springs
ts was prolly asked up in chat but how do i get the custom joker names for my mod bc I got a whole ass table set up and it js aint loading
do you have a loc_txt table or a loc file of the language you use
J_modprefix_jokerkey
Small j
do booster packs use a loc colour
-# I have too
red card has the attention/yellow colour but my voucher already has +1 as attention/yellow
thinking on either keeping it the standard colour or maybe blue or red?
Oh you mean in the loc_txt
yeah
I think it’s depends on the booster type
yeah it is
I would just make it PURPLE
like maybe this is good enough
Good enough
Okay so it crashes for some reason cool cool cool cool
It’s always like that
i'm still very lost about making balatro mods but I'm js hoping ts works when I put it in the code
bad news chat it didn't work
i'm gonna kms and see if that fixes it
I think I put the code in wrong actually 1 sec
Uh why are you using JS or TS instead of Lua?
.
the worst part is I know jack shit about code so I can't tell if you're joking or not
I mean, follow the SMODS docs to learn how to make mods
There is also a tutorial in YouTube
Welcome to the second edition of Balatro Modding 101 tutorial.
Steammodded upgraded their logic so i re-made this tutorial!
In this beginner-friendly guide, I'll walk you through the steps to get started with modding in Balatro. Whether you're looking to install mods created by others or dive into making your very first mod, I've got you covere...
every tutorial I look up tells me to change it in the game's files itself but I plan on sharing this mod and want the joker names to stick
if I change it in the game's files for myself then it will only apply to my game
Follow above tutorial, you should be able to make your own jokers/ consumables / etc
And make it shared as your mod
thinking on having the second one unlock if you buy a certain number of booster packs
How do I change the icon of the mod? Instead of a green jester, use my own png or something
Thank you!
do you want to just change the name of jokers?
Hey, question: Is there a way to make so a button in a UI sends the user to the mod config page?
yup, I'm making a mod that reworks the appearance of all jokers
this is a texture pack that changes the names of cards
it uses malverk
https://github.com/xssgm/Touhou-Balatro-texture-pack/tree/main
thx gng
thinking that a better way to improve the idea of the booster pack limit is instead have the second more expended one being where you can select or spawns another card so in a mega pack it can be either 3 of up to 5 or 2 of up to 6
still ain't goin well but I think I'm getting somewhere?????
fucked my mod up so bad it ain't even load anything anymore I may be cooked gng 💔
ong I'm boutta js give up on the renaming part n js make ts a reskin mod
which one is more balanced
The second one would be +1 choice instead of size btw
i know i am prototyping if i do the second
im asking which one is more balanced
if you want i could do one and then the other
I think the size is more balanced ever so slightly because of more booster skipping opportunities on the choice one
But that's literally it
you have a point not fully sure how to do that
not even the other
looks like both are config/loc vars but is there a way to permanently edit those to increment by one
the booster size?
i think? like for example of a normal size you get four cards
in the next version of smods you just modify
G.GAME.modifiers.booster_choice_mod and G.GAME.modifiers.booster_size_mod
next version? 👀
thought about it and i think both can work, i'll leave their redeem function empty for now but thanks
Does this functionality work
I was wondering how to do it recently
What if you don’t want to modify all Boosters
I only wanted to change some specific ones ;P
pretty sure you can do an if statement for the kind of booster pack (either it would be a new kind of easy return or you can brute force with a for if contain loop) and THEN modify the booster
I mean I imagine it’s doable I’m curious how other people are doing it
How are you doing it
then patch/hook the parts that use that
https://github.com/Steamodded/smods/pull/814/files
its empty rn just waiting until the next release as the two methods nh mentioned to do that
Build-Your-Own Joker
bump
any possible reason this isn't working? the png is 138 x 744 and the atlas is set to 138 x 186
do you like my sword sword my diamond sword sword
for some reason i can't change the soul pos of this joker specifically
okay wait i can
If the soul is at y2 then it changes, shows that post_joker is working but the set_sprite_post for joker_main and pre_joker aren't
what gives?
We love ⅓ of a hand
we love hooks
not sure if i did this right i skipped 12 booster packs and it hasn't updated maybe it needs to be a saved variable?
can you change the logo thats on the title screen? if so how would i do that
Does anyone have an example of inserting a stake between two vanilla stakes?
Previously asked: #💻・modding-dev message and #💻・modding-dev message without an answer.
I have the following code:
SMODS.Stake {
name = "Silver Stake",
key = "silver",
applied_stakes = { "orange" },
unlocked_stake = "gold",
atlas = "Chips",
pos = { x = 0, y = 0 },
sticker_atlas = "Stickers",
sticker_pos = { x = 1, y = 0 },
modifiers = function()
G.GAME.modifiers.enable_preorder = true
end,
colour = G.C.GREY,
shiny = true,
loc_txt = {},
above_stake = "orange"
}
SMODS.Stake:take_ownership('gold', {
name = "Gold Stake",
key = "gold",
applied_stakes = { "silver" },
pos = { x = 2, y = 1 },
sticker_pos = { x = 3, y = 1 },
modifiers = function()
G.GAME.modifiers.enable_rentals_in_shop = true
end,
colour = G.C.GOLD,
shiny = true,
loc_txt = {},
above_stake = "silver"
}
)
But it still shows up at the end of the list and does not unlock correctly.
I added orange stake to the above code to chain to the silver:
SMODS.Stake:take_ownership('orange', {
name = "Orange Stake",
key = "orange",
unlocked_stake = "silver",
applied_stakes = { "purple" },
pos = { x = 1, y = 1 },
sticker_pos = { x = 2, y = 1 },
modifiers = function()
G.GAME.modifiers.enable_perishables_in_shop = true
end,
colour = G.C.ORANGE,
loc_txt = {},
}
)
This changed the behavior I am experiencing. Now Gold Stake no longer works, (it tops out at Orange.)
With the part of it showing up at the end of the list, you can fix that by adding , true after the final }
would this be relevant?
that's what i used for mine to apply a vanilla stake and for it to be above gold
Also, you do not have to recreate the entire stake object from scratch, you can remove everything that you didn't change
context.identifier and context.identifier == 'soul'
is that checking if a soul is use
oh ok
js here checking in, still struggling w/ getting the text implemented (The 2 examples and all the helpful replies did nothing asides from break my mod and make me recode half of it < / 3)
so what should Iuse
if context.using_consumeable and context.consumeable.config.center.key == 'c_soul' then
Astra has Hot Potato begun

I guess we'll never know
oh ok thx
guess not
Okay, i must be stupit: why cant it find this enhancement center:
scored_card:set_ability('mode_m_flesh_zygote', nil, true)
SMODS.Enhancement { -- Zygote
key = 'flesh_zygote',```
mod key is mode
m goes first
i am stupit
this code makes all the cards in the deck lucky cards, how do I change it to only apply to specific ranks like aces or face cards?
for i = #G.playing_cards, 1, -1 do
G.playing_cards[i]:set_ability(G.P_CENTERS.m_lucky)
end
Use ifs on such specific ranks i guess
I thought, after reading the enhancement wiki that this should work, but it doesn't appear to? Am I misinterpreting x_mult?
SMODS.Enhancement { -- Smooth
key = 'flesh_smooth',
pos = { x = 3, y = 0 },
atlas = "ModeEnhancements",
config = { x_mult = 1.75},
replace_base_card = true,
no_rank = true,
no_suit = true,
always_scores = true,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.x_mult}}
end,
}```
Wanted it to be below gold. I was under the impression that too of the list was default behavior
yo gng I think I've tracked down the issue of my mod not loading the custom text for the jokers but js wanna check with ppl who know how to do ts stuff
right after alt_texture I put Joker because that's the same thing as the key = "Joker" but idk if that's right
Thanks!
Inside of the call to take ownership?
Im js gonna keep brute forcing it ig i'll check back in later
is that fucking notepad 😭
Please use VSCode 😭
i will literally be ACTIVELY ignoring your problems here :3
gng it WORKS DW
nah but on a serious note, using visual studio code is much more efficient than notepad lol
theres, really no reason why you gotta torture yourself like this 😭
It does work, but it doesn't work well
just because it works doesnt mean you should
guys i looked up vscode and now my discord is grey what curse have ye layed upon me
-# is discord not gray
wtf 😭
im back
am i colorblind
i thought it happened again but no vscode just has the worst website background ever I think I just hit two frames per second
when I attempt to retrigger this joker, i get this crash
any ideas?
btw i'm retriggering it through a "red joker seal"
this also happens when i try to retrigger it through other modded avenues, such as "the normal joker" from paperback mod (which retriggers all common jokers)
How do I prevent this like I want my consumable to be rare in my packs but I don't want them to spawn in spectral pack
add soul_set = '[your consumable type]'
so likely soul_set = 'Giga_Food'
do I remode the hidden = true
no need
like this
yeah
thx
soul_set consumables can still appear in spectral packs (e.g. The Soul is soul_set to Tarot packs)
i got vscode but i don't think it rlly mattered because even after moving my text into the right file it still ain't workin < / 3
i think that's because The Soul itself is a spectral card
if they're part of the same set it should be fine?
actually yea you're prob right
I'll test it out for seeing who's right
I oppened thes same pack that I my consumable and it didn't appear in it
so thx
very cool
at ts point im js figuring ts out on my own but this is tripping me up is it supposed to be this or nah
it should just be
descriptions = {
Joker = {
j_textestingmod_joker = {
ah
thank you
js to make sure the text + { "Description placeholder..." } part being in {} is not the issue?
no that's how it should be
alr thx gng < 3
still not loading, I will figure this out before it makes me kill myself thank you for the help
here's the main.lua it may b a lil autistic but i love it all the same
edward i dropped me feckin main respond lad
i can't help u I just told u to post it so someone could
I'm off my pc for the night
What's the problem
me mod text is nae loadin in lad
i cannae get it ta work i been swappin around statements n shite all night
Can you show the localisation file
And maybe the metadata file
As well as what's showing ingame
it's just showing the base balatro names and descriptions in game
this is the localisation file
Ayone know if its possible to have a joker cost money to sell? I see people a few months back used card.sell_cost but I keep getting crashes when using it. Do I just put into the calculate function or is there something specific I need to do beforehand?
What is the goal here because I don't think this will do anything at all
Are you trying to change vanilla jokers?
Okay well you should probably learn the basics
i have frankensteined 30 guides, 30 of which were useless, together with like 2.5 mods
and this came out
istg if I spent 2 days tryna make ts work and it's been doing nothing this whole time I'm gonna crash out so hard mao zhedong will cry himself to sleep in his grave
Change texttestmod_jokers to Jokers
I think you should maybe learn Lua and study the wiki a bit
hey that was the same fix for when my main.lua wasn't loading my image files
I had Jokers instead of Joker
You should only do what when changing vanilla content btw
When making custom content you should generally make an atlas with a different name
This enhancement is supposed to give +12 Mult before cards are scored, but it does nothing instead. I know scoring is a little different for enhancements, did I do something wrong here? lua SMODS.Enhancement { -- Fat key = 'flesh_fat', pos = { x = 4, y = 0 }, atlas = "ModeEnhancements", config = { extra = { mult = 12}}, replace_base_card = true, no_rank = true, no_suit = true, always_scores = true, loc_vars = function(self, info_queue, card) return { vars = { card.ability.extra.mult}} end, calculate = function (self, card, context) if context.initial_scoring_step and context.cardarea == G.hand then return { mult = card.ability.extra.mult} end end }
Try:
REMOVE if context.initial_scoring_step and context.cardarea == G.hand then
ADD if context.before and context.cardarea == G.hand then
No but context.before specifically happens before scoring, and clears all the scoring stuff when scoring happens. I mean, i can try it, but its literally why context.initial_scoring_step exists
It also does nothing
It may work, it may not. Give this a look.
I'm well aware of the calculate functions here. I tested it with a print and it's not even passing the if statement.
Oh, it was because it was in G.hand, not G.play
G.hand moment
this truly is a G.hand moment
context.initial_scoring_step was made for doing stuff to Chips and Mult before the actual scoring begins, whilst context.before is for checking the hand, modifying cards, etc iirc.
This triggers on that context.
unbalances!? 
Adds the two values together, then rolls for % of it to go to Chips and the rest to Mult.
So 35 x 4 can become 39 x 1... or 1 x 39.
What's the easiest way to go from rarity (number) to rarity (string)?
a.k.a i am trying to get the rarity from a joker using joker.config.center.rarity and pass that into SMODS.add_card
When I tried passing a number into that, it only would create Rares
I know I can define a numbered table with the number being an index to a string but honestly i would prefer not to because it'll not support custom rarities
Hey Thermo I saw you talk about changing sell cost. I have this snippet that I think should work but idk. Where exactly should this be put? Should I put it in the calculate function or is there a specific function that would handle it? (Im unfamiliar how to format code on discord and I dont wanna spam with a huge wall of unformatted text )
You can put it wherever you want, although I suggest either putting it directly near the joker or with other hooks in a utilities file. It shouldn't be in an object definition, though, so keep it out of a SMODS.Joker {}
also, for formatting code you can place it in between ``` code ```, which works in multiple lines, and you can put a code language after the first one, like:
```lua
code
```
Is there a way to change the values displayed on a Joker if a certain Joker is held?
I think you can modify loc_vars and go through every joker (G.jokers.cards) and if a specific joker is present return table with other values (or use an alt localization)
there's a variable system for loc_vars but i've only used it for color
you don't really need to use it for this though, you can just change the values that are returned by loc_vars
This is PROBABLY not gonna work, but let's try it.
Thanks, I had it in my head to put it inside the joker creation, didnt even occur to me to put it outside for whatever reason. Go it working nicely now. Thanks
It will show other values, but they will not be used
No dice.
(That disc needs to double the values shown cosmetically.)
Ok
why not just double the card's internal values for chips and mult during the add_to_deck of the disc
The disc and Joker are from different mods.
do you own the mod that the disc is from
The Jokers are from Wildcard Collection, while the discs are from Wildcards' Music
if not i'm pretty sure you can take_ownership of the disc anyway as a modded object and add the add_to_deck in that way, assuming said disc doesn't already use an add_to_deck
(if it does use an add_to_deck, you can take_ownership and overwrite its add_to_deck with the same one + your extra code)
If I even understood how to use add_to_deck or take_ownership.
they're very easy i'll run you through it
add_to_deck is like the calculate function
but it uses self, card, from_debuff instead of self, card, context
it runs 1 time whenever the joker is added to your joker slots, or undebuffed
(you can make it not trigger when undebuffed by checking if not from_debuff
it has an accompanying function remove_from_deck which is identical, but it runs when the joker is debuffed or removed from your joker slots
So is there a way to have the Wildcard Music mod do all this or do I need additional code inside WC Collection?
the disc can do all of the code itself yeah
Thank GOD
during the disc's add_to_deck, iterate over your joker slots (for index, value in ipairs(G.jokers.cards) do)
check if value is the joker whose effects need to double
double its effects and add value.ability.modprefix_doubled = true
do not double it if the joker already has that flag, to prevent the doubles stacking
and then do the inverse during remove_from_deck
ok the other joker actually does need to do a tiny bit of code itself
in its own add_to_deck, it should check if the disc exists and double its own values and add value.ability.modprefix_doubled = true to itself there
but it doesn't have to do anything in remove_from_deck
that should make it so
- when the disc is added to deck, it doubles all the values of the joker that needs to be doubled
- when the disc is removed from your deck, it halves the values that it doubled
- if the other joker is added to your deck after the disc, it will still double its own values
i think that covers all bases?
for k, v in pairs(G.jokers.cards) do
if (something to find the Joker) = (modded joker key here) then
end
end
end,```
Ok, here's all I definitely know so far.
now how would I go through and check for the Joker matching the exact one?
How do I use blocking and blockable from G.E_MANAGER:add_event(Event({})) to stop the scoring hand to wait for something to finish happening? And how do I continue the scoring hand?
hey, how do you change the number of hands or discards with a joker
Example: Merry Andy.... Merry Andy......
Here's Merry Andy's code, which should help.
thank you!
Speaking of, where does one find the code for the base game jokers? I extracted balatro but couldn't find hwere
epic! thank you
bump
Needing some help. How do I:
find a specific Joker with this loop
double the values of the Joker from a completely different mod?
for k, v in pairs(G.jokers.cards) do
if (something to find the Joker) = "j_WCCO_common_arya" then
-- code to double the values
value.ability.modprefix_doubled = true
end
end
end```
is these a way to use a specific hex code for the color attribute? if not what colors are available?
something like
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].label == "j_WCCO_common_arya" then
-- do stuff
end
end
might work
yes
oh?
Here's an example from ColorfulCards using it.
local loc_colour_ref = loc_colour
function loc_colour(_c, _default)
if not G.ARGS.LOC_COLOURS then
loc_colour_ref()
end
G.ARGS.LOC_COLOURS["idk"] = HEX("something")
return loc_colour_ref(_c, _default)
end
this makes it so {C:idk} should use your new color
You could also just use V
ah ok thx <3
yeah but if you are using the color in more place than one then id recommend doing my approach more
I agree but if they want just one time off it's also nice to mention the V: tag
mhm
yay pink :D thx for the help
in this case i dont think you need to change blocking or blockable at all
the event should already stop the scoring hand by default if your timing is correct
aka context.before or something similar
new question, whats the id of Overstock? i thought it would be 'v_overstock' but the game crashes when i use that :/
I think v_overstock_norm
ahh i see, weird inconsistency but ok. thx
v_overstock_norm for regular one and v_overstock_plus for it's tier 2
Do I really have to use lovely patches to make alt variants for regular blinds?
Show the code for your booster pack
key = 'p_bali_itempack1',
loc_txt = {
['name'] = 'Item Pack',
['text'] = {
"Choose {C:attention}1{} out of {C:attention}3{} {C:gold}Item Cards{}"
}
},
atlas = 'customBoosters',
pos = {
x = 0,
y = 0
},
config = {
extra = 3,
choose = 1
},
pools = {
["bali_itempool"] = true
},
discovered = false,
draw_hand = false,
group_key = "bali_itempacks",
cost = 4,
} ```
How do I use it in my case?
can you see ze problema
what are you trying ot do
I didn't use the pools function, instead opting for the create_card function.
That's not how pools work
could you explain
I want it to stop the played hand from scoring while the video is playing and let it continue afterwards
huh
pools field puts the object it's defined in into the pool
i dont think you need an event there, then?
try G.SETTINGS.paused = true
that should pause the scoring animation until you set it to false
owh
I think you meant to use
create_card = function(self, card)
...
end,
Where do I set it true and where false?
You return either a card created or a table you would pass to SMODS.create_card()
set it to true in the code that plays the video
and set it to false after the video ends
im clueless
Like this?
G.SETTINGS.paused = true
G.FUNCS.overlay_menu{
print("JACKPOT!"),
definition = create_UIBox_custom_video1("slotsMeme","Continue..."),
config = {no_esc = true},
}
G.SETTINGS.paused = false```
no
that literally does nothing lmao
it will stop pausing the game immediately after the ui is created
Remove the pause = false
Where do I put it then?
what should i replace for the create card function
Now I get this error...
Nothing I think?
oh okay
Probably the print in the overlay menu if I had to guess
How to add a non-boss blind?
I removed it and it still crashes
Probably the function you're calling then
I created UI using
G.SETTINGS.paused = true
G.FUNCS.overlay_menu{
definition = EF.FUNCS.UIDEF.minesweeper_score(),
}
And it worked fine
This is all of my code. How do I change it then to not crash?
can i replace Joker in set = "Joker" which the key to an object type of my own?
I think so
I have no idea, it could be anything and I can't debug on mobile
Can someone else help me with that error?
return {
set = "bali_itempool", area = G.pack_cards, skip_materialize = true, soulable = true, key_append = "bali"
}
end,```
Does that object type have anything
wtf
What?
This code looks way too complicated
Does video even work in sprites?
key = 'bali_itempool',
cards = {
['j_bali_sadonion'] = true,
['j_bali_innereye'] = true,
['j_bali_spoonbender'] = true,
['j_bali_cricketshead'] = true,
['j_bali_myreflection'] = true,
['j_bali_numberone'] = true,
['j_bali_bloodmartyr'] = true,
['j_bali_brotherbob'] = true,
['j_bali_skatole'] = true,
['j_bali_haloflies'] = true,
['j_bali_magicmush'] = true,
['j_bali_thevirus'] = true,
['j_bali_roidrage'] = true,
['j_bali_heart'] = true,
['j_bali_rawliver'] = true,
['j_bali_skelekey'] = true,
['j_bali_dollar'] = true,
['j_bali_boom'] = true,
['j_bali_trans'] = true,
['j_bali_compass'] = true,
['j_bali_lunch'] = true,
['j_bali_dinner'] = true,
['j_bali_dessert'] = true,
['j_bali_breakfast'] = true,
['j_bali_rotten'] = true,
['j_bali_woodenspoon'] = true
},
Doesn't look like it
this is my objecttype
Why?
Because it utilizes something beside Smods and Balatro's source
What if you removed the pool field in the booster
What do you mean?
You litteraly use love engine instead of modloader
Is that bad/wrong? How do I change that?
ill try it
As I said, just complicated
I think it's due to how Balatro's UI works
Can you tell me how I could change it to make it simpler then?
You're trying to insert love ui into balatro ui and i'm not sure they are compatible
didnt work
If you have debug plus try
eval SMODS.ObjectTypes["pool_key"]
It plays the video (Atleast it did before I added G.SETTINGS.paused = true)
in-game?
Yeah
Can you send me contents of lovely/dump/functions/state_events.lua?
Press / and then type it out
I think paste also works
Did
is key = false a bad thing?
-# No idea

Uhh, It says that G.GAME.hands.<played hand> is somehow equal to nil and I'm not sure why this even happened
Wtf
What now?
Idk
<_>
Every object type I checked in other mods are like here
https://github.com/SpectralPack/Cryptid/blob/main/lib/content.lua#L379-L397
that's specifically an entry in prefix_config
That's just a default I think
G.SETTINGS.paused = true is NOT the thing you want to use
Did you look at the link I sent?
Basically everyone is using
SMODS.ObjectType({
key = "Food",
default = "j_reserved_parking",
cards = {},
inject = function(self)
SMODS.ObjectType.inject(self)
-- insert base game food jokers
self:inject_card(G.P_CENTERS.j_gros_michel)
end,
})
What do i want to use instead?
why not, whats the difference between using an event that waits for a flag to return true to pause the events and using G.SETTINGS.paused?
Nah, I just did a little logical-thinking stuff
and besides, using an event to do this also doesnt really prevent other blockable = false events from running too
Maybe the timings are off
Probably, try to put G.SETTINGS.paused = true somewhere else
im guessing you want to add G.SETTINGS.paused = true within the ui's code itself
since there might be stuff that runs on events in the ui's code
and since you are pausing the game before creating the ui, they dont run?
So where in my code?
The error message is a little odd tho
what line is this
maybe its because pausing during scoring animation causes it to crash, idk
How do I make it so that an object spawns any joker but it cannot spawn jokers from a specific rarity? (Say it can’t spawn any from the common category but it spawns any from the exotic category)
you can probably try moving the line to here instead
-# though i kinda doubt thats the problem
mmmmmmmmmmmmmm
Steal create_card code and modify it a little
i think pausing the game doesnt stop those functions from running, bleg
maybe try using an event with G.SETTINGS.paused = true in it?
hopefully that works
What would it look like?
event with that in the func
so i have to put in all the jokers again 😭
Like this?
func = function()
G.SETTINGS.paused = true
end
}))```
mhm
You forgot the return true part
oh yeah, that too
And I put that in the if statement?
My bad
if my guess is right it should allow the functions to run first before pausing the game, which shouldnt crash anymore
replace your single line of G.SETTINGS.paused = true with that
Why the hell would SMODS add an option to make a blind non-boss if it wouldn't even work that way

Smods is goated like that
@rotund sable
key = "Passive Items",
default = "j_bali_breakfast",
cards = {},
inject = function(self)
SMODS.ObjectType.inject(self)
self:inject_card(G.P_CENTERS.j_bali_sadonion)
self:inject_card(G.P_CENTERS.j_bali_innereye)
self:inject_card(G.P_CENTERS.j_bali_spoonbender)
self:inject_card(G.P_CENTERS.j_bali_cricketshead)
self:inject_card(G.P_CENTERS.j_bali_myreflection)
self:inject_card(G.P_CENTERS.j_bali_numberone)
self:inject_card(G.P_CENTERS.j_bali_bloodmartyr)
self:inject_card(G.P_CENTERS.j_bali_brotherbob)
self:inject_card(G.P_CENTERS.j_bali_skatole)
self:inject_card(G.P_CENTERS.j_bali_haloflies)
self:inject_card(G.P_CENTERS.j_bali_magicmush)
self:inject_card(G.P_CENTERS.j_bali_thevirus)
self:inject_card(G.P_CENTERS.j_bali_roidrage)
self:inject_card(G.P_CENTERS.j_bali_heart)
self:inject_card(G.P_CENTERS.j_bali_rawliver)
self:inject_card(G.P_CENTERS.j_bali_skelekey)
self:inject_card(G.P_CENTERS.j_bali_dollar)
self:inject_card(G.P_CENTERS.j_bali_boom)
self:inject_card(G.P_CENTERS.j_bali_trans)
self:inject_card(G.P_CENTERS.j_bali_compass)
self:inject_card(G.P_CENTERS.j_bali_lunch)
self:inject_card(G.P_CENTERS.j_bali_dinner)
self:inject_card(G.P_CENTERS.j_bali_dessert)
self:inject_card(G.P_CENTERS.j_bali_breakfast)
self:inject_card(G.P_CENTERS.j_bali_rotten)
self:inject_card(G.P_CENTERS.j_bali_spoon)
end,
})```
is this good
whar?
should i put the code for the jokers before the object type?
Did you move the joker code before the object type
Or object type after the joker code
In what contexts do G.STATES.GAME_OVER = true and G.STATE_COMPLETE = false work?
ok since i want to art where are the templates for just a joker card but not like buried in a thread
hello hi, how do i make so when a specific joker is in possession, a custom music plays ?
woah thats cool! No idea how youd do that, but cool
Check out smods wiki https://github.com/Steamodded/smods/wiki/SMODS.Sound
bump
There’s no context like that
you should be able to do it anywhere since it just ends the run
idk why there would be a context where forcing a game over wouldnt work
Mhm
Should work anywhere
In SMODS.Blind it doesn't work in every context
how did you come to that conclusion
also it doesnt matter what object it is they all use the same contexts
if its a blind or not doesnt matter
I tried some stuff the other day and it didn't work
what context did you use
changing states in the middle of scoring might not work because it probably gets changed immediately after
Try doing context.after maybe
context.before andcontext.after for example don't work
when I refer to a custom enhancement do I need to add that m_ like the game does with m_glass or m_steel or can it just be modprefix_enhancement?
m_modprefix_enhancement
Did you added an event ?

Where?
After context
For what?

This
Wait, what do you mean by event? I feel like I'm not understanding this right
Thanks eris
Okay, so i am understanding this right. Why do I need to put an event there?
Changing game state is an event
not really
the reason you want an event is for it to happen after all the scoring animations
So I write it in the function of the Event?
Yes
This doesn't do anything in my calculate (RNGesus is my pseudorandom)
if RNGesus == 3 then
G.E_MANAGER:add_event(Event({
func = function()
G.STATES.GAME_OVER = true
G.STATE_COMPLETE = false
return true
end
}))
end
end```
i have a question:
i have created some jokers for my mod and can see them ingame,
why is the Textbox blank for the Joker, even if i have inputted text for it in a localization file?
Can you send the code of it?
You’re probably doing it wrong
SMODS.Joker{ key = 'hammah', rarity = 2, eternal_compat = false, perishable_compat = false, atlas = 'Jokers', pos = {x = 3,y = 0}, unlocked = true, config = { extra = { odds = 3 } }, }
do you mean the code for the joker or localization?
Localization
here ye go
I think you're missing a } if I'm seeing that right
well i added a s to despriction didn't work.
imma look which } is missin
would like to make a mod again sometime but like
i just have absolutely no ideas 😭
ah
Wait i’ll fix it
Can you send the code ?
return {
description = {
Joker = {
j_km_thatcher_effect = {
name = 'Thatcher Effect',
text = {
"This Joker gains",
"(X:mult,C:white) X#1# {} Mult every time", -- [[0.1]]--
"when {C:attention} #2# {} is discarded",
"face-rank changes every round",
"{C:inactive}(Currently {X:mult,C:white} X#3# {C:inactive} Mult)"
}
},
j_km_tax_collector_bones = {
name = 'Tax-Collector Bones',
text = {
"Prevents Death",
"if Money in bank",
"is at least {C:attention}Dollar per Percent",
"of the amount that is missing for the required chips",
"{$:1.1,C:red,E:2}self destructs and taxes thy tried death()."
}
},
j_km_fatal_curtain = {
name = 'Fatal Curtain',
text = {
"Retrigger all",
"played {C:attention}face{} cards",
"and destroy them afterwards."
}
},
j_km_hammah = {
name = 'Smithing Hammer',
text = {
"If a {C:attention}steel{} card is played",
"{C:green}#1# in #2# {} chance to",
"upgrade level of",
"played {C:attention}poker hand()"
}
}
}
}
}```
Nvm got it
that was quick

well i know that if a bracket was missin the game just goes crashin
wait... is there a code needed to connect the mod's localization with the mod itself?
how can i destroy random card in full deck?
lol
i had my prefix in uppercase not lowercase. Lmao problem solved
Local card = G.playing_cards[math.random(0.#G.playing_cards)]
And context.remove i think
(I may be stupid)
DONT use math.random
also math.random doesnt take arguments from what i know
I love planting seeds
if you use math.random the outcome will change
every time you play the same seed
also math.random is just a random float from 0-1
OHHHHH
It does take arguments?
no
It does tho
what do they do tho
also in this case you can just do pseudorandom_element since G.playing_cards is a table
I didn't understand anything)
Why does it only do my print? I don't get it...
if RNGesus == 3 then
G.E_MANAGER:add_event(Event({
func = function()
print("EVENT is happening!")
G.STATES.GAME_OVER = true
G.STATE_COMPLETE = false
return true
end
}))
end
end```
try context.drawing_cards maybe
local card = pseudorandom_element(G.playing_cards, "idk whatever you want this is just a seed")
card:start_dissolve()
this should work for destroying a random card i think
and why i cant just use math.random?
you can but that will make it be independent from the run seed
Still nothing
so running the same seed will have a different outcome each time
i think thats the difference
what about hand_drawn
in my case, it doesn't have that much effect, but thank you
Math.randomseed()
Nothing either
why the effort to recreate what pseudorandom already does lol
I’m making lua++
[all i know is C++]
will anything bad happen if a global mod calculate exists in an smods version that doesnt support it or will it just do nothing
It would be so cool if someone made an smods fork and made it like 10 times better
ok last idea, go back to context.after and do this
G.E_MANAGER:add_event(Event({
blocking = false,
func = function()
if G.STATE == G.STATES.SELECTING_HAND then
-- your code here
return true
end
end
}))
how
Idk i’m just being silly
it will do nothing
-<
nice
youre in a bad place for the vibes
I like the vibes here
Still does nothing... It always only does the print and that's all
Hello! I'm new here and it's been two months I've been playing Balatro on mobile. But recently I really wanted to start playing mod to see new things.
After a bit of thinking I really have a lot of jokers and consumables ideas so I want to try coding some mods. I have one precise idea of a first thing to do but I don't know a thing about modding (I don't even have the PC version yet) so I'm here to ask if anyone want to help me with modding and codding :D
#📜・modding-rules rule 4
why did you eat the P?
Yeah I'll get that soon (like in two days if I have the money)
Its my PC problem lol
No no dw, I was talking about modding on PC
yea, you should read #1349064230825103441 and RemadeVanilla
I can't print uppercase p without a capslock
Sorry I'm not great at explaning (and I'm french so excuse my bad english)
dont worry, is rare, but that's not a problem with more words
Oh ok thanks :D
you can always ask here or in #⚙・modding-general
whats the difference between chat and dev?
chat is for talk about mods or ideas
here is just code
but we chat here)
another big difference:
chat is just to talk about problem with mods
here is to talk a problem with your mod
Ok im just kidding
we need to chat to talk
chat is just better game chat
like

omg
modding chat is just a better version of server chat because the people there are awesomer
tbh they even look like they're from different games xd
another question: how can i check for using for exemple Death card. I know about context.consumeable.ability.set but still dont know how to check for certain cards
wdym, like check when the card is used?
yes
idk
the other day i tried to make a fool for spectrals and have a stroke with the code
context.using_consumeable and context.other_card.config.center.key == "c_death"
ok, ill try
i see
Could it be that G.STATES.GAME_OVER = true and G.STATE_COMPLETE = false don't work in SMODS.Blind? Because I tried putting it at the start of press_play and then in calculate and both did not trigger it
why wouldnt it work
its code
thats being run
why would it be different in a blind
Every time I tried it, it just got 'skipped', like it was not there
i mean okay but then thats an issue with the code not with it being a blind
well i know that getting a game over during scoring isnt possible since scoring has to play out first
but besides that
uh idk
I tried every context that's in a blind and not something with scoring and it doesn't game over
game over never comes 😣
didn't you say end_of_round worked
wait also it's not G.STATES.GAME_OVER = true
lol
it's G.STATE = G.STATES.GAME_OVER
if i want to make a joker, that does it's action with a specific face card, and the face card needed changes every round.
i need to add a own randomizer for that, right?
OMG, WHY DID I THINK IT WAS G.STATES.GAME_OVER = true?! Any way, it works now
And I feel so stupid now but thank you xD
my first joker
thoughts?
excuse the art please
im just starting
btw hand size is over 7
it cut that off
Interesting but sounds too strong if you're trying to keep it balanced
Good schmorning chat
Hello Dilly
hello there
Hello
