#💻・modding-dev
1 messages · Page 587 of 1
now that you mention that, it could be easier to do yesterday's worlde but i think thats less fun
i am once again asking why this doesnt work
its loc_txt, not loc_text
i gotta be honest thats the first time ive even heard of that idea
not without patches. theres only 3 blind choices that can be used
you would have to patch in another and then do a bunch of ui shenanigans to make the blind selection also show it
maybe its easier to assign the joker a random word from all the wordle options instead
G.GAME.round_resets.blind_choices.Big = "bl_modprefix_key"
just make a function that picks a random blind with a certain parameter
thats how get_new_boss works too, it grabs a random blind with a boss parameter set
where do i put the function
wdym where do you put it? like where you want to change the big blind i guess?
local date = os.date("*t")
local newdate = string.format("%04d-%02d-%02d", date.year, date.month, date.day)
local _, json = require"SMODS.https".request("https://www.nytimes.com/svc/wordle/v2/"..newdate..".json")
local word = JSON.decode(json).solution
```?
hold on im still making the sprite 😭
okay so how do i make something that checks the value of local word?
in vs code
<@&1133519078540185692>
What do you mean?
like just a System.out.println(word); in java
print(word)?
yes that ty
okay so furthermore on this
https://www.nytimes.com/2025/09/27/crosswords/wordle-review-1562.html
wordle has these "articles" that gives you hints and the answer on the wordle
and it shows even the one in advance
Do you want to retrieve those in text form?
hmmm
i think so?
bcs i want it to store the daily wordle, idk how else you'd do that
No, the code I gave you does that.
how do you run a lua file in vs code tho
previously ive just been booting up balatro to check lmao
Yes, that's how you do it.
how do you make an easy check to see if something is working then?
Use DebugPlus
I've been using that but how do I check If the code u gave me correctly gives back the wordle
eval code in the console.
But it does work.
I tested it.
what day does it take the wordle from tho?
Today, according to your computer.
alr
how do i make this code run when you launch the game
bcs it does indeed work (really surprised you can just check the worlde in 4 lines of code) but when i play a blind with the joker in hand it takes like a second to load
Do it in Game:main_menu
Also it could be one line.
do i put that code in my main?
am I applying the editions wrongfully in this challenge?
local word = JSON.decode(({require"SMODS.https".request("https://www.nytimes.com/svc/wordle/v2/"..string.format("%04d-%02d-%02d", os.date("*t").year, os.date("*t").month, os.date("*t").day)..".json")})[2]).solution
Yes.
I answered myself
g
why do the brackets not see eachother?
No, you hook it.
what does hooking something mean?
im reading the example and it uses Card: something something, what on earth do i need for checking the local wordle?
local oldmainmenu = Game.main_menu
function Game:main_menu(change_context)
local g = oldmainmenu(self, change_context)
local date = os.date("*t")
local newdate = string.format("%04d-%02d-%02d", date.year, date.month, date.day)
local _, json = require"SMODS.https".request("https://www.nytimes.com/svc/wordle/v2/"..newdate..".json")
G.modprefix_wordleword = JSON.decode(json).solution
return g
end
so a hook is essentialy storing an entire function inside a single variable?
No, every function is stored in a single variable.
wdym every function?
Every function that exists.
To run code before or after the function runs.
lua is such an interesting language
ah
the jimbo curse
is taking over
so I got 2 issues here:
- the jimbo curse
- the negative edition not applying on the other half of the cards
Code?
havent made the custom rules and stuff yet
doing the starting stuff first
quick question do custom jokers appear in buffoon packs or judgement automatically or do I have to implement this myself?
they should appear automatically
ok thx
yes
e is the enhancement, d is the edition.

Also it's without the e_ prefix.
I love having to change 52 lines
twice
🗿
I just sneezed so hard I felt my soul leaving my body
why am i getting this error
does anyone know why the last pixel of my pack is being extended this is my atlas lua SMODS.Atlas({ key = 'Junk1', path = 'JunkPack.png', px = 71, py = 95 })
pixels at the edge of the 71x95 area usually cause colour bleeding issues, not this
yep
oh nvm then
what are you saying i do to fix it
it does
local other_card1 = nil
for i = 1, #G.hand.cards do
if G.hand.cards[i] == card then other_card1 = G.hand.cards[i + 1] end
end
if context.cardarea == G.hand and context.other_card == other_card1 then
return {repetitions = 1}
end
why this not work?
the sprite is way too small
you need 71x95
and then a 1 pixel gap between the border
oh am i supposed to leave extra room
yep
yeah
regardless of the actual sprite size, all centers should be 71x95 sprites
I don't want the joker I actually want this to work in the hand
thanks
that is unless you specify a size change
then why are you doing if G.hand.cards[i] == card
card is the joker
wait then how do I check for the hand/scoring hand
context.other_card
what card are you even trying to retrigger
it is an edition that retriggers the card to the right
playing cards cant retrigger anything other than themselves
would require some extra shenanigans for the playing card version of the edition
oh man
been messing around with retrigger effects and was wondering if there is a context that occurs directly after all retriggers involving this joker has. my joker uses a count to determine how many retriggers occur but i cant seem to find a way to set the count back to zero after it has finished retriggering without breaking blueprint and brainstorm interactions
its pretty simple to retrigger other playing cards now we have mod calculate functions
depends on what youre trying to do i imagine
yeah i know, the way my joker figures out how many retriggers to do is based on a count tho and blueprint and brainstorm cause issues
in my current implementation, im using context.after to reset the count which works for after scoring situations but doesnt take into account if the joker was triggered or not
just resetting card.ability.extra.count before the return should work
i imagine
actually
what is card.ability.extra.count
it doesnt unfortunately because if blueprint or brainstorm are used, they'll reset the count and then the joker wont have its own retriggers to use
its a counter im using to keep track of retriggers in my joker's config.
the way my joker gets retriggers is by playing gold cards with each gold card adding to the count. if the joker is used to retrigger, i want the count to get reset to 0 but right now, it'll only work if its being used immediately to score whereas i want to have the option to be able to save the retriggers when not pointing to another joker thats involved in scoring.
im curious if there is a way to use event but i dont quite know how i would do so
card.ability.extra.xmult,
localize(suit, 'suits_singular'),
colours = { G.C.SUITS[suit]
} } }```how to use the color in loc_txt
{V:1}
how to make editions not appear for playing cards?
how do i make a joker check if there's another specific joker anywhere?
i want to check for j_otm_python
how would i do that
SMODS.Find_card
if next(SMODS.find_card('j_modprefix_key'))
like this?
Yes.
how to check during context.after if the hand was not valid during a boss blind (not 5 cards for example)
No, it's context.debuffed_hand
how do i change the scale of a consumable like how wee is but with a consumable
The same way you’d do for a Joker AFAIK
i dont know what that is
Jokers?
no AFAIK
as far as I know it means a friend and I know 😉
“As far as I know”
Anyways it’s somewhere in the wiki but it might be easier to look at Vanilla Remade
Because I assume it’s done there too
ok
how can i give a index to my custom rarity
What do you mean?
Why?
so i dont have to add the joker to a table in the rarity everytime
why does your key have formatting
you do rarity = "modprefix_key" in the joker
adding a name to things doesn't do anything, you want loc_txt or a localization file
mmm, how do people add buttons into the run_setup screen properly? I want to rewrite my code from a while ago because right now I'm just inserting the button very awkwardly..
dude
I would look into how cardsleeves does it maybe
it's likely those don't take formatting
ty
alrighty
does badge_colour support gradients
Yes.
how so
will this work?
Yes.
kty
if i wanted to go about
A. altering the card on the main menu
B. pushing the card on the main menu upward
how would i go about that?
i literally cannot find the vanillaremade or whatever mod no matter what i search on google
Please don’t spam
repeating your question 3 times doesn't make it more likely for someone to answer
i sent it 2 minutes inbetween each time
okay but the old messages are still visible
no they're not
(i'm joking)
i still don't know how to sprite new ranks :P
i'm trying to sprite a new rank, not a suit, a suit sounds much more simple than a rank, but i'm trying to sprite a rank
Have you tried reading his name
how is that any different its still in the docs
its the same as suits but organized in columns instead of rows
X or Y
because i don't know if you're saying if each should be in a different column or if they should all be in a column
set = "Joker"
organized in columns means they should all be in a column
like this?
yes
and then the suits should be in the same order as the suits are in the vanilla sprites iirc
like this? (this is obviously not the final version, this is just a base so i know what the cards look like)
If you’re making a new suit or a deck skin you don’t need the background for the card
i know :P
it's just good for me to have as a base
so that i don't screw it up
also i'm making a new deck in general
not deck
rank
Suit
i'm making a new rank
Ah
thats the correct order i think yeah
yeah
I think that's covered in VanillaRemade
Also... I'm having problems installing mods still
i did it! thank you
ooh
#⚙・modding-general, also ask an actual question
guys is there a way to create a deck that starts only with specific ranks?
like abandoned deck but I wanna remove 8 9 and 10s
Again, VanillaRemade
everything I'm trying is either deleting every rank ore none
I'll check it out thanks
I was using olatrab and paperback as reference code
i can't find anything called like that... am i dumb
can you give me a link
tnx
abandoned deck uses
apply = function(self, back)
G.GAME.starting_params.no_faces = true
end,
but 8, 9 and 10s aren't in a category like face cards
What is the code for the chances of a joker appering in the shop?
probably tied to its rarity
Got it. thanks
so can anyone explain how negative works as a shader
trying to recreate it in blender
Now how can i find the rarity in the files of vanilla balatro?
What's the best/easiest way to implement increasing the odds of certain Jokers appearing when a special deck is being used?
Not of certain rarity, just strictly saying that x, y, and z jokers appear twice as often
local rarity = joker.config.center.rarity
local new_joker = SMODS.create_card({
set = 'Joker',
legendary = legendary,
rarity = rarity,
edition = joker.edition,
stickers = joker.stickers,
})
trying to make a consumable that rerolls a random joker into a new one of the same rarity, but for some reason it only rerolls into rare jokers.
there isn't a good or easy one really, joker pools work off of rarity
the rarity value in create_card works different than the normal rarity values, it's in the docs
you probably want to convert the rarity to the string keys ("Common", "Uncommon", etc) first
Ahhh that's a shame, thank you!
Specifically, How can I access the code to see the weight of the vanilla rarities for balance?
do you want to change the weights or just see them
just see them
And these are the original games weights (The words "Remade" kinda make me feel like they got edited.)
yes
Okay, Thanks.
vanillaremade is just recreations of vanilla stuff using smods, these are just copied from the smods version of the rarities
local rarity = (type(joker.config.center.rarity) == 'number' and ({"Common", "Uncommon", "Rare", "Legendary"})[joker.config.center.rarity]) or joker.config.center.rarity
local _pool, _pool_key = get_current_pool("Joker", rarity)
local key = pseudorandom_element(_pool, pseudoseed(_pool_key))
joker:set_ability(key)
```?
figured it out
although now I should figure out how to make it so that it only gets an edition if the joker that is being rerolled had an edition previously
oh wait i figured that too
No, card.stickers doesn't exist and card.edition is not a key.
then how do I apply the stickers and edition from the joker?
also if you just want to change a joker for another the easiest way is to do joker1:set_ability("key for joker2") and it will keep everything
did some testing, and suddenly I got this:
INFO - [G] 2025-09-28 13:28:20 :: ERROR :: StackTrace :: Oops! The game crashed
card.lua:262: Could not find center "UNAVAILABLE"
how do you check if a card is a consumable
figured out the issue
if card.ability.consumeable
thx
local rarity = (type(joker.config.center.rarity) == 'number' and ({"Common", "Uncommon", "Rare", "Legendary"})[joker.config.center.rarity]) or joker.config.center.rarity
local _pool, _pool_key = get_current_pool("Joker", rarity)
local key = pseudorandom_element(_pool, pseudoseed(_pool_key))
local it = 1
while key == 'UNAVAILABLE' do
it = it + 1
key = pseudorandom_element(_pool, pseudoseed(_pool_key..'_resample'..it))
end
joker:set_ability(key)
what does get_id return for stone cards
yea I figured something like that
local key = pseudorandom_element(_pool, pseudoseed(_pool_key))
while not G.P_CENTERS[key] do
key = pseudorandom_element(_pool, pseudoseed(_pool_key))
end
this is what I proceeded to do
No, you should use the code I provided.
iirc some random negative number
A completely random negative number between 100 and 1000000 not based on the seed.
oh
Fun
how do i check if a Joker is being destroyed? i had this but this isn't working
if context.selling_self or (context.destroy_card and context.destroy_card == card) then
if context.joker_type_destroyed
No, use the remove_from_deck function.
i tried that but it didn't work for my application
i need it to delay before it gets sold
(or destroyed)
What is the goal?
play a sound, eval a status text, delay 4.5 seconds, proceed
You mean you want it to display a message with a sound, wait 4.5 seconds, then continue with the destruction?
For what?
for a card enhancement, how do I check when the card itself is about to be destroyed?
if context.remove_playing_cards and table.contains(context.removed, card)
how do I check the card's rank and suit?
if card:get_id() == id and card:is_suit("Suit")
Is it possible for something to be something and not be something at the same time?
what does that even mean in the context of balatro
A card could be a face card and a non-face card at the same time.
how do I check if a very specific probability succeeds, specifically something like wheel of fortune?
Like a Glass card that never shatters as it's not a glass card
if context.pseudorandom_result and context.result and context.identifier == 'wheel_of_fortune'
so like, Card:is_face() would be true but not Card:is_face() would also be true at the same time?
Yes.
i would imagine that couldnt be the case
i cant think of a possible way that this could ever be true
Card:is_face == not Card:is_face()
i dont think that would be possible, would require a not metamethod i imagine
but that doesnt exist
what about for the banana jokers?
also even then you would have to differentiate any random false from a false coming from is_face
No, you could set a flag when the first one runs that tells the second one to return the opposite.
hmmmmge
yeah i suppose
but that would also rely on separate calls
i dont think there's a good way to make a playing card be both treated as a face and a nonface card
cuz if for instance Midas Mask calls Card:is_face to check if its truthy and Ride the Bus calls Card:is_face to check if its falsy
there'd be no way to predict the order to have Card:is_face determine whether it should return its normal or inverted value
so i think its safe to assume that if Card:is_face is true then not Card:is_face is false
use a lua parser to replace every instance of not Card:is_face with a unique function :clueles:
oh
yeah true
Why when i print to console does nothing happen
the function that the print statement is in is called and properly works as seen by my mod working but nothing gets printed
🤔
oh u right im brainwashed
Yes, that was just a possible way that would work specifically in that situation.
I wonder if the new context stack stuff could help
hmm maybe
guys why does my joker keep getting a self destructive tag applied?
but then you'd need to know somehow if a joker is checking if a card is a face or if a joker is checking if a card is not a face
and i cant think of a good way that doesnt involve checking the code of the joker
Also Ride the Bus would still reset because technically the card is a face card still I think.
is there a way to change the strength effect for a specific card? for example strengthening a 7 to a new rank I made
Also it doesn't check not card:is_face() so it would be difficult to check even if this wasn't the case.
I don’t know if there’s an easy* way to do it. Try looking at the wiki and age for Ranks
And/or the function they cite for changing the rank of cards
Otherwise, you could try taking ownership of Strength, or hooking the aforementioned function
I found there is a next parameter but not previous
that sounds like a lot of work
But did you find the function?
Maybe at the bottom section, where it lists methods
table.insert(SMODS.Ranks["7"].next, 1, "modprefix_key")?
It doesn’t seem like a good way to do it
Why not?
It seems dubious to manipulate the config of objects mid run; I don’t know if it affects existing objects, and how it interacts with saving and loading
It’s more straightforward to hook the SMODS function that changes ranks and use that
They didn't say they were doing it mid-run
I need to change it in general
like whenever the mod is active the strength effect is different
Oh
not for specific jokers or decks
Just take ownership
Then yes, you would do table.insert(SMODS.Ranks["7"].next, 1, "modprefix_key")
I think that’s the recommended way
Taking ownership is better practice
It avoids collisions, for one
No, it doesn't.
hmmm... does this work if I want only 7s of specific suits to do that?
What do you mean?
It overrides everything in the center that was changed.
No
yeah I mean is there a way to add an if
Hook SMODS.modify_rank
I don’t follow your argument
-# which is what I had suggested originally
Perhaps, but that is how it works.
I don’t think it is
Which is why I don’t understand
Taking ownership checks for collisions
AFAIK
No, it just replaces everything.
So two mods can’t change the same value
I thought the point of taking ownership was to check for collisions
i have an absolutely evil idea for a blind, but i don't know how i would make it
as soon as the blind starts, you get 100 seconds, and if you fail to beat the blind in those 100 seconds, you immediately lose the run
reference cryptid "the clock" for how to track time
couldn't i just use os.time
that's in base lua
the main issue would be drawing a timer to the screen
No, you would hook Game:update
oh yeah because pausing and stuff
how do i hook
and also how do i draw the timer :P
time since asking: 30 minutes
responses: 0
... where do i put the localization strings for a new consumeable type?
Localization > misc > dictionary
can you be more specific? there's several relevant localization strings and i don't know what keys they go under
k_key is for the label and b_key_cards is for the collection.
and the undiscovered description?
SMODS.Challenge {
key = 'laundry_day_1',
rules = {
custom = {
{ id = 'laundry_day' },
}
},
jokers = {
{ id = 'j_DNA' },
},
restrictions = {
banned_cards = {
{ ...27 jokers... },
{ id = 'c_star' },
{ id = 'c_moon' },
{ id = 'c_sun' },
{ id = 'c_world' },
{ id = 'c_sigil' },
{ id = 'c_incantation' },
{ id = 'c_grim' },
{ id = 'c_familiar' },
{ id = 'v_magic_trick' },
{ id = 'v_illusion' },
{ id = 'p_standard_normal_1', ids = {
'p_standard_normal_1', 'p_standard_normal_2',
'p_standard_normal_3', 'p_standard_normal_4',
'p_standard_jumbo_1', 'p_standard_jumbo_2',
'p_standard_mega_1', 'p_standard_mega_2' } },
},
banned_other = {
{ id = 'bl_club', type = 'blind' },
{ id = 'bl_goad', type = 'blind' },
{ id = 'bl_window', type = 'blind' },
{ id = 'bl_head', type = 'blind' },
},
},
deck = {
type = 'Challenge Deck',
cards = {
{ s = 'H', r = 'A' },
{ s = 'H', r = 'K' },
{ s = 'H', r = 'Q' },
{ s = 'H', r = 'J' },
{ s = 'H', r = 'T' },
{ s = 'H', r = '9' },
{ s = 'H', r = '8' },
{ s = 'H', r = '7' },
{ s = 'H', r = '6' },
{ s = 'H', r = '5' },
{ s = 'H', r = '4' },
{ s = 'H', r = '3' },
{ s = 'H', r = '2' },
}
},
}```
Code for a mod challenge I'm trying to play
this could help you https://discord.com/channels/1116389027176787968/1292578290665525338
"could"
You guy want to read the crash log?
yea, gimme one second im getting in my computer
you can copy paste from the crash screen
I probably should have
see above
can you send the whole file
@red flower see here
whole
im assuming thats not the whole file because it says ...27 jokers...
not an edited snippet
it's a syntax error but i dont see it there
It couldn't fit with all 27 jokers in place
don't send it as a message, upload it as a file
My Challenge, called Laundry Day, which rescricts your deck down to one suit of cards
I don't see the problem there either. Maybe you didn't save?
well yeah but it won't, its just an api that adds challenge rules and thats it
Save what?
the file
to your hard disk
maybe you just typed the changes and then didn't commit them
Ooohh!
i mean that seems unlikely but it's worth checking
most things you can use to edit lua files don't autosave
Then how save in github?
are you editing the file on github, the website?
yea
that is,
certainly a workflow you've chosen
you should edit the file that's on your computer
that a problem, or...
smods isn't looking on github for your mods, after all
it's looking in your mods folder
I download the files when I fix them and put them there
okay, well, double-check that you actually did that with this one
yeah i straight up don't get this error when i load that file
Woops. I didn't, thanks for catching it
i generally recommend editing your files in a local workspace, perhaps using a tool like visual studio code, and then using git to put your files on github (visual studio code integrates this and makes it easy to do without having to learn git itself, probably other coding environments do also)
j_dna, not j_DNA
keys are case sensitive
ah. but what about the center issue?
i believe that is the center issue
it's trying to get info about j_DNA, which doesn't exist
Still not working
same issue too, indexing a local center
Also, it's titled "ERROR", so... I'm a bit bad at ccoding
it doesn't have localization strings
How do I add those in?
easy way to do it is
loc_txt = {
name = "Laundry Day"
}
the proper way to do it is to make a localization file, but that's a fair amount of work to get started and only relevant if you expect to translate the mod
Also, when I click on restrictions, it just crashes then and there
kid named dump_loc:
yes, managing that for the first time is a fair amount of work
what is
getting rid of all the random additional stuff that gets in there because you're a new modder who doesn't know what you're doing
(source: that's what i did lol)
what random additional stuff, just don't run other mods when you do it
Not getting the game to crash upon trying to make a bonus challenge happen. Also, it's only the restrictions, the deck works just fine, and the name didn't update.
(if there's additional stuff from smods, that's a bug and I don't know about it)
Any reasons why the restrictions seem to break th game?
not really, i haven't made a challenge in a while
hold on lemme have a look at the crash
give me a momen
probably one or more of your keys is wrong
it's trying to display the restricted cards, so if a key is wrong it will try to index G.P_CENTERS.["key that doesn't exist"], which will be nil
you still have j_DNA
I think some of the jokers are wrong or inaccurate, but Idk their actual code
it needs to be j_dna
lmao yes that would do it
the bans wouldn't cause a crash if they were to be inaccurate
might have the wrong files...
they'd just fail to ban the card
best way to determine a card's key is to search localization/en-us.lua in the vanilla source for it
banned_cards = {
{ id = 'j_greedy_joker' },
{ id = 'j_lusty_joker' },
{ id = 'j_wrathful_joker' },
{ id = 'j_gluttenous_joker' },
{ id = 'j_blackboard' },
{ id = 'j_seance' },
{ id = 'j_shortcut' },
{ id = 'j_ancient_joker' },
{ id = 'j_castle' },
{ id = 'j_certificate' },
{ id = 'j_smeared_joker' },
{ id = 'j_certificate' },
{ id = 'j_bloodstone' },
{ id = 'j_rough_gem' },
{ id = 'j_arrowhead' },
{ id = 'j_onyx_agate' },
{ id = 'j_flower_pot' },
{ id = 'j_seeing_double' },
{ id = 'j_crazy_joker' },
{ id = 'j_droll_joker' },
{ id = 'j_devious_joker' },
{ id = 'j_crafty_joker' },
{ id = 'j_four_fingers' },
{ id = 'j_runner' },
{ id = 'j_superposition' },
{ id = 'j_the_order' },
{ id = 'j_the_tribe' },
{ id = 'c_star' },
{ id = 'c_moon' },
{ id = 'c_sun' },
{ id = 'c_world' },
{ id = 'c_sigil' },
{ id = 'c_incantation' },
{ id = 'c_grim' },
{ id = 'c_familiar' },
{ id = 'v_magic_trick' },
{ id = 'v_illusion' },```
here is the joker ban list, as is written in my code
jokers = {
{ id = 'j_DNA' },
},
you didn't update this
but again that would just not ban the card, not crash the game
the crash is from the j_DNA
gimme a second
(uploaded th wrong file)
these also each don't have _joker unlike their suit counterparts
do you have that exact file in your mod folder?
yes
does it still crash
when does it crash and what's the crash log now
As soon as I click on 'restrictions'
oh alright
that's because of the bad keys then
smeared, crazy, droll, devious and crafty are what I've noticed
does someone know how to code custom card skins into the game?
new altas
oh hello again
hi there
and ancient joker's fine as is?
have you seen this example mod? https://github.com/Steamodded/examples/tree/master/Mods/DeckSkinTemplate
nope
so, J_ancient there too?
I have, it's just that I don't know how to do anything related to coding, so I messed it up. is there something pre-written I can use? thanks!
the type-chips jokers, ancient joker, and the order and the tribe all had the wrong keys
oh i missed order and tribe
you did a tyop somewhere
well now you have a syntax error in your code 🤪
here's the fixed code
all i had to do was fix the keys to refer to things that actually existed
not really if the example fails to help you at all. there used to be DeckSkinsLite but it's long discontinued so I can't recommend taking that path
if you're at all interested in learning something, I'd encourage you to just give it a try and ask if you get stuck. if not I can also just make it for you if you give me the assets
okay, thanks!
Thank you!
It works! Mys. Minty, you're got yourself a credit on the total mod!
this is what my "code" looks like. is there any major problems?
Also, if anyone wants, you can download it and play it yourself! The name still doesn't work, but the rest is still there
yes, you're using an outdated template
though it should still be supported if I'm not mistaken
Should I download the template you sent?
it's not strictly a template, just an example
ah so i need to write the code from scratch kind of?
you'd have to copy the code from the example for each suit you have a skin for and adapt the data to fit what you have
really, just changing the key and suit as well as the palette colours (or removing the palette colour, i guess) should be enough
👍
Should I take this and merge all the code here instead of that Go after the "Do not change" line?
I'm not sure that's a coherent sentence, but don't merge code from both examples if that's at all what you were trying to say
you'd want to create 3 more copies of everything after SMODS.DeckSkin { and change the key and suit for each as well as the loc_txt (for the display name)
you might also want to adjust the colors and customize the metadata in the json file
-# it'd totally better to have the example do all four suits
what words, I can try to explain better
what is metadata?
yeah I did, ty for asking
sure!
how about you?
yea pretty good
you mean duplicate it 3 times?
yeah, you want one instance of that code snippet for each suit
I'm going insane trying to make strenght effect depend on card suits
nope
you can get rid of the second palette
lets go
also snap the corresponding atlas definitions if you don't have the files
i have the image for the cards, is that good?
i meant if you don't have separate high contrast files
you'd want to get rid of the atlas definitions with hc in them
ah ok makes sense
Can someone help me with this? I'm trying to make 7 be strenghtened to a new rank only if it's of my modded suits
{
next = { '8', 'napoli_Fante' },
strength_effect = { fixed = 1 }
})
G.E_MANAGER:add_event(Event({
func = function()
local napoli_suits = {
napoli_coppe = true,
napoli_denari = true,
napoli_bastoni = true,
napoli_spade = true
}
local rank_7 = SMODS.Ranks["7"]
if not rank_7 then return true end
if G.playing_cards then
local applied = false
for _, card in ipairs(G.playing_cards) do
if card and card.base and card.base.suit then
local suit = card.base.suit
if napoli_suits[suit] then
rank_7.next = { "napoli_Fante", "8" }
rank_7.strength_effect = { fixed = 1 }
applied = true
break
end
end
end
end
return true
end
}))```
this code obviously does not work
ugh that's not something that plays nice with the current API
a possible solution I see is allowing strength_effect to be a function
i tried that but it crashes if i make it a function
ik, it's not currently supported
I'm just thinking about how to support it
there's not really a clean workaround
I'm trying to make a neapolitan deck of cards, so ranks 8, 9 and 10 are face cards "Fante", "horse" and "king"
and J,Q,K are not there
for now i was able to make the deck with the right cards and to make straights work, but then if i use strenght on a 7 of neapolitan suits it gives me an 8 (which has no sprite cause that card doesn't exist, instaed it's replaced by the fante)
this is what i've got for now, sprites are wip
Can I also delete the "icon lc", or is that important? (Sorry if I'm interrupting)
are you talking about suit icons?
you need them if you call them in the code
if you're making a deck skin it shouldnt be needed
otherwise the game sets a default one
since im pretty sure its just used for the suit icon in the deck view
which deck skins dont change
like paperback stars to make an example
sorry for delay, for now you can use this patch to allow strength_behavior (and prev_behavior) to be a function
[[patches]]
[patches.regex]
target = '=[SMODS _ "src/utils.lua"]'
pattern = '(?<indent>[\t ]*)(?<beh>local behavior =.*)\n[\t ]*if'
payload = """$beh
if type(behavior) == 'function' then
rank_key = behavior(rank_data, card)
elseif"""
position = 'at'
line_prepend = '$indent'
why does that not parse
do you have any lovely patches in your mod yet?
just put this file in there
I'll get the functionality added into smods, just can't do it right away because of other pending changes affected by it
so i just put it in the main folder right?
I'll make sure the patch won't cause issues when it does get added (if I remember)
yeah
if you don't want custom suit icons attached to your skin, you don't need that either
👍
just make sure to also get rid of the suit_icon = {...} lines
how do i split my mod into multiple lua files?
from your main file, load each additional file using assert(SMODS.load_file('folder/filename.lua'))()
Say, does anyone here know how to remove certain poker hands from scoring?
by taking ownership of them and changing their evaluate methods
tada! is this any good
like this?
assert(SMODS.load_file('src/atlas.lua'))()
assert(SMODS.load_file('src/jokers.lua'))()
sorry we are all asking for help all at once
local old_eval = SMODS.PokerHands['Full House'].evaluate
SMODS.PokerHand:take_ownership('Full House', {
evaluate = function(parts, hand)
if condition then return {} end -- invalidate hand under condition
return old_eval(parts, hand) -- otherwise defer to the original method
end,
})
thank you!
suit = 'any' won't do
like i said you need a copy of this for each suit
oh ok
yes
On an unrelated note: "Laundry Day" version a.1 to release later today
a.1?
alpha.1
I'm working on truly removing flushes, straights, and related hands from playing
[SMODS _ "src/game_object.lua"]:2029: bad argument #1 to 'ipairs' (table expected, got function)
Yeah, I'm not filewise calling it that
maybe this code is wrong for the patch idk
next = function(card)
local napoli_suits = {
napoli_coppe = true,
napoli_denari = true,
napoli_bastoni = true,
napoli_spade = true
}
if card.base and napoli_suits[card.base.suit] then
return 'napoli_Fante' -- safe even as a string, patch wraps it
else
return '8'
end
end,
strength_effect = { fixed = 1 }
})```
I didn't let you have next be a function
strength_effect is the one that can be a function
I think next is safe to just contain both ranks though?
yeah just change that back to a table
probably not the best way to start coding
fixed
that's all over the place, lemme fix it for ya
Thanks!
what's the varible to tell how many hands you have?
there were a lot of missing closing brackets, you didn't remove the suit_icon fields, the keys need to be unique and the suit names need to be capitalized. just to outline what I changed
also note the sprites in the asset file should be in the order of hearts, clubs, diamonds, spades from top to bottom
and 2->Ace from left to right
G.GAME.current_round.hands_left
omg thank you so much!
I'm trying to show the Description of "another" Joker, but I cannot figure out how to make the Variable work....```lua
local next_val = 2.0
info_queue[#info_queue + 1] = {
key = 'j_SEMBY_parking_disc_1', --..next_disc,
set = "Joker",
config = { extra = { ret = next_val } },
vars = { next_val },
specific_vars = { next_val }
}
it's not as hard as you're making it
info_queue[#info_queue+1] = G.P_CENTERS.j_SEMBY_parking_disc_1
if you do ever need to use this form, the correct version would be specific_vars = { vars = { next_val } } though
That doesn't work; It doesn't show another Description
This Crashes the Game, unless I also specify an empty config = { } and then it doesn't show anything
the mod is loaded but it doesn't change the deck
i'm going insame
unless you have a mod that adds a new "1" rank, there is no "1" rank. it's "Ace"
it doesn't change automatically, you need to select it in "customize deck"
select what there?
oh, it appears I'm lacking context as to what the joker you're trying to display is
@plucky berry
"Example" as you haven't changed the display name from that
it works!!!!!!!
amazing
I supposed you'll want to change the display name though, for that just change the loc_txt = "Example" lines to have the name instead of Example
i really appreciate you taking your time to help me. It really means a lot
I'm not tryna do that tho
what are you trying to do then
I'm tryna make 7 turn into either 8 or a new rank depending on suit
that one's on me for explaining poorly
I only have one j_SEMBY_parking_disc Joker
Simply said: The _1 gets added when a Condition is met, I just wanna show the next Stage
don't return 1 in the strength_effect function
it being self-referential does make things more tricky and you're probably right to not want it to loop back into itself in that case
SMODS.Consumable {
key = 'Fent',
loc_txt = {
name = "Fentanyl",
text = {
"Give one card the {C:attention}Fent{} seal"
},
},
set = 'Tarot',
atlas = "consumables",
pos = { x = 0, y = 0 },
config = { extra = { seal = 'Fentanyl'}, max_highlighted = 1 },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_SEALS[card.ability.extra.seal]
return { vars = { card.ability.max_highlighted } }
end,
use = function(self, card, area, copier)
local conv_card = G.hand.highlighted[1]
G.E_MANAGER:add_event(Event({
func = function()
play_sound('tarot1')
card:juice_up(0.3, 0.5)
return true
end
}))
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
conv_card:set_seal(card.ability.extra.seal, nil, true)
return true
end
}))
delay(0.5)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
G.hand:unhighlight_all()
return true
end
}))
end,
}
i dont understand why thid doesnt work i double checked all the keys but when i run it i still get this error
looks like a mod prefix issue
how would i destroy a random joker that is not the joker that's destroying another joker, and destroying itself if there are no other jokers?
where in this are you supposed to use a mod prefix?
in the seal key
set_seal has no context to know what mod it's being called from
so it needs the prefix
extra = 'toga_sealseal', as example of my Seal^2.
config = { extra = { seal = 'YA_Fentanyl'}, max_highlighted = 1 },
Updating my config to this (YA being my prefix) still gives the same error
Or spawn a fresh copy of the tarot.
or that, but on the same tarot the value won't update
where can i find all the base game sound effect keys for play_sound?
unzip your balatro executable using 7-zip or similar
and look in resources/sounds
Under resources/sounds, actually.
oops, too used to assets
so, can i have some help... im a noob, trying to add a custom "collab"/extra deck only appearance
Like these:
why is that even different in smods
if you read up a bit, you'll see I just helped someone do exactly that
I'll be off to sleep shortly, surely someone else can help if you need any further assistance
could someone send an example of this
because without examples this isn't very helpful
thank
bump
whats the difference between the line at the top, "atlas_lc" or "atlas_hc"
or is it just preference
lc is for low contract, hc is for high contrast
yea lol i was just looking at the wiki for atlases, thanks
found deck
I also don't understand why it's crashing...
Just to test around I'm pointing at another existing Joker;
info_queue[#info_queue+1] = { key = 'j_SEMBY_pear', set = 'Joker', specific_vars = { 1 } }
Comes up with this Crash (when I don't specify config = {})
Worked literally a Year ago apparently :D
rebump
¯_(ツ)_/¯
key = "coderdeck",
path = "coderdeck.png",
px = 71,
py = 95,
}
SMODS.DeckSkin {
key = "coderdeck_Hearts",
suit = "Hearts",
loc_txt = "Example",
palettes = {
{
key = 'coderdeck',
ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', "King", "Ace",},
display_ranks = {"King", "Queen", "Jack"},
atlas = atlas_lc.key,
pos_style = 'deck',
},
},
}
SMODS.DeckSkin {
key = "coderdeck_Diamonds",
suit = "Diamonds",
loc_txt = "Example",
palettes = {
{
key = 'coderdeck',
ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', "King", "Ace",},
display_ranks = {"King", "Queen", "Jack"},
atlas = atlas_lc.key,
pos_style = 'deck',
},
},
}
SMODS.DeckSkin {
key = "coderdeck_Clubs",
suit = "Clubs",
loc_txt = "Example",
palettes = {
{
key = 'coderdeck',
ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', "King", "Ace",},
display_ranks = {"King", "Queen", "Jack"},
atlas = atlas_lc.key,
pos_style = 'deck',
}
}
}
SMODS.DeckSkin {
key = "coderdeck_Spades",
suit = "Spades",
loc_txt = "Example",
palettes = {
{
key = 'coderdeck',
ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', "King", "Ace",},
display_ranks = {"King", "Queen", "Jack"},
atlas = atlas_lc.key,
pos_style = 'deck',
},
},
}```
It's only working for the hearts suit...
Well, I'm gonna give up.
I'll just have that Jokers Description in my Translation-Files twice.
One in Jokers and one in Others
im confused
How do i have a joker forcewin the blind? not the run, the blind
Hey folks! I've found a function I am interested in patching, but I am having some dificulty determining whether it's possible to do with smods and / or lovely.
It's update_canvas_juice under comment_events.lua. I'd like to be able to update the entire implementation of that method to reflect a setting I am adding, but I am really lost. Does anyone know if this is doable?
Its only caller is in the Game (not G) namespace, but I certainly can and will not be responsible for the game loop itself in this mod lol. TIA!
there's a snippet on this in the vanillaremade wiki
You should be able to just override/hook/lovely patch the function unless there's something I'm missing
I can, sorry, I should be more specific - I know you can patch per-line with lovely, but is there a nicer way to instead do the entire implementation of a function?
Based on how I understand it works, the answer is likely no. I can use regex to do the whole thing but I wanted to avoid that
I never made a pure lovely mod so I don't know exactly how but you can just load your own file and reimplement the entire function and it will rewrite the original or hook it to add functionality
SMODS handles the loading files part as well
Ah sweet, that sounds promising! Cheers 😄
any notes? first time shading something like this
background planning to do smth else but don't know quite yet
What does this mean
can someone help me with SMODS.DeckSkin?
some lovely patch is wrong
is this your mod or someone else's
How do I make a consumable like the Black Hole or the Soul? Having a hard chance of appearing in booster packs
the documentation is pretty cool https://github.com/Steamodded/smods/wiki/SMODS.Consumable
vanillaremade is too https://github.com/nh6574/VanillaRemade/blob/main/src/spectrals.lua
is this a good sprite
btw the back is just "4A4F4B4552" repeated a bunch, and if you interpret that as ascii bytes, it says "JOKER"
how would i make a card get an enchancement if it is the only card played on the first hand of a round (example: Ace of Spades, Ace of Diamonds would not do anything, but 6 of clubs would get enhanced, but only if it's the first hand of a round)
this is also inside of a joker btw
"do something if first hand of round has only one card": reference DNA in vanillaremade
"apply an enhancement to a card": card:set_ability("m_modprefix_enhancementkey")
(replace card with whatever object refers to the card in the played hand)
i told you i could run with 100 mods
:P
but of course the balatro purists have to be high and mighty </3
Oh shit, more sticker functionality added since last time I worked on modding? fantastic
now I gotta redo my apply functions though
oh and my probability stuff
😔
looks better overall though
hey, im just starting out modding, how would one go about making a joker similar to bloodstone but for spades? im stuck trying to find out how to check the suit of cards
any help would be appreciated, been looking thru the documentation but i cant seem to find anything there either
I highly recommend you check out the VanillaRemade project. You can see exactly how Bloodstone is made so you can adjust accordingly
where would i be able to find that?
thank you so so much
No prob! It's a resource I wish I had when I started out lol
so i have a statement here that checks if a sold card is a specific edition (the edition changes; the edition_ returns the key of an edition)
whenever i satisfy the other stuff, its all good but it never gets through that step
is there a way to open a custom collection-like page with some specific cards other than manually making the ui for it
SMODS.card_collection_UIBox?
if context.card.edition and context.card.edition.key == edition_
lifesaver, thank you
i'm trying to access another mod's atlas in a center,
key = {
mod = false
}
},
atlas = 'paperback_decks_atlas',```
but it just crashes
Log?
works! found out i also forgot an else statement for when the card isn't enhanced lol
thanks
Okay so you need to add atlas = false to the prefix_config table
what does card_eval_status_text do
eval a card status, similar to return {message = something} but more customizable i think
both do the same thing afaik, you can at least pass most arguments that the function takes to message too
Anyone know how to make the joker like.. tell you something? like the text prompt when you finish a round/start one
?
return message = "whatever you want it to say"
thxx
if context.setting_blind then
card.ability.extra.Xmult = card.ability.extra.Xmult + 0.2,
return message = '*grows*'
end
``` not working...
return {message = '*grows*'}
Thanks omg that worked, and its so funny XD
Which design do you all like best? Working on my first mod and i want something pretty to look at to convince me to actually finish the project
How do I check if the player is in a specific boss blind?
if G.GAME.blind.config.blind.key == 'bl_modprefix_key'
If you're checking for a vanilla blind, don't include a modprefix!! ^^
hey y'all, how would i get the description of a joker that uses a multibox description (preferably as a list of lists or a list of lists of lists)? i've used the code below before but it breaks down if a joker uses multibox
localize{type = "raw_descriptions", set = "Joker", key = G.jokers.cards[my_pos + 1].config.center_key, vars = {0,0,0,0,0,0,0,0,0,0,0,0,0} }
G.localization.descriptions.Joker[key].text
excellent, ty!
Why might #G.deck.cards == 0result in a nil compare with number?
It wouldn't.
Using == doesn't crash when you compare different types of values.
What does SMODS.inject_p_card do?
It adds a rank and suit combination to G.P_CARDS
does anyone here know what specifically the negative shader does so i can try and remake it in blender?
how does debugplus do savestates internally/where is the code for handling savestates in debugplus?
nevermind, found it!
i think you need to add your mod prefix onto args.type == '<insert prefix here>_badheadache'
wait no nvm
worth a shot but prolly something else
i tried that before yeah
so I am trying to patch the game for the first time and for some reason I get a crash with a message I don't understand
[manifest]
version = "1.0.0"
dump_lua = true
priority = -10
[[patches]] #G.GAME
pattern = '''
target = 'game.lua'
match_indent = true
position = 'after'
payload = '''
allow_legendary = {in_shop = false, rate = 1.00},
'''
what's the crash
ok i think its because of the savestate thing
im gonna try and
uh
make it last a few more frames
allow_legendary = {in_shop = false, rate = 1.00},
| ^
expected newline, `#`
sorry for the late response used to hearing that discord ping noise
[[patches]]
[patches.pattern]
...
not the problem apparantly
it might just be check for unlock function
but then what do I do with the the #G.GAME
Is that meant to be the pattern?
I don't know I was playing the all in jest mod https://discord.com/channels/1116389027176787968/1357543332602970212
then I saw that there is a joker that adds legendary to the shops which I couldn't implement(skill issue)
so I looked at the toml files and "borrowed" the code and I have no idea what I am doing lol
in conclusion I can't understand patches too much for me
what do you prefer?
it turns out I didn't close patterns with another '''
hey guys, how do i get the first letter of a joker name? (for more details i want a deck that looks at the first letter of a jokers name)
localize({type = 'name_text', set = "Joker", key = 'j_modprefix_key'}):sub(1, 1)
why 1,1 if you dont mind me asking?
ohh i see
I presume those are custom suits?
the only two decks the sleeves to be changed i think is checkered and hawaiian since that's the point of checkered and hawaiian already adds a full set to the initial deck
maybe do something similar to abandoned deck/sleeve where it converts another suit into leaves and roses
i could also do something like the starting cards for checkered and/or hawaiian with the sleeve are wild cards
starting with a lot of wild cards is kinda busted no matter how you spin it
yeah that is true
ideas:
checkered deck with hawaiian sleeve: starter leaf and rose cards are turn into spades or hearts
hawaiian deck with hawaiian sleeve: starter spade/heart cards are turn into leaves, and starter diamond/club cards are turn into roses
you don't technically have to make any modifications for checkered deck
i mean yeah
but yeah you could make checkered deck turn the extra cards into more hearts and spades
its more that checkered decks entire gimmick is you start with only spades and hearts
making it easier to build flush or spade/hearts builds
hawaiian deck + hawaiian sleeve maybe just gives you more hand size?
tbh I recommend making it easier to sift through the base deck anyway since you're adding so many new cards
do the new suits come with new hand types?
thats something im not sure
since the other mods and an entire api does that with spectrum hands so idk
well either you assume the use of the API or another mod or you add it yourself or you ignore it
ill think about it
guh, help
SMODS.Joker {
key = "kittybrained",
loc_txt = {
name = "KittyBrained",
text = {
"Makes adjacent Jokers",
"Become {C:attention}feline{} Jokers",
}
},
rarity = 1,
--atlas = 'genderbending.png',
--pos = { x = 0, y = 0 }
cost = 4,
update = function(self, card, dt)
if G.jokers then
local adjacent_jokers = get_adjacent_jokers(center) --logic for adjacent jokers stolen from pokermon xwx
for i = 1, #adjacent_jokers do
CardSpecies.transform(adjacent_jokers[i], "cat")
CardSpecies.transform(card, "cat")
end
end
end
}
heres the related functions:
function CardSpecies.transform(card, specie)
-- morphs cards
card.species = specie --crashes if i do card.center.species????
return
end
get_adjacent_jokers = function(card) --stole from pokermon xwx
local jokers = {}
if #G.jokers.cards > 1 then
local pos = 0
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
pos = i
break
end
end
if pos > 1 and G.jokers.cards[pos-1] then
table.insert(jokers, G.jokers.cards[pos-1])
end
if pos < #G.jokers.cards and G.jokers.cards[pos+1] then
table.insert(jokers, G.jokers.cards[pos+1])
end
end
return jokers
end
its currently not transforming them qwp
i may be stewpid,,,,,,
what is changing card.species supposed to do
hi nh
hello
just cosmetic change
mod progress is going well
changing a badge basically
made two suits with art from @rotund ridge and made an edition that adds a hand size with help from @timid zinc
is the badge not changing or is the value not getting set
all is left for the deck that properly adds the suits is the art which i might do later since i have work in about two hours
badge not changing
It's card.config.center not card.center
so card.species is changed but the badge is still the same? then that's a problem with the badge code
OH, thanks
i dont recommend changing a center at runtime however
i actually cant friggin check if the values change cuz idk how to print values to console on lua (im not accustumed to lua im a js dev blehhhhhh)
n i need help
you have debugplus right?
yes
you can just run print(put whatever you want to print here, including variables)
with debugplus you can hover it and run eval dp.hovered.species in the console
that too
idk anything about achievements
i tried, but it didnt work
so i may be stewpid
send code
WAIT, ITS HALF WORKING NOW
although its not changing actually adjacent jokers hmmmm, okay i mightve botched the logic i had copied while trying to test it over and over, let me re-make the pokermon logic fully and test again, if it works then we'll be poggers
i thought it was supposed to return true and then thats it but its still fucked i cba
question. how many ghosts have you angered
because i dont think theres any other explanation for this
like none
ask ghostsalt
why is it fucked up ts pmo
🥀
buy a oujia board and make a deal with the ghosts to stop haunting your code
@wind steppe can you check if its normal on your side
press y anywhere
do u have a localized name defined
im 99% sure that isnt the problem but ill try anyways
great readme btw
i did in fact read it
there is a slight hotpot related issue preventing me from doing so
(i dont think its your fault considering i updated it since the last time i booted it up)
wait like half an hour
i cant because it crashes on load
how to make the add_to_deck function auto update for example:
mult = 2
add_to_deck mult = mult*2
mult = 4
remove_from_deck mult = mult/2
now mult = 2 when it was supposed to be mult = 4
look at vanillaremade turtle bean, it tracks how much hand size its still giving to remove the correct amount
ok thx
i got the achievement in clean save state. am i misisng something
wtf
actually
ok am i just fucked
am i supposed to press y at a specific time or wut
yeah it works
wtf
with a clean save
this is so rigged
why am i just fucked
hm
oh yeah thats the problem
whatever im gonna do something else anyways
question: how can I set for the showman effect to make only common jokers and tarots reappear in the shop multiple times?
if G.P_CENTERS[card_key].rarity == 1 or G.P_CENTERS[card_key].set == "Tarot"
Also you're missing your mod prefix.
oh yeah I forgot about that
okay fixed it, just out of curiosity how does the showman effect work in default?
like, when you normally have some jokers in the joker slots, the game has a pool of all the jokers in the collection and doesn't instance the same ones you have as long as you don't have showman (or use other ways), right?
i THINK when its generating valid targets to pull from it excludes already owned ones from the set
aight