#💻・modding-dev

1 messages · Page 83 of 1

restive badger
#

No...

edgy reef
#

This is definitely outdated Balatro, this is crashing at deck skin API which iirc wasn't added until 1.0.1g

restive badger
#

1.0.1m seems to be avalible?

edgy reef
#

Not the API, but the vanilla functionality for it

tepid crow
#

if you're getting into modding balatro, I'm assuming you already spent quite some time playing the game, you should probably go buy it

restive badger
#

I bought it on other platforms, I only pirated on pc because I wanted to mod it...

tepid crow
#

yeah it absolutely sucks that you have to pay for it on every platform

restive badger
#

I apriciate the game a ton especially because im obsessed with cards and I've played it on my switch, Ive been meaning to get it on my phone too I dont usually pirate that the reason why I did

mighty stump
#

I wouldn't disclose that on here

restive badger
#

do you think 1.0.1m with the same steps would work here?

#

what letter would work best there seems to be alot..?

tepid crow
#

Sorry man, doesn't feel right to openly discuss this any further in this server
You should be able to figure out how to proceed from here though, there should be enough breadcrumbs in this chat for you

restive badger
#

I understand, I believed you've helped alot, thank you for everything so far(:

tidal ice
#

if you wanna support the game further when youre low on cash, perhaps wait for a sale, thats when I got it on both switch and steam (which i currently cant play lol i dont have a pc rn)

#

I only thought about getting it on Switch as I didn't know this game had a modding scene

#

same with Inscryption I think

half aspen
#

Hi! New modder here; How could I get a joker to run code for each card discarded? I got this code working for each card played; just unsure how to get it working for discards instead. Here is the code I am using (I am using steammodded)
calculate = function(self, card, context) if context.individual and context.cardarea == G.play then -- run code end end

tepid crow
half aspen
#

Got it working by using context.discard if anyone is wondering in the future

cerulean rose
#

the reason this wasn't working was because i didn't return true at the end of my event call… 😤

hardy viper
#

widegladeline2 don't disable ping next time but thanks

edgy reef
#

ping disable is instinct

fair mortar
#

hope this can save someone some time: got an undisable slash enable boss function working

primal robin
#

Why Steamodded-1103a process .vscode folder?

maiden phoenix
#

Is it not possible to just create a SMODS.Shader alone without an edition for it to be used in Card:draw_shader? Either there's an issue with it or I got the path wrong, can't find a mod to cross-reference (Cryptid does it in an unusual way)

#

nvm I forgot the prepend key again..

teal estuary
#

having some issues with the code - it works all fine, shows the message at the end of the played hand, etc - but it doesnt add the chips to the actual score? i have no idea why, i presume im missing something trivial but no clue 😭

crisp coral
#

Try mod_chips instead of chips

teal estuary
#

for all the .extra.chips or?

crisp coral
#

context.joker_main's return

teal estuary
#

ah, gotcha

glossy stone
#

BOO SURPRISE I'M BACK TO MAKING JOKER ART FOR ORIGINAL SOUND

#

I know it's not much but at least i'm back

teal estuary
crisp coral
#

Oh wait, I'm so stupid

#

It's chip_mod, not mod_chips

teal estuary
glossy stone
teal estuary
#

i wanna be absolutely sure, do you mean the chips = card.blah.blah.blah to turn into chip_mod? just so i dont have to test it mulitple times

glossy stone
#

7 card arts left...

crisp coral
#

chip_mod = card.ability.extra.chips,

teal estuary
#

cool, jsut making sure

#

ty mwah

#

it works!

#

ty

#

is that the same for mult and the like? mult_mod? raisedcateyebrow

crisp coral
#

Yup!

#

And Xmult_mod

teal estuary
#

thank you kindly

#

oooh

#

my 2 jokers should now work!! yipee!!

humble gale
#

Am i not able to make my own values in the config? i get an error when i do math with the steel value

config = {extra = {mult = 20,chips = 50,mult_gain = 5, chip_gain = 25,Xmult=2.5,secAbility = false, steel = 0}},

--math below
card.ability.extra.steel = card.ability.extra.steel + 1
wintry solar
#

where's your calculation code going?

humble gale
#

its in a calcuate function and is used when a steel card is scored in a straight flush

  if context.individual and context.cardarea == G.play and not context.other_card.debuff and not context.end_of_round and --Activates secert ability
            context.other_card.ability.name == 'Steel Card' and next(context.poker_hands['Straight Flush']) and not context.blueprint and not card.ability.extra.secAbility then
            card.ability.extra.steel = card.ability.extra.steel + 1
            if card.ability.extra.steel >= 5 then
                card.ability.extra.secAbility = true;
                return {
                    message="Secert Ability Active!"
                }
            end
        end
#

i have it in the loc_vars section too

crisp coral
#

not context.end_of_round and Activates secert ability?

humble gale
#

i dont want it to fire if this already happened

crisp coral
#

I mean, is the Activates secert ability supposed to be in a comment?

humble gale
#

yeah lol

wintry solar
#

yeah it wraps on the next line

#

the function is function(self, card, context) right?

humble gale
#

yes

wintry solar
#

how are you testing?

humble gale
#

i was using debug plus and i played a straight flush of all steel and got the error

wintry solar
#

try spawning the card in fresh

humble gale
#

Im not getting an error but the code isnt working either

wintry solar
#

can you send the entire function?

humble gale
#
calculate = function (self,card,context)   
        if context.individual and context.cardarea == G.play and not context.other_card.debuff and not context.end_of_round and --Activates secert ability
            context.other_card.ability.name == 'Steel Card' and next(context.poker_hands['Straight Flush']) and not context.blueprint and 
            not card.ability.extra.secAbility then
            card.ability.extra.steel = card.ability.extra.steel + 1
            if card.ability.extra.steel >= 5 then
                card.ability.extra.secAbility = true;
                return {
                    message="Secert Ability Active!"
                }
            end
            return {
                message = "Steel!"
            }
        end

        if context.individual and context.cardarea == G.play and not context.other_card.debuff and not context.end_of_round and
            context.other_card.ability.name == 'Steel Card' and card.ability.extra.secAbility then
            return {
                message = localize { type = 'variable', key = 'a_xmult', vars = { card.ability.extra.Xmult } },
                Xmult_mod = card.ability.extra.Xmult
            }
        end

        if context.joker_main then
            return {
                message="Fence!",
                mult_mod = card.ability.extra.mult,
                chip_mod = card.ability.extra.chips
            }
        end

        if context.before and next(context.poker_hands['Straight Flush']) and not context.blueprint then
            card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain 
            card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_gain 

            return {
                message = "Charge!",
                card = card            
            }
        end
    end

wintry solar
#

try lua return { extra = { message = 'Secret Ability Active!' } }

#

there's nothing that just handles a plain message return in this context from what I can see on my phone

#

wait no

#

ignore that

#

can you throw some print commands in there and see where it's getting to?

humble gale
#

yea

#

its running all of it just not returning the message

#

i placed a print before the if and before the return and both printed something

wintry solar
#

huh

#

worth taking a look at the lovely dump of state_events to see where its returning to

humble gale
#

where excatly is that?

wintry solar
#

mods/lovely/dumps/functions

#

then search for individual = true and it'll be one of the eval_card calls it brings up

humble gale
#

it found it in 3 different spots which one is it

wintry solar
#

whichever one is evaluating G.play

humble gale
#

this it?

local eval = G.jokers.cards[k]:calculate_joker({cardarea = G.play, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, other_card = scoring_hand[i], individual = true, callback = function(card, eval, retrigger)
wintry solar
#

yeah

humble gale
#

what do i do with it then?

wintry solar
#

look in the bits below to see how the eval table is used

humble gale
#

I dont see anything that would explain why it isnt sending a message

#

probaly because i dont know what im looking at lol

wintry solar
#

let me grab my dev machine, hold on

humble gale
#

ight

wintry solar
#

try the extra thing I sent earlier

humble gale
wintry solar
#

alternatively if that doesnt work, you can use card_eval_status_text

humble gale
#

i got the message to return

#

thx

tepid crow
wintry solar
#

What mod interface is this using?

tepid crow
#

I'm assuming this isnt aure or anyone else here?

#

seems to be loaded using ony lovely as far as I can tell

cerulean rose
#

i'm working on my mod, but the code is quite tough to manage with it being all in the same file
could i get some help with this?

tepid crow
#

you can use SMODS.load_file("path/to/file.lua")() to load other lua files

hardy viper
tepid crow
#

haven't we been over this before? 🤔

hardy viper
#

dotn remember

tepid crow
#

oh maybe it was someone else then

hardy viper
#

ya

#

all it seems to do is name the chunk after the mod calling it and use the mods directory as the working directory instead of the typical one

tepid crow
#

idk any more than you do 🤷

hardy viper
#

itd probably be better for error tracing i guess?

#

only slightly

tepid crow
#

yeah I think it's better at showing the mod that caused an error?

#

instead of being a path that's cutoff

edgy reef
#

If you wanted to use loadfile you might as just well use love.filesystem.load anyways

hardy viper
#

+one of them is shorter to type so egg

#

most stuff seems to use SMODS.load_file

tepid crow
#

I get paid by the character I code though, so egg

hardy viper
wintry solar
#

SMODS.load_file does all the path work for you and has better crash info 🤷‍♂️

cerulean rose
#

👋 actually, is there anything that needs to be done for lovely patches?

hardy viper
#

virgin if statement vs chad logical operation ...

tepid crow
#

won't somebody think of the readability 😩

hardy viper
#

to be fair its readable in this instance

#

youre right that readability does usually become an issue though

edgy reef
hardy viper
#

lol fair

teal estuary
#

sorry to butt in, but having an issue with math.min - after adding it in, it now just wont add anything? no matter what i play, it just stays at 0 balatrojoker

(im gonna presume im just missing something trivial, but no clue)

cerulean rose
tepid crow
#

either named lovely.toml or in a subfolder named lovely yeah

#

(should say that somewhere on the lovely github)

wintry solar
teal estuary
#

mhm! it works fine without the math.min, i just want to impose a limit on how much it can gain

rough furnace
lusty epoch
#

It’s not gonna increase at 0 :p

hardy viper
#

0+0=0

#

is this true

teal estuary
#

i might be stupid clueless

vague island
#

do yall have golden ticket's code? I need to build off of it for a joker im working on.

rough furnace
#

you can extract the games code from the exe using 7zip then open card.lua and search for golden ticket

languid mirage
harsh adder
#

quick question, do you guys know how I could add an audio clip to play when a specific joker triggers?

#

specifically for popcorn & baseball card (referencing a joke amongst friends)

languid mirage
harsh adder
#

also, how do i change the images for the base jokers? i tried to use like the collage thing within the games files but that didnt change anything

hardy viper
humble gale
#

does anyone know of a good way to change joker descriptions in the middle of a game? ive been putting a descrption in the extra array but no formatting works

tepid crow
#

like changing the entire description?

humble gale
#

just a part of it

tepid crow
#

could you give an example?

humble gale
#

i have a specail ability that activates on a joker when a condition is met and i want to change the hint on the description to the effect of the ability

mighty stump
#

I dont want to intrude so please do finish helping out shado first, I am interested in learning how to mod this game. I have some familiarity with Java and that is about it. Where do you all recommend me starting to look in terms of modding the game?

humble gale
#

it gives a good explanation on some of the basic stuff

mighty stump
#

Thx, gl with coding

tepid crow
# humble gale

Ah, I see the issue yeah. You're trying to put a variable within a variable right?

humble gale
#

yes pretty much

tepid crow
#

yeah I doubt that'll work

humble gale
#

dam

tepid crow
#

you should be able to manually insert it yourself though

humble gale
#

am i able to just refernce loc_txt.text and append it?

#

vscode give a blue underline and yells at me when i did that

#

so i didnt try it

tepid crow
#

technically you could but you'd have to re-parse

#

I meant why don't you do something like this

loc_vars = function(...)
    local ability_text = normal .. "/" .. odds .. " chance to add a random edition to a played card"
    return { vars = { maxretrig, normal, ..., ability_text } }
end
mighty stump
#

How dumb would it be for me to attempt to piece together what is given in example mods and attempt to make a mod myself without knowing lua?

#

Cause I have done something similar with origins mod in minecraft but this seems like a whole other can of worms

tepid crow
tepid crow
mighty stump
#

I have a few years expirence in Java through college courses but I still am not the best at it

tepid crow
#

Probably good enough to start. At least you won't be wondering what a for loop is, only how to format it 🙃

mighty stump
#

Only problem is the syntax looks so foreign to me lol

#

Is there a compiler that is recommended to use or does that not really apply for modding games?

brisk rose
mighty stump
#

Welp time to start learning ig lol

#

Anyone have any recommendations on what I should try to make first? Like baby's first mod?

tepid crow
#

probably a joker or deck or smth

mighty stump
#

Maybe I'll try to make an all 2s deck

#

Power of wee lol

tepid crow
#

that sounds like a good idea

mighty stump
#

Oki

#

Would anyone mind hopping in a vc with me in a lil to guide me while I start, kinda like training wheels, if not it's totally fine

tepid crow
#

I suggest you just check out the steamodded documentation and examples

#

and possibly also other mods on github, and how they do stuff

mighty stump
#

Oki thank you all

#

Oh hey there is already a deck of 4s in example mods lol

#

I am seeing the word Atlas alot what does that meanm

#

Also sorry in advance for the biblical flooding of questions that is about to commence

#

Oh wait nvm

#

I see now

#
SMODS.Back{
    name = "Deck of fours",
    key = "fours",
    pos = {x = 1, y = 3},
    config = {only_one_rank = '4'},
    loc_txt = {
        name ="Deck of fours",
        text={
            "Start with a Deck",
            "full of {C:attention}Fours{}",
        },
    },
#

what fuction does the pos variable have?

humble gale
#

pos is the location in the picture

#

so the image for the deck is the first pic on the third row

mighty stump
#

ooooh for when I implament a texture file?

humble gale
#

yeah

mighty stump
#

is it required to have a texture out of curiosity?

humble gale
#
SMODS.Atlas {
    -- Key for code to find it with
    key = "ModdedVanilla",
    -- The name of the file, for the code to pull the atlas from
    path = "ModdedVanilla.png",
    -- Width of each sprite in 1x size
    px = 71,
    -- Height of each sprite in 1x size
    py = 95
}
humble gale
mighty stump
#

i am

#

I am just wondering if it is needed is all

humble gale
#

i wouldnt think it is if you never tell it to have a picture

#

never tried it

mighty stump
#

also ignore what i said about atlas i didnt realize that it was just referring to a modded joker example

#

rn I am looking to understand how to make a deck

#

I am gonna make a wee little deck

#

basically you have only 2s, and if I can learn how to do it, start with a wee joker

#

so for when I do make an image for the deck what coordinates would be the first image?

humble gale
#

0,0

#

like on a graph

mighty stump
#

okay thanks

#

for a second I thought that was a reaction not coords lol

#

so I assume the only_one_rank config is used to set all card ranks to a specified number?

humble gale
#

yes

mighty stump
#
apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
#

what does this do?

humble gale
#

i dont really know, havent made a deck yet

mighty stump
#

fair

humble gale
#

is there any comments with it?

mighty stump
#

nope

humble gale
#

i love undocumented code

mighty stump
#

its so great (sarcastic)

#

I wonder how hard it is to make a suit that is classfied as wee lol

#

i might add it once I get this all figured out somewhat

mighty stump
#

wait nvm I figured it out

#

kinda-ish

brisk rose
mighty stump
#

bascially make a custom suit that is just called wee

#

Bascially I wanna make a dumb little stupid mod that revolves around the wee joker and similar concepts

brisk rose
#

Oh that's interesting

#

Yeah that should be fairly simple

mighty stump
#

only problem is I dont know lua
I know a decent amount of java so I am just trying to apply some of that gen coding logic to this

brisk rose
#

I mean I'm working on a mod wget suits she I hadn't done coding since basically two introductory programming classes, one python one c++ over 5 years ago

mighty stump
#

gl with that btw, I believe in ya

brisk rose
#

Thank you :3

mighty stump
#

I made the icon for my wee little mod

#

ok so what all do i need to put in my wee mod folder for it to work?

#

cause I have no idea what it needs for me to start testing stuff

#

cause I like to test stuff as I am coding not just code the whole thing then test it

maiden phoenix
#

This is how you set up one

SMODS.Atlas{
    key = "modicon",
    path = "path_to_modicon.png",
    px = 34,
    py = 34,
}
mighty stump
#
SMODS.Back {
    name = "A Wee Little Deck",
    key = "twos",
    -- pos = {x = 0, y = 0},
    config = {only_one_rank = '2'},
    loc_txt = { 
        name = "A Wee Little Deck",
        text = {
            "Start With a Deck",
            "full of {C:attention}Twos{}"
        },
    },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
}    
#

here is what I have so far

#

where would I put that code?

maiden phoenix
#

Anywhere like any SMODS object (preferably in your main lua file)

mighty stump
#

okay

#

is adding the atlas object necessary or is that just part of the example provided

maiden phoenix
#

For the mod icon yes

mighty stump
#

okay

maiden phoenix
#

If you try to refer to a spritesheet you usually use SMODS.Atlas

mighty stump
#

I only have one image as of rn, it isnt really a sprite sheet

maiden phoenix
#

Doesn't matter

mighty stump
#

okay good to know

#

would i but that on top of the back object in my main lua file?

maiden phoenix
#

Above or below, if it's for your modicon it doesn't matter

#

If you try to load your back atlas tho it will be above all other SMODS.Back objects

mighty stump
#

also sorry if ya have to repeat yourself or answer dumb questions. this is my first time with Lua

maiden phoenix
#

with Lua or with coding in general?

mighty stump
#

lua

#

I know a decent amount of basic java but that is about it

maiden phoenix
#

The size of your image in the spritesheet

mighty stump
#

oki

#

thx

#
SMODS.Atlas{
    key = "modicon",
    path = "path_to_modicon.png",
    px = 256,
    py = 256,
}
SMODS.Back {
    name = "A Wee Little Deck",
    key = "twos",
    -- pos = {x = 0, y = 0},
    config = {only_one_rank = '2'},
    loc_txt = { 
        name = "A Wee Little Deck",
        text = {
            "Start With a Deck",
            "full of {C:attention}Twos{}"
        },
    },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
}    
#

is anything else needed for my deck for it to run?

#

the example mod for the deck doesnt give much to go off of

maiden phoenix
#

The path of your SMODS.Atlas is wrong, it doesn't have to literally be this

mighty stump
#

oh okay

mighty stump
#

thank you

maiden phoenix
#

It has a SMODS.Atlas reference in it

brisk rose
mighty stump
#

okay

#

ill just scale down the image cause legit it just is weee in mspaint lol

brisk rose
#

For references 34x34 is the default

mighty stump
#

got it

maiden phoenix
#

Some atlases uses different dimensions

brisk rose
#

Yes for modicon

#

Thought that was implied

maiden phoenix
#

They pasted the atlas path as it was written as so I'm taking precaution lol

mighty stump
#

oh wait

#

I am dumb I just realized my mistake in doing that haha

#

I blame the hours of hw I had to do today

#

college is killer

#

-- Width of each sprite in 1x size
px = 71,
-- Height of each sprite in 1x size
py = 95

so is this the default size?

maiden phoenix
#

Yes, for jokers/decks/consumables etc

mighty stump
#

okay thank you

cerulean rose
#

i'm trying to check if the selected joker has a sticker, and the code i've tried doesn't seem to work

for k, v in ipairs(SMODS.Stickers) do
    if G.jokers.highlighted[1].ability[v.key] then
        return true
    end
end
mighty stump
maiden phoenix
#

For modicon only, the key needs to be "modicon"

mighty stump
#

so i dont need to do that because i am using atlas right?

maiden phoenix
#

Don't need to do what?

brisk rose
brisk rose
mighty stump
#
    key = "",
    path = "wee_icon.png",
    px = 71,
    py = 95,
}
SMODS.Back {
    name = "A Wee Little Deck",
    key = "twos",
    -- pos = {x = 0, y = 0},
    config = {only_one_rank = '2'},
    loc_txt = { 
        name = "A Wee Little Deck",
        text = {
            "Start With a Deck",
            "full of {C:attention}Twos{}"
        },
    },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
}    

I am confused, here is what i have so far

maiden phoenix
#

you need to create an assets folder, then put 1x and 2x in it, then put your image in each folder

brisk rose
#

Basically the atlas png name is whatever you want it to be. Add is the key I just mozpoke

maiden phoenix
#

1x is the normal size and 2x is double the size of your image

brisk rose
#

Replied to the wrong message

brisk rose
brisk rose
maiden phoenix
#

Yea not sure why you made your atlas key empty

maiden phoenix
mighty stump
#

oof

#

that is early/late

brisk rose
maiden phoenix
brisk rose
maiden phoenix
#

Wow that example is from last month

brisk rose
#

You said it again more recently I think

#

I'm... autistic so weirdly observant

maiden phoenix
#

Right the correct term is translation

brisk rose
#

nods

maiden phoenix
#

Idk my brain thinks "traduction" sounds english enough 🤷

#

They sound very alike too, i'll try to avoid doing the mistake again

brisk rose
#

It's not a big deal. And yeah when you spell it like that it does seem very English

mighty stump
#

i got the 1x and 2x in my asset folder

#

what else is needed for me to start testing?

maiden phoenix
#

it's called "asset" or "assets"? Needs to be the latter

mighty stump
#

assets

maiden phoenix
#

Good

maiden phoenix
mighty stump
#

I dont know what to put there

maiden phoenix
#

modicon

mighty stump
#

okay thanks

#

anything else?

maiden phoenix
#

What did you call your art file in both 1x and 2x?

mighty stump
#

wee_icon

#

both are png

brisk rose
#

Then it should work

#

Wait, why is the medicine the shape of a card?

maiden phoenix
brisk rose
mighty stump
#

wdym

brisk rose
#

Oh this is for the back

#

Nvm

maiden phoenix
#

Ah nvm then

brisk rose
#

Icon made me think modicon

mighty stump
#

is this correct in terms of folders?

maiden phoenix
#

Looks good so far

#

Launch the game and see in "Mods" if your mod icon applied

mighty stump
#

oki

#

it isnt there

brisk rose
#

So I'm confused. You have it set up as the back sprite., but you're talking about modicons

maiden phoenix
#

Aren't they trying to make an icon for their mod?

mighty stump
#

I dunno, I am just copy pasting what is on the template

maiden phoenix
#

Are you trying to make art for your deck or for your mod icon?

brisk rose
mighty stump
#

I am trying to make a deck

brisk rose
#

But are you trying to set up the image for the deck itself or for the mod icon?

mighty stump
#

I think so?

brisk rose
mighty stump
#

oh woops

#

i forgot to undo that

maiden phoenix
#

This is the deck art

#

And this is mod icon art (on the left)

mighty stump
#

ye

#

oooooh

maiden phoenix
#

Which are you trying to modify?

mighty stump
#

oki

#

dont i need both for making a custom deck?

maiden phoenix
#

modicon is optional

mighty stump
#

oh then ill do that later

brisk rose
#

Then yeah just Jake sure your 1x image is actually 71x95 and uncomment the pos

mighty stump
#

it is

#

is that all that is left?

maiden phoenix
#

Also your SMODS.Back object needs to have an atlas = 'your_atlas_key'

#

(replace your_atlas_key by the key you've put in your atlas)

mighty stump
#

so as my code stands rn is the image I have in assets being used for the deck art or mod icon?

#
SMODS.Atlas{
    key = "modicon",
    path = "wee_icon.png",
    px = 71,
    py = 95,
}
SMODS.Back {
    name = "A Wee Little Deck",
    key = "twos",
    atlas = ''
    pos = {x = 0, y = 0},
    config = {only_one_rank = '2'},
    loc_txt = { 
        name = "A Wee Little Deck",
        text = {
            "Start With a Deck",
            "full of {C:attention}Twos{}"
        },
    },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
}
brisk rose
#

Waot

#

Neither

#

Well it is used as the modicon

#

But it's the wrong shape

#

It should be square for that

mighty stump
#

what dimentions do i need for deck art

brisk rose
#

They did?

mighty stump
#

I am gonna ignore it for now since I want to get to testing my deck first

#

then i will add the mod icon since yall said it is optional

brisk rose
#

Or dors the png need to be named just modicon too?

#

But yeah good idea

mighty stump
#

functionality over flavor

maiden phoenix
#

Holy shit troubleshooting at 2am is such a bad idea

mighty stump
#

until it works that is

brisk rose
#

So to make it not the medicine just give it a different key

maiden phoenix
#

If you keep the key as "modicon" it will be for the mod icon, you need to rename it

brisk rose
#

And include the key on the deck object

maiden phoenix
#

Lmao medicine strikes once more

mighty stump
#

what is the naming convention

brisk rose
#

Just no spaces

mighty stump
#

oki

#

ill just do d_art cause it is deck art

#
SMODS.Atlas{
    key = "d_art",
    path = "wee_icon.png",
    px = 71,
    py = 95,
}
SMODS.Back {
    name = "A Wee Little Deck",
    key = "twos",
    atlas = 'd_art'
    pos = {x = 0, y = 0},
    config = {only_one_rank = '2'},
    loc_txt = { 
        name = "A Wee Little Deck",
        text = {
            "Start With a Deck",
            "full of {C:attention}Twos{}"
        },
    },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
}    
#

thius good?

maiden phoenix
#

should be

mighty stump
#

ill try it rn

maiden phoenix
#

I forgot if SMODS.Atlas preprend the mod prefix

brisk rose
#

Yes but you should probably do wee_deck or smth. Just so it's clear what it is

maiden phoenix
#

Try with this for now

#

Btw did you rename the files in your assets as d_art too?

mighty stump
#

oki

brisk rose
maiden phoenix
#

Right they need to match the path

brisk rose
maiden phoenix
#

3 mistakes in a row I think it's time for me to sleep

#

Gl with your deck

mighty stump
#

yes, and thank you for the help

#

have a good night

mighty stump
#

so is the key in atlas just for sprite work or is it used for more stuff?

brisk rose
mighty stump
#

okay

#
SMODS.Atlas{
    key = "wee_deck_art",
    path = "wee_icon.png",
    px = 71,
    py = 95,
}
SMODS.Back {
    name = "A Wee Little Deck",
    key = "twos",
    atlas = 'wee_deck_art'
    pos = {x = 0, y = 0},
    config = {only_one_rank = '2'},
    loc_txt = { 
        name = "A Wee Little Deck",
        text = {
            "Start With a Deck",
            "full of {C:attention}Twos{}"
        },
    },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
}    
#

this good?

#

or do i need to change size proportions for my image?

#

darn

#

my mod still isnt showing up in mod list

#

what else do I need?

#

oh wait

#

I accidentally saved the code file as a text doc not a lua file

#

let me fix that

#

damn didnt work

brisk rose
#

Does your mod have a header?

mighty stump
#

wdym

#
--- STEAMODDED HEADER
--- MOD_NAME: Edition Examples
--- MOD_ID: EditionExamples
--- PREFIX: edex
--- MOD_AUTHOR: [Eremel_, stupxd]
--- MOD_DESCRIPTION: Adds editions that demonstrate Edition API.
--- BADGE_COLOUR: 3FC7EB
--- DEPENDENCIES: [Steamodded>=1.0.0~ALPHA-0905a]
#

this?

#

I thought this was just comments and was not needed...

#

ill add one

brisk rose
#

Yeah it's needed

mighty stump
#

imma try again

#

nope

#

wait I might not have saved

#

let me try one more time

#
--- STEAMODDED HEADER
--- MOD_NAME: A Wee Little Deck
--- MOD_ID: WeeDeck
--- MOD_AUTHOR: The #1 Erratic Deck Lover
--- MOD_DESCRIPTION: Create a wee little deck that only contains 2s!
--- DEPENDENCIES: [Steamodded>=1.0.0~ALPHA-0812d]
#

here is my header

#

yeah it aint showing up on mod list

brisk rose
#

Why dud you turn the dependent down? Are your still on that old smodded version?

mighty stump
#

wait let me try putting brackets around my name

#

oh I dunno

brisk rose
mighty stump
#

I just copy pasted

brisk rose
#

Ah I see. It's just different than the other thing you pasted

#

You don't need that line at all tbh

mighty stump
#

so i can delete dependancy line?

brisk rose
mighty stump
#

done imma try to boot up again

#

progress ig lol

cerulean rose
brisk rose
#

The two in a row there

mighty stump
#

okay

#

wait i dont see it

brisk rose
#

You're not trying to close the whole object there right? Apply is part of it

mighty stump
#

found it

#

okay time to run it back

#

okay I am so lost I tought i fixed it but i didnt

#

do you mind deleting the curly bracket for me?

#

or wait imma try one last thing

brisk rose
#
SMODS.Atlas{
    key = "wee_deck_art",
    path = "wee_icon.png",
    px = 71,
    py = 95,
}
SMODS.Back {
    name = "A Wee Little Deck",
    key = "twos",
    atlas = 'wee_deck_art'
    pos = {x = 0, y = 0},
    config = {only_one_rank = '2'},
    loc_txt = { 
        name = "A Wee Little Deck",
        text = {
            "Start With a Deck",
            "full of {C:attention}Twos{}"
        },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.only_one_rank))
                end
                return true
            end
        }))
    end
}    
#

That was the one I meant

#

But there might be other bracketing issues

mighty stump
#

thank you

#

ill try this then attempt to fix any others that pop up

#

yeah i cant figure out where that extra bracket is

#

im sorry for all this heh heh

brisk rose
#

On the atlas line

#

On the back object

mighty stump
#

omg lol

#

lets see if that fixes it

#

LETS GOOOO

brisk rose
#

Ayyy

mighty stump
#

now to see if it actually functions

#

The Wee came out better than I thought tbh

#

woooooo

#

okay now to figure out how to make a wee suit

#

and then the stupidity can really begin

#

actually what is easier, making a custom suit or having the deck start you out with a negative eternal Wee joker?

mighty stump
cerulean rose
#

can't imagine either would be that tough

brisk rose
brisk rose
cerulean rose
#

i'm getting this crash when attempting to view a joker description

mighty stump
#

okay so I see how to add new jokers but I am confused on how to add a vanilla joker to the starting hand of the deck

cerulean rose
#

should just drop it into the apply function to add the joker

cerulean rose
mighty stump
#

I have no idea on where to even begin looking to find out how to make a custom suit

cerulean rose
#

look at some mods that add custom suits

mighty stump
#

I can make heads or tales of them

#

I only started modding balatro today

#

Also I have never touched lua before

cerulean rose
brisk rose
cerulean rose
#

yeah, tried that

#

didn't seem to work

#

unless i'm doing something else wrong

mighty stump
#

would I put custom made jokers before or after the back object

cerulean rose
#

doesn't matter

mighty stump
#

oki

narrow pollen
#

so, is there a way to prompt the game to restart if it detected a mod config option changed after the config tab is closed?

#

i'm figuring out that i simply can't have on-the-fly joker modification, and i'd really hope there's a way to at least have the game automatically restart for the user so they don't have to do that themselves.

mighty stump
#

how much should i make a joker that makes all scored 2s trigger again and what should its rarity integer be?

hardy viper
#

i forget the exact syntax for patching a steamodded file tho

narrow pollen
mighty stump
#

I think I know my mistake, it is a problem with sprite placement correct?

#

what coordinates do I put when accessing a second image in a sprite sheet?

#

here is what I have so far

#

cause I just have a deck and the card that repeats all played 2s

mild night
#

anyone working on procedurally generated content? I don't just mean "random haha", I mean unique independent jokers, bosses, etc

brisk rose
#

It's a 0 indexed x, y grid

mighty stump
#

okay

#

so the Wee Mirror would be 1,0 got it

#

thanks

#

I got this error again

#

oh! I found where I went wrong

#

let me fix that rq

#

accidentally put a pathway isntead of the key

#

okay

#

I have obtained the card without crashing

#

now lets see if it works as intended

#

how do I check if a card is a two?

#

cause I tried replacing is_face with is_2 like a dumb dumb and that didnt work

I am suprised I have gotten this far seeing as I know 0 lua

mellow sable
mighty stump
#
SMODS.Joker {
    key = 'wee_mirror',
    loc_txt = {
        name = 'A Wee Mirror',
        text = {
            "Retrigger all",
            "played {C:attention}Two{} cards"
        }
    },
     config = { extra = { repetitions = 1 } },
    rarity = 1,
    atlas = 'wee_deck_art',
    pos = {x = 1, y = 0},
    cost = 4,
    calculate = function(self, card, context)
        if context.cardarea == G.play and context.repetition and not context.repetition_only then
            if context.other_card:is_two() then
                return {
                    message = 'Again!',
                    repetitions = card.ability.extra.repetitions,
                    card = context.other_card
                }
            end
        end
    end
}
#

I just ripped this from the sock n buskin template and I just need to modify the if statement to check for 2s but i dont know how to do that

#

oh wait i found it

#

now i hope this workds

#
SMODS.Joker {
    key = 'wee_mirror',
    loc_txt = {
        name = 'A Wee Mirror',
        text = {
            "Retrigger all",
            "played {C:attention}Two{} cards"
        }
    },
     config = { extra = { repetitions = 1 } },
    rarity = 1,
    atlas = 'wee_deck_art',
    pos = {x = 1, y = 0},
    cost = 4,
    calculate = function(self, card, context)
        if context.cardarea == G.play and context.repetition and not context.repetition_only then
            if context.other_card:get_id() == 2 then
                return {
                    message = 'Again!',
                    repetitions = card.ability.extra.repetitions,
                    card = context.other_card
                }
            end
        end
    end
}
#

it didnt crash but i dont understand why it didnt repeat when i played a 2 while testing it

#

oh i am dumb scoring animations are off

#

it works!

narrow pollen
#

nice!

#

well, if anyone knows how to patch a steamodded file, or similarly help me figure out how to enable and disable my rebalanced jokers... i'd appreciate it!

halcyon fjord
#

I wasn't sure if I was supposed to put it in here or modding-chat, but I'm having trouble with a playing card mod, it was working like a week ago, but now it only shows a fourth of the card skin on each card. I just took a mod someone else made and just replaced the textures. Like I said it worked fine for about a week and then just stop working. Any ideas?

narrow pollen
#

@halcyon fjord what are the dimensions of your card sprites?

halcyon fjord
#

the cards individually? or the entire image?

narrow pollen
#

the image

#

if the image for your playing cards is larger than 923 x 380, that's the problem

halcyon fjord
#

oh yeah its literally double that lol

#

i changed the dimensions to 923x360 and it fixed, tysm

narrow pollen
#

just making sure, that's all.

halcyon fjord
#

yeah i just typed 360 on accident

narrow pollen
#

glad i could help

#

had the same issue on my own mod once

narrow pollen
#

yeah, every asset in the game is broken up into 71 x 95 tiles.

silent pawn
#

yeah i know that but i didnt know like the atlas couldnt be bigger than 923x380

#

i think thats what you're referring to right

narrow pollen
#

no, it can be. it's just that the playing card asset is 923 x 380

#

so making it bigger or smaller leads to... problems

silent pawn
#

oh right right

#

does having it at a different size just completely break it or does it appear bigger in game

#

i feel like if its higher it just cuts off the edges

#

but what if its smaller does it just look messed up

narrow pollen
#

it just takes whatever is there

#

like this

#

because it's supposed to be this size

silent pawn
#

you can change the px and py variables of the joker and it'll work fine

narrow pollen
#

but it WAS this size

#

yeah, but that's individual jokers

silent pawn
#

?

#

it works if you use one image for an atlas

#

pretty sure

#

ive never had issues with it

narrow pollen
#

fair. you can do that... but that requires knowledge of coding

silent pawn
#

oh wait i said under the joker i meant under the atlas aha

#
  key = "example",
  path = "example.png",
  px = HERE,
  py = HERE
}):register()```
#

defines the dimensions of each joker

#

then under the joker you can use the variable pos to define where in the atlas it is

#

pos = {x = 3, y = 0}

narrow pollen
#

yeah, but again... this is way more effort than shrinking it down

#

especially if you aren't using all the pixels of your new size

silent pawn
#

depends on the desired resolution of jokers

#

some people could want pretty high res joker art

#

for example i think SDM_0's Stuff has some pretty high res jokers

limpid flint
#
for i = #G.P_CENTER_POOLS["Center"], 1, -1 do
    local entry = G.P_CENTER_POOLS["Center"][i]
    if string.find(entry.key, "c_bunc_the") then
        table.remove(G.P_CENTER_POOLS["Center"], i)
    end
end
limpid flint
silent pawn
#

i have no idea what you are trying to do

limpid flint
#

Remove a bunch of consumables that all have a full key name starting with c_bunc_the

silent pawn
#

remove them from your consumable slots or from the item pool

limpid flint
#

Pool

silent pawn
#

theres probably way easier ways to do it than what you are doing then

#

theres a variable you can use thats just called in_pool

limpid flint
#

To be honest I don't know what I am doing

silent pawn
#

yeah tbh picking up literally any knowledge for modding this game is a pain

#

the documentation is unfinished and the best way to learn how to do things is just to look at other peoples mods

#

which is a pain

limpid flint
#

This is the snippet I know works, which removes booster packs

#
    if (SMODS.Mods["Bunco"] or {}).can_load then
        for i = #G.P_CENTER_POOLS["Booster"], 1, -1 do
            local entry = G.P_CENTER_POOLS["Booster"][i]
            if string.find(entry.key, "p_bunc_virtual") then
                table.remove(G.P_CENTER_POOLS["Booster"], i)
            end
        end
silent pawn
#

i see

#

i dont think ive ever referenced anything from bunco so i have no idea how they work their stuff

#

i also have no idea if the main pool is called Center so

#

cant help too much on this

#

):

limpid flint
#

I am trying to get it to also remove the consumables

#

Thanks for the reply nonetheless

silent pawn
#

best of luck

limpid flint
crisp coral
#

I can't check source code right now, but in the code consumable is always referred as consumeable

silent pawn
#

thunk cant spell 🔥

crisp coral
#

I don't think center pools use that though, but I could be wrong

silent pawn
#

times like this the documentation would be very nice to be able to refer to

crisp coral
#

There is barely any documentation for the source code, but there's plenty for Steamodded :)

silent pawn
#

have they updated the steamodded docs?

#

last time i checked it was bare bones asf

#

oh it looks like it has been updated

#

at least somewhat

teal estuary
#

what was updated raisedcateyebrow

silent pawn
#

oh maybe not

#

half the pages have like

#

2

#

nevermind last updated sep 14 😭

#

WE NEED MORE DOCS RAHHH

limpid flint
#

No dice

teal estuary
wintry solar
#

It’ll be whatever set the consumables are in

#

So, Tarot, Spectral, etc.

limpid flint
#

So I should state "Polymino"?

#

Let me try

brisk rose
olive shoal
#

in the last time since ive moded this game my lovely patches have seemed to magically stopped working

#

i moved from lovely version 6 to version 5 but they still come up in the dump file

#

is there anything i need to do to get them to work now

hardy viper
#

i mean first of all use latest lovely not beta6 or beta5 and second of all use the format described on the lovely readme

#

idk if it ever changed but

olive shoal
#

is latest lovely not v0.6.0

hardy viper
#

oh

#

thought you were talkin about beta6

#

hm

olive shoal
#

the format seems to be the exact same also

hardy viper
#

try regex if normal patterns arent working

#

would also help to see the .toml file that isnt applying in question

olive shoal
#
version = "1.0.0"
dump_lua = true
priority = 0

# evaluate_poker_hand, this is a really awful way of doing this idc
[[patches]]
[patches.pattern]
target = "functions/misc_functions.lua"
pattern = 'function evaluate_poker_hand(hand)'
position = 'after'
payload = '''
    local has_doctor_house = next(find_joker('Dr House'))
      print(has_doctor_house and "true" or "false")
    print("anything?")
'''
match_indent = true```
#

it still modifies the dumped file but this patch doesnt apply

frosty dock
#

iirc steamodded overrides that function now, so even if the patch hits, it won't do anything?

hardy viper
#

ya

#

top ten reasons lovely patches are a last resort

frosty dock
#

there's simply no reason to do any of that when you can just switch to using steamodded's poker hand api

limpid flint
hardy viper
#

ni

#

l

limpid flint
#

But now collection look like this

hardy viper
#

why does lua use "nil" instead of "NULL" anyways

#

is there an actual reason or was it just to be different

limpid flint
#

How do I remove the category

hardy viper
hardy viper
#

i would guess that SMODS adds the category itself

olive shoal
frosty dock
#

yes

brisk rose
teal estuary
#

if you want a joker to display two messages, one after another, can you just put two messages = x in the same return?

nocturne tiger
#

finally want to get into modding balatro :) anyone have a starting guide or something? :0

teal estuary
#

however, the documentation is a little.. sparse

#

so the game files, this channel and other mods will be a big help 😭

nocturne tiger
#

👍 thanks so much

teal estuary
#

np

limpid flint
wintry solar
olive shoal
#

isnt it spelt polynimo

#

it is not nvm ignore that

wintry solar
#

I believe ConsumableTypes are stored in SMODS.ConsumableTypes, so in theory doing something like SMODS.ConsumableTypes['Polymino'] = nil would remove it

teal estuary
#

quick question: is there something specific you need to do when you have 2 messages? i cannot get mine to work 😭

limpid flint
#

Do I add it anywhere in a Lua file?

wintry solar
#

wherever you put the other bit should work

limpid flint
#

Then it's not working

topaz sun
#

Does anyone know of the function used to make the player lose the run? Is it just lose_game() or something?

rough furnace
rough furnace
# hardy viper top ten reasons lovely patches are a last resort

I'd argue otherwise. Lovely patches are generally more compatible with things, and they only really fail in cases like this where another mod completly replaces the function (which doesn't happen much). The same issue with something replacing your functon can happen with you hooking methods. I also find in general, people often mess up lua hooks and are more likely to not run the original code as often.

olive shoal
#

yeah i dont think that was a lovely fail that was an api changing making stuff i wrote before obsolete

#

which happens its alright

shell timber
#

is there a way to force a modded object to show up with a different mod badge?

rough furnace
#

probably but I don't think theres a proper api for it

tepid eagle
#

hack their computer and remove the object from their mod and then put it in yours

shell timber
#

it's my mod

rough furnace
#

could you have the other mod register the object but only conditionally if the other mod is present

shell timber
#

the other mod is also my mod

#

i just want it to visually look different

#

and they're actually the same mod

rough furnace
#

oh I see

#

you could probably hook SMODS.create_mod_badges and do a check

shell timber
#

yeah i was going to do that

#

ideally it would be a lovely patch but i've forgotten the syntax for patching another mod

rough furnace
#

uhhh if you have beta7+ you should be able to target =[SMODS _ "utils.lua"] I belive

#

oh it might be =[SMODS _ "core/utils.lua"]

#

also as a note that there won't be a dump for that patch

#

btw @gaunt thistle are you aware of that

#

it fails to write due to invalid filename

shell timber
#

uhh, is this correct?

#

this causes lovely to unwrap an error

rough furnace
#

show error

shell timber
#

and then just the regular panic cannot unwind thing

rough furnace
#

oh hmmm

#

I've had it fail before but it didn't panic for me

#

ERROR - [♥] Failed to write patched buffer to "C:\\users\\shorty\\AppData\\Roaming\\Balatro\\Mods\\lovely\\dump\\=[love \"wrap_Event. lua\"]": Os { code: 123, kind: InvalidFilename, message: "Invalid name." }

#

but no vrash

shell timber
#

this is with dump_lua = false btw

rough furnace
#

does dump_lua do anything?

shell timber
#

doesn't change anything, no

rough furnace
#

I mean it is patching at least

#

ooooh

#

it's because there is a slahs in the name

#

so the parent folder is invalid

shell timber
#

ah

rough furnace
#

where my patch just the filename is invalud

#

I can make a fix, but your patch would only work on the next lovely version

shell timber
#

hm

#

just using utils.lua wouldn't work?

rough furnace
#

no it needs to match the buffer name

shell timber
#

i see

#

well that's annoying

#

ok i'll just hook into the function then

gaunt thistle
#

Uhhh how should we format that as a filename?

#

maybe PREFIX/filename.lua?

rough furnace
#

it's kinda just screwed

#

the buffer name is arbitrary

#

so it can be whatver

#

well if it starts with =

#

the issue is if you start removing stuff then it can have conflicts

#

but idealy I think just removing invalid characters is fine

#

so =[SMODS _ "core/utils.lua"] becomes SMODS _ coreutils.lua or smth

#

I don't remebr the invalid characters off the top of my head

#

I don't know enough rust to properly handle this

shell timber
#

could you do <mod folder>/whatever/it/is.lua?

#

so this would become Steamodded/core/utils.lua in the filesystem

rough furnace
#

well the issue is the name is arbitratry

#

I could make a buffer that has the name =hi mom

shell timber
#

ah

gaunt thistle
#

I can do my best to fix it but it definitely needs an opinionated solution. I'm thinking that lovely won't attempt to patch targets that don't follow the =[PREFIX _ "file/path.lua"]

#

If it follows that schema then I can parse it super easily.

lusty garden
rough furnace
# gaunt thistle I can do my best to fix it but it definitely needs an opinionated solution. I'm ...

I think it should still patch them but I think it would be fine if it didn't dump them. Maybe we could specify an override to the dump patch to allow dumping of incompaible formats. Also the _ can be any stirng (SMODS uses it for the mod id (_ is for internal stuff) and lovely uses it for the module name). Also you should support loves format that has a prefix but no middle bit, just the path name

lusty garden
rough furnace
#

you can extact the games code using 7 zip and look in card.lua

lusty garden
#

oh i didnt know that

rough furnace
#

they aren't created in the same way as modded jokers but there behaviours should still work

lusty garden
#

does it have to be 7zip or can i use win rar and uh what do i extract

wintry solar
#

You can use win rar, just extract the balatro.exe

lusty garden
#

oh i see ty

teal estuary
#
    calculate = function(self, card, context)
    if context.repetition and context.cardarea == G.play and not context.repetition_only then
      local suits = {
        ['Hearts'] = 0,
        ['Diamonds'] = 0,
        ['Spades'] = 0,
        ['Clubs'] = 0
    }
    for i = 1, #context.scoring_hand do
        if context.scoring_hand[i].ability.name ~= 'Wild Card' then
            if context.scoring_hand[i]:is_suit('Hearts', true) and suits["Hearts"] == 0 then suits["Hearts"] = suits["Hearts"] + 1
            elseif context.scoring_hand[i]:is_suit('Diamonds', true) and suits["Diamonds"] == 0  then suits["Diamonds"] = suits["Diamonds"] + 1
            elseif context.scoring_hand[i]:is_suit('Spades', true) and suits["Spades"] == 0  then suits["Spades"] = suits["Spades"] + 1
            elseif context.scoring_hand[i]:is_suit('Clubs', true) and suits["Clubs"] == 0  then suits["Clubs"] = suits["Clubs"] + 1 end
        end
    end
    for i = 1, #context.scoring_hand do
        if context.scoring_hand[i].ability.name == 'Wild Card' then
            if context.scoring_hand[i]:is_suit('Hearts') and suits["Hearts"] == 0 then suits["Hearts"] = suits["Hearts"] + 1
            elseif context.scoring_hand[i]:is_suit('Diamonds') and suits["Diamonds"] == 0  then suits["Diamonds"] = suits["Diamonds"] + 1
            elseif context.scoring_hand[i]:is_suit('Spades') and suits["Spades"] == 0  then suits["Spades"] = suits["Spades"] + 1
            elseif context.scoring_hand[i]:is_suit('Clubs') and suits["Clubs"] == 0  then suits["Clubs"] = suits["Clubs"] + 1 end
        end
    end
    if 
    suits["Hearts"] > 0 and
    suits["Diamonds"] > 0 and
    suits["Spades"] > 0 and
    suits["Clubs"] > 0 then 
      card.ability.extra.repetitions = math.min(card.ability.extra.repetitions + card.ability.extra.repetitions_gain, 10)
        return {
            message = "Again!",
            repetitions = card.ability.extra.repetitions,
            card = card,
        }
    end
  end
end

sorry for the super long message, but im having some trouble making card.ability.extra.reptitions only equal 1 after a hand with all 4 suits is played - with this code it immediantly jumps to 4

#

and if i put, for example, card.ability.extra.repititions - 3, 10), it makes it equal -4?

stiff locust
#

wait no

#

what is extra repetitions set to

teal estuary
#

0 raisedcateyebrow

#

repitions_gain is set to 1

stiff locust
#

¯_(ツ)_/¯

teal estuary
#

fair enough 😭

stiff locust
#

my best guess is that it's counting them more than once somehow

tepid crow
#

probably triggering for multiple contexts

teal estuary
#

(here is the rest of the code, if you are interested)

teal estuary
tepid crow
#

oh your if statement does have pretty specific requirements

#

try printing anyway to check I guess

teal estuary
#

i mean, the contexts there are also what is used in the example jokers, so idk - but printing? raisedcateyebrow

#

should i put a print in the context if statement or?

wintry solar
#

you check the entire hand on every card

teal estuary
#

yes, so that the joker knows if all 4 suits have been played

tepid crow
#

yeah but if you do that on every card, you do it 4 times

wintry solar
#

no, I mean you run this block of code on every card, and each time you check all the cards

teal estuary
#

OH

#

my bad 😭

#

so what should i do instead, because this is the only way i know of checking for multiple suits (iterating over every card 😭 )

wintry solar
#

you need to change your context

teal estuary
#

oh, cool

#

easier then i expected

tepid crow
#

shouldn't this trigger when the joker is scoring? instead of when the cards are?

teal estuary
#

joeshrug no idea, all the other jokers i've made with this same "setup" (play X thing, gain +Y of Z) have been using context.individual and context.cardarea == G.play - since this is a repititon joker though

#

it uses context.repititon and not context.repition_only (everything else is just me guessing 😭 )

hardy viper
#

you arent making those spelling errors in your code right

teal estuary
#

no, i just type too fast for my hands and fuck up often

#

in code i usually use the prompts given by VSC anyway, so joeshrug

wintry solar
#

what does the joker do?

teal estuary
#

when a hand contaning all 4 suits is played, it gains 1 retrigger, which maxes at 10

wintry solar
#

the cards played gain the retrigger?

#

or the joker?

teal estuary
#

the joker gains the retrigger, like how runner gains chips

wintry solar
#

I'd evaluate your retrigger gains in this context

topaz sun
#

Maybe try using context.after as well in your if statement, no? That way it'll only do the thing once during the after context (after scoring)

teal estuary
teal estuary
wintry solar
#

then I don't remember how retrigger api works properly

rough furnace
#

Remeber, you can have multiple if staments in yoru calculate. As such you can have a different context for increasing your value, and retriggering cards

teal estuary
#

and thats essenitally all this one is 😭 flowerpot checking with its return changed for repetitions, and the math.min wedged in

rough furnace
#

yeah you should just be able to move that to a different check

#

not srue wheich one

teal estuary
#

do you mean like, a different type of iteration over the played cards?

rough furnace
#

no just don't run it in the repitition context

teal estuary
#

(instead of using flower pots way of doing it)

#

OH

#

correct me if im wrong, but doesnt repetitions need that context to function?

rough furnace
#

well you don't do your incrementing in that context

teal estuary
#

true

#

true

rough furnace
#

just giving the repition

wintry solar
#

you also arent retriggering the cards

teal estuary
#

oh, wait

teal estuary
teal estuary
#

(which honestly, is a joker idea in itself)

wintry solar
#

didnt you say you want the joker to retrigger though?

teal estuary
#

i realised how that sounded now - the joker gains a retrigger (like runner gains chips), but the cards are retriggered

wintry solar
#

oh right

teal estuary
#

this is what it currently does, it just gains the amount of retriggers equal to the amount of cards played

wintry solar
#

so yeah, do your iteration in before, then return it in the context you have here

#

at the moment, you check the first card, see you have met the condition, increase retriggers to 1, send 1 as repetitions, move to 2nd card, see you have met the condition, increase retriggers to 2, send 2 as repetitions, etc...

teal estuary
#

😭 amazing

#

okay, so, wanna be sure - the checking is outside of the context.repetition.. if statement, but the return{ is inside that context statement?

rough furnace
#

you want to make 2 if statments

#

and then the context you currently have to add repitions to cards

teal estuary
#

ah, thank you

#

(that is what the error was calling for)

#

okay, so, wanna be absolutely sure - is this essenitally what i need?:

if context.scoring_hand then
-- checking stuff
end
if context.repetition and ..
-- math
return{
--repetition stuff
}
narrow pollen
#

you're forgetting the end at the end of that

#

but essentially, yes.

teal estuary
#

i forwent the ends, but yeah cool

#

ty

wintry solar
#

that first one is horribly wrong

#

iirc the unique property is context.before

teal estuary
#

im sorry this is a me thing, but do you mean just if context.before then, if context.before and context.scoring_hand then, or raisedcateyebrow

wintry solar
#

first one

teal estuary
#

ty

weary jungle
#

i remeber you were able to view souce code for balatro, where was that?

teal estuary
#

view it, as in not on your own .exe file?

weary jungle
#

as in you could view like UI.lua and game.lua or something, and it would show it

timid parrot
#

yeah you can unzip the exe with apps like 7zip

weary jungle
#

from my own .exe

#

i remeber you didnt need to unzip anything

tepid crow
#

yeah you do

timid parrot
#

well regardless of what you remember unzipping it is probably the easiest and most up-to-date way to view it

rough furnace
#

you can view the lovely dump but that doesn't have all the files and also has patches from mods applied

tepid crow
#

true, but that's not really the source code

#

(and arguably more important)

weary jungle
#

it might have been the locvely dump

#

how do i view the lovely fomp?

tepid crow
#

mods/lovely/dump

weary jungle
#

how do i see what cards are in your hand?

timid parrot
weary jungle
#

yea

timid parrot
#

G.hand.cards

weary jungle
#

also, is there any function that gets ran everytime the held cards change? (adding/removing cards, discarding, playing, changing cards)

timid parrot
#

most that stuff is handled by the global draw_card function, which is used to move cards between different areas of the screen

#

it contains parameters for where cards are coming from and going to

#

among other things

rough furnace
#

What are you trying to do?

weary jungle
#

show if you have a straight or other hand, sometimes i miss it because im going for a flush

rough furnace
weary jungle
#

so turns out i hate everything!

#

like 3rd tiume something has already been done

glossy stone
#

it's ok tbh, i have a joker in my mod which was already implemented in another one

#

sloghtly different xmult values tho so ha

silent pawn
#

i remember seeing a joker somewhere that made it so discards roll over to the next blind does anyone know what mod its from

spare elk
#

that's just the old version of Merry Andy

silent pawn
#

from which mod

#

oh wait its a vanilla card

#

i have never seen that card in my life

spare elk
#

merry andy is a goat with yorick and mail-in

silent pawn
#

does it carry your rerolls over to the next blind?

#

discards i mean

spare elk
#

not anymore

#

that was its old effect

#

now it gives you +3 discards in exchange for -1 hand size

silent pawn
#

oh right

spare elk
#

which is a pretty good deal i think so

silent pawn
#

yeah

#

im just looking for a joker that gives temporary discards that carry over so i can reference it for my code

spare elk
#

unfortunately i am not a guy who knows enough about modding to help you with this

silent pawn
humble gale
#

Does anyone know how to check what seal is on a card? This is what i have rn

context.other_card.seal.name == 'Blue'
hardy viper
#

would that be subject to localization

edgy reef
#

no

#

Thunk treats names as a card's "key" in most of Balatro's code

flat pier
#

Working on picking up modding, running into an odd issue.
When trying to load a joker.lua (Learning from other mods) It throws an error stating it is trying to call a nil value.
The loading code:
line 36: SMODS.load_file('data/jokers/testJoke.lua')()
The error:

#

I'm not sure what I'm doing wrong here

rough furnace
#

try changing it to assert(SMODS.load_file('data/jokers/testJoke.lua'))()

#

but my guess is minor spelling mistake

#

testJoke.lua > testJoker.lua

flat pier
#

No, the lua file is testJoke.lua

flat pier
rough furnace
#

that shouldn't have fixed the issue but glad it did

wintry swallow
#

Is there a way to add a joker to the next shop? So far I got

   if context.selling_self then
      G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.0, func = function()
        local ccard = copy_card(card, nil, nil, nil, nil)
        ccard:start_materialize()
        ccard:add_to_deck()
        G.shop_jokers:emplace(ccard)
        return true end }))

But G.shop_jokers does not exist.
It's supposed to add a copy of itself to the next shop when sold.

#

.

cerulean rose
rough furnace
#

take a look at how the rare joke r tag works

cerulean rose
#

indexing seems to work though

#

seems like print just habitually lies to you

rough furnace
#

does SMODS.Stickers have integer keys?

cerulean rose
#

no, just figured that out

#

as you can see i don't know lua well

edgy reef
#

Forgot to add one

cerulean rose
#

its keys are the internal names of the stickers

#

just switched ipairs to pairs and now it works perfectly

south karma
#

Does anybody know where midas mask effects are in the code?
Im trying to base a similar effect on it (polychrome instead of gold)

wintry swallow
#

card.lua line 3444

#
                    if self.ability.name == 'Midas Mask' and not context.blueprint then
                        local faces = {}
                        for k, v in ipairs(context.scoring_hand) do
                            if v:is_face() then 
                                faces[#faces+1] = v
                                v:set_ability(G.P_CENTERS.m_gold, nil, true)
                                G.E_MANAGER:add_event(Event({
                                    func = function()
                                        v:juice_up()
                                        return true
                                    end
                                })) 
                            end
                        end
                        if #faces > 0 then 
                            return {
                                message = localize('k_gold'),
                                colour = G.C.MONEY,
                                card = self
                            }
                        end
                    end
#

Ah juice_up, good old well named functions

silent pawn
#

juice_up best function

#

such a silly name

cerulean rose
#

getting this error when trying to view a blind i've created in the collection

#

so apparently blind sprites MUST have their atlas type set to animated

silent pawn
#

is it possible to check if the blind you enter is a boss blind?

silent pawn
#

lets see the part of your code where you declare your atlases

cerulean rose
#

i already got it

#

the issue was that my atlas wasn't set to animated

silent pawn
#

oh right

#

thats mandatory for blinds?

#

didnt know that

silent pawn
static cairn
#

how would i make my own mod?

silent pawn
#

best place to start is coming up with ideas for things you'd implement

static cairn
#

ok

silent pawn
#

or a general idea for the theme of the mod

static cairn
#

i had an idea for like eets jokers

silent pawn
#

for example theres a pokemon mod and stuff

static cairn
#

like the prankster whale

#

and the happy marshmellow

#

ok step 1 done. What next?

silent pawn
#

is it possible to re-enable boss blinds after they have been disabled by a joker?

silent pawn
#

nuh uh

#

im just trying to make a card that disables the boss for a couple hands then it reenables

#

but idk if its possible

tidal ice
#

I like that idea tbh

brisk rose
#

It ought to be possible

tidal ice
#

idk if your idea is possible but I like it

brisk rose
#

Saying it can be disabled while active

silent pawn
#

it'd be possible i should imagine but theres no function for enabling blinds

brisk rose
#

The opposite should be true

brisk rose
silent pawn
#

we have G.GAME.blind:disable() but theres no alternative for enabling

#

i might just have to change my idea then );

brisk rose
#

Can't it just reroll the blind to be the same one and not disable it?

#

Might be feasible

rough furnace
#

funnily enough I did a bit of looking into this earlier

tidal ice
#

if you need to, maybe make it where it disables the boss blind after two or three hands instead?

#

it just doesnt work on the needle though

brisk rose
#

The 'first hand' will be the first what is enabled for

#

And that's when it'll set it to 1

#

Pretty sure

silent pawn
#

yeah looks like coonies idea of just setting it to the same blind you're playing on

brisk rose
#

Oh after

#

I can't read

silent pawn
#

yea u get 1 disabled hand

#

then boss activates

#

similar to my idea xdd mine was its disabled for 2 hands

silent pawn
#

ill do some screwing around with that idea

#

thanks guys

brisk rose
#

Np :3

silent pawn
#

whats the function for it is it G.GAME.set_blind or is it like G.GAME.blind:set_blind()

rough furnace
#

G.GAME.blind:set_blind(G.GAME.blind.config.blind) works

#

with a few quirks

silent pawn
#

think what ive done should work

#

i hope