#💻・modding-dev
1 messages · Page 304 of 1
alpha it is then.
Is the second pic a thing or should I keep it as the first one?
also what do I do for the current mult?
At least show how many mult it currently has in your description?
Calculate effect does support functions.
how do I do the code +3 mult or whatever
It really sounds like you should learn some coding basics
{X:mult,C:red} +#1# {} Mult?
No, it would just be {C:mult}+#1#{} Mult
oh
{X:mult,C:white} is for the red border you see on xmult
{C:mult} is for regular mult
well... I dunno, a couple reasons, I guess? I like to avoid, like, external dependencies whenever I can when I'm modding stuff, especially when the mod is for a game that I'm already struggling with and the dependency doesn't feel absolutely necessary because the process without the dependency seems fairly well-supported and/or easy and/or simple and/or functional, like it is with Balatro.
like, it seems to me that since all of my packs are working 100% fine as-is except for this specific one, like, based on prior experience, introducing a new dependency (sorry if I'm using that word wrong, also, because I might be) has a high likelihood to create more problems then it would solve. I've had a lot of experience with "let's use [X tool] to make [Y process] simpler" turning into "spending 5 additional hours troubleshooting [X tool]". adding a new dependency for this one minor thing feels like, from what I've experienced before, overkill with a high likelihood of backfiring and just making me more frustrated.
I'm also specifically nervous about learning a new Balatro tool because, in my experience, there are extremely limited online resources for learning and troubleshooting modding for this game. I've kinda been running in circles a bit in making these texture packs because, well, y'know how bad Google has been recently, and I'm finding it really hard to find good tutorials, templates, examples, etc etc etc. Like, someone mentioned earlier that my pack format was for an old version, but it's based on literally the only format template I could find online that had what I needed.
sorry for wall of text. I'm trying to be as clear as I can. thank you for being patient with me.
in this case, mult is just the name of a color
"Gains {C:mult}+#2#{} mult for played {C:attention}Aces{}.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} mult)"
}``````config = { extra = { mult = 0, mult_gain = 1 }},
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain,
}
}
end,```
ok now it isn't showing up in the game.
Do you have the JSON?
Malverk is specifically designed to make managing multiple texture packs easier from both an end user and a mod dev perspective. You are currently just hard replacing the files the game uses, with no customisability after installing your mod. Malverk works by creating options for you to select between, meaning once your mod has been installed it never needs to be removed if you want to use other textures. It also allows much more advanced control if that’s something that you’re looking for. The syntax is designed to be reasonably simple, but there are plenty of people here who are familiar enough with it to help you out if you’re struggling.
I would really recommend its use for any texture packs.
how do i overwrite the stats of an existing planet card
config = {extra = {Xmult = 0.5, face_cards_played = 0, odds = 1000, cass_rounds = 0, reset_rounds = 5}},
rarity = 3,
--sprite location
atlas = 'Jokers',
pos = {x = 1, y = 0},
cost = 10,
loc_vars = function(self, info_queue, card)
return { vars = { 1 + (card.ability.extra.face_cards_played * 0.5), (G.GAME.probabilities.normal), card.ability.extra.odds, card.ability.extra.cass_rounds, card.ability.extra.reset_rounds } }
end,
calculate = function(self, card, context)
if (card.ability.extra.cass_rounds < card.ability.extra.reset) and context.end_of_round and context.game_over == false and not context.repetition and not context.blueprint then
card.ability.extra.cass_rounds = 1 + card.ability.extra.cass_rounds
end
if (card.ability.extra.cass_rounds >= card.ability.extra.reset) and context.end_of_round and context.game_over == false and not context.repetition and not context.blueprint then
card.ability.extra.face_cards_played = 0
card.ability.extra.cass_rounds = 0
end
end
``` meant to reset amount of face cards it has detected after 5 rounds (there is a lot more between calc and the if but it doesnt affect it)
Yeah
`SMODS.Atlas{
key = 'Jokers',
path = 'LetterJoker.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'alpha',
loc_txt {
name = 'A',
text = {
"Gains {C:mult}+#2#{} mult for played {C:attention}Aces{}.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} mult)"
}
}
atlas = "Jokers",
pos = {x = 0, y = 0}
config = { extra = {
mult = 3,
mult_gain = 1
}
}
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain,
}
}
end,
}
`
for number
You would take_ownership of it.
Yes.
this should be pinned in this channel ngl
hmm
what about uh, the planet
You need to put commas here, here, and here.
whats the class for it
I think there's more up-to-date content that is pinned in the other channel
SMODS.Consumable
thx ill check
I don't think we're talking about the same message but sure
I thought you were talking about the tutorial for how to make your first Joker
I added the commas in.
yeah no I was talking about the message I was replying to
You need an = between loc_txt and {
oh
so... this is good, in theory, but I feel like this is kinda a "using a nailgun to put in a thumbtack" kind of situation, if that makes sense? like, I'm not really a programmer, and looking over the Malverk github page, it feels like a bit much to learn a bunch of new coding things just so that I can make my one malfunctioning texture pack out of four work properly.
like, I'm really grateful to everyone in here for offering Malverk as an option, and if I were in a different situation it would absolutely be helpful, but right now I'm not really looking for a full replacement engine so much as I'm just looking for a fix to this one issue I'm facing.
is there a way to get my joker unlocked?
again, though, thank you for the advice! I'm not trying to accuse you of being unhelpful or anything
Put unlocked = true and discovered = true in your joker.
where in there?
Yeah but that message is replying to another and linking a third…
here's a relatively minimal Malverk example that you're free to reference or steal the structure of:
https://github.com/BakersDozenBagels/ShootTheLooksToTheMoon/blob/main/main.lua
@iron haven Also, while you're at it, take a read in this: https://github.com/Steamodded/smods/wiki/Your-First-Mod
does this work?
No it needs to be outside of everything except SMODS.Joker
unlock and discovered are at the same level with atlas and config
bump
that's very kind, but looking at this, I'm just, like, frankly, absolutely lost. part of the reason I'm using the format I'm using is because it's so simple, and this doesn't look anywhere near as simple to just pick up and go with., y'know?
?
Yes.
I might make a video tutorial on Malverk because it's not that hard, just a tad finicky. if you give me <unspecified time range>, that is
You were using card.ability.extra.reset in your if condition while it should've been card.ability.extra.reset_rounds.
thank you TwT
that would be very helpful! if possible, could you also do it in the form of text and images? I find step-by-step tutorials much easier to follow if they're in textual format rather than video format, as long as there are example images attached
I'm looking for my joker.
in the meantime, could I get help with my weird little outdated non-Malverk pack format? I don't even necessarily need someone to fix it, I just want to understand why it isn't working/where to start with fixing it
oh sure, that's less effort for me
or well not more effort
DebugPlus allows you to spawn it in.
hi, quick question about how tags are executed, basically got a joker that creates random tags on skip, although it seems that all tags that should apply dont apply immediatly and instead are delayed either on next shop, or on next post shop phase
loc_txt = {
name = 'Cassette Tape',
text = {
"{X:mult,C:white} X0.5 {} Mult per face card played",
'{C:inactive}(Currently {X:mult,C:white}X#1#{} Mult)',
"{C:green}#2# in #3#{} chance this card is destroyed",
"at end of round",
'After 5 rounds, reset.',
'{C:inactive}(Currently #4# / #5# rounds)'
}
},
config = {extra = {Xmult = 0.5, face_cards_played = 0, odds = 1000, cass_rounds = 0, reset_rounds = 5}},
rarity = 3,
--sprite location
atlas = 'Jokers',
pos = {x = 1, y = 0},
cost = 10,
loc_vars = function(self, info_queue, card)
return { vars = { 1 + (card.ability.extra.face_cards_played * 0.5), (G.GAME.probabilities.normal), card.ability.extra.odds, card.ability.extra.cass_rounds, card.ability.extra.reset_rounds } }
end,
calculate = function(self, card, context)
if (card.ability.extra.cass_rounds < card.ability.extra.reset_rounds) and context.end_of_round and context.game_over == false and not context.repetition and not context.blueprint then
card.ability.extra.cass_rounds = 1 + card.ability.extra.cass_rounds
return {
message = 'Track #4#!'
}
end
if (card.ability.extra.cass_rounds >= card.ability.extra.reset_rounds) and context.end_of_round and context.game_over == false and not context.repetition and not context.blueprint then
card.ability.extra.face_cards_played = 0
card.ability.extra.cass_rounds = 0
return {
message = 'Reset!'
}
end
end
}
``` it isnt increasing the round number nor resetting nor sending a message
better than triboulet?
its like trib mixed with cavendish and campfire* so good but not better
ive got a syntax error i cant seem to find for the life of me
i have it installed
Press 3 whilst hovering over your joker in game
SMODS.Atlas {
key = "Delatro1",
path = "Delatro1Sprites.png",
px =71,
py = 95
}
SMODS.Joker{
key = 'jambo',
loc_txt = {
name = 'Jambo',
text = {
"{C:chips}+#1# {} Chips"
}
},
config = { extra = { chips = 20 } },
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.chips
}
}
end,
rarity = 1,
atlas = 'Delatro1',
pos = {x=0,y=0},
cost = 2,
calculate = function(self,card,context)
if context.joker_main then
return {
chips_mod = card.ability.extra.chips,
message = localize {type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}}
}
}
This is the first joker ive written, and i followed the smod examples but i cant figure out where this error is coming from.
does anyone know where that dastardly comma is missing from? if thats even the issue
What is line 23?
loc_txt = {
Your calculate function and ifs dont have ends
instead of Xmult_Mod, what do I do instead?
lol thank you, i forgot those are needed in lua
this is from the video.
It's also chip_mod not chips_mod
Use mult
noted. Do you know where i can find the documentation for different kinds of something_mod so i dont have ask people lol?
`SMODS.Atlas{
key = 'Jokers',
path = 'LetterJoker.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'alpha',
loc_txt = {
name = 'A',
text = {
"Gains {C:mult}+#2#{} mult for played {C:attention}Aces{}.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} mult)"
}
},
atlas = "Jokers",
pos = {x = 0, y = 0},
config = { extra = {
mult = 3,
mult_gain = 1
}
},
unlocked = true,
discovered = true,
rarity = 1,
cost = 4,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain,
}
}
end,
calculate = function(self,card,context)
if context.joker_main then
return(
card = card,
mult_mod = card.ability.extra.mult,
)
end
end
}
` so this is correct?
The source code.
oh ok
No, it should just be mult not mult_mod
Line after card = card,
that's line 40.
mult = card.ability.extra.mult,
Yes.
bump
or no?
No.
ok
After adding this i still get the same error
You need to return {} not ()
yeah I know
I FOUND IT
is there a reference guide for what the key for each object is
lol thank you for the help guys
Like base game objects?
yes
game.lua in the source code.
and it doesn't gain mult
okay
bro idk what this is i tried to change it so much
anyone know why is it giving this error from the source code of the game?
Try changing tarot to Tarot
Update runs every frame?
I want it to update if you play an ace. increase mult
You need to use calculate for that.
idk whats going on exactly but i think you use a calculate function
yeah
i dont think you're checking if the card is an ace
how do I?
you have to check if its rank is 14
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
return {
mult = card.ability.extra.mult,
card = card
}
end
does .Aces work
I recommend you do this instead
so.
Remove the joker_main one.
Does it work?
Put into text in case you wanna copy-pastecalculate = function(self, card, context) if context.end_of_round and context.cardarea == G.jokers and not context.blueprint then if card.ability.extra.cass_rounds < card.ability.extra.reset_rounds then card.ability.extra.cass_rounds = 1 + card.ability.extra.cass_rounds return { message = 'Track '..card.ability.extra.cass_rounds..'!' } else card.ability.extra.face_cards_played = 0 card.ability.extra.cass_rounds = 0 return { message = 'Reset!' } end end end
Thats normal.
i can't hook Game:start_run without the game exploding? 
Still not working but I am an idiot so I be able to fix the rest of it (i have another function that is doing something at the end of the round too
What are you trying to do?
thank you regardless
All three of those errors are normal.
Yes.
so those five are normal?
Yes.
ok
to add to this, I have changed end_of_round to setting_blind and it still wont work (otherwise it is the exact same as that)
yes.
the problem is that it's imploding at the :prep_stage() call when i call the old func 
OH i was still having the same issue then i realized i was editing a coppied file. so none of the changes were actually doing anything lol
Have you taken a look in this page? https://github.com/Steamodded/smods/wiki/Calculate-Functions
two errors.
one (it didn't update): I played 2 aces
two (logic error): not playing aces should also trigger A.
yeah, is there a specific part?
Show your code.
There's also a cheat sheet I made a while ago
`SMODS.Atlas{
key = 'Jokers',
path = 'LetterJoker.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'alpha',
loc_txt = {
name = 'A',
text = {
"Gains {C:mult}+#2#{} mult for played {C:attention}Aces{}.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} mult)"
}
},
atlas = "Jokers",
pos = {x = 0, y = 0},
config = { extra = {
mult = 3,
mult_gain = 1
}
},
unlocked = true,
discovered = true,
rarity = 1,
cost = 4,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain,
}
}
end,
calculate = function(self,card,context)
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
return {
mult = card.ability.extra.mult,
card = card
}
end
end
}`
calculate = function(self,card,context)
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
card.ability.extra.mult = card.ability.extra.mult + 1
end
if context.joker_main and context.cardarea == G.jokers then
return {
mult = card.ability.extra.mult,
card = card
}
end
end
thank you (itll be helpful) but i still do not see the correlation?
if context.setting_blind then
if (card.ability.extra.cass_rounds < card.ability.extra.reset_rounds) then
card.ability.extra.cass_rounds = 1 + card.ability.extra.cass_rounds
return {
message = 'Track '..card.ability.extra.cass_rounds..'!'
}
else
card.ability.extra.face_cards_played = 0
card.ability.extra.cass_rounds = 0
return {
message = 'Reset!'
}
end
end
end
``` is my code
May I see the after-change if condition?
is above
Sorry, slow typing.
all good
There are two ifs but three ends.
Is the third end corresponding to calculate = function(self, card, context)?
yes
wait
self is nil.
do i have to pass self into start_run
calculate = function(self,card,context)
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
card.ability.extra.mult = card.ability.extra.mult + 1
return {
message = 'Upgrade!'
}
end
if context.joker_main and context.cardarea == G.jokers then
return {
mult = card.ability.extra.mult,
card = card
}
end
end
calculate = function(self,card,context) if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then card.ability.extra.mult = card.ability.extra.mult + 1, message = '+1' end if context.joker_main and context.cardarea == G.jokers then return { mult = card.ability.extra.mult, card = card } end end
oh upgrade is ok
I didn't find anything out of ordinary in this code.
Did it crash the game or did it fail to do what it suppose to do?
@daring fern
What is line 36?
failure to do what it is meant to do
Instead of message = '+1' you need to return {message = '+1'}
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
What does your current code look like?
fixed it
`SMODS.Atlas{
key = 'Jokers',
path = 'LetterJoker.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'alpha',
loc_txt = {
name = 'A',
text = {
"Gains {C:mult}+#2#{} mult for played {C:attention}Aces{}.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} mult)"
}
},
atlas = "Jokers",
pos = {x = 0, y = 0},
config = { extra = {
mult = 3,
mult_gain = 1
}
},
unlocked = true,
discovered = true,
rarity = 1,
cost = 4,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain,
}
}
end,
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
card.ability.extra.mult = card.ability.extra.mult + 1
return {
message = 'Upgrade!'
}
end
if context.joker_main and context.cardarea == G.jokers then
return {
mult = card.ability.extra.mult,
card = card
}
end
end
}
`
was a problem with my keyboard's s key lmao
Why did you remove the calculate function?
bump
am i calling start_run() wrong
this is weird, my joker seems to be able to appear in the shop while I already have it even without a showman. How do I fix this?
Did you use DebugPlus to get that?
Yes.
debugplus spawning doesn't remove stuff from the pool, yeah
alright, thanks
Put card = card in the return with the message.
Then return { message = 'Upgrade!', card = card, } instead
hi how could i force tag evaluation?
@daring fern how do i duplicate playing cards?
This is what 'Cryptid' spectral does: ```lua
G.E_MANAGER:add_event(Event({
func = function()
local _first_dissolve = nil
local new_cards = {}
for i = 1, self.ability.extra do
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
local _card = copy_card(G.hand.highlighted[1], nil, nil, G.playing_card)
_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, _card)
G.hand:emplace(_card)
_card:start_materialize(nil, _first_dissolve)
_first_dissolve = true
new_cards[#new_cards+1] = _card
end
playing_card_joker_effects(new_cards)
return true
end
}))
Hmmm... @tall wharf
in the debug thing.
oh god
Please also show them your alphabet joker collection, would you?
I regret this.
If you have DebugPlus you can press r on it
CTRL + R
i have just successfully added my first joker to my first mod and gave it compatibility with jokerdisplay, i just thought id share lol
don't mind me
how would i check if a players hand has only 4 cards, and has 1 of every suit?
Is there a guide for blueprint capabilities?
reference flower pot and square joker
you define where you wane blueprint not to trigger. you just put "if not context.blueprint" in the contexts of the abilities that you do not want copied, such as a scaling ability (this joker gains x), and you don't change anything for the contexts you do want, as blueprint copies all abilities by default
whys it sayin blueprint isnt compatible? (also, is brainstorm the same?
that's purely a cosmetic thing. i dont remember the exact value but you need to put "blueprint = true" somewhere in the start of your joker
how would i check the played hand, and not the scoring hand?
is it just context.full_hand?
Yes.
okay so my joker is just
done
had to go to roblox to debug my bracket usage but like
it works
jippie
isn't this just flower pot
oh
i wasnt aware of flower pot
is that times new roman??
but tbf im just making htese mainly for my friends so like
yeah
it should be {C:mult}, not {X:mult,C:white} for consistency
the coloring you are using is for XMult
you should probably shorten it too
you can remove "your"
copy this :trol:
How does one draw a shader on a seal?
the descriptions in balatro never have "your" in it, in case you havent noticed yet :p
its just stuff like "Held in hand", not "Held in your hand" for instance
or you could do something like
+10 Mult if exactly 1 card of each suit is held in hand
which should be pretty accurate to Blackboard's wording imo
I need to know how to do these things:
-
Generate a random suit each round
-
Add chips when said suit is scored
Doesn’t it say “your deck”?
I remember talking about “your graveyard” and there was a counterexample
welp, my point has been made invalidated, im gonna off myself from this conversation :3
-# bruh
xD
in my defense, balatro's wording is inconsistent as hell
Tell me about it
There are exactly 9 jokers with your
↗️
😭
bump
for the second part, you got :is_suit("Hearts")
idk about the first one though, theres definitely a function to create a playing card but i havent used it before
so i cant remember it :p
3 jokers have you
create_playing_card
Yes
does math.random work here
dont use math.random
what do i use then
use pseudorandom_element instead for consistency
suits = {
"Heart",
"Spade",
"Diamond",
"Club"
}
suit = suits[math.random(1,4)]
so what would i do here?
it chooses a random value from a table:
local randomSuit = pseudorandom_element(suits,pseudoseed("your unique seed here"))
but you probably want to change allat to H,S,D,C instead
I’d recommend using the list of suits
no, you also wanna include the pseudoseed
So it can work with modded suits
how do modded suits work with create_playing_card, actually
You can also pass no arguments AFAIK
3_(?)
And it automatically creates a card with a random rank and suit
wait so how would i get the list of all suits
so how would i get the suit of the most recently scored card
do i just like
do a for loop
Escalate.
config = { extra = { chips = 0, chip_gain = 2, suit = pseudorandom_element(suits, pseudoseed('albuquerque')) } },
i feel kinds stupid but why does this not work??
Your checking that there is no edition and then your checking if its negative.
gotcha, if G.jokers.cards[my_pos-1].edition.key == 'e_negative' then so do this?
You change it to if not G.jokers.cards[my_pos-1].edition or (G.jokers.cards[my_pos-1].edition and G.jokers.cards[my_pos-1].edition.key ~= 'e_negative')
thank you
could someone help with this?
What is not working?
Have you defined suits?
You need ss on those.
Oh you can’t do that in the config
theyre for the desc, i concatenate with "s" when i check the suit
so can i do something like this outside of config
gensuit = pseudorandom_element(suits, pseudoseed('albuquerque'))
then set suit to gensuit in config?
No
You just set card.ability.extra.suit = pseudorandom…. in the set_ability function
okay i got it to work by modifiying some code i found
Oh reverse castle, kinda silly
It aint working nor showing the details (I thought this would be an easy one 😭 )
SMODS.Joker{
--identifier
key = 'streamingService',
--what it says
loc_txt = {
name = 'Streaming Service',
text = {
'{C:chips}+#1#{} Chips',
'if 5 cards are played',
'{C:green}#2# in #3#{} chance',
'for {C:money}$#4#{}'
}
},
config = {extra = {chips = 100, odds = 1000, money = 1}},
rarity = 3,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
--sprite location
atlas = 'Jokers',
pos = {x = 1, y = 0},
cost = 8,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chips } }
end,
calculate = function(self, card, context)
if h_size_ge == 5 then
if pseudorandom('streamingService') < G.GAME.probabilities.normal / card.ability.extra.odds then
return{money = 1}
end
return {
chips = 100,
}
end
end
}
return stuff in loc vars
thank you, is h_size_ge correct btw? only saw it in boss blinds cus idk any jokers that use it
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chips,G.GAME.probabilities.normal, card.ability.extra.odds, card.ability.extra.money } }
end,
calculate = function(self, card, context)
if context.play.cards.h_size_ge == 5 then
if pseudorandom('streamingService') < G.GAME.probabilities.normal / card.ability.extra.odds then
return{money = 1}
end
return {
chips = 100,
}
end
end
}```
crashed now
think i did this wrong
Okay thanks a lot man
Imma post this here for no reason elaborated.
What variable name do I call this string? localize('c_planet_x').name?
ping me if someone can figure this out
what are you trying to do
😭
give 100 chips if 5 cards are played (like the psychic boss blind) and a 1 in 1000 chance for $1
so like
if (context.cardarea == G.play and #context.cardarea.cards == 5) then
if pseudorandom("twitchandytgaming") < G.GAME.probabilities.normal / card.ability.extra.odds then
return { dollar = card.ability.extra.money,
chips = card.ability.extra.chips
}
else
return { chips = card.ability.extra.chips }
end
end
How does one make a seal only show when the card is facing down?
Forgot to ask earlier, do I need to return true in func or would SMODS handle it for me?
no iirc
drawstep condition back i think
thank you!
question: is there a way to just have it add chips to the end rather than per card?
thank you
What is the variable name if I want to info_queue[#info_queue+1]= this?
How could one check that a joker hasn't triggered on the current hand?
Is the joker itself detecting or you need to detect other jokers?
It needs to check itself.
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chips,G.GAME.probabilities.normal, card.ability.extra.odds, card.ability.extra.money } }
end,
calculate = function(self, card, context)
if ( context.joker_main and #context.cards == 5) then
if pseudorandom("streamingService") < G.GAME.probabilities.normal / card.ability.extra.odds then
return { dollar = card.ability.extra.money,
chips = card.ability.extra.chips
}
else
return { chips = card.ability.extra.chips }
end
end
end
``` i feel like i did smth wrong
wait, i might see it
has_scored = false in your config.extra
card.ability.extra.has_scored = true right before returning scoring table,
card.ability.extra.has_scored = false when you want to reset it.
where code for planet cards
thank you
What I meant was I have some seals that do things on untriggered jokers.
Would you elaborate more?
tho it isnt giving money at all
made odds 1 in 1
I am trying to put the green seal from cryptid on a joker and I need to know if it has triggered or not.
You might need to use patches, that's the most I know.
tried to fix this the best i can but, upon creating immediate effect tags, some are triggered and other are triggered on next post-shop phase. Tried fixing it and the only other outcome with them functionally working was them spawning all at the exact same time, i don't know if there is a way to have them visually spawn delayed (this all is in calculate)
if context.skip_blind and not G.FORCE_TAG then
local _pool, _pool_key = get_current_pool('Tag', nil, nil, nil)
local _tag_name = pseudorandom_element(_pool, pseudoseed(_pool_key))
local it = 1
while _tag_name == 'UNAVAILABLE' or _tag_name == "tag_double" or _tag_name == "tag_orbital" do
it = it + 1
_tag_name = pseudorandom_element(_pool, pseudoseed(_pool_key .. '_resample' .. it))
end
G.GAME.round_resets.blind_tags = G.GAME.round_resets.blind_tags or {}
local _tag = Tag(_tag_name, nil, G.GAME.blind)
add_tag(_tag)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end}))
end```
change dollar to dollars
how do i make a custom planet card
brilliant, thank you
half a dollar
chat is it time for a lovely patch
yeah im looking at that and it doesnt explain how the use thing works
No, this means it's time for a bad selector
All I had to do was this.
v_reroll_glut?
wait
That... is slightly similar to what I suggested earlier.
nvm
wait k_reroll
It's localization key
You might wanna add some prefix to scored just in case.
I need id to select button with get_UIE_by_ID
ah
The use function does things when you, uh, use the card.
Because I dicide to use buttons instead of just their functions, for better compatibility and events simulation
right but what do i return to make i level up a specific hand
caluclate only has things for played hande
This one?
And then replace self.ability.consumeable.hand_type to the name of the hand you want to level up, like "Two Pair" or "Full House".
thank you
does seals in everything work on mods that have not coded compatibility with it?
No.
Is it easy to make compatible?
I have to manually code each seal.
Often yes.
good to know cus the idea is really cool (havent tried it yet cus I'm a bit slow at downloading mods ^^')
bump
speaking of which, is there a guide for making a mod compatible?
With what?
Like if i wanted to add SOE compatibility to my jokers, is there a way I could do that (similar to how you can with card sleeves)
Seals that are on jokers work with all jokers.
I only have to do the seals.
gotcha, and thats a you side and not something someone else could code?
like if i had a seal, i couldnt make it compatible?
You could if you wanted to.
Cool, thank you
You would just have to hook Card:calculate_seal like I do and check next(SMODS.find_mod('SealsOnEverything'))
Man this sucks
SMODS.Back{
name = "Pumpkin Deck",
key = "Pumpkin",
Atlas = 'Decks',
pos = {x = 0, y = 0},
config = {},
loc_txt = {
name = "Pumpkin Deck",
text = {
'Only contains Diamonds and Clubs'
}
},
loc_vars = function(deck)
end,
calculate = function(self, back, context)
G.E_MANAGER:add_event(Event({
func = function()
for k, v in pairs(G.playing_cards) do
if v.base.suit == 'Spades' then
v:change_suit('Clubs')
end
if v.base.suit == 'Hearts' then
v:change_suit('Diamonds')
end
end
return true end
}))
end
}```
Stumped (its a reverse of checkered)
Gives all cards instead of clubs and diamonds
Put it in apply.
apply(self, back) {
G.E_MANAGER:add_event(Event({
func = function()
for k, v in pairs(G.playing_cards) do
if v.base.suit == 'Spades' then
v:change_suit('Clubs')
end
if v.base.suit == 'Hearts' then
v:change_suit('Diamonds')
end
end
return true end
}))
}
}
i removed calculate and replaced it with apply
bump
You need to put = function between apply and (
gotcha, thank you
Kinda wish smods wiki does that so we can just copy those API methods we need from wiki pages.
Idk if we can do card sleeve this here but having an issue with it if someone can help
--pumpkin sleeve
if CardSleeves then
CardSleeves.Sleeve {
key = 'pumpkinSleeve',
prefix_config = {atlas=false},
atlas = "casl_sleeve_atlas",
pos = { x = 0, y = 0},
loc_txt = {
name = 'Pumpkin Sleeve',
text = 'Converts all spades into clubs and all hearts into diamonds'
},
loc_vars = function(self)
return { vars = {}}
end,
CardSleeves.Sleeve:apply() == function(self, sleeve)
G.E_MANAGER:add_event(Event({
func = function()
for k, v in pairs(G.playing_cards) do
if v.base.suit == 'Spades' then
v:change_suit('Clubs')
end
if v.base.suit == 'Hearts' then
v:change_suit('Diamonds')
end
end
return true end
}))
end
}
end
bump
Its just apply like a deck
Not text = 'Converts all spades into clubs and all hearts into diamonds',
it should be text = {'Converts all spades into clubs and all hearts into diamonds'}.
Or text = { 'Converts all spades into clubs', 'and all hearts into diamonds' } if you will.
thank you both
bump
also card sleeves has a unique context to convert cards, look at checkered sleeves code
Hey chat, any suggestions on how to get into Balatro mod dev?
I've got some ideas cooking in my brain I want to try implementing
Ah, didn't notice that, thank you so much ❤️
I can't edit the jkr file it just says complete action with files, and I need to do it in zarchiver
What are you using to edit it?
What's happening when you select the file?
What do you mean
What I'm saying is
I click choose file
And it says
"Choose an action"
Files, photo and camera
But I need to do it with zarchiver cuz that's where the file is
What browser are you using?
Chrome
Is this a feature of a higher stake?
No this was a mod I added compatibilty with my mod.
Ah
Are you clicking Browse...?
I figured it out but wha5 does this mean
?
My mistake it looks different on different browsers.
What do I do now
How is the debuff seal integrated into the game then, if I may ask?
What do you mean?
Why is it called settings (1).jkr?
Idk cuz it's from my drive
Only way I can insert the file
Is it naturally appearing in the shop, is there a Spectral card that attaches it, etc?
I'm not sure.
I see
What do I do now
Seems like it'd be an interesting addition to normal card packs in a modded higher stake
Why are you editing your settings save?
Cause I wanna idk
I wanna see what I can do to my game
I'm pretty sure that stuff is in the settings file or am I like dumb as shit
settings.jkr is not your save.
Well where can I edit my save
It's in the 1 or 2 or 3 folders save.jkr
I don't have a save.jkr
that means you dont have an ongoing run on that save currently
thanos
Building around Kings of Hearts and you find a polychrome one in a booster pack with that seal, having to think about whether you take it or not
how do i modify the list of palettes for the default skin of a custom suit? i need to add options other than low and high contrast
Did you try profile.jkr?
how do i keep the game from restting my globlas on lanch
Put it in G.GAME
y dis no work :(
How do I add globals to that
G.GAME._____ = wthcr
third joker is the copier
The ret is mostly nil unless the joker you're copying does something.
..the joekr it was copying does do something
Swap the cards around
so bpcard = card and vice versa?
Yeah in the blueprint effect call they’re in the wrong order
Also, wrap print inside if ret then ... end to avoid nil spamming.
You don’t need to wrap that
works now ty eremel
mostly its kinda weird with some jokers
trying it with a retrigger and it only retriggers once instead of three times
how do i give a modded suit more palettes? for deckskins you can just add more alongside the lc and hc palettes but that doesnt seem to be an option for the default palette of a modded suit
How do I add a sticker desc to info_queue?
actually it doesnt even retrigger it just shows the again message
gotta make a custom localization def iirc
wthcr?
I have like a million mods downloaded, I cant delete them or disable them
I've got no clue why they keep appearing
I wanna play normal balatro
But they won't leave me alone
#📜・modding-rules rule 4
com.unofficial.balatro
Oh sorry
What to name these tags:
When you buy a consumable, get a copy
(Must have room)
and
Next shop, when you buy a card, get another card of the same type
(Must have room)
Combo Tag and Hallucination tag
im gussing i need to initalise it when a new agame is started, how do i do that
Rebate Tag and Liquidation Tag
I don't think Hallucination fits since it doesn't work with the Hallucination Joker
not necessary i think
just aslong as you dont have G.GAME.tablea.value
it crashes when i just put it in my joker file
Hmmm, Liquidation is better than what I had in mind (Sale)
hmmm
i was thinking based on the digital hallucinations joker from cryptid
ah i see
that is because game does not exist at that point
you need to wait for the player to be in a game so yea it would have to be in some func
probably just hook whtv function is responsible for starting a new run
SMODS provides a function for these kinds of effects
or you can hook the vanilla one
see Castle https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua
hooking is exactly what it does
It also provides reset_game_globals
i dont need to do that
I think you could just use reset_game_globals and not even hook
Because you can create the variable at run start
i think the hook is to get the variable in the collection but that could probably be done with a nil check
wdm
somthing like this?
I thought collection was usually handled by checking where the Joker was
is it G.C.Suits["Club"] or G.C.Suits["Clubs"]?
idk im not really following the conversation, just saw the point about reset_game_globals
i mean this
it worked
I guess I still don't understand it
i prefer resetting variables per-card so im not really affected by this lol
bump
Which variable do I need to determine whether the player unlocked Planet X or not?
Twin Headed Behemoth's SOPG
Planet X or just played 5OAK?
Unlocking the planet card (or not) in the profile.
But the question is: where?
try directly on the center
What about these?
same tags?
Yes
loc_vars = function(self, info_queue, center)
return {
center.ability.extra.xmult, center.ability.extra.perhand, center.ability.extra.perclub, localize("Clubs", 'suits_singular'),
colours = {G.C.SUITS["Clubs"]}
}
end
is colours deprecated? im following https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua
first one works, second one kinda could be better but idk how it just doesnt convey what it does very well
yellow tags are always money related, I wouldn't use yellow for a non-econ tag
It's technically econ
getting another card of the same type?
It's part of the "Buy One, Get One" theme and a reference to the Humbleing Bundle Joker (referencing BOI)
I mean its econ in the same way getting free jokers is econ
technically rare and uncommon and top up tags are also econ then
Yes
....and my point is that those aren't yellow, tags that are fully yellow like that are always the ones that give actual sums of money when they trigger
?
you can just do {C:Clubs}and this text will be clubs coloured{}
ya like that
i think ModdedVanilla.lua is outdated
thank you
I wonder if I could do something like this
i feel like there is a better way of conveying what it does but i just cannot figure out what it is lmao
is that supposed to say 1+1?
No
You need to use V
Found it. G.P_CENTERS.c_planet_x.unlocked
to access vars.colours
you mean {V:...} right? i did
Yes
How did you do it
{V:1}#4#{}
interesting
Oh you did this incorrectly
It should all be inside vars
example
i know xd
It was meant to have variables too but this Joker didn't use them
Hmmm, why is it ERROR?
Badges need two dictionary entries
And which is the second one?
maybe not two but at least one in misc.labels
You know what, screw this, hide_badge=true it is.
Oh you meant those ones.
what other ones
how do you check if a card has scored?
Temporary is a sticker
is there a context for when something is bought from the shop
yes
what isit
context.buying_card
example
Jokers, consumeables, vouchers, and booster packs.
alr cool
bump
i wanna download the brainstorm mod but i dont see the main file? what do i download
SMODS.in_scoring
source code should work maybe
oh? i thought it would be apart of card or context not SMODS
SMODS.in_scoring(played_card, context.scoring_hand)
It returns a boolean value (true/false).
thanks!!
i can pass in card for the played_card argument right
alr
And you might also wanna check if the card is debuffed.
is it possible to make an edition that, instead of applying a shader, replaces the atlas?
i already do that
you could make a shader that replaces the atlas
awesomeeee i lovee shadersssss
You could make an edition do that yeah
blink any number of times if you've been kidnapped
it? didn't blink, that's a zero number of times
THERES NO CLOSED EYE EMOJI
😌
green
😀 😁 😀
lmao
does anyone know a easy way to restart a run on random seed from a joker? (I want to make a stupid one that has a possibility to just delete your run)
G:delete_run() just crash everything ahah
high contrast red, low contrast green
I mean I guess that could work
exponential perkolating
high contrast should change to 😡
did i cook
Are editions exclusive to each other?
I want to make a shader that can apply to any jokers, editioned or not.
editions are, but shaders can be stacked i think with enough patience
You could add a shader to every joker, but im not too sure how shaders like being combined
dont quote me tho
What does the shader do?
just rotate all jokers
No you wouldn’t be able to do that with a shader
You can just rotate the cards though
i mean technically you could but why
Not to stack with other shaders
i am once again asking for help to figure out help to stop my game exploding when i my run_start() hook runs - given that self is nil is causing it to asplode, i strongly suspect that i'm doing something wrong in my hook, but; i looked through my dump files at the run_start() calls and self is never passed in, so idk what's happening here 
oh yea for other shaders
is context.other_card not a thing anymore
occasionally it is but most contexts use card now
It depends on, you know, context.
I was ctrl-f'ing the wrong word. Yea other_card exists
💀
Maybe liquidation should be one-time use at the shop? Unless the idea is for it to be OP.
Unless liquidation tag is like way harder to get probably nerf it
with a deckskin you can define as many palettes as you want, is there a way to do that for the default skin of a custom suit?
I was sad it didn’t give an extra voucher
It's not a card 🤔
@native vapor What would you suggest
how do i get hands remaining
Yeah I forget they aren’t technically cards
But when you redeemed it I expected another as a demo
Otherwise why redeem it 😂
Is it not the proper way to add in an existing pool? Just calling this?
SMODS.ObjectTypes.x:inject_card(joker)
Probably make it limited use (like maybe three uses?) or make it a chance based effect but unlimited uses per shop
What do you guys think of this?
I get this crash from doing it this way
To show it didn’t work.
Also for some reason buying a pack makes it stop working. I blame thunk
(I do check if the pool exists first)
bump for some reason
Hmmm, limited makes sense.
I have in mind that thunk has buffed the Edition Tags three times and they’re still bad
See Acrobat
well theyre mainly bad because you will 99% of the time get no value from them
bump
Most tags are bad because you lose a shop right?
I'd say so yeah
I wouldn’t say losing the shop is the issue
Losing the Blind is the issue
Definitely depends on the tag
Money, interest
In some cases losing the shop is bad
Losing the free Reroll is the main impact of missing a shop IMO
So a Tag needs to provide at least $15 to compensate for everything else
bump
Bad syntax
using smods.modify_rank(card, 1) causes it to modify the rank by 2 instead of just 1...?
Type:method(args) is equivalent to Type.method(self, args)
and AFAIK you can't do Type:method except as a call
you have to create a variable to be able to use the obj:method syntax, otherwise it won't have anything to operate on
so i need to be passing self in, right?
Yes but also you don't want a call AFAIK
no, self needs to be used in obj:method syntax
you can't operate on an object that doesn't exist
...weird. every hook i've done up until this point has worked just fine
what are you trying to do
to_big = to_big or function(num)
return num
end
Suit 2 from Enemies of Jimbo WIP:
^
Try asking in the SMODS server or raising an issue
there are so many
when it crashes press ctrl-c on the error screen and paste that here
here it is without checking if money is greater than zero
it is an issue with talisman
i just have no clue what the issue is
...i'm not understanding what it is i need to change in code 
Type.method = function(self, args)
ahhh
very cool
They're both cool, but one does seem wildly stronger than the other, even if it's just for the ability to generate more money
bump
If anything I think that the one that only generates a copy is too weak
Seems about right.
xD
i mean, that's the one I picked out as the weaker one. The shop doubler is very strong, I'd say
what's the crash?
^
too strong?
Or just good enough?
idk, I'd play around with it. my take is that a skip tag probably's allowed to be stronger than vanilla, to compensate for how disadvantageous skipping is
which of those lines is the offending one?
i mean, you have the line number, no?
Yeah earlier I was calculating that a Tag should reward at least $15 to even be considered at all
does your IDE not show line numbers?
it's the to_number
nope
ya
none of the other code here should be impacted by talisman. But I also haven't seen talisman throw up a crash that signals there is a nil being compared
the crash on talisman's part is due to the math relating to ante calc, which is weird. You're not affecting that at all. If you comment out the ease_hands_played, does it not crash?
ill test in a min
heya, been having trouble with this, i'm trying to make a joker that starts at 3x mult, and takes the factorial of its mult at the end of each round, making that the new mult, but i can't figure out what's wrong
it crashes when i end a round
yea no crash
hmm, could you print the value of that formula before you pass it to the ease_hands? I don't see why passing a number should result in a nil being passed there
a Cryptid dev offered to help if you go to the Cryptid side
wait maybe its because dollars is a table
and
im putting dollars into ease hand
so im giving ease hand a table
and it no likey
another thing - i wrote this hook with the intent to track all joker encounters (any time a joker spawns) but i just realised that this only covers shop spawns and not things like riff raff or booster packs 
what should i be hooking for this purpose? emplace()?
talisman should theoritically take care of that. The latest version should support hand counts that go beyond naninf as well, iirc
create_card
bump
yea no that was it lmao
crashes in which way? error message or hard crash
error
whats it say
tonumber(n) probably doesnt work for bignums
you can do to_big(n):to_number() to ensure that all regular and bignums are converted
Does the steamodded wiki have the different return variables like mult_mod, xmult_mod, etc?
hm after doing that it now freezes and hard crashes
hm
you might be better off trying to find a suitable approximation of factorials thats faster
since it will get exponentially slower for larger numbers
hm
damn
ill probably put that joker on the backburner then
it's a bit out of my reach right now
ive been stuck on this for quite a while
i dont get what im supposed to put there if i want to use it
You define a color or use a var like this
my_colour = HEX('2B6D40')
SMODS.Suit{
...
hc_colour = HEX('FF0000'),
lc_colour = my_colour,
...
}
how would i make it so every card will automatically have a tooltip if it has a certain ability
man they couldve made that clearer
automatic in what sense? The way to go about it generally is to define a description in your localization file under the Other set, and pass that through to the info_queue in loc_vars
make it so that every joker will automatically check for a certain variable and if that exists automatically add the related tooltip to the info_queue
for that, you'll wanna hook generate_ui, or make a custom generate_ui that all your jokers use
Card:generate_ui, yeah
i may try and find a more unique way of doing credits instead bcus this is kinda boring
Maybe look at how Cryptid does its credits
i would but i wanna try to find smth different first
just "George The Rat" under the "Artist" banner sells the point enough. that's what cardsauce does.
https://github.com/Steamodded/smods/wiki/Calculate-Functions#step-3-returning-effects you might have already found this but its here
literally the link above you
Are you asking how to make a Joker increment xmult?
In your Joker's calculate function:
return {
xmult = 5 -- Any number
}
anyone know how i could stop a booster pack from being bought
hmm
wayyyyyyy too op for an uncommon
also {X:mult,C:white} for the xmult text
what should I change it to?
rare with .025 increase
what does it mean if my cards keep demanding a sacrifice
no use in running from the ritual, it has already started, and you must see it through before the Fallen arrive
i hope that helps!
Oh hey another Comedian
hey @glad osprey? did you see the spreadsheet of my letter jokers?
I have to change the uncommons now....
why are there like 96 people watching me fix my spreadsheet?
there was
holy it's duct tape
goofy ass banana
does B work now for being an uncommon?
how would y'all make a joker increase hand size?
basically just G.hand:change_size in add_to_deck and remove_from_deck
is there a way for me to make edition shaders update in real time instead of just when the card it's on is loaded?
i want my rtx edition shader to actually have real time reflections
so i don't need to use if context.joker_main ?
bazaar moment
bizarre
i also have these other hooks and i'm getting errorless CTDs on selecting a blind
is it safe to assume the same issue with these or is it something else
wait
it's calling the wrong thing, nvm 
reading comprehension is a virtue
psa: do not write code at 8AM after having been awake for at least 20 hours
I feel like having to play only against bots at the start took the wind out of me. (Also I have too much Balatro in the brain to enjoy a second hobby.)
no
is this not the correct way to destroy cards? the cards aren't destroying
i'd post a clip but it no work atm
ok
👍
do i have to do context.other_card:start_dissolve() wrapped in an event manager, in the func var of the return table
i think you can do it outside of one
what?
i'm not confident that the timing would be correct
this is line 257: if context.individual and context.cardarea == G.play and context.other_card:get_id() == 4 or context.other_card:get_id() == 5 then
?
^
yea idk whats going on there
can anyone point me in the right direction. I'm trying to make this joker increase hand size
idk if i'm using the add to deck and remove from deck functions wrong
no that should work
if context.individual and context.cardarea == G.play and context.other_card.base.value == 4 or context.other_card.base.value == 5 then
yea idk what the issue is
the issue is that order of operations matters for logic
oh?
if context.individual and context.cardarea == G.play and (context.other_card.base.value == 4 or context.other_card.base.value == 5) then
should work
its checking if everything before the or is true or everything atfer
but in some contexts that dont get checked for after the or in the original version other_card doesnt exist
so it crashes
what is other_card.base.value?
amount of chips the card gives
the value of ht eother card
you should specifically avoid using it unless you wanna check the exact chip amount because of mod compat btw
i was told to use it specifically for that reason 😭
id is better for this reason
since mods can change the chip value
other_card.base.id will be the actual rank of the card
uh
also it doesnt give the chips it gives the rank
cryptids glitched for example will change the value though
ruby i think you hae your things mixed
nvm im wrong
now F doesn't upgrade.
wait, so do i need the base value check or nah in this case?
i was thinking of nominal
we are not talking to you currently
we are helping f
2 things:
- You don't need the
ifchecks because changing hand size should be done every time the joker is added or removed, not only on debuff - My suggestion was about changing hand size, not play size. that's a very different thing. I would recommend waiting a bit before making this joker because smods is adding a function for this soon

guys I have a logic error
rip
now i'm confused. how would i check for having the joker? and am i supposed to change play size instead of hand size?
add_to_deck is called when you add the joker, so if it's called then that means you have it
to change play size you need to change a couple of things like the highlight limit in the hand and the play button function. that's why I say I recommend waiting a bit because Eremel is working on adding that to smods
I think you don't yet have the Joker during add_to_deck
gotcha. so i'd have to use if context.joker_main??
yeah but for the purpose of this conversation that technicality is indifferent
balatro fent update
no, there's no context in add_to_deck
In the context of hooking generate_card_ui, how does the game generically add the default values that come with a given center? e.g. running eval generate_card_ui(G.P_CENTERS.j_joker).main[1][1].config.text gives you +nil when it preferably should be +3 (just as it appears on the collection)
and i also can't use the add_to_deck when trying to increase hand size? I'm sorry if i'm asking too many questions. I'm so lost rn
so F doesn't upgrade when you play 4's and 5's but B, C, D, and E upgrade when you play the corresponding cards.
i dont really understand this part, what do i do if i want to remove all hearts from a deck for example?
anyone got ideas on fixing this? 
You want to increase the size in add_to_deck and decrease it in remove_from_deck, that part is correct. You don't need any extra checks. If you remove the if checks from the image you sent it will increase and decrease hand size properly.
BUT that's not what the description of your Joker says, it says that you can play 6 cards which is not what hand size is
if context.other_card
Just to be extra clear, here's the last bit of the hook to generate_card_ui that's relevant: (vanilla is a SMODS.Center in this context, _c is the first argument that is also an SMODS.Center)
local ret = orig_generate_card_ui(_c, ...)
return G.STATE == G.STATES.MENU and ret or orig_generate_card_ui(vanilla, ret)
ohhhhh. tysm for clearing that up. Is increasing play size more complicated?
yeah, I'm not sure if you can do it without hooking or patching
but like I said, it's probably getting added to smods in the next couple of days as a simple function

