#💻・modding-dev
1 messages · Page 200 of 1
huh
Like ill hold the card in my joker hand, and then suddenly its in the shop
yeah it's def because of spawning it via debug
the game doesn't actually realise you have it
havent seen any but the burger but i have made it the burger can appear more than ince
once
it's happened to me plenty while testing
M!
this joker is feeling quite jolly
is there a way to insert the variable associated with a challenge rule into its loc text?
-# I wish I had enough brainpower to make a mod :(
there's some great resources out there to help you get started!
it's very scary at first but really rewarding once you learn the basics
evil alternate universe
Oooo
The examples and smods wiki are really helpful!
I just need to have the pc version first ig idk
https://github.com/Steamodded/smods/wiki and https://github.com/Steamodded/examples/tree/master/Mods are two places i check often
i mean pc version is a requirement
i developed Cryptid after being inspired by an intentionally unbalanced mod called Mistigris
Cool
I might try that out
Omg are you really a cryptid dev

deja vu as a dependency
You’re still cool to me so nothings changed
Does anybody know how i can get a joker i made to have additional effects with another joker from the same mod? Like if i have Joker A it does +10 mult but if Joker B is in your Joker slot then it would do +20 instead something like that.
you can check the key of the joker next to it by checking what the position of your first joker is (iterating over G.jokers.cards), and then checking the key for G.jokers.cards[i+1]
Im wanting to make a card that converts a random joker into negative every 6 rounds, How would i tackle this
tick down a variable each round, and when it reaches the threshold, pick a random joker using pseudorandom_element() and use card:set_edition({negative = true}, true)
what would i put into the psuydorandom?
cause i doubt this would work and is enough lmao
G.jokers.cards
which is a selection of all of your jokers. If you don't want to be able to pick itself, you can add a check to see if the selected object is the same as 'card'
yep entitycount crashes it agh
card:set_edition() in this case will set the joker itself to negative, btw! you want to store the pseudorandom_element result in a variable, and use :set_edition on that one!
store entitycount like config = { extra = { entitycount = 0} }
that way you can increment it by using card.ability.extra.entitycount = card.ability.extra.entitycount + 1
Because currently, you're storing entitycount as an element of the joker, while in the calculate function, you're looking for a global variable called entitycount, which doesn't exist
i did crash cause of that
Have you looked at the smods example jokers? the structure is laid out really well in there
check for card.config.center.mod.id
might be easier than trying to fully explain the structure. Each joker should basically always have a config = { extra = {}}, even if it's empty, I'd say
yeah i have no clue what i am doing
` config = { extra = { entitycount = 0} }
SMODS.Joker{
key = 'Entity',
loc_txt = {
name = 'Glitched Entity',
text = {
'Every 6 rounds, Turn 1 Random Joker Negative',
'{entitycount}'
}
},
atlas = 'Jokers',
rarity = 3,
cost = 10,
unlocked = false,
discovered = false,
blueprint_compat = false,
eternal_compat = true,
perishable_compat = false,
pos = {x = 1, y = 0},
config = { extra = {
}
},
calculate = function(self,card,context)
if context.end_of_round then
card.ability.extra.entitycount = card.ability.extra.entitycount + 1
if card.ability.extra.entitycount == 6 then
pseudorandom_element(G.jokers.cards)
card:set_edition({negative = true}, true)
card.ability.extra.entitycount = 0
end
end
end
}`
i thought this challenge would be hard but i guess i'm way too good at white stake
don't think i can really make it harder in any way that feels natural and fair
I really recommend looking at the example mod
but like starting off with a legendary that goes crazy with xmult is a big help
three ` marks on each side will create a better codeblock! But you can see that below pos, there is already a config. That's where you want to store information that changes throughout the round
where 😭
oh, damn, sniped 😛
(it's in the steamodded docs)
under what category
don't worry too much about knowing what you're doing. Just play around with it so you learn and figure out how lua and SMODS store information, and you'll start to make sense of the gibberish at some point!
they should really update this to the new returns tho
oh they do, just later
it should probably be reversed so that people don't use mult_mod + message
Okay well i can make it make things negative
Just
adding the 6 round timer on it
it just makes a negative every turn
Values in the config.extra table are stored and altered through the run, so there's where you want to store the base, and count it down
the extra table?
Thank you! I’ll look into that
idk what u mean lol but heres this
you see above the calculate function, there's config = { extra = {} }, right?
ye
information you store there is able to be changed and saved during the run
so if you put a 'countdown = 0' and a 'threshold = 6' there, you can tick it up each end_of_round, and only trigger the event when the countdown and threshold meet
boop
I'm also working my job, so please don't bump! I'll get to it when I look at discord again
o sorry
Do be aware that in this case, it'll only trigger once, and then never again. You wanna set entitimer back to 0 whenever it goes through
hmmm Okay so it can hit already negative jokers which is an issue
in that case, you want to check if the joker's already negative, and keep selecting new ones until it isn't. At which point, you'd also want it to be able to check if there are even any valid targets, before it gets stuck, ofc
hmmmm
well this caused a crash
and this doesnt reset the variable
Oh got that working!
(you were redefining the local card)
i got it to work for the resetting
now, i just need it to sense negative jokers
also got no clue how to display the variables on the description
From my understanding, the variables returned in loc_vars can be referenced in the order they're listed, starting as #1# and incrementing 1 each. So in the (partial) joker screenshot here, #1# returns the value of XMult, and #2# returns the value of XMult_mod
https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua The example jokers have a lot of good examples of all sorts of things, but the basic Joker 2 has a good explanation of what you're looking for
Question, is there anything out there that just has all the base game decks and jokers but as code?
to reference
that's called the game's code. the way we do things modded is significantly different though so it might not be of that much help
i don't think anyone wants to implement every vanilla effect in smods
Ah
I'm just trying to find all the variables
like if I want to make a deck increase ante size (like plasma deck), what would I do?
for a general idea of how something works, you can still just have a look at the game code and go from there
esp decks aren't that different
where do I find deck code in the game
plasma just has this as its config for the ante scaling and the game converts it to a starting parameter
it's a bit over the place. it's best to search for the deck name first across all files and then for any config values that might be interesting
curious on how to do this tbh, Locking is preffered but this could be better hmmm
would it be possible to divide a joker's values by 2 temporarily?
Im currently trying to adding new editions with SMODS.Edition. Everything works fine but it doesnt seem to apply anything regarding the config/loc_vars
I tried comparing it with other editions of other mods, but the main difference is only Im using SMODS.Edition instead of item with object_type = "edition"
Can someone recommend working with SMODS.Edition or just with the object_type variation
how are you accessing the config values?
loc_vars = function(self)
return { vars = { self.config.p_dollars } }
end
you're not supposed to use the config directly, though I don't see how that doesn't work if you've set up the respective config. I should be like
loc_vars = function(self, info_queue, card)
return { vars = { card.edition.p_dollars } }
end,
what if though, I have this joker as Last Pirority, and if you play any hand thats Not the one its locked, your chips and mult become 0, which saves me actually going into thingsa
hello, i've made a retexture of some cards for myself, i already have the 8bitdeck.png file edited with them, how do i get it to work with steammodded? i know it's related to lua but i'm too dumb to understand the language
or i can have it give less of a penalty and it has no pirority, instead it does the x0 on both, but you can set it to go first so then your other jokers could possibly activate
I tried this as well with chips, mult and p_dollar but it doesnt work as well
can you show me the edition code in full?
key = "royal",
loc_txt = {
name = "royal",
label = "Royal",
text = {
"Earn {C:money}$#1#{} when",
"King is played."
}
},
discovered = true,
unlocked = true,
shader = 'royal',
config = { p_dollars = 3 },
in_shop = true,
weight = 2,
extra_cost = 8,
apply_to_float = true,
loc_vars = function(self, info_queue, card)
return { vars = { card.edition.p_dollars } }
end
})
So I just spent about half an hour putting up this kind of thing:
i don't think edition loc_vars works correctly with card.edition
Ignore what I just typed, I forgot edition works differently.
how would I add a string to the beginning of every jokers name during specific situations
How do I create a new tooltip entry for a patched in attribute to playing cards? I wanted it to show up similarly to the extra chips from hiker
like a guide for us?
just pushed something to steamodded that should make this work with card.edition. previously it had to be self.config
More like, you local ctx = context_timing(context) at the start of calculate = function(self, card, context), and then you use if ctx == 'when scored' then instead of if context.individual and context.cardarea == G.play then.
anyways, How can i make a joker keep track of what hand i play
context.scoring_name
I dont want a specific hand, i want it to Get the first hand that it sees, and then only score off that hand
I'd check this wiki page https://github.com/Steamodded/smods/wiki/calculate_functions
Just pulled the newest one but it still doesnt seem to trigger.
it has a lot of info on which information is passed to the jokers in each specific context
card.ability.extra.hand = context.scoring_name
end```Something like this?
pokerhand, so like, Play a flush, Only scores off flushes, or if it sees highcard, only scores off that
For current round or for entire run?
And "scores off" as in...?
grants Mult
my brain may have come with something from what you gave me, but i wont be suprised if it crashes
So your calculate function would be like if context.scoring_name and (card.ability.extra.hand == 'nothing') then card.ability.extra.hand = context.scoring_name end if context.joker_main and context.scoring_name == card.ability.extra.hand then return {mult=card.ability.extra.mult} end with config = { extra = { mult = 10, hand = 'nothing' } }
well, it didnt crash but it did just casually score everything in hand
i think the wiki is just wrong then. config.p_dollars on editions doesn't do anything (automatically)
Okay, Wait, what i did, Kinda worked but it is, SO weird
what do i put as the second constructor for SMODS.Sprite:new? i'm not really sure what this "name".path is
SMODS.Sprite:new is the old API
you're not supposed to be using it
small lil edit before i use your one Riv
oh gotcha
Yes and no. In the Wiki it mentions also the same method with mult.
I saw in one other mods Source code their Edition, that it uses the same method with the config / self.config.mult.
But when I try to apply it with smods.edition it recognizes the value but doesnt seem to handle it in any way.
Well I got my first deck done
I was gonna word it differently with the "3-7" part but eh it gets the message across. not a very balanced deck I'm sure
Trifolium subterraneum is a type of clover that ranges from 3 to 7 leaves, instead of the typical 3-4.
Me when I finally had enough for all the time I have to type ggameprobnorm:
It doesn't handle p_dollars even though the docs claim it does. You need to use a calculate function for that
okay so, It works, but the thing is, if its the wrong hand, it deletes the cards
and idrk why
I think you did not just only delete the cards.
the x0 is what i want lol, i dont want cards to get deleted 😭
context.cardarea == G.play doesn't uniquely identify a context
So it happens in destroying_card too
Also, SMODS should automatically add "X0 !" message without you specifying it.
oooh
it was saying x3 from smth else lol
Also G.C.MULT is already its default colour when Xmult is specified.
do you know of a retexture mod that uses this? there's not really a code snippet in the page using the function fully from what i understand
btw does SMODS.Joker.key have to not have any spaces?
Honestly, your code is kinda an example as why I wanted to write the context_timing function in the first place.
😭
Im new to this
this is like, the first time ive done something kinda by myself
other joker cards i had bigger help
and I actually got it to work
What I meat was that it's suppose to help new modders to understand context timings more easily.
The card that i made, Triggers x3 mult on every card played, however the first Pokerhand you play is the only one you are permitted to play, playing anything else puts your chips and mult to 0 (aka a debuff but i dont have to do the weird stuff that i dont know what to do)
what is key here?
Then I'd suggest that you put {Xmult=3} under if context.individual and context.cardarea == G.play then, and {Xmult=0} under if context.joker_main then.
only part i havent done is setting chips to 0
I dont think you need to, since anything times zero would still become zero.
Unless you wanna be extra cruel.
the string you want to use to refer to your atlas in your code
ah so like a variable name
key = unique identifier in the code
I mean like the boss blind i want other jokers to still be able to score, so setting chips to 0 would be nice for that
then any joker that grants chips is your chip gen for said hand
okay this is just crazy luck the only card i summoned was the spider one (for testing) the others are all rares
one important thing to know is that mods appends prefixes to keys so each of the mods can use similar keys but still be distinct
by default u wouldnt worry about it bcos smods does the appending for all the items ur mods adds (so like if u have an atlas with the key of "myatlas" and a joker that uses that atlas, you'll just write "myatlas" in the joker)
for atlas, do i still have to call it with something like register? or will it work without that
just defining it as SMODS.Atlas{} is enough
gotcha
key = 'myatlas',
path = 'myatlas.png',
px = 71,
py = 95
}```
^^ this by itself is already a valid atlas as long as the file exists
actually, how do i make it that cards dont trigger?
that would solve the chip issue
if the card returns nothing in its eval card then it doesnt trigger/retrigger
my pngs are in a folder named 1x/2x that's inside an assets folder with the lua file, will it find the png by itself or do i have to specify the folder/path it needs to find it in
just the file name
unless your 1x and 2x folders have subfolders
basically path already assumes the file to exist at 1x and 2x
im not sure how you'd achieve this with playing cards but i know this bcos i was writing custom played joker handler and by default as long as you make the jokers not crash in play area, they dont trigger anything bcos they dont return anything
so like no chad no anything
perhaps you could just hook eval_card to return blanks for played cards if the condition is met
SMODS.Edition({
key = "royal",
loc_txt = {
name = "Royal",
label = "Royal",
text = {
"+{C:mult}#1#{} Mult"
}
},
discovered = true,
unlocked = true,
shader = 'royal',
config = { mult = 100 },
in_shop = true,
weight = 8,
extra_cost = 4,
apply_to_float = true,
loc_vars = function(self, info_queue, card)
return { vars = { self.config.mult } }
end,
calculate = function(self, card, context)
if context.cardarea == G.jokers and context.scoring_hand then
if context.joker_main then
return {
colour = G.C.MULT,
mult_mod = self.config.mult
}
end
end
end,
})
I also tried hits with card.edition.mult. None responses. But the Tooltip seems to acknowledges the config value.
This is my whole code and it's not working, should the console that appears when booting up the game show that the script loaded?
local mayburideck_mod = SMODS.findModByID("Mayburideck")
SMODS.Atlas {
key = 'mayburireplace',
px = 71,
py = 95,
path = 'MayburiDeck.png'
}
end```
hold on... there's nothing here that indicates what this should be used for, like for the playing cards, tarot, etc
damn where are you pulling this old code from
btw it's best to use malverk for texture mods
i wanna try finishing this though
there's plenty of examples out there
there's no point in basing your mod off the old system when there's something better available
is it just the playing cards
bridget playing cards ❤️
brisket <3
brisket?? where
okay i’ll try this tomorrow
development resumes today
damn people fw bridget here?
time to figure out how to initialize a dummy version of a blind
i’m making a retexture of her
like from guilty gear?
yeah
i already have the designs, i just can’t code to save my life, and i’m taking CS LMAO
nice
look
i also take CS
and here i am drawing
I have a bachelor's in CS, but game design is a different skillset entirely from what you learn in the classroom lol
that’s funny cause i’m shifting to art instead after 2 semesters of CS
but i wanna continue modding balatro cause it’s p fun
I'm in year 4 of com sci i think it's too late to quit 💔
maybe just a little late 💀
cant put down the cup
no time is too late
If I wanted to add a button that did something similar to the Run info button, (With a popup) And a centered checkbox, how would i do that
(I want the button to be where the run info and the button is, Instead of the ri and op being ½ i want it to be ⅓ With my button)
grim does something of the sort of its skills button iirc
BAGEL
Where do i find the code for that
-# Ik its github
-# But where
AppData/Roaming/Balatro/Mods/lovely/dump/...
Oh, that grim. Sorry.
and yes it's ok
you thought I meant the spectral? lmao
i'm a bit confused, if i'm gonna use this, what do i need to upload on modding sites to share my retexture?
for playing cards you don't need that
that looks great
SMODS.DeckSkin will work
sorry
Malverk works good if you want to retexture jokers
Malverk works for anything but playing card textures
It's crashing...
since the ink suit color is similar to spades, i dont know how to make the tarot look different from the world
maybe i color the background instead and make the center white?
where do i indicate the file name of the textures?
you need to also have an atlas
and use that in the atlas option
the thing we had before
ohhh
the DeckSkin then uses the atlas
it's starting to make sense now
(Note: that's the old format)
there's been an overhaul to the DeckSkin API. It's still compatible with the old format but it's been removed from the docs
palettes you say
do i need to put the atlas_table thing too? what does that do
in fact that's the default value, you only need to touch it if it's a different kind of sprite
(like an animated one)
is there a way to have only one deckskin for all suits?
is there a context for when you discard?
i mean, there's context.discard but it seems to run for each card discarded, while i only want it to be once
oh I forgot to mention, there's also an example mod https://github.com/Steamodded/examples/tree/master/Mods/DeckSkinTemplate
Grim crashes, so i cant see how it looks...
no, a DeckSkin is for one specific suit. That's how the game lays these out
oh i see
seems different enough
what am i supposed to put for my lc_atlas and hc_atlas? the documentation doesn't mention them
pre_discard is only run once afaik
mr smods mentioned that this is the old format
but lc is for low contrast and hc is for high contrast
Is the modding code the same as game code?
o, thank
modprefix_atlaskey
what do you mean?
If i copy the game code for a button, and edit the size, would that work.
yes
And how do i modify existing UI
should i just go collab for the pos_style too?
you either hook or patch the function that creates that UI element
i believe so
Uhh, ookay
does your png look like mine
if so i think you can use collab
i just edited in my pixel art to the 8bitdeck.png of the game
hn
put it on top of the face cards basically
so like the entire thing
yeah
'deck'
Any mod that does that
That i can learn from
a lot of them, what specifically do you want to do
i tried
if context.pre_discard then
print("wassup big dawg")
end
it seems it still runs correlatively to the number of cards i discarded + 1
or do i need to declare a specific card area here?
Change the size of the Options and run info button
this might just be a Lua unfamiliarity thing for me, but I cannot for the life of me figure out how objects of a specific class type are initialized
I think aure already told you a good example
yeah im not sure about this one
i think Grim does smt like that?
Grim? It crashes.
odd
So its hard to look for something i dont know how it looks.
any idea why this is still not working
SMODS.Atlas {
key = 'mayburireplace',
px = 71,
py = 95,
path = 'MayburiDeck.png'
}
end
SMOD.DeckSkin {
key = 'mayburiskinhearts',
suit = "hearts",
ranks = ranks,
atlas = 'maybr_mayburireplace'
pos_style = 'deck'
}
end```
I know that it does "something like that." But its hard to look for "Something like that"
prob
no need to have the end
also
i think you need both lc_atlas and hc_atlas but i am not sure
oh i see
you can just set it to be the same one for now
Especially on a "big" mod
my pc wifi decided to crash on me so cant show the footage of this, but the print output when i discard one card is:
"wassup big dawg"
"wassup big dawg"
oh i missed a comma
man
wassup big dawg
wassup big dawg
this is still a hell of a description
Wait, how do you create a custom side window
false...
Like gives
@tall wharf can i see what your function looks like?
Contribute to Aikoyori/Vocalatro development by creating an account on GitHub.
have a look
?
oh wait
i think my wifi is genuinely so shit it didnt fully load the page
thats the end of my page
😭
clone the wiki locally 🙂
why is video game

why is game video
why the long face
i tried this, it still prints equal to the number of cards i discard
hello my mod now has 10 jokers
glorious
i will make art for the rest of them
whats the ability.name for Bonus cards? ability.name == 'Bonus Card' doesnt seem to work, though it does work for wild cards so im guessing the name is different for some reason
use SMODS.has_enhancement
if context.pre_discard and context.main_eval then
is it forbidden to
though
how would one initialize a blind object?
oh thanks, what does context.main_eval mean?
the debugger window when opening the game is showing "Could not open device." is this supposed to happen?
huh
(i keep forgetting to turn off the mention when reply)
does it crash
nope
i run the game normally, i check the decks in the setting and it doesnt apply
i prefer pings honestly
did you add prefix to the atlast in deckskin
oh, i think it can be annoying when ur in the middle of something and the mention sounds pop out of nowhere
ah figures, thanks
im in the middle of working so this is the best time to annoy me
i dont want to work (dont tell my boss)
yup
im your boss N'
real
this was a social experiment.
the prefix is initialized at the header right
yeah
man
show code rn
i freaking love SMODS.Jokermmmmmmmmm{}
i have balatro pinned to the taskbar, resetting with m is annoying
i could just add another keybind to restart on press honestly
❤️
but my lazy ass aint doing that even though its easy 💔
oh i removed my mod from the mod folder and the error is still there, might be an issue with my injector, gonna redownload it
oshi no ko mention 👀
🔪
🩸
🔵 🔴
💢
💩 ending
lmao
forever hating onk for the ending 💔
it actually looks like the skybox in Minecraft
allo there again
immense aura
ello mate
i got a joker functioning on my own mostly lol
nice
anyways is it bad i dont know what the variable for the money is, is it cash, gold, or what 😭
im like searching the thingy
depends on what u wanna do
its how much money you have in the run
i wanna make a cloud 9 but with just every card on deck
that is truer
oh nvm
and then it breaks forever
isnt it just cloud 9 with modified if statement for the cash tho
i haven't messed around with money much
also the card i did was the lock one
such messy code but it functions
i got the first bit at the top from someone
How do i reskin a modded tarot with malverk?
SMODS.Atlas {
key = 'mayburireplace',
px = 71,
py = 95,
disable_mipmap = true,
path = 'mayburideck.png'
}
SMODS.DeckSkin {
key = 'mayburiskinhearts',
suit = "hearts",
ranks = ranks,
lc_atlas = 'maybr_mayburireplace',
hc_atlas = 'maybr_mayburireplace',
pos_style = 'deck'
}``` i fixed some obvious stuff but it still wont work :(((
it still uses the default deck
try Hearts with uppercase H
so the blind effects don't work yet but I love the way this switches the blind when the hand is played. And I didn't have to do anything special to implement that
visually I think this is really cool
@pearl trout
are localization files loaded automatically?
suit = 'Hearts'
how can i get the number of enhanced cards in the deck?
the method that Driver's Licence uses isn't immediately copyable
So this seems to create the blind object at least visually, but it doesn't let me call Blind:press_play() on it
G.GAME.blank_played = false
G.GAME.blank_blind = self.eligible_blinds[math.floor(pseudorandom('blinds')*#self.eligible_blinds) + 1]
G.GAME.blank_obj = Blind(G.GAME.blind.T.x, G.GAME.blind.T.y, G.GAME.blind.T.w, G.GAME.blind.T.h)
G.GAME.blank_obj:set_blind(G.P_BLINDS[G.GAME.blank_blind])
return
end,```
```press_play = function(self)
G.GAME.blank_played = true
G.GAME.blank_obj:press_play()
end,```
because it crashes saying attempt to call method 'press_play' (a nil value)
im pretty sure you can loop through the deck to do your own checks if you want
👍
maybe there's another method I need to call when I set the blind?
on the bright side, any blind that has a card debuff effect appears to have taken care of itself, because they debuff and rebuff on their respective hands without me having to do anything fancy
i wonder what would happen if you add a nil check in the press play
oh wait
you might be right
I think I might have called it on one of my custom blinds that doesn't have a press_play effect
I think these are everything listed in smods wiki. Am I missing anything?
whats that for?
Well, it should still call the default one anyways though
did you include context from optional features
I'm tired of typing "context." over and over again, so I made this.
-# *undocumented features
-# gotta love when someone tells you to read non-existent data 🗣️
I am confident that every documented context (that I'm going to need) has been included.
u could also uh do for i,v in pairs(context) and printout i ig
might work
idk. only helps if there are undocumented contexts
gn chat
gn
gn chat
thac ng
Gm chat
modify_scoring_hand and starting_shop
I think if I add a nil check it simply never executes...
so that's fun
Could someone plsssssss help me. I have a joker idea, but I don't know how to do it. I want to make a joker: If the first hand of a round is 1 card it transforms that card into a queen. Any idea how I would do that.
check DNA's code for first hand
so, if I move the set_blind() outside of this if statement, it throws a nil error..
G.GAME.blank_blind = self.eligible_blinds[math.floor(pseudorandom('blinds')*#self.eligible_blinds) + 1]
G.GAME.blank_obj = Blind(G.GAME.blind.T.x, G.GAME.blind.T.y, G.GAME.blind.T.w, G.GAME.blind.T.h)
G.GAME.blank_obj:set_blind(G.P_BLINDS[G.GAME.blank_blind])
G.GAME.blind:set_text()
end```
I thought I had properly defined a global for it, but it seems like something's not persisting
hey quick question, is there a way to quick reset balatro when testing localization? it's a bit slow to relauch balatro to look at the changes
how can i make a joker be debuffed for a certain number of rounds?
the fastest way I know is to hold m
which still relaunches it, but you don't have to do it manually
oh well it's better than nothing! thanks
if you have debugplus, you can do eval init_localization() in the console i believe
also hi blooky
well it just receives back, "nil"
yeah that's normal
can someone tell me how i can get started making my own mods?
the cards' loc should have changed
thank you i appreciate it
Hey out of curiosity, has anyone made a super-basic mod template with basically nothing but a very basic test joker? I think it'd be a really nice resource for new modders to have
Just want to make sure no one's made something like that before I do it myself later today ;p
https://github.com/Steamodded/examples this has a bunch of examples on things
Well sure, those are great examples of code to look at, but I'm moreso talking about a skeleton with a common.lua, assets folder with a placeholder Jimbo texture, placeholder json, and code for one test joker
not really, they stay the same, unless it's only changing the vanilla localizations and not modded ones (like ortalab)
which honestly i think that's it
This would mainly be for ppl who want to learn balatro modding but don't know very much programming at all. I found a template extremely useful when I first started SPM modding because there were a ton of moving parts, balatro is nowhere near as complex at all but I still think it could maybe be a useful resource ;p
true
You'd just pull it, replace json stuff, import your own assets, rewrite common.lua to have whatever you want, etc. etc. just saves time and could be a good learning resource
how do i make a custom suit list below the default ones instead of above them?
So apparently, it's only my custom blind object that doesn't persist when I reload the game...
print(G.GAME.blank_played)
print(G.GAME.blank_blind)```
If you click the steammodded examples link and click the example joker mod it DOES have that
It has the json, assets, etc
this is how I was handling them, but I guess it's not quite right
local eligible_blinds = {
'bl_hook',
'bl_ox',
'bl_arm',
'bl_club',
'bl_wheel',
'bl_fish',
'bl_psychic',
'bl_goad',
'bl_plant',
'bl_serpent',
'bl_pillar',
'bl_head',
'bl_tooth',
'bl_flint',
'bl_mark',
'bl_reverse_berkano',
'bl_reverse_dagaz',
'bl_reverse_perthro',
'bl_reverse_ansuz'
--'bl_reverse_void'
}
G.GAME.blank_blind = G.GAME.blank_blind or eligible_blinds[math.floor(pseudorandom('blinds')*#eligible_blinds) + 1]
G.GAME.blank_played = G.GAME.blank_played
G.GAME.blank_obj = G.GAME.blank_obj
return
end```
Ahhhh!!! I didn't think it'd be in a subdir 😭 Tysm sorry I should've looked more closely
and is there a way to hide a custom suit from the menu on the left in the deck menu until it's actually in your deck?
Np, this was actually how I got my stuff running was using this :)
I didn't know these could be used as templates & I wanted to learn how other mods worked, so what I did was pull the source for a mod (I think it was plantain?) and modified it until none of the original code remained xD
I found that to be a really cool way to figure out how all the files are read in lua, very interesting to me that you don't have to do #include for literally everything you use like i did in c++ 😭
I think i started working on 1326a for steammodded
So my code still retains alot of stuff from that because 'fuck you it works' but I need to start going back and changing things to the better way they have things set up now
someone should definitely start making tutorial vids
what is the correct way to set a custom global variable that persists over a reboot?
This would be fantastic
G.GAME should do just that, idk why it doesnt for you
and it's only that one variable
hm
is it because it's a table?
probably something setting it wrong
nope, shouldnt be
this is the only place in the code I could find "MANUAL_REPLACE" at, so maybe this is related
I'm going to post the code, because I feel like the odds I'm doing something wrong with the global implementation are pretty high
I should probably make the list of eligible blinds a global too for simplicity's sake
yeah it's not a table issue because this persists print(G.GAME.eligible_blinds) after I made the eligible blinds a global and reload the game
so it must be with the way I'm initializing the dummy blind?
idk
minecraft joker
I was gonna say that looked like a redstone block and a piston
indeed
very nice very nice
3d is hard to do in pixel art
yeah I bet
luckily squares you can measure out generally, but oof once the corners get complex, it becomes so much harder
just model it in 3d and then project the image down to a flat surface
Hard to do but you made it work! I love the art
Also the JOKER text being like minecraft chat is a really neat touch
meanwhile I will continue to be vexed by my ambitions exceeding my current knowledge of how to implement features
I'm this close to hard-coding in all of the blind effects
does anyone know where a good place to start would be when learning to mod Balatro? I know some lua and I've got like a basic understanding of how lovely and steamodded work, but I didn't know if there was a like guide anyone had made with tips for getting started
thank you!
You don't even need to know how lovely works, but it's definitely helpful if you want to do more particular things like changing joker backs
just starting I'll probably just try and make a basic joker or something, I made a custom deck design for face cards before, but I've got no clue if the mod I made even still works (or where I put it :p)
I've still got the art for it I made at least
yeah I've got absolutely no clue why my global object is resetting to 'MANUAL_REPLACE' when I reload the game
how can i make an an edition applied to a joker remove itself from the joker and then apply a different edition?
@pearl trout did you post the mod on gamebanana 😭
for future reference please post it in #1209506514763522108 and probably GitHub nobody uses gamebanana for Balatro
This is definitely the function that is causing me problems, and I'm pretty sure it is because I'm trying to use a table...
local ret_t = {}
for k, v in pairs(t) do
if type(v) == 'table' then
if v.is and v:is(Object) then ret_t[k] = [["]].."MANUAL_REPLACE"..[["]]
else ret_t[k] = recursive_table_cull(v)
end
else ret_t[k] = v end
end
return ret_t
end```
so I need to figure out how to load it manually when the game boots up I think
You can’t save objects like that
I'm getting an error saying that there's an unknown value near 'local', but I don't see anything weird.
I can't save objects that way, or it isn't possible to save that kind of object?
encountering an error trying to make a deck start with vouchers
That way
you have to cover the stuff inside the event with func = function
It won’t save objects in G.GAME
so then, where can I put it that it will save?
I see
Look at how it saves the card areas
You need to add a vouchers = {“key1”, “key2”,} to your config, not whatever madness you have here
I'm not seeing what about the CardArea doesn't also make it get culled
you forgot to define the start of the function
Whenever I open a booster pack, it's giving me an error due to the pseudorandom and I'm not sure why
now I get a different error
Oh dw I already fixed that
(okay I forgot the [1] but this is after I tried debugging myself, the [1] not being there doesn't make a difference)
like, it calls CardArea:save() on all of the cardareas, but what it returns is still a table so why would it not get culled?
it's getting caught up on the apply_to_run parts now, and it's getting hung up on one of the game's own variables??
for some reason, the chip gain on my joker isnt working? is there any ideas to make this work?
How do I create a new tooltip entry for a patched in attribute to playing cards? I wanted it to show up similarly to the extra chips from hiker
how are you checking for lost mult?
this litttle thing here
i dont think im qualified to assist in this
maybe its your return?
what is new_mult being returned as
god I wish I could find the actual place where Zodiac Deck's functionality is defined
whats the best way to check that
well im pretty sure you are the one that defines how returns are managed, and your return is just giving back a value without modifying any values
what is the return new_mult suppossed to be doing
wait this isnt in calc
no
yeah im just gonna step back and let someone else help
ok thanks for the attempt
Hello, it's been hours and i can't figure out how to make one of my jokers to display a message at the start of a round. Anybody would like to enlighten me on how i could figure it out?
use context.first_hand_drawn and card_eval_status_text() for that
or a return { message = } call (tho i haven't tested that)
Okie i'll try that thanks!
I did find it
Didn't change the result though 
uh
i would store the old mult somewhere
i think it should call a different function
well i have to do that to get the difference in mult
bro using vim theme
i giggled at this but thank you
wait what was the tag for checking jokers again
i dont think ive had to use it yet
self.config.center_key == "prefix_key" ?
ill try that out
persistent global variables on save continue to elude me
Ough it finally works I'm gonna combust
Get rid of the apply function
❤️
Look at the save function on the card objects
again, a table
It’s to do with how it serializes it though iirc
is it because it indexes it like this cardAreaTable.cards[#cardAreaTable.cards + 1] = self.cards[i]:save() instead of doing a table.insert() or something similar?
I don’t remember exactly how it works but I’m sure it’s to do with table depth or something
oop. global self value. can i do like you would do in calc and put self in the function?
what is wrong with the joker file
Am I not implementing pseudorandom here correctly? Why is it saying 'a nil value'?
"pseudorandom", not "psuedorandom"
if self.config.center_key == 'j_hpfx_cyanosis' then
hi
oh my god
why are you faster than me again

testing
Thank you 😭 I cant believe I missed that lol
It happens lmao
Code shouldn't ever have used complicated words like pseudo, ability, and consumable, the spelling errors cause too much harm
well, the name of the copied blind persists through save so I can probably set it up to create the table when the save is loaded 🤔
that might be easier
banana man
how the fuck
Is that the moon, looking away?
PICKAXE 😭
global card 
Is that in the dump?
ah
?
so i copied the code from debugplus's "win blind" function to use in a consumeable, but if i tried just copying the code directly, i could never actually use it, but if i remove the
if G.STATE ~= G.STATES.SELECTING_HAND then return end
then it bugs out and draws another hand while the win screen is playing >_<
bluenana
Because of lovely injects, the line numbers in those files won't actually match the line numbers in the source code. The lovely folder in your mods folder should have a dump of the injected code
ow would i check the number of cards being played???
ooooh
#context.full_hand
oh i am braindead
Smart, tell the zombie you're braindead so he thinks you ain't tasty
How do I create a new tooltip entry for a patched in attribute to playing cards? I wanted it to show up similarly to the extra chips from hiker
the question of the ages (i haven't figured this out but i think i saw some other mod was able to do this, one sec lemme pull it up)
I can check how I'm doing it later, but AutumnModMechanics' mult and xmult upgrades code does this, and is something you can peek at!
That's upgraded like hiker, at least
no crash (:D) but no score (:ᗡ)
😭
If you want a separate text box, Kino has one for genres you could peak at, though I won't act like I write competent code
I will look at those some other time, could be useful for custom enhancements
here's what im looking at
thank you!
now THAT is a pickaxe
do i just, add this in its own folder?
idk if it's safe to put a function in card ability
because cryptid might very well change that to 4.2
for custom enhancements, i think if you have like the basic stats (+mult, +mult in hand, etc.) then it should already show up in the description?
when you define a custom enhancement too, you can also just make its localization description include the extra stats you want
or crashes
im not sure designing your card around gimmicks that crash the game more often than not is a wise idea, anything can crash in cryptid if you have enough fun
I should start looking into how to make descriptions dynamically change. I'm working on a system for jokers to change effect based on whether they're in slot 1 or not, and I wanna keep the descriptions a slight bit contained
i see, thank you!
btw where do i put the lua file from that repo?
ok it shouldn't
there is a check
Also considering whether I should make a system that expands descriptions into more detailed ones if you press a key, because some of my jokers are... Wordy
so i think you can just put a function that changes the card
i think you put it in it's own folder? idk i haven't installed it yet
inside the ability
you can actually make it so entire lines are based on a variable, i've done that before with my dry bones joker.
my most painful part is it used to work (but no i wanted "big number" too curse you talisman compatibility)
Something like
card.ability.extra.bool and localize(' your first message key here ') or localize('your second message key here')
I do have that, but I don't love how I have to pass that information on. I'd prefer to just be able to have a second entry in the localization file
Bruhhhhh I still can't figure out this stuff I started trying to do last night
curse you straight calc
that i don't know exactly how to do, but i think you might be able to change the loc_txt variable on the fly? idk
are you trying to do shenanigans with straight calculations?
yes...
is there already a boss blind that was made that is kind of like an opposite of psychic, basically played hands cannot have 5 card? if not i was wondering how i could go about doing that
I have NO clue how it works lmao
it's ok vro i spent 3 days just to throw the work away
The horror
I'm planning on just diving deep into undocumented waters and seeing if I can give jokers specialized descriptions. Updating in the fly would still leave the problem of having to put game text in the code rather than in the localization file
The worst part is that I feel like I'm close. What I have rn makes any 5-card hand return as a straight for some reason
im just trying to make it where any 5 card hand just doesnt score
idea for new joker: any hand now counts as a straight 
Closeted Joker
That sounds very easy to do ngl
are you changing the priorities in power ?
the huh
how dare you be funnier than i /s
aint for me 👁️
if #current_hand == 5 then card:debuf or something like that ?
smthn like that
i need the template for a blind in general actually
actually, show code
it'd probably be a return true in debuff_hand
did you make a new Straight hand ?
No I did not. I'm hooking into get_straight
hey people im working on making a custom language mod for balatro and for some reason every time i test it it returns to base english, i used balatro uni as an example and for some reason even the base mod doesnt work
actually is there a fresh custom blind template?
is it returning a bool ?
you might be modifying/returning always true so it always returns as a straight
It's basically an exact copy of SMODS' get_straight override with the edits I've put in which come right after the shortcut check. here's the code
ew yucky formatting
ew
why it look like that
If I wanted a deck to remove every card and then manually add a specific set of cards, what would I do?
remove_card doesn't seem to work unless I'm using it wrong
and whats your goal essentially ? do thinks to straights but all hands are straigtht ?
um i haven't worked much with decks but try deck creator? it's really easy to make the kind of deck you're looking for
deck creator?
On the subject of tooltips, I'm attempting to add a tooltip to a UI element that is NOT a card. tooltip is insufficient as doesn't seem to allow customizing the style.
Ideally I'd leverage detailed_tooltip, but this process involves passing the config through the generate_card_ui function, which is a bit unwieldy to grok and is producing an Error tooltip. Is there a source that better describes how to use detailed_tooltip correctly?
no. basically the idea is allow faces or aces to fill in gaps within a straight
is deck creator up to date with the current version though?
oh use face/aces as any cards in a straigth
basically yeah
https://github.com/XLuma/Balatro-DeckCreator I updated the mod for latest smods/balatro/calc here
are you limiting how many faces/aces can be used in a straight or can you just like do
A Q A K Q
and even hands like high cards get treated as straight ?
(without having 5 cards played)
Yeah I have it so the boolean can only be set once
No, it's only 5-card hands
if straight_length >= (5 - (four_fingers and 1 or 0)) then
straight = true
end``` this dont make sense ? its always true
That's base SMODS, not me
which code is yours if you can strip it down
This right here is all I added (not counting the initial has_face_filled declaration at the top)
since I assume get_straigth actually doesnt make your hand become one
What is this juice up
The little shake animation cards do
this alone seems alright, nothing looks like it would make evrey 5 hand become a straigth
I agree lol
Making a card like the baseball one and i look for the code for reference and i find "juice up"
and im like "what is this?"
So i go to discord and ask
"Tf is juice up"
However
Juice up is the card shaking
byeah
Ok
so I was answering the question right
the fkn gif made me think you already knew 😭
Looks like the code works as intended lol
No lol
maybe you're not checking the rank properly? dk
There's a chance of that
SMODS ranks are weird man
the two is clearly filling in a gap it shouldnt
And as I said, it goes for any 5-card hand
can you test if it does that for something like 9 6 2 3 10
just so we can have it be like absolutely no straight is possible there
do nil checks on face and shorthand
I'll test that when I get the chance. I can't launch the game for a half hour or so due to classes lol (the screenshot was old)
how about this
i am mining blocks and shit
also indexing via val works ? isnt vals a table so val is an object, not an index ?
Imma be so real, I've stared at the function for so long and I cannot make sense of how it actually ticks
?
You really nailed the diamond block. I reckon some edge lighting the pickaxe would look great too
also sendTraceMessage() exists and you should use it
I'm aware. I've tried
Stupid problem
i cant get this thing to say 1.5 mult instead of nul ingame
you just want #1#
that gives you the first entry in the returned vars table
Where do I find the message sent from sendDebugMessage
your console
So it has to be 1?
because each number inside # # represents a variable in loc_vars i.e. #1# is your first variable, #2# is your second, and so on
i noticed your loc_vars uses center instead of card, maybe try replacing center with card in both the function() and the return {vars =}
Ok lemme see
why is this not working in deck code?
sendDebugMessage(tostring(G.playing_cards))
its crashin
center does work, it's just a different name for the function input, it's just not standard lol
No still
show code
opinions?
Wait that's a sick concept
Is the information about stickers stored anywhere specific? Like how Seals are in G.P_SEALS, centers are in G.P_CENTERS? I want to add the sticker information on a consumable popup, do I just feed in G.localization.descriptions.other.[sticker]?
Joker? Boss Blind?
capitalize Xmult
hell yeah
oh i’m sorry! i just wanted a place to put the mod in to share on twitter
i saw it on bsky 😭
Oh please don't let this be the bug
ohhh gotcha
wait so how does this work? like how do you deal damage
there are literally 11 mods for Balatro on GB
😭
You were right
Yeah mod hosting sites won't do you any good
It was
yep
it's so much easier to upload to github too i love using github desktop ❤️
github is so much easier for mod creators and so much worse for users haha
apparently the latest version of steammodded causes this condition to fail inside of tarot packs if G.STATE == G.STATES.SELECTING_HAND or G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK or G.STATE == G.STATES.PLANET_PACK and #G.hand.cards > 1 then
tbf with balatro mods you can legit just download the "source code" and put it in it's really easy
Will a context like this count for all hands that have a Pair in them (like Pair, Three of a kind, four of a kind, two pair, full house, etc)?
i think you gotta surround it with next() but yes
ok i need to work out the description
chips scored are damage
as it stands, it hits for all hands
Like this?
ah
i love fifty mile long descriptions lmao
Forgot the sprite lol
i try not to be too verbose
Okay yay
The true invisible joker
now it works for all hands that contain a pair
i'm probably going to put that in an info queue
me too, but sometimes it just happens...
Perfect!
that doesn't just mean all hand types that inherently contain pairs though
it worked on 1418a but it does not on 1427c
(this used to also apply splash btw)
Doesn't seem like a smods version issue
you can totally split that into three lines it would work much better
I think you're just forgetting about G.STATES.SMODS_BOOSTER_OPENED
I should really show my Poet joker here...
this one needed three info-queues because i didn't want the description to be fifty miles long
Vanilla boosters no longer have their respective states to be true (this was to address a bug related to vanilla booster relying on logic with their state instead of SMODS_BOOSTER_OPENED, such as their UIBox overriding SMODS reimplementation).
creative process
forged in the fires of mordor
so i am following the example mod of Runtem for the random chance of being destroyed taking some bits of the gros michel 2 example and it wont understand what "context" means.
i have checked for typos and therre are none, any advice?
link to the example mod, the thing i attempted to copy is at line 377 (https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua)
i wonder if i can make a consumable that allows you to skip a blind and go straight to shop 🤔 I know it's possible to go into shop inside a blind because of cryptid's code cards but idk if it's possible to win/skip a blind through a consumable
this is the first time ever i feel like the fire i draw feels hot
what function would I used to add a card to a deck
right now I'm doing
local t_cards = {
"7",
"6",
"5",
"4",
"3",
"7",
"6",
"5",
"4",
"3"
}
G.playing_cards = []
for i = #t_cards, 1, -1 do
G.playing_cards[i] = create_playing_card({front = G.P_CARDS['Clubs'..'_'..t_cards[i]]})
-- G.playing_cards[i]:set_base(G.P_CARDS[random_s .. "_" .. random_r])
end```
and it's not working
so I assume it's either not create_playing_card, or I'm not using it right
oh nevermind G.playing_cards = [] doesn't work
huh.
oh wait
oof i used wrong brackets
i think
I'm working on a joker and I'm attempting to make it play a sound when triggering, for some reason the sound isn't being registered though, and the game crashes when the joker triggers. All my folders are in the right place, and my sound registering looks like this:
SMODS.Sound:register_global()
SMODS.Sound ({
key = 'yippie',
path = 'yippie.ogg'
})
when I try to trigger it later I'm using this:
play_sound('yippie')
if G.STATE == G.STATES.SELECTING_HAND or G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK or G.STATE == G.STATES.PLANET_PACK and #G.hand.cards > 1 then
return true
end
end
is there a context for when a joker appears in general? like when its seen in shop or gets created by judgement
basically a context for when a joker starts existing in any shape or form
so when a specific joker appears
yea
its for a joker that uses random poker hands, i cant figure out how to randomize the first
what?
so
like if the joker appear
as in
if you already have a joker and if another specific one appears
no
or just if joker appears
just if the joker itself appears
then you can use add to deck i believe
does that work for when it appears in shop before you buy it?
I believe it only works after you purchase
is there somewhere I can find all the base functions?
stuff like "set_base"
I'm searching through the wiki on the steammodded page and can't find a lot of stuff
i reccomend reading the balatro source code
I don't know how to do that
you can extract the exe for balatro with anything like 7zip or winrar
to-do list is weird cuz it randomizes its rotating variable different from all the other vanilla rotators lmao
What functionality are you going after?
This joker is meant to scale with each hand played of the same type as the random type, and the type changes at the end of the round
I did that. so where would I go to look for functions for decks like set_base?
and now back to my regularly scheduled trying to figure out how to make a global table variable that persists on reload
you can probably just create it in reset_game_globals
im not sure where decks are located
aha ok
so what you're gonna want to do is set up a SMODS.current_mod.reset_game_globals function
i mostly look at the functions in jokers (inside the card.lua file)
I have done this, and every time I reload the game, it gets reset to 'MANUAL_REPLACE'
huh
is there a file or place that has simple mechanics we can mix and match for those who aren't good with coding? example something like increasing xmult by x1 when a blind is selected. Sorry if this has been asked a lot!
works fine for my case
First time someone's actually asked for something like this
this is the code in question
So from what I'm looking at, is G.playing_cards[i]:remove_card() right?
does the function have any paramaters? or do i just write the code inside that function
Refer to this screenshot for more specifics (thanks alrex)
how did you implement it?
in my case i create the table only if run_start
no, remove_card is for CardArea and that's an array of cards
mostly because it changes dynamically
ugh
where would i add this function?
are there people out there who are able to legitimately just look at the source code and know exactly what to do?
You're also probably gonna want to hook into init_game_objects so you can set an initial fallback value for when you're not mid-run
Anywhere in your main.lua
me
I'm looking at the source code and I just can't figure out what i'd do here