#đŸ’»ăƒ»modding-dev

1 messages · Page 630 of 1

slim ferry
#

wouldnt you just use calculate for this?

#

unless you still have to use the consumable i guess

frosty rampart
#

ali and eris are both correct
make keep_on_use return true, make the use function set a variable in its config, make its can_use function only return true when that variable isn't set, and then use the calculate function to check for the context + if the variable is set

#

(the can_use and keep_on_use functions are in lib/dice.lua, the use function has a bunch of visual work and most of it is offloaded to a separate function in lib/functions.lua, and the calculate function is in each individual die in content/Dice/dX.lua)

static valley
#

Just a quick question

#

is it possible to get mp4s to play

#

and how would I go about doing that?

copper perch
#

How would I go about subtracting money from the player on a joker? I wanna subtract $3 after you win a blind and on the evaluation screen I wanna show if you win any from doing that (the joker is like slots lol)

daring fern
copper perch
#

If thats possible of course

verbal vigil
#

I know this might be a stupid question but is there any way to set the rank of a card on deck generation? I tried looking through the VanillaRemade, Balatro code (or thats what my vscode says), and SMODS docs (including SMODS#change_base). Can anyone help me?

daring fern
vale zinc
#

Could anyone say why my game keeps on crashing when I try to add anything to main_end? I'm going off of VanillaRemade's code for the Invisible Joker.

main_end = {}
localize {
    type = 'other',
    key = 'm_lapsems_uranium_destroy',
    nodes = main_end,
    vars = {
        card.ability.extra.cards_to_destroy
    }
}
return {
    main_end = main_end,
    vars = {
        card.ability.extra.blind_handicap,
    }
}

-- Here's the localization bits:
m_lapsems_uranium = {
    name = "Uranium Card",
    text = {
        "{X:attention,C:white}X#1#{} {C:attention}Blind{} amount",
        "no rank or suit",
    }
}
m_lapsems_uranium_destroy = {
    name = "u",
    text = {
        "Destroy {C:attention}#1#{} random",
        "card in hand",
    },
}
Oops! The game crashed:
engine/ui.lua:693: attempt to index field 'colour' (a nil value)
tranquil gull
#

@marble flint WHEN I GET MY HANDS ON YOU
this is such a fucking dumb idea /pos i love it

copper perch
#

Is there a way to play a sound in calc_dollar_bonus?

tranquil gull
#

question

#

if you have 1e10 mult does this set it to 5e92 mult

marble flint
#

yep

tranquil gull
#

LOL

marble flint
#

although the intermediate step needs to get rendered with an e

#

significantly funnier is that 101 goes to 20.22

tranquil gull
#

also if you wanna uh

tranquil gull
#

if you wanna fit the whole code on there I Have A Font that you could mess with

marble flint
#

idk if it's worth it tbh

tranquil gull
#

fair

vale zinc
tranquil gull
marble flint
#

that is correct but it actually happens after you've won with vanilla balance

gusty compass
#

How would I correctly delay a consumable effect when used, for instance how cards are all flipped at a short delay when a suit changer or enhancing tarot was used?

vale zinc
gusty compass
#

Alright

solid salmon
#

guys

#

is there a way to make sure that specific jokers cant appear in shops, packs and consumables

marble flint
#

look into in_pool for that

tranquil gull
solid salmon
#

and i tried

#

but i didnt do it right

vale zinc
#

Show us what you did.

solid salmon
vale zinc
#

What do "jud", "sho" and "buf" signify?

solid salmon
#

judgement, shop and buffoon

daring fern
# solid salmon

return not args or (args.source ~= 'jud' and args.source ~= 'sho' and args.source ~= 'buf')

vale zinc
normal crest
#

try main_end = { main_end }

#

in the return

chrome widget
#

Something's not being properly added in the main_end nodes. That specific crash occurs because there's either an empty node or the arrangement of the nodes are misaligned

normal crest
#

The localize call looks correct to me

#

So I think it has to do with the structure of the returned main_end

normal crest
vale zinc
#
-- Here's how I tried to implement mine.
local main_end = {}
localize {
    type = 'other',
    key = 'm_lapsems_uranium_destroy',
    nodes = main_end,
    vars = {
        card.ability.extra.cards_to_destroy
    }
}

-- Here's what VanillaRemade did for Invisible Joker, which I used as a guide.
main_end = {}
localize {
    type = 'other',
    key = 'remove_negative',
    nodes = main_end,
    vars = {}
}

-- Both ended with this in their return calls:
return {
    main_end = main_end
}
normal crest
#

Can you show the localization entry for m_lapsems_uranium_destroy

vale zinc
normal crest
#

The 2nd one should be in the set "Other"

vale zinc
normal crest
static valley
#
-- loading videos
Comedy_video_dont_ever_do_that_again = Comedy_loadVideo('dont_ever_do_that_again')

-- in utils.lua
function Comedy_loadVideo(name)
    local path = (ComedyGold.path .. "assets/videos/" .. name .. ".ogv")
    ComedyGold.videos[name] = assert(love.graphics.newVideo(path))
    ComedyGold.show_vid[name] = false
    return ComedyGold.videos[name]
end

i dont get it. The video is there. What's causing this?

vale zinc
normal crest
#

idk where you got it has main_end = main_end

vale zinc
normal crest
#

What does your loc_vars code look like now

vale zinc
# normal crest What does your loc_vars code look like now

Here's the full loc_vars call.

loc_vars = function(self, info_queue, card)
    local main_end
    local hazmat_joker = false
    if G.jokers and G.jokers.cards then
        for _, joker in ipairs(G.jokers.cards) do
            if joker.config.center.key == 'j_lapsems_hazmat' then
                hazmat_joker = true
                break
            end
        end
    end
    if not hazmat_joker then
        main_end = {}
        localize {
            type = 'Other',
            key = 'm_lapsems_uranium_destroy',
            nodes = main_end,
            vars = {
                card.ability.extra.cards_to_destroy -- 1
            }
        }
    end
    return {
        main_end = main_end[1],
        vars = {
            card.ability.extra.blind_handicap,
        }
    }
end
normal crest
#

okay, I said the localize type should be "other"

#

Also in your case specifically you want to check whether main_end exists in the first place, so do main_end = main_end and main_end[1]

vale zinc
#

Must I split the lines among separate localization-signifiers?

normal crest
#

uhhh, if I had to guess the main_end[1] is what's causing only the first line to show

vale zinc
normal crest
#

try

main_end = main_end and {
  n = G.UIT.C,
  nodes = main_end
}
#

that's all I can think of

#

actually nvm, that's wrong too, as you can see I have no experience lol

golden field
#

question: is there a way for a boss blind to debuff cards with a certain enhancement

daring fern
copper perch
granite jay
#

Is it possible for a joker’s xmult message to have custom colours and sounds?

wispy falcon
#

Anyone got any idea, why it shows --5 in the mult message? I only see 1 -, in the return

    key = "curse",
    config = { mult = 5 },
    shader = "cstorm_curseShader",
    in_shop = false,
    weight = 2,
    extra_cost = 5,
    badge_colour = HEX("8000CC"),
    --sound = { sound = "cstorm_curse1", vol = 0.7 },

    calculate = function (self, card, context)
        if context.post_joker or (context.main_scoring and context.cardarea == G.play) then
            return{
                mult = -card.edition.mult
            }
        end
    end,

    in_pool = function (self, args)
        return false
    end,

    loc_vars = function (self, info_queue, card)
        return { vars = { card.edition.mult }, key = self.key }
    end
}```
granite jay
granite jay
#
SMODS.Sound ({
    key = 'gourdy_ability',
    path = 'dw_gourdy_ability.ogg',
    pitch = 1,
})

SMODS.Sound ({
    key = 'gourdy',
    path = 'dw_gourdy.ogg',
    pitch = 1,
})

SMODS.Joker{
    key = "gourdy",
    atlas = 'dandysworld',
    pos = { x = 7, y = 9},
    soul_pos=nil,
    rarity = 3,
    cost = 10,
    config = { extra = {chips = 50, mult = 10, x_mult = 1.5} },
    blueprint_compat=true,
    eternal_compat=true,
    perishable_compat=true,
    unlocked = true,
    discovered = true,
    calculate = function(self,card,context)
        if context.joker_main then
            local effects = {
                {
                    message = localize("dw_gourdy_ability"),
                    sound = "dandy_gourdy_ability",
                    colour = G.C.FILTER
                }
            }

            for _,v in ipairs(G.jokers.cards) do
                if v ~= card then
                    local vEffectType = pseudorandom('dw_gourdy', 1, 3)
                    local vEffect = {}

                    if vEffectType == 1 then
                        vEffect.x_mult = card.ability.extra.x_mult
                    elseif vEffectType == 2 then
                        vEffect.mult = card.ability.extra.mult
                    elseif vEffectType == 3 then
                        vEffect.chips = card.ability.extra.chips
                    end

                    vEffect.sound = "dandy_gourdy"
                    vEffect.colour = G.C.FILTER
                    vEffect.message_card = v
                    
                    effects[#effects+1] = vEffect
                end
            end

            return SMODS.merge_effects(effects)
        end
    end,

    loc_vars = function(self, info_queue, card)
        return { vars = {card.ability.extra.chips, card.ability.extra.mult, card.ability.extra.x_mult}, key = self.key }
    end
}```
wispy falcon
#

Why do you put the custom stuff into a table?

static valley
#

trying to get video loading to work.

-- video loader
video = nil
game_volume = 0

function Comedy_play_video(name)
    local path = SMODS.Mods["ComedyGold"].path.."assets/videos/" .. name .. ".ogv"
    love.filesystem.write("temp.ogv", path)
    video = love.graphics.newVideo('temp.ogv')

    -- mute the game until finished
    game_volume = G.SETTINGS.SOUND.volume
    G.SETTINGS.SOUND.volume = 0

    video:play()
end

-- love2d hooks
loveUpdateHook = love.update
function love.update(dt)
    loveUpdateHook(dt)
    if video and not video:isPlaying() then
        video:release()
        video = nil
        G.SETTINGS.SOUND.volume = game_volume
    end
end

loveDrawHook = love.draw
function love.draw()
    loveDrawHook()
    if video then
        local xScale = love.graphics.getWidth() / 1920
        local yScale = love.graphics.getHeight() / 1080
        love.graphics.draw(video, 0, 0, 0, xScale, yScale)
    end
end
static valley
#

it also says "file not found" even though the file does in fact exist

#

how do I fix this?

static valley
#

(same issue, btw)

gaunt folio
#

this code is probably incorrect, what am i doing wrong?

daring fern
gaunt folio
#

k

daring fern
#

Also context.individual and context.joker_main don't happen at the same time.

gaunt folio
#

doesnt do the function, what am i doing wrong?

daring fern
gaunt folio
#

this returns the message for everyone (placeholder) but it doesn't actually turn them gold

#

whats wrong?

#

again this

#

i have the boolean as greater than just to test

daring fern
gaunt folio
#

works

daring fern
#

‎

ashen drift
#

how would i draw something (le sprite) below a card

#

i guess i would just have to do drawstep jank

#

ive never used it before though

stoic void
rocky osprey
#

how does cryptid make its own variables i wonder

G.GAME.code_rate
#

im tryna do the same for my set
-# if you do answer please ping

sturdy compass
solid salmon
#

Chat

#

how do i mkae it so

#

a joker cant spawn if yuou have a specific joker

faint yacht
#

return not next(SMODS.find_card('j_modprefix_key'))

solid salmon
#

what if i got like many said specifc jokers or like a group

#

can i just do

#

that?

brazen kite
#

tried to open the balatro sounds folder and it crashed file explorer. i love windows 11

wind steppe
solid salmon
#

can it work with a joker group?

wind steppe
#

like a pool?

#

no you'd have to do a couple hooks/patches to spawning logic

solid salmon
#

...

#

so i have to manually list every single joker

wind steppe
#

what are you trying to do

solid salmon
wind steppe
#

so just put the in_pool into the base form

solid salmon
#

ik that

#

but the issue is

#

it has lots of transformations

wind steppe
#

make an objecttype

#

that all your transformations have

#

and then loop through joker slots and check for jokers with that objecttype

#

return true if nothing is found

solid salmon
#

i already made the group

#

i mean the "object type"

#

in mind

brazen kite
#

i want to add an attention_text that displays just above where the deck lives but i have no idea how to do that

    attention_text({
        text = localize('k_reset'),
        scale = 1.3, 
        hold = 1.4,
        backdrop_colour = G.C.SECONDARY_SET.Joker,
        align = 'br',
        offset = {x = 0, y = 0},
        silent = true
    })

right now what this is doing is flying across the screen

faint yacht
#

Set major to the deck?

brazen kite
#

huge

#

it seems to work

wind steppe
#

what part dont you get

spiral mural
maiden phoenix
#

Check set_ability

solid salmon
#

you want it to check

#

every jonkler slot

#

for if the joker (or a transformation of it) exists

#

and if it does then return true

spiral mural
maiden phoenix
spiral mural
maiden phoenix
#

Vanillaremade wiki prob has something on that Idk the exact formula and cant check rn

spiral mural
#

born to ask questions

#

forced to look at documentation

wind steppe
solid salmon
wind steppe
#

what do you mean the loopy thing then

solid salmon
wind steppe
#

I did

frosty rampart
#

lua allows you to make for loops of the form for x, y in pairs(z), where y represents an element in the table z and x represents the label of that element in z
each element of G.jokers.cards is a joker

wind steppe
#

You want to check every joker slot for if the joker or a transformation of it exists

#

also you should probably be checking SMODS.Showman for each as well

dusty fractal
#

how do you tell what cards are about to be discarded in pre_discard context

wind steppe
#

G.hand.highlighted afaik

faint yacht
#
if context.pre_discard and context.cardarea == G.play then
{
    cardarea = G.jokers, -- G.hand, (G.deck and G.discard optionally enabled)
    full_hand = G.hand.highlighted,
    pre_discard = true,
    hook = hook -- true when 'The Hook' discards cards
}
dusty fractal
#

gathered that while i was coding just now but

#

im trying to compare if the card im evaluating is inside of g.hand.highlighted

#

by iterating through all of the cards in the highlighted hand

#

and comparing

#

but i cant just use ==

#

so how would i tell if a card is the same card im looking at

#

is there something like full deck position or

faint yacht
#

What's the effect?

dusty fractal
#

applying enhancements of discarded cards in the first hand

#

to a random non-discarded, unenhanced card in hand

#

problem is that it can apply it to ones that are part of the discard

#

i want to grab the inverse of g.hand.highlighted to pick from basically

frosty rampart
#

cards individually store their highlighted state in card.highlighted
so iterate over G.hand.cards and grab all the cards where card.highlighted is false, and then pick a random one from that subset

dusty fractal
#

ahhhhh ok

#

thats useful thank u

verbal vigil
#

Does anyone know if its possible to make a key combo? (like ctrl + k + r)

faint yacht
frosty rampart
#

^

verbal vigil
#

Ty! (also very cute cat pic :D)

solid salmon
#

hey guys

#

is there a context for FAILED probabilities

slim ferry
#

context.pseudorandom_result and not context.result

white hull
#

hey y’all, is there a context for doing something before a hand is scored but before context.before? like how the tooth takes your money after your cards are moved to the play area but before the cards move up slightly for scoring

slim ferry
#

context.press_play

white hull
#

i tried that, but i can’t access the played cards because that context doesn’t have context.full_hand, and i need that

slim ferry
#

G.hand.highlighted?

#

well

#

i think G.play works

white hull
#

oh full hand is just G.play.cards

#

maybe

#

let’s see

#

doesn’t seem to be working, plus it happens the instant you press play and not after the cards are moved to be played

#

i’m looking at the tooth in vanilla remade and it uses events with delays

#

maybe it’s just that and there isn’t a context specifically for this?

slim ferry
#

probably then yeah

tranquil gull
#

@marble flint bakery bug with stickyfingers: charms go in the consumable slot when bought through the added buy area

#

they also do this when spawned from debug

#

(playing with drawing pen)

brazen kite
#

Is there a way I can change the color of the hand/discard number to something else

tranquil gull
#

yea just hook into functions/UI_definitions

#

unless you mean also on jokers then no not without changing everything else thats red and blue

brazen kite
#

nah i just wanted to change the color in the UI

#

good 2 know

wispy falcon
#

Why does this hook crash my game?

function eval_card(card, context)
    if card.edition.key == "e_cstorm_glitch" then
        print("Glitched :O")
    end
    local ret = eval_card_ref(card, context)

    return ret
end```
daring fern
wispy falcon
daring fern
wispy falcon
#

What was the problem though? Did it give 2 things and I only returned one?

wispy falcon
#

Okay, how do I make the card not trigger with the odds in the edition's config? I'm struggling...

function eval_card(card, context)
    if card.edition and card.edition.cstorm_glitch then
        local RNGesus = pseudorandom("cstorm_glitch", 1, card.edition.denominator)
        if RNGesus <= card.edition.numerator then
            return
        end
    end
    local ret, post = eval_card_ref(card, context)

    return ret, post
end```

This crashes my game... It also rerolls the number every frame instead of once when the card would score
#

Wait, only thing that I don't understand is how I stop the card from scoring

wispy falcon
#

Now the Joker never triggers at all...

    key = "glitch",
    config = { numerator = 1, denominator = 4, already_rolled = true },
    shader = "cstorm_glitchShader",
    in_shop = false,
    weight = 2,
    extra_cost = 5,
    badge_colour = SMODS.Gradients["cstorm_glitchGradient"],
    sound = { sound = "cstorm_glitch1", vol = 0.7 },

    calculate = function (self, card, context)
        if (card.ability.set == "Joker" and context.pre_joker) or
        ((card.ability.set == "Default" or card.ability.set == "Enhanced") and context.main_scoring and context.cardarea == G.play) then
            print("Runnt")
            card.edition.already_rolled = false
        end
    end,

    in_pool = function (self, args)
        return false
    end
}

local eval_card_ref = eval_card
function eval_card(card, context)
    if card.edition and card.edition.cstorm_glitch and card.edition.already_rolled == false then
        print(card.edition.already_rolled)
        local RNGesus = pseudorandom("cstorm_glitch", 1, card.edition.denominator)
        card.edition.already_rolled = true
        if RNGesus <= card.edition.numerator then
            card.edition.already_rolled = false
            print("Glitch activated! Card skipped.")
            return {}, {}
        end
        print("Glitch check passed: " .. RNGesus)
        card.edition.already_rolled = false
    end
    local ret, post = eval_card_ref(card, context)

    return ret, post
end```
lyric maple
#

i'm confused as to how the aura code works (i need to use the random edition thing). what is info_queue?

#

the code is

    loc_vars = function(self, info_queue, card)
        info_queue[#info_queue + 1] = G.P_CENTERS.e_foil
        info_queue[#info_queue + 1] = G.P_CENTERS.e_holo
        info_queue[#info_queue + 1] = G.P_CENTERS.e_polychrome
        return { vars = { card.ability.max_highlighted } }
    end,
frosty rampart
#

it's irrelevant to the actual behavior of the card
adding an entry to info_queue adds an extra little pop-up box next to the card's description box that explains a related thing (in Aura's case, it has 3 pop-up boxes with the descriptions for Foil, Holographic, and Polychrome)

terse marsh
#

just starting to get into balatro modding (ive done mostly python and JS development as well as some light roblox lua programming), besides following the beginner guide and looking at examples any advice on making my first mod?

any advice would be appreciated but would also like advice about what IDE's are best for balatro/lua development as well as build scripts/extensions

obsidian spear
# terse marsh just starting to get into balatro modding (ive done mostly python and JS develop...

just have fun, and any ide works, personally i use the most popular vsc, the lua plugin on it is quite useful, theres also alot of help you can get from vanilla remade (by our god n'), usually you should think of a theme, or you can just do anything to do with you, balatro modding should be smth you find fun

anyway with the actual question, I'd suggest either a basic joker that does flat mult or flat chips, but you can also do a scaling joker, so smth like
gains +1 mult per stone card played
(currently +0 mult)

#

its also very important you start with doing a localization folder when adding text to your jokers if you any bit serious with your mod, since its less messy and will help when you just wanna change 1 word in all jokers to something specific

#

hope this helped

feral tree
#

can SMODS.blueprint_effect copy multiple cards or is it restricted to only one target?

harsh belfry
#

i don't know the args of the blueprint effect function so ig figure it out

terse marsh
feral tree
harsh belfry
#

obviously didn't test this

#

and ofc replace the whatever placeholders

#

in order it:

  • makes a list of all of the effects that the targeted jokers have given
  • if there is any effects, then:
  • it provides each one as an arg to merge_effects, using unpack to do so
  • returns the combined effect
normal crest
#

return SMODS.merge_effects(rets) instead

#

pretty sure it takes a list of effects

feral tree
#

it works!

spiral mural
#

is there a way to have a ternary result from pseudorandom_probability

stoic heron
#

probably

frosty rampart
spiral mural
#

true false evil third bool

spiral mural
harsh belfry
#

true fruse false

golden field
#

question: how do i do an operation (i.e. division) on the score of a hand played

spiral mural
umbral zodiac
#

just use pseudorandom with a range of -1 to 1 then right

#

rather than pseudorandom probability

frosty rampart
#

yea lol

local value = pseudorandom("seed", -1, 1)
[something] = something + value
umbral zodiac
#

^

normal crest
#

^

spiral mural
#

^

harsh belfry
#

^

umbral zodiac
#

v

harsh belfry
#

v

frosty rampart
#

if you pass the second and third arguments to pseudorandom, it returns only integers

spiral mural
frosty rampart
#

i actually forget if it's inclusive on both the lower and the upper bound or not

#

but i think it is

spiral mural
#

all my homies hate exclusive randoms

golden field
#

how'd i do that

frosty rampart
#

great

#

oh hi lily i didn't recognize you with the nickname

umbral zodiac
#

wait meta

#

ur literally the dice girl

#

how the fuck do u not know if its inclusive

spiral mural
#

💔

frosty rampart
#

i haven't looked at the actual dice rolling code in a while

umbral zodiac
frosty rampart
umbral zodiac
#

im crine

spiral mural
frosty rampart
#

anyway if you needed to do something more complicated than just adding one of three random values to another variable, here's something cool you can do: define a table containing three functions, each one runs the behavior of one of the options. then just use pseudorandom_element on that table and call whatever function you get out of it :3

normal crest
#

:3

spiral mural
frosty rampart
#

cryptid chocolate die

spiral mural
#

blunder emoji

#

let me take a look at what it does

frosty rampart
spiral mural
#

ok that makes sense

#

but im just adding to a value 💔

#

(and the actual value of it matters)

frosty rampart
#

ya i know, i was just giving some general advice for anyone (it's what i was gonna send before you mentioned your specific use case)

normal crest
#

that's why you always ask for the goal

spiral mural
#

how do i move a joker to a specific slot

#

(specific goal: move a just created joker to a slot that i know should exist due to the addition of the joker)

normal crest
#

By swapping their positions, example swapping the 1st joker with the 2nd joker

local swapped_joker = G.jokers.cards[1]
G.jokers.cards[1] = G.jokers.cards[2]
G.jokers.cards[2] = swapped_joker
spiral mural
#

wait i can move cards just by changing indexes!?

spiral mural
#

if i remember correctly anyways

normal crest
normal crest
golden field
cerulean rose
#

trying to set a floor on player money, but it's not quite working
i have this so far

calculate = function(self, card, context)
    if context.main_scoring and context.cardarea == G.play and G.GAME.dollars < card.base.nominal then
        return { dollars = card.base.nominal - G.GAME.dollars }
    end
end

it doesn't work because G.GAME.dollars isn't updated immediately
any ways i could get it to work?

bold gyro
#

how do i delete or move a UIBOX? i have the following functions to define and draw it:

function G.UIDEF.suika_main()
    return {n = G.UIT.ROOT, config = {r = 0.1, minw = 7, minh = 10, align = "tm", padding = 0.2, colour = G.C.UI.TRANSPARENT_DARK }, nodes = {
    }}
end

function SuikaLatro.f.drawBG()
    return UIBox{
        definition = G.UIDEF.suika_main(),
        config = {align='cm', offset = {x=0,y=G.ROOM.T.y + 2}, major = G.ROOM_ATTACH, bond = 'Weak'}
    }
end
spiral mural
#

wait didn't reply ping

#

@normal crest

cerulean rose
spiral mural
normal crest
#

and what is created_card

spiral mural
#

is it not obvious

normal crest
#

i mean you're comparing it to a number

spiral mural
#

?

normal crest
#

so it could be either a number or you incorrectly are comparing it to a number

spiral mural
#

oh shit

#

i meant to compare ot jokers[j]

#

😔

normal crest
#

also in vanilla it always does box = nil afterwards

#

dunno if that matters at all

spiral mural
#

probably for memory mangement despite lua having a garbage collector

golden field
ocean sinew
ocean sinew
# golden field end

just do x_mult=0.5
x_mult_message="/2"
remove_x_mult_message=true
on context.final_scoring_step

golden field
#

-# i forgor to specify that fml

ocean sinew
#

u could check it on blinds.lua

golden field
ocean sinew
#

u could use that and context.final_scoring_step

ocean sinew
ocean sinew
spiral mural
#

how do i change the badge color of the rarity

#

(need to do this for only one joker)

lime iron
#

save and replace the original png inside the exe using 7 zip

spiral mural
#

do you know

#

what you are talking about

harsh belfry
spiral mural
#

@lime iron grindset

#

> enter the server
> tells me to replace sprites using 7zip
> leaves

#

absolute blunder

loud citrus
#

I asked this in modding chat but here is more appropriate.

is there a way to track when you draw the last card you have of a certain rank (or any rank)

frosty rampart
#

the first way i can think of is to loop over G.deck.cards every time a card is drawn, and check if there are any other cards of the same rank as the drawn card in G.deck.cards (that card area is only for cards that haven't yet been drawn)

a more complicated way that might still end up being more efficient than looping over a giant table like G.deck.cards would be to have a table that tracks how many cards of each rank you have in total, update that table whenever playing cards are added or destroyed, have a second table that tracks how many cards of each rank you have left in the deck, and update that table every time playing cards are added to specifically the deck, destroyed from specifically the deck, drawn to hand, and then reset it to the state of the first table at the end of the round (after any end-of-round card destroying/adding of course)

spiral mural
#

52 elements

frosty rampart
#

are you referring to the first method or the second
because you are correct on the first one, but the second one would only have 15 elements unless you have mods that add more ranks

spiral mural
loud citrus
pale holly
#
    loc_vars = function(self, info_queue, blind)
        return { vars = { G.GAME.dollars }  }
        end,

local prestige_money = {}

calculate = function(self, blind, context)
    
    if context.setting_blind then
        prestige_money = G.GAME.dollars
    end

    if context.money_altered and G.GAME.dollars ~= prestige_money then
        local diff = G.GAME.dollars - prestige_money

        G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.4,
            func = function()
                ease_dollars(-diff, true)
                blind:wiggle()
                return true
            end
        }))

        delay(0.6)
    end
end

Alright so i did tried out, putting the prestige_money in local didn't worked out and would constantly apply the dollar change even if it should not
I did tried setting outside of the calculate function but it it wouldn't work and directly crash my game, so i would like to know if there's a config setting that can work out similar like card.ability.extra.prestige_money but for blinds ? Should i make something like self.ability.extra.prestige_money or is there a different way to do it ?
Would appreciate the help thanks

urban wasp
#

what's the color key in G.C for balancing (the color behind the message on plasma deck)?

normal crest
#

idk if it's there, but it's { 0.8, 0.45, 0.85, 1 }

normal crest
#

In calculate

#

First think about when you want this effect to happen

pale holly
#

well i want it to happen whenever the money change (from Tarot, Joker, etc) but i guess to make it safe i can just put a context.main_eval

normal crest
#

Uh I don't remember if there's an SMODS context for that

pale holly
#

I'll just use context.main_eval, i think this should work out that way as a safe way, that or simply use things like consumable used or triggered joker

#

whatever that works without breaking

#

right now my issue is to store the amount of money the player got when setting the blind, since i don't think i can simply do a card.ability.extra.prestige_money like how you could do with a Joker

#

and using a local might work but with what i tried to do, it either make the function constantly run or crash my game directly upon starting

pale holly
#

oh

#

thanks

#

but what about storing money ?

frosty rampart
#

here's all the documentation on it

pale holly
#

but thanks again

frosty rampart
#

yea latest release

pale holly
#

Ah that make sense

frosty rampart
#

context documentation is sadly in need of a lot of work still

pale holly
#

yeah i feel like the wiki misses a lot of important things and makes it hard to search what you need, i rely a lot on Vanilla Remade since the exemples helps A LOT

pale holly
#

Does, anyone know how i could do it please ?

daring fern
pale holly
#

thanks

pale holly
lavish elm
#

how do you replace in a lovely patch
position = "?"

wind steppe
#

at

lavish elm
versed swan
#

I dont remember the exact keys (currently afk), but whats the point in having both x_mult and perma_x_mult in Card.ability? (Same with h_x_mult and perma_h_x_mult)

#

I'm implementing similar "bonuses" for the custom scoring parameters in a mod im developing

spiral mural
#

to have a joker that kills perma_x_mult

#

idk

versed swan
#

Consider not answering if you don't have a serious one.

daring fern
versed swan
#

...huh

#

Now I'm wondering why that would even be needed - like wouldn't it be better to like see those values always, gameplay-wise?

spiral mural
#

what's the context (combo) that is at the end of the round, but the scoring_hand is still existant

stiff locust
#

context.after and (blind score + hand score > required score) is the closest iirc

spiral mural
#

how do i keep the game from discardiing the cards if the effect isn't done yet
jonkler code:

        if (context.after) or context.forcetrigger then
            -- stolen vanillaremade code
            for i = 1, #context.scoring_hand do
                local percent = 1.15 - (i - 0.999) / (#context.scoring_hand - 0.998) * 0.3
                G.E_MANAGER:add_event(Event({
                    trigger = 'before',
                    delay = 0.15,
                    func = function()
                        context.scoring_hand[i]:flip()
                        play_sound('card1', percent)
                        context.scoring_hand[i]:juice_up(0.3, 0.3)
                        return true
                    end
                }))
            end
            delay(0.2)
            for i = 1, #G.hand.highlighted do
                G.E_MANAGER:add_event(Event({
                    trigger = 'before',
                    delay = 0.1,
                    func = function()
                        -- SMODS.modify_rank will increment/decrement a given card's rank by a given amount
                        if context.scoring_hand[i]:get_id() == 14 then
                            
                        elseif context.scoring_hand[i]:get_id() == 2 then
                            assert(SMODS.modify_rank(context.scoring_hand[i], 12))
                        else
                            assert(SMODS.modify_rank(context.scoring_hand[i], card.ability.extra.decrease))
                        end
                        return true
                    end
                }))
            end
        end
    end```
lavish elm
#

how can I change the desc of vanilla consumables?

stoic void
#

english only tho

lavish elm
#

nvm I figured it out

stoic void
#

k

pale holly
#
SMODS.Blind {
    name = "bos_prestige",
    key = "bos_prestige",
    atlas = "pseudoblinds",
    mult = 2,
    pos = { y = 2 },
    dollars = 5,

   boss = { min = 1, max = 3 },
   
    boss_colour = HEX('b55e9e'),
    
    config = { prestige_money = 0 },
    
    loc_vars = function(self, blind)
    if G.GAME.dollars < 0  then
    local key
    key = self.key .. '_alt'
    else
    key = self.key
    end
    
        return {key = key, vars = { G.GAME.dollars or 0,  }  }
        end,


calculate = function(self, blind, context)
    
    if context.setting_blind and context.main_eval  then
    if G.GAME.dollars > 0  then
    --blind.effect.prestige_money = G.GAME.dollars
    self.prestige_money = G.GAME.dollars
    ease_dollars(-G.GAME.dollars, true)
    elseif G.GAME.dollars < 0 then
    self.prestige_money = -G.GAME.dollars
    end
    end
    end,
    
     disable = function(self)
     ease_dollars(blind.effect.prestige_money, true)
     end,
     
     defeat = function(self)
     if G.GAME.current_round.hands_left > 0 then
     ease_dollars(self.prestige_money, true)
     end
     end,
} ```

so i wanted to try to change the blind's text depending on either you have money or are in debt but got that error,  is there a work around for this ?
daring fern
pale holly
#

oh wait yeah it's on

#

lemme disable it

#

I forgot Talisman fucks up some of the calculations

#

Yeah it works now thanks

lavish elm
#

how to control the temperance value bc I removed the limit and it is still showing 50 dollars even though the self.ability.money is higher than 50

#

here is what my patch looks like

if G.GAME.no_limit then
        self.ability.money = self.ability.money
    else
        self.ability.money = math.min(self.ability.money, self.ability.extra)
    end
#

found the value

golden field
pale holly
#
add_to_deck = function(self, card, from_debuff)
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.5,
        func = function()
            SMODS.add_card{ set = "Joker" }

            G.E_MANAGER:add_event(Event({
                trigger = 'after',
                delay = 8.5,
                func = function()
                    SMODS.destroy_cards({card}, nil, nil, true)
                    message = "Goodbye !"
                    return true
                end
            }))

            return true
        end
    }))
end,
}```

Hi again sorry but i wanted to know how do i make the joker do the message once it autodestroy itself (like Gros Michel), tried to do a return message outside, didn't worked out and inside doesn't either
gusty compass
#

sorry if i disturb anyone but what would i have to do to make this stake apply gold and everything below, since apparently {"gold"} still doesnt work đŸ„€

pale holly
gusty compass
#

Yea I did, I tried it a few times but it would not emplace it correctly

pale holly
gusty compass
#

I did reference cryptid for this but I'll try build it off orange and copy the gold stake code

pale holly
#

yeah seems the easiest workaround right now

wintry solar
#

you need prefix_config = {applied_stakes = {mod = false}}

gusty compass
#

In SMODS.Stake?

wintry solar
#

yes

stoic void
gusty compass
#

It did something, showing Applied Gold Stake, should I leave that be?

gusty compass
wintry solar
#

it should be working then

gusty compass
#

Alright thanks a lot you all

stoic void
#

👍

ocean sinew
#

or did u want it to be /2 chips too

golden field
slim ferry
#

smods should probably have a context for between score being totaled and it being added to round score so modifying hand score at all isnt scoring calculation hell

ocean sinew
#

fr

harsh belfry
hardy vessel
#

Making a joker that gives an investment tag, but the info queue shows the dollar value as nil (and shows the normal $25 when you actually have the tag). Is there a potential fix for this?

Nothing is changed from vanilla in regards to the tag.

slim ferry
#

what does the info_queue look like?

#

actually no

#

just add config = G.P_TAGS.tag_investment.config to the info_queue thing for it i think

hardy vessel
slim ferry
#

oh okay

white hull
#

is there a way for me to set a joker’s default sell value ala the cost property? or do i need to make an add_to_deck function that sets its sell value?

slim ferry
#

Hook Card:set_cost

#

Also sell value is always half of the cost so if the cost doesnt matter just make it double the sell value

white hull
#

it seems easier to just double the sell value lol

vale zinc
#

The "+1 Tarot" and "+1 Spectral" messages do not appear. What am I doing wrong here?

G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 2
G.E_MANAGER:add_event(Event({
    trigger = 'after',
    delay = 0.2,
    func = (function()
        SMODS.add_card {
            set = 'Tarot',
            key_append = 'witch_hunter'
        }
        G.GAME.consumeable_buffer = 1
        return {
            message = localize('k_plus_tarot'),
            colour = G.C.SECONDARY_SET.TAROT
        }
    end)
}))
delay(0.2)
G.E_MANAGER:add_event(Event({
    trigger = 'after',
    delay = 0.2,
    func = (function()
        SMODS.add_card {
            set = 'Spectral',
            key_append = 'witch_hunter'
        }
        G.GAME.consumeable_buffer = 0
        return {
            message = localize('k_plus_spectral'),
            colour = G.C.SECONDARY_SET.SPECTRAL
        }
    end)
}))
harsh belfry
#

you can use SMODS.calculate_effect on those tables instead of returning them, with a second argument that is the joker/consumable/card that is creating these

#

for example:

SMODS.calculate_effect({
    message = localize('k_plus_spectral'),
    colour = G.C.SECONDARY_SET.SPECTRAL
}, card)
vale zinc
harsh belfry
#

yes

#

and similar for the other one

#

and of course make sure card is actually the card running the effect

#

(it may be named something else after all)

vale zinc
#

The messages still don't show up, but now it fills up the consumable slots indefinitely.

if context.end_of_round and context.game_over == false and context.main_eval and context.beat_boss then
    G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 2
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.2,
        func = (function()
            SMODS.add_card {
                set = 'Tarot',
                key_append = 'j_lapsems_witch_hunter'
            }
            G.GAME.consumeable_buffer = 1
            SMODS.calculate_effect({
                message = localize('k_plus_tarot'),
                colour = G.C.SECONDARY_SET.TAROT
            }, card)
        end)
    }))
    delay(0.2)
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.2,
        func = (function()
            SMODS.add_card {
                set = 'Spectral',
                key_append = 'j_lapsems_witch_hunter'
            }
            G.GAME.consumeable_buffer = 0
            SMODS.calculate_effect({
                message = localize('k_plus_spectral'),
                colour = G.C.SECONDARY_SET.SPECTRAL
            }, card)
        end)
    }))
end
#

However, I'm about to head out for a little while, so I can't stay and chat.

normal crest
#

so you have to return true at some point

vale zinc
#

The messages still don't show up, though.

pale holly
#

Is there a way to make the text of the blind requirement wiggle too ?

#

Like when i want for exemple the requirement to change, it could wiggle to show it's changing

tired kestrel
#

how do I make this work?

ocean sinew
tired kestrel
#

for a mod

#

either by hooks or lovely patch

#

I'm trying to see if I can do a hook method.

ocean sinew
#

you could probably hook Game:load_profile

tired kestrel
#

I'll try

jolly path
#

how do i start making balatro mods

stoic void
jolly path
#

Thank you

pale holly
#
calculate = function(self, card, context)
    if context.joker_main then
        G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.4,
            func = function()
                G.GAME.blind.chips = G.GAME.blind.chips * 0.97
                G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
                G.GAME.blind.chip_text:wiggle()
                return true
            end
        }))

        delay(0.6)

        return {
            message = "-3%"
        }
    end
end
}```

Hi again, just trying to make my joker do a little shaking effect when the score changes but i got this error despite during blinds this wouldn't happen, could i have some help to know if there's a way to make the blind requiremenet text wiggle or not ?
tired kestrel
#

interesting thing when I was trying to do the loc_txt. for some reason I believe that inside the code still contains the "{C:voucher}" for blank.

However when I try to make "voucher" a custom color despite it never exists.

The color shows.

pale holly
pale holly
pale holly
#

Wouldn't that just be a re-added feature of SMODS ?

tired kestrel
pale holly
#

unless maybe, localthunk just left that somewhere hidden in the code

tired kestrel
#

Honestly, I don't get to see the reason why he get rid of that function. thought would be interesting since obviously how on earth would modders would use an unlock feature where you just tells you that it's a voucher by it's own color text.

Just like how Planets, Tarots and also Spectrical had their color in text.

#

I feel like it was ever since in the demos probably.

pale holly
#

maybe since it's close to C:attention he just, didn't see the use of C:voucher, but kept it in case

tired kestrel
#

Probably, but yeah it's really interesting to find it like that.

tired kestrel
#

oh what the heck!

#

how did this happen!?

vale zinc
#

This Joker's "+1 Tarot" and "+1 Spectral" messages don't show up, and I sought help in this channel a few hours ago, to no avail. What am I doing wrong?

if context.end_of_round and context.game_over == false and context.main_eval and context.beat_boss then
    G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
    G.E_MANAGER:add_event(Event({
        func = (function()
            SMODS.add_card {
                set = 'Tarot',
                key_append = 'j_lapsems_witch_hunter'
            }
            G.GAME.consumeable_buffer = 0
            SMODS.calculate_effect({
                message = localize('k_plus_tarot'),
                colour = G.C.SECONDARY_SET.TAROT
            }, card)
            return true
        end)
    }))
    
    delay(0.2)
    
    G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
    G.E_MANAGER:add_event(Event({
        func = (function()
            SMODS.add_card {
                set = 'Spectral',
                key_append = 'j_lapsems_witch_hunter'
            }
            G.GAME.consumeable_buffer = 0
            SMODS.calculate_effect({
                message = localize('k_plus_spectral'),
                colour = G.C.SECONDARY_SET.SPECTRAL
            }, card)
            return true
        end)
    }))
end
tired kestrel
grand sage
#

Hello I am currently trying to make malverk crossmod textures and add them to my mod does anyone have any resources or something similar or if someone's already done this before that i could look at?

lucid owl
#

trying to think of how to make editions trigger when held in hand

#

questioning if it's worth it

#

taking ownership probably wouldn't be the route considering modded editions will do nothing

#

augh

spiral mural
#

how would i make something run after everything is loaded

#

(as in all mods)

faint yacht
#

Hook Game:splash_screen() or patch right before if G.SETTINGS.skip_splash == 'Yes' then. blueprint

solid salmon
#

how do i make a misprint like description

fallow pebble
#

so when i tell the game to run doom it doenst owkr

#

can someone hel[p

#

i used c++

frosty rampart
solid salmon
#

but its so weird

#

as the card itself doesnt have a description

frosty rampart
#

yea everything is in the loc_vars function

solid salmon
#

yeah

lucid owl
#

the description is found in localization

solid salmon
#

but i wanna do that for xmult and chips

frosty rampart
lucid owl
frosty rampart
#

everything's in the main_start in loc_vars

solid salmon
#

it makes me want to misprint myself

frosty rampart
#

because it's dynatext

lucid owl
#

i figured it'd have some sort of translation

frosty rampart
#

it does
it calls the localize function for "k_mult"

lucid owl
#

ohh i just looked at it and it really doesnt need any

#

yeah lol

frosty rampart
#

the rest of it is just numbers pretty much

lucid owl
#

that's the only text that needs to be shown since. its only +mult

solid salmon
#

k_xmult

#

or something

#

or k_chips

#

i fricked up

#

nvm

#

i fricked up

#

its only jumping from 1.5 to 2.5

#

does anyone know where i could find the code for k_mult

lucid owl
#

send the joker's code

solid salmon
#

oh wait

#
        for i = card.ability.extra.xmult_min, card.ability.extra.xmult_max do
            r_xmults[#r_xmults + 1] = tostring(i)
        end
        local loc_xmult = ' ' .. (localize('k_mult')) .. ' '
        main_start = {
            { n = G.UIT.T, config = { text = '  X', colour = G.C.MULT, scale = 0.32 } },
            { n = G.UIT.O, config = { object = DynaText({ string = r_xmults, colours = { G.C.RED }, pop_in_rate = 9999999, silent = true, random_element = true, pop_delay = 0.5, scale = 0.32, min_cycle_time = 0 }) } },
            {
                n = G.UIT.O,
                config = {
                    object = DynaText({
                        string = {
                            { string = 'rand()', colour = G.C.JOKER_GREY }, { string = "#@" .. (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11) .. (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.suit:sub(1, 1) or 'D'), colour = G.C.RED },
                            loc_xmult, loc_xmult, loc_xmult, loc_xmult, loc_xmult, loc_xmult, loc_xmult,
                            loc_xmult, loc_xmult, loc_xmult, loc_xmult },
                        colours = { G.C.UI.TEXT_DARK },
                        pop_in_rate = 9999999,
                        silent = true,
                        random_element = true,
                        pop_delay = 0.2011,
                        scale = 0.32,
                        min_cycle_time = 0
                    })
                }
            },
        }
        return { main_start = main_start }
    end,```
granite jay
#

How do I check if a certain mod is active (Like Cryptid) in my mod?

#

Nvm found it

#

You use swift SMODS.find_mod(id)

solid salmon
#

ye

spiral mural
#

how do i get specially unscored cards?

vale zinc
wispy falcon
#

Is there a function to make a Joker move to a specific slot position?

analog marsh
#

hey guys uh

#

i wanna like

#

start modding

#

uh

#

i just wanna like

#

add more suits and ranks

#

how can i do that

wispy falcon
analog marsh
normal crest
toxic cave
#

is it possible to re-use an in-game sprite for something else? i wanna reuse ancient joker's sprite for a deck sprite

distant junco
#

please help idk why this isnt working

daring fern
toxic cave
#

thank you my glorious king

loud citrus
distant junco
#

theres no error it just doesnt do anything

loud citrus
#

i see

#

i remember return values being quite jank with this game

daring fern
distant junco
#

ah

slim ferry
#

tags dont do normal returns either

#

at least not in the way centers do

distant junco
#

what should i do then

slim ferry
#

get patching the scoring loop buddy

distant junco
#

hhhhhhhhhhhhhhhh

#

is there a list of all the context.type stuff

#

or something

loud citrus
#

or card.lua

distant junco
#

ah fuck there isnt one fuuuck

#

now im gonna have to... put effort into my code

loud citrus
#

you could do on discard like burned joker

daring fern
distant junco
distant junco
loud citrus
#

i used it in my rebaloed mod

distant junco
#

tags dont do contexts the same way otherwise my code would have worked

loud citrus
#

OH

#

that makes sense

daring fern
sturdy compass
solid salmon
#

how do i make something that affects the LAST played card

loud citrus
#

what is the G.P_CENTERS equivalent of poker hands?

sturdy compass
#

SMODS.PokerHands

toxic cave
#

im not sure if this is the correct channel to ask since im no longer in the developing part of things but
i now have a mod that works and im happy with, whats next? where do i upload the mod, etc, and does it really need a github if its 37 lines that can be contained within a screenshot or is that overkill for something that small scale

wind steppe
#

yes upload the mod to github

#

its more trustworthy when you can see the code

#

secondly you can upload it in the modding forum here or in a couple other servers

#

and if you want you can make an entry on the wiki

toxic cave
wind steppe
toxic cave
wind steppe
#

yep

spiral mural
spiral mural
#

@wispy falcon

#

(the positions need to exist)

#

And?

#

Don't be a smart ass

#

Say "There's not a function, but there's a way."

lyric maple
#

is there a function for checking if a card has an edition (in general)? backreading tells me SMODS.has_edition isn't a thing

frosty rampart
keen hinge
#

guys i dont understand what this part means, im assuming it means i can automate the version number so i dont have to keep on changing it manually but i dont really get it

#

ok i mean i understand the most part but idk if it would work for my project because i have a git containing multiple mods instead of just one

wispy falcon
golden field
#

question: how do i make a blind trigger its effect if the hand played does not contain a certain rank

frosty rampart
#

is the effect "this hand does not score" (i.e. it just throws away the cards like psychic) or something else

golden field
#

like setting money to a certain amount

frosty rampart
#

gotcha
i haven't done much with blinds but i'm pretty sure this should work
in the blind's calculate function, you'll want to do this

if not blind.disabled and context.before then
  local flag = false
  for i, v in ipairs context.full_hand do
    if v:get_id() == (the ID of whatever rank) then
      flag = true
      break
    end
  end
  if not flag then
    -- do whatever
  end
end
golden field
#

ah ok thanks

keen hinge
#

so if the mod i published to the mod manager links back to a specific folder within a git instead of the whole repository, would automatic-version-check still work or not?

golden field
# frosty rampart gotcha i haven't done much with blinds but i'm pretty sure this should work in t...

uhh

SMODS.Blind {
    key = "peach",
    atlas = 'wacleblinds',
    dollars = 5,
    mult = 2,
    pos = { x = 0, y = 4 },
    boss = { min = 1 },
    boss_colour = HEX("46a4f7"),

    calculate = function(self, blind, context)
        if not blind.disabled and context.before then
            local triggered = false
            for i, v in ipairs context.full_hand do
                if v:get_id() == 14 then
                    triggered = true
                    break
                end
            end
            if not triggered then
                ease_dollars(-G.GAME.dollars+11, true)
            end
        end
    end
}
#

-# ok nvm theres some stuff i forgot to change hold on

#

-# yep still that

#

update: i forgor to add parentheses 💀

#

it works now

vale zinc
# normal crest can you show the entire calculate function

Here's the relevant bit.

if context.end_of_round and context.game_over == false and context.main_eval and context.beat_boss then
    G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
    G.E_MANAGER:add_event(Event({
        func = (function()
            SMODS.add_card {
                set = 'Tarot',
                key_append = 'j_lapsems_witch_hunter'
            }
            G.GAME.consumeable_buffer = 0
            SMODS.calculate_effect({
                message = localize('k_plus_tarot'),
                colour = G.C.SECONDARY_SET.TAROT
            }, card)
            return true
        end)
    }))
    
    delay(0.2)
    
    G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
    G.E_MANAGER:add_event(Event({
        func = (function()
            SMODS.add_card {
                set = 'Spectral',
                key_append = 'j_lapsems_witch_hunter'
            }
            G.GAME.consumeable_buffer = 0
            SMODS.calculate_effect({
                message = localize('k_plus_spectral'),
                colour = G.C.SECONDARY_SET.SPECTRAL
            }, card)
            return true
        end)
    }))
end
normal crest
tranquil gull
#

@marble flint I GOT SOMETHING

vale zinc
tranquil gull
#

seems like it's the fault of whoever rewrote the entire implementation of scoring parameters without asking me

normal crest
tranquil gull
vale zinc
#

But here's the only other thing in calculate():

if context.setting_blind and G.GAME.blind.boss then
    return {
        message = 'X'..card.ability.extra.boss_blind_size,
        func = function()
            G.E_MANAGER:add_event(Event({
                trigger = 'ease',
                blockable = true,
                blocking = false,
                ref_table = G.GAME.blind,
                ref_value = 'chips',
                ease_to = G.GAME.blind['chips'] * card.ability.extra.boss_blind_size,
                delay =  0.6,
                func = (function(t) G.GAME.blind.chip_text = number_format(t); return t end)
            }))
        end
    }
end
normal crest
normal crest
vale zinc
normal crest
#

Same with Tarot

vale zinc
normal crest
#

Maybe just remove the color entirely...

#

try going to a game, get 1 joker and do eval SMODS.calculate_effect({ message = "hi" }, G.jokers.cards[1])

vale zinc
#

That does produce a message from my first Joker, but removing the colors in Witch Hunter's calculate() function changed nothing.

normal crest
#

you are modifying the right file and saving it, right

vale zinc
#

The src/jokers.lua file which contains all Joker information, Witch Hunter included? Yes!

normal crest
#

guess I'm gonna try your code in my pc and see what goes

#

The messages show up for me, they don't show up at the right time but they show up for sure

vale zinc
#

When do they show up?

normal crest
#

After the consumables spawn

#

But your issue was that they don't show up at all right

#

genuinely don't know why it doesn't work for you

tranquil gull
#

@marble flint i got it working kind of!
it works until it hits hash notation. omeganum doesn't know how to parse hash notation

#

..nor do i

#
    elseif n:arraySize() < 8 then
        --e12#34#56#78
        local r = (n.sign == -1 and "-e" or "e")..e_ify(math.floor(n.array[1]*10^places+0.5)/10^places).."#"..e_ify(n.array[2] or 1)
        for i = 3, n:arraySize() do
            r = r.."#"..e_ify((n.array[i] or 0)+1)
        end
        return r
    else
        --e12#34##5678
        return (n.sign == -1 and "-e" or "e")..e_ify(math.floor(n.array[1]*10^places+0.5)/10^places).."#"..e_ify(n.array[n:arraySize()] or 0).."##"..e_ify(n:arraySize()-2)
    end

time to write a parser for this

frosty rampart
#

hash notation is sbiis saibian's Hyper-E Notation
this is a bit of a dry read, but the original definition should cover pretty much the rest of what omeganum is capable of (you can ignore the extended definition section)
https://googology.miraheze.org/wiki/Hyper-E_notation

Googology Wiki

Not to be confused with Δ function.
Hyper-E Notation (E# for short) is a notation for large numbers devised by Sbiis Saibian. It was first introduced on his Web book One to Infinity: A Finite Journey on November 19, 2011, and was generalized to Extended Hyper-E Notation (xE# for short). Hyper-E Notation is a refined version of a notation Sbiis ...

tranquil gull
#

so i just need to write a parser for that then

frosty rampart
#

ya
here's a bit of demonstration to help you get started

e6.79#9 = e(e6.79#8) = e(e(6.79#7)) = ...
e3#3#3 = e3#(e3#3#2) = ...
tranquil gull
#

i mean

#

i don't need to make the number i need to make the bignum

#

which means i can num.array[i] =

frosty rampart
#

true,,,

tranquil gull
frosty rampart
#

nice

golden field
#

question: how do i make a blind have multiple effects and activate one of those effects randomly each after each hand

loud summit
#

calculate function and context.after

tranquil gull
# frosty rampart true,,,
function parse_hyper_e(num)
    local split_array = num:sub(2)
    local arr = {}
    local current_run = 0
    local i = 1
    for _, str in ipairs(Split(split_array, "#")) do
        current_run = current_run + 1
        if #str ~= 0 then
            if current_run > 1 then error("currently unimplemented") end
            current_run = 0
            local val = tonumber(str)
            if i > 2 then val = val - 1 end
            arr[i] = val
        end
        i = i + 1
    end
    return setmetatable({array = arr, sign = 1}, OmegaMeta)
end

what i've got so far

#

works round trip for everything without a ## in it

#

how do those ##'s work

frosty rampart
#
E3##5 = E3#3#3#3#3 (there are 5 3's)
Ea##b = Ea#a#a#...#a (there are b a's)
#

that expansion can happen whenever the ## is the rightmost separator

tranquil gull
#

@frosty rampart tysm

#

i'm Not doing triple # btw that sounds like a fucking headache

#
function parse_hyper_e(num)
    local split_array = num:sub(2)
    local arr = {}
    local current_run = 0
    local i = 1
    for _, str in ipairs(Split(split_array, "#")) do
        current_run = current_run + 1
        if #str ~= 0 then
            local val = tonumber(str)
            if current_run == 1 then
                if i > 2 then val = val - 1 end
                arr[i] = val
            elseif current_run == 2 then
                local last = arr[i-1]
                for _ = 1, val do
                    arr[i] = last
                    i = i + 1
                end
            else
                print("Extended Hyper-E notation for # > 3 is currently unsupported. Returning Infinity.")
                return math.huge, true
            end
            current_run = 0
            i = i + 1
        end
    end
    return setmetatable({array = arr, sign = 1}, OmegaMeta)
end
frosty rampart
#

triple # is basically the same as double # but it expands to a bunch of double #s
but yea you don't need to do it for balatro purposes because that's far beyond what omeganum is capable of

tranquil gull
#
i = i + 1
if i > 4000 then
    -- This number is way too big. Bail.
    return math.huge, true
end
young leaf
#

is there a way to add ban your own items for vanilla challenges?
i would like to add my mod's tags to the list of banned tags in Jokerless

tranquil gull
#

@marble flint i got lua joker up to e10#10##10000, aka 10{10000}10

#

wait. mutual servers. something something why are you also at the devils sacrament

marble flint
grand sage
#

Im trying to do Crossmod stuff and i believe i did something wrong could anyone help me?

tranquil gull
#

make a .json file

#

please

winter flower
granite jay
#

Is there a way to make it so a Joker's rarity depends on settings?

grand sage
grand sage
daring fern
granite jay
#

Oh thx

#

Anyone know how to make a boss blind sprite twice as big?

chrome widget
#

I'm trying to look into doing talisman compatibility against my better judgement, what exactly do you need to use the to_big() function for? Just any value that could contribute to scoring?

grand sage
#

i fixed the {} issue but i did something wrong with my Compats/Crossmods as it keeps giving me attempting to call a nil value error

golden field
#

why does it crash

daring fern
golden field
#
SMODS.Blind {
    key = "knife",
    atlas = 'wacleblinds',
    dollars = 5,
    mult = 2,
    pos = { x = 0, y = 21 },
    boss = { min = 1 },
    boss_colour = HEX("A391CE"),
    calculate = function(self, blind, context)
        if not blind.disabled then
            if context.modify_hand then
                blind.triggered = true 
                mult = mod_mult(math.max(math.floor(mult - G.GAME.hands[text].played), 1))
                update_hand_text({ sound = 'chips2', modded = true }, { mult = mult })
            end
        end
    end
}
daring fern
stiff glade
#

Aaaaughh, been at this for HOURS trying to figure out why a sound wont trigger, finally gonna ask for help.

Oops! The game crashed:
Thread error (Thread: 0x020ddab161f0)

Could not open file resources/sounds/Key:Nuke_Boom.ogg. Does not exist.
stack traceback:
[C]: at 0x7fff57e558a0
[C]: in function 'newSource'
engine/sound_manager.lua:63: in function 'PLAY_SOUND'
engine/sound_manager.lua:197: in main chunk

grand sage
# granite jay BRUH

like in game or just the sprite because i dont know how to do it in game but if you wanna make the sprite (more detailed) bigger just double the sprite dimensions in the code so where its like x= and y= double those

stiff glade
daring fern
stiff glade
daring fern
stiff glade
granite jay
#

It’s used in collection and blind selection screen but not here

granite jay
golden field
tranquil gull
#

do you know what a string is

stiff glade
tranquil gull
#

you need to know lua to use lua

#

read up

#

end of chapter 16 is a good stopping point

#

but also read 19 and 20

tranquil gull
granite jay
tranquil gull
#

if thats not supported then i bet it's a big hassle snd you[re better of downscaling (or better, redrawing at a lower scale) the blind texture

#

path of least resistance

urban wasp
#

is something off here? i can't for the life of me figure out why i can't use this consumable on a joker with the fused rarity

can_use = function(self, card)
    local highlighted = G.jokers.highlighted or {}
    if #highlighted < 1 or #highlighted > card.ability.extra.max_highlighted then
        return false
    end
    local joker = highlighted[1]
    return joker.rarity == "bfs_fused"
end,
daring fern
daring fern
#

‎

granite jay
#

Is there a way to make the Blind reward have custom text instead of money?

#

Cos I made it so if you defeat that Blind, you get a very good Joker as a reward

#
SMODS.Tag {
    key = "dyle",
    pos = { x = 0, y = 2 },
    apply = function(self, tag, context)
        if context.type == 'new_blind_choice' then
            local lock = tag.ID
            G.CONTROLLER.locks[lock] = true
            tag:yep('+', G.C.GREEN, function()
                G.from_boss_tag = true
                G.FUNCS.reroll_boss()

                G.E_MANAGER:add_event(Event({
                    func = function()
                        G.E_MANAGER:add_event(Event({
                            func = function()
                                G.CONTROLLER.locks[lock] = nil
                                return true
                            end
                        }))
                        return true
                    end
                }))

                return true
            end)
            tag.triggered = true
            return true
        end
    end
}```
Anyone know how to make it so the reroll always lands on a specific Boss Blind?
granite jay
granite jay
#

I'll replace the 1 with G.GAME.round_resets.ante and see how that works tomorrow

winter flower
#

OH WAIT

#

IM FUCKING STUPID

daring fern
granite jay
#

Oh thx

granite jay
granite jay
stiff locust
#

chat i got a really weird issue to fix

#

one of my jokers is unaffected by the eternal sticker when I apply it

#

as in it can be sold or destroyed by other jokers as if it didn't have eternal

#

even though i used the same method as i did on several other jokers its just this one that breaks it

#

wait i'm stupid no I didn't

#

i used the wrong method to apply it

#

ok its fine

#

nevermind that it has decided not to apply the sticker now

#

ok the issue appears to actually be that the joker doesn't like stickers being put on it

#

i can't even give it one with debugplus

#

i figured it out

#

it had eternal compat off oops

#

my insane ramblings cannot be accompanied by gifs for they are blocked

maiden phoenix
#

I was thinking that and was like "Nah she couldn't have forgotten that"

tired kestrel
#

why does this lovely patch doesn't work? the print function doesn't show up at all

tired kestrel
#

what is this what am I doing wrong now?

golden field
#

question: what's the set name for stickers

tired kestrel
sturdy compass
solid salmon
#

hey guys

#

i dont know how to ui

slim ferry
#

hit up the steamodded ui page

#

and besides that theres like nothing

#

figure it out from other mods ig đŸ€·

solid salmon
#

i just wanna add button that transforms a card

#

(kinda like fusion)

loud citrus
#

i'm trying to create a system where the joker tracks if you've play a flush or a straight, after doing both you get a spectral card, a rework of seance.

dose someone know why my flush_done and straight_done parts of my code aren't functioning the way i'm intending? it gives the spectral card without having checked if the other poker hand has been played.

normal crest
#

uhm you're using {} in your condition

#

presumably they're meant to be parenthesis

#

@loud citrus

short girder
#

would this work for destroying cards of x rank before the scoring happens

daring fern
loud citrus
short girder
wintry solar
#

Use context.before and put the cards you want to destroy into SMODS.destroy_cards

short girder
#

kayyy thanks eremel

vale grove
#

iam trying to make a joker that flips the base and chips mult, context.before changes it back and context.modify_hand makes the blind icon spin around, what would be the correct solution to this?

faint yacht
#

Swaps?

#

return { swap = true }

vale grove
#

because context.before doesnt work(instantly swaps it back)
and modify_hand makes the blind icon spin for some reason

faint yacht
#

context.initial_scoring_step

granite jay
#

Anyone know how to make a Joker debuff a random card in your hand when played?

#
SMODS.Joker{
    key = "shrimpo",
    atlas = 'dwJoker',
    pos = { x = 0, y = 6},
    soul_pos=nil,
    rarity = 1,
    cost = 1,
    config = { extra = {} },
    blueprint_compat=true,
    eternal_compat=true,
    perishable_compat=true,
    unlocked = true,
    discovered = true,
    calculate = function(self,card,context)
        if context.before then
            local scored_card = pseudorandom_element(context.scoring_hand, "dw_shrimpo")
            G.E_MANAGER:add_event(Event({
                func = function()
                    scored_card:juice_up()
                    scored_card:set_debuff(true)
                    return true
                end
            }))
            return {
                message = localize('k_debuffed'),
                colour = G.C.RED,
                sound = "tarot2",
            }
        end
    end,
}```
I have this code which makes the card display work, but the scoring treats the debuffed card as if it wasn't debuffed.
frosty rampart
#

i think you have to move the set debuff call out of the event

#

although that might mess with the timing of some visuals

strong plume
#

First time coding a tag - the effect works normally, but it softlocks the game after adding the cards; anyone knows why?

spiral mural
#

how do i get the cardarea of a card

normal crest
spiral mural
normal crest
#

i don't remember what the 90 or 'up' are for

#

they may not even be necessary

spiral mural
#

the card

#

SMODS?

normal crest
#

nah it's just a global function, I think if you want to move a specific card there's an additional parameter

#

Don't have the source code available rn so you'll have to check yourself

#

but that function is from cardarea to cardarea

slim ferry
#

You can also just use CardArea:emplace(card)

#

Usually

normal crest
strong plume
#

oh bruh ty, that makes sense lol idk how that slipped me

normal crest
#

Also you might be able to replace your creating card logic with local _card = SMODS.create_card { set = "Base", enhancement = "m_gold", edition = "e_bstuck_paradox" }

rigid solar
#

So I've noticed music plays slower than the given file. How would I go about making my music play regularly? Either through code or modifying the file itself, I just don't want it to be giga slow lol

#

At first I thought it was playing at half the speed but it's not the case it's faster than that
edit: nvm found my answer, just set pitch and volume to 1

rich pollen
#

I need help.

I'm making a quick/shitty sprite sheet for my mod im making that way i can test and learn how to write my content. I have 4 cards in the 1x format done. What is the best method to convert it to 2x???

Im using Krita at the moment.

river grail
# rich pollen I need help. I'm making a quick/shitty sprite sheet for my mod im making that w...

What you can do is Image > Scale Image to New Size, and it'll let you resize the sheet into any given number

to make a 2x version, you should set the px move to %, meaning if you type in 200 instead of 100, the image will double in size
IMPORTANT: Keep the filter to Nearest Neighbor, so that there's no blurring or blending between the pixels!

then you can export the 2x image, and then CTRL + Z to undo the image resizing

solid salmon
#

is there a context for beating blinds in first hand?

spiral mural
#

what's the final context before the hand's score gets added

umbral zodiac
daring fern
#

‎

versed merlin
#

is there a way to check what position card is being scored currently

daring fern
dapper sun
#

how do i get the current chips/mult?

daring fern
dapper sun
#

ty

#

is that G.GAME?

daring fern
dapper sun
#

ok

versed merlin
wispy falcon
#

To make a shader deform a card like this, would I need to draw the shader on the layer of the card, that is the white in the background or how would I make that?

daring fern
versed merlin
#

excluding joker retriggers

versed merlin
versed merlin
#

trying to get this latch to work with retriggers, so the joker only triggers on the first card but it will trigger twice on a retrigger

#

latch prevents it from retriggering

#

my thought was like reset the latch if you're scoring the same position card twice in a row

pastel kernel
#

@unkempt thicket you said i can borrow your martellino code, right? how do i change it to fit a consumable card?

SMODS.Consumable {
    key = 'mugen',
    set = 'Spectral',
    atlas = "atlas_Slumber",
    pos = { x = 0, y = 0 },
    soul_rate = 0.1,
    can_repeat_soul = true,
    soul_set = 'Spectral',
    loc_txt = {
        name = "MUGEN",
        text = {"Create a joker of {V:1}your choice{}."}
    },
loc_vars = function(self, info_queue, card)
        return { vars = { colours = {SMODS.Gradients["busterb_Epileptic"]} } }
    end,
    use = function(self, card, area, copier)
        local eval = function(card) return (card.ability.loyalty_remaining == 0) and not G.RESET_JIGGLES end
                juice_card_until(cardd, eval, true)
        if #G.jokers.cards <= G.jokers.config.card_limit then 
            G.SETTINGS.paused = true
            G.FUNCS.overlay_menu{
              config = {no_esc = true},
              definition = SMODS.jest_no_back_card_collection_UIBox(
                  G.P_CENTER_POOLS.Joker, 
                  {5,5,5}, 
                  {
                      no_materialize = true, 
                      modify_card = function(card, center) 
                          card.sticker = get_joker_win_sticker(center) 
                          if card.config.center.discovered then
                            jest_create_select_card_ui(card, G.jokers)
                          end
                      end, 
                      h_mod = 1.05,
                  }
              ),
            }
      end
    end
}
unkempt thicket
#

To get a Consumable instead of a Joker? if so look at Morio

pastel kernel
unkempt thicket
#

I mean morio's code

pastel kernel
#

morio?

unkempt thicket
pastel kernel
#

oh i meant to spawn jokers

#

ok let me try to rephrase myself

frosty rampart
#

you want a consumable that can spawn jokers from a menu
reference paperback's apostle of wands

#

(it also uses all in jest code)

frosty rampart
#

it shouldn't be hard to pick through the code and find what hides legendary+ jokers from the menu

pastel kernel
#

what's PB.UTIL

unkempt thicket
#

Did you also grab the UI code for it?

frosty rampart
pastel kernel
unkempt thicket
#

Is its name SMODS.jest_no_back_card_collection_UIBox ?

pastel kernel
#

yea

#

do i need to add my own ui functions?

unkempt thicket
#

It probably be better to change the prefix, did you also add jest_create_select_card_ui?

pastel kernel
#

yes

#

so i still have to add ui functions?

unkempt thicket
#

If you didn't add them

#

Are you calling the one aij uses or a copy?

pastel kernel
#

aij

unkempt thicket
#

If its not the latter thats probably the problem

pastel kernel
#

i'm using marty's code

unkempt thicket
#

Try copying the UI functions and change the prefix.

pastel kernel
#

is it this one?

#
function create_joker(card_type,tag,message,extra, rarity)
#

wait

pastel kernel
unkempt thicket
#

Yea line 263

#

So line 263-439 and line 529-547 in Utils/UI

pastel kernel
#

line 263?

#

this? ```lua

      return true
    end
  }))
end

end
G.FUNCS.jest_gold_tags = function(e)
if G.GAME.jest_upgrade_tab then
G.GAME.jest_upgrade_tab = false
else
G.GAME.jest_upgrade_tab = true
end
end
function jest_create_select_card_ui(card, area, extra_data)
extra_data = extra_data or {}
extra_data.copies = extra_data.copies or 1
local t2 = {n=G.UIT.ROOT, config = {ref_table = card, minw = 0.6, maxw = 1, padding = 0.1, align = 'bm', colour = G.C.GREEN, shadow = true, r = 0.08, minh = 0.3, one_press = true, button = 'jest_select', data = {area, extra_data}, hover = true}, nodes={
{n=G.UIT.T, config={text = "Select",colour = G.C.WHITE, scale = 0.5}}
}}

card.children.select_button = UIBox{
    definition = t2,
    config = {
        align="bm",
        offset = {x=-0,y=-0.15},
        major = card,
        bond = 'Weak',
        parent = card
    }
}

end
function jest_create_select_playing_card_ui(card, area, extra_data)
extra_data.times = extra_data.times or 0
extra_data.copies = extra_data.copies or 1
local t2 = {n=G.UIT.ROOT, config = {ref_table = card, minw = 0.6, maxw = 1, padding = 0.1, align = 'bm', colour = G.C.GREEN, shadow = true, r = 0.08, minh = 0.3, one_press = true, button = 'jest_continue_select', data = {area, extra_data}, hover = true}, nodes={
{n=G.UIT.T, config={text = "Select",colour = G.C.WHITE, scale = 0.5}}
}}

card.children.select_button = UIBox{
    definition = t2,
    config = {
        align="bm",
        offset = {x=-0,y=-0.15},
        major = card,
        bond = 'Weak',
        parent = card
    }
}

end

#

line 263 is blank

#

Should this work?lua SMODS.Consumable { key = 'mugen', set = 'Spectral', atlas = "atlas_Slumber", pos = { x = 0, y = 0 }, soul_rate = 0.1, can_repeat_soul = true, soul_set = 'Spectral', loc_txt = { name = "MUGEN", text = {"Create a joker of {V:1}your choice{}."} }, loc_vars = function(self, info_queue, card) return { vars = { colours = {SMODS.Gradients["busterb_Epileptic"]} } } end, use = function(self, card, area, copier) if #G.jokers.cards <= G.jokers.config.card_limit then G.SETTINGS.paused = true G.FUNCS.overlay_menu{ config = {no_esc = true}, definition = SMODS.busterb_no_back_card_collection_UIBox( G.P_CENTER_POOLS.Joker, {5,5,5}, { no_materialize = true, modify_card = function(card, center) card.sticker = get_joker_win_sticker(center) if card.config.center.discovered then busterb_create_select_card_ui(card, G.jokers) end end, h_mod = 1.05, } ), } end end }

pastel kernel
#

Do I really need to borrow all this just to make a spectral card?

unkempt thicket
pastel kernel
#

It works but then I can’t play a hand.

unkempt thicket
#

Just copy the functions with these names SMODS.jest_no_back_card_collection_UIBox, G.FUNCS.jest_select, jest_create_select_card_ui

pastel kernel
#

Thx

#

Im going to test it out now

pastel kernel
unkempt thicket
#

I'm not sure why, if you have all the UI functions it should be working.

unkempt thicket
#

Do you have any other mods enabled? Everything you have seems to be right.

pastel kernel
#

A lot of mods yeah

#

I should put my mod priority to at the very last

ivory citrus
#

Hello

#

anyone knows how can i use localize?

pastel kernel
#

I just found out they have exclusive funcs for apostle of wands so i'm using that instead. how do i use it tho?```lua
can_use = function(self, card)
return #G.jokers.cards < G.jokers.config.card_limit
end,

use = function(self, card, area, copier)
if #G.jokers.cards < G.jokers.config.card_limit then
G.SETTINGS.paused = true

    G.FUNCS.overlay_menu {
      config = { no_esc = true },
      definition = mugen_apostle_of_wands_collection_UIBox(
        selectable_jokers,
        { 5, 5, 5 },
        {
          no_materialize = true,
          modify_card = function(other_card, center)
            other_card.sticker = get_joker_win_sticker(center)
            busterb_create_select_card_ui(other_card, G.jokers)
          end,
          h_mod = 1.05,
        }
      ),
    }
  end
end
#

ok this shit keeps happening, i can't make a move anytime i use the card.

pastel kernel
#

IT WORKS

loud citrus
#

the game keeps crashing because my loc_vars is invalid... i don't know what i'm doing lol

feral tree
#

is there a way to detect if any joker gets added or removed in general?

daring fern
feral tree
#

and the opposite is just context.card_removed?

daring fern
pastel kernel
#

i need to legally ask first

chrome widget
#

hmmm I'm having to do someting to specifically retrigger seal effects, I'm sure I can find a specific way to do this universally

chrome widget
#

Something like this......

lyric maple
#

the error says "attempt to index upvalue chosen_joker"

    use = function(self, card, area, copier)
        local applicable_jokers = {}
        for _, joker in pairs(G.jokers.cards) do
            if not card.edition == nil then applicable_jokers[#applicable_jokers + 1] = joker end
        end
        local chosen_joker = pseudorandom_element(applicable_jokers, 'ang_choice')
        G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.4,
            func = function()
                local random_edition = poll_edition("ijsj_ang", nil, true, true)
                chosen_joker:set_edition(random_edition, true)
                card:juice_up(0.3, 0.5)
                return true
            end
        }))
    end,
daring fern
lyric maple
#

also is poll_edition automatically seed-dependent?

warm solar
#

is there a way to make a joker that does something only if the current hand's mult is higher than x?

#

nvm i got it

spring lantern
#

y'all know how context.card_added works? never knew about it before and thought it would be super helpful but it's not triggering the upgrade rn

#

wait i'm stupid

#

i think i may have outdone myself here

#

aand it works now

#

wait it also counts consumables

#

eh i'll change the text and call it a feature

normal crest
spring lantern
#

ohh sweet thanks!

normal crest
pastel kernel
solid salmon
#

-- Makes all 7s be treated as Steel and Gold
if context.check_enhancement and context.other_card.base.value == "7" then
return {
m_gold = true,
m_steel = true
}
end

Guys what does this code actually do? does it give the enhancement abilities?

#

guys

#

is there a way to check if held in hand cards have a certain enhancement

mystic river
solid salmon
#

figured it out

vale grove
#

how do you add a soul over a card?

slim ferry
#

soul_pos

vale grove
slim ferry
#

cant

#

soul sprite just uses the same atlas

#

as main sprite

vale grove
#

so i put my soul sprite in the jokers.png?

slim ferry
#

yeah

vale zinc
#

Running SMODS.add_card(G.hand.cards[1]) doesn't produce the card that I expected to produce. What do I do to ensure that I'm picking the right card?

slim ferry
#

you shouldnt be using add_card to copy a card regardless

#

use copy_card

#

see vanillaremade dna

vale zinc
#

I was looking at VanillaRemade Cryptid instead.

#

And Ortalab's Rouge Rose.

slim ferry
#

...those also use copy_card

#

At least they should

vale zinc
#

Rouge Rose uses SMODS.add_card(), Cryptid uses copy_card().

slim ferry
#

That is because rouge rose does not copy any cards

tired otter
#

Chat how do i make the core lua file load stuff from a different lua?

#

Like i have a Joker.lua file but it dosen't load stuff, it only loads them from the main lua file

frosty rampart
#

you have to put code in the main lua file to load the joker lua file

tired otter
#

oh alright, thanks!

ashen drift
#

assert(SMODS.load_file('/yourpathrelativetothemodfolder.lua'))()

tranquil gull
#
--[[
    WARNING!!!!

    MESSING WITH THE INTERNAL
    FIELDS OF THIS STRUCT
    THAT ARE NOT EXPOSED USING METHODS
    MAY CAUSE UNDEFINED BEHAVIOR
    AND / OR SEGFAULTS.

    BE RESPONSIBLE.
]]


local ffi = require "ffi"

ffi.cdef [[
    typedef double Layer[2];
    typedef struct {
        size_t arrayCapacity; 
        size_t arrayLength;
        size_t layer;
        int sign;
        Layer * arrayBuffer;
    } ExpantaNum_t;
]]

chat am i cooking or am i cooked

#

something something ffi.metatype

#

if this does end up getting finished then people might start seeing "error: attempted to compare number with cdata" instead of "error: attempted to compare number with table" (but hopefully not)

#

cdataman? in my talisman? it's more likely than you think

#

i love malloc

hardy viper
#

idk if you have Observed

tranquil gull
#

this is omeganum

#

i want higher.

hardy viper
#

i mean like

#

cdata comparison metamethods work w numbers

#

also you can probably just make the stuff that has invariants private

#

or just the entire struct

gusty compass
#

How would I utilise dotted characters for SMODS.Language, since so far it doesn't seem to be working as intended unless there is some workaround

slim ferry
#

you need to use an SMODS.Font for any characters not supported by the base balatro font, just like the vanilla languages that use a non-roman alphabet

sudden stratus
#

Hi, I'm new to modding and I've been trying to get a Joker to recognise, which card has been destroyed/added if it happens, but I only got gibberish as an output. Can someone with a higher understanding explain to me, what I'm doing wrong?

current calculate function of the joker:

calculate = function(self, card, context)
    if context.remove_playing_cards and not context.discard then 
        sendInfoMessage("removed playing card", "MyInfoLogger")
        sendInfoMessage(tableToString(context.removed), "MyInfoLogger")
    end
    if context.playing_card_added then 
        sendInfoMessage("added playing card", "MyInfoLogger")
        sendInfoMessage(tableToString(context.cards), "MyInfoLogger")

    end


end

output (I destroyed a 2 of Diamonds with hanged man, and copied a 5 of clubs with cryptid):

2025-12-09 19:42:39 :: INFO  :: MyInfoLogger :: removed playing card
2025-12-09 19:42:39 :: INFO  :: MyInfoLogger :: {1 = table: 0x1b27a5a8, }
2025-12-09 19:44:01 :: INFO  :: MyInfoLogger :: added playing card
2025-12-09 19:44:01 :: INFO  :: MyInfoLogger :: {1 = table: 0x1adf60b8, 2 = table: 0x1abb49d0, }

the tableToString function (I stole from https://luascripts.com/lua-table-to-string):

function tableToString(tbl)
    local result = "{"
    for k, v in pairs(tbl) do
        result = result .. tostring(k) .. " = " .. tostring(v) .. ", "
    end
    result = result .. "}"
    return result
end
slim ferry
#

cards are tables

#

theresfore it simply prints out the table into the logger, which is just a memory adress

#

using print while having debugplus installed would actually expand the card table to show contents

sudden stratus
#

well, I do have debug++ installed, but how do this?
do I just replace it with print(tableToString(context.removed)) and do I need to do anything in debug++?

slim ferry
#

there is a setting for it in debugplus

#

but its enabled by default iirc

weary merlin
#

trying to make a joker which removes reroll cost scaling for non-free rerolls
thinking of using add_to_deck and remove_from_deck methods for this, but I don't know what I would call to prevent the reroll cost from incrementing

in other words
how do i get/set the current reroll cost
how can i interrupt the reroll cost increment

weary merlin
#

wait can't I just hook calculate_reroll_cost(skip_increment) where skip_increment is true

#

couldn't i just

calculate
shop reroll and not blueprint
calculate_reroll_cost(true)

#

hmm i'll have to try that

weary merlin
#

yeah i have no clue how to hook here

daring fern
# weary merlin yeah i have no clue how to hook here
local oldcalculatererollcost = calculate_reroll_cost
function calculate_reroll_cost(skip_increment)
    if conditions then
        return oldcalculatererollcost(true)
    end
    return oldcalculatererollcost(skip_increment)
end
#

Also you would put it outside of the joker.

white hull
#

hey how would i return a message from the add_to_deck function?

#

as in have a joker say something when it's obtained