#💻・modding-dev
1 messages · Page 625 of 1
oh wtf
fucked up brackets
also idk if the Tag needs an extra false, "Small" as the second and third argument
it might because the vanillaremade example for giving a tag does that
How do I make a custom string for the loc that determines?
yeah, I used vanilla remade's diet cola
Wait does that support editions or is it strictly for joker effects
what is the equivalent to #1# but for strings?
i have no idea
it retriggers a lot of things though
that arent jokers
so mayb
you can still just use #1# and such
It returns nil in the edition code so I'm a bit skeptical
I fixed one of them
and itll use the variables passed into localize
so for example how do I use a modifier that a joker when four fingers are dictected it changed the word "five" to "four"
Ok what do i use to fix the last one
I did not try this but tell me
just use loc_vars then?
if its in a joker description
with SMODS.find_card
I did use loc_Vars but for soem reason it registered it as "null"
what does the loc_vars code look like
FiXED IT!
this is what mine looks like
dont need the index
please someone its 11pm and i needa sleep
your issue is that this just always will say five
because you dont have anything set to make it not do that
weird.
?
ok the joker functionally does nothing
dunno just said weird that this doesn't do it ehat I exactly thought.
yeah
but at the same time is there a way a proper way to do this?
just do next(SMODS.find_card("j_four_fingers")) and "Four" or "Five" in the loc_vars return
instead of having strings in the config
pretty please help, I just wanna know why its doing that
there we go.
How can I change this line to account for ANY enhancement and not just Gold?
~= "c_base"
i think
im going with error 🤷♂️
yes
Seems to not work. Is it cuz of the calculate in SMODS.Rank?
yeah ranks dont calculate
What do they use instead?
nothing they can't have effects in the API
hooks?
probably incorrect
very

should be SMODS.get_enhancements or SMODS.has_enhancement
idk which one is better i dont want to look at the code
SMODS.has_enhancement uses SMODS.get_enhancements iirc
so probably SMODS.get_enhancements
yeah i dont remember which way around it is
Hey eris👋
So basically, I just have to hook this func and it's done
and I have no idea how to make hooks

Anyone have any ideas to make a single box black or gray background?
kinda like how paya's comment except it's the text box instead without labelling it as "paya's comment"?
box_colours in loc_vars iirc
how does that work? does it work with how many boxes you have?
how would i get the current ante/round
let me look
it works like text colours
G.GAME.round_resets.ante
G.GAME.round
so if I want to ask if I want to like make the bottom box to be black only the bottom box, how do I do it?
since box_colours is something I didn't try before
i think it was vars = { box_colours = { nil, nil, nil, G.C.BLACK } }
and this would be placed in the loc_txt right?
(just wanna make sure)
if context.evaluate_poker_hand and next(evaluate_poker_hand(G.hand.cards)['Three of a Kind']) then
if next(context.poker_hands['Pair']) and next(context.poker_hands['Flush']) and not next(context.poker_hands['Five of a Kind']) then
return {
replace_scoring_name = "Flush House"
}
elseif next(context.poker_hands['Pair']) and not next(context.poker_hands['Four of a Kind']) then
return {
replace_scoring_name = "Full House"
}
end
end
end```
Any quick fixes to have this kind of scenario? It plays as a pair, it's just this should be displaying as pair since I'm playing part of the held 3oak.
I think it worked
Just another thought, you can customize fonts too?
as seen in the yahiamice video for example?
assuming it works during play, you would need to use the cards not highlighted when you're not in play
yes
you would need to create an SMODS.Font and then use {f:key} in loc_txt
I see.
so do i need to make like, a for loop that removes highlighted from G.hand.cards or is there something simpler than that
you need to do that yeah
(dont actually remove them from G.hand.cards tho make another table)
Still need help
is there a way to add another language to the language selection thingy.
Folks, let's say I want to make a new Rank and any card with that rank always has a certain quantum enhancement by default (my custom enhancement)
How would the hook for it look like?
That's what Im working with
(UPD)
instead of hooking check enhancement directly, you should add a mod calculate with the quantum enhancement context
also for rank checking do card.base.value == "rank_key"
somehow {F:key} didn't work.
how do you apply emojis to a font that doesn't have it?
@red flower I'm having troulbe triyng to import a custom font and I'm staritng to get crazy as I did try to load in a custom font but for some reason it doesn't load into the loc_txt or whatever?
where are you defining the font
the fonts are located in the fonts.lua file:
thought of taking the approach that Aiko did
iirc you need to prefix it in your loc txt
{f:modprefix_CasinoKidNES}
how do i make any card that has a specific edition give an additional xmult
like polychrome
on jokers/cards
isnt there a SMODS.FourFingers or something like that that you should be using instead of checking for the joker itself
for other modded jokers that do similar things
This is just for description but i guess so
how do I use text color exactly?
But I meant like, do text colors but like how you do box colors. cause I did try it but for some reason ti defaults to the default color
is there a way to change a random asset to an image.
yeah but right now I'm triyng to change the default text color to white
on each box.
why dont you C:white in your loc_txt
you can't change the default text colour, you have to do it manually like myst said
iirc
??
use card.edition to check the edition
i think the key is inside one of its propreties
alright fair enough
might be worth adding though
how do i change the title music
or replace any music basically
and how do i play a song on loop forever?
until you quit the run.
read the docs on SMODS.Sound
will that help with my goal?
-# my goal:
replace all music of antes with a number thats a multiple of 7
There we go.
Is there a code exmple of how to make a planet card ? I didn't see VanillaRemade to have those
Oh that could explain why, thanks
what is the variable for the hand size
G.hand.config.card_limit
is there a way to know what hand is being upgraded in Scoring Parameter's level_up_hand? id be shocked if there wasnt but as far as i can tell it only receives the data for the hand to upgrade, which doesn't contain a key referring to the hand itself
...
hand.key
yeah it should probably copy those to G.GAME.hands too
yeah the SMODS.PokerHand game objects have it, but G.GAME.hands doesn't, which is what level_up_hand uses
would be nice if it added the keys to G.GAME.hands
(that or level_up_hand should receive the PokerHand object instead. not sure if that's viable)
See title. A case that has come up for this is finding the keys in ScoringParameter's level_up_hand since it receives the G.GAME.hands table but it would probably be nicer to have this for ...
neat ty
hey, this doesn't retrigger anything, what did I do wrong?
instead of using a local variable inside calculate you should store the value in the card's ability table
return {n = G.UIT.C, config = {align = "tm", minw=0.5, minh=0.5, colour = HEX("00000088"), padding = 0.15, r = 0.02}, nodes = {
-- Use a Row node to arrange the contents in rows:
{n=G.UIT.R, config={align = "cm"}, nodes={ {n = G.UIT.T, config = {align= "cm", text = time, colour = G.C.WHITE, scale = 0.75 }}, }}
}}```
why no appear
Do jokers and consumables add mod prefixes to atlases specified on the centers?
I don't remember if they do by default
ok, thx
they do by default yes
thank you!!!
how do i ban a group of boosters in a challenge
as its a local, once it leaves the calculate function that variable ceases to exist. since it can't be both context.setting_blind and context.repetition at the same time, that means whenever it checks the id, it'd simply be nil
like said earlier, just storing it elsewhere so it still exists fixes this
I ended up copying it from vanillaremade, but that just bans them all individually. is there a cleaner way to do it?
why cant you just ban all the standard packs individually there arent that many?
i did
I was under the impression that when using SMODS.Atlas, the item should become available in the Atlas table immediately. But for some reason, even though I'm adding the spectrals atlas, it's returning nil when I try to access it immediately afterwars?
Scram
Oi
don't delete the pings
what're the other mods gonna do when they come in here and can't find them
Let em check this out
We find eggs notes
savage
Yep
holy, the entire gang
can’t make an omelette without breaking a few eggs
A week right
Where did you all come from
oh that's a jumpscare 😭
Noooo
Dunno, not like we were pinged
holy whats happening
half the modteam chilling in modding dev 😭
10/10 emote you’re saved
This is the mod channel right
assuming,
someone pinged mods here and deleted their ping
it’s got mod in the name
I at everyoned but deleted it real fast
true
@ everyone
yeah I know its just funny to see every mod
nearly
I know it won't do anything but my fight or flight instincts are still firing
Live living dangerous
@eggryone
@everyegg
Yeah we lost the privilege after the last incident....
I think we gave it up freely
@eggryegg
what happend
Or at least I advocated to have it removed from us
I didnt
Now it really is mod chat
What do you expect to happen when 160k people are pinged
yeah but what did the mod that ping everyone says
P*** raids and other stuff
@egg hi
almost nothing it happened by accident
Can I use @ everyone on my birthday?
sure
lol
@soulware hi
They were seeing if they could use it
@everyone
👀
omg
Wait please tell me that didn’t work
Ahahahhha
Jan 14, I'll be waiting
'
That it highlighted scared me
The terror
ahahahahahaha
it worked... i died
ahahahahah
mods???in my mod channel??
Yeah that's scary
oh my days
Eggs don't have blood
good bye eggbert
this isn’t even true
we should have an annual celebration of The Incident™
hell yeah
we should ping @everyone every day
omg
shhhh
another one
we should turn it on for everyone all at once
I'm having nam flashbacks
And not tell anyone
@everyone
rarity: rare...
effect: retrigger everything
April fools joke: chaos and notifications
april fools joke: /ban @here
I don’t think the slash command works that way
But thanos snapping the server is really funny
Touch grass as a survival mechanism
to the point where you can't even say, their name
Reminds me of the jschlatt purge
rarity: rare...
effect: retrigger everyone for each @evеrуоne in the chat...
kaizer soze
@everyone @everyone @everyone @everyone @everyone
5 free retriggers
ok rarity: common...
at this point no one cares about @ everyone
it’s nerf or nothin
🎄🎄🎄🎄🎄 5 tree figures
@someone
rartiy: common
effect: retrigger something
this is the problem with modern society yes
yeah
if @everyone pings @everyone... no one will be pinged
should make a @civilization that ping evryone on the planet even those whose doesnt have a pc or internet at this point you just get ping and it sound in your head
@Homo Sapiens
yeah
no internet..... not a problem..... @humankind will help you.....
oh no its dead now
thanks for giving me a chance to steal this emote-> 
<@&1133519078540185692>
shame
hi mods
bumb since yeah. How do I fix this wacky animation
Just like last time, put the set ability call in an event and make it instant
thru its parameters
yeah but I was trying that but I have a joker that upgrade enhancement in context.before so the effect of the upgraded card wasnt applied during the hand
No, set_ability is instant by default.
that's because context.before doesn't happen early enough, how is that related to this tho
Log?
its related to this
I'm kinda new to modding, and on top I'm spanish, and for any reason I don't think you're refering to a tree
What log
?
sorry
The crash log.
I don't really get it, but putting set ability in an event should make the animation look fine
you might want your joker to have its effect before context.before, I think there's initial_scoring_step now but I'm not sure if that'll work
i think this means the set "matronmod" doesn't exist
like thats what my joker looks like
oh, that's bad, and how do I create it?
by using SMODS.ObjectType
Looks fine, maybe you don't need that event since the function call already has its own events
yeah I'll try
the animation with the cunsumable works fine but now with the joker its so weird
Is that with having set_ability in an event
yeah but now like I said earlier the animation with the joker is ok but the effect of the upgraded enhancement isnt there
Uhh, I'm not sure actually, I thought that'd work
isnt a thing thats reload cards
Move the set_ability call out of the event, and set the third input to true
like thats
Yes.
Sorry, now it almost works, but I dont know how to insert jokers into the type
If it's your own jokers you can go to each joker and add pools = { matronmod = true }
To each of them
hell yeah it work now
Depends on how you defined stuff
oh
could it be a problem of the object type, is the first one I define
it probably is
What about in the jokers themselves
^
And a message like 'Not allowed' when thats happend
you could copy how the Nope! text of failing a wheel of fortune is created
and just change it to Not allowed!
Hi! Is there any tutorial on every component needed to create a new deck or an small example deck mod to understand how the initial setting and events work? I'm a dev, but new to lua ;-;
SMODS.calculate_effect({message = localize('k_not_allowed_ex')}, other)
this doesn't allow me to use it even when jimbo is highlighted
can_use = function(self, card)
if #G.jokers.highlighted ~= 1 or G.jokers.highlighted[1].ability.key ~= 'j_joker' then
return false
end
local joker = G.jokers.highlighted[1]
return not joker.ability.eternal and not joker.ability.rental and not joker.ability.perishable
end,
It's card.config.center.key not card.ability.key
ah ok thank you
why does this not remove the specified consumable k from the consumable pool after being used? (k is from a custom consumable set)
it still persists... (the only unlockable hand is Flush House)
i only want the consumable to be removed from the pool, not the hand
i have it running in a loop for every hand to planet and to its respective unlock consumable (p is for planets, which is added after unlocking and works just fine)
maybe theres something wrong in this?
Okay, so I'm trying to manipulate the starting deck to have additional cards, but I don't want the cards to spawn in after i load into the game, but instead just already be in there. Is that possible?
maybe a hook onto Game:start_run?
like doing stuff to G.deck.cards occurs after running the Game:start_run reference
local game_startrun_ref = Game.start_run
function Game:start_run(args)
game_startrun_ref(self, args)
create_playing_card(...) -- silent = true
end
Not that I've tried this, but this might be a possibility?
i have no experiance with lua, and baltros code would someone be willing to help explain how i could go about adding a new joker? i am doing this a weird way
thank you!
i spoke too soon! im trying my hardest to mod the gamepass version. i already added a custom chalange but im trying to add a joker and have no ides where to start.
ITS NOT A RULE 4 #1349064230825103441 message
Yes, you can't.
you cant mod the gamepass version with smods
No, it's not possible currently.
okay, but can i know why?
it works differently so the tools aren't compatible yet
i have found some of the code relating to the jokers functionality
i mean if you want help finding code we can help but i don't think almost anyone here has made jokers without smods
also distributing the mod would be a pain
i dont want todo that, this is just for fun
i'm adding custom suits to my mod, and i want there to be a set of secret hands which all involve 5 or more suits. i'd want this to be functionally identical to paperback mod's implementation of the same system, without relying on it. but, i'd also like there to be cross compatibility and i don't want to flood planet packs and the store with effectively dupes of the same planet cards. any painless way of going about this? i was thinking of checking if the player has paperback installed, enabled, with spectrums toggled for every check on my mod's end, but that seems tedious.
i can add a 151st joker but i cant get it todo anything because i do not know how
the behavior of jokers are in card.lua
in the calculate_joker function for most of them
i know but i do not know lua to add the functionality
you need to know lua
Is there a built-in method in SMODS to make a single card pullable from a pack, or is it limited to just boosters?
Nice! Thanks!
is there a way i can run a task every say 10 seconds in the background? i tried to figure it out earlier but i can't seem to find a way that doesnt crash
an event with a 10 second delay that never returns true?
there's also probably some threading stuff that's possible but idk about that
i know cryptid has one that runs every 60 seconds to get the discord member count, but their codebase is so huge i couldnt find my way into what i needed and when i did it didnt really make sense
the wiki page for the event manager has an example of a periodic event iirc
i literally just found that on google, not sure how i didnt see that earlier
oh cryptid just hooks update
i should mention i am very new to lua but not programming in general
welcome lua feels like everything is glued with playdoh and magic
yeah thats the impression i get
playdoh is yummers
i added a joker but im lost on adding functionality
isnt there like jokerforge or whatever
never used it
but either you're gonna learn lua or use that thing
joker forge also doesn't work on gamepass balatro lol
:3
:3
:3
:3
also one more is there a way i can tell if the user is in the game or not?
like versus being on the title screen or pause menu
G.STAGE == G.STAGES.RUN
i think i didnt check
I really did not think this effect through and I don't know how I feel about the hand being treated as a flush house
this is correct thatnks
surely I could just run get_poker_hand_info (n choose 5) times surely that'd be so efficient
elseif self.ability.name == 'Photograph' then loc_vars = {self.ability.extra}
elseif self.ability.name == 'test' then loc_vars = {self.ability.extra}```
i dont wanna check with ai because ai is stinky so can yall doube check im doing this right?
That's fine but that part doesn't define the behavior, it's for the variable values in the joker description
if self.ability.name == 'Photograph' then
local first_face = nil
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:is_face() then first_face = context.scoring_hand[i]; break end
end
if context.other_card == first_face then
return {
x_mult = self.ability.extra,
colour = G.C.RED,
card = self
}
end
end
if self.ability.name == 'test' then
local first_face = nil
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:is_face() then first_face = context.scoring_hand[i]; break end
end
if context.other_card == first_face then
return {
x_mult = self.ability.extra,
colour = G.C.RED,
card = self
}
end
end```
is this right? im copying photographs code
for k, v in pairs(self.GAME.starting_params.extra_cards) do
card_protos[#card_protos+1] = v
end
end```
Where is this used?
How do I use it?
based on that it'd be like
G.GAME.starting_params.extra_cards = {
{ s = 'H', r = '2' },
{ s = 'C', r = '9' }
}
something like that, where s is the suit and r is the rank
it's kind of annoying
think i can add an enhancement?
i think there was a steamodded wiki page on this
how do you make it so discards give money under SMODS.current_mod.calculate
is it just the same logic as having a joker?
it's in the SMODS.Challenge wiki page
ty
ignore the deck.cards part of that screenshot
each table can have those 5 keys
suit and rank are needed
I'm gonna make a while loop so that it goes through giving a random rank/suit and then adds stone to them (until i get 13 cards)
like, discarding cards gives money?
no, like remaining hands at the end of the round
in the cash out screen?
you wouldn't use calculate for that no
i remember lovely patching for cashout effects idk if smods has stuff built in for that
i don't know if there's a global version of it, but jokers have a function dedicated for it
No, you would have to patch.
also does your mod just do this unconditionally
yes
well technically yes
there is a condition but its under using a consumable once
this sounds like a voucher with extra steps
Yes, you would have to patch G.FUNCS.evaluate_round
you will have to patch like somethingcom said, it's in state_events.lua in that function
So s = "H", r = "2", e = "m_stone"
right?
that looks correct, does it work?
lemme test
Oh my gosh it works
Well...
now there's a new problem
each refresh, it seems like it won't change
if self.effect.config.stone_total then
local i = 0
local suits = {"H", "C", "S", "D"}
local ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"}
local extras = G.GAME.starting_params.extra_cards or {}
for i = 1, self.effect.config.stone_total do
local stone = {
s = pseudorandom_element(suits, pseudoseed('StoneSuit' .. i)),
r = pseudorandom_element(ranks, pseudoseed('StoneRank' .. i)),
e = 'm_stone'
}
table.insert(extras, stone)
end
G.GAME.starting_params.extra_cards = extras
end```
When are you doing this?
Back:apply_to_run
wdym by each refresh btw
are you starting a new run each time
also a better way of picking a suit and rank would be pseudorandom_element(SMODS.Suits, "seed").card_key
specifically "seed" like that?
so "pseudorandom_element(SMODS.Suits, "StoneSuit).card_key"?
you're missing a quote there but yes
and same for ranks
yes
Let's try again then
btw i have a separate list for vanilla ranks and suits (the ones I want in this case so that's why i'm not using the smods.suits/ranks)
but one sec
hm...
wonder if it's because I put T instead of 10
one moment
nope
I guess if you don't want any compatibility with modded ranks and suits what you did is fine
doesn't matter, i tried your method and it still has the same outcome
Every time i refresh
So every time you start a run with that deck you get the same cards
yes
you're not starting a seeded run right
function Back:apply_to_run()
if self.effect.config.stone_total then
local i = 0
local suits = {"H", "C", "S", "D"}
local ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"}
local extras = G.GAME.starting_params.extra_cards or {}
for i = 1, self.effect.config.stone_total do
local stone = {
s = pseudorandom_element(suits, pseudoseed('StoneSuit' .. i)),
r = pseudorandom_element(ranks, pseudoseed('StoneRank' .. i))
e = 'm_stone'
}
table.insert(extras, stone)
end
G.GAME.starting_params.extra_cards = extras
end
Correct
cus I can't really think of why that'd be happening
is there a way to have a string be constantly randomizing?
Wait, do you get more and more cards every time you start a run
no it's the same 13 stone cards
uhh, can you try s = suits[math.random(1, #suits)] and same with rank, that should make it fully random
just to see if the problem is with pseudorandom_element here
it won't work for seeded runs no
So we closed one problem but opened another
what if pseudorandom_element but instead of "StoneSuit"...
can you show the full hook if it's not too long
It's just seed seed
It's... not a hook
it's a lovely patch
then could you show the patch
[[patches]]
[patches.pattern]
target = "back.lua"
pattern = ''' if self.effect.config.edition then
G.E_MANAGER:add_event(Event({
func = function()
local i = 0
while i < self.effect.config.edition_count do
local card = pseudorandom_element(G.playing_cards, pseudoseed('edition_deck'))
if not card.edition then
i = i + 1
card:set_edition({[self.effect.config.edition] = true}, nil, true)
end
end
return true
end
}))
end'''
position = "before"
payload = '''if self.effect.config.enhancement then
G.E_MANAGER:add_event(Event({
func = function()
local i = 0
while i < self.effect.config.enhancement_amount do
local card = pseudorandom_element(G.playing_cards, pseudoseed('enhancement_deck'))
if not card.edition then
i = i + 1
card:set_ability(G.P_CENTERS.m_steel, nil, true)
end
end
return true
end
}))
end
if self.effect.config.stone_total then
local i = 0
local suits = {"H", "C", "S", "D"}
local ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"}
local extras = G.GAME.starting_params.extra_cards or {}
for i = 1, self.effect.config.stone_total do
local stone = {
s = pseudorandom_element(SMODS.Suits, "StoneSuit").card_key,
r = pseudorandom_element(SMODS.Ranks, "StoneRank").card_key,
e = 'm_stone'
}
table.insert(extras, stone)
end
G.GAME.starting_params.extra_cards = extras
end
'''
match_indent = false
i undid the random btw
what if...
s = pseudorandom_element(SMODS.Suits, G.GAME.pseudorandom.seed).card_key,
r = pseudorandom_element(SMODS.Ranks, G.GAME.pseudorandom.seed).card_key,
Maybe try putting everything in an event?
that seems to be how the other deck effects do it
maybe that function is called before the seed is applied
lemme try my thing rq and if that doesn't work then i'll try yours
idk why this popped into my brain
that said, maybe the event will make it happen too late
Okay so it's different
so far so good
Now lemme use my test seed "Shinku"
Damn
I thought It'd work since y'know... tie it to the seed
unless i didn't do it properly
Is there anything that is tied directly to the seed that we could possibly find how it works?
local numbers = { 1, 2, 3 }
local bap = Back.apply_to_run
Back.apply_to_run = function(self)
for i = 1, 5 do
local num = pseudorandom_element(numbers, "meow")
print(num)
end
return bap(self)
end
i tested this code and it works as intended
Okay, so how do I apply this to the lovely patch?
I mean I just did the same thing as you and it worked for me
I guess I can try using your stone adding code
cus it's a hook
oh right
local bap = Back.apply_to_run
Back.apply_to_run = function(self)
local suits = { "H", "C", "S", "D" }
local ranks = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" }
local extras = G.GAME.starting_params.extra_cards or {}
for i = 1, 13 do
local stone = {
s = pseudorandom_element(suits, "StoneSuit"),
r = pseudorandom_element(ranks, "StoneRank"),
e = 'm_stone'
}
table.insert(extras, stone)
end
G.GAME.starting_params.extra_cards = extras
return bap(self)
end
this works just fine
that said I'm not in the same smods version as you
I'm on 1118a
I guess it's possible it's somehow broken in the latest release
the version I'm on isn't a release
I can try the release
ok
it still works
I hid the stone for now, but lemme try
Huh...
Those are different runs, I swear
is it something with lovely?
I wish I knew what the issue was
you mean this?
yes
I put that at the end of my main file
alright, lemme try with my code
okay i'm not getting it, i used your code and it's not working
I can't work on it anymore rn, It's 1:40 AM
it is 3:43 am for me
You want me to just send you the WIP mod in DMs or something?
even if you do I'm about to sleep so I'm not gonna look over it rn
I'd say try disabling all other mods first
except debugplus ofc
I have. Other than Galdur
Good morning
question: why does this softlock the game when i select a blind
SMODS.Joker {
key = "khet",
config = { extra = { xmult = 5 } },
rarity = 2,
atlas = "khet",
blueprint_compat = false,
pos = { x = 7, y = 0 },
cost = 7,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.xmult } }
end,
calculate = function(self, card, context)
if context.joker_main then
return {
xmult = card.ability.extra.xmult
}
end
end,
add_to_deck = function(self, card, from_debuff)
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.starting_params.ante_scaling = G.GAME.starting_params.ante_scaling * 2
end
}))
end,
remove_from_deck = function(self, card, from_debuff)
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.starting_params.ante_scaling = G.GAME.starting_params.ante_scaling / 2
end
}))
end
}
-# yes this is for the aforementioned hebrew part of my goofy ahh mod that i mentioned yesterday
You need to return true in the events.
so at the lines after the ones that do the scaling(?)
-# cant type this properly rn im away from my pc
Yes.
ah i see
hooking Game:start_run to create something at the start recreates it when reloading the run, is there anyway to check if the run is being reloaded under it?
if not args.savetext
Any idea how I can fix this? It doesn't seem to care what mods I have, I think one of the mods I installed caused a lasting break somehow. I've even tried uninstalling and reinstalling. It happens almost any time I click any planet card.
hey, has anyone compiled a reference of all of the keys used (and what they are used for) for the pseudoseed function? i need to compile something like it for a personal project and i'm wondering if it's been done already.
Does anyone know what happen to the originally jellymod?
When download it only gives me Bad Apple or crashes
its broken due to being Very Old
why does this joker turn every card lucky?
Remove the for loop.
how could i like pull from a fork of smods that isnt merged yet to use that code's functionality in my code ?
like, you want that code in your mod?
because that code means "when a card is scored, iterate over the scoring hand and turn each card lucky if the card just scored was a king"
if you're trying to turn just that one king lucky you don't need to iterate over the scoring hand at all, just set ability directly on context.other_card
question: how do i make something pick a random joker
how do i set the number of chips a card gives?
random out of which group?
the chips from its rank, enhancement, extra chips, or some other thing?
i want to erase any hiker bonuses and set how many base chips the card gives
jokers that you have in joker slots
card.ability.perma_bonus = 0 to erase its hiker bonus
if you want to override the rank chips without affecting the rank, I'm not sure there's a simple way to do that
i tried looking at how misprintize.lua from cryptid does it, but i wasnt able to understand it
pseudorandom_element(G.jokers.cards, "some seed string") should do it
what is the seed string for
i would try overwriting card.nominal and see what that does
it controls randomness
is card.nominal a cryptid thing or is that in smods?
i believe it's vanilla, actually
ah so the odds(?)
oh, cool
no, not the odds
it uses the run seed
you don't need to understand what a seed does on a deep level for that
just know that it's a convention that all random events get their own seed string
I'll explain it anyway if you want, though
please explain
i dont rlly get this
if i make a new random event, does that mean i make a new seed string
basically, computers can't actually do randomness, so instead they do complicated math to be unpredictable
the seed gets fed into the complicated math to get a specific series of unpredictable numbers
also for balatro specifically, each type of random event gets its results from its own specific series of random numbers, so that e.g. "what order you draw your deck in" doesn't disrupt "what jokers the shop has"
what people usually do for a seed string is just say what they're doing
i think there's examples of this in the vanilla code too
ah so
in my case
pseudorandom_element(G.jokers.cards, "pick_random_joker")
or smth
(?)
basically
how do i display a message on a scoring card without putting it in the return table? my code is already using the return table for something else
You should first test your joker if it works as intended that way you could see if your code is correct or not
ah
huh
I think you've added an extra 'end', since you only got two 'if' unless the third one is meant to close to the calculate function
it's also possible the syntax error is somewhere else
after fixing and going through a shit ton more errors i get one i'm stumped on
i already have the }
either there's a { open somewhere else or you might need to add an extra '}', try that last idea first then check again, otherwise, see for any open {
syntax errors are always hell with this
i've checked
there are none fml 😭
ok, thx
yeah that's the problem, either there's a 'end' a missing comma or whatever detail it is
but now what do I write insted of "v:" to give the card the enhancement?
ohhh ok
UPDATE: I FIXED IT ‼️
now to test if it REALLY works
after all the changes this still gives me problems
how do you change a jokers sprite when something happens?
(i have a countdown joker that i want to change sprites when the countdown finishes)
card.children.center:set_sprite_pos{ x = num, y = num }
i see i see
(bump)
loc_vars = function(self, info_queue, card)
local rounds = 3
return { vars = { card.ability.extra.Xmult, rounds } }
end,
calculate = function(self, card, context)
local rounds = 3
if context.end_of_round and context.game_over == false and context.main_eval and not context.blueprint then
rounds = rounds - 1
if rounds == 0 then
return {
card.children.center:set_sprite_pos { x = 1, y = 1 },
message = 'wakey wakey',
}
else
end
end
end,
}
why do the rounds not actually go down?
here, rounds is a local variable
whenever loc_vars or calculate are run, a new rounds is created, which always starts at 3
consider making rounds a variable in card.ability.extra
Welp... this is fun to work aorund with.
(also the colors would be adapted soon just right now I'm testing out about how it would look with game-accurate boxes)
However there was this issue.
there is a limit on this which is the 500 limit.
but overall it only does if you only have 3 of a kind
though I know people are going to like over tops the stuff so I had set up a limit of 500 since in the oriignal DOS game the Gin game had the limit of winning scores from 100 to 500 and I picked the maximum one though I'd be happy to set it back to 100
whats the 500 limit
but overall I don't think it would be overpowered as long as you kept looking for three of a kind or four of a kind.
I haven't tried it.
okay i'm very confused
same
so like
why do you have an arbitrary limit not listed on the card
i assume that joker gives you X12 Mult if you play a hand containing a 3oak
and gains X3 Mult when doing that 3 times
that, in itself, is Legendary
and a high Legendary, at that
hell that's an Epic
honestly ya true
(because cryptid epics are better than legendaries go figure
I mean, honestly I tried to apply sometihng about Gin Rummy
Although I am processing about the other jokers
cause I was thinking like maybe if I were to like have a feature where you choose between like casual or boundless.
i think we're missing lots of context
let me show you a screenshot from somewhere
oh i see, XMult is capped at 500
that will almost never apply
Yup.
neato
Yeah, now I'll show the first set of jokers I had made for my mod I'm currently thinking of processing.:
Which those jokers in different styles came from different games that involved with playing cards.
However I don't know why how is this posible but at the same time I want to know how you can adjust stickers
okay well
X500 Mult for an Uncommon is.
a bit absurd, don't you think
I know but right now I have most of the new jokers as uncommons but I might change the rarity
but right now I think I'm foing mosto f the fun of trying to like goinf for pin-point accuracy of game dialouges
Cause I had one idea of a joker being themed after a game I can make it obvious more if I also replicate more from the kind of dialouge as well as the style of it
how do i make a joker apply negative to a random joker you have every ante?
I tried this:
config = { extra = { Xmult = 10, last_ante = 1 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.Xmult } }
end,
calculate = function(self, card, context)
if context.buying_card and context.card == card then
card.ability.extra.last_ante = G.GAME.round_resets.ante
end
if G.GAME.round_resets.ante ~= card.ability.extra.last_ante then
card.ability.extra.last_ante = G.GAME.round_resets.ante
if G.jokers.cards and #G.jokers.cards >= 1 then
local r = pseudorandom('j_closet_will', 1, #G.jokers.cards)
local card = G.jokers.cards[r]
card:set_edition('e_negative', true)
end
end
end
(bump)
how do i make that one 'code art idea' thingy that some mods have.
i think hot potato has it (?)
after doing G.C.colour = SMODS.Gradients['colour'] , it allows you to do {C:colour} in localization files (or loc_txt) right?
also does {C:white,C:black} make the text black and the highlighted bg white?
the card you're trying to enhance
yes but gradients do that by default
modprefix_key
X in the first one
so {C:modprefix_colour}?
yes
?
where it shifts between "Code: X", "Art: Y", "Idea: Z".
as a badge.
okay i fixed the issue i had earlier, but i have a new one
this is Silver Deck, unscored cards give $1, -1 hand size
this is The Apparition, retriggers all played and scored cards
The Apparition doesn't retrigger the deck's effects, why not?
DANG
THE FONTS
oh nevermind, i fixed it ^^
is it possible to put an animating sprite on a rarity badge
not with the api
been scrolling through the code to no dice still
It is possible to add sprites to any part of the UI if you work it out but there's no API that provides that
oh
is it any easier to put it in the joker's name instead?
no
damn.
is there no like. font shenanigans or anything you can do to just have a character be animated
it would be the same level of difficulty because both use the same system for ui
maybe dynatexteffect?
oh yeah
Am i going at this wrong because I'm putting it on "Back.apply_to_run"
I don't want the game to just have a second where it puts them into the deck like how other decks do it, since the actual deck itself just automatically does it
where is that?
aint no way i can't find it on github, bmm not even codeberg?
is it even a mod ;-;
Wait, i had a stupid idea
What if I used the same logic as the metal deck, how it chooses random cards, and then whatever cards it chooses, it stores a base edition copy that gets inserted
its a feature within smods
oh...
well is there any doc on how to use it
no
or has it been used in any mods so i can reference it?
aiko uses it
oh ok
well the use cases doesn't explain much..
if i have a blind-like spritesheet,
how can I do it? dyk?
I don't think you can use dynatext for sprites but I might be wrong
idk if this is for a sprite or not, but this looks like one... it was used in aikoshen
SMODS.DynaTextEffect {
key = "obfuscate",
func = function (dynatext, index, letter)
letter.letter = love.graphics.newText(dynatext.font.FONT, string.char(math.fmod((string.byte(letter.char) + math.fmod(math.floor(G.TIMERS.REAL * 142.1 + index), 192)), 94)+ 33))
end
}
that's for a character of text
oh.
but what if each frame was a character of a new font and i just animated it somehow....?
how??
I mean if you want to create a font that functions as a sprite sheet knock yourself out
do i need cdataman and talisman or just cdataman?
Ok so i'm getting closer
do you know how tables work in lua
no ):
I copypasted a lot when doing my mod
you should look that up real quick
it would make this make a lot more sense
ok, thx
G.E_MANAGER:add_event(Event({
func = function()
local i = 0
local extras = G.GAME.starting_params.extra_cards or {}
while i < self.effect.config.stone_total do
local card = pseudorandom_element(G.playing_cards, pseudoseed('rockydeck'))
local suit_prefix = string.sub(card.base.suit, 1, 1)..'_'
local rank_suffix = card.base.id == 14 and 2 or math.min(card.base.id+1, 14)
if rank_suffix < 10 then rank_suffix = tostring(rank_suffix)
elseif rank_suffix == 10 then rank_suffix = 'T'
elseif rank_suffix == 11 then rank_suffix = 'J'
elseif rank_suffix == 12 then rank_suffix = 'Q'
elseif rank_suffix == 13 then rank_suffix = 'K'
elseif rank_suffix == 14 then rank_suffix = 'A'
end
if not card.edition then
i = i + 1
local stone = {
s = card.suit_prefix,
r = card.rank_suffix,
}
table.insert(extras, stone)
card:set_ability(G.P_CENTERS.m_stone, nil, true)
end
end
G.GAME.starting_params.extra_cards = extras
return true
end
}))
end
trying to get whatever card it is to set the prefix/suffix to add to to the extra_cards
oh
i see a comma
Okay so prefix and suffix are working, so lemme try something
okay this is useless apparently
lemme try again
Sorry to interrupt the current conversation but I have some questions. I want to make a mod that adds jokers and maybe consumables and other things, like vouchers, etc. I have modding experience in more... dynamic platforms, like in The Elder Scrolls Construction Set, but I have never modded in a code-based system directly. Is there any video tutorial or similar resource anyone could recommend to me to start out with to learn the basics of modding Balatro?
just cdataman
I added in the importance color stuff but no idea if it's right dispite I tried ot use a guide on how it works.
Thank you!! And I think I can already tell from all of the previous discussions I've been reading, but essentially modding Balatro is always going to be a coding experience, right? Like, there's no visual interface to go about modding it?
the videos I found only help create pretty simple jokers, based on what you're saying you'd be better reading the code of other mods, or the game
also how am I goign to adjust the sticker when the texture is like very tiny or small
exactly
Thank you! I will now dissapear into the learning curve of coding Lua and maybe have something to show you guys in a few days lol
good luck
this is AWFUL to look at
how can i replace all the music with X every 7th ante?
ohhh looks nice
duality of man
Follow up question, do y'all just use notepad for editing this stuff or is there a better program I could be using? I'm sure there is something better, it's just that I've never modded in code before
i mean it is awful to look at
Notepad++, Visual Studio Code, Notepad, whatever you want
Thank you!
still can't figure this out
I use visual studio code, but I don't know if any other option is better
I'm just used to it
vscode is my favorite.
for now I have it in steel cards so i can see if it duplicates properly, but obviously it's not duplicating at all
The idea is that whatever card is a stone card, it copies itself without a rank. (I'm inputting this as a lovely patch)
Thank you all! This is an awesome community
I've watched some tutorials and I didn't learn anything new
What do I have to write instead of card to make this work?
The plan is to get whatever suit/rank into the extra cards parameter
{ s = 'H', r = '2' },
{ s = 'C', r = '9' }
}```
whats the goal
transform the kins to lucky cards
that should already work
and I0m pretty sure that 'card' is the problem
ohhhhh
oh
yeah, thanks
also this is self,card
true
damn
no idea
I executed it. It was a noble sacrifice🫡... 8 more gigs of storage for me 
damn. I'll just do the try and true method of "throwing stuff at a wall and see if it sticks
empty your recycling bin if theres a to of stuff there
there's nothing.
this is the best i can get 🥀
well 20.7 now
my steam folder is only 4.28gb ;-;
my biggest culprit of storage is (other than steam) images and videos
idk how much of those you have
I just cleared my photos and videos folder.
barely anything
ah
only managed to get .5gigs
then whats takin up everything else?
i like to use windirstat to look at my storage it helps a lot to see whats taking up the most
hm ill try to install that
managed to get 0.5GB free so far.
interesting, it's installing rn
got it.
it's loading.
22% 🥀
yeah it takes a bit to boot up cuz its gotta measure everything
I don't think you should be using an event; by the time that event runs, the game has already skimmed through the (undefined) G.GAME.starting_params.extra_cards table and finished initialization
The reason why the other self.effect.config checks involve an event is because they need to wait for the run to finish initializing to modify cards and whatnot
Back:apply_to_run is called before G.GAME.starting_params.extra_cards is checked
AppData is apparently 80gigs
mostly /Local
damn docker is 30??
might aswell uninstall that lmaoo
Super quick question, in Balatro logic, does a Flush Five contain a five of a kind?
Planning out Joker effects
is there a function to hook so I can generate something when I enter blind selection screen
so how should i code it then?
yes

Flush Five contains 5OAK and Flush
same goes for flush house and straight flush with their respective non-flush aspects
Awesome, thank you!
dont forget that four fingers exists when planning it out btw
yeah quite literally yes
a flush five is just “a hand that has both a flush and a five of a kind”
Oh shit that's a good point, thank you!
(so with four fingers a hand with four ace of hearts, and one ace of diamonds, would be a flush five)
I'm making a spreadsheet (cuz I'm a nerd) to plan out all Joker/Consumable effects before I start coding anything because I need to know what I'm coding, and one of the Joker effects is going to be "When played hand contains a five of a kind destroy all cards held in hand" so the Four Fingers integration is really important
gimme a moment
four fingers doesnt effect x of a kind hands though, only flushes and straights
and also even if it did you could just do the contains hand function and it would already account for four fingers
how can i make a config variable for a joker that always keeps track of your highest mult this run?
Ohhhh sweet sweet thank you!!
take your time 
actually taking a look at the code, it can be written differently; asking for clarification, you're trying to add some amount of stone cards in the default deck?
oh and also heres some code for runner, although you might want a later context than context.before depending on whether you want it to trigger stuff like steel cards before the cards get destroyed
key = "runner",
blueprint_compat = true,
perishable_compat = false,
rarity = 1,
cost = 5,
pos = { x = 3, y = 10 },
config = { extra = { chips = 0, chip_mod = 15 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chips, card.ability.extra.chip_mod } }
end,
calculate = function(self, card, context)
if context.before and not context.blueprint and next(context.poker_hands['Straight']) then
-- See note about SMODS Scaling Manipulation on the wiki
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod
return {
message = localize('k_upgrade_ex'),
colour = G.C.CHIPS,
}
end
if context.joker_main then
return {
chips = card.ability.extra.chips
}
end
end
}```
gotcha
just swap Straight for the hand type you want, and put in the different effect :P
My only thing is that i have 2 custom suits but i don't want them in the pool for suits
?
idk if putting it at the top of calculate is efficient
config = { extra = { highest_mult = 0 } }
to actually code it is a different question but i'll answer that too :3 do you want it to track even before you picked up the joker?
oh yeah i did that, i meant the actual code, and yes i want it to track before. thanks lol
ok, gimme a bit to run use the bathroom and then look into how to save game global variables
kk
is that the function when you enter the blind selection screen
Game:update_blind_select creates the blind selection UI if that's what you're looking for
step 1: add this function to your mod
function SMODS.current_mod.reset_game_globals(run_start)
if run_start then
G.GAME.modprefix_highest_mult = 0
end
end
(replace modprefix with your mod's actual prefix, just so that you don't accidentally collide with any other global variables. do not replace current_mod, it should literally be current_mod)
this sets a global variable in G.GAME to 0 at the start of the run
step 2: add this to your mod's global calculate function (add one if you don't have it yet)
function SMODS.current_mod.calculate(self, context)
-- potentially other stuff if you already have a mod calc function
if context.after then
if mult > G.GAME.modprefix_highest_mult then
G.GAME.modprefix_highest_mult = mult
end
end
-- potentially more other stuff
end
step 3: G.GAME.modprefix_highest_mult will always be the highest mult this run
wowza, thanks!
um I'm looking for when you enter the blind selection. I want to hook that function so it check if you have a certain set of joker and if so creating a another one
no need to hook
use a mod calculate and do the thing in context.ending_shop
yeah but its not on a joker
like I can do it on a pool ?
so would this be in my main file? like:
local thecloset = SMODS.current_mod
...other stuff in between...
function thecloset.reset_game_globals(run_start)
if run_start then
G.GAME.thecloset_highest_mult = 0
end
end
function thecloset.calculate(self, context)
if context.after then
if mult > G.GAME.modprefix_highest_mult then
G.GAME.modprefix_highest_mult = mult
end
end
end
still need to replace modprefix with thecloset in the calculate function too
yea i just did lol
you need to replace where it says modprefix, not SMODS.current_mod
SMODS.current_mod needs to stay
using local thecloset = SMODS.current_mod is perfectly fine
oh huh
cause as far as I know pools doesnt have context
the mod calculate function always runs regardless of what content you have
if you mean the ObjectType no, but your mod can have a calculate function that handles stuff related to it if you want
Has anyone have an idea of changing offset of the stickers on a joker?
cause I have this pool
and if i wanted to have it set to the highest mult in the localization file, would i do #2# and have something like:
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult, card.ability.extra.highest_mult } }
end,
and the config is
config = { extra = { mult = 3, highest_mult = G.GAME.thecloset_highest_mult } },
Do you want to change the offset of all stickers or only one that you specifically made
I dont use the object type cause I want to use it like Giga.POOLS.fusion_jokers
You should just return G.GAME.thecloset_highest_mult directly from loc_vars
^ you don't need the joker's config variable for highest_mult at all anymore
oh yeah
While i wait for onite to try and code up the deck effect, I'm gonna work on other jokers and whatnot
i do want to update one of the jokers' config value when the highest mult is passed though
card.ability.extra.mult = card.ability.extra.mult + distance_between_last_highest_mult_and_the_amount_passed
^ that's basically it.
like if it went from 1-101
add 100.
and you want that to happen whenever the highest mult is updated?
yeah.
function thecloset.calculate(self, context)
if context.after then
if mult > G.GAME.modprefix_highest_mult then
SMODS.calculate_context({ highest_mult_changed = true, current = mult, previous = G.GAME.modprefix_highest_mult })
G.GAME.modprefix_highest_mult = mult
end
end
end
Maybe just something like this? Then in your joker you'd modify mult when if context.highest_mult_changed then
oh nice, thanks.
context.highest_mult_changed.previous is the last one?
or?
just context.previous
so like
if context.highest_mult_changed then
local dist = context.current - context.previous
card.ability.extra.mult = card.ability.extra.mult + dist
end
i'll test in a sec.
im having trouble getting a joker to retrigger other jokers
if context.other_joker and context.other_joker.label == 'j_joker' then
return {
repetitions = 1
}
end
i think that'll retrigger all jimbos.
after they trigger.
would it retrigger itself?
yeah
i can test
found out why pseudorandom isn't working in your implementation; the run's seed is generated after apply_to_run
so the seed "rockydeck" always maps to the same seed value and hence randomness never occurs
rip
since you're patching already, why not patch directly in the deck generation
Wait, I thought that too, but that wasn't the case for me
so how do i fix it?
Like this code worked perfectly fine for me
how do i do the box
surround with triple `
alright
well if we want a seamless addition of cards into a deck, we'll need to do an entirely different patch
that's fine
if context.other_joker and context.other_joker.label == 'j_joker' then
return {
repetitions = card.ability.extra.repetitions
}
end
if context.repetition and context.cardarea == G.play then
return {
repetitions = card.ability.extra.repetitions
}
end
if context.repetition and context.cardarea == G.hand and (next(context.card_effects[1]) or #context.card_effects > 1) then
return {
repetitions = card.ability.extra.repetitions
}
end
end```
i'll check this first tho