#💻・modding-dev

1 messages · Page 651 of 1

granite bane
#

how

#

oh

loud summit
#

modded rarities

#

its really not super hard

granite bane
#

this would work but I kind of want to make it so that only the SHOP cards are limited this way

granite jay
#

Is there any way to make it play a custom sound or nah?

granite bane
#

(so not packs or tarot-made ones)

red flower
#

P_CENTERS is not an array btw

granite bane
#

oh

#

oof

#

well then how do I loop over it?

red flower
granite jay
#

Ah ok

red flower
granite bane
#

that's not much context

#

is that after P_CENTERS?

faint yacht
#

for k, v in pairs(G.P_CENTERS) do

loud summit
# loud summit its really not super hard
local ranks = {}
for _, playing_card in ipairs(G.deck.cards)
    if not SMODS.has_no_rank(playing_card) then
        local r = playing_card.base.id
        ranks[r] = (ranks[r] or 0) + 1```
faint yacht
granite bane
loud summit
#

yes

faint yacht
#

v.rarity ~= 1 and G.GAME.banned_keys[k] = true

shell timber
#

could you just change the spawn rates for the rarities?

granite bane
#

yeah that would be better if I can do that

#

Ideally I want the other rarities to still be available outside of shop

#

spawn rate changing would probably be most Ideal

#

and then rare skips would still function

obtuse wraith
#

@loud summit circle what shoud be changed.

red flower
#

G.GAME.rare_mod = 0
G.GAME.uncommon_mod = 0

loud summit
#

add "do" after the ipairs call

faint yacht
#
debuff_hand = function(self, cards, hand, handname, check)
    for k, v in ipairs(cards or {}) do
        if SMODS.has_no_rank(v) then return false end
    end
    return true
end

as example.

loud summit
#

and two "end" after the ranks[r] line

red flower
lyric wadi
#

still doesnt add the bonus :(

loud summit
red flower
lyric wadi
faint yacht
#

Don't think context.main_scoring fits for this, then.

red flower
#

can people follow my instructions

#

other card is not a thing

faint yacht
#

-# Actually, exhausted, that's me done for now- 😵‍💫

obtuse wraith
loud summit
#

wait you need to put that in a function

red flower
obtuse wraith
scenic ether
#

hey i have some prior knologment of codding and i wanted to create a deck is there a video or tutorial where i can learn how to do it?

scenic ether
#

it seen i dont have the permition to see that channel

red flower
#

its a public channel

#

if it says unknown click on it

scenic ether
#

ok

obtuse wraith
loud summit
#

uh

#

under pos put calculate = function(self, context)

#

and put another end after the last one

obtuse wraith
loud summit
#

no what

#

look at vanillaremade

obtuse wraith
loud summit
#

uea

obtuse wraith
loud summit
#

ya

obtuse wraith
#

...I regret doing this early. Give me a hint.

loud summit
#

do you understand context blocks

obtuse wraith
loud summit
#

so function() opens a context

#

and everything between it and a end statement is in the function

#

for [] do ... end is also a context

#

if [] then ... end is also one

#

everything in the ... is considered part of that for or if statement

red flower
#

there's not much hint that can be given if you don't understand basic lua

obtuse wraith
#

Guess I have to insert "playing card" or "rank"

loud summit
#

what

obtuse wraith
loud summit
#

what does that even mean

#

how much like basic coding knowledge do you have

red flower
#

I would really recommend doing a simpler thing, anything else is just asking someone to code it for you or spend a lot of time on speed teaching you the basics

obtuse wraith
#

Better get some hour of code thing at some point. Right now doing this is like playing The Lost without the Holy Mantle and having tears that move in a drunk motion.

mystic river
#

they indicate syntax errors in your code

obtuse wraith
lament agate
#

what does glass_trigger do

shrewd cobalt
daring fern
glass scaffold
#

Is it possible to have the game play a sound when some specific Jokers are held?

granite jay
#

Is there any way to make it so certain cards are added back to deck after discard/play?

daring fern
glass scaffold
daring fern
glass scaffold
daring fern
glass scaffold
naive agate
#

how can I make a card have a 1 in 2 chance to not score (including from jokers and editions)

lament agate
daring fern
subtle hawk
#

If you want it to be when the card scores instead you'll probably want to hook something tho. Maybe multiple things, depending on what exactly you're doing?

#

I kinda want to look into how cards score now lol

naive agate
#

gotcha

round lion
#

how do i make custom tooltips, vanillaremade only shows how to append a existing card's description

slim ferry
#

look at diet cola tooltip

#

or perkeo tooltip

subtle hawk
#

Perkeo has a unique tooltip?

#

I don't remember

slim ferry
#

Negative consumable tooltip

subtle hawk
#

How are hands on this screen sorted? Could I somehow get position of a played hand on it?

daring fern
subtle hawk
#

Ty

wild patrol
#

Also thinking of adding random enhancements

bold gyro
#

how do i take_ownership of an object in order to remove it? i swore at some point i've seen something along the lines of SMODS.<type>:take_ownership('name'):remove()

daring fern
daring fern
#

primal robin
#

Add smal description what kind of issue in each message, clicking on messages and wait it to load sucks

white hull
frosty dock
#

might be a smods bug, I'll have a look

white hull
#

My mod is the only one loaded in this clip so maybe a smods thing

#

And this happened with several other mods I've played, though I can't tell you which specific ones

red flower
#

does negative nancy have a tooltip for negative usually?

white hull
#

Yep

red flower
#

my guess is that it's trying to create that but it can't so the dynatext object is just stuck there

white hull
#

Sounds plausible

slim ferry
#

Thats just an issue with recursive tooltips in general for decks iirc

white hull
#

There was a mod that included playing card objects in a tooltip, and those playing cards would just spawn in the corner

slim ferry
white hull
#

And they'd spawn infinitely if you kept hovering over the tooltip

red flower
#

funny

white hull
frosty dock
#

there's an old-ish issue that claims it does, but that seems to be untrue now

#

might be specific to things that these tooltips don't handle in vanilla

slim ferry
#

Huh

#

I recall it being a thing at least

#

Might be fixed then

frosty dock
#

anyways what are you even doing if you're not using galdur

red flower
#

there was an issue of some tooltips flashing for a bit that i pr'd a fix for

white hull
frosty dock
#

yes actually

#

because these tooltips aren't hover tooltips when you use galdur

#

they're just plain old tooltips attached to the main infobox

white hull
#

Oh interesting

#

I just saw this text in the corner fairly frequently when playing various mods and I never knew what caused it

#

Sometimes it would say nil or just like a random word related to the mod

#

But now I made my own deck and it's clear that it's an info queue thing I guess

red flower
#

not necessarily, it's just a dynatext that's orphaned other mods can have that issue for other reasons

#

in this case it's probably because of the info queue tho since smods changed them to have name styling

frosty dock
#

ok i think i see what's happening

#

this specific display is handled somewhere in vanilla code smods has never touched

#

that code, of course, having no reason for it, doesn't support additional info boxes

white hull
#

But it also doesn't ignore them completely?

frosty dock
#

the DynaText still gets created, it still runs a full generate_card_ui after all

#

it just doesn't tell the UI to render them anywhere

white hull
#

Interesting

#

Why does it go in the corner though

frosty dock
#

because that's the default

white hull
#

And it's not like completely stuffed in the corner, there's spacing

red flower
#

that's 0,0 i think

white hull
#

Funky

frosty dock
#

the UI element has spacing around it

#

as it would otherwise have too

#

the only difference is that we didn't tell it where to go

#

so it went to the corner instead

#

it's not fully inside the corner because both locations are based on top-left corners, i think

white hull
#

Interesting :P

frosty dock
#

anyhow I'll track this as an issue on the smods repo for now

#

not gonna be top priority since it only occurs when you for some reason don't use galdur

white hull
#

Lol good to know, thank you

frosty dock
#

also i guess i can close #1010 now, which I didn't notice before

wanton jolt
#

card.context.after is after scoring right

slim ferry
#

its just context.after

#

But yes

wanton jolt
#

right right

#

idk why i typed card here

#

whats the order of activation between context.after and context.joker_main

red flower
#

joker first after after

#

:3

slim ferry
#

between those context.final_scoring_step

red flower
#

they should be ordered in the contexts page

wanton jolt
#

and the game ends after that

red flower
#

scoring? yes

wanton jolt
#

after context.after

red flower
#

yeah thats the last context in scoring

wanton jolt
#

ok cool

slim ferry
#

Isnt context.destroy_card after that too

red flower
#

destroy_card is just before after iirc

slim ferry
#

I dont think so?

#

I use context.after to mark cards to be destroyed for stuff that destroys random cards

#

And that works

red flower
#

im checking evaluate_play and it is after last

#

always very funny to see

slim ferry
#

Wait

#

Does that mean

#

That that just doesnt localize

white hull
#

how can i juice up the deck?

frosty dock
red flower
white hull
#

so G.deck.cards[1]:juice_up() ?

red flower
#

yeah

white hull
#

let's see

red flower
#

if it doesnt exist you can do the area itself too

#

but it looks bad when there are cards

white hull
#

Interesting lol

#

If I have a deck that starts you with a joker by specifying jokers in config, how can I guarantee that it won't have an edition?

red flower
#

i dont think you can

white hull
#

damn.

daring fern
white hull
#

Just generally or is using jokers in config okay?

daring fern
white hull
#

Yeah makes sense

white hull
#

I like this function

#

🙏

wild bison
#

Hey, is there a way for me to check what rarity a joker has? I want to make a consumable that gives a joker of the same rarity of the joker you have selected, but I cannot find a way to check the selected joker’s rarity.

daring fern
wild bison
#

Thank you very much!

white hull
#

Why does get_current_pool('Edition') also return UNAVAILABLE as an edition? Is there another way to get a list of editions?

slim ferry
#

get_current_pool always does this

#

things that cant spawn get replaced with UNAVAILABLE

white hull
#

It doesn't do this with "Enhanced" or "Seal" as the argument though

#

When I run it in the DebugPlus console at least

slim ferry
#

yeah because all enhancements and seals can always spawn in vanilla

white hull
#

So then what's this fifth edition that can't spawn? Base?

slim ferry
#

but edition has e_base (no edition) in the pool as well and that cant spawn from edition generation

#

yeah

white hull
#

Interesting

red flower
white hull
#

Let's see

tawdry bloom
#

im trying to make a joker that gives money at the end of round equal to its sell value, im 99% there but i cant figure out how to access the jokers sell value, does anyone know how?

red flower
#

joker.sell_cost

tawdry bloom
#

i tried that but it crashes

red flower
#

may i see

#

the crash and the code

tawdry bloom
#

this is my code

SMODS.Joker{
key = "myfirstjoker",
config = { },
pos = { x = 0, y = 0 },
rarity = 2,
cost = 6,
blueprint_compat = true,
eternal_compat = true,
unlocked = true,
discovered = true,
effect = nil,
atlas = 'myfirstjoker',
soul_pos = nil,

calculate = function(self,card,context)
    if context.end_of_round then
        ease_dollars(joker.sell_cost)
    end
end,

loc_vars = function(self, info_queue, card)
    return { }
end

}

red flower
#

joker would be card in this instance

tawdry bloom
#

ahh

red flower
#

also do you want to give money during round eval?

tawdry bloom
#

before eval

red flower
#

ah ok

tawdry bloom
#

it gave me money but instead of the sell cost (3), it gave me ~50

red flower
#

you're missing context.end_of_round and context.main_eval

slim ferry
#

does running table.unpack on an empty table act as returning nil

#

asking because im putting a table.unpack output into math.min and the table can be empty

red flower
#

seems like it

slim ferry
#

wait i forgor

#

i can just put it as the last argument and then it doesnt matter because there wont be nils in the middle

#

why the fuck is table.unpack a nil value

#

oh thats a 5.2 thing

#

silly me

red flower
#

yeah its just unpack

mystic river
white hull
#

Oh whaaaaaat

#

Yeah I don't have it in the latest release

#

So I guess for now I'm removing the UNAVAILABLEs myself lol

slim ferry
#

-# or you could do a little SMODS.get_clean_pool = SMODS.get_clean_pool or <copy of SMODS.get_clean_pool from dev>

white hull
#

It's fine

tawdry bloom
#

how do i set the edition of a playing card

#

and can they be negative

frosty rampart
#

card:set_edition("edition_key") (where card is the relevant card object and is probably called something different than card)
and yes, the key for negative is e_negative

white hull
#

and they're even (mostly) bug-free as of the latest release!

ripe thicket
#

I've been trying to make exponential chips but I keep getting the crash error that I'm performing arithmetic on global 'chips' (a nil value)
I basically copied what I did with my exponential mult jokers which work just fine so I'm not sure what's different for chips

granite jay
#

How do you change the name of a vanilla joker?

frosty rampart
frosty rampart
granite jay
#

Ah ok

#

Tho I do wanna make it a config option

ripe thicket
frosty rampart
# granite jay Tho I do wanna make it a config option

ok so what you can do is have a custom localization entry for it with a different key
then take ownership of the vanilla joker, and in the new loc_vars function, if the config option is turned on, add key = "different_key" to the return table (where "different_key" is the key you used in your custom localization), and it'll use your custom entry only when that key is returned

pastel hinge
#

im using joker forge [im not good with code] and idk how to use the trigger for a 1 in 16 chance to gain a negative blueprint when a card is destroyed

#

i found out how to give but idk the modprifx for blueprint

#

im kinda new to this

slim ferry
#

its just j_blueprint

red flower
pastel hinge
#

do i just type in blueprint

red flower
#

try it idk

winter flower
#

if you’re using a modded joker then it’s j_(MODPREFIX)_key

pastel hinge
#

thx

#

where do i find the keys

winter flower
#

ie. “j_ocstobal_somethingevil”
ocstobal being mod prefix
and somethingevil being the key

red flower
#

left menu > more > keys reference

pastel hinge
#

found it

gentle rain
#

whats the variable for the current round?

#

or where would one find it

#

im rusty on finding stuff in balatro source code

slim ferry
#

G.GAME.round

#

im pretty sure

gentle rain
#

mhm

#

ty

spiral mural
#

how do i have dynatext constantly call a function for its text value...

primal robin
#

strings = { { ref_table, ref_value } }

#

as usual

#

note that dynatext does make own text smaller when longer text appears and there's no space, but not makes it back

spiral mural
primal robin
#
DynaText({
  string = {{ ref_table = G.GAME, ref_value = 'dollars' }},
  colours = { G.C.MONEY },
  scale = 0.3  
})
spiral mural
#

uh

#

this is the function i was calling

#

number_format(collectgarbage("count")*(G.GAME.round_resets.ante or 1)*card.ability.extra.per)

primal robin
#

ok one second

#
DynaText({
    string = {{
        ref_table = setmetatable({}, {
            __index = function()
                return number_format(collectgarbage("count")*(G.GAME.round_resets.ante or 1)*card.ability.extra.per)
            end,
        }),
        ref_value = "doesnt matter"
    }},
    colours = { G.C.UI.TEXT_LIGHT },
    scale = 0.3,
})
spiral mural
#

thankerss 😇

gentle rain
#

does this joker like. Make Sense to read

#

it checks your score at the first end of round, then gives you money at future end of rounds if you score less than that score

frosty rampart
#

I think it's more interesting if the condition is always based on the previous round, rather than the very first round you played with the joker

gentle rain
#

thats a good idea

half peak
#

I'm working on making my first joker and this is what I have at the top of the smods.Joker object:

   loc_text = {
       name = 'Bottom Half Joker',
       text = {
           "{C:mult}+#5# {} Mult",
           "For each empty slot",
           "In scoring hand"
       }```
which to my understanding is what defines the name and the description, however the image is what shows up in game. Where did I go wrong?
slim ferry
#

Its loc_txt

#

Not loc_text

half peak
#

OH, thank you

#

What's a good way to test it without resetting until I get it in the first shop?

slim ferry
#

Debugplus

frosty rampart
#

install debugplus and hold Tab in-game to see all the shortcuts

#

(including spawning jokers from the collection at will)

half peak
#

Ok cool, thank you so much

spiral mural
#

do vouchers support calcuate....

frosty rampart
#

yes, and observatory uses it in vanillaremade

hardy vessel
#

Is there a way to check when a joker is triggered?

red flower
gaunt folio
#

would this work to make a card immutable from what ive seen in previous messages? idk

red flower
#

but i dont know how cryptid works

simple hound
#

hey guys is there a way to change the blind description mid-blind? changing the loc_vars doesn't update the text

fallen topaz
#

sorry😭

subtle hawk
#

Ok

loud summit
simple hound
#

could you explain? i'm making a blind that debuffs a random rank each hand, and when it changes the rank, the description doesn't update

loud summit
#

oh

#

you return the card.ability.extra.whatver var in your loc_vars

simple hound
#

blind looks like this
the description says the rank is 2, but whenever the rank changes, the description doesn't

SMODS.Blind {
name = "boss_calculator",
key = "boss_calculator",
atlas = "zbsblindatlas",
pos = { y = 0 },
dollars = 5,
mult = 2,
boss = { min = 1 },
loc_txt = {
name = {"What is diddy blud doing on the calculator"}
text = {
"Random rank debuffed",
"each hand",
"{C:inactive}(Currently {C:attention}#1#{C:inactive})",
}
},
boss_colour = HEX('0e1330'),
config = {rank = 2, rankstring = "2", canredorank = false},

loc_vars = function(self, info_queue, center)
    return { vars = {self.config.rank or 5, self.config.rankstring or ":33", self.config.canredorank or false}}
end,

calculate = function(self, blind, context)
    if not blind.disabled then
        if context.before then
            self.config.canredorank = true
        end
        if context.hand_drawn then
            if self.config.canredorank then
                self.config.canredorank = false
                local ranks = getRanksInDeck()
                print(":3", self.config.rank)
                if #ranks > 0 then
                    self.config.rank = pseudorandom_element(ranks, pseudoseed("calculator"))
                end
                print(":33", self.config.rank)
        for i, v in ipairs(G.playing_cards) do
            G.playing_cards[i]:set_debuff(self:debuff_card(v))
        end
            end
        end
    end
end,

debuff_card = function(self, card)
    print(self.config.rank, card:get_id())
    if self.config.rank and card:get_id() == self.config.rank then
        return true
    else
        --return false
    end
end

}

#

idk how to do the code thing style like the above posts

red flower
#

dunno how to solve your issue but you shouldnt save things to self

#

they wont get saved between reloads and they will persist between runs

simple hound
#

oh ok

celest anvil
#

what the hell am i doing wrong.
Oops! The game crashed: [SMODS _ "src/utils.lua"]:228: Attempted to insert object "j_ecattos_element0" into an empty pool.

    key = "handmade",
    default_weight = 0,
    badge_colour = HEX("707A86"),
    pools = {["Joker"] = true},
    get_weight = function(self, weight, object_type)
        return weight
    end,
}

function ishandmade(rarity, bool)
    if (not bool) and SMODS.current_mod.config["disable_nonfunctional_cattos"] then
        return "ecatto_handmade"
    end
    return rarity or 3
end

local elements = {
    --Atomic number, Symbol, Name, Pronouns, Base Mass, Calculate
    {0, "Mu", "Muonium", "hse_ehr", 0, rarity = 3, functional = false},
        --blah blah blah
}```
red flower
celest anvil
#

its weird and

    local n = v[1] + 1
    if v[4] and CardPronouns and not CardPronouns.badge_types[v[4]] then
        v[4] = "ecatto_" .. v[4]
        if not CardPronouns.badge_types[v[4]] then
            print("ElementCatlatro | Not found pronouns for key "..v[4])
        end
    end
    if type(v.loc_vars) == "table" then
        v.loc_vars = elementcattos.simpleLocVars(v.loc_vars)
    end
    --[[if not v.rarity then
        print("ElementCatlatro | Not defined rarity for "..v[1].." "..v[3])
    end]]
    local j = SMODS.Joker({
        key = "element" .. tostring(v[1]),
        loc_txt = {
            name = v[3],
            text = {"{C:inactive}Symbol: "..v[2]..", Atomic number: "..tostring(v[1])}
        },
        atlas = "elements",
        pos = {
            x = n % 8,
            y = math.floor(n / 8)
        },
        pronouns = v[4] or "she_her",
        cost = v.cost or 1,
        atomic_number = v[1] or v.atomic_number,
        element_symbol = v[2] or v.element_symbol,
        in_pool = inpool,
        pools = {
            ElementCattosCommon = true,
            ElementCattosUncommon = true,
            ElementCattosRare = true
        },
        rarity = ishandmade(v.rarity, v.functional) or 3,
        config = v.config,
        loc_vars = v.loc_vars,
        calculate = v[6] or elementcattos.defaultJokerCalculate,
        element_base_mass = v[5] or v.element_base_mass
    })
    
    --[[if v[6] then
        topuplib.ezcalc(j, v[6])
    end]]
    if not elementcattos.atomicnumber[v[1]] and v[1] > 0 then
        elementcattos.atomicnumber[v[1]] = j.key
    end
end```
red flower
#

can you post the full log pls

#

for the crash

celest anvil
red flower
#

no idea

#

make sure the rarity is actually 3

#

wait i misread

#

make sure it is "ecatto_handmade"

#

maybe the prefix is wrong

midnight halo
#

Hi, I don't wanna bother on this chat, or to interrupt anything, so I'm gonna be quick.

I am doing a retexture mod where the clubs are green. The thing is that the text in game when mentions "clubs" has blue color.

Is there any way to change the base color text for specific concepts like the different suits and else?

thank you :)

faint yacht
#

If this retexture is automatically applied with the mod, you could simply edit the G.C.SO_1.Clubs and G.C.SO_2.Clubs color definition, I suppose?
-# Just my two cents on thought.

celest anvil
midnight halo
#

it worked :)

loud citrus
#

am i able to take ownership of modded objects? i want to modify/replace objects in another mod (make a mod for a mod)

loud citrus
#

sweet!

urban wasp
#

does order work anymore? it doesn't seem to affect when the joker appears in the collection like in this

SMODS.Joker {
    key = "a_dragonfruit",
    name = "Dragonfruit",
    config = {
        extra = {
            nommed = false
        }
    },
    pos = { x = 5, y = 0 },
    cost = 1,
    rarity = 3,
    order = 1,
...
#

and then this

SMODS.Joker {
    key = "a_blueberry",
    name = "Blueberry",
    config = {
        extra = {
            perma_bonus = 6,
            perma_bonus_mod = 1
        }
    },
    pos = { x = 0, y = 0 },
    cost = 5,
    rarity = 1,
    order = 2,
...
#

dragonfruit seems to appear after blueberry in the collection

umbral zodiac
#

as far as i can tell order was never an argument for jokers in base smods

urban wasp
#

i must've been cryptid-pilled then

umbral zodiac
#

at least it's not in the lsp definitions

frosty rampart
#

yea manually setting order isn't a thing in smods, it's just ordered by load order

granite jay
#

I know this is months ago but this is painfully true

#

ugh

wanton jolt
#

let me show you how i did it for lily's joker

daring fern
#

long sun
#

is this the best way of counting rares, or is there a better way?

function count_rares()
    local count = 0
    for _, v in ipairs(G.jokers.cards) do
        if v and v.config and v.config.center and v.config.center.rarity == 3 then count = count + 1 end
    end

    return count
end```
daring fern
long sun
#

thanks ^^

junior tapir
#

When I make a seal and put in the en-us file name+text in the Others table, the seal wouldn't show anything. I account for the mod prefix like I do for my stickers, but it doesn't seem to work like them

long sun
#

what key did you use?

junior tapir
#

for the seal? normal lowercase word

long sun
#

does it have _seal on the end?

#

if not, try that

junior tapir
#

still doesn't work

past spade
#

which of the 2 info boxes reads better?

junior tapir
#

I like the 2nd one, I'd add some color on 'retrigger'

daring fern
wild patrol
#

Short simple easy to understand

junior tapir
# daring fern Code?

Lua file:

SMODS.Seal {
    key = 'stone_seal',
    badge_colour = HEX('99A2B3'),
    pos = {x = 5, y = 0},
    atlas = 'seals',
    discovered = true,
    loc_vars = function(self, info_queue, card)
        local odds = 4
        local numerator, denominator =
            SMODS.get_probability_vars(card, 1, odds)
        return {vars = {numerator, denominator}}
    end
}

En-us:

(in descriptions>Other)
CTEH_stone_seal = {
    name = 'Stone Seal',
    text = {
        'Permanently gain {C:chips}+40{} chips',
        'when {C:attention}changing Enhancement',
        'Discard to turn into {C:attention}Stone'
    }
},
(in misc>labels)
CTEH_stone_seal = 'Stone Seal',
daring fern
junior tapir
#

well even if I remove the _seal in the seal definition file, it still wont work

#

the effect should be identical

subtle hawk
junior tapir
#

misplace? it is in the Other table alongside my stickers' descriptions which work like supposed to

subtle hawk
#

Huh

junior tapir
#

I use the Other table for my sticker descriptions too

pastel kernel
#

do i write scored_card:set_ability('m_glass', nil, true) to transform a scored card into glass?

red flower
#

yes

red flower
subtle hawk
subtle hawk
red flower
#

in the code i see everything gets lower'd

subtle hawk
#

Oh really?

#

Interesting

junior tapir
#

yeah lowercase works on the mod prefix

red flower
#

thats what the docs say too

#

it also needs the second _seal

junior tapir
red flower
#

i said also

red flower
junior tapir
#

that case sensitivity inconsistency throws me off. I could just make my mod prefix lowercase, but ah well

frosty dock
quick scarab
#

Bump

tawdry bloom
#

why does this crash :(
calculate = function(self, card, context) if context.individual and context.cardarea == G.play and context.other_card:is_suit("Diamonds") then return { chips = card.ability.extra.chips, card = self } end end,

mystic river
#

because self isn't a card in this context

tawdry bloom
#

and how on earth did i mess up pasting that lol

mystic river
#

just delete that line

tawdry bloom
#

is self the joker

mystic river
#

self is G.P_CENTERS[joker key]

#

in this context

tawdry bloom
#

it works now thx

mystic river
#

card is the individual joker object, when you need that

median lark
#

does anyone have an example of a deck that has boosted chance for jokers from your mod

mystic river
#

yes, i have one and paperback has one

median lark
#

may i see it

mystic river
#
GitHub

A mod for Balatro that adds a bunch of things I found amusing. - wingedcatgirl/MintysSillyMod

GitHub

A mod for Balatro that adds a bunch of things I found amusing. - wingedcatgirl/MintysSillyMod

#

it requires lovely patching get_current_pool()

median lark
#

right, tysm

mystic river
#

(my code is basically a carbon copy of paperback's, just copied and edited to add the sleeve effect :v )

daring fern
#

dapper sun
#

how would i make an enhancement copy another card's enhancement

frosty rampart
#

like permanently replacing the enhancement or behaving more like blueprint?
the second one probably requires quantum enhancements

daring fern
dapper sun
#

ty :3

#

is this supposed to be a hook

#

or does it go in the calculate func

#

wait yea it would i'm dumb

dapper sun
#

also it's copying the chips not just the enhancement

daring fern
dapper sun
#

now it's the 3rd-last card

#

here's the full calculate func

calculate = function(self, card, context)
    local pos = 0
    if (card.area and card.area.cards) then
        for i, v in ipairs(card.area.cards) do
            pos = v == card and i or pos
        end
        
        local c = card.area.cards[pos+1]
        if card.area.cards[pos+1] then
            -- thanks to @somethingcom515 for the code
            local eval, post = eval_card(c, context)
            local ret = {}
            for k, v in pairs(eval) do
                if type(v) == 'table' and (k == 'playing_card' or k == 'enhancement' or k == 'end_of_round') then
                    if not v.card or v.card == c then v.card = card end
                    table.insert(ret, v)
                end
            end
            return SMODS.merge_effects(ret)
        end
    end
end```
white hull
#

Does anyone know why this code causes the first two pools to become copies of sealpool?

local enhpool = get_current_pool('Enhanced')
local edipool = get_current_pool('Edition')
local sealpool = get_current_pool('Seal')
-- Remove invalid items from each pool
for _, pool in ipairs{enhpool, edipool, sealpool} do
    repeat
        local restart = false
        for i, item in ipairs(pool) do
            if item == 'UNAVAILABLE' then
                table.remove(pool, i)
                restart = true
                break
            end
        end
    until not restart
end
slim ferry
#

ive had this issue before and i couldnt tell you what causes it

#

i think you just need to create and then use each pool one by one to prevent this

white hull
#

Yeah I guess

#

But like why lol

slim ferry
#

idfk

#

its probably wierd table shenanigans

#

actually

red flower
#

they use G.ARGS.TEMP_POOL im pretty sure

slim ferry
#

try printing sealpool == enhpool

#

bcs i think its table shenanigans

slim ferry
red flower
white hull
#

I've removed the first for ipairs() do part and just copypasted the repeat until thrice, nothing changed, so it's not that

#

here's the three resulting tables...

primal robin
#

because it returns same object every time but with different content

white hull
#

Huh.

white hull
red flower
#

you can use SMODS.shallow_copy(table)

slim ferry
#

SMODS.shallow_copy(get_current_pool(...))

red flower
#

why does it do that anyway

primal robin
#

because localthunk decided this

#

G.ARGS shoult not exist in theory, sounds like bad pattern

#

it stores too much stuff inside

azure valley
#

I was investigating the properties of balatro's RNG, and I wrote a short lua script to attempt to dump a whole bunch of random numbers to stdout to use with random number test suites. But I'm having some trouble getting the random numbers to... be random?

require "functions/misc_functions"

-- init the game object so that the pseudoseed function can work.
G = {GAME = {pseudorandom = {}}} 

G.GAME.pseudorandom.seed = arg[1]
seed_name = arg[2]

while true do
  rand_value = pseudorandom(seed_name, 0, 4294967295)
  print(rand_value)
  print(tprint(G.GAME.pseudorandom, 2))
  -- string_value = string.format(
  --   '%c%c%c%c',
  --   bit32.band(rand_value, 0xff),
  --   bit32.band(bit32.rshift(rand_value, 8), 0xff),
  --   bit32.band(bit32.rshift(rand_value, 16), 0xff),
  --   bit32.band(bit32.rshift(rand_value, 24), 0xff))
  -- io.write(string_value)
end

This script calls into the balatro RNG to pull random values. But the values I get are all identical. (I also patched the pseudorandom function to print out the current seed after it sets it.) The output when I invoke with randomness_test.lua TUTORIAL Tarot starts with:

pseudoseed:     0.42662880480655
random:         1693861772
  {
    seed= "TUTORIAL",
    Tarot= 0.8532576096131,
  }
pseudoseed:     0.3028680272979
random:         1693861772
  {
    seed= "TUTORIAL",
    Tarot= 0.6057360545958,
  }
pseudoseed:     0.08946579143175
random:         1693861772
  {
    seed= "TUTORIAL",
    Tarot= 0.1789315828635,
  }
pseudoseed:     0.22149368274415
random:         1693861772
  {
    seed= "TUTORIAL",
    Tarot= 0.4429873654883,
  }
pseudoseed:     0.4491510049583
random:         1693861772
  {
    seed= "TUTORIAL",
    Tarot= 0.8983020099166,
  }

As you can see, the pseudoseed and the stored value in the pseudorandom object are both changing, but the number output by the pseudorandom function is locked to a single value. Has anyone come across this before?

primal robin
#

do not post same message twice, specifically this big

azure valley
#

I'm deleting it from the other channel, because it's in the wrong place

white hull
#

That's so weird lol

slim ferry
#

blame thunk

white hull
#

What does pressing B actually do
Is it just a faster version of holding R?

red flower
#

mine does nothing

white hull
#

I think it's a debugplus thing

#

I'm just concerned if it's a proper restart and it's safe to use for testing rng stuff

wintry solar
#

it is a proper restart

white hull
#

Sweet!

red flower
azure valley
# azure valley I was investigating the properties of balatro's RNG, and I wrote a short lua scr...

originally, I was running this under lua 5.2, but then I looked at the love documentation and they use lua 5.1, so I downloaded PUC Lua 5.1 and tried it there, but it didn't help. New error with the integer version of things, (saying my range is empty), and additionally the floating point version still emits the same number over and over. That being said, I booted up balatro for a sanity check and it does seem to work there.

red flower
#

balatro is specifically luajit

azure valley
#

cool, I'll try luajit

#

luajit works

#

Thanks

#

❤️

desert ore
#

I haven't touch modding in a while and the calculate function page has updated to include SMODS.scale_card, should I change my cards to have these for mod compatibility even if I don't plan to need it myself?

frosty rampart
#

it would be good to do so, yes

wintry solar
#

it's up to you

desert ore
#

ok, I don't think I've implemented many scalers yet anyhow so shouldn't be too big a deal, although maybe it's because I'm not used to it, it seems a tad more complex

wintry solar
#

it is one of the less important things to update imo

red flower
azure valley
#

my guess is that it has something to do with how puc lua passes the value to the C implementation of randomseed. My hypothesis is that (because the value is a floating point) it truncates it, effectively setting it to 0, each call.

#

whereas luajit simply pushes the raw bytes around, essentially reinterpret casting it to an int.

ripe thicket
#

I'm trying to make this joker effect where it takes the +chips and +mult from an enhanced card and adds it to itself
I'm just running into the issue of how to actually see how much +chips and +mult to add
I was thinking of trying something similar to how to get joker keys (using .config stuff or whatever) but I haven't been able to come up with anything that works

red flower
#

it depends on how you store them but they should be in wooden_card.ability.whatever_chips_or_something

half peak
#

Could someone help me understand what this means in the steamodded api

card_key: Used to create keys for playing cards, formatted like S_R, where S is the suit's and R is the rank's card key. Your mod prefix gets prepended by default."
I'm trying to make a new suit and ranks

granite jay
#

How do you get the base blind score for boss blinds?

ripe thicket
red flower
#

it can just be the same as the key

vocal helm
#

Is there any way to animate card positions with events? I have two cards I want to move together before they create a new Joker, and I know how to get their midpoints, but accessing their transformations has kept crashing for me

primal robin
#

if card in cardarea, then card's position dictated by cardarea

#

So you need remove card from cardarea and then you can mve it by changing card.T.x and card.T.y

#

And make sure to make card not collideable, so player cannot grab it

vocal helm
#

gotcha, I'll see what I can do

vocal helm
primal robin
#

insane

#

Impressive, even

crimson kestrel
pastel kernel
#

does this work?lua if G.GAME.current_round.hands_left == 0 then card.ability.extra.mult = card.ability.extra.mult * card.ability.extra.powerup card.ability.extra.mult = card.ability.extra.mult * card.ability.extra.powerup SMODS.calculate_effect({ message = "X" ..card.ability.extra.powerup, colour = G.C.GOLD}, card) end

nova sleet
#

wanna hop on with mod dev, what do I need to start

pastel kernel
#

how do you check for, "if round is beaten in one hand"

mystic river
#

i believe smods has a flag for this, though i don't recall its name

umbral zodiac
#

SMODS.last_hand_oneshot i think

#

well, its for if the previous hand did the entire blinds score

#

but you can just check if only 1 hand was used in the round additionally

pastel kernel
#

how about "if round is beaten by first played hand"

umbral zodiac
#

i already described that

#

last_hand_oneshot tells you if the previous hand did it

#

if you want to see if it was done in the first hand, just check for SMODS.last_hand_oneshot while also seeing if only one hand was used this round

pastel kernel
#

is there a joker that uses SMODS.last_hand_oneshot

#

i'm gonna see how they work

#

or how SMODS.last_hand_oneshot works

umbral zodiac
#

it is a value and you check for it (preferably in context.after) to determine if the last hand oneshot the blind

pastel kernel
#
if context.after and SMODS.last_hand_oneshot then
SMODS.add_card{...}
SMODS.calculate_effect{...}
end```
umbral zodiac
#

yea looks good

pastel kernel
#

it creates 2 instead of 1lua calculate = function(self, card, context) if context.after and SMODS.last_hand_oneshot then SMODS.add_card{set="Infinity"} SMODS.calculate_effect({message = "+1 Infinity Card", colour = HEX('FFB570')}, card) end end

half peak
#

I added this object and now the game is crashing, any idea where I went wrong?

    key = "head",
    card_key = "head",
    pos = { x = 0 },
    nominal = 0,
    loc_txt = {
        name = 'Exodia The Forbidden One'
    },
    face = true,
    strength_effect = { ignore = true },
    in_pool = function(self, args)
        return false
    end
}```
#

The error message is game.lua:1893: bad argument #1 to 'ipairs' [table expected, got nil]

north crescent
#

i made an items folder with the jokers lua inside, but now the jokers file is looking for atlas in the folder it's in, how do i fix that ?? (prob a dumb question but i'm pretty new to this ...)

half peak
north crescent
half peak
#

oh thats a good point, idk then, hopefully someone else can help you

north crescent
#

alr, thanks anyways

pastel kernel
#

how do i make it so that ```lua
"{C:blue}Blue Seal{}, {C:blue}Bonus{}, {C:blue}Foil{}, and{} {C:blue}Club{} Cards",
"{C:attention}always score{} and give {C:white,X:chips}X#1#{} Chips"

frosty rampart
#

for the "always score" part, check how Splash works in vanillaremade
for the "give Xchips" part, that's just basic context.individual stuff

pastel kernel
#

no i mean blue cards specifically

#

i wanna check for blue cards

frosty rampart
#

yes
you can adapt the code for splash in vanillaremade to include those checks

#

if you don't know how to make those checks, that should be documented on the vanillaremade wiki

#

(extra detail- the context that splash uses runs once for every individual card in the played hand, much like context.individual)

pastel kernel
frosty rampart
#

you need it for the "and gives Xchips" part, but not for the "always scores" part
you do understand that you can interact with multiple contexts in your calculate function, right

pastel kernel
#

how do you check for if a card has blue seal

frosty rampart
#

if you don't know how to make those checks, that should be documented on the vanillaremade wiki

pastel kernel
#

welp, time to test it out```lua
calculate = function(self, card, context)
if context.modify_scoring_hand and not context.blueprint then
for _, bluecheck in ipairs(context.full_hand) do
if context.individual and context.cardarea == G.play then
if
bluecheck:is_suit("Clubs") or
(bluecheck.edition and (bluecheck.edition.foil)) or
SMODS.has_enhancement(bluecheck, 'm_bonus') or
(bluecheck.seal and bluecheck.seal == 'Blue')
then
return {
add_to_hand = true
}
end
end
end
end
end

frosty rampart
#

this will not work

daring fern
frosty rampart
#

first of all, like i already said, modify_scoring_hand behaves like context.individual. you don't need to embed individual inside modify_scoring_hand, and in fact that will make nothing calculate
second of all, modify_scoring_hand behaves like context.individual. as per the calculate functions wiki page on smods, it directly gets context.other_card

pastel kernel
#

so make them separate?

#

modify_scoring_hand for the always scores and context.individual for the xchips?

frosty rampart
#

yes

#
calculate = function(self, card, context)
  if context.modify_scoring_hand and not context.blueprint then
    -- always scores code
  end
  if context.individual and context.cardarea == G.play then
    -- xchips code
  end
end
pastel kernel
#

i need to make a local to use for checking blue cards

#

how about this?

        local bluecard = context.other_card:is_suit("Clubs") or
                    (context.other_card.edition and (context.other_card.edition.foil)) or
                    SMODS.has_enhancement(context.other_card, 'm_bonus') or
                    card:get_seal() == 'Blue'

        if context.modify_scoring_hand and not context.blueprint then
                    if bluecard then
                        return {
                            add_to_hand = true,
                        }
                    end
                end

                if context.individual and context.cardarea == G.play then
                    if bluecard then
                        SMODS.calculate_effect({xchips = card.ability.extra.xchips})
                    end
                end
            end
        
frosty rampart
#

this won't work because context.other_card isn't guaranteed to exist every time the calculate function is run

#

and for the xchips part you can literally just return { xchips = card.ability.extra.xchips }, you don't need to do SMODS.calculate_effect

#

but yes you're much closer

pastel kernel
#

do i replace bluecard with the complete check?

frosty rampart
#

yea

#

oh also it should be context.other_card:get_seal()

#

but once you've done all that it should work

pastel kernel
#
        if context.modify_scoring_hand and not context.blueprint then
                    if context.other_card:is_suit("Clubs") or
                    (context.other_card.edition and (context.other_card.edition.foil)) or
                    SMODS.has_enhancement(context.other_card, 'm_bonus') or
                    context.other_card:get_seal() == 'Blue' then
                        return {
                            add_to_hand = true,
                        }
                    end
                end

                if context.individual and context.cardarea == G.play then
                    if context.other_card:is_suit("Clubs") or
                    (context.other_card.edition and (context.other_card.edition.foil)) or
                    SMODS.has_enhancement(context.other_card, 'm_bonus') or
                    context.other_card:get_seal() == 'Blue' then
                        SMODS.calculate_effect({xchips = card.ability.extra.xchips})
                    end
                end
            end
        
#

i pray in the name of lord ruby this works

#

i'm certain this is supposed to work with cryptid

frosty rampart
#

i assume the calculate_effect function is crashing

#

because you aren't giving it a card to calculate on

pastel kernel
#

huh... that worked?

#

i guess you're right

#

sometimes return is good

#

it works

#

time to update the mod

daring fern
pastel kernel
#

i keep hearing that SMODS.calculate_effect is almost always better

frosty rampart
#

where are you hearing that???

pastel kernel
#

jamirror iirc

#

there's a couple of other peeps who agree so he's not exactly the source

frosty rampart
#

it's only good for getting other cards to animate with a message when smods doesn't already handle it for you
smods handles it for you in context.individual

daring fern
vocal helm
#

I'm not sure how to exactly search for it, so I'll ask here; is there a way to make a joker mod-dependent? i.e. this joker won't even be in the game if this mod isn't enabled

#

(this is for a custom joker, not a base-game joker)

marsh horizon
vocal helm
#

hey, you never know, that might be the actual solution

marsh horizon
#

try it ig

#

some shit like
if [specific joker] in [joker slots]
idfk

umbral zodiac
#

dependencies = {"mod_id_here"} in your joker definition

marsh horizon
#

oh

umbral zodiac
#

note that including this will also make it display the other mod's badge when you hover over it

marsh horizon
#

theres just an actual thing for that

#

crazy

#

i am so stupid

vocal helm
# umbral zodiac yes

thank you!
in addition to the dependency I was curious if you could enable/disable it with a boolean since I made a config for enabling cross-mod jokers for my mod

umbral zodiac
#

for that - i would recommend putting all of them in one file/folder and only loading stuff in that file/folder based on the setting

#

e.g. if modname.config.crossmod then ... end

#

it means itd require a restart to toggle on/off but i think that's the best solution youd get

vocal helm
#

yeah fair

#

this does indeed work, thanks!

umbral zodiac
marsh horizon
#

so i was still right technically

#

epic

vocal helm
humble apex
#

Hi all, I'm trying to create my first mod, which aims to add various card enhancements as seals, and I have managed to get Bonus, Mult, and Lucky working flawlessly, but I am having issues with Glass. It for the most part works, but I cannot get it to proc Glass Joker, which is strange because the Lucky Seal can proc Lucky cat without issue. Attached is the code for the Glass seal. Apologies if it's a mess.

daring fern
faint yacht
daring fern
faint yacht
#

-# Or that-

daring fern
#

pastel kernel
#

how do you make it so that the first shop always gives you cavendish?

#

as in all the slots in the rerolls

pliant remnant
#

WHY does this return a number sob2k

red flower
#

# is the lenght operator

pliant remnant
#

oh i forgot to remove the hashtag

#

ffs

mystic river
open moth
#

how can I implement Cobblemod's Foresight? By copying the related code?

red flower
#

I don't know what that is but most devs are ok with using their code with credit

pastel kernel
#

how do you check if cavendish is destroyed

#

or sold

#

as in an external joker

red flower
#

context.joker_type_destroyed and context.selling_card

pastel kernel
#

<@&1133519078540185692>

red flower
#

i also won that

karmic creek
pastel kernel
#
if context.joker_type_destroyed and context.card == "j_cavendish" then 
            end
            if context.selling_card and context.card == "j_cavendish" then
            end
red flower
#

context.card is the card object not the key

open moth
lusty marten
#

hey , are there any planet card template???

pastel kernel
#

how do i check if the card being sold/destroyed is cavendish then

red flower
subtle hawk
pastel kernel
#

local key = "j_cavendish"?

subtle hawk
#

You don't need a local

#

I mean you can have it

#

But like context.card.config.center.key == "j_cavendish"

pastel kernel
#

ok hold on

mystic river
pastel kernel
#
if context.setting_blind or context.forcetrigger then
            SMODS.add_card{key = "j_cavendish", edition = "e_negative"}
            if context.joker_type_destroyed and context.card.config.center.key == "j_cavendish" then 
                SMODS.scale_card(card, {
                ref_table = card.ability.extra,
                ref_value = "emult",
                scalar_value = "emultmod",
                colour = SMODS.Gradients["busterb_eemultgradient"]
            })
            end
            if context.selling_card and ontext.card.config.center.key == "j_cavendish" then
                SMODS.scale_card(card, {
                ref_table = card.ability.extra,
                ref_value = "xmult",
                scalar_value = "xmultmod",
                colour = G.C.RED
            })
            end
        end```
#

oh wait

#

i see the problem wiht my code immediately

#

it's in setting blind wtf

pastel kernel
#

saw

#

it crashed

#

fixed it asap

#

i don't like this method of scaling

#

also does joker_type_destroyed actually work

subtle hawk
#

Why, didn't work for you?

mystic river
#

think so
test it with the knife and/or investigate the code

pastel kernel
#

it says upgrade

#

so the context works

#

oh wait

#

my fault

#

i never wrote the updating text

wild patrol
#

how do you add an enhancement to card like say I wanna make a joker make a random card a glass how would I do that

#

I see hwo to check if a card has an enhancement

#

but I can't find how to add one to a card

mystic river
#

Card:set_ability(enhancementkey)

wild patrol
#

Why is always so simple

#

but just so confusing sometimes

#

lmao

#

thanks

subtle hawk
#

Would be weird if setting an enhancement was complex

mystic river
#

there are both benefits and drawbacks to thunk code

wild patrol
#

it's not that I was digging around the tarots

#

trying see how they did it

#

but it looked more complicated than it actually was

subtle hawk
wild patrol
#

working on a command for twitch intergration to let chat randomly make cards enhanced

subtle hawk
#

SMODS tarots I mean

#

buh

wild patrol
#

just like #G.jokers.cards

#

gonna assume #G.hands.cards does the same

#

as the number of cards in your hand

subtle hawk
wild patrol
#

just hand or G.hand

subtle hawk
#

G.hand

wild patrol
#

ok

subtle hawk
#

G.jokers G.hand G.consumeables(why the fuck) are areas themselves and the .cards is the table of cards in the area

wild patrol
#

G.hand.cards:set_ability('m_stone')

#

so this should turn the hand to stones

subtle hawk
#

Funny to admit but idk if set_ability works with tables of cards

#

Try it

wild patrol
#

it doesn't

subtle hawk
#

Oh

wild patrol
#

returns a nil vaule

subtle hawk
#

Then ig you do a loop and apply the enhancement to each card?

daring fern
subtle hawk
#

Ye

wild patrol
#

Yeah it worked

#

I really need to learn how thefor k, v in pairs work

#

I see it done alot but I just can't get it to click in my brain yet

frosty rampart
subtle hawk
frosty dock
#

also that the order can be pretty much anything

#

if you want to loop though a list with numerical indices (aka an array), in order, use ipairs

subtle hawk
frosty rampart
#

oh yea my bad
like aure said, that one's a thunkism

#

shoutouts caino

subtle hawk
#

caino is funny

frosty dock
#

gluttenous joker

#

selzer, even

wild patrol
#

well the basic setup is there

frosty dock
#

so like, crowd control?

wild patrol
#

just need to figure how to make it were more random

#

instead of just making every card the same

mystic river
#

the index is just table[index] = value

daring fern
subtle hawk
mystic river
open moth
#

how can I add raw round score before the round starts?

subtle hawk
#

What

open moth
#

like, 100 points

subtle hawk
open moth
#

ye

subtle hawk
#

Oh that

open moth
#

yeah, I tried an addition but it doenst update the number

#

graphically i mean

subtle hawk
#

The number must be manually updated I think

daring fern
# open moth graphically i mean

⁨⁨```lua
if context.setting_blind then
return {func = function()
G.E_MANAGER:add_event(Event({
func = function()
ease_chips(100)
return true
end
}))
end}
end

open moth
#

ok

subtle hawk
#

Oh or that ig

#

Didn't know ease_chips was a thing damn

open moth
#

ok no its just that I suck

open moth
frosty dock
#

return { message = 'blah', func = ...}

daring fern
frosty dock
#

right, timing stuff

frosty dock
open moth
frosty dock
#

...

#

i meant the calculate_effect

lusty marten
#

hey, what is the name of planet font?

daring fern
# open moth

⁨⁨```lua
return {func = function()
G.E_MANAGER:add_event(Event({
func = function()
ease_chips(100)
SMODS.calculate_effect({message = 'message', instant = true}, card)
return true
end
}))
delay(0.9375)
end}

open moth
#

thanks!

mystic river
wild patrol
#

what do you think

#

I tried flipping it

open moth
#

card = card?

wild patrol
#

but when I added another flip it would mes up

mystic river
open moth
mystic river
daring fern
mystic river
#

well that's odd

slim ferry
#

Well not really

slim ferry
#

The second argument adds the card = ...

#

Which is normally done automatically

mystic river
#

smods does a lot of work to make card = card unnecessary

daring fern
honest light
subtle hawk
#

I don't want to

honest light
#

is there an option in jokerforge to affect mult?

subtle hawk
#

Elaborate

honest light
#

like i want to male a joker's effect be "+[mult] or x[mult]"

#

make*

#

soothing chips

honest light
subtle hawk
#

Why do you want me to sooth chips

honest light
#

also you mean put your mod names in the display anme?

subtle hawk
#

???

honest light
#

when you said "you should try it"

#

when i asked for a name of the busted baffoons mod

#

@subtle hawk

#

also when im done do i just export the whole thing

#

like from jokerforge into my mods folder

subtle hawk
#

My brain is being fried at the moment can you not ping please

honest light
#

ok

next timber
#

how can i make a joker use a localisation key other than its own?

slim ferry
#

Add key = "..." to the loc_vars return

next timber
#

cool thx

slim ferry
#

You can additionally return a set to change which localization category it uses

#

If needed

wicked heron
#

I'm having issues issues with patching card.lua. I added a "Rank_bypass" function call to any Joker ability that checks the rank of a card (even steven, cloud 9 etc), so that if a certain joker is in play, face cards always pass the check.

⁨```
function rank_bypass(playing_card)
if G.jokers and G.jokers.cards then
for i=1, #G.jokers.cards do
if G.jokers.cards[i].config.center.key == "j_hft_gwynplaine" and playing_card:is_face() then
return true
end
end
return false
end
end

like this
⁨```
                if self.ability.name == 'Hack' and (
                context.other_card:get_id() == 2 or 
                context.other_card:get_id() == 3 or 
                context.other_card:get_id() == 4 or 
                context.other_card:get_id() == 5 or rank_bypass(context.other_card)) then
                    return {
                        message = localize('k_again_ex'),
                        repetitions = self.ability.extra,
                        card = self
                    }
                end
```⁩

However, this seems to cause strange behaviour on some of abilities. Cards like Hack, 8 Ball and Idol now give mult on top of their original ability. It seems to be equal to whatever card.ability.extra value they have (Hack -> +1 mult due to 1 repetitions, 8 Ball -> +4 mult due to 1 in 4 chance to trigger, Idol -> +2 mult due to 2 xmult)

Does anyone know what might be causing this behaviour? All I did was inject a Boolean returning function into the if statement of these Jokers.
quick scarab
#

I'm having a bug where when you load up a run in progress, if you previously used one of the consumables, the game would softlock like this

#
SMODS.Joker {
    key = "diver",
    blueprint_compat = false,
    rarity = 1,
    cost = 4,
    atlas = 'Joker',
    pos = { x = 9, y = 2 },
    config = { extra = { levels = 0, maxlevel = 6, chips = 0, mult = 0, xmult = 0, h_size = 0} },
    loc_vars = function(self, info_queue, card)
        info_queue[#info_queue + 1] = { key = "fnaf_bug", set = "Other" }
        return { vars = { card.ability.extra.levels, card.ability.extra.maxlevel, card.ability.extra.chips, card.ability.extra.mult, card.ability.extra.xmult, card.ability.extra.h_size} }
    end,
    calculate = function(self, card, context)
        if context.using_consumeable and not context.blueprint and context.consumeable.ability.set == 'fnaf_item'
        and not (card.ability.extra.levels == card.ability.extra.maxlevel) and context.consumeable.config.center.key == 'c_fnaf_clearance' then
            card.ability.extra.levels = card.ability.extra.levels + 1

            card.ability.extra.chips = 100 * card.ability.extra.levels -- 1
            card.ability.extra.h_size = math.max(0, card.ability.extra.levels - 1) -- 2
            card.ability.extra.mult = math.max(0, 5 * (card.ability.extra.levels - 2)) -- 3
            card.ability.extra.xmult = math.max(1, 1 + (0.125 * (card.ability.extra.levels - 3)))  -- 4
            -- 5
            -- 6

            if card.ability.extra.levels >= 2 then
                G.hand:change_size(1)
            end
        end

        if context.joker_main then

            return {
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult,
                xmult = card.ability.extra.xmult,
            }
        end
    end,
    remove_from_deck = function(self, card, from_debuff)
        G.hand:change_size(-card.ability.extra.h_size)
    end
}
#
SMODS.Consumable{
    key = 'clearance',
    set = 'fnaf_item',
    atlas = 'TarotFnaf',
    pos = {x = 0, y = 1},
    cost = 4,
    loc_vars = function(self, info_queue, card)
    end,
    use = function(self, card, area, copier)
    end,
    can_use = function(self, card)
        return next(SMODS.find_card("j_fnaf_diver"))
    end,
    in_pool = function(self, args)
        return next(SMODS.find_card("j_fnaf_diver"))
    end
}
#

It's a card where when it's used a joker gets a progression point, where it gets some buffs

daring fern
daring fern
quick scarab
#

I can still press stuf

#

It just soft locks

lyric wadi
#

how do you remove a seal from a playing card via code

#

and would it be a problem if i try to make a seal remove itself

wintry solar
#

card:set_seal()

#

iirc

brazen kite
#

i've never managed to make a bug this catastrophic before

#

(i fixed it)

winter flower
#

go my rendering issues

lyric wadi
#

hepl this is crashing when the break chance triggers i know im dfoing it wrong so how do i do it right

white hull
#

maybe try making the first argument of the pseudorandom function ⁨card⁩ instead of ⁨self⁩?

lyric wadi
#

no still crash :(

sturdy compass
#

All instances of self in your probability calls should be card instead

slim ferry
#

which uhhh

#

you shouldnt

past spade
#

is there some way to have a dynamic amount of lines in a description? other than having an alt key for each one. Tried using a linebreak in a loc var but that doesnt work

daring fern
past spade
#

hmm sounds spooky, maybe I'll just hardcode 4 different description keys

#

is there a color loc var tag like {V:1} for background color?

daring fern
dawn granite
#

is there a way to make a hand not score randomly? (basically if SMODS.pseudorandom_probability hits the hand doesn't score)

frosty rampart
#

do you want to skip all scoring (like how boss blinds block hands from scoring), or just make the playing cards not score?

dawn granite
#

how boss blinds block scoring so like the eye and the mouth

daring fern
dawn granite
#

ok ill try that rq

vocal helm
#

I'm looking at VanillaRemade for reference and I'm curious if there's a slightly less invasive way to ensure or append a card to a booster pack without taking ownership, assuming that it would no longer default to vanilla from there
I'm making a joker that ensures a specific Tarot shows up in Arcana packs; is there a way to do that without completely taking ownership for the sake of compatibility? i.e.

-- rough pseudocode
create_card = function()
    if has_joker and i == 1 then
        return card
    end
    return create_card
red flower
#

hook the create card function? you can also hook in a take ownership

vocal helm
#

take_ownership_by_kind was the example I'm working off

#

I'm basically asking if I have to re-implement vanilla behavior on top of the additions

#

i.e. stuff with omen globe and such

red flower
#

well you would need to do it individually but you can hook each

#

(and you can just do it in a loop)

dawn granite
vocal helm
dawn granite
red flower
# vocal helm what would that look like?
-- somewhat pseudocode cuz phone
for key, prototype in pairs(SMODS.Boosters) then -- i dont recall if this exists or it's just P_CENTERS
    local ref = prototype.create_card
    SMODS.Booster:take_ownership(key, { 
         create_card = function(...)
              -- code
              return ref(...)
         end
    })
end
vocal helm
#

awesome, thank you so much!

dawn granite
north crescent
#

i made an items folder with the jokers lua inside, but now the jokers file is looking for atlas in the folder it's in, how do i fix that ?? (prob a dumb question but i'm pretty new to this ...)

#

i had asked yesterday but no answer was given so i am asking it Again!

wintry solar
#

that's not how it works, you must have your code or folder set up incorrect. Can you share your code that tries to create the atlas, and a screenshot of where you atlas is in your mod folder with a folder path visible?

north crescent
north crescent
#

ah

mystic river
#

what is actually going incorrectly?

slim ferry
#

what does the inside of assets look like

#

first of all

mystic river
#

you've described what you think the cause is, but you haven't said what the actual problem is

#

... actually, random question. what's the top of your jokers.lua look like

north crescent
mystic river
#

you know what. i can just barely see it in the first image. it's the steamodded header, isn't it
you didn't create a second file in the same mod, you created a second mod

slim ferry
#

thats just not how it works

#

oh

#

amazing

north crescent
#

oh wait i'm smart

#

how do i fix that

mystic river
#

use SMODS.load_file() in your main file

slim ferry
#

assert(SMODS.load_file("items/jokers.lua"))()

#

specifically

mystic river
#

also consider switching your metadata to json, the header has been outdated for very long...

north crescent
#

i had done something like that i think ..

vocal helm
#

I didn't realize "take_ownership" actually added it to the additions to your mod
is there a way for that to not happen

slim ferry
#

add ⁨true⁩ as the last argument

#

iirc

mystic river
#

correct

frosty rampart
#

outside of the table, yes

north crescent
#

do i remove the steammodded header too

mystic river
wintry solar
#

the header will be dead soon also

mystic river
#

kinda surprised we collectively kept it this long

red flower
#

people want early 2024 mods to still work with new mods

wintry solar
#

it just stuck around for back compat afaik

north crescent
#

that worked !!! thank you all

wintry solar
#

but I believe zip loading doesn't work with it or something

vocal helm
mystic river
red flower
#

you can say that every two months and it will be true

vocal helm
#

super-quick follow-up to taking ownership of a booster pack; does this allow you to change how many cards it has to start?

shell timber
slim ferry
#

does anyone know of something i could reference for adding an additional counter alongside hands/discards/whatever in the bottom left

#

i tried looking at entropy but i just couldnt find it

ripe thicket
#

how do I get the current blind size?

daring fern
ripe thicket
#

ty!

half peak
#

I have a bug right that when you use a spectral card I made that creates a card of a 5th suit and custom rank (which are kept out of the pool) they are added to the deck, the total deck counter goes up accurately but the remaining cards goes up inaccuratly. For example it starts 44/52, use the spectral card then it goes to 46/53, when nothing was added to the hand, only the deck. Any ideas?

granite jay
#

How do you make it so a Blind detects if a Joker is triggered?

red flower
#

context.post_trigger

granite jay
#

Oh thx

red flower
half peak
#

⁨``` use = function (self, card, area, copier)

    if #exodiaLeft ~= 0 then
        local nextExodia = table.remove(exodiaLeft, 1)

        local new_card = create_playing_card({
            front = G.P_CARDS[nextExodia],
            center = G.P_CENTERS.c_base
        }, G.deck)

        new_card:add_to_deck()
        G.deck:emplace(new_card)
    end
end```⁩
half peak
red flower
rigid solar
#

I've created an object type, but when I hover over a card of that type the game crashes because it's trying to localize the object

#

I can't find in smods' doc how to localize a new object type, if it's explained anywhere to begin with

red flower
#

objecttypes dont have localization

#

as far as i know

#

may i see the log

rigid solar
unkempt thicket
#

The Binding of Jssac

red flower
#

ah you also extended center

rigid solar
#

jimbo

red flower
#

that makes more sense

rigid solar
#

yeah i'm trying to make cards that go in a new card area

red flower
#

they should be under descriptions.tboj_active iirc

rigid solar
#

the gist of it is reusable consumables, but if I code them as consumables then it has many side effects (because I don't want them to actually be consumables)

half peak
red flower
#

probably

half peak
#

oh ok, thank you

rigid solar
half peak
#

N' fr the goat rn

red flower
#

play joyousspring

rigid solar
#

now to figure out how to make them spawn in the shop lol

red flower
#

add it to this table

rigid solar
#

the rate should be defined in G.GAME.tboj_active_rate right?

#

like joker_rate tarot_rate etc

red flower
#

it can be anything since its custom

rigid solar
#

figured

#

was just wondering if it was auto generated in some way

red flower
#

not unless you make a consumabletype

rigid solar
#

inserted that with a patch (with 100 as the val so it's supposed to be very common) but it doesnt seem to be working

#

oh i need to change total_rate too

half peak
#

in the evaluate function for poker hands is the variable hand a table of all cards in the scoring hand?

rigid solar
#

most likely

#

so the card appears in the shop, i can buy it, it gets emplaced properly but it's not being drawn
any idea of what i'm missing?

red flower
rigid solar
#

it was "active" so yeah it was wrong, but I changed it to tboj_active and it still doesnt show

red flower
#

it has to be one of the vanilla ones

rigid solar
#

oh

red flower
#

like 'joker' i think

#

also theres a function to initialize areas now you dont need to patch

rigid solar
rigid solar
#

i copied it from multiplayer and they're patching

#

might be an old version of mp, idk

red flower
#

the mp devs are not very active around here so i just assume theyre not on top of smods features

#

also theyre always a version behind

daring fern
#

granite jay
#

Can you make it so a Joker can bring played cards back to hand?

red flower
rancid kindle
#

Hey I might be a top 10 idiot but forever ago I made a mod that had jokers that did ^ mult, and now it just... doesn't work. upon research it might require stuff like talisman now, so how do I.... do that.

red flower
#

with talisman (I actually recommend Amulet now) you can just return emult = number where you would normally return mult or chips

rancid kindle
#

okay it's emult, cool

rancid kindle
#

echips

frosty rampart
#

yes

rancid kindle
#

okay lets see if this works

rancid kindle
#

It did

#

While I’m at it is tetration native to talisman or nah

red flower
#

yes

rancid kindle
red flower
#

< 3

half peak
#

Is there a way to make it so a playing card can not be affected by tarot cards?

frosty rampart
#

i can think of a fairly easy way to handle tarot cards that specifically target the card, but not a single general way to do it for tarot cards that affect the whole hand/random cards (which doesn't exist in vanilla balatro, but something like familiar or sigil if it was a tarot card)

red flower
#

even if it specifically targets the card i would think there are many cases it would break modded tarots

frosty rampart
#

i mean i was thinking of hooking whatever G.FUNCS function handles whether you can use a card to make it just flat out disable the use button if you have the relevant card highlighted

red flower
#

yeah i was thinking that but its kinda bad if the tarot doesnt have anything to do with the card

#

or maybe you have a tarot that upgrades selected poker hand or something

frosty rampart
#

hm true

#

also like. using death to copy it

red flower
#

i would maybe do something more like the inmutable thing astra PR'd

frosty rampart
#

ooh that's interesting

half peak
#

Ok, ill take a look at that

#

the idea is that it is exodia from yugioh, so if you play all 5 you instant win the blind, and adding things like enhancing the card and changing the suit break it

#

it might be easier to change what I have so enhancing it etc. doesn't break it then just preventing that from happening

red flower
#

you can just prevent those by hooking the respective functions

half peak
#

oh ok

lyric wadi
#

does context.after happens before context.repetition?

red flower
#

no

lyric wadi
#

i fixed the crashign but now the seal is destroying itself before its effect activates

#

and then the effect happens anyway

frosty rampart
#

sounds like timing things, you probably need to put the destruction in an event

glass scaffold
#

Ok, really weird question, but:

Is there a way to play sounds whenever things like a new run is started, lost, or won?
Preferably without having to use Jokers.

red flower
torn remnant
#

im learning about making mods, whats the best mod for like a debug menu to spawn in jokers and stuff? i wanna test my first joker!

red flower
#

debugplus

torn remnant
#

copy, thanks

#

how does one bring up the menu in debugplus?

red flower
#

tab in a run, it also has all the shortcuts

dapper sun
#

to spawn in jokers you just open the collection & press 3 over the joker

torn remnant
#

ah, thank you!

sturdy compass
#

welcome to modding SunglassesSwagling

torn remnant
#

but i had to pull myself away from my pc, i was enjoying modding too much