#💻・modding-dev

1 messages · Page 589 of 1

daring heron
#

like, 25%? 50%? 75%?

maiden phoenix
#

<@&1133519078540185692>

exotic hedge
#

Boom

maiden phoenix
#

Ty 👍

daring fern
#

It's 0.7 times scale.

daring heron
#

thanks

manic rune
#

in eval_card, card should point to the joker, right?

alpine tulip
#

im trying to use destroy_cards to destroy some cards but im messing up marking the cards to be destroyed (what im trying to do in the first image). i feel like im messing up something really obvious 😅

red flower
#

local variables are not kept between contexts

#

also context.individual already loops through all cards, you don't need to loop inside it

#

SMODS.destroyed_cards doesn't exist, it's SMODS.destroy_cards

alpine tulip
#

cheers, programming is hard when im tired :))))

wispy falcon
alpine tulip
daring fern
alpine tulip
#

what would you suggest for making a table in the joker to store those gold cards that can be used in both contexts?

#

like whats the common practise for this type of thing in balatro modding?

red flower
#

the best way is to mark the card itself

#

like card.marked_for_destruction = true

alpine tulip
#

would card in this instance be context.other_card as thats the one being checked for the enhancement?

red flower
#

yeah

queen meadow
#

can i refer to a different joker's variable?

alpine tulip
#

how would i destroy all cards then that I've marked for destruction in context.after or would i have to destroy the card in that same context?

queen meadow
#

probably not, but would be nice i think

red flower
red flower
queen meadow
#

ay hold on

#

if i have a smeared joker, it will also add the diamonds

red flower
#

I don't get it

daring fern
queen meadow
#

the diamond card on the right does that counting already

alpine tulip
queen meadow
#

so i would like
heartsindeck + (different joker's variable) diamondsindeck

red flower
queen meadow
#

i see

loud summit
#

how do you destroy a card instantly

faint yacht
#

SMODS.destroy_cards(card, nil, true)

loud summit
#

oke

#
    calculate = function(self, card, context)
       if context.open_booster then
          local newcard = card:create_card(card, 1)
          local set = card.ability.set
          SMODS.destroy_cards(newcard, nil, true)
       end
    end``` also is this a stupid thing to do
red flower
#

card:create_card doesn't exist

loud summit
#

oh

#

how do you call that for a booster

red flower
#

what's the effect supposed to be

loud summit
#

when booster is opened, create the default card for the set

red flower
#

that's hard because boosters don't store the set anywhere and they can also have different sets

#

even in vanilla

loud summit
#

thats why im approximating it by having it generate a card and getting its set

red flower
#

oh i get it now, yeah i wouldn't do that

#

i would get the first card in the booster area

loud summit
#

oh

#

oh yea

#

is the booster area filled by the time open_booster is fired?

red flower
#

uhhh no idea

loud summit
#

hmn

#

so i should set up an event that returns false until the booster area's first card is non null?

#

and then run the code

red flower
#

if it doesn't generate before then yes that's what I would do

loud summit
#

oke cool

unkempt bronze
#

isn't that covered in VanillaRemade?

red flower
#

no

unkempt bronze
#

Feels like something that should be.

red flower
#

i dont think there's anything ui related there

#

the only questions about UI are not done

wispy falcon
#

Anyone know what mods I could look into for that?

red flower
#

mine :3

unkempt bronze
#

The joker goes like this: Once every ante, you can buy a rare or uncommon joker and get it in its own booster pack next ante. The rest of the time, it doesn't do anything except look flashy.

red flower
#

i don't understand what that means even

unkempt bronze
#

what part are you confused on?

red flower
#

where do you buy the joker from? the shop? what does its own booster pack mean?
also i don't play many mods so i don't have examples of effects at hand

unkempt bronze
austere oasis
#

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

wispy falcon
unkempt bronze
austere oasis
austere oasis
red flower
red flower
unkempt bronze
#

do you know at least where to make a left tab?

red flower
red flower
#

on the joker?

unkempt bronze
austere oasis
red flower
red flower
unkempt bronze
#

Nice! I'll figure out the other part as it does.

austere oasis
red flower
#

then send the code

#

also it's better to test your mod on its own first

austere oasis
#

huh thats weird

#

whenever i try to open my code it crashes

unkempt bronze
#

The... code crashes?

vocal helm
#

Do poker hand levels start at 0 or 1?

austere oasis
#

oh wait

vocal helm
#
in_pool = function(self, args) --equivalent to `enhancement_gate = 'm_stone'`
        for _, hand in ipairs(G.GAME.hands or {}) do
            if hand.level > 1 then
                return true
            end
        end
        return false
    end

mostly just wanted to check if a hand was higher than 1 for a pool check

austere oasis
#

lmme do a few adjustments

red flower
vocal helm
#

awesome ty :>

wispy falcon
#

Why does this result in an error when I press the button?

long sun
#

similar to add_to_hand during modify_scoring_context, for deciding which cards do score, is there a remove_from_hand?

loud summit
#

yea its in the smods wiki

long sun
#

wait this is documented? 💥 hold on

red flower
#

it's not

long sun
#

not finding it in calculate functions

red flower
#

but remove_from_hand is indeed a thing

long sun
#

i thought i checked, ya

#

ah schweet 🤘thanks!

#

i'm like a psychic :3 hehe

loud summit
queen meadow
#

can we edit how many cards a booster pack has inside it using vouchers?

loud summit
queen meadow
#

i'm very original you see

loud summit
#

the number of cards a booster has is based on the config value of the booster

daring fern
red flower
loud summit
queen meadow
#

why is this not on the wiki 💔

loud summit
#

more undocumented vars my beloved

red flower
red flower
loud summit
#

thats a changelog

red flower
#

with documentation

loud summit
#

why would i look at the announcements for documentation

#

when theres a wiki

red flower
#

that's a completely separate issue

#

huh

#

huh

wispy falcon
red flower
#

i know what rage against the machine is
i dont follow what that has to do with what you're replying to

wispy falcon
red flower
#

ok, i get what that means now but i still don't follow what that has to do with what you replied and why you moved the conversation to modding dev

red flower
#

ai is not good at reading logs for balatro

lucid owl
#

BULLS ON PARADE

#

ai goes against the entire thesis of rage against the machine lmao

#

not with their consent

#

i don't care

prisma loom
#

Is this too vague of a description?

queen meadow
lucid owl
#

either way ai sure as hell isn't making anything for me

prisma loom
#

btw
Hi trif!

lucid owl
#

hellooo

prisma loom
#

My dumbass deleted your progress on Dark Idol

#

pls forgive me

#

I confess

lucid owl
mossy minnow
#

what do you think about trump using ai

prisma loom
red flower
#

chat there's a rule about this

limber blaze
#

hello

tall wharf
#

ahem

mossy minnow
#

ruby

#

assault this ai bro

wind steppe
#

shut up about ai discussion of it is banned

limber blaze
ionic cobalt
#

can we kill this guy

wind steppe
#

everyone else block the guy

mossy minnow
limber blaze
#

there are infinitely many better uses of my time

#

I think rolling around in the mud would be more productive

lucid owl
#

driving up the electricity bill by 30% to ai generate motorcycle crashes 💜

#

shuuut uuuuuup

limber blaze
#

"nothing ever happens"

#

I think you are actually less than worthless

slow ocean
#

disengage

tall wharf
#

Muse Dashへの楽曲収録を記念して、ばやちゃおさんから特別仕様のMVをいただきました!
⇣「描いてみた」動画はこちら
https://youtu.be/wBo_-GPXDcQ

動画内に登場するキャラクター達はばやちゃおさんの創作『魔けモン!』のキャラクターです。
https://bayachao.wixsite.co...

▶ Play video
red flower
#

modding-chatting in modding-dev 😥

slow ocean
#

restore the sanctity and preserve it for helping the folks

#

saluting emoji

queen meadow
#

this is probably baby shit for the real programmers i feel kinda bad

lavish elm
#

I miss my x += num

queen meadow
#

idk it crashes when i do that

terse merlin
#

hawk.lua

red flower
frosty rampart
#

is there an easy way to detect if a copy_card call is being used to actually make a copy of a card in-game and not just for e.g. the deck view

frosty rampart
#

inch resting
i'll give it a try

#

yep works, thanks

lavish elm
#

how to do recursion inside calculate?

outer jungle
#

how do i make a joker immune to changes made by oops / and other changes that could be made to the probability?

loud summit
slim ferry
#

don't do that, use no_mod in pseudorandom_probability

#

otherwise probability detection wont work with it

lavish elm
sand sandal
#

that does the actual stuffs

manic rune
sand sandal
#

then calculate is a wrapper

#

for the function

#
local function recursive(card, ctx)
  -- do things
  if card.ability.extra.skibidi_id > ctx.skibidi_id then
    recursive(card, ctx)
  end
end
#

then in calculate

lavish elm
#

ok thx

sand sandal
#
{
  calculate = function(_, card, ctx)
    recursive(card, ctx)
  end
}
sand sandal
#

recursion is usually last ditch

lavish elm
slim ferry
#

math.random is unseeded

#

you should always use the pseudorandom functions over the base random stuff

lavish elm
#

will there be any issues when using unseeded?

slim ferry
#

well

manic rune
#

yes

manic rune
#

main menu -> load run will also give different results

slim ferry
#

it will be independent from run seed

#

so running the same seed twice will give different outcomes

#

iirc

#

only ever use math.random for things that dont affect gameplay

manic rune
#

so unless its something thats not important gameplay-wise, dont use math.random

#

yeah dang i should stop multi tasking

lavish elm
#

ok thx

willow scroll
#

i may be dumb how do i target another mod in a lovely patch? =[SMODS (mod_id) "(relative_file_location)"]?

willow scroll
#

noted, thank you

lavish elm
sand sandal
#

did you not declare the function beforehand

lavish elm
#

wdym by that?

hardy viper
frosty rampart
#

you know what they mean

hardy viper
#

teeeeeeeeeeeeeeechnically

lavish elm
#
local count = 0
count = func(card, context, count)

why does this make it nil?

frosty rampart
#

show the code for the func function

lavish elm
#
func = function (card, context, count)
            if SMODS.pseudorandom_probability(card, "xmpl_glitchyness", 1, card.ability.extra.immutable.odds) then
                count = count + 1
                func(card, context, count)
            else
                return count
            end
        end
frosty rampart
#

you need to return the recursive call, otherwise it just throws out the result

prisma loom
frosty rampart
prisma loom
#

First time seeing smth like that

loud summit
#

how do you fire a warning with debugplus

frosty rampart
loud summit
#

oh

outer jungle
# slim ferry don't do that, use no_mod in pseudorandom_probability

hey can someone look at this i can't seem to get it working
i'm trying to make this joker immune to probability changes

    key = "recycled_joker",
    atlas = "j",
    pos = { x = 3, y = 0 },
    rarity = 3,
    cost = 8,
    blueprint_compat = true,
    config = { extra = { xchips = 2, xmult = 2 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.xchips, card.ability.extra.xmult } }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            if SMODS.pseudorandom_probability(card, tostring(G.GAME.seed), 1, 2, "recycled_joker", true) then
                return { xchips = card.ability.extra.xchips }
            else
                return { xmult = card.ability.extra.xmult }
            end
        end
    end

}```
loud summit
#

wwwwwhyyy are you getting the seed directly

outer jungle
#

i can put anything in there right?

frosty rampart
#

yea

wispy falcon
#

How do I make a field for user input in a window?

outer jungle
frosty rampart
frosty rampart
outer jungle
frosty rampart
#

what version of smods are you using? the ability to prevent probabilities from being modified was only introduced in 0827

outer jungle
#

smods-1.0.0-beta-0827c

frosty rampart
#

strange

outer jungle
#

i mean i can try to change the seed

frosty rampart
#

worth a try? i literally don't see anything else out of the ordinary

plain apex
#

still need help on this it runs fine for me but other people crash trying to run this

outer jungle
broken rivet
#

is it possible to fully replace a joker return

red flower
outer jungle
red flower
#

Are you playing rounds or loading a save state or reloading the game or what?

outer jungle
#

new runs

frosty rampart
#

did you install smods from balatro mod manager?

outer jungle
red flower
#

maybe you have been really lucky lmao

outer jungle
#

maybe xd

red flower
#

but yeah no_mod works for me

outer jungle
#

hmmm

lavish elm
#

how to double the level of played poker hand

red flower
#

return { level_up = G.GAME.hands[context.scoring_name].level }

loud summit
#

get the level and call SMODS.smart_level_up_hand()

#

oh

red flower
outer jungle
lavish elm
#

ok thx

red flower
outer jungle
#

i think cryptid makes my joker behave weird

red flower
#

some mod might be hooking it wrong because it's a new argument to the function

outer jungle
#

it works fine without it

red flower
#

yeah it might have an incorrect hook, cryptid has some probability shenanigans

outer jungle
#

alr thanks

outer jungle
#

i used cryptid for testing other jokers that why i had it installed

frosty rampart
#

i'll put in a bug report on the cryptid discord

thorn basin
#

Some time ago I made a joker that reveals the next 5 drawn card but I just discovered that for some reason the UI registers only the rank and suit of said cards and not if they have an Edition/Enhancement/seal.
How is it possible to fix this?

red flower
#

instead of c_base get the enhancement key

#

for edition and seal it's a bit more complicated because you need to save the card first and then give it the edition and seal

#

you can maybe use copy_card instead

thorn basin
red flower
#

if you get the center key for a card without enhancement it will be c_base

thorn basin
#

also this means that I must put ALL the enhancements keys

#

including my custom ones...

red flower
#

i think you didn't understand what i said

#

use G.P_CENTERS[G.deck.cards[number].config.center_key]

vocal helm
#

Is there a way to set up a deck/back so that it prevents specific jokers/vouchers/etc. from showing up? i.e. I don't want Wasteful/Recyclomancy to show up for the deck

red flower
#

yes add them to G.GAME.banned_keys iirc

vocal helm
#

ooh alright

thorn basin
red flower
#

'c_base' is the default card which was what you were using

#

that just uses whatever the current enhancement is

thorn basin
#

aight

#

so I always getting the base version of the playing cards

#

thx for the clarification N'!

hidden oak
#

I completely redid some code i had from yesterday to turn played face cards into queens, I took midas mask and combined it with some of ouija. It was working (though not as intended) so i redid it, i think it's better overall but now i'm getting an error instead of the wrong result. It's trying to set the suit to nil. I'm not sure why, i expected it to work fine since it's almost exactly the same as the original code i took

#
    calculate = function(self, card, context)
        if context.before and not context.blueprint then
            local faces = 0
            for _, scored_card in ipairs(context.scoring_hand) do
                if scored_card:is_face() then
                    local _rank = 'Q'
                    faces = faces + 1
                    for i = 1, #context.scoring_hand do
                        G.E_MANAGER:add_event(Event({
                            func = function()
                                local _card = context.scoring_hand[i]
                                assert(SMODS.change_base(_card, nil, _rank))
                                scored_card:juice_up()
                                return true
                            end
                        }))
                    end
                end
            end
            if faces > 0 then
                return {
                    message = "Sweet!",
                }
            end
        end
    end
}
vocal helm
vocal helm
hidden oak
lavish elm
#
G.E_MANAGER:add_event(Event({
                    delay = 0.1,
                    func = function()
                        assert(SMODS.modify_rank(context.other_card, 1))
                        return true
                    end
                }))

why not work?

hidden oak
humble pawn
#

Is there a way to hide these? I want this card to be indistinguishable from a normal card

#

Nvm I figured it out

vocal helm
#

ty!

unkempt bronze
#

Mister "Code-Problems" is back

#

Anyone know any clean fixes?

solid mesa
unkempt bronze
frosty rampart
#

so why are you trying to do something with it

unkempt bronze
#

I was trying to unlock jokers to see them show up in the shops

frosty rampart
#

no why are you trying to do something with card.ability.extra.copy

#

i don't see it anywhere else in the code either

unkempt bronze
#

Cuz it's DNA but worse

solid mesa
#

"top to bottom" closes in line 60, it should close in line 69

frosty rampart
#

no that's a hook

unkempt bronze
frosty rampart
#

top to bottom is fine

solid mesa
#

nvm i get it

frosty rampart
#

the joker itself does nothing, all it does is indicate that wrap_around_straights are supposed to happen

solid mesa
#

mb

frosty rampart
# unkempt bronze Cuz it's DNA but worse

DNA has card.ability.extra.copy because it has config = { extra = { copy = 1 } }. it's a configurable value for how many copies to create. you don't have that. either add that line to your joker or remove the loc_vars function

unkempt bronze
#

those... those aren't the right designs. And the names aren't there...

winter flower
frosty rampart
#

well you need to do localization

vocal helm
#

and set which atlas you're using

frosty rampart
#

yea you already have the atlas, you just need to tell each joker to use that atlas

unkempt bronze
#

Is that like a line at the top of the unified code, or is it per joker?

solid mesa
#

every joker has is own (atlas = "")

unkempt bronze
#

Thank you

#

Meta, should I make you a joker?

frosty rampart
#

i'd rather not, but thanks for the offer

lavish elm
#

how to make explosion effect?

#

well not necessarily explosion but how to do effects?

unkempt bronze
frosty rampart
#

you probably got the pos wrong for the other two

#

i see you have them at y = 1 and y = 2, but y is the vertical positioning

#

i assume your atlas has them all in a row, so you need to change the x value instead

unkempt bronze
#

And their names aren't there

frosty rampart
wispy falcon
#

How do I make a field for user input?

lavish elm
#
if context.mod_probability and not context.blueprint and (G.cardarea == G.play or G.cardarea == G.hand) then
            return {
                denominator = context.denominator * 2
            }
        end

why this not work?

frosty rampart
#

G.cardarea isn't a thing, and context.mod_probability doesn't get a context.cardarea (which is what i assume you were trying to check)

lavish elm
#

then how to do it?

frosty rampart
#

what's your goal? is this a card modifier of some kind?

lavish elm
#

joker making glass harder to break

frosty rampart
#

you should check if context.identifier is whatever identifier glass cards give for their probability rolls
you can figure that out by just having if context.mod_probability and not context.blueprint then print(context.identifier) end

lavish elm
#

ok thx

slim ferry
#

vanillaremade also has the same identifiers as vanilla

#

so you can look there as well

frosty rampart
#

even if what you were doing did work, it'd have unexpected effects because there are other cards that roll probabilities when they're played or held in hand (lucky cards)

#

the identifier ensures that you're only affecting glass cards

wispy falcon
slim ferry
#

object nodes have the option for a text input field

hardy viper
#

i love zero documentation

vocal helm
#

Is it possible to have a deck/back double the interest at the end of round? I don't think decks can reward bonus money

slim ferry
#

decks can do calculates and other stuff just like any other card

#

though here you would just increase G.GAME.interest_amount by 1

vocal helm
#

ahh, fair, yeah

#

thanks!

wispy falcon
slim ferry
#

its.. ui 😱

#

actually

#

its not an object node

#

i forgot that its a seperate node type

#

G.UIT.I

frosty rampart
wispy falcon
hardy viper
#

brilliant way to get out of writing docs

frosty rampart
#

fr lmao

slim ferry
#

plus a width and height so it actually shows

keen atlas
#

create_text_input function

wispy falcon
#

Why does local position = pseudorandom{"bossRiddle", 1, #CSTORM.boss_riddles.Jokers} result in the error number expected, got table?

frosty rampart
#

use parentheses, not curly braces

wispy falcon
#

Shit, my bad. Sorryyyy

thorn basin
#

what is the table for all consumables?
(if there is one, I hope)

slim ferry
#

just do set = "Consumeables" in create_card

topaz berry
#

I'm trying to check the suit of the first two cards in a scored hand in a before context but I am getting a nil value specifically the second card I read. Specifically in the following line of code
if(context.scoring_hand[2]:is_suit("Clubs")
How do I get the second card in a played hand?

thorn basin
slim ferry
thorn basin
#

okay so, um I have no idea how did this happen.
How can I fix it in order to make the consumables get created in the consumables area?

wispy falcon
#

How can I make this text move? Like the Joker names, for example

unkempt thicket
#

Add area = G.consumeables, to it

thorn basin
#

aight

unkempt thicket
slim ferry
#

no idea how text animations work for ui though

wispy falcon
slim ferry
#

i dont think so

gaunt thistle
#

lovely editor thing is coming along nicely

#

maybe lovely-ide is a better name? idk

keen atlas
#

fire

hidden oak
gaunt thistle
#

hmm that's not bad

thorn basin
#

how can I set the edition of a consumable I just added?

#

should I make a local variable that stores the created consumable?

tranquil cypress
#

it would just be edition = 'e_negative' I think

thorn basin
#

oh, aight

wispy falcon
#

How do I use dynatext?

modern kindle
#

as beautiful as you

wispy falcon
#

Hi Dilly o/

granite jay
#

Thinking of making an Xmult version of misprint, how do I achieve the description effect?

gaunt thistle
#

man im just happy that there's going to be a proper way to make patches now

#

we're almost out of the dark ages

modern kindle
#

yea thats gonna be absolutely fantastic

wispy falcon
#

UI needs to be less scary (easier) too

slim ferry
#

also idk how background colours work with ui text you'd probably need to nest the text elements

wind steppe
#

what function handles spawning consumables for the collection

wispy falcon
#

What are ref_table and ref_value for?

granite jay
#

Didn't work, it just shows blank

slim ferry
#

should at least have a single empty line like misprint does

#

if you have that then idk

granite jay
slim ferry
#

hm

#

okay well then

#

idk

granite jay
hidden oak
#

sorry for bringing this up again but the last suggestion worked, and now my joker is turning cards to the correct rank, but it's turning ALL scored cards into said rank instead of just the faces. could anyone figure a solution? I tried putting

if scoring_card:is_face() then

after defining card and before it changed the card's rank but it didn't change anything, i think i do need the statement but i can't determine where to put it

    calculate = function(self, card, context)
        if context.before and not context.blueprint then
            local faces = 0
            for _, scored_card in ipairs(context.scoring_hand) do
                if scored_card:is_face() then
                    local _rank = 'Queen'
                    faces = faces + 1
                    for i = 1, #context.scoring_hand do
                            G.E_MANAGER:add_event(Event({
                                func = function()
                                    local _card = context.scoring_hand[i]
                                    assert(SMODS.change_base(_card, nil, _rank))
                                    scored_card:juice_up()
                                    return true
                                end
                            }))
                    end
                end
            end
            if faces > 0 then
                return {
                    message = "Sweet!",
                }
            end
        end
    end
wind steppe
#

how would i check if a given card is in the collection

#

not if it has no_collection if a card object is in play or in the collection

wispy falcon
#

Why does the create_text_input stuff crash my game?

        n = G.UIT.ROOT, config = {r = 0.1, minw = 8, minh = 6, align = "tm", padding = 0.2, colour = G.C.BLACK}, nodes = {
            {n = G.UIT.R, config = {minw=1, minh=1, colour = G.C.MONEY, padding = 0.15}, nodes = rows },
            {n = G.UIT.R, config = {minw=1, minh=1, colour = G.C.CSTORM.GIT, padding = 0.15}, nodes = {

                create_text_input{
                    max_length = 30,
                    all_caps = true,
                    ref_table = Answers,
                    ref_value = "answer",
                    align = "cm",
                    callback = function()
                        check_riddle_answer(Answers.answer:lower(), Riddle.answer:lower())
                    end
                }
            }}
        }
    }```
#

Nvm, I got it

minor magnet
#

how would i go about making an oil lamp type effect

wispy falcon
#

How do I add to the current score?

frosty rampart
mossy quest
#
    calculate = function(self, card, context)
        if context.first_hand_drawn and not context.blueprint then
            local eval = function() return G.GAME.current_round.hands_played == 0 and not G.RESET_JIGGLES end
            juice_card_until(card, eval, true)
        end
        if context.cardarea == G.jokers and SMODS.end_calculate_context(context) and G.GAME.current_round.hands_played == 0 then
            local currChip = hand_chips
            local currMult = mult
            card.ability.extra_chips = card.ability.extra_chips + currChip
            card.ability.extra_mult = card.ability.extra_mult + currMult
            mult = 0
            hand_chips = 0
            return {
                message = localize('glutton'),
            }
        end
        if context.joker_main then
            return {
                chips = card.ability.extra_chips,
                mult = card.ability.extra_mult
            }
        end
        if context.end_of_round and G.GAME.blind.boss and not context.blueprint and card.ability.extra_chips ~= 0 and card.ability.extra_mult ~= 0 then
            card.ability.extra_chips = 0
            card.ability.extra_mult = 0
            return {
                message = localize('k_reset')
            }
        end
    end

this worked before I updated steammodded, any clue why it crashes now?
[SMODS Rickie "items/rimuru.lua"]:18: attempt to call field 'end_calculate_context' (a nil value)

frosty rampart
#

use three tick marks at the start and end of a whole code block, instead of one at the start and end of each line, to make it easier to read

#
like this
wispy falcon
mossy quest
#

I used the single ticks for the error msg

frosty rampart
#

you just edited it to look better, yes
anyway I can only assume smods removed the end_calculate_context function in an update. what does that check do anyway?

mossy quest
#

honestly I don't recall at this point, I just came back to this after 2 months of not touching Balatro

wispy falcon
granite jay
#

I wanna make an Xchip joker, does G.chips work so the joker knows how many chips there are?

#

Cos there's no xchip function.

wind steppe
#

there is an xchip function

#

you return xchips same as you would for xmult or mult or chips

#

also if you wanted to get the amount of chips for another reason you would use hand_chips

#

not G.hand_chips or G.GAME.hand_chips just hand_chips

vocal helm
#

howdy! this one's a little loaded but I think it's my last question for the day
I'm trying to make a deck so that every future instance of a specific consumable type gets replaced with one you already have; i.e. if you have Death in your consumables, all other Tarot cards will turn into Death.
I have my create_card_for_shop hooked so that it should do this + a custom function to do so but it's not working, plus it doesn't solve the other issue of every other way of obtaining a card turning into the right one. Any advice?

-- replaces a card with a card in the player's consumables if possible; takes a set and returns the KEY
function replace_with_player_consumable(set)
    local shuffled_consumeables = G.consumables
    pseudoshuffle(shuffled_consumeables, "j8mod_shuffle")
    print(shuffled_consumeables)
    for i, consumable in ipairs(shuffled_consumeables) do
        print(consumable.ability.key.." is part of "..set)
        if set == consumable.ability.set then
            return consumable.ability.key
        end
    end
    return nil
end

local ccfs = create_card_for_shop
function create_card_for_shop(area)
    local card = ccfs(area)
    if G.GAME.selected_back == "b_j8mod_hypnotic" then
        local new_key = replace_with_player_consumable(card.ability.set)
        if new_key ~= nil then
            card:set_ability(new_key)
        end
    end
    return card
end
granite jay
#

now what variable determines the back of the text?

#

for Xmult?

wind steppe
#

and instead of set_ability just return a different key

vocal helm
#

ahh, smart

#

thanks!

wispy falcon
#

How do I add to the current score, how do I check if a new run got started and how do I allow spaces in create_text_input?

minor magnet
#

dinamically changing config.center.config seems to not be affecting calculations

#

shame, i made such a clean recursive function too

mossy quest
#

baby is working again

frosty rampart
#

lmaoooo yea that's old

#

glad it's working again

mossy quest
#

Fixed my Undiscover mod as well

for v in pairs(SMODS.Centers) do
    SMODS.Joker:take_ownership(v,
        {
        discovered = false
        },
        true -- silent
    )
end
hexed stump
#

So if I'm understanding it correctly, with the new probability changes I could do something goofy like an enhancement that checks if a joker's probability is below 1/2, and then add 1 to it if so?

frosty rampart
#

yep
although note that because it's via calculate functions, the enhancement might not get to it before e.g. oops all 6s modifies it first, and it'll see the doubled probability from that
(i dunno if enhancements calculate before or after jokers)

hexed stump
#

From what I'm seeing from how it's written, 6s should do it directly to mod.probability so that shouldn't be an issue

frosty rampart
#

i think oops interacts with the new system now. maybe. i dunno for sure
but either way, it could still be an issue with any other modded content that interacts with probabilities like that

hexed stump
#

that's what I'm saying though, my assumption is when you get it it sets the global modifier

#

either way it does it's thing on buy and shouldn't be a problem

#

I can just whip something up to check after I fix all my probability stuff

vocal helm
#

How would I set the ability of a card to a random card from a specific pool?

#

(trying to set a joker to a random joker from my mod)

jolly shadow
vocal helm
#

nice, lol

#

I'm trying to make the classic "deck that makes your jokers show up more often"

jolly shadow
jolly shadow
#

cant u just do card:set_ability(center of your card from ur pool)

#

to change a card into one of ur jokers

vocal helm
#

that's what I got going

#

But I'm not sure what the pool/set is for all my modded jokers

#

and I can't really create a card to do this b/c it's setting the ability

atomic edge
#

is there a mod that adds a whole seal-type thing to jokers but as a whole new thing

#

i can check out

jolly shadow
atomic edge
#

besided cryptid

#

i realised i wrote in the wrong one

jolly shadow
#

no, modding chat was more correct

atomic edge
#

but its for mod development

jolly shadow
jolly shadow
#

that's a modding chat thing

frosty rampart
atomic edge
#

yea but im looking for it so i can check the code out to develop my mod

jolly shadow
#

🫡

atomic edge
#

thanks

frosty rampart
#

i'd probably recommend referencing paperclips instead of counters, because counters are a lot more involved and they can apply to jokers too (unless that's what you want)
i guess technically paperclips "can" apply to jokers in that they're stickers under the hood, but they're designed to only work on playing cards

hexed stump
#

there's still no way to check for the prescence of a sticker in a unified way right? even though now you don't need to apply the specific id of the sticker applied

atomic edge
#

oh okay thanks

frosty rampart
hexed stump
#

I assume that'll get added at some point later and then I can cry and update my stickers again

#

But for now I only need to remove one entry of the apply function

harsh belfry
#

how would i make an enhancement trigger after all the other card scoring is done (base chips, edition, etc)

clear ocean
harsh belfry
frosty rampart
#

yea that crash indicates an issue in the shader.fs file itself

harsh belfry
#

you can make a useless if statement with the edition1 variable

#

edition1.x > 2 * edition1.x or some shit

clear ocean
#

you hate to see it

pseudo sun
#

Can someone help me or give a sample code on how to make a tarot card when used on a card replaces it Enhancement?

frosty rampart
daring fern
#

manic rune
#

u want to create an UIBox with the major set to G.ROOM_ATTACH iirc

#

i gotta go outside rn though sorry, i will get back to u when i get home

daring fern
granite jay
#

How do I add the face decals on legendary jokers?

daring fern
granite jay
#

Yeah starting to suspect it's soul_path

daring fern
granite jay
#

Oh ok

#

Do both the card and the floating sprite have to be on the same png?

frosty rampart
#

yea

#

technically no, but it's a lot more effort than just putting the floating sprite in the same atlas

#

or wait lemme check the documentation hold on

#

ok yea you can't easily put the floating sprite on a separate atlas

daring fern
frosty rampart
#

which is why i qualified my statement with "easily"

daring fern
#

And change card.children.floating_sprite.atlas

frosty rampart
#

it's certainly possible, but often not worth the effort

daring fern
frosty rampart
#

still more effort than just putting the floating sprite in the same png as the base sprite

feral pier
#

Jonkler Idea: "Real Joker" (joker itself is just a guy dressed up as Jimbo)

Effect: gains 0.5 mult if hand played is possible with a normal deck of cards (maybe except high card idk yet)

#

maybe a other caveat is it resets if you play a hand that's NOT possible with a normal deck ex. flush five

granite jay
#

What's the best way to make a joker that copies the effects of every joker in the current run?

daring fern
ripe oak
#

Quick question: Does anyone know if there is a list of possible vanilla args.type arguments somewhere? (For card unlocking)

granite jay
#

Yeah every joker owned.

faint yacht
#

...be mindful such can result in a stack overflow - I tried that myself before and it was one hell of a headache.

daring fern
# granite jay All of your jokers here
local effects = {}
for k, v in pairs(G.jokers.cards) do
    if v ~= card then
        local effect = SMODS.blueprint_effect(card, v, context)
        if effect then
            effect.colour = G.C.RED
        end
        table.insert(effects, effect)
    end
end
return SMODS.merge_effects(effects)
faint yacht
#

-# At least such was the case for me, especially the probability contexts that would just loop constantly.

daring fern
# granite jay Oh boy

No, it wont break unless the card you're copying is copying the card and it's not using SMODS.blueprint_effect

faint yacht
#

I personally had to add the (context.mod_probability or context.fix_probability or context.check_enhancement or context.blueprint or context.pseudorandom_result) as filter back when I still used it. 😅

granite jay
#
 loc_vars = function(self, info_queue, card)
        local r_value = ""
        local r_mults = {}
        for i = card.ability.extra.min, card.ability.extra.max do
            r_mults[#r_mults + 1] = tostring(i)
        end
        local loc_mult = ' ' .. (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_mults,
                        colours = {G.C.MULT},
                        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_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult,
                            loc_mult, loc_mult, loc_mult, loc_mult },
                        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,```
#

How do i make it so the X# mult here has the red background?

granite jay
#

Would it be best to make it blueprint incompatible for balancing?

granite jay
#

Oki

ripe oak
#

Does anyone know what the unlock requirement code that Brainstorm uses looks like?

#

I need to copy it.

daring fern
ripe oak
#

nice

versed swan
#

how do you set a sticker on a card?

granite jay
#

How do you get the current round number when triggering jokers?

#

I want a joker to do smth in odd numbered rounds and smth else on even numbered rounds for context.

daring fern
versed swan
#

thank you

granite jay
versed swan
daring fern
versed swan
#

that works, thank you

granite jay
#
calculate = function(self,card,context)
        if context.first_hand_drawn and not context.blueprint then
            local eval = function() return G.GAME.current_round.hands_played == 0 and not G.RESET_JIGGLES end
            juice_card_until(card, eval, true)
        end

        if context.before and G.GAME.current_round.hands_played == 0 and #context.full_hand == 1 then
            local scored_card = context.scoring_hand[1]

            scored_card:set_ability('m_mult', nil, true)
            G.E_MANAGER:add_event(Event({
                func = function()
                    scored_card:juice_up()
                    return true
                end
            }))
            return {
                message = localize('k_upgrade_ex'),
            }
        end
    end,
#

What's the best way to make it so the joker adds a random enhancement?

mystic river
#

something like

local enhancements = {}
for k,v in pairs(G.P_CENTERS) do
 if v.set == "Enhanced" then
  table.insert(enhancements, k)
 end
end
local enhancement = pseudorandom_element(enhancements, "some seed")

this will get you the key of a random enhancement, put that in set_ability()

#

assuming i didn't forget or miss anything, which is always possible
always use debugplus to test stuff to make sure it's what you think it is

faint yacht
#

...wouldn't it be simpler to

card:set_ability(SMODS.poll_enhancement({guaranteed = true}), nil, true)

?

mystic river
#

or that lol
i forgot that existed

real crown
#

How do I add specific jokers to a booster pack? To have it work similarly to buffoon packs, but just have a list of jokers that can appear?

granite jay
#

Does it exclude stone cards?

faint yacht
#

Includes, as Stone is an enhancement.

granite jay
#

Fair

#

Oh yeah what about making it so only cards with no enhancement are affected?

#

And so stones don’t get drawn?

daring fern
long sun
#

is there a list that stores all unlocked hands, or do i need to manually check through G.handlist?

granite jay
daring fern
mystic river
daring fern
mystic river
#

do we care about quantum enhancements in this context?

daring fern
granite jay
#

Thx

daring fern
mystic river
#

define "counts as"

daring fern
granite jay
#

Is no enhancement technically regarded as an enhancement?

#

To the game code

mystic river
#

okay, is that what we care about?
or do we care about "there's not already an enhancement there that will be overridden if we add this one"?

mystic river
#

that was directed at 515 anyway

mystic river
#

like - are quantum enhancements supposed to be completely equivalent to real enhancements, or are they supposed to be subordinate?

#

am i completely misunderstanding the design goal?

lavish elm
#

what is the difference between using strings message = "hello" and using localization message = localize("k_hello_ex") and is there any benefits?

mystic river
#

the benefit of localization is that you can localize

#

like, the result of localize("some_key") can depend on what language the game is set to

#

(provided it's actually been translated, of course)

lavish elm
#

ok thx

lavish elm
#

how to change the text inside the loc_text using the calculate function?

lavish elm
#

how to check if a card is not scoring?

granite jay
granite jay
daring fern
#

lavish elm
#

how to write custom info_queue?

limber blaze
#

just let it go already

#

someone always has to have the last fucking word instead of letting the conversation die down

#

go away

#

<@&1133519078540185692>

#

I would assume the person who brought back a dead conversation from yesterday

#

about a topic that's not even allowed to be discussed here

#

someone hurting your feelings doesn't make you automatically in the right

exotic hedge
#

I have a paper due in 2 hours so I’m just going to say, if anyone continues this conversation you’re getting banned

#

❤️

ionic cobalt
#

gl with your paper

exotic hedge
long sun
#

i'm looking to replace this draw function, as it's not working properly

#

tilting the card doesn't interact with the shader

#

like, the light reflection doesn't shift

#

also, why is this tooltip appearing on Apollo's Bracelet?

#

it doesn't have loc_vars

daring fern
long sun
#

which script is that in, UI_definitions?

daring fern
long sun
#

hmm, seems like the only thing changing anything is MmmmmJokers

#

i'll disable it and see if that fixes it

#

alas, fix it it did not

manic rune
#

wat do u mean by this, too 🤔

is it like, retriggering the effect that retriggers jokers?

#

i suppose an easy way out of this would be like, patch/hook into whatever code that handles joker retriggers and multiply the number of retriggers if its retriggered

manic rune
#

making a huge guess it has to do something with eval_card, lemme check

manic rune
#

if you run eval_card on a joker again in here then it should hopefully be rescoring?

#

though if you want it to like, rescore on all contexts then u probably can just hook to eval_card, run the ref function twice and merge the effects, idk

daring fern
manic rune
#

dang

daring fern
manic rune
#

whats the difference between that and rescoring though

daring fern
manic rune
#

i feel like what i suggested should do that, since the first local a1 = eval_ref(...) for instance would include both the triggers and retriggers of the first time, then the second local a2 = eval_ref(...) would include those of the second time

if you merge them together, iirc ret from a2 will only run after a1's ret which should be identical? idk

#

🤔 unless eval_card doesnt account for retriggers which i can see why

daring fern
manic rune
#

dang.

#

lemme find something else

#

hmm

#

how about SMODS.trigger_effects?

#

that should account for retriggers
-# hopefully

manic rune
#

wtf really

hardy viper
#

retriggers aren't real

manic rune
#

true

#

erm

#

what about SMODS.calculate_effect

#

idk i cant find anything else

minor magnet
#

how do i remove this (making a new stage/states)

daring fern
manic rune
#

im gonna cry

#

idk, my only idea rn is to figure out whatever function that has the return table of both triggers and retriggers, so you can merge them both together through SMODS.merge_effects....

thorn basin
#

uuuh... is it normal that with the coupon tag the booster packs prices become -1?
Okay nvm, I figured it out why it does that.
Some time ago I made two vouchers and one of them it adds one extra booster pack in the shop and makes it so booster packs cost 1$ less.
How can I fix this?
(I was thinking about specifying which voucher is allowed to modify the hooked set cost function but I'm not sure...)

daring fern
thorn basin
manic rune
#

takes the higher value among the two

thorn basin
#

aight

manic rune
#

for instance, if self.cost-1 is 1, then since its higher than 0, it will be taken

#

else if its a negative number then it will take 0

thorn basin
#

thanks Bepis and Somethingcom!

manic rune
#

the opposite is true for math.min

thorn basin
#

oooh I understand it now

wispy falcon
#

How do I add to the current score, how do I check if a new run got started and how do I allow spaces in create_text_input?

manic rune
#

ease_chips iirc

#

and i have no clue what the second part means 3:

wispy falcon
#

Okay and how do I allow the user to type spaces in a text input field?

wispy falcon
daring fern
wispy falcon
#

Wait, does update not exist in SMODS.Blind?

daring fern
broken rivet
#

does anyone have any idea what could be causing this artifact
it only affects one row of a specific sprite atlas

#

it doesn't show inside of image viewers or editors, only in-game

lavish elm
gaunt thistle
#

Really early WIP of a timetravel patch debugger. When complete it'll let you scrub through the patch timeline so you can see how different patches interact, etc. Should be cross mod easier

#

Oh and I added tabs to the editor

#

so you can keep stuff open while you work

gaunt thistle
#

🤔

quartz pendant
#

does the mod description allow blank lines? I feel like it looks a bit crowded

bold sleet
#

As far as I know, there is a way to completely override the mod description tab.

#

I don't know exactly how it works, but there is an option for that.

#

Well, more than an option, a function.

red flower
atomic edge
#

hey guys how do i make my custom consumable not appear in the shop? like spectral cards

atomic edge
#

so at 0 they wont right?

#

thanks

red flower
#

yeah

#

the text also implies that if you leave it empty it wont but im not sure

atomic edge
#

okay ill just set it to 0

red flower
#

ok yeah if you leave it empty it's set to 0 too

lavish elm
red flower
# lavish elm bump

put it in set Other in the loc file and then do info_queue[#info_queue+1] = { set = "Other", key = "the key of the entry"}

lavish elm
#

where is the text part?

frosty rampart
#

you put it in your localization file like joker text (but in Other instead of Joker)

lavish elm
#

can you show me an example I learn best with these

willow scroll
#

is there a way to check highlighted cards independent of cardarea?

#

like if i want to check if i have a consumable highlighted, no matter if its in G.consumebles or in G.pack_area or G.shop

willow scroll
#

aha thank you

quartz pendant
timber oriole
#

is there someone named ethan in this chat

red flower
gaunt thistle
#

hi

#

am I about to be yelled at

timber oriole
#

wake up ethan

gaunt thistle
#

this redbull aint doing it for me

real crown
#

How can I add specific jokers to a custom booster pack? Like listing a bunch of jokers, and other than that it's like a buffoon pack

gaunt thistle
#

some more ui experimenting

charred widget
#

Hi friends! I was just playtesting Rayquaza when I got this crash. Anyone know what this means?

willow scroll
#

i assume something that cares about this forgot to typecheck other_joker_ret

lavish elm
#

How to make this take in the values of the Joker
this is inside the Other Set

text = {
  "Gains {X:chips,C:white}X#3#{} Chips",
  "When {C:diamonds}Diamonds{} or {C:hearts}Hearts{} are scored",
  "Currently: {X:chips,C:white}X#4#{} Chips"
}
charred widget
willow scroll
#

returning true in a normal context should just mean that the joker was triggered/checked but had no effect

willow scroll
#

so i think whats happening here is that the mod youre testing modified context blueprint with a patch but isnt typechecking other_joker_ret before trying to index it

charred widget
#

something like that

#

well for some context i had a brainstorm hooked up to Rayquaza

willow scroll
#

could you check your lovely dump

#

go to mods folder > lovely > dump > card.lua and see what line 2650 is doing

willow scroll
#

is rayquaza your joker or?

charred widget
#

yes, but idk why it would be crashing, because brainstorm worked several times with Rayquaza before it ever crashed

willow scroll
#

do you perhaps have a return [bool] in your rayquaza calc function?

willow scroll
charred widget
willow scroll
charred widget
#

but i'm confused as to why it would only crash now. it never crashed before this

red flower
timber oriole
gaunt thistle
#

update lovely

timber oriole
#

im on 1.0

gaunt thistle
#

we're at 2.0

timber oriole
#

thanks that helped

gaunt thistle
#

also make sure you didnt forget the dump_all property in your patch file

ashen drift
hardy viper
timber oriole
ashen drift
#

truly an enigma

#

teach me your ways

timber oriole
#

as a janitor

ashen drift
#

interesting

#

thank you

loud summit
gaunt thistle
thorn basin
#

how do I display the name of a custom consumable?
I tried making a label but it still doesn't work

vocal helm
#

you have to make a custom localization, I'd imagine

thorn basin
thorn basin
#

I also made a label to see if it worked but it still doesn't

#

maybe I should modify the label

frosty rampart
#

for that specifically you need to localize b_modprefix_consumabletype_cards = "something" in misc -> dictionary

thorn basin
#

aight

thorn basin
frosty rampart
#

yea, for the badge it's k_modprefix_consumabletype (also in misc -> dictionary)

thorn basin
frosty rampart
#

idk

vocal helm
#

@chrome widget sorry for the ping, wanted to reach out since you're the most knowledgable on the subject, I think
How'd you get your joker shaders working with the distortion effects so that they don't encroach on other parts of the card atlas? And do edition shaders work with your cards? Mine break when not editionless/foil

minor magnet
#

how do i have a non-card function get called on update?

chrome widget
vocal helm
#

Yeah, Starry-Eyed Jokestar (iirc) has a wavy effect applied to it that's similar to what I'm trying to do with one of mine

#

(Werewire's edges are supposed to be wavy but are disabled since they went into Color Cafe/D100's sprites)

chrome widget
#

Oh! Yes, that one actually specifically had this problem

#

But there's two solutions to it

#

Starry's full atlas looks like this, with the two wavy bar effects having these individual sections, and the shader control having this math for the wave effect. The constant 0.01 modifier there is the function amplitude, and when set too high, the actual wave pulls too far of neighboring pixels in the atlas. The alternative is the modifications within the sin function (wave_t and the radians result primarily) which affects the level of distortion within the amplitude (I think it's called phase shift but it's been a while since I did trig)

#

However, the alternate solution is to just use individual atlases for effects that you want clear borders on. Starry is actually one of the more complicated Joker atlases I use but unlike a lot of modders, my cards have individual sprite files. Some of them specificially separate out a number of individual shader effect textures to prevent any overlap, such as Joker M having some different masks that it applies in its shader, which are just passed in with extern Image

#

Some of these admittedly need consolidation, but with the exception of a few edge cases (ironically, also Joker M), it tends to make working with unique art effects easier

#

Joker M for reference. I had to fiddle with it because the UV calculation I was using expected single atlases, not big multi-card atlases like vanilla uses, so eventually I fixed that and it now works regardless of atlas size

fiery bronze
#

Still trying to make this joker work

#

This is all I have right now

#

Trying to figure out how to detect if this card had a destruction attempt made on it

vocal helm
# chrome widget Some of these admittedly need consolidation, but with the exception of a few edg...

sorry for the delay, but yeah, this makes sense! I'm curious what the process is like inputting the uniform for the image given I'm also gonna be doing the Deltarune Prophecy thing at some point haha

so is the shader conflict thing with Polychrome/Holographic/Negative an atlas issue as well? is there a specific way you do the draw function in the joker so that the shaders work together, or is that something I'd have to hook/use a DrawStep for

minor magnet
#

how do i create an event only if the previous event has finished?

chrome widget
#

In rare cases I've just implemented edition drawing custom for cards, but that only works for very limited effects

#

Let me get you the code for that

vocal helm
#

much appreciated 🙇
love the effects too btw, insanely creative stuff

chrome widget
#

So this is a little messy since I'm on mobile, my full hooked center draw step has a bunch of custom branches for specific cards that need special behavior, but the thing at the bottom is what I'm referring to. If any card has card.late_center_draw set, then it skips calling the center function until the later step after editions in priority

-- prevent late drawing centers from drawing twice
SMODS.DrawStep:take_ownership('center', {
    func = function(self, layer)
        --Draw the main part of the card
        if (self.edition and self.edition.negative and not self.delay_edition) or (self.ability.name == 'Antimatter' and (self.config.center.discovered or self.bypass_discovery_center)) then
            self.children.center:draw_shader('negative', nil, self.ARGS.send_to_shader)
        elseif not self:should_draw_base_shader() then
            -- Don't render base dissolve shader.
        elseif self.config.center.key == 'c_fnwk_streetlight_notorious' and self.children.noto_layer then
            self.children.noto_layer:draw_shader('fnwk_stand_notorious', nil, nil, nil, self.children.center)
        elseif self.config.center.key == 'c_fnwk_bluebolt_insane' then
            local hue_mod = math.rad(G.TIMERS.REAL % 1 * 360)
            G.SHADERS['fnwk_stand_insane']:send('hue_mod', hue_mod)
            self.children.center:draw_shader('fnwk_stand_insane')
        elseif not self.greyed then
            self.children.center:draw_shader('dissolve')
        end

         --If the card is not yet discovered
        if not self.config.center.discovered and (self.ability.consumeable or self.config.center.unlocked) and not self.config.center.demo and not self.bypass_discovery_center then
            local shared_sprite = (self.ability.set == 'Edition' or self.ability.set == 'Joker') and G.shared_undiscovered_joker or G.shared_undiscovered_tarot
            local scale_mod = -0.05 + 0.05*math.sin(1.8*G.TIMERS.REAL)
            local rotate_mod = 0.03*math.sin(1.219*G.TIMERS.REAL)

            shared_sprite.role.draw_major = self
            if (self.config.center.undiscovered and not self.config.center.undiscovered.no_overlay) or not( SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].no_overlay) then 
                shared_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)
            else
                if SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite then
                    SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)
                end
            end
        end

        if self.ability.name == 'Invisible Joker' and (self.config.center.discovered or self.bypass_discovery_center) then
            if self:should_draw_base_shader() then
                self.children.center:draw_shader('voucher', nil, self.ARGS.send_to_shader)
            end
        end

        if self.late_center_draw then
            return
        end

        local center = self.config.center
        if center.draw and type(center.draw) == 'function' then
            center:draw(self, layer)
        end
    end,
}, true)

SMODS.DrawStep {
    key = 'late_center_draw',
    order = 22,
    func = function(self, layer)
        if not self.late_center_draw then
            return
        end

        local center = self.config.center
        if center.draw and type(center.draw) == 'function' then
            center:draw(self, layer)
        end
    end,
    conditions = { vortex = false, facing = 'front' },
}```
vocal helm
#

after editions

#

ooh alright

chrome widget
#

Ye. Unfortunately the only way to easily do fully procedural stacked shader effects with the vanilla editions would probably be to like..... get the direct color information on a sprite pixel-by-pixel, then record it as a new image, then apply that custom as the image drawn for the main center child prior to the edition being drawn, then draw it, then reset the image. And doing that every frame feels a bit clunky and unperformant

#

So instead I go the route of just having a lot of these effects work like floating sprite cards do, where the floating sprite in vanilla doesn't apply the edition normally, just to the card below

vocal helm
#

that makes sense, yeah, esp in context

#

thank you!

chrome widget
#

Yw!!!

slim ferry
#

Im assuming thats what you mean

daring fern
chrome widget
#

Also J8 thank you for expressing interest in my work!! I'm firmly in a low period right now and I'm not making much progress so it's nice that people think about it even when I'm not actively prompting discussion

vocal helm
#

yeah ofc!! i would've reached out in DMs to nerd out about shaders and stuff if I could lol

chrome widget
#

Oh do I have them turned off?

#

Probably to avoid harassment lmao

vocal helm
#

which is fair lol

chrome widget
#

🏳️‍⚧️ unfortunate consequences 🏳️‍⚧️

wintry solar
#

I would be interested to hear your thoughts on using DrawStep vs :draw Winter, I know Victin has some very strong opinions on the two methods but I'm not aware of anyone who has actually used either thoroughly enough to where I would trust there opinion

chrome widget
#

Oh! I've used :draw fairly often for custom behavior that doesn't warrant a full draw step

#

Primarily for layered effects atop the standard center, which are most cards when trying to be relatively accurate to the vanilla style

#

Primarily, :draw() is good because it allows more compartmentalized code, at least how I have it set up. Being able to have the draw behavior on the center itself means I don't risk breaking something if I disable and remove the center, and it's easier to clean up and bugtest when it's all in one place

#

But I'm also someone who organizes putting all my shader stuff in one file rather than individual draw steps with relevant files, mostly because I tend to reuse and expand ones rather than creating new ones when I don't need to

vocal helm
#

I'm still really curious why Foil - and only foil - doesn't break anything

wintry solar
#

do you have any thoughts on the differentiation between the two for editions?

chrome widget
#

Foil is the only vanilla shader that draws transparent pixels

#

For editions specifically? Like mentioned above I did need to make that workaround to call :draw() after editions, so honestly if it could be called post-edition by default I'd probably prefer it

#

There are some rare occasions that I prefer that effects just get quashed by editions entirely because I think they'd be way too visually busy I suppose

minor magnet
wintry solar
#

do you have any editions that use a layering of different shaders, similar to negative?

vocal helm
chrome widget
#

But yeah this is my typical setup for a bunch of cards for these custom effects, rather than making a unique drawstep. Which results in this effect + editions

vocal helm
#

oooh

chrome widget
vocal helm
#

hell yeah

chrome widget
#

I need to make one, and it's gonna be one of the final things I add, but I can't advise there

versed swan
#

Is there a way to "append" functionality when taking ownership in SMODS, instead of outright overriding it?

loud summit
#

local ref_func = [nameoffunction]
function nameoffunction
ref_func()
end

wintry solar
#

You seem pretty knowledgable on the two styles though, so I'd like to know what you think about what would be the best way to have an edition that does apply multiple shaders interacting with a card that has multiple extra layers across mods, if that's something you can make sense of 🤣

chrome widget
#

Ough, that's a toughy. The shader I was gonna make for my one edition would probably use two separate effects, but I don't know yet how I'd set it up if it would be separate shaders or just combined into one

wintry solar
#

that is a very valid response

chrome widget
#

(IMO vanilla negative probably doesn't need multiple shaders too)

versed swan
loud summit
#

i dont see why it wouldnt?

chrome widget
#

Oh good, the Love2D site is experiencing a cloudfare error. Well I was gonna check if there's an easy way to get pixel out information for an entire sprite once it's been drawn

loud summit
#

tho im not sure if vanilla jokers are stored in SMODS.Jokers

wintry solar
#

I'm not sure that there's a way that currently exists to allow something like that to blanket work, afaik all the shader code (which I would personally house in a DrawStep) would refer to specific layers directly to determine what to apply it too, and having extra layers from some other mod that you aren't in control of, there's no way to recognise those

loud summit
#

maybe you could get the calc from the G.P_CENTERS table instead?

unkempt bronze
wintry solar
#

if you're taking ownership of a joker and want to maintain the original calculation code, just don't return anything in your take ownership function

loud summit
wintry solar
#

you can't store the original code anywhere though

#

yes that's what I mean, write your new function and just don't put a return at the end

#

it'll then run the original code afterwards

loud summit
#

oh what really?

#

is there a way to make it run after

#

the original code

chrome widget
wintry solar
unkempt bronze
#

Lemme explain: I want to have asort of mini-shop where you can buy an uncommon/rare joker through the phone, and have it show up in a mini booster pack like a box.

versed swan
loud summit
#

oh

wintry solar
loud summit
#

yea idk then ive never touched it

red flower
wintry solar
#

you can also just hook SMODS.calculate_individual_effect and add your keys to the table that I forgot the name of instead

chrome widget
#

Basically, per Love2D, the Image type is a drawable that contains pure pixel information. You could, if im not mistaken, create a new Image per drawable child, then draw each shader to it, and feed the pixel data from the last shader draw into the following shaders so they have the actual cumulative result of multiple shader-drawn layers as a single texture. And then once that's done, you draw the result of the image to the final card quad, instead of just a texture per child

versed swan
chrome widget
#

That would be a major overhaul, but it would mean reducing the number of drawn children from each card to 1

wintry solar
#

that'd majorly increase the computation before that though, no?

chrome widget
#

Mhm, probably

unkempt bronze
chrome widget
#

Like I said, it's wonky and I doubt performant

versed swan
#

Ah

chrome widget
#

But without benchmarking it, idk

unkempt bronze
#

Imma loosely start with riff-raff as a coding base, since it creates common jokers in a similar, if unanalogous way

versed swan
#

Sorry got called for something, I'll try to brb asap

chrome widget
#

That helpful at all Eremel? I know I can't really give a straight yes or no answer

vocal helm
#

That'd be an implementation I would use, lol

#

When I did shaders in Game Maker Studio they had surfaces that let you stack shaders like that

chrome widget
#

Yeah it's basically the same thing. I don't use Images very often but that's how the NES emulator works, it draws to an image from the NES PPU using Image:setPixel() or whatever and then the full image is just drawn to the screen using regular methods

vocal helm
#

-# you have an NES emulator in your Balatro mod?

chrome widget
#

Correct

vocal helm
#

holy shit, awesome

chrome widget
vocal helm
#

yoooo holy shit awesome

chrome widget
#

I also just have it set up as a config tab if you want to dump your own roms into it and play the least performant emulator known to man. I'll likely have to provide the mod without the three roms used for its actual in-game item anyway if I don't want to face some trouble

unkempt bronze
red flower
vocal helm
chrome widget
#

oooo!!!!

shadow mauve
#

guys would trying to figure out how to make a balatro mod help me get into coding

vocal helm
chrome widget
#

Ough I am a big Mega Man head, hence why I have a bunch of model kits behind me

unkempt bronze
red flower
shadow mauve
unkempt bronze
# red flower

I'm aware it could be in there, but I searched, and nothing

chrome widget
chrome widget
#

downloading this immediately

shadow mauve
#

ok then here we go now
-# on the offense

unkempt bronze
chrome widget
#

My dream project is a combined remake/demake of X4-X6, been wanting to make something like that for a while, esp because I'm a big fan of X5 and the game itself has some really wonky systems

vocal helm
#

i could introduce you to the engine I use

chrome widget
#

You use Megamix according to the posts here

vocal helm
#

yee :D

chrome widget
#

Unless you've moved on from there

#

Megamix isn't super oriented towards the X games afaik and would need a pretty big overhaul

vocal helm
#

correct, but the systems are still a good foundation
Episode Zero exists

chrome widget
#

That's true

unkempt bronze
real crown
#

Can I add jokers individually to a custom booster pack?
Like have them all listed and working similarly to a Buffoon pack, but only offering the listed jokers? They're also in the normal buffoon packs (as they should be), so I don't want to separate them from the normal joker set

red flower
chrome widget
#

I was considering trying to build my own ECS engine using some Love2D plugins I've seen, since I've had some professional experience working on an engine that splits between ECS physics/rendering and object-oriented scripting, which was a good system (but also potentially overkill for a single-persn project)

unkempt bronze
vocal helm
#

:D

chrome widget
#

oh dang

#

let me open that up a sec

real crown
red flower
chrome widget
#

should be on now, give it a go

vocal helm
#

👍

real crown
#

Thank you!

red flower
#

you can also make the objecttype and add the key to your joker's pools

red flower
unkempt bronze
#
        self.highlighted = is_highlighted
        local can_summon = JoyousSpring.can_summon(self)
        if self.highlighted then
            self.children.use_button = UIBox {
                definition = {
                    n = G.UIT.ROOT,
                    config = { padding = 0, colour = G.C.CLEAR },
                    nodes = {
                        {
                            n = G.UIT.R, config = { ref_table = self, r = 0.08, padding = 0.1, align = "bm", minw = 0.5 * self.T.w - 0.15, maxw = 0.9 * self.T.w - 0.15, minh = 0.3 * self.T.h, hover = true, shadow = true, colour = can_summon and G.C.JOY.RITUAL or G.C.UI.BACKGROUND_INACTIVE, button = can_summon and 'joy_perform_summon' or nil }, nodes = {
                            { n = G.UIT.T, config = { text = localize('k_joy_summon'), colour = G.C.UI.TEXT_LIGHT, scale = 0.45, shadow = true } }
                        }
                        },
                    }
                },
                config = {
                    align = "bmi",
                    offset = { x = 0, y = 0.65 },
                    parent = self```

must be the new button code I'm looking for, is it?
red flower
#

basically, this one is for packs specifically so it adds the button to the bottom (and obviously includes a bunch of things that are mod-specific)

#

well not "adds"

#

it replaces

unkempt bronze
#

Mmmm. Anything you got on the left that does add a new button?

red flower
#

the other ones

#

oh sorry i have nothing on the left actually

#

but the process would be the same

unkempt bronze
#

ah, gotcha

#

So take ownership of the use and sell buttons, and add one offset on the left

#

is that loosely right?

red flower
#

there's no take ownership of functions

#

you either hook it, patch it or override it (i do the latter, others do the former two)

unkempt bronze
#

I could hook on the code to the phone joker, yeah?

#

Just code it separate, and then hook it onto it like my Top To Bottom

unkempt bronze
#

button function pseudocode

wind steppe
#

do you hate other mods

red flower
#

me when i don't know the context of the conversation:

#

(i make an entirely different function)

gaunt thistle
#

smh

#

patch hygiene just went out the window

#

shitting my pants

unkempt bronze
real crown
#

Does anyone know why my booster pack has no name and description in-game? They are empty, even though I have a loc_txt with name and text in it

exotic hedge
#

Morning

haughty cargo
#

I am trying to test my mod (remotro) so I need to give myself all of the jokers, how do I do this? SMODS.create_card() hasn't done what I wanted it to do

#

I have put it in a loop so they can all spawn

slim ferry
#

Use debugplus

haughty cargo
#

oh nvm worked it out lol

#

can I stop it keep making jimbos though

#

I ideally want them to all load at once so I can just get their tables saved all at once

slim ferry
#

What are you even doing man

#

Just spawn them with debugplus

hazy cosmos
#

What do you guys think of Joker Forge?

red flower