#💻・modding-dev

1 messages · Page 588 of 1

loud summit
#

and if the list is empty it bails selecting a random one and spawns the default for the set instead

thorn basin
#

and the default one should be the default joker, right?

slim ferry
#

by default cards that are in play anywhere get excluded from the pool

#

excluding enhancements and editions

thorn basin
#

alrighty

wind steppe
#

i dont think playing cards are excluded

slim ferry
#

wdym

#

they definitely are

#

otherwise you would get defaults as soon as you have one of each enhancement

wind steppe
#

no like the base cards

#

if i have a ten of clubs i can still get another ten of clubs

#

from standard packs

slim ferry
#

yeah

#

correct

#

you can

#

because ranks and suits arent even centers so duplicates can appear by default

static valley
#

me when i cardboard

lavish elm
#

how to check if a specific voucher has been redeemed?

#

on a joker

vale grove
#

about this code mr seals,how do i update the local word to be split into 5 (i want to check each individual later to see if every letter is arranged properly for wordle)

#

or alternatively how do i check the first letter of the local

daring fern
vale grove
daring fern
vale grove
#

or well not call

#

but check

daring fern
vale grove
#

thanks

#

one more how do i check joker position?

daring fern
vale grove
#

does this call work the same as with letters?

#

as in my_pos[2] for example?

slim ferry
#

G.jokers.cards[2] is the second joker if thats what you mean

vale grove
#

then what is the point of my_post if you mind me asking

slim ferry
#

my_pos is the position of the joker itself

vale grove
#

so if i want to check the first letter of the joker in the second position do i need my_pos[2} or G.jokers.card[2]

slim ferry
#

G.jokers.cards[2]

#

also my_pos isnt a table its just a number

vale grove
#

weird how in local letters the letters is the table but here it is

#

im learning something new everyday

frail parcel
#

is this how i would do debuffing cards of a certain rank

daring fern
lavish elm
#

how to add joker slots?

vale grove
lavish elm
#

ok thx

slim ferry
#

black deck does it via built-in deck functionality

#

for anything else its G.jokers:change_size(mod)

frail parcel
daring fern
# vale grove would both of these work?
local passed = true
for i=1, #word do
    local joker = G.jokers.cards[i]
    if word:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
end
if passed then
    -- code
end
vale grove
# daring fern ```lua local passed = true for i=1, #word do local joker = G.jokers.cards[i]...
        local letters = {}
        local firstletter = {}

        for i = 1, #word do
            table.insert(letters, word:sub(i, i))
        end
        for i = 1, #word do
            table.insert(firstletter, getJokerName:sub(i, i))
        end

        for i = 1, #G.jokers.cards do
            if G.jokers.cards[i] == card then
                my_pos = i
                break
            end
        end
if context.joker_main and G.jokers.cards[1] then

    if first_letter{1} ==  Letters[1] then
        return { 
            message = "test",
        }
    end
end

i currently have this

#

any reason this would /wouldnt work?

#

besides the second table doing #word twice

daring fern
vale grove
#

besides the 2 fixed typos

#

first_letter and #word on

daring fern
vale grove
#

play wordle with the first letter of the name of the joker

#

(for example runner would be r)

wispy falcon
#

Okay, can someone help me with making blackjack as a boss blind?

daring fern
vale grove
daring fern
vale grove
#

yes

daring fern
# vale grove yes
if context.retrigger_joker_check then
    local passed = true
    for i=1, #word do
        local joker = G.jokers.cards[i]
        if word:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
    end
    if passed then
        return {repetitions = 1}
    end
end
vale grove
#

so lets say the word was READY
you'd need
R unner
E ven steven
A bstract
D elayed gratification
Y orick

#

in that order

vale grove
daring fern
#

Assuming word exists.

vale grove
#

im changing word to G.YA_wordleword

#
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.YA_wordleword = JSON.decode(json).solution
    return g
end

bcs this is how i define the wordle word

#

or do you advice creating a local word = G.YA_wordleword?

lavish elm
#

how to get the variables from vars and use it in calculate?

slim ferry
#

wdym vars

red flower
wispy falcon
lavish elm
frosty rampart
#

this is why value manipulation should have never been invented /j

frosty rampart
ruby delta
#

Hey can you help me, been trying this and it has been almost 9 months now yet I still can't get this working all I want is that the card does what mime joker does but x2 instead of once and it's second function is to give me x10 xmults when I have all my other 4 custom joker card I made j_rwby_....

Now the second function doesn't work it gives me 10x mults even tho if those cards are not there.

slim ferry
#

also you dont have to delete it and resend it

frosty rampart
#

with a message this big, it's so annoying to keep reposting it that people are probably less likely to help you

wispy falcon
ruby delta
ruby delta
slim ferry
#

have you looked at like any vanillaremade joker

#

that does held in hand effects

ruby delta
vale grove
# daring fern ```lua if context.retrigger_joker_check then local passed = true for i=1...
calculate = function(self, back, context)
        local letters = {}
        local firstletter = {}
        
        
        for i = 1, #G.YA_wordleword do
            table.insert(letters, G.YA_wordleword:sub(i, i))
        end
        for i = 1, #firstletter do
            table.insert(firstletter, getJokerName:sub(i, i))
        end

        for i = 1, #G.jokers.cards do
            if G.jokers.cards[i] == card then
                my_pos = i
                break
            end
        end
if context.retrigger_joker_check then
    local passed = true
    for i=1, G.YA_wordleword do
        local joker = G.jokers.cards[i]
        if G.YA_wordleword:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
    end
    if passed then
        return {repetitions = 1}
    end
end
end

when i run this i get an error saying itsays YA_wordleword is a nil value
despite G.YA_wordleword = JSON.decode(json).solution me defining it here

ruby delta
slim ferry
#

oh nevermind

#

i see now

#

you need to do next(SMODS.find_card(...))

daring fern
vale grove
ruby delta
slim ferry
#

wdym how theres not much to do different

daring fern
ruby delta
slim ferry
#

yeah and thats not what i said

#

its next(SMODS.find_card(...))

vale grove
# daring fern Everything other than the code I gave you, it still says `G.modprefix_wordleword...
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.YA_wordleword = JSON.decode(json).solution
    return g
end

im probably just really stupid but i genuinely dont see it?

cursive gazelle
#

Sorry but “Team Bonus !” Is too funny

wispy falcon
daring fern
vale grove
daring fern
ruby delta
# cursive gazelle Sorry but “Team Bonus !” Is too funny

The card is about Team RWBY, and the card has a second function where the other character joker cards are active it give a team bonus 10xmults but yah I can't figure out how to make this joker to detect the other 4 joker and give me 10x mults it's either it doesn't give me or it give me even if the other joker are not there

cursive gazelle
#

You can do

#

And

ruby delta
vale grove
# daring fern No.

then i mustve imagined it, anyway why does it not recognize my G.YA_wordleword = JSON.decode(json).solution
In my deck.lua?

cursive gazelle
#

And call the other function

vale grove
ruby delta
# slim ferry yeah and thats not what i said

Am new I use Smods wiki and learnt Lua a bit to get till here and asked so many people for their option on how to get those function am sorry if am being annoying but I really am confused when u tell me it's next (SMODS.find_card(...))

ruby delta
cursive gazelle
slim ferry
#

capitalization moment

cursive gazelle
#

You lizard lover

ruby delta
slim ferry
#

yes just everything you had before

#

its the exact same but inside next()

cursive gazelle
slim ferry
#

which is
what i was trying to say

cursive gazelle
#

you’re pretty horrible at communicating with people

#

Try sign language next time

ruby delta
ruby delta
#

Thanks both of u let me try and I will come back (am sure I will mess it up)

cursive gazelle
#

Btw ai doesn’t know how to make balatro mods

#

Unless you feed one the entire smods framework

#

And lovely

slim ferry
#

and the entirety of balatro

cursive gazelle
#

Honestly you can make an ai that does that if you have the source code

slim ferry
#

and also it has to even understand lua to begin with when most ai's knowledge ends at python lmao

ruby delta
frosty rampart
ruby delta
cursive gazelle
frosty rampart
slim ferry
#

i mean thats like literally the only thing python is good at besides that its bad at fucking everything

cursive gazelle
ruby delta
frosty rampart
#

check the pinned messages in this channel

lavish elm
#
config = {extra = {extra_Xmult = 2, required_mult = 10, extra_Joker_slot = 1, current_Xmult = 1, current_Joker_slots = 0}}


modify_joker_values(G.jokers.cards[i], {["*"] = mult_rand}, {x_mult = 1, x_chips = 1, card_limit = true, extra_slots_used = true,
                    current_Joker_slots = true})

why is it still tampering with the value

cursive gazelle
#

Interpretive language when the immortal “public class main” walks in

ruby delta
frosty rampart
#

what part of "Discussions regarding the use of AI and AI tools is now strictly prohibited in these channels." encourages you to continue talking about using AI

ruby delta
#
        if context.cardarea == G.play and context.repetition then
            return {
                repetitions = card.ability.extra
            }
        end

        if context.joker_main then
            if next(SMODS.find_card('j_rwby_ruby')) and 
               next(SMODS.find_card('j_rwby_weiss')) and 
               next(SMODS.find_card('j_rwby_blake')) and 
               next(SMODS.find_card('j_rwby_yang')) then
                return {
                    xmult = self.config.team_mult,
                    message = "Team Bonus!",
                    colour = G.C.RED
                }
            end
        end
    end
}```


Now? Better?
slim ferry
#

yeah that works

frosty rampart
ruby delta
# slim ferry yeah that works

There is two more jokers that I have an issue my ruby joker stopped working for some reason now after updating Smods (ya I got bck to this mod after a 3months gap) and keeps on crashing 😭

echo parrot
#

--The Magician? - Discards 3 random cards in hand without spending a Discard
SMODS.Consumable {
    key = 'reverse_magician',
    set = 'Tarot',
    atlas = 'reverse_tarots',
    unlocked = true,
    discovered = true,
    cost = 3,
    pos = {x = 8, y = 2},

    config = { extra = { discards = 3 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.discards } }
    end,

    loc_txt = {
        name = 'The Magician?',
        text = {
            [1] = 'Discards {C:attention}#1#{} random cards in hand',
            [2] = 'without spending a {C:attention}Discard',
        }
    },

    can_use = function(self, card)
        if G.hand.cards then
            return (#G.hand.cards > 0)
        end
    end,

    use = function(self, card, area, copier)
        local not_selected = {}
        local numb_discarded = 0
        for _, playing_card in ipairs(G.hand.cards) do
            not_selected[#not_selected + 1] = playing_card
        end
        for i = 1, 3 do
            if G.hand.cards[i] then
                local selected_card, card_index = pseudorandom_element(not_selected, 'tboj_reverse_magician')
                G.hand:add_to_highlighted(selected_card, true)
                table.remove(not_selected, card_index)
                numb_discarded = numb_discarded + 1
                play_sound('card1', 1)
            end
        end

        G.FUNCS.discard_cards_from_highlighted(nil, true)
        SMODS.draw_cards(numb_discarded)

        return true
    end,

}```

Reverse Magician almost works, but I have a problem that it's not returning discarded cards when it's used in a pack
#

Like the cards are still discarded when you enter a new blind

vale grove
ruby delta
frosty rampart
#

you still left a self.config in the second return, but yea that's better

daring fern
# lavish elm pls help

No, you need to put everything you don't want to be changed in a table called immutable in the config.

lavish elm
daring fern
lavish elm
#

config = {extra = {extra_Xmult = 2, required_mult = 10, extra_Joker_slot = 1, current_Xmult = 1}, immutable = {current_Joker_slots = 0}}

woven topaz
daring fern
lavish elm
#

oh ok thx

daring fern
nova orchid
#

how would i make a blind change your cards when you play them?

daring fern
nova orchid
echo parrot
daring fern
nova orchid
daring fern
nova orchid
#

and i replace "suit" with the suit, right

lavish elm
#

for some reason when changing the values the joker slots go back to 5

#
if context.individual and context.cardarea == G.play and 
        (context.other_card:is_suit("Clubs") or  context.other_card:is_suit("Spades")) then
            card.ability.extra.current_Xmult = card.ability.extra.current_Xmult + card.ability.extra.extra_Xmult
            if card.ability.extra.current_Xmult >= card.ability.extra.required_mult then
                card.ability.extra.immutable.current_Joker_slots = card.ability.extra.immutable.current_Joker_slots + card.ability.extra.extra_Joker_slot
                G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra.extra_Joker_slot
                card.ability.extra.current_Xmult = 1
                return{
                    message = "Upgrade",
                    colour = G.C.IMPORTANT
                }
            end
            return{
                message = "Upgrade",
                colour = G.C.IMPORTANT
            }
        end
daring fern
vale grove
# daring fern No, in the code you sent previously it was still `G.modprefix_wordleword`
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.YA_wordleword = JSON.decode(json).solution
    return g
end

no matter what i seem to do this G.YA_wordleword just is not found in here

SMODS.Back({
    key = "Wordle",
    loc_txt = {
        name = "Monkey with a typewriter",
        text = { "Play the daily wordle",
            "with the first letter",
            "of your jokers",
            "All your jokers retrigger"
        },
    },
    config = {},
    pos = { x = 1, y = 1 },
    atlas = "Jokers",
    unlocked = true,
    calculate = function(self, back, context, word)
        local letters = {}
        local firstletter = {}
        local word = G.YA_wordleword
        
        for i = 1, #word do
            table.insert(letters, G.YA_wordleword:sub(i, i))
        end
        for i = 1, #firstletter do
            table.insert(firstletter, getJokerName:sub(i, i))
        end

        for i = 1, #G.jokers.cards do
            if G.jokers.cards[i] == card then
                my_pos = i
                break
            end
        end
if context.retrigger_joker_check then   
    local passed = true
    for i=1, #G.word do
        local joker = G.jokers.cards[i]
        if #G.word:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
    end
    if passed then
        return {repetitions = 1}
    end
end
end

})

i just cannot figure it out

#

maybe for additional context the first lua file is main.lua and the second is decks.lua

daring fern
vale grove
#

it doesnt recognize g.YA_wordleword

#

in this

        for i = 1, #word do
            table.insert(letters, G.YA_wordleword:sub(i, i))
        end
#

even if i remove local word and just put G.YA_wordleword it also doesnt work

vale grove
tender ermine
#

How would one change the weight of a modded enhancement depending on a variable

slim ferry
#

use get_weight for things that need a weight that changes dynamically

tender ermine
#

I know that, but how would I set the weight? Like do I use self.weight? How would I access the weight variable to set it

slim ferry
#

yeah use self.weight

tender ermine
#

Huh, okay

slim ferry
#

and then whatever other variable that you set to change the weight

wintry solar
#

you return the weight

tender ermine
#

I’ll try

slim ferry
#

yeah

vale grove
vale grove
daring fern
vale grove
# daring fern Yes.

okay so now it doesnt crash my game anymore but still does not work
if #G.YA_wordleword:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
what does name_text need to be? (i want it to check the first letter of the joker name)

daring fern
vale grove
#

today is kinda a bad wordle for testing CIVIL

heavy elm
#

how do i affect the odds that a joker shows up in shop? i want to make a joker with a very small chance of appearing, way smaller than if i were to just make it a rare

daring fern
vale grove
heavy elm
unkempt bronze
#

Hello, everyone. Mister "Trouble_with_mods" is back again, and I have a trouble with mods. Specifically, in one I'm making. See, I have a joker that should randomly add or subtract a rank and randomly change the suit of a duplicated card, but I don't know how to code such a thing. Ideally, the original card isn't altered at all, just the copy.

vale grove
# daring fern It needs to be `name_text`
im trying calculate = function(self, back, context, word)
if context.retrigger_joker_check then   
    local passed = true
    for i=1, #G.YA_wordleword do
        local joker = G.jokers.cards[i]
        if #G.YA_wordleword:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
    end
    if passed then
        return {repetitions = 1}
    end
end
end

is there eanything else i need for this besides the definition of G.YA_wordleword

daring fern
vale grove
daring fern
vale grove
daring fern
vale grove
#

wdym outside of everything?

slim ferry
#

optional features also dont need to be a function

vale grove
slim ferry
vale grove
#

another thingy

#

before i read that

#
calculate = function(self, back, context, word)
    SMODS.current_mod.optional_features = function()
    return {
        retrigger_joker = true,
    }
end
if context.retrigger_joker_check then   
    local passed = true
    for i=1, #G.YA_wordleword do
        local joker = G.jokers.cards[i]
        if #G.YA_wordleword:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
    end
    if passed then
        return {repetitions = 1}
    end
end
end

how do i make each joker message their own first letter at the end of a round

daring fern
slim ferry
topaz berry
#

I have been getting the message 'attempt to index field 'extra' [a nil value] when running if SMODS.pseudorandom_probability(card, 'callosum', 1, card.ability.extra.odds) then in context.before. my config looks like config = { extra = { effects = 1, {}, odds = 2} },. Is there a reason I am card.ability.extra is returning nil?

#

i can post more of the jokers code if it may be relevant

topaz berry
#

oh

#

i see

#

let me check

#

that makes so much sense thank you

crude ermine
#

?

red flower
#

?

slim ferry
#

vivid mesa
#

I had an idea to make Fortunato from The Cask of Amontillado a legendary joker but it turns out he isn't actually a jester, he just wears a jester's clothes for symbolism

frosty rampart
#

do it anyway

cursive gazelle
#

?

vivid mesa
#

So what I thought of for his effect was "stone cards give x3 mult when scored or held in hand, which is kinda bad

frosty rampart
#

I mean that's pretty strong, stone cards aren't too hard to make/find and that makes them both outclass steel cards and kings/queens with triboulet

latent river
#

Doesn anyone know how to enable the high contrast option for custom cards?

vale grove
#
SMODS.Back({
    key = "Wordle",
    loc_txt = {
        name = "Monkey with a typewriter",
        text = { "Play the daily wordle",
            "with the first letter",
            "of your jokers",
            "All your jokers retrigger"
        },
    },
    config = {},
    pos = { x = 1, y = 1 },
    atlas = "Jokers",
    unlocked = true,
    
calculate = function(self, back, context, word)
    
if context.retrigger_joker_check then   
    local passed = true
    for i=1, #G.YA_wordleword do
        local joker = G.jokers.cards[i]
        
        if #G.YA_wordleword:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
        
    end
    if passed then
        return {repetitions = 1}
    end
    if context.end_of_round and context.main_eval then
    local effects = {}
    for i, v in ipairs(G.jokers.cards) do
        table.insert(effects, {message = localize({type = 'name_text', set = v.ability.set, key = v.config.center.key}):sub(1, 1), message_card = v})
    end
    return SMODS.merge_effects(effects)
end
end
end

})

bcs i currently have it like this

calm ember
#
SMODS.Joker{
        cost = 7,
        key = 'snakeJoker',
        loc_txt = {
            name = "Snake",
            text = {
                'A fragile {C:attention}Snek.{}',
                'Everytime you free this snek...',
                'It comes back {C:red}STRONGER.{}',
                'Gains {X:mult,C:white}X1{} mult',
                'each time you find and buy it again',
                '{X:mult,C:white}X#1#{}'
            }
        },
        atlas = 'Jokers',
        pos = {x = 0,y = 0},
        config = { extra = {Xmult = 1}},
        loc_vars = function(self,info_queue,center)
            return {vars = {
                        SnekLevel
                        }
                    }
        end,

Im trying to get it to show a custom number, and when i sell the card the mult increases by 1 the next time i find the card, but the number isnt showing at the bottom of the description of the joker.
the joker effect of selling and buying works fine, just the description is stuck saying "X1" at the bottom

prisma cape
#

how would i get my script to edit an existing balatro function? wanting to export card information when selected

#

or override an existing function* i guess

red flower
#

(next section is hooks)

prisma cape
#

thanks so much

#

can a patch call functions contained in the same script or does the patch execute inside of balatro.exe and therefore couldn't find the reference?

red flower
#

yeah it can

prisma cape
#

this is great news

static valley
#

when iterating through card.ability, how can I tell when I've reached card.ability.extra, if it's even there?

red flower
vale grove
# daring fern ```lua if context.end_of_round and context.main_eval then local effects = {}...
SMODS.Back({
    key = "Wordle",
    loc_txt = {
        name = "Monkey with a typewriter",
        text = { "Play the daily wordle",
            "with the first letter",
            "of your jokers",
            "All your jokers retrigger"
        },
    },
    config = {},
    pos = { x = 1, y = 1 },
    atlas = "Jokers",
    unlocked = true,
    
calculate = function(self, back, context, word)
    
if context.retrigger_joker_check then   
    local passed = true
    for i=1, #G.modprefix_wordleword do
        local joker = G.jokers.cards[i]
        
        if #G.YA_wordleword:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
        
    end
    if passed then
        return {repetitions = 1}
    end
    if context.end_of_round and context.main_eval then
    local effects = {}
    for i, v in ipairs(G.jokers.cards) do
        table.insert(effects, {message = localize({type = 'name_text', set = v.ability.set, key = v.config.center.key}):sub(1, 1), message_card = v})
    end
    return SMODS.merge_effects(effects)
end
end
end

})

for today im leaving it at this, the displaying at the end of round works (although not in the wordle colour format but thats an issue for later) the retriggering doesnt work yet

hidden oak
#
SMODS.Atlas {
    key = "Blazing",
    path = "Blazing.png",
    px = 71,
    py = 95
}


SMODS.Joker {
    key = 'findyouroneway'
    loc_txt = {
        name = 'Find Your One Way'
        text = {
            "Hands of your most played"
            " {C:attention}poker hand{} gain {X:mult,C:white}X5{} Mult."
            "Other hands do not score."
        }
    }
    config = { extra = { Xmult = 5 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.xmult } }
    end
    rarity = 3
    atlas = 'Blazing'
    pos = { x = 0, y = 0 },
    cost = 6,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                Xmult_mod = card.ability.extra.Xmult,
                message = locaize { type = 'variable', jey = 'x_mult', vars = { card.ability.extra.xmult } }
            }
        end
    end
}
#

I've never done any sort of coding before (outside of scratch) so forgive me if this is an easy question, but i can't figure out what this crash explanation means

#

from what i understand it has the correct closing bracket where it wants them

#

could someone help me understand?

red flower
#

you're missing commas in the text

#

between each string

#

also after the name

#

also after a bunch of other stuff

hidden oak
#

oh alright

#

so like this then?

SMODS.Atlas {
    key = "Blazing",
    path = "Blazing.png",
    px = 71,
    py = 95
}


SMODS.Joker {
    key = 'findyouroneway',
    loc_txt = {
        name = 'Find Your One Way',
        text = {
            "Hands of your most played",
            " {C:attention}poker hand{} gain {X:mult,C:white}X5{} Mult.",
            "Other hands do not score."
        }
    }
    config = { extra = { Xmult = 5 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.xmult } }
    end,
    rarity = 3,
    atlas = 'Blazing',
    pos = { x = 0, y = 0 },
    cost = 6,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                Xmult_mod = card.ability.extra.Xmult,
                message = locaize { type = 'variable', key = 'x_mult', vars = { card.ability.extra.xmult } }
            }
        end
    end
}
maiden phoenix
#

It will highlight errors like missing commas

hidden oak
#

i'm just using base vs code

maiden phoenix
#

Ah, without any lua extension?

hidden oak
#

i didnt know there were extensions

red flower
hidden oak
red flower
maiden phoenix
#

You can click on this button in VSC and get this extension

hidden oak
#

thank you both so much

quick prairie
#

does anyone have an example of how to make a joker that targets the probability only on specific random groups? like if i wanted to make an oops but specifically for lucky cards

hidden oak
#

ok the Xmult part works but it says error instead of X5 when it activates

faint yacht
#

return { xmult = ... }

frosty rampart
# quick prairie does anyone have an example of how to make a joker that targets the probability ...

i don't have an example but i can explain how to
as per the documentation in the smods 0711 release notes, every probability roll has an identifier, which you can get as context.identifier
to figure out which one(s) you want, do if context.mod_probability then print(context.identifier) end in your joker's calculate code and then have the relevant probability run so you can see what prints. make sure you have debugplus so you can see the console in-game
once you know what identifier you're looking for, check if the probability roll is for that identifier in your context checks

quick prairie
#

any chance the identifier is the same as the probability key? im using joker forge to try and make the bulk of my mods, and im so lazy i dont want to consider making a joker outside of it to then adding everything back in to the main mod and editing the atlas or whatever. ill probably end up doing it anyway if i have no other option though

nova orchid
#

how do i instantly destroy a joker with no animation, i want to make it so that 2 j_otm_magnetictile jokers coagulate into a j_otm_magnetictower joker, i have this so far:

calculate = function(self, card, context)
    if context.card_added and context.cardarea == G.jokers then
        local new_card = context.card
    end
end
plucky berry
#

guys what's the command for ^mult

#

I'm trying Emult but it's not working

#

looked in the cryptid files and it's using both Emult and emult I don't understand

frosty rampart
#

you need talisman for emult to work

#

it's not built into smods

nova orchid
#

or you might be able to do Xmult with the current amount of mult or exponetilized further (X * X = X^2, X * X^2 = X^3, etc.)

plucky berry
#
    key = "sodalite",
    unlocked = true,
    discovered = true,
    atlas = "jokers",
    blueprint_compat = true,
    rarity = 3,
    cost = 8,
    pos = { x = 1, y = 1 },
    config = { extra = { odds = 3, Emult = 1.1 } },

    loc_vars = function(self, info_queue, card)
        local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'napoli_sodalite')
        return { vars = { numerator, denominator, card.ability.extra.Emult } }
    end,

    calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play and context.other_card and context.other_card.base
           and context.other_card.base.suit == "napoli_spade"
           and SMODS.pseudorandom_probability(card, 'napoli_sodalite', 1, card.ability.extra.odds) then
            return {
                Emult = lenient_bignum(card.ability.extra.Emult)
            }
        end
    end
}```
#

this is my code it's to make a joker like bloodstone with ^mult

#

napoli_spade is my custom suit

#

made the same code for another jocer with xchips and it works

nova orchid
#

is anybody gonna help me with mine

plucky berry
#

i'd help you if i knew how to

hidden oak
#

How would i use this section of code from VanillaRemade's wiki

-- Similar to The Ox
local _handname, _played = 'High Card', -1
for hand_key, hand in pairs(G.GAME.hands) do
    if hand.played > _played then
        _played = hand.played
        _handname = hand_key
    end
end
local most_played = _handname

to activate this card

SMODS.Joker {
    key = 'findyouroneway',
    loc_txt = {
        name = 'Find Your One Way',
        text = {
            "Hands of your most played",
            " {C:attention}poker hand{} gain {X:mult,C:white}X5{} Mult.",
            "Other hands do not score."
        }
    },
    config = { extra = { Xmult = 5 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.xmult } }
    end,
    rarity = 3,
    atlas = 'Blazing',
    pos = { x = 0, y = 0 },
    cost = 6,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                Xmult_mod = card.ability.extra.Xmult,
                message = "Step it, Buddy!"
            }
        end
    end
}

only when the most played hand is played

nova orchid
#

how do i instantly destroy a joker with no animation, i want to make it so that 2 j_otm_magnetictile jokers coagulate into a j_otm_magnetictower joker, i have this so far:

calculate = function(self, card, context)
    if context.card_added and context.cardarea == G.jokers then
        local new_card = context.card
    end
end
red flower
hidden oak
#

Thank you

nova orchid
#

.

#

can anyone help me T .T

red flower
#

if nobody replies is because 1) there's nobody here, 2) they don't know, 3) they don't want to help rn
spamming the channel won't make people help faster (ive seen you do this multiple times now)

clear ocean
nova orchid
#

i think it's

SMODS.Back { stuff here }

not

SMODS.Back( { stuff here} )

but i may be wrong

clear ocean
#

i don't think that is the issue but i can try just to cross it out

nova orchid
#

here's an example i have

clear ocean
#

same error it isn't that. i didn't think it was that, but it didn't hurt to try

#

maybe try with only one voucher

#

yeah it is because its a table. but is there a way to make it where it starts with two vouchers?

winter flower
#

how do i make it so that if there's a specific blind present
something like let's say the music changes to something else

clear ocean
#

looking at cardsleeves it might just be where vouchers only do one maybe thats because thats how balatro was coded or balancing which i guess is fair since you do start off with a voucher

nova orchid
#

have you checked this

clear ocean
#

i actually tried that with adding the apply before reading the top comment and doing +2

#

might be showing how it wouldve been implentanted if it wasnt config done

#

which one do you prefer when you dual play with the sleeve and deck all star? hone or out the park

high verge
#

Working on my own design for cards

#

Faces placeholders

#

Interesting. If you have an enhanced card it just uses the shadow of that

clear ocean
#

thats actually kinda cool

#

having a border around it

high verge
#

So guess that means even regular ones are only using the card back for the shadow

clear ocean
#

i think there's a variable or function to disable the shadow if needed

high verge
#

Yeah since my design covers a good chunk of the card I figure I'd have to make custom enhancers so they'll actually show up xD

#

Oh no the shadow is fine it's just something interesting to notice

fickle vale
#

does anyone know how I could set the level of a specific hand to lvl 4 from the start of the game? (I have a deck that I want to have high card start at level 4)

#

besides giving myself 4 plutos

clear ocean
#

i think there are either two ways: some config that i don't know of that does that or an apply function that levels up

#

you could look at space joker

#

SMODS.smart_level_up_hand(card, "High Card", true) and there is either another argument or you can just do a for loop four times

#

okay the sleeve combo might be cracked 😭

#

rerolling its was just a lucky pull of rares and editions but uncommon/rares and editions appear which is the point of the vouchers which does work

#

not too worried of the sleeve combo since you will need to play with the sleeves mod idk

#

you decide on that

#

yeah after rerolling its i think balanced enough and more of a fun deck to play around with

#

yeah its a fair deck tested with sleeve and red deck

clear ocean
#

since i made an edition, its only natural to make a tag

feral tree
#

what's wrong with this? trying to make it so planet cards dont take up any consumable slots in a joker

harsh belfry
#

what is rares default_weight?

vocal helm
#

How would I apply a shader effect to a Joker that shifts its pixels (i.e. a wave shader) without it going past its card size in the canvas? Right now the shader I've got draws itself normally and then applies a copy of itself with the shader that kinda bypasses into other parts of the atlas

loud summit
#

hey so when youre directly calling level_up_hand to level a custom hand

#

do you use the key of the hand instead

frosty rampart
#

it can take either the key or the poker hand object itself i think

loud summit
#
local ref_levelup = level_up_hand
function level_up_hand(card, hand, instant, amount, ...)
   if next(SMODS.find_card("j_nflame_genplanet")) and hand ~= "nflame_generic" then
      level_up_hand(card, "nflame_generic", instant, 1)
   end
   return ref_levelup(card, hand. instant, amount, ...)
end
``` ok am i doing this right
frosty rampart
#

not quite
you've got the right idea but the hook is a bit wrong

harsh belfry
#

you are doing a bit of recursion

loud summit
#

thats what i was worried of :(

#

oh wait do i call ref_levelup in the inner one too

frosty rampart
#

yes

#
local ref_levelup = level_up_hand
function level_up_hand(card, hand, instant, amount, ...)
   if next(SMODS.find_card("j_nflame_genplanet")) and hand ~= "nflame_generic" then
      ref_levelup(card, "nflame_generic", instant, amount, ...)
   end
   return ref_levelup(card, hand, instant, amount, ...)
end

also pass amount instead of 1, unless that was intentional

loud summit
#

hmm... trying to thinnk if that would be balanced lol

frosty rampart
#

what's the mechanic here exactly

harsh belfry
frosty rampart
#

oh right forgot the return

loud summit
harsh belfry
#
local ref_levelup = level_up_hand
function level_up_hand(card, hand, instant, amount, ...)
   if next(SMODS.find_card("j_nflame_genplanet")) and hand ~= "nflame_generic" then
      ref_levelup(card, "nflame_generic", instant, amount, ...)
      return ref_levelup(card, hand, true, amount, ...)
   end
   return ref_levelup(card, hand, instant, amount, ...)
end

heres what you would do if you wanted it to level both but not show the original level up (if instant is what i think it is)

loud summit
#

ohh thats what instant means

#

yea i probably want that

frosty rampart
#

ah ok
intuitively i'd say let the amount pass through, especially since i don't think there's any vanilla content that does more than 1 level up at a time. balance wise i'd only cap it if there's an easy way to level up a hand by multiple levels at once in your mod

loud summit
#

i havent made something like that

#

yet

#

ok its still erroring

#

indexing nil with key level

vocal helm
mild bronze
#

Justymakeit wigly

vocal helm
#

is this a case of adding a DrawStep

#

if editions can disable_base_shader, can Jokers do that too

loud summit
quick prairie
#

so i managed to get the mod to not crash, but the jokers and tarots i made dont appear in collections. is there perhaps a common reason why?

hidden mirage
#

how to juice up the deck

daring fern
hidden mirage
plucky berry
#

how do you set your mod icon?

faint yacht
#

SMODS.Atlas{key = "modicon", path = "modicon.png", px = 32, py = 32}

hidden oak
plucky berry
#

tnx!

#

im also having trouble implementing emult even if i have talisman on

#

tried making a bloodstone like joker and it works if i put x_chips but it doesn't trigger with Emult

gaunt thistle
sterile lotus
#

I'm tryin' to check before scoring a hand if the played cards are hearts. I'm trying it on a for k, v in ipairs(context.scoring_hand) block. Does anyone know how can I access to the suit property, and compare it to the Hearts value? quq

daring fern
sterile lotus
#

Thanks!

shell timber
gaunt thistle
shell timber
#

egui makes it crossplatform right

gaunt thistle
#

yep!

#

really easy to make crossplatform

meager quiver
#

oops didnt realize that was old

#

i was behind on a ton of messages

meager quiver
hardy viper
long sun
#

is there a way to specify that a draw step shouldn't be overridden by Holographic / Polychrome / Negative?

#

my Jokers with extras lose their extras if they're any of those

hardy viper
long sun
#

it at least doesn't appear

#

lemme grab an example

manic rune
#

is it possible to make cards transparent

long sun
#

regular

vale grove
#
SMODS.Back({
    key = "Wordle",
    loc_txt = {
        name = "Monkey with a typewriter",
        text = { "Play the daily wordle",
            "with the first letter",
            "of your jokers",
            "All your jokers retrigger"
        },
    },
    config = {},
    pos = { x = 1, y = 1 },
    atlas = "Jokers",
    unlocked = true,
    
calculate = function(self, back, context, word)
    
if context.retrigger_joker_check then   
    local passed = true
    for i=1, #G.modprefix_wordleword do
        local joker = G.jokers.cards[i]
        
        if #G.YA_wordleword:sub(i, i) ~= localize({type = 'name_text', set = joker.ability.set, key = joker.config.center.key}):sub(1, 1) then passed = false end
        
    end
    if passed then
        return {repetitions = 1}
    end
    if context.end_of_round and context.main_eval then
    local effects = {}
    for i, v in ipairs(G.jokers.cards) do
        table.insert(effects, {message = localize({type = 'name_text', set = v.ability.set, key = v.config.center.key}):sub(1, 1), message_card = v})
    end
    return SMODS.merge_effects(effects)
end
end
end

})

hey yall, im trying to make a deck where you have to play wordle with the first letter of your jokers, now theres alot of things wrong with this but currently im trying to get the right colour sceme down
(for those who dont know,if a letter isnt in the wordle its gray
if the letter is in the wordle but not in the right space its orange
and if the letter is in the wordle and on the right space its green

long sun
#

busted

vale grove
#

now currently im just trying to change the colour in general which is also giving me a hard time

daring fern
manic rune
long sun
vale grove
manic rune
#

wuh

long sun
#

what do you need the transparency for?

manic rune
#

not really, the joker's sprite has a gap in the middle

#

i want to have the joker fade away

long sun
#

ah

#

you'd probably either need to make an animation, or a shader

vale grove
manic rune
#

it has to be for all jokers, too

manic rune
#

i want to make this ui fade away after about 2 seconds or so

long sun
manic rune
#

dang it

#

3:

#

yeah thanks, im gonna opt for my alternative which is to pull the ui back to the right then lmao

long sun
manic rune
#

it would be hard to sync the shader with the transparency of the ui box otherwise

#

-# not me making up excuses since i dont know SHIT about shaders :3

long sun
#

-# BASED and TRUE and COMMON thought

#

-# SHADERS are AWFUL

daring fern
# long sun

You're drawing the sprite under the edition.

manic rune
#

-# so true

long sun
#

wait, so how are the editions rendered then?

#

does the edition affect the extra if it's rendered before it?

daring fern
long sun
#

oh i see

#

do i have to add edition logic to the extra?

daring fern
long sun
#

grand, thanks ^^

latent river
long sun
#

is the sheet transparent?

#

it must be for the enhancements to show underneath

latent river
long sun
#

can i see the sheet?

latent river
#

hold on

gaunt thistle
long sun
latent river
#

ah mb

long sun
#

allg ^u^

#

explodes

vocal helm
#

i wonder how @/thewintercomet does it, would mention her but idk if that'd be unwarranted

#

mods get its ass

#

<@&1133519078540185692>

#

thank you :>

daring fern
# long sun

No, you should do the edition in the one where you're drawing it.

long sun
#

Ohhhh I see

#

Will try that when I get home

thorn basin
#

how can I make by boss blind trigger the effect after all the cards and jokers triggered?
(like crimson heart does)
((cuz rn my boss blin's effect triggers after you chose the playing cards))

daring fern
thorn basin
daring fern
thorn basin
#

both functions or one of them?

daring fern
thorn basin
thorn basin
#

aight

thorn basin
wispy falcon
#

Which of these is for what things?

button.nodes[1].nodes[1].config.ref_table = G.GAME
button.config.button = nil
button.config.func = nil```
red flower
ashen drift
#

where can i check if a run is seeded or not

red flower
ashen drift
#

alr

wispy falcon
# red flower that just seems to clear out some values for a button, for the specifics you wou...

Here's the whole hook:

function create_UIBox_buttons()
    local t = old_buttons()
    if G and G.GAME and G.GAME.blind.config.blind.key == 'bl_cstorm_the_riddler' then
        local index = 3
        if G.SETTINGS.play_button_pos ~= 1 then
            index = 1
        end
        local button = t.nodes[index]
        button.nodes[1].nodes[1].config.text = "Test"
        button.nodes[1].nodes[1].config.ref_value = nil
        button.nodes[1].nodes[1].config.ref_table = G.GAME
        button.config.button = nil
    end
    if G and G.GAME and G.GAME.blind.config.blind.key == 'bl_cstorm_the_riddler' then
        local index = 1
        if G.SETTINGS.play_button_pos ~= 1 then
            index = 3
        end
        local button = t.nodes[index]
        button.nodes[1].nodes[1].config.text = "Test2"
        button.nodes[1].nodes[1].config.ref_value = nil
        button.nodes[1].nodes[1].config.ref_table = G.GAME
        button.config.button = nil
        button.config.func = nil
    end
    return t
end```
queen meadow
#

is there an evaluation for when a card is discarded in JokerDisplay?

red flower
queen meadow
red flower
#

jokerdisplay is not meant to run calculations like that

#

save it in the joker and then display that value

#

i.e. the one in loc_vars

queen meadow
#

dang aight i'll do it like ramen instead

#

(displaying just the xmult)

red flower
#

i don't understand what other than displaying the xmult is there

wispy falcon
dusty fractal
#

How would I grab a specific element from the hand in relation to a scored card?

#

I’m trying to just make a list of all the scored cards and go one down the list

#

But I’m struggling to access my card itself to check

queen meadow
#

actually i guess this could also work

hallow slate
#

How would I change the SMODS src/ui lua file?

manic rune
#

gimme a sec

manic rune
#

put this in the target

hallow slate
#

Excellent, thanks!

thorn basin
#

why my joker doesn't seem to activate for unscored cards?

frosty rampart
#

not context.scoring_hand isn't how you check if a card is unscored

thorn basin
#

what is the context for checking if a card is scored?

frosty rampart
#

there isn't a dedicated context
you just have to check if context.other_card is contained in context.scoring_hand or not

thorn basin
#

I'm kinda confused...

frosty rampart
#

context.scoring_hand is a table of cards

slim ferry
#

context.individual doesnt get called for unscoring cards anyway, you should be using context.destroy_cards for this

frosty rampart
#

oh right

wispy falcon
slim ferry
#

yeah

#

and then you just need to do a for loop over context.scoring_hand to check if the card was scoring or not

frosty rampart
#

i think destroy_cards actually has a special "unscored" cardarea

#

might be an optional feature

slim ferry
#

yeah

#

except the optional feature enables the unscored area for like everything

thorn basin
slim ferry
#

...no

thorn basin
#

no wait

slim ferry
#

thats not how not works

thorn basin
#

without the "not"

slim ferry
#

yeah

thorn basin
slim ferry
#

you use the for loop to check if the card isnt scoring

#

not

#

whatever that is

thorn basin
#

but how can I check if the card isn't scoring?

slim ferry
#
local unscoring = true
for _, v in ipairs(context.scoring_hand) do
  if v == context.other_card then
    unscoring = false
    break
  end
end
thorn basin
#

so you use a local variable to determine if the card is unscored

slim ferry
#

huh

red flower
#

it was for like a version a year ago

slim ferry
#

wtf

slim ferry
#

you can just do context.cardarea == "unscored" apparently

#

i think thats the correct thing

thorn basin
#

oh so

red flower
#

also SMODS.in_scoring exists

slim ferry
#

wha

#

damn

red flower
#

although it is literally just that same loop

thorn basin
#

ah so like this then

red flower
#

destroy_card*

#

also other_card doesnt exist in it

thorn basin
#

oh true

#

gotta remove it

thorn basin
modest cradle
#

Okay hear me out

#

Joker that says it will give x10000 mult

#

But

#

When the next hand is played it turns into a ditto that does nothing

thorn basin
#

((i don't think this is the best channel to ask that))

unkempt bronze
#

And hear me out
Joker that changes the background music
How do I code such a thing?

red flower
thorn basin
#

aight

unkempt bronze
#

Do i just slot my music in the .ogg spot?

red flower
modern kindle
#

Its N my goat

wispy falcon
#

Why do the buttons only work once?

    local index = math.random(1, #G.hand.cards)
    SMODS.destroy_cards(G.hand.cards[index])
end

function G.FUNCS.draw_a_card(e)
    SMODS.draw_cards(1)
    e.config.button = 'draw_a_card'
end

local old_buttons = create_UIBox_buttons
function create_UIBox_buttons()
    local t = old_buttons()
    if G and G.GAME and G.GAME.blind.config.blind.key == 'bl_cstorm_the_riddler' then
        local index = 3
        if G.SETTINGS.play_button_pos ~= 1 then
            index = 1
        end
        local button = t.nodes[index]
        button.nodes[1].nodes[1].config.text = "Test"
        button.nodes[1].nodes[1].config.ref_value = nil
        button.nodes[1].nodes[1].config.ref_table = G.GAME
        button.config.button = 'draw_a_card'
        button.config.func = nil
    end
    if G and G.GAME and G.GAME.blind.config.blind.key == 'bl_cstorm_the_riddler' then
        local index = 1
        if G.SETTINGS.play_button_pos ~= 1 then
            index = 3
        end
        local button = t.nodes[index]
        button.nodes[1].nodes[1].config.text = "Test2"
        button.nodes[1].nodes[1].config.ref_value = nil
        button.nodes[1].nodes[1].config.ref_table = G.GAME
        button.config.button = 'destroy_a_card'
        button.config.func = nil
    end
    return t
end```
#

Sorry for that wall OwO

ashen drift
#

how can i unfuck this

#

the 2nd text input window uses create text input and supposedly "there can just be only one idless input"

#

how do i assign an id to the thing returned by create text input

red flower
#

im about to play fftactics..

prisma cape
#

is there a place i can view the parameters of an object?

modern kindle
#

I hope it's epic

prisma cape
#

currently making a hook and i want that hook to return the name of the card and also whether that card is negative. assuming it will be something like card.joker.edition but i want to know exactly what the reference is

red flower
#

you can also print a cards info with debugplus

prisma cape
#

i have debugplus, how do i do that?

#

also thanks, i'll take a look

red flower
#

open the console, hover over the card and type eval dp.hovered

prisma cape
#

awesome

ashen drift
queen meadow
#

finally implemented JokerDisplay on all of my jokers that need it

#

(took me a whole day to figure it out)

thick wren
#

is there just like a massive list of all the base game keys to refer to somewhere

queen meadow
thick wren
#

much obliged 💜

queen meadow
thick wren
#

ok i thought different types of consumables had their own prefixes i was doing "t_wheel_of_fortune"

#

okay working :)

#

is there a way to get rid of the extra edition ones

sonic cedar
#

masterpiece

queen meadow
#

i have no guthib page btw

red flower
tepid crow
#

the table is a tad outdated

queen meadow
#

yeah because my mod is not listed 🤓

#

yeah i'm js gonna stop

long sun
#

okay i tried moving the edition inside the extra drawstep, but no dice

wispy falcon
long sun
#

i think both buttons have a one_press attribute, or so-named

wispy falcon
#

How do I change that?

long sun
#

you could set it to nil

#

though i'd inspect the table first to find what that attribute is actually called

long sun
#

add print(inspect(button))

wispy falcon
#

Yeah, it's called one_press

#

Thank you >W<

long sun
#

yay!! np :D i hope it works!

prisma cape
#

how do i sell a card?

long sun
#

there should be a wee button that does that <3

#

/silly /i can check

#

okay try:
G.FUNCS.sell_card({ config = { ref_table = card_you_want_to_sell } })

#

unless smods has a handier way

prisma cape
#

if there is i can't find it

wispy falcon
#

Okay, now the scary thing... How do I make a UI pop-up when the button is pressed?

long sun
#

OMGOMGOMG guess who finally got my card extra drawstep working!!!!! >:3

#

i'm actually the best

#

my fellows are back pleading

prisma cape
#

love the art!

long sun
#

just ignore whatever the fuck's happening down here and you'll be fine :333

#

(i know what caused this)

long sun
wispy falcon
long sun
#

at lastttttt 😩

#

now i can get back to balance patching 😭

long sun
#

oh and arguably the best polychrome is back >:3

prisma cape
#

right is this going to do what I want it to?

wispy falcon
topaz berry
#

I'm wanting to make a joker that does something if the current number of scored chips is equal to a number. Is there a way to check for the current number of scored chips in context.after?

frosty rampart
#

SMODS.calculate_round_score()

topaz berry
#

thank you

hallow slate
#

Is there a way to get the mult and chips HUD to show negative numbers?

red flower
#

also SMODS.find_card is always truthy

topaz berry
red flower
#

and it will crash if it has no edition because newJoker.edition will be nil

prisma cape
#

thank you, i'll add in some checks

red flower
#

and G.jokers is not a list

#

G.jokers.cards is, and i don't think ipairs works like that

frosty rampart
topaz berry
#

Thank you

prisma cape
red flower
#

yeah ipairs is used in for loops usually

#

i would read a bit of lua basics as well

wispy falcon
plucky berry
#

guys can someone help me fix my modded joker? it's supposed to be like bloodstone but with ^mult, (i have talisman on and i edited the code from bloodstone in vanilla remade) but the ^mult never triggers, even if i make it full odds

#

i can send the code if needed

slim ferry
#

yeah definitely send the code people cant help you without code

plucky berry
#
    key = "sodalite",
    unlocked = true,
    discovered = true,
    atlas = "jokers",
    blueprint_compat = true,
    rarity = 3,
    cost = 8,
    pos = { x = 1, y = 1 },
    config = { extra = { odds = 3, Emult = 1.1 } },

    loc_vars = function(self, info_queue, card)
        local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'napoli_sodalite')
        return { vars = { numerator, denominator, card.ability.extra.Emult } }
    end,
    calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play and context.other_card.base and context.other_card.base.suit == "napoli_spade" and
            SMODS.pseudorandom_probability(card, 'napoli_sodalite', 1, card.ability.extra.odds) then
            return {
                Emult = card.ability.extra.Emult
            }
        end
    end
}```

napoli_spade is my custom suit
slim ferry
#

i dont think the e in emult should be capitalized

#

for the return

plucky berry
#

if I use any other talisman scoring effect like x_chips it works

slim ferry
#

i mean xchips isnt from talisman

#

thats just an smods thing

plucky berry
slim ferry
#

also

#

you should do context.other_card:is_suit("napoli_spade") instead

wispy falcon
plucky berry
#

i will try but i think using is_suit crashed me already

slim ferry
#

if is_suit is crashing you then youre definitely doing something else wrong

#

it has no reason not to work

hallow slate
#

Is there any way to add a feature for showing negative mult?

slim ferry
plucky berry
slim ferry
#

what does the code look like now

#

and also the code for your suit

plucky berry
#

suit key is right

#
    key = "sodalite",
    unlocked = true,
    discovered = true,
    atlas = "jokers",
    blueprint_compat = true,
    rarity = 3,
    cost = 8,
    pos = { x = 1, y = 1 },
    config = { extra = { odds = 3, emult = 1.1 } },

    loc_vars = function(self, info_queue, card)
        local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'napoli_sodalite')
        return { vars = { numerator, denominator, card.ability.extra.emult } }
    end,
    calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play and context.other_card.base and context.other_card:is_suit("napoli_spade") and
            SMODS.pseudorandom_probability(card, 'napoli_sodalite', 1, card.ability.extra.odds) then
            return {
                emult = card.ability.extra.emult
            }
        end
    end
}```
wispy falcon
slim ferry
plucky berry
#

yes, otherwise everything else wouldn't work

slim ferry
#

yeah true

plucky berry
#

i could implement my own exponential mult i guess but i wouldn't know how to

#

could it maybe be an issue of mod priority?

slim ferry
#

shouldnt be

#

as long as the emult stuff is loaded at all it should work

plucky berry
#

well idk how to troubleshoot this

slim ferry
#

try removing the check for context.other_card.base i guess? i doubt thats the issue but not like its needed anyway

plucky berry
#

still nothing

hidden oak
#

does anyone know how i can cause a joker to disable scoring for a hand?

#

similarly to a boss blind

wispy falcon
quick prairie
#

does anyone have an example or can help with how to make a custom enhancement increment mult each time the same enhancement is scored? but reseting after the hand plays

red flower
#

check vanillaremade blinds

#

(you can use it on jokers)

hidden oak
#

oh awesome

#

i was looking at blinds but i assumed all that stuff was exclusive to them

wispy falcon
red flower
#

all the calculate stuff you can use anywhere

hallow slate
#

Is there a list of align codes

#

for text alignment and stuff

frosty rampart
#

in the uhh UI guide page on the SMODS wiki

split cairn
#

how can I make consumable destroy a specific joker when the consumable is used? what do i put in the "use" section of the code?

lavish elm
#

I have a joker that applies enhancements but the problem is that
the enhancements don't take effect after being applied
current condition:
if context.cardarea == G.play and context.individual and not context.blueprint_card then

wispy falcon
split cairn
lavish elm
frosty rampart
#

check midas mask vanillaremade

#

context.individual is run for each scored card individually, whereas context.before just runs once

split cairn
#

how can i destroy a specific joker by using a consumable?

lavish elm
#

ok thx

slim ferry
#

main_eval changes literally nothing

frosty rampart
frosty rampart
#

SMODS.destroy_cards(SMODS.find_card("j_modprefix_jokerkey")) will destroy all copies of the joker, if the player has any (replace modprefix with the relevant mod's prefix (you don't need one if it's a vanilla joker), and replace jokerkey with the key of the relevant joker)

#

and if you only want the consumable to be usable if the joker in question exists, do this for the can_use function: return next(SMODS.find_card("j_modprefix_jokerkey"))

hidden oak
#

in the way that it could set debuff_hand to true

red flower
#

this one is for disallowing a hand

hidden oak
#

oh ok

#

so then i would set the hand to be debuffed with

debuff_hand = not 'ph_most_played'
``` ?
#

or wait actually would it be G.GAME.current_round.most_played_poker_hand

prisma cape
#

whats the best way to register a keybind? I want a specific function to start and stop on a key press

frosty rampart
#

SMODS.KeyBind
it's not really documented, but this example built into smods binds "Alt + F5" to restarting the game

red flower
#

did you read the code for how the blinds do it

wispy falcon
austere oasis
#

can someone help me with this? dont mind the mods though i was trying to make something

slim ferry
hidden oak
# red flower did you read the code for how the blinds do it

i did, but i dont think i understand enough to implement it into the joker's code

calculate = function(self, card, context)
        if context.joker_main then
            local _handname, _played = 'High Card', -1
            for hand_key, hand in pairs(G.GAME.hands) do
                if hand.played > _played then
                    _played = hand.played
                    _handname = hand_key
                end
            end
            local most_played = _handname
            if most_played == context.scoring_name then
                return {
                    message = "Step it, Buddy!",
                    Xmult_mod = card.ability.extra.Xmult}
            end
            if most_played ~= context.scoring_name then
                if context.debuff_card then
                    return {debuff = true,
                    message = "Tch, pathetic."}
                end
            end
        end

I took code from the pillar and removed the part that checked if a card was already played this ante, i cant seem to get it to trigger at all

red flower
#

well first i said debuff_hand not debuff_card

#

but joker_main and debuff_card cant be combined

#

(or debuff_hand)

#

you need to use them in separate if conditions

hidden oak
#

Oh, alright

hidden oak
#

Thank you for your help, it finally works!
The only issue i'm having is it says the message any time you select cards that are the wrong hand instead of when you submit the hand, but I think i can figure out how to fix it

red flower
#

i think it's not context.check

#

or something like that

hidden oak
#

yeah that worked 👍

prisma cape
#

'''SMODS.Keybind {
key_pressed = 'f5',
event = 'pressed',
action = function(self)
start_or_end_loop()
end
}'''

#

any idea why this is causing me issues?

#

also mb formatting problems

#

nil value error

#

but idk why because my settings.json is fine

red flower
#

what's the crash log

prisma cape
#

this is just in the debugger

#

"attempted to index a nil value (global 'SMODS')"

#

using vscode

red flower
#

oh the vscode debugger?

prisma cape
#

yes

red flower
#

it can't run balatro code

prisma cape
#

but i have the lua debug extension installed

red flower
#

you run all the code in game

prisma cape
#

assuming there isn't a debugger mod for balatro?

red flower
#

no

prisma cape
#

nvm the error log is pretty comprehensive

red flower
#

there are mods that help debug like debugplus and balatest

static valley
#
    calculate = function(self, card, context)
        if (context.post_trigger and context.other_card == card)
        or (context.main_scoring and context.cardarea == G.play)  
        then
            card.edition.extra.money = card.edition.extra.money + card.edition.extra.money_gain
            return {
                message = "+" .. card.edition.extra.money_gain,
                colour = G.C.MONEY
            }
        end
        if context.end_of_round and card.edition.extra.money >= 1 then
            return {
                p_dollars = card.edition.extra.money,
                message = "reset",
                colour = G.C.FILTER,
                func = function()
                    card.edition.extra.money = 0
                end
            }
        end
    end

this works when a card with the edition scores, but not when a joker is triggered. how do I fix this problem?

prisma cape
#

anyway still getting a nil value error in game, this function isn't working: function use_card(currentCard) currentCard:use_consumeable() end

#

here's how i'm getting currentCard: use_card(SMODS.find_card("c_judgement"))

red flower
red flower
static valley
#

(obviously the amount of money stored resets afterward)

red flower
#

other_card == card means when itself is triggered

static valley
#

is that why it's not doing anything for jokers?

red flower
#

what is this? a joker? an enhancement?

red flower
static valley
#

an enhancement

red flower
#

yeah that's always false then

static valley
#

after removing that part it still does nothing

red flower
#

did you enable the optional feature

#

idk if enhancements get post_trigger honestly

static valley
frosty rampart
#

maybe i'll PR it if i'm happy with how it comes out

red flower
frosty rampart
#

ohh

red flower
static valley
red flower
#

no

#

it needs to be exactly that

mossy quest
#
    SMODS.Joker:take_ownership( v ,
        { -- table of properties to change from the existing object
        discovered = false
        },
        true -- silent | suppresses mod badge
    )
end```
This was working last time I played Balatro, but now it's broken
ocean sinew
#

for i,v in pairs(G.P_CENTERS) do
if v.set == "Joker" then

end
end

unkempt bronze
#

So I have a ton of joker images. Do I put them together in like... Illustrator or whatever and link to that png for the joker images or link to each separately

mossy quest
ocean sinew
#

yes I think

mossy quest
#

nah, that gives me a different crash

prisma cape
#

am i misunderstanding what G.jokers.cards does? when i do this: newJoker = G.jokers.cards[-1] i get an "attempted to index a nil value" error, surely it should just give the rightmost joker?

mossy quest
#

also looks like G.P_CENTERS only pulls the vanilla jokers

prisma cape
#

last() also did not help me

hasty mist
#

hi coming back to balatro modding after a hiatus is there documentation yet for global operator stuff

sturdy compass
#

holy moley you're alive

hasty mist
#

yep

sturdy compass
broken rivet
#

does SMODS.find_card() work for non-jokers? it looks like it shouldn't looking at the source code and i'm annoyed by the amount of find_joker() calls in cryptid

lament agate
#

riley is alive

#

huzzah!

sturdy compass
broken rivet
#

god

broken rivet
#

time to make Cryptid.find_consumable() to replace these then

sturdy compass
#

😭

broken rivet
#

i had to commit too many modding sins today

#
  • find_joker
  • Emult_mod
hasty mist
#

i am honestly considering fully rewriting my mod

sturdy compass
sturdy compass
broken rivet
lament agate
hasty mist
#

i cant look at this code without getting physically sick

#

and also everything is broken as fuck

sturdy compass
#

Sounds like a rewrite is worth

broken rivet
hasty mist
#

yeah

#

astronomica rewrite will take weeks probably

#

but this whole mod is held together with tape and string so

#

its probably necessary

broken rivet
#

yea

lament agate
#

please fix astronomica

#

i love that mod

dusty fractal
#

does the print() function print into the console as in the log itself

lament agate
#

🙏

hasty mist
#

im trying 😭

dusty fractal
#

or where does it print

hasty mist
#

wish i had like a team or something

sturdy compass
dusty fractal
#

ahhh kk

hasty mist
#

i dont have the passion i used to

sturdy compass
#

Assuming you have DebugPlus obv

dusty fractal
#

yea

sturdy compass
dusty fractal
#

whats the button for debugplus again?

sturdy compass
#

Should be / to open game console

lament agate
dusty fractal
#
calculate = function(self, card, context)
        if context.after and context.cardarea == G.play then
            print("Hello")
            my_cards = {}
lament agate
#

i think

#

😭

dusty fractal
#

cus im doing this as the start of my calculate function

#

and its not printing anyhting into the console

#

which is confusing me

feral tree
#

need help, this is turning cards that have an enhancement into gold even though i dont want it to

sturdy compass
#

Pretty sure G.play is empty during after?

#

Not sure tho

dusty fractal
#

that checks out

feral tree
#

so how would i fix it?

dusty fractal
#

not sure why that'd interfere with just printing to console though

sturdy compass
sturdy compass
dusty fractal
#

i tried doing it here, as well

#

and it just doesnt print anything

frosty rampart
#

calculate functions wiki page does seem to indicate context.after gets G.play as a cardarea

dusty fractal
#

yea

sturdy compass
#

nevermind then

#

hrm

prisma cape
#

how do i go about getting a function to use a specific consumable held? like using c_emperor as an example

jolly shadow
#

if it's the 2nd one, just use SMODS.find_card(key)

prisma cape
#

trigger the consumable, checking i can do but i'm struggling to actually assign the specific consumable to a variable so i can call G.FUNCS.use_card()

#
    G.FUNCS.use_card({ config = { ref_table = selectedCard } })``` this doesn't seem to work
humble pawn
#

Is there a way to hide this?

solemn shuttle
#

am i missing smth with uh
checking the flame fx/score req

#

cuz i check G.ARGS.score_intensity.flames and am just getting 0 ,,

#

unless im not checking the right thing

#

-# to be precise im using it for effects involving beating a blind with one hand or Not doing so

frosty rampart
#

you don't need to check that, they added a variable in 0827

solemn shuttle
#

oh wait 👀

#

ty lol

frosty rampart
#

if you specifically want to check if the player beat the blind in one hand, check for this + if it's currently the first played hand

solemn shuttle
#

i just was wanting Flame fx in general but noted...

#

ty :3

frosty rampart
#

np :3

granite jay
#

Hey guys, where do I find all of the tags in the context?

#

I'm trying to find context.jokers_destroyed

#

Or make the card trigger when you destroy any joker.

#

(The card itself cannot destroy jokers, but it triggers when jokers are destroyed via means such as ceremonial dagger)

sturdy compass
faint yacht
#

And context.card to check the destroyed card still.

hidden oak
#

Sorry for asking so many questions, but i'm trying to make a joker that turns played kings and jacks into queens, i took some of midas mask and ouija's code but it's activating all face cards, not just ones that scored

#
    calculate = function(self, card, context)
        if context.before and not context.blueprint then
            local faces = 0
            for _, scored_card in ipairs(context.scoring_hand) do
                if scored_card:is_face() then
                    faces = faces + 1
                    local _rank = 'Q'
                    for i=1, #context.scoring.hand do
                    G.E_MANAGER:add_event(Event({func = function()
                        local card = context.scoring.hand[i]
                        local suit_prefix = string.sub(card.base.suit, 1, 1)..'_'
                        local rank_suffix = _rank
                       card:set_base(G.P_CARDS[suit_prefix..rank_suffix])
                   return true end }))
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            scored_card:juice_up()
                            return true
                        end
                    }))
                end
            end

this is probably really bad code but here's what i have

quartz pendant
#

what's the actual difference between nesting two layers of G.E_MANAGER:add_event and just using one?

hidden oak
#

🤷‍♂️

hidden oak
granite jay
faint yacht
#

context.card.ability.set == 'Joker'

granite jay
#

gotcha, imma try that

hidden oak
granite jay
#

whether that be hanged man or ceremonial dagger

faint yacht
#

(context.remove_playing_cards and context.cards[1]) or (context.joker_type_destroyed and context.card)?

unkempt bronze
#
  local xiferp_spade_change = psuedorandom_element(G.hand.cards, xiferp_astro_card)
  set xiferp_spade_change to suit_conv //priorly set to spade
end```
#

How make this actual code?

frosty rampart
#

to be clear, you want to pick a random card held in hand and change its suit to spade?

unkempt bronze
#

yeah, and the end of each round

frosty rampart
#

look at any of the suit-changing tarot cards in vanillaremade

#

there's some event coding involved to get the nice visuals where the card flips around

unkempt bronze
#

(when I asked Astro what they wanted their card wanted to do in my mod, they said just that)

unkempt bronze
# frosty rampart to be clear, you want to pick a random card held in hand and change its suit to ...
SMODS.Joker {
    key = "astro_card",
    blueprint_compat = false,
    rarity = 2,
    cost = 7,
    pos = { x = ?, y = ? },
    config = { extra = { suit_conv = Spades } },
    loc_vars = function(self, info_queue, card)
    calculate = function(self, card, context)
        if context.end_of_round then
            local xiferp_spade_change = pseudorandom_element(G.hand.cards, xiferp_astro_card)
            return { vars = { card.ability.xiferp_spade_change, localize(card.ability.suit_conv, 'suits_plural'), colours = { G.C.SUITS[card.ability.suit_conv] } } }
        end,
    end
    
}```
#

How's this?

#

(most of the crucial code is cribbed from The World)

frosty rampart
unkempt bronze
#

Alright, fine. Lemme set-up my other jokers first...

sturdy compass
unkempt bronze
#
        if context.scoring_hand[1] not context.blueprint then
        if local eval = function() not G.RESET_JIGGLES then
            juice_card_until(card, eval, true)
        end```
This part of Corrupted Dna is itself corrupted, "then expected near not"
plain apex
#

i hate shaders they just dont make sense to me how is it a re-occurring issue where i'll have a shader that works perfectly fine for ME but crashes for anyone else

keen tiger
#

hey whats the common way to spawn in jokers/cards/etc.
im trying debugplus's keybindings but its not working

hidden oak
#

Debug

#

Open conf.lua and change release to false

keen tiger
hidden oak
#

Balatro.exe

plain apex
keen tiger
#

ah thanks

keen tiger
#

also ctrl+3

#

nothing works

#

also: is there a way to mass-spawn like all 150 vanilla jokers (its kind of important for what im testing)

plain apex
#

what about ctrl+c

unkempt bronze
#
SMODS.Joker {
    key = "astro_card",
    blueprint_compat = false,
    rarity = 2,
    cost = 7,
    pos = { x = 0, y = 2 },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra }}
    end
   
    calculate = function(self, card, context)
        if context.end_of_round then
            local xiferp_spade_change = pseudorandom_element(G.hand.cards, xiferp_astro_card)
            SMODS.change_base(xiferp_spade_change, 'S')
        end,
    end
end```
daring fern
unkempt bronze
#

this is an excerpt of my code

#

from line 71 to the end. Where is the error?

daring fern
plain apex
daring fern
#

It should be on the loc_vars end.

keen tiger
#

okay awesome this makes stuff so much easier to test

unkempt bronze
daring fern
unkempt bronze
#

message

daring fern
unkempt bronze
#

(problem is between lines 71 and 81. For my life, I don't know)

plain apex
# daring fern Log?

runs fine for me but when they crash from trying to view it its always like
Oops! The game crashed:
engine/sprite.lua:117: Shader uniform 'shockwaved' does not exist.
A common error is to define but not use the variable.

daring fern
unkempt bronze
#

where?

daring fern
unkempt bronze
#

Seems to break before then, but okay

plain apex
#

this same issue was also present with overshielded before it got reworked into an entirely different shader

unkempt bronze
plain apex
#

my only solution i've found to this shit is literally just entirely different (usually much worse shaders)

daring fern
unkempt bronze
plain apex
#

but shockwaved honestly looks sick i dont want to use the entirely different much worse looking shader (left) when a cool shader (right) exists :/

unkempt bronze
#

nope.

#

Everything is ready, except the literal last piece.

plain apex
#

does anyone here understand shaders at all to tell me wtf is wrong with this?

unkempt bronze
#

Okay, the game's just angry.

#

It wants } at line 88, I give it } at line 88, it still wants } at line 88

frosty rampart
#

why is that your mod's id

unkempt bronze
#

BFDI.

#

The id could be anything, I just chose that

frosty rampart
#

anyway you have one too many ends at the very end of the astro_card joker

unkempt bronze
#
SMODS.Joker {
    key = "top_to_bottom",
    blueprint_compat = false,
    rarity = 2,
    cost = 7,
    pos = { x = 0, y = 1 },

    local xiferp_top_to_bottom = SMODS.wrap_around_straight
    function SMODS.wrap_around_straight()
    if next(SMODS.find_card("j_xiferp_top_to_bottom")) then
        return true
    end
    return xiferp_top_to_bottom()
end```

Where is the "unexpected symbol near local"?
frosty rampart
#

what

#

no don't put the hook in the joker definition, you had it right before (albeit with weird indenting)

frosty rampart
ebon shell
#

can seals not return stuff like chips and mult in their calculate function? I keep getting this crash

unkempt bronze
#

why can't it read it?

ebon shell
daring fern
ebon shell
#

I tried context.individual, context.individual and context.cardarea == G.play, context.individual and context.cardarea == G.play and context.other_card:get_seal("customseal") but none worked. what's a context check that works for when a card with a seal is scored?

daring fern
ebon shell
lavish elm
#
if context.individual and context.cardarea == G.play then
            local reps = math.random(card.ability.extra.min_rep, card.ability.extra.max_rep)
            print(reps)
            return{
                repetitions = reps,
                message = "Again!"
            }
        end

why does it only retrigger once?

daring fern
lavish elm
#

ok thx

#

how to make a joker take no space?

lavish elm
#

nvm figured it out

hearty crane
daring heron
#

does anyone know how much smaller specifically wee joker is?