#Balatro Tutorials

1 messages · Page 1 of 1 (latest)

devout vortex
minor ledge
#

lol

#

he ain't got no olive oil to juice up >_>

#

but i love this, :)

grim terrace
#

it'd get a lot more people into this

#

and its entertaining even if you already know imo

unborn hollow
devout vortex
#

other than jokers, what's the most common thing people ask for help in creating for modding?

#

might make a tutorial out of it

lone locust
devout vortex
#

I have failed myself

lone locust
#

You should have put DebugPlus link in the desc too imo

devout vortex
#

oh shi yeah

lone locust
#

Is there a reason you didn't make the mod initial data using metadata.json?

devout vortex
#

im gonna be honest

#

i dont even know what that is

#

i know things

#

but not that many things

lone locust
#

It's a new SMOD things that replaces the mod header

devout vortex
#

damn

lone locust
#

Love the outro, wish the context in calculate would have more details but I guess it could be a different video

sudden flare
#

subbed! love this, i hope to see some more in-depth vids too. thanks for taking the time to make this 😄

midnight basalt
minor ledge
#

Lets uuh stay at jokers first

#

Lol

torn magnet
#

Also, what coding software did you use in the video?
Seems very useful

grim terrace
minor ledge
#

And what i prefer

unborn hollow
#

Use vscode and install a lua extension

devout vortex
#

soon!!!

#

(this ones gonna take a while i think)

#

(three different things to add)

minor ledge
#

season 1 = jokers
season 2 = consumable
season 3 = enhancements

devout vortex
#

ermnmnmmmm

#

idfk

minor ledge
#

i mean its your videos

#

u do u

#

just a suggestion

queen storm
#

If I wanna make multiple jokers in my mod, what do I copy? Do I make a second SMODS.Joker

lone locust
#

Yes

queen storm
#

nvm, I already did that

#

figured it out lol

boreal charm
#

wait nvm i messed something up

boreal charm
#

In the next video can you show how to add gray text in the joker description

minor ledge
#

goes for all colours like purple, chips, mult, green

#

C is so the like how bull has the chips coloured

#

and X: is how blackboard has it coloured (like a marker)

minor ledge
boreal charm
#

@minor ledge thank you 🤑

minor ledge
devout vortex
minor ledge
#

ooh rarity text o-o

boreal charm
#

how would i make a scaling joker that goes up by 0.25 Xmult if hand 5 of a kind

#

also how would I add a joker rarity

raw cedar
# devout vortex soon!!!

From my experience the atlas value in undiscoveredsprites is one a lot of people get wrong. It should be the full key of the atlas, like mod_key, but a lot of people just use the original key instead so it doesn't work (but don't notice if they don't have them undiscovered)

boreal charm
grim terrace
queen storm
#

where did I go wrong here?

#

it isn't showing up in the collection

devout vortex
#

i have

#

no idea

#

that should work, i dont know why it wont

queen storm
#

hmm

#

like it just doesn't exist at all

minor ledge
#

At required stuff

queen storm
#

ok

queen storm
#

How do I change the color of the tab in the collection page?

devout vortex
#

thats why its white

queen storm
#

oh yeah

mystic tiger
#

Hi @devout vortex, may I know what IDE are you using and how are you able to do autocomplete in it?

devout vortex
#

its autocompleting because i have the games files in my workspace

mystic tiger
dim sorrel
devout vortex
#

thas weird

white adder
#

trying to do that now but I'm getting lost in the process

devout vortex
#

took me a little bit of coding just to get that cool transition

minor ledge
#

o-o

#

jumpscare warning next time pls

vast grail
#

and then you extract it with 7zip

#

and then you drag the folder with all the balatro code in it
into vscode and it creates the workspace

grim terrace
devout vortex
#

nope

#

still makin it

grim terrace
devout vortex
#

whoopsies

grim terrace
#

if you know whati mea

#

n

devout vortex
#

consumables in the joker slots? nono.....

#

jokers in the consumable slots.

vast grail
grim terrace
#

new tutorial just dropped from OP

devout vortex
grim terrace
boreal charm
devout vortex
grim terrace
#

Dereck Deck - Create a Derek Consumable at end of Boss Blind

#

/j

grim lava
#

Ewwwwww thunks jank ass set edition coding style

grim terrace
grim lava
#

card:set_edition(‘e_negative’)

devout vortex
grim lava
#

Some people like to use thunks cursed way because who knows, but using a string is the recommended usage

harsh apex
#

hello there.

#

How would i change the weight of a modded booster pack?

raven coyote
#

how would I go about setting a random edition similar to this spectral card?

#

preferably random for each card selected one might be negative the other polychrome etc

grim lava
#

card:set_edition(poll_edition(‘random key’, nil, false, true))

raven coyote
grim lava
#

Remove the card:

raven coyote
raven coyote
#

i got it yippee

raven coyote
hoary tinsel
boreal charm
#

wait nvm

#

I'm dumb

raven coyote
# boreal charm How did you get it to work, im trying something similar and idk

SMODS.Consumable{
key = 'LTM', -- key
set = 'LTMConsumableType', -- the set of the card: corresponds to a consumable type
atlas = 'Jokers', -- atlas
pos = {x = 1, y = 0}, -- position in atlas
loc_txt = {
name = 'Erics Sword', -- name of card
text = { -- text of card
'This thing seems VERY unstable',
'Add a random edition to up to 5 selected cards',
}
},
config = {
extra = {
cards = 5, -- configurable value
}
},
loc_vars = function(self, info_queue, center)
if center and center.ability and center.ability.extra then
return {vars = {center.ability.extra.cards}}
end
return {vars = {}}
end,
can_use = function(self, card)
if G and G.hand and G.hand.highlighted and card.ability and card.ability.extra and card.ability.extra.cards then
if #G.hand.highlighted > 0 and #G.hand.highlighted <= card.ability.extra.cards then
return true
end
end
return false
end,
use = function(self, card, area, copier)
if G and G.hand and G.hand.highlighted then
for i = 1, #G.hand.highlighted do
G.hand.highlighted[i]:set_edition(poll_edition('random key', nil, false, true))
end
end
end,
}

boreal charm
#

@devout vortex how would I make a consumable pack, or is that gonna be the next video?

boreal charm
boreal charm
raven coyote
boreal charm
#

I asked Crimson and after I tried changing the set_edition(poll_edition to set_enhancement(poll_enhancement he said set_edition is a unique function so idk what to do

raven coyote
#

i know how to make scored cards lucky but thats about it
for k, v in ipairs(context.scoring_hand) do
v:set_ability(G.P_CENTERS.m_lucky, nil, true)
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
return true
end

devout vortex
raven coyote
#

got this but it only selects from the default ones in the game not sure if it can include modded

raven coyote
# boreal charm how would I make it random

SMODS.ConsumableType{
key = 'LTMConsumableType', -- consumable type key

collection_rows = {4,5}, -- amount of cards in one page
primary_colour = G.C.PURPLE, -- first color
secondary_colour = G.C.DARK_EDITION, -- second color
loc_txt = {
    collection = 'LTM Cards', -- name displayed in collection
    name = 'LTM Cards', -- name displayed in badge
    undiscovered = {
        name = 'Hidden LTM', -- undiscovered name
        text = {'you dont know the', 'playlist id'} -- undiscovered text
    }
},
shop_rate = 1, -- rate in shop out of 100

}

SMODS.UndiscoveredSprite{
key = 'LTMConsumableType', -- must be the same key as the consumabletype
atlas = 'Jokers',
pos = {x = 0, y = 0}
}

SMODS.Consumable{
key = 'LTM', -- key
set = 'LTMConsumableType', -- the set of the card: corresponds to a consumable type
atlas = 'Jokers', -- atlas
pos = {x = 1, y = 0}, -- position in atlas
loc_txt = {
name = 'Erics Sword', -- name of card
text = { -- text of card
'This thing seems VERY unstable',
'Apply a random enhancement to up to #1# selected cards',
}
},
config = {
extra = {
cards = 5, -- configurable value
}
},
loc_vars = function(self, info_queue, center)
if center and center.ability and center.ability.extra then
return {vars = {center.ability.extra.cards}}
end
return {vars = {}}
end,
can_use = function(self, card)
if G and G.hand and G.hand.highlighted and card.ability and card.ability.extra and card.ability.extra.cards then
if #G.hand.highlighted > 0 and #G.hand.highlighted <= card.ability.extra.cards then
return true
end
end
return false
end,
use = function(self, card, area, copier)
-- List of possible enhancements
local enhancements = {
G.P_CENTERS.m_bonus, G.P_CENTERS.m_mult, G.P_CENTERS.m_wild, G.P_CENTERS.m_lucky,
G.P_CENTERS.m_glass, G.P_CENTERS.m_steel, G.P_CENTERS.m_stone, G.P_CENTERS.m_gold
}

    if G and G.hand and G.hand.highlighted then
        for k, v in ipairs(G.hand.highlighted) do
            -- Randomly select an enhancement for each card
            local random_enhancement = enhancements[math.random(1, #enhancements)]
            
            -- Apply the randomly selected enhancement to the current card
            v:set_ability(random_enhancement, nil, true)

            -- Trigger the event to juice up the card
            G.E_MANAGER:add_event(Event({
                func = function()
                    v:juice_up()  -- Calling juice_up on the card
                    return true
                end
            }))
        end
    end
end,

}

boreal charm
#

I want to include modded ones as well but I don't want to add them manually and I don't want the mods to be dependencies so yeah idk HQ_goofysob

raven coyote
#

yeah no idea there

raven coyote
#

i mean atleast it works

grim lava
unique oasis
lone locust
unique oasis
#

I see...

#

congrats on actually being able to read it

vast grail
#

look around and find another mod that does something similar

fleet trellis
#

i will definitely be visiting this thread a lot. i have never used lua in my life.

dim sorrel
#

no

unique oasis
#

I have a silly request for you: How does one make menus for like mod settings and sht?

#

(yes, i am stoopid and I have tried to read the documentation thing)

oblique coyote
#

hope elial1 (tutorial person) makes an overview on how to use the general commands/functions (kinda like steamodded wiki but with some more specific examples)

#

also generally wish more documentation on making custom mods were available

boreal charm
boreal charm
#

How would I edit base game consumables with a mod

blazing axle
#

Hi everyone, trying to learn modding - Trying to make a really basic mod that adds a seal that does something when the playing card bearing the seal is destroyed. I used the SealExample template in the Steamodded examples but I just can't get it to trigger on destruction. Any ideas; is the Card:calculate_seal() function in card.lua the issue or is it the calculate function in the mod's script. Here is the calculate function I have so far (just getting it to print test if it works for now)

#

This seems pertinent but I don't know what 'context calls' I am meant to be adding to Card:calculate_seal() - it dosen't seem to do what the API says it does.

blazing axle
#

yeah, theres a joker in extra credit that uses it

#

ship of theseus

#

caino uses it as well i think

#

not sure if that is the right one to use

#

I'm thinking that when the card is being destroyed, afterwards it looks for the seal - but there is no card anymore so there isn't any seal so nothing happens?

#

idk ive been slamming my head against this for hours now

grim terrace
#

rip

blazing axle
#

can you help though rather than pointing out a typo?

dim sorrel
#

you'd probably need to hook the destroy function

blazing axle
#

@dim sorrel what do you mean by that? Where can I find the destroy function as well?

dim sorrel
#

Card:start_dissolve

minor ledge
dim sorrel
#

wrong.

#

he is called caino in the code tho

blazing axle
blazing axle
blazing axle
#

doesn't Card:start_dissolve just handle the look and feel of a card's destruction? Rather than anything functional about it?

dim sorrel
#

true

#

should be remove then

dim sorrel
blazing axle
#

But where can i find all this? The source code is quite obtuse, naturally, but it makes it really hard to know how I am meant to even edit it

#

Like where is the function and how do i even 'hook' it?

#

sorry I know im just asking and asking

dim sorrel
#

check out hanged man

blazing axle
#

Ok, I guess it calls on the remove function

blazing axle
#

Appreciate the responses but still just smashing my head against this. Gonna sleep on it, if anyone has any other suggestions I'd be most grateful

blazing axle
#

Ok so ive hooked into the Card:start_dissolve function, and tested it with the base game seals and it works properly. How do I check for my new seal? Doing 'if self.seal == sealtype then' isn't working because I assume I have to add it somewhere?

blazing axle
#

like I get you are meant to put the something like 'mod_sealtype' to denote it's a custom seal but it still isn't working?

dim sorrel
#

remember to add the type prefix as well

#

also you'd prolly need to do self.seal.key or smthn

blazing axle
#

yeah this is the last thing i need! I've made it I just can't reference the damn thing. my key is "navy" and I turned SMODS.current_mod into "mymod". So shouldn't

if self.seal == 'mymod_navy' then

just work????!!??!

minor ledge
blazing axle
#

@dim sorrel think i have it working to some degree. Searching through the source code frantically gave me a load more knowledge on how shit works, thanks for your help!

blazing axle
#

Does anybody know if any extra considerations need to be made for 'The Fool' when making a custom Tarot/Planet card? My game crashes when trying to hover over the fool - I'm assuming that it is having issues displaying the custom tarot's information; any ideas?

dim sorrel
#

thats a loc_vars issue

finite atlas
#

Can someone explain what is context.blueprint?

blazing axle
# dim sorrel thats a loc_vars issue

yeah, got it fixed thanks had kirbio help me with that one. So many nested references I missed that I had a self.abillity rather than self.config in loc_vars.

blazing axle
# finite atlas Can someone explain what is context.blueprint?

you'll have to ask someone more knowledgable but I think it's a check to do with whether the card is compatible with blueprint or if it is what the copied effect should and shouldn't do. If you study the joker calculations that use it in the source code then you can get an idea for what exactly it does.

dim sorrel
outer meadow
#

bluestorm basically work by setting context.blueprint and then running the other joker's calculate
so you add if not context.blueprint to any behavior you don't want copied

finite atlas
#

Thank you!

night scarab
#

the first vid does a great job at explaining how to make a simple post scoring joker!
but i was wondering how to make a mid scoring joker? along the lines of the sinful jokers, scholar, etc

#

after reading through the steamodded wiki a bit i understand it has something to do with context.scoring_hand but im unsure how to make it target a specific kind of card (value, suit, enhancement, etc)

lone locust
#

You can also check this

night scarab
#

this looks useful, thank you!

crystal ocean
#

did i do something wrong, half the smod functions aren't showing up, and it doesnt work ingame 💔

dim sorrel
#

read the documentation

#

youre missing a lot of required fields

crystal ocean
#

oh okasy

crystal ocean
crystal ocean
#

am i stupid i followed the metadata

night scarab
#
        extra = {
            chips = 50,
            mult = 10,
            xmult = 2,
        }
    },
    loc_vars = function(self,info_queue,center)
        return {vars = {center.ability.extra.chips, center.ability.extra.mult, center.ability.extra.xmult}}
    end,
    calculate = function(self,card,context)
        if context.cardarea == G.play then
            if context.other_card.ability.name == 'Stone Card' then
                return {
                    chips_mod = card.ability.extra.chips,
                    message = 'Rock!',
                    colour = G.C.CHIPS,
                    mult_mod = card.ability.extra.mult,
                    message = 'And!',
                    colour = G.C.MULT,
                    xmult_mod = card.ability.extra.xmult,
                    message = 'Stone!',
                    colour = G.C.MULT,
                    card = card,
                }
            end
        end
    end,```
ive hit an impass here; trying to make a joker that gives chips, mult and xmult when you score a stone card but it does... nothing. no game crash either, so it seems like its just never going down the `if` tree. any advice?
dim sorrel
dim sorrel
#

use SMODS.calculate_effect

night scarab
#

separately as in 3 different returns or? apologies, still new to this

dim sorrel
#

no, use calculate_effect for the first 2 events

#

any return statement anywhere immediately ends the function

night scarab
#

ahhhh i see

#

so how would i write that out? does calculate_effect substitute in for the first two returns?

dim sorrel
#

yup

#

same table

night scarab
#

gotcha

dim sorrel
#

also i'd recommend reading up on bettercalc

night scarab
#

oooh okay

#

hm. well thats not promising

#

ill prolly pick this back up later

dim sorrel
#

its SMODS.calculate_effect

tacit steppe
#

Anyone got an example of how to use calculate_effect?

dim sorrel
#

if you need to do multiple messages in a row

tacit steppe
#

Yeah, but, how does that actually work?

dim sorrel
#

same table format as a return

tacit steppe
#
    calculate = function(self, card, context)
        local sevens = 0
        for i = 1, #context.scoring_hand do
            if context.scoring_hand[i].get_id() == 7 then sevens = sevens + 1 end
        end
        
        if sevens >= 3 then

            ease_dollars(self.ability.extra.payout)
            G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + self.ability.extra.payout
            G.E_MANAGER:add_event(Event({func = (function() G.GAME.dollar_buffer = 0; return true end)}))
            -- Money
            calculate_effect {
                message = localize('$')..self.ability.extra.payout,
                dollars = self.ability.extra.payout,
                colour = G.C.MONEY
            }
            
            -- Mult
            return {
                message = localize{type='variable',key='a_xmult',vars={self.ability.extra.x_mult}},
                Xmult_mod = self.ability.extra.x_mult
            }
        end
    end
``` what, like this?
tacit steppe
#

I was able to get it to working through trial and error

#

For anyone else searching, here is how you use calculate_effect

                -- This joker gives Money
                ease_dollars(card.ability.extra.payout)
                SMODS.calculate_effect {
                    message = localize('$')..card.ability.extra.payout,
                    colour = G.C.MONEY,
                    card = card
                }
                
                -- Then it gives xMult
                return {
                    message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}},
                    Xmult_mod = card.ability.extra.x_mult
                }
urban cipher
#

Anyone here know how to make a simple way to detect if a heart card is destroyed. A joker I am making games +2 mult per heart card destroyed. And I need to know how to detect if a heart card is destroyed.

dim sorrel
#

check canio

urban cipher
outer meadow
#

tbh i'd start by looking at another mod with a joker like this
the way thunk did joker abilities is so weird

#

only ones i can think of though are the lambs in #1239829592693538816, which don't check what the destroyed card is

blazing axle
#

or you can look at how Ship of Theseus works in the ExtraCredit mod

merry elm
raven coyote
#

if you make a new one then you put your mod extension in like j_fn_Eric

merry elm
raven coyote
#

the drop downs?

unique oasis
#

What dropdowns?

outer meadow
#

are you referring to this thing?

proud geyser
outer meadow
#

well, y'know, it's not my footage, but that looks like visual studio code

unique oasis
#

Probably visual studio code + having a decompiled version of balatro and SMODS (when you download it you already have the second one) inside your working directory.

proud geyser
#

i seee....

devout vortex
devout vortex
outer meadow
#

visual studio code just does that with the files in your workspace
(though you'd need more specific files if you want it to define the terms rather than just autocomplete)

merry elm
merry elm
outer meadow
#

yeah this is a default function of visual studio code
put the files in your workspace and it'll autocomplete terms it finds in them
(it's not very smart about doing this, it'll pull from everything equally)

finite glen
#

If you install the lua extension and set up lsp definitions, you can have autocomplete for the SMODS objects

proud geyser
finite glen
#

Uh

#

There's a tutorial somewhere

#

I think it's in the original PR for the lsp_def branch

proud geyser
#

there’s an lsp branch here?

#

oh smods duhh

finite glen
#

Yeah

#

They merged it into main a bit ago, but the actual setup was in the pull request

proud geyser
#

i seee

#

thanks!

restive rivet
proud sage
restive rivet
#

I don't know what a manifest file is, i'm new to lua and don't know much, sorry

proud sage
#

the "main_file" key will point to the file that will have your content

#

that you want to add

#

once you have set that up, you will be able to see it

restive rivet
#

I'll try do this and see of it works, tysm!!

restive rivet
#

It worked!

Tysm, i'll try to make some jokers now!

proud sage
next tree