#💻・modding-dev

1 messages · Page 594 of 1

gusty compass
#

Welp, idk if I could have it before joker effects for multiplicative joker bonuses but ima just increasing the mult gained I suppose

red flower
#

i dont understand what you mean

slim ferry
#

i mean

#

yeah

#

what does that even mean

red flower
#

initial_scoring_step is before jokers

gusty compass
#

Yea I was lost for a sec

red river
#

okay, aside juice_up() looking weird, the bug is fixed! thanks!
-$3 popup being off-sync with substraction animation is pretty concerning though, is that how money manipulations look in smods' newest version? or is it as specific as setting seal before the card is scored?

#

it's off-sync with rough gem too. weird

slim ferry
#

money animations are off-sync with everything currently

#

because smods

red river
#

sad

long urchin
#

Making a resource for fonts, and so I'm having to fill in some. Z and Q letters for spectral cards didnt exist, what do we think about these customs? Should i change anything about them?

gilded goblet
#

yooooo thank u for this, ive always been looking for the lettrs used in spectral cards

gusty compass
#

Q seems to look fine

gilded goblet
#

i think those look good

long urchin
long urchin
gusty compass
#

Looks a little odd but overall it's good imo

long urchin
#

should i change it? would it be better without the little nibs? Im wondering if the flourish/style gets in the way of readability

gusty compass
#

Yea the left one looks a bit like an 8, but the right one looks decent

long urchin
#

heres an in-practice comparison

gusty compass
#

👍

#

You could ask other people for their opinions

long urchin
#

asked around and from a distance its readable so im keeping the flourish :)

gusty compass
#

Up to you

#

But it's great imo

#

Well done

copper perch
#

For aesthetic I like the 1st, but the 2nd is a lot more readable...what I'd probably do is have a switch so you can swap between versions if its unreadable to some people

lyric wadi
#

chat i need wording help

gusty compass
#

They could also add multiple letter varieties, like the two Zs

#

Like what they get to pick aesthetics or readability so probably consider adding both

copper perch
#

yeah

lyric wadi
#

i personally vote B tbh, since i personally value clarity over aesthetic

#

but A isn't too bad i probably would still know what word it is

#

plus if it's just the sprite then it's really not an issue

copper perch
#

So I am new to the modding scene...and havent coded in 2 years, so I know I'mma screw up a lot lol. I'm just trying to make the values of the Joker's chances and +mult pop up for the card but they're not and just saying 'nul,' I'll give all the code I have for a possible fix on that (also just trying to figure out how to mod in its effects so thats why theres a lot extra)

SMODS.Joker{
    key = 'RocketLauncher',
    
    loc_txt = {
        name = 'Rocket Launcher',
        text = {
            '{C:green}#1# in #20#{} chance',
            'to gain {C:mult}+#100#{} Mult',
            '{C:red}and destroy itself!{}'
        }
    },
    config = {
        odds = 20,
        mult = 100,
    },
    rarity = 1,
    blueprint_compat = false,
    eternal_compat = false,
    atlas = 'DRY_Jokers',
    pos = {x = 0, y = 0},
    cost = 4,
    loc_vars = function(self, info_queue, card)
        local probabilities_normal, odds = SMODS.get_probability_vars(card, 1, card.ability.odds, "RocketLauncher")
        return { vars = { probabilities_normal, odds, card.ability.mult } }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            if SMODS.pseudorandom_probability(card, "RocketLuncher_mult", 1, card.ability.odds, "RocketLauncher_mult") then
                SMODS.calculate_effect({ mult = card.ability.mult }, card)
            end
        end
    end
}
gusty compass
#

I think loc_txt is the source of the issue

slim ferry
#

it should be #1#, #2# and #3#

gusty compass
#

Ye

#

Loc_txt accesses loc_vars vars values though an index surrounded by two #

copper perch
#

So what I'd want is

SMODS.Joker{
    key = 'RocketLauncher',
    
    loc_txt = {
        name = 'Rocket Launcher',
        text = {
            '{C:green}#1# in #2#{} chance',
            'to gain {C:mult}+#3#{} Mult',
            '{C:red}and destroy itself!{}'
        }
    },
    config = {
        odds = 20,
        mult = 100,
    },
    rarity = 1,
    blueprint_compat = false,
    eternal_compat = false,
    atlas = 'DRY_Jokers',
    pos = {x = 0, y = 0},
    cost = 4,
    loc_vars = function(self, info_queue, card)
        local probabilities_normal, odds = SMODS.get_probability_vars(card, 1, card.ability.odds, "RocketLauncher")
        return { vars = { probabilities_normal, odds, card.ability.mult } }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            if SMODS.pseudorandom_probability(card, "RocketLuncher_mult", 1, card.ability.odds, "RocketLauncher_mult") then
                SMODS.calculate_effect({ mult = card.ability.mult }, card)
            end
        end
    end
}
slim ferry
#

yes

copper perch
#

alright, thank you! :)

gusty compass
#

Also for context.ante_end, is there a reason why it triggers twice?

copper perch
#

Honestly I just copied from a card that was similar to what I was doing, forgot it had 2 things on that card

gusty compass
#

Well at least the description shouldn't show nil as far as it seems

copper perch
#

Correctt

#

Now just the fun part for actually coding it

sturdy compass
gusty compass
#

I see

#

So I might as well use context.end_of_round and G.GAME.blind.boss for this

wind steppe
#

context.end_of_round triggers like fifteen billion times

slim ferry
#

kid named main_eval

gusty compass
#

G.GAME.blind.boss only allows it to trigger after the boss blind is beaten I believe

#

Btw I only seemed to manage to have the deck give mult via context.before but that didn't really work as it doesn't run after the game sets the hand values, essentially overriding the mult gain

slim ferry
#

initial_scoring_step

#

as said like

#

multiple times

red flower
gusty compass
#

context.ante_change accounts for any sort of Ante changes, like the vouchers no?

red flower
#

if you still want to do end_of_round it should be context.end_of_round and context.main_eval and context.beat_boss

gusty compass
red flower
#

its better for mods that add extra boss blinds

gusty compass
#

Alright I will give that a shot

#

Idk if context.ante_change would work at all since I have a spectral that moves players back antes

red flower
#

like i said with context.ante_end it will only trigger after the boss blind

gusty compass
#

Alr

#

But I did encounter an issue with ante_end

red flower
#

what is it

gusty compass
#

Triggering twice

red flower
#

i am going to cry

gusty compass
#

Same honestly..

red flower
sturdy compass
gusty compass
#

I'm sick ok debugging

#

And I can't type..

prisma loom
#

What could cause this error? (i've added a new deck and it crashes)

red flower
prisma loom
#

one sec

slim ferry
#

missing mod prefix on voucher

prisma loom
#

mb mb

slim ferry
#

also it should be vouchers = { <voucher 1>, <voucher 2>}

red flower
gusty compass
#

Finally...

#

Man this sucked

prisma loom
#

:)

long urchin
#

Had to do custom B, J, Q, V, Y, and Z. What do we think?

#

Alright heres a Consumable Font Generator

#

Download and use to your own delight

vernal seal
prisma loom
daring fern
wind steppe
#

in your apply function

daring fern
wind steppe
#

what are you trying to do here

prisma loom
#

actually I was originally trying to do Jokers cost extra $ equal to current Ante

#

but no idea how

wind steppe
prisma loom
#

No, I mean increase the cost of jokers in shop

#

all of them

#

perma

wind steppe
#

move the hook outside calculate

#

and remove the event mangaer part

#

couple other issues with this hook as well

#

hold on theres a guide for this

slim ferry
#

same as the challenge uses

wind steppe
wind steppe
#

forgot Inflation existed

prisma loom
#

so I can equalize it to Antes

prisma loom
slim ferry
#

idk if that affects just joker though

wind steppe
#

It doesn't

prisma loom
#

I just can't find any mods that utilized this effect or anything similar

wind steppe
#

Rewrite your hook

slim ferry
#

cryptid has smth that increases the cost of jokers only

wind steppe
#

according to the guide that i sent

slim ferry
#

and also yeah that

vernal seal
wind steppe
#

dont put it in calculate

prisma loom
#

kk

wind steppe
prisma loom
faint yacht
#

local old_ret

prisma loom
red flower
#

just delete this it's doing nothing

prisma loom
#

oh wait I should return ret

#

I think

slim ferry
#

that is still not how that is there

#

it should not be in the calculate at all

prisma loom
#

How do I ref it in the deck's code?

slim ferry
#

either create a modifier in G.GAME.modifiers with the deck and then check for that in the hook

#

or just check for the selected deck in the hook

prisma loom
slim ferry
#

no, it should be G.GAME.selected_back == "b_hnds_premiumdeck"

#

besides that its fine from the looks of it

gilded goblet
#

how can i run some code if the player restarts a run/goes to the main menu?

red flower
slim ferry
#

oh

gilded goblet
#

yeah

red flower
#

hook Game:delete_run

wind steppe
#

hook G.FUNCS.go_to_menu

#

oh wait also restarting a run

vernal seal
slim ferry
# prisma loom

try G.GAME.selected_back and G.GAME.selected_back.effect.center.key == "b_hnds_premiumdeck"

rotund sable
#

It's just text to description

rain atlas
vernal seal
slim ferry
#

also you created an infinite loop somewhere

wind steppe
#

also whats wrong with loc_vars 💔

rotund sable
prisma loom
slim ferry
#

yeah

final jewel
#

is this how I get the lenght of the Joker name

prisma loom
#

oh

#

I see

slim ferry
#

the double == 🔥

gilded goblet
prisma loom
vale zinc
#

Anyone know how to get Edition information to show up beside the tooltip?

prisma loom
frosty rampart
#

^ it's documented in smods localization wiki iirc

prisma loom
wind steppe
#

also why not just add #name directly

slim ferry
# final jewel is this how I get the lenght of the Joker name
if G.jokers and G.jokers.cards[1] then
  local name = localize{type = "name_text", key = G.jokers.cards[1].config.center.key, set = G.jokers.cards[1].ability.set} --set can just be "joker" but this is to be safe from shenanigans
  local mult = #name
end
wind steppe
#

whats with the for loop

slim ferry
#

also just return #name in the calculate

#

right

#

unless its scaling

wind steppe
#

i assume its scaling or else they would need to return something

slim ferry
#

idk

wind steppe
slim ferry
#

idk its not my joker

vernal seal
slim ferry
#

how

#

😭

vale zinc
final jewel
#

When Giga is going to be on the wheel of mod Im gonna be sooo happy

#

its not scalling

#

its the lenght of the name

#

like if the name is Joker it would give 5 mult

slim ferry
#

then dont have a card.ability.extra.mult

#

just return the length of the name as mult

wind steppe
#

should just say +1 mult for every character in the leftmost joker's name

#

get sounds like it scales

#

tldr never use get in a joker description ever

#

it never seems to work out

slim ferry
#

hmmm

#

this reminds me of someone

vernal seal
final jewel
slim ferry
#

then do the same thing in loc_vars

#

as in the calculate

wind steppe
slim ferry
#

9+10

wind steppe
#

oh wait i see the issue

#

should be self.config.extra not self.config

wind steppe
queen crescent
wicked leaf
#

how do you manipulate the value of one of the abilities of a selected card?

final jewel
#

like that its working fine

wicked leaf
#

wait actually lemme try smth

weary grail
#

what should i cram into his noggin

vernal seal
slim ferry
final jewel
slim ferry
#

it will not update until you hover the joker

final jewel
#

you are soo right

slim ferry
#

doing anything that affects gameplay in loc_vars is generally bad practice

final jewel
#

better like that

slim ferry
#

yeah

#

just remove the and card.ability.extra.mult > 0

wind steppe
#

self.ability.extra not self.config.extra

slim ferry
#

it is self.config.extra for decks

#

self is the prototype object, it does not have an ability table

vernal seal
slim ferry
#

yep

final jewel
#

for checking if its not himself do I do that:
if G.jokers.cards[1] ~= self then

slim ferry
#

G.jokers.cards[1] ~= card

final jewel
#

but in the loc_vars

slim ferry
#

center instead of card then

final jewel
#

omg yeah

#

I forgot everything

#

I take just a day for doing some homework and I forget everything

wind steppe
slim ferry
#

that

#

doesnt work

#

because decks arent spawned as a card

vernal seal
slim ferry
#

yeah because apply_to_run is a function of a card object

#

the first argument has to be a card iirc

final jewel
# slim ferry

I made it uncommun and 6$ since the mult can be 30

next timber
#

is there a context for entering the shop? i'd like to force every card in the shop to be polychrome

slim ferry
#

context.starting_shop

next timber
#

thank you

slim ferry
#

also

#

actually

#

idk nvm thats probbly works

vernal seal
slim ferry
#
local voucher = SMODS.create_card {
  key = self.config.extra.voucher
}
G.vouchers:emplace(voucher)
voucher:apply_to_run(G.P_CENTERS[voucher.config.center.key])
#

try this

vernal seal
slim ferry
#

hmmmmmmm

#

try adding area = G.vouchers to the SMODS.create_card ig

#

idk why SMODS.create_card needs that tbh but 🤷

slim ferry
#

thats the same screenshot

wind steppe
#

actually quick question

#

is this deck going to need apply for anything else

vernal seal
wind steppe
#

or is this just a "start with overstock" deck

slim ferry
#

i imagine this is for joker forge

#

im guessing

vernal seal
wind steppe
#

ah that would make sense

#

rq smods is updated to the latest release right

wind steppe
#

i have No Idea then

slim ferry
#

is there any reason you cant just put a vouchers directly in the config

#

this seems way more complicated

wind steppe
#

doing that only works if there's not an apply function afaik

slim ferry
#

oh

#

well then uh

#

wait no it doesnt

wind steppe
#

wait rlly

slim ferry
#

yeah

#

ghost deck hex also works with an apply function

#

Back:apply is a seperate function thats called inside of Back:apply_to_run

#

and apply_to_run handles all the built-in functionality

vernal seal
slim ferry
#

no like

wind steppe
#

still in extra

slim ferry
#

you shouldnt need apply for this

wind steppe
#

(also vouchers should be a table of keys)

slim ferry
#

it can just be config = { vouchers = { "v_overstock_norm" } }

wind steppe
#

why did thunk call it overstock_norm instead of just overstock

slim ferry
#

because theres also overstock plus

wind steppe
#

that one can be called overstock_plus then

slim ferry
#

it is

#

just make the apply an empty function

#

you dont need to do anything in apply for vouchers

vernal seal
slim ferry
#

for the codegen, i imagine you could just take any keys from "apply voucher" effects and drop them into vouchers

#

thgaats all i got though idk jackshit about how jf works

copper perch
#

Sorry to butt in the middle here, just having trouble with sound effects. I think its file directory thats being weird but unsure how to fix it
I have the sounds in my assets folder in its own folder called sounds and have the below code. It all worked just fine before I put the sound in

SMODS.Sound {
    key = 'EXPLODE',
    path = 'explosion.ogg',
    pitch = 0.8,
    volume = 0.7
}
---and---

if context.joker_main then
            if SMODS.pseudorandom_probability(card, "RocketLuncher_mult", 1, card.ability.odds, "RocketLauncher_mult") then
                SMODS.calculate_effect({ mult = card.ability.mult }, card)
                SMODS.destroy_cards(card, nil, nil, true)
                G.GAME.pool_flags.RocketLauncher_extinct = true
                return {
                    message = 'BOOM!',
                    colour = G.C.RED,
                    sound = 'EXPLODE'
                }
slim ferry
#

The sound key in the return needs your mod prefix

copper perch
#

oh, duh. Thanks!

#

Still is crashing when I try to use it

SMODS.Sound {
    key = 'DRY_Jokers',
    path = 'explosion.ogg',
    pitch = 0.8,
    volume = 0.7
}

--and--

        if context.joker_main then
            if SMODS.pseudorandom_probability(card, "RocketLuncher_mult", 1, card.ability.odds, "RocketLauncher_mult") then
                SMODS.calculate_effect({ mult = card.ability.mult }, card)
                SMODS.destroy_cards(card, nil, nil, true)
                G.GAME.pool_flags.RocketLauncher_extinct = true
                return {
                    message = 'BOOM!',
                    colour = G.C.RED,
                    sound = 'explosion'
                }
            else
                    return {
                    message = 'No Ammo!',
                }
            end
        end
    end
}
slim ferry
#

Yeah you didnt add your mod prefix

#

You just made it lowercase

copper perch
#

ohhhh, so in the code to do the sound do the key?

slim ferry
#

what

copper perch
#

Idk, I'm somehow confused

slim ferry
#

what you had before was correct it was just missing the mod prefix at the start

copper perch
#

oh

slim ferry
#

Like the prefix in your metadata json file

copper perch
#

ohhh, so I'd wanna search for the sound prefix_explosion?

slim ferry
#

prefix_EXPLOSION

#

Since the key is in uppercase in the SMODS.Sound

copper perch
#

Got it, I'll try it out

#

Thank you :)

feral tree
#

how do i add a joker with a sticker?

daring fern
versed swan
#

I have a Joker that runs calculate_context with a specific key intended for another Joker to receive, i.e.:

SMODS.Joker {
...
  key = 'joker_1',
  calculate = function(self, card, context)
    if context.end_of_round and context.game_over == false and not context.blueprint then
      print('test')
      SMODS.calculate_context({custom_key = true})
      return {...}
    end
  end
...
}

SMODS.Joker {
...
  key = 'joker_2',
  calculate = function(self, card, context)
    if context.custom_key then
      ...
    end
  end
...
}

But joker_2 doesn't run when joker_1 sends the context, even if print('test') and the return occurs; what do I do?

#

oh, forgot to mention; multiple jokers send context.custom_key, and I'd like this to be a context key to allow more jokers than joker_2 to detect the specific context

atomic edge
#

why are my card textures so much darker when in the game

#

or is it normal

frosty rampart
#

It does get a little darker in-game than in the texture, but I wouldn't describe it as extreme as you're describing

#

show a comparison?

gilded goblet
atomic edge
#

left one is in game

gilded goblet
#

maybe something to do with the crt filter?

atomic edge
#

im sorry but im not familiar with that?

#

what is it

#

just for refrence the normal planet cards look much more like the ones in the textures

#

only my "custom" ones look darker to me

versed swan
gilded goblet
atomic edge
#

ohh thanks

versed swan
#

im fairly certain that a lower CRT filter still applies a saturation effect on the entire screen

#

causing sprite differences

atomic edge
#

oh okay thanks

#

oh yea much better

#

thanks

wintry swallow
#

Could I get some more coding help? Been trying to figure this out for a few hours and haven't had any luck

frosty rampart
wintry swallow
#

bruh

#

ok then

#
    key = "trifuricated",
    path = "j_trifuricated.png",
    px = 71,
    py = 95
})

local sigil = {
    object_type = "Sigil",
    atlas = "trifuricated",
    key = 'trifuricated',
    pos = { x = 0, y = 5 },
    badge_colour = G.C.RED,
    calculate = function(self, card, context)
        if context.repetition then
            return {
                repetitions = card.ability.sigil.extra.triggers,
            }
        end
    end,

    loc_vars = function(self, info_queue, card)
     info_queue[#info_queue + 1] = G.P_SIGILS[card.ability.extra.sigil]
     return { vars = { self.config.extra.retriggers } }

    end
}```
#

Sigils are meant to work like Stickers or Seals

#

I'm having trouble giving the sigil to a joker inherently, so i can't test if it even works or not yet

#
    key = "mantisgod",
    pos = { x = 0, y = 0 },
    rarity = 1,
    blueprint_compat = true,
    eternal_compat = true,
    unlocked = true,
    discovered = true,
    effect = nil,
    soul_pos = nil,
    atlas = "mantisgod",
    cost = 1,
    config = { extra = { chips = 10, mult = 1, sigil = "trifuricated" } },
    func = function()
                set_ability(card.ability.sigil, nil, true)
                return true
    end,

    loc_vars = function(self, info_queue, card)
       return { vars = { card.ability.extra.chips, card.ability.extra.mult, card.ability.extra.sigil } }
    end,

    calculate = function(self, card, context)
        if context.joker_main then
            return {
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult,
                sigil = card.ability.extra.sigil,
            }
        end
    end
}```
lament agate
#

can someone help me explain how to make achievement

copper perch
#

Trying to figure out how to make my times mult on my custom joker display in white text like Balatro does, this is what I saw in other code but its not working for me and is still in black

loc_txt = {
        name = 'The Orb Larcenists',
        text = {
            '{C:green}#1# in #2#{} chance',
            'for {X:mult, C:white}X#3#{} Mult',
        }
    },
frosty rampart
#

no space after the comma

#

it's very strict about that

copper perch
#

thank you :)

frosty rampart
wintry swallow
#
    key = "trifuricated",
    path = "j_trifuricated.png",
    px = 71,
    py = 95
})

SMODS.Sticker = {
    key = 'trifuricated',
    badge_colour = G.C.RED,
    pos = { x = 0, y = -5 },
    blueprint_compat = true,
    config = { extra = { retriggers = 2 } },

    calculate = function(self, card, context)
        if context.repetition then
            return {
                repetitions = card.ability.sigil.extra.triggers,
            }
        end
    end,

    loc_vars = function(self, info_queue, card)
     return { vars = { self.config.extra.retriggers } }
    end
}```

```SMODS.Joker {
    key = "mantisgod",
    pos = { x = 0, y = 0 },
    rarity = 1,
    blueprint_compat = true,
    eternal_compat = true,
    unlocked = true,
    discovered = true,
    effect = nil,
    soul_pos = nil,
    atlas = "mantisgod",
    cost = 1,
    config = { extra = { chips = 10, mult = 1, sticker = "trifuricated" } },

    loc_vars = function(self, info_queue, card)
       return { vars = { card.ability.extra.chips, card.ability.extra.mult, card.ability.extra.sticker } }
    end,

    calculate = function(self, card, context)
        if context.joker_main then
            return {
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult,
                sigil = card.ability.extra.sticker,
            }
        end
    end
}```
#

I don't understand what the issue is, as far as I can tell I'm using Stickers and the functions correctly

#

crash error in relation

cedar pendant
#

Gng is there anyone here who can make art for my balatro mod (its just a crappy joke mod mainly for my friend group but idk anyone who can do art)

#

I can probably pay via like steam games (dm if unterested]

red flower
#

also idk what sigil = card.ability.extra.sticker, does here

wintry swallow
#

OH SHOOT I DIDNT CHANGE IT

#

The only thing I'm still stuck on is giving a Joker a Sticker inherently

red flower
#

like, it always has it?

wintry swallow
#

yes

red flower
#

do card:add_sticker("modprefix_key", true) in add_to_deck

frosty rampart
#

then it won't show up in the shop until after you buy it I think
do it in set_ability instead (with a bit of extra work if you don't want it to have the sticker in the collection)

red flower
#

yeah i dont know why i said add to deck lol i was thinking set_ability

wintry swallow
#

well now its crashing whenever it try to load the sticker in

vale zinc
#

Do any of you know how to get the rank of the most recent card added to deck?

loud summit
#

make a mod calculate function and track it with context.playing_card_added

vale zinc
#

"Mod calculate function"? D'you mean put it in calculate = function(self, card, context)?

loud summit
#

yea

red flower
loud summit
#
 718       if context.pre_discard then
 719          for _, card in ipairs(context.full_hand) do
 720             if not context.blueprint then
 721             G.E_MANAGER:add_event(Event({
 722                 func = function()
 723                    if not G.STATES.SELECTING_HAND then return false end
 724                    draw_card(G.discard, G.hand, nil, "up", true, context.other_card)
 725                    return true
 726                 end
 727             }))
 728             end
 729          end
 730
 731          context.other_card.ability.perma_h_x_mult = (context.other_card.ability.perma_h_x_mult or 1) + card.ability.extra.xmhandgain
 732          card:juice_up(0.5, 0.5)
 733          context.other_card:juice_up(0.5, 0.5)
 734
 735          return {
 736             extra = {
 737                card = card,
 738                message = localize("k_upgrade_ex"),
 739                colour = G.C.MULT
 740             },
 741          }
 742       end``` ok anyone know why this isnt drawing my cards to hand? its also for some reason erroring with a "attempt to index a nil value" on line 731
red flower
#

theres no other_card in pre_discard

loud summit
#

oh

vale zinc
loud summit
#

its identical to a calculate function but runs globally

red flower
#

you dont need to own a joker for it to work

vale zinc
#

I'm asking for a Joker I'm making.

loud summit
red flower
loud summit
#

you can store it in a G global i think

red flower
#

theres nothing else that keeps track of the last card added

loud summit
#

or G.GAME global

#

G.GAME is the one tied to the current run i think

vale zinc
#

So, could I put a SMODS.current_mod.calculate = function(self, context) and calculate = function(self, card, context) function in the same Joker?

loud summit
#

no

red flower
#

the first one goes outside the joker

loud summit
#

you have the calculate function globally tracking it and writing to G.GAME.yourmod_last_added

#

and your joker can then read from that global

vale zinc
#

So, do I need only return context.playing_card_added:get_id()?

loud summit
#

well, what are you trying to do exactly

vale zinc
#

Determine the rank of the card that was most recently added to deck!

loud summit
#

then yes that is fine

#

and NOT return it

vale zinc
#

Why ever not?

loud summit
#

you set G.GAME.yourmod_last_rank

loud summit
vale zinc
#

<@&1133519078540185692>

wintry swallow
#

BEGONE CRYPTO BRO

vale zinc
#

What, then?

red flower
#

in context.playing_card_added, context.cards is the list of cards added
you want to take the last card in the list and save the id or rank key (you can use get_id) to something like G.GAME.modprefix_last_rank

vale zinc
#

So, would context.cards[#context.cards]:get_id() work?

red flower
#

yeah

vale zinc
#

Wouldn't that be changed if the most recent card added was later destroyed?

#

Perhaps I could make it only kick in when a card's added to deck.

frosty rampart
#

if you destroy the card, it was still the most recent card added to your deck. doesn't matter that it doesn't exist anymore

loud summit
#

if youure really worried you could make a list of the most recent cards added

#

but like meta said i dont think it would matter

vale zinc
#

Would this still do the trick?

if context.playing_card_added then
    local most_recent_rank = context.cards[#context.cards]:get_id(),
end
#

Cribbed from Hologram.

frosty rampart
#

no, because the local disappears as soon as that calculate function ends (which would be immediately)

#

it needs to be in G.GAME.modprefix_last_rank for other objects to be able to access it later

#

(replace "modprefix" with your mod's actual prefix)

vale zinc
#

Would it still work, though, if most_recent_rank was defined outside of the if statement?

local most_recent_rank
if context.playing_card_added then
    most_recent_rank = context.cards[#context.cards]:get_id(),
end
frosty rampart
#

no
because then the local gets overwritten with a nil the next time the calculate function runs (which would be immediately)

#

the calculate function runs many many times over the course of a single hand

#

again

#

it needs to be in G.GAME.modprefix_last_rank for other objects to be able to access it later

vale zinc
#

Would this work?

most_recent_rank = G.GAME.<modprefix>_last_rank
frosty rampart
#

G.GAME.modprefix_last_rank is a variable you should be setting/modifying yourself

#

you are making it exist in the global mod calculate

#

and then you can reference it in the joker you want to use it in

#

G.GAME.<modprefix>_last_rank = context.cards[#context.cards]:get_id()

versed swan
vale zinc
#

Do you mean to say that G.GAME.<modprefix>_last_rank gets overwritten all the time with the newest rank?

frosty rampart
#

if you use a local in any capacity, it will not persist longer than a fraction of a second. it must be a variable stored in G.GAME

vale zinc
#

At the risk of frustrating you even more, I ask: what is a global mod calculate function?

frosty rampart
vale zinc
#

I have G.GAME.<modprefix>_last_rank defined outside of any function.

#

Am I doing this right?

SMODS.current_mod.calculate = function(self, context)
    G.GAME.<modprefix>_last_rank = context.cards[#context.cards]:get_id()
end
frosty rampart
#

nearly

  1. it still needs the context.playing_cards_added check
  2. replace <modprefix> with your mod's actual prefix (technically you don't need to, but for identification/uniqueness/making sense purposes it's a very good idea)
loud summit
#

yea

#

you dont neccesarily need to add the modprefix

frosty rampart
#

you should in case another mod decides to also add G.GAME.last_rank

mystic river
#

is there a built in way to change a voucher's price when it spawns or am i gonna have to hack one together
(the voucher is intended to be redeemed multiple times and get more expensive each time)

#

i mean like natural spawns

vale zinc
#

I see in Clearance Sale's code that it applies G.GAME.discount_percent, presumably to everything, and I'm currently peering at Astronomer's code and I'll report my findings soon...

#

Looks like it sets their self.cost to 0.

#

Here's how it determines if it's a Planet Card or a Celestial Pack:

if (self.ability.set == 'Planet' or (self.ability.set == 'Booster' and self.config.center.kind == 'Celestial')) then
    self.cost = 0
end
#

I hope this helps.

urban wasp
#

i'm confused this doesn't decrease joker slots when the round is ended
like, it does decrease the number of joker slots, just not from the "only in blind effect"

...
        if ((G.GAME.blind:get_type() == "Small" or G.GAME.blind:get_type() == "Big" or G.GAME.blind.boss) and not context.blueprint) and card.ability.extra.context == 1 then
            G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra.joker_slots
            card.ability.extra.context = 0
        end
        if context.end_of_round and not context.game_over and context.main_eval and not context.blueprint then
            if card.ability.extra.joker_slots >= 2 then
                G.jokers.config.card_limit = G.jokers.config.card_limit - card.ability.extra.joker_slots
                card.ability.extra.joker_slots = card.ability.extra.joker_slots - card.ability.extra.joker_slots_mod
                card.ability.extra.context = 1
            end
...
#

here i'll record a video showing what's happening

vale zinc
#

One thing I like to do a lot for these things is see how existing Jokers do their thing. Here's what I pulled from Ramen:

if context.discard and not context.blueprint then
    if card.ability.extra.Xmult - card.ability.extra.Xmult_loss <= 1 then
        SMODS.destroy_cards(card, nil, nil, true)
        return {
            message = localize('k_eaten_ex'),
            colour = G.C.FILTER
        }
    else
        card.ability.extra.Xmult = card.ability.extra.Xmult - card.ability.extra.Xmult_loss
        return {
            message = localize { type = 'variable', key = 'a_xmult_minus', vars = { card.ability.extra.Xmult_loss } },
            colour = G.C.RED
        }
    end
end
loud summit
#
 722                 blocking = false,
 723                 func = function()
 724                    if G.STATE ~= G.STATES.DRAW_TO_HAND then return false end
 725                    -- gimmie my quickdraws damnit
 726                    draw_card(G.discard, G.hand, nil, "up", true, c, 0.01)
 727                    SMODS.draw_cards(1)
 728                    card:juice_up(0.5, 0.5)
 729                    return true
 730                 end
 731                }))``` does anyone know why this is drawing cards so slow? i want it to be at the same speed as normal drawing
unkempt bronze
#

Say, does anyone know how to have a consumable add chips to a score after use? Or mult, or even xmult?

languid aurora
#

I can dig up some astronomica code for resolving +score or xscore, but if you mean like modify the chips or mult of next hand played I have no idea

unkempt bronze
#

That's what I meant, but I think I figured something. Mind if I show it?

winter flower
#

how do i check if a player is on a specific stake

unkempt bronze
#

See if player is on small blind. if so, yes. if not,

#

see if player is on big blind. if so, yes. if not,

#

see what boss blind player is on

#

(if they are in blind anyway)

red flower
red flower
#

do you want to add it to the next hand played?

unkempt bronze
#

Yeah, but only the next hand.

red flower
#

you can either keep the consumable in the slots and use calculate with it or use something like the global mod calculate to keep track of how much chips or mult should be added next hand

unkempt bronze
#

Mind if I show the base code I figured up? (very vague, likely won't work.)

red flower
#

ok

unkempt bronze
red flower
#

no it wont

unkempt bronze
#

I kinda figured. Where does it break?

red flower
#
  1. calculate is not an attribute of an event
  2. if the idea is to have the calculate on a delay with the event that's not how functions work
unkempt bronze
#

If I fix those, will it work as I think it will?

red flower
#

no

#

my second point is that the idea is not correct

unkempt bronze
#

So, for my idea to work as it should, just set the global mod calculator to whatever I want it to be for the card?

red flower
#

you would need to save how much chips or mult you want to give somewhere and then return that in the mod calculate, in context.main_scoring or something

unkempt bronze
red flower
#

not even close no

#

lol

#
-- in yiur consumable
use = function(self, card, area)
    G.GAME.modprefix_iron_mult = (G.GAME.modprefix_iron_mult or 0) + number
end

-- somewhere else in your file
SMODS.current_mod.calculate = function(self, context)
    if context.main_scoring then
        local give_mult = G.GAME.modprefix_iron_mult or 0
         G.GAME.modprefix_iron_mult = 0
         return { mult = give_mult }
    end
end
#

something like that

unkempt bronze
#
    key = "iron",
    set = "xiferp_lement",
    cost = 3,
    pos = { x = 3, y = 5 },
    use = function(self, card, area)
        G.GAME.xiferp_iron_mult = (G.GAME.xiferp_iron_mult or 0) + 4
    end
end

SMODS.xiferp.calculate = function(self, context)
    if context.main_scoring then
        local give_mult = G.GAME.xiferp_iron_mult or 0
         G.GAME.xiferp_iron_mult = 0
         return { mult = give_mult }
    end
end
} ```
#

like so?

red flower
#

it has to be SMODS.current_mod.calculate exactly

#

but otherwise yes

unkempt bronze
#

Ah. And if I swap mult with chips it works much the same there?

red flower
#

yeah

unkempt bronze
#

Okay. one last thing.

#

How do I make it so that it adds per card of a certain rank? (Ik this is joker, not consumable-level, but I have an idea)

red flower
#

per card of a certain rank in deck? or in the hand played?

unkempt bronze
#

in hand played

red flower
#

you can check context.scoring_hand like you would in a joker

#

or use context.individual

#

that makes more sense actually

unkempt bronze
#
    key = "iron",
    set = "xiferp_Element",
    cost = 3,
    pos = { x = 3, y = 5 },
    use = function(self, card, area)
        G.GAME.xiferp_iron_mult = (G.GAME.xiferp_iron_mult or 0) + 5
    end
end

SMODS.current_mod.calculate = function(self, context)
    if context.individual and context.cardarea == G.play and context.other_card:get_id() == 7 and context.main_scoring then
        local give_mult = G.GAME.xiferp_iron_mult or 0
         G.GAME.xiferp_iron_mult = 0
         return { mult = give_mult }
    end
end
}```
like so?
red flower
#

you would remove context.main_scoring in that case and the part that does G.GAME.xiferp_iron_mult = 0 would need to be moved to context.after so it doesnt reset on the first card (unless thats what you want)

unkempt bronze
#
    key = "iron",
    set = "xiferp_Element",
    cost = 3,
    pos = { x = 3, y = 5 },
    use = function(self, card, area)
        G.GAME.xiferp_iron_mult = (G.GAME.xiferp_iron_mult or 0) + 4
    end
end

SMODS.current_mod.calculate = function(self, context)
    if context.individual and context.cardarea == G.play and context.other_card:get_id() == 7 then
        local give_mult = G.GAME.xiferp_iron_mult or 0
        
         return { mult = give_mult }
    end
    if context.after then
    G.GAME.xiferp_iron_mult = 0
end
}```
#

like this or?

red flower
#

youre missing an end but yes

winter flower
#

lil stuck on why it's only doing "omega defeated" despite being on the proper stake

unkempt bronze
#

Thank you, N. I would make a joker of you if I may

red flower
winter flower
#

it was indeed the lowercase issue

unkempt bronze
#
            trigger = 'after',
            delay = 0.2,
            func = function()
                SMODS.destroy_cards(G.hand.pseudorandom)
                return true
            end
        }))
        delay(0.3)
    end,```
Will this destroy a random card in hand?
red flower
#

no

unkempt bronze
#

what's missing?

red flower
#

G.hand.pseudorandom is not a thing

#

i would recommend looking at the vanilla remade wiki, there's a section for getting a random element from a table
you would use G.hand.cards in that case

unkempt bronze
#
-- set before...
local xiferp_kill_the_cards = pseudorandom("xiferp_youdienow", G.hand.cards)

-- and now...
         G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.2,
            func = function()
                SMODS.destroy_cards(xiferp_kill_the_cards)
                return true
            end
        }))

like this?

vale zinc
#

Does anyone know how to pass a string as an argument out of loc_vars?

red flower
#

no

unkempt bronze
#

what's wrong?

red flower
#

that's not how you use pseudorandom and not the function you should be using

vale zinc
unkempt bronze
red flower
#

pseudorandom_element
it is in the wiki I mentioned

unkempt bronze
#

okay, anything else?

wintry swallow
#

I'll write about it after I got home from the dentist

unkempt bronze
#

Is that not just the rest of the card, or the atlas?

#

nevermind, figured it out. Setting it up now

copper perch
#

Is there a way I'd be able to combine this code? I cant figure it out without my coder saying something is wrong

    loc_vars = function(self, info_queue, card)
        local probabilities_normal, odds = SMODS.get_probability_vars(card, 3, card.ability.odds, "Eastville")
        return { loc_txt = {
            name = "NOT Westville :D",
            text = {
                "Gains {X:mult,C:white}X#1#{} Mult for",
                "{C:attention}each{} discarded card",
                "{C:inactive}(Currently {X:mult,C:white}X#2#{C:inactive} Mult)"
            }
        },
    }
    end,
        
        --And--
        
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.xmult_gain, card.ability.xmult } }
    end,
true jasper
#

the loc_txt should be its own seprate thing

copper perch
#

Its intentional, I'm wanting a chance to change its name

red flower
copper perch
#

I'll take a look and see what I can find, thanks!

#

So my 2 code lines should be like this?

    loc_vars = function(self, info_queue, card)
        local probabilities_normal, odds = SMODS.get_probability_vars(card, 3, card.ability.odds, "Eastville")
        return { descriptions = {
            Joker = {
                j_DRY_Eastville = {
                    name = "Eastville",
                    text = {
                        "Gains {X:mult,C:white}X#1#{} Mult for",
                        "{C:attention}each{} discarded card",
                        "{C:inactive}(Currently {X:mult,C:white}X#2#{C:inactive} Mult)"
                    },
                    j_DRY_Eastville_alt = {
                        name = "Eastville 2",
                        text = {
                            "Gains {X:mult,C:white}X#1#{} Mult for",
                            "{C:attention}each{} discarded card",
                            "{C:inactive}(Currently {X:mult,C:white}X#2#{C:inactive} Mult)"
                        }
                    }
                }
            }
        } }
    end,
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.xmult_gain, card.ability.xmult } }
    end,
red flower
#

no, i would reread what it says on the wiki

copper perch
#

Confused then, cause I basically copied the code over and replaced as needed

true jasper
copper perch
#

Oh...I just have 1 main code line

#

and the .json, of course

#

So...what would I do in that case? Cause I'm unsure how to add another file and have it connected

true jasper
unkempt bronze
#

After running my base code through a debugger, I got this. Anything that got messed up?

copper perch
#

Doing a simple Joker where it just multiplies chips, game crashed so I know I'm doing something wrong and its always been returning 1 every other time (having a calculate function still had it at 1)

    config = {
        xchips = 1.5,
    },

    loc_vars = function(self, info_queue, center)
        return {vars = {center.ability.extra.xchips}}
    end
true jasper
copper perch
#

ahh

#

okay, I have the extra but the multiplier is still not applying in rounds, would I need the calculate function?

true jasper
copper perch
#

Okay, I dont know why I thought it would. Thanks

#

Okay, progress

        loc_vars = function(self, info_queue, center)
        return {vars = {center.ability.extra.xchips}}
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                xchips = card.ability.xchips
            }
        end
    end
#

still doesn't work though

true jasper
# copper perch still doesn't work though

from vanilla remade, just use this as a base

SMODS.Joker {
    key = "joker",
    pos = { x = 0, y = 0 },
    rarity = 1,
    blueprint_compat = true,
    cost = 2,
    config = { extra = { mult = 4 }, },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.mult } }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                mult = card.ability.extra.mult
            }
        end
    end
}```
copper perch
#

Thank you :)

#

Got it working

wicked leaf
#

how do you set the icon to the mod

true jasper
prisma loom
#

Would this be too complicated to make in terms of coding?

daring fern
prisma loom
#

(I just learned what hooks are yesterday lol)

daring fern
# prisma loom Flag? Whats that?

It's a value that is used to signal that something has happened, so you would set the flag when it's sold and you would check for that in the hook.

prisma loom
#

Ohh ic ic

#

So if the flag was set, hook would be able to activate and add Art to the Pack

#

Right?

daring fern
wicked leaf
#

how do you remove a joker from the main pool while also keeping it on other pools?

#

I know its

#

in_pool = function() return false end,

#

to remove it from ALL pools

#

but idk about JUST the main pool

#

actually just using that could work?

daring fern
wicked leaf
#

appearing in the shop and via judgement creation

#

I want them to only be generated via a single consumable so I dont want them in the main joker pool

#

can you use add_card with a pool?

granite jay
#

Anyone know how to set release mode in conf.lua through a mod? I wanna make a Balatro mod that just does that rather than having to unzip the .exe file to enable/disable debug mode

granite jay
#

What's debug plus?

wicked leaf
#

I dont understand.

#

does anyone have any idea how to make it so it creates one of these four randomly

#

pools dont work with add_card

spring lantern
#

anyone got experience with malverk? had no issue replacing most textures in the game using it but for blind chips (which the repo lists as one of the things that malverk can replace) i get this crash on launch

wicked leaf
#

Shouldnt it be Malverk.AltTexture

#

I could be wrong

#

nope, nvm

daring fern
wicked leaf
#

oh ive never used pseudorandom uhh

#

do I just make the array/table inside pseudorandom

#

yes okay

wicked leaf
#

im probably missing an argument in pseudorandom

daring fern
wicked leaf
#

shit I just realized

#

I was wondering why keeping it in a table wasnt working either

#

the _ is barely visible lol

spring lantern
#

ah

#

now i get this crash when selecting blinds in the collection

#

wait i need to specify frames dont i

#

there ya go

#

also need help replacing the title screen

#

wait i can literally just check the file size

#

am i duymb

daring fern
spring lantern
#

ye thx

#

dear god

plucky berry
#

hey guys i made the mistake of coding my mod with pokermon installed and now when i disable pokermon my custom planet cards (they work with pokermon on) crash the game with: functions/misc_functions.lua:2031: attempt to index field 'colours' (a nil value)
can you help me figure out what part of this code is a pokermon dependency?

wintry swallow
#

So I'm running into the same issue as last night; the sticker doesn't seem to be adding itself to the card

#
    key = "mantisgod",
    pos = { x = 0, y = 0 },
    rarity = 1,
    blueprint_compat = true,
    eternal_compat = true,
    unlocked = true,
    discovered = true,
    effect = nil,
    soul_pos = nil,
    atlas = "mantisgod",
    cost = 1,
    config = { extra = { chips = 10, mult = 1 }, },

    loc_vars = function(self, info_queue, card)
       return { vars = { card.ability.extra.chips, card.ability.extra.mult,} }
    end,

    set_ability = function(self, card)
        card:add_sticker("inscrypt_trifuricated", true)
    end,

    calculate = function(self, card, context)
        if context.joker_main then
            return {
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult,
            }
        end
    end
}```

```SMODS.Sticker{
    key = "trifuricated",
    badge_colour = G.C.RED,
    pos = { x = 0, y = -5 },
    config = { extra = { retriggers = 2 } },

    calculate = function(self, card, context)
        if context.repetition then
            return {
                repetitions = card.ability.seal.extra.triggers,
            }
        end
    end,

    loc_vars = function(self, info_queue, card)
     return { vars = { self.config.extra.retriggers } }
    end
}```
#

And this is the code for the Joker and the Sticker

plucky berry
wintry swallow
plucky berry
#

i'd be glad to be part of the team if you need

#

i'm also making a mod and could use help if this makes an equal exchange

wintry swallow
#

idk if I'll need extra help yet cuz I just started but I'll def keep it in mind if I end up needing it

plucky berry
#

yeah in the beginning it's easy

wintry swallow
#

SURE NOT SEEMING LIKE IT lol, I've been stuck on how Stickers work for the past like 18 hours

plucky berry
#

i think there's a force sticker thing

#

force_stickers = {"prefix_trifurcated"}

#

try this

plucky berry
#

so it doesn't have a sprite or text

#

have you tried it in game?

wintry swallow
#

not yet i'm still struggling on actually apllying the sticker

wintry swallow
#

this is the error i keep getting

#

i even set the pos to 0, 0

plucky berry
#

how are you implementing it

#

show the code

wintry swallow
#
    key = "mantisgod",
    pos = { x = 0, y = 0 },
    rarity = 1,
    blueprint_compat = true,
    eternal_compat = true,
    unlocked = true,
    discovered = true,
    effect = nil,
    soul_pos = nil,
    atlas = "mantisgod",
    cost = 1,
    config = { extra = { chips = 10, mult = 1 }, },

    loc_vars = function(self, info_queue, card)
       return { vars = { card.ability.extra.chips, card.ability.extra.mult } }
    end,

    set_ability = function(self, card)
        card:force_sticker("inscrypt_trifuricated", true)
    end,

    calculate = function(self, card, context)
        if context.joker_main then
            return {
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult,
            }
        end
    end
}```
queen meadow
#

how does one reverse this

wintry swallow
#

i checked the collection, the game recignizes there's an added sticker but is not loading data

plucky berry
#

stickers = { "inscrypt_trifuricated" },
force_stickers = true

#

i think you need this

daring fern
wintry swallow
plucky berry
#

joker

plucky berry
#

you need to set the sprite and the loc_text to show properly

#

or add localization file

wintry swallow
#
            j_inscrypt_trifuricated = {
                name = "Trifuricated",
                text = {
                    "Retrigger this",
                    "card {c:attention}+#1#{}",
                    "additional times."
                },```
plucky berry
#

but except graphics it should still work

wintry swallow
#
    key = "trifuricated",
    path = "j_trifuricated.png",
    px = 71,
    py = 95
})```
plucky berry
#

yeah stickers don't have j_ before the name

#

that's only for jokers

wintry swallow
#

:\

plucky berry
#

hold on i'll check to be sure

#

yeah remove the j_ stickers and seals don't need prefixes

#

also in your sticker code you have pos = { x = 0, y = -5 }, i think you should have pos = { x = 0, y = 0 }, if it's the fist one in the sheet, don't think negative coordinates have a meaning

wintry swallow
#

yeah that's what i changed it to

plucky berry
#

was looking at the earlier code you sent

#

sry

wintry swallow
plucky berry
#

i think it's
apply = function(self)

#

but i may be wrong

#

try it

wintry swallow
#
        stickers = { "inscrypt_trifuricated" },
        force_stickers = true
    end,```
#

it's crashing because of an unexpected symbol near 'end' but i dont see what's incorrect about this function

plucky berry
#

that's the error when you have mismatched ends and brackets

#

always check if all ends are matched

#

i suggest using visual code studio with the lua extention cause it tells you beforehand when this type of errors would happen

wintry swallow
#

that IS what i'm using, im just not observant

#

it's loding into the game now, but when the mantisgod attempts to call force_sticker, it's saying it's a nil value

#

but i should have it defined correctly

#
        card:force_sticker("inscrypt_trifuricated", true)
    end,```
vale grove
#

how do you check the last played hand?

plucky berry
#
    key = "mantisgod",
    pos = { x = 0, y = 0 },
    rarity = 1,
    blueprint_compat = true,
    eternal_compat = true,
    unlocked = true,
    discovered = true,
    effect = nil,
    soul_pos = nil,
    atlas = "mantisgod",
    cost = 1,
    config = { extra = { chips = 10, mult = 1 }, },

    loc_vars = function(self, info_queue, card)
       return { vars = { card.ability.extra.chips, card.ability.extra.mult } }
    end,

    apply = function(self)
        stickers = { "inscrypt_trifuricated" },
        force_stickers = true
    end,

    calculate = function(self, card, context)
        if context.joker_main then
            return {
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult,
            }
        end
    end
}```
plucky berry
#

also it's probably wrong

daring fern
plucky berry
daring fern
wintry swallow
daring fern
plucky berry
#

so what should i change it to?

#

do i need to put the hex color after V: in localization or do i need to return it inside the poker hand

daring fern
# plucky berry so what should i change it to?
loc_vars = function(self, info_queue, center)
    return {
        vars = {
            G.GAME.hands["modprefix_key"].level,
            localize("modprefix_key", "poker_hands"),
            G.GAME.hands["modprefix_key"].l_mult,
            G.GAME.hands["modprefix_key"].l_chips,
            colours = {
                (
                    G.GAME.hands["modprefix_key"].level == 1 and G.C.UI.TEXT_DARK
                    or G.C.HAND_LEVELS[math.min(7, G.GAME.hands["modprefix_key"].level)]
                ),
            },
        },
    }
end
plucky berry
#

woah

#

okay

#

tnx

#

worked

wintry swallow
#

ok so the sticker is applying itself now, but the retriggers don't work, stating that "sticker" with in card.ability.sticker.extra.retriggers is nil

#
    key = "trifuricated",
    badge_colour = G.C.RED,
    pos = { x = 0, y = 0 },
    config = { extra = { retriggers = 2 } },

    calculate = function(self, card, context)
        if context.repetition then
            return {
                repetitions = card.ability.sticker.extra.retriggers,
            }
        end
    end,

    loc_vars = function(self, info_queue, card)
        return { vars = { self.config.extra.retriggers } }
    end
}```
#

i tried taking sticker out but no dice

daring fern
wintry swallow
# daring fern `card.ability.modprefix_key.extra.retriggers` also it should be `if (context.rep...

like this?

    key = "trifuricated",
    badge_colour = G.C.RED,
    pos = { x = 6, y = 1 },
    config = { extra = { retriggers = 2 } },

    calculate = function(self, card, context)
        if (context.repetition or context.retrigger_joker_check) and context.other_card == card then
            return {
                repetitions = card.ability.trifuricated.extra.retriggers,
            }
        end
    end,

    loc_vars = function(self, info_queue, card)
        return { vars = { self.config.extra.retriggers } }
    end
}```
atomic edge
#

what is this transparent texture used for?

#

its in the games original files

maiden phoenix
#

Undiscovered boosters iirc

daring fern
wintry swallow
#

oh thought i changed it back sorry

atomic edge
#

oh okay thanks

wintry swallow
daring fern
wintry swallow
#

where would i find/put that?

daring fern
wintry swallow
#

thank you so much!

wicked leaf
#

Is there a way to trigger a hand decrease for the round

#

I want to make a card that uses up a hand when you score it

faint yacht
#

ease_hands_played(-1)

wicked leaf
#

no SMODS or anything behind it?

faint yacht
#

ye.

upper sundial
#

Hey, is there a good way to apply a shader to all cards of a consumable type?

upper sundial
#

ok phew

#

I looked at Card::draw() and it was horrifying

upper sundial
#

apparently yes

red river
#

is there a way to make Again! popup (during card retriggers from jokers) say something different for a specific joker?

#

actually no, i figured it out

#

but how can i make it display the number of repeats left?

spring lantern
#

there was a function for resetting the game right

#

i thought it was in the smods wiki but i can't find it

upper sundial
#

Is there a method to get the cards within a booster pack when it's opened from a joker context? open_booster seems to trigger too early for that

daring fern
spring lantern
#

thanks lul

winter flower
#

im a bit lost on how this works

upper sundial
winter flower
upper sundial
#

ty

cobalt citrus
#

is there a way for a joker that creates other cards to exclude a specific card from ever being created by it?
i have a joker that has a chance to create a random legendary joker when boss blind is defeated, but if it creates chicot, the ui bugs out and i also think the ante increases for some reason
i don't know how to fix when that happens so is there a way to just have it exclude chicot from the possible jokers it can create while still targetting legendary jokers in general?

daring fern
winter flower
#

oh fuck sakes formatting is ass

daring fern
winter flower
#

oh

upper sundial
#

Is there a way to restart scoring the whole hand?

daring fern
upper sundial
#

I assume I can call that within an event?

#

ok that's not quite what I am looking for

daring fern
faint yacht
willow scroll
#

how does one modify blind size (upon picking up a joker or smth similar for example) so that it's also reflected in the blind select screen?

upper sundial
faint yacht
faint yacht
willow scroll
faint yacht
#

You can hook the function.

daring fern
willow scroll
#

id just like to be able to do smth like this but "globally"

faint yacht
willow scroll
upper sundial
#

only thing is that the "again" text happens after rather than before

lyric wadi
#

chat how do i make them align

#

i don't want to use T for 10s since it's kinda cringe

willow scroll
lyric wadi
#

but like i fudges with the size and alisgments and they're not lining up

upper sundial
#

I forget if this font has monospace figures or not

lyric wadi
#

it's not

upper sundial
#

dam

willow scroll
lyric wadi
willow scroll
#

or what the actual word for padding is

slim ferry
upper sundial
# daring fern Code?
        if context.joker_main then
            for _,v in ipairs(SMODS.get_card_areas("playing_cards")) do
                SMODS.calculate_main_scoring({cardarea = v, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands }, v == G.play and scoring_hand)
                delay(0.3)
            end
            return {
                message = 'Again!',
                colour = G.C.AMBER
            }
        end
lyric wadi
#

you can have a look and see

willow scroll
#

easiest fix would be max_h and max_w i think

#

or what the equivalent is i dont remember exact balatro ui names for the stuff

lyric wadi
#

would that shrink the 10s or grow everything else

willow scroll
#

shrink the 10s

#

however let me check what its called again

#

another option is

#

adding a padding

#

i think?

#

padding: the extra space inside the edges of the current node.
Standard values are 0.05 or 0.1.

faint yacht
lyric wadi
#

it does have padding tho

#

or unless you mean on every node

willow scroll
daring fern
# upper sundial ```lua if context.joker_main then for _,v in ipairs(SMODS.ge...
if context.joker_main then
    return {
        func = function()
            SMODS.calculate_effect({message = localize('k_again_ex')}, card)
            for i ,v in ipairs(SMODS.get_card_areas("playing_cards")) do
                SMODS.calculate_main_scoring({cardarea = v, full_hand = G.play.cards, scoring_hand = context.scoring_hand, scoring_name = context.scoring_name, poker_hands = context.poker_hands }, v == G.play and scoring_hand or nil)
                delay(0.3)
            end
        end
    }
end
upper sundial
#

ty, that sounds correct

slim ferry
faint yacht
#

The card itself doesn't have to be in the matching cardarea, even.

#

SMODS.score_card(G.deck.cards[1], context) will score the card in deck even if the context.cardarea is G.play, G.hand and such.

lyric wadi
#

what did you say about maxh and maxw again? do i replace h and w with them or do they both have to be there

lyric wadi
#

am i not doing it right

willow scroll
#

yeah you might be in the value tweaking hell stage of the ui rn

upper sundial
#

just never pick 10s in this joker

#

ez

slim ferry
#

how could i make context.destroying_card calculate for cards held in hand? im trying to make something that makes cards in hand act as if they were played which does currently work, but i havent gotten glass destruction and such to work

hushed field
#

As in, have a card in hand by the source of a destruction effect?

slim ferry
#

wdym

daring fern
upper sundial
#

Do spectral packs have weird behaviour when you open too many of them? I opened a bunch and now every single one of them contains deja vu and incantation and I'm not sure if I got into a weird rng loop or if this is intended behaviour

slim ferry
#

do you have every other spectral card

upper sundial
#

no, I do not

hidden notch
# slim ferry how could i make context.destroying_card calculate for cards held in hand? im tr...

I had something very very similiar:
If your Joker selects and triggers a card in hand, give that cards a tag
Then just use context.destroy_card (maybe with cardarea set to hand) and look for the tag

Also as example, my Joker that needed to destroy Triggered cards in hand:``` calculate = function(self, card, context)
if context.repetition then --> Some Context that Selects a Card
if next(SMODS.get_enhancements(context.other_card)) then
context.other_card.SEMBY_repeated = (context.other_card.SEMBY_repeated or 0) + 1
return { repetitions = card.ability.extra.repetitions }
end
end
if context.destroy_card and not context.blueprint then
if context.destroy_card.SEMBY_repeated then
local destroy = false
if next(SMODS.get_enhancements(context.destroy_card)) then
for i = 1, context.destroy_card.SEMBY_repeated do
if SMODS.pseudorandom_probability(card, 'SEMBY_benthic_bloom', 1, (G.P_CENTERS.m_glass.config.extra or 4)) then
destroy = true
break
end
end
end
context.destroy_card.SEMBY_repeated = nil
if destroy then
context.destroy_card.shattered = true
return { remove = true }
end
end
end
end,

upper sundial
#

mega spectral packs look like this

#

not sure if I messed something up or if this just. happens

frosty rampart
#

no yea that's strange
somehow you got nearly every spectral card taken out of the pool

#

incantation is the default spectral card when there's nothing left in the pool, so that's why there are so many of them

#

and i guess deja vu is still in the pool

#

what's that joker do btw?

upper sundial
#

It is supposed to upgrade one card in a spectral pack, but I think it also inadvertently removes the original card from the pool for some reason

frosty rampart
#

yea that's probably related to the issue

upper sundial
#
function upgrade_spectral(self, card, context)
    local cards = {};
    for k,v in pairs(G.pack_cards.cards) do
        if v.ability.set == "Spectral" and spectral_upgrade[v.config.center.key] then
            cards[#cards+1] = { idx=k, v=v, key=spectral_upgrade[v.config.center.key] };
        end
    end
    local sel = pseudorandom_element(cards, pseudoseed('ustr_ext_upgrade'));
    if not sel then return end
    local card = create_card('ExtSpectral', G.pack_cards, nil, nil, nil, nil, sel.key, 'ustr-signal')
    card:add_to_deck();
    G.pack_cards.cards[sel.idx] = card;
    card:set_card_area(G.pack_cards);
    card:juice_up(0.6,0.4);
end

did I do this wrong

#

ok I assume the problem is that the card isn't properly destroyed and so the game assumes it is still being held by the player in some form

daring fern
slim ferry
#
function upgrade_spectral(self, card, context)
    local cards = {};
    for _,v in pairs(G.pack_cards.cards) do
        if v.ability.set == "Spectral" and spectral_upgrade[v.config.center.key] then
            cards[#cards+1] = v
        end
    end
    local sel = pseudorandom_element(cards, pseudoseed('ustr_ext_upgrade'));
    sel:set_ability(spectral_upgrade[sel.config.center.key])
    card:juice_up(0.6,0.4)
end
upper sundial
#

no idea, this was written a few months ago targeting a much earlier version of steamodded

upper sundial
#

How do I properly destroy the card, anyway?

slim ferry
#

either card:remove() or card:start_dissolve()

upper sundial
#

tyvm

slim ferry
#

using set_ability is usually equivalent to destroying and replacing though from what i know

#

besides that editions and such get kept

upper sundial
#

aha

#

that's useful to know, ty

faint yacht
willow scroll
#

finally i removed all the jank code i had from global mod calculate to patch jank behaviour 🎉

#

all my shit works normally without jank now woo

#

my ransom sticker can work normally now

lyric wadi
#

imagine having jank in your code couldnt be me

#

unrelated dont look at how i shuffle a list

willow scroll
#

surely its with pseudoshuffle(list, seed) :clueless:

willow scroll
lavish elm
#

so I changed 8 ball's odds from 1 in 4 to 1 in 2, it was working fine but randomly it just stopped working and I have no idea why

red flower
upper sundial
willow scroll
faint yacht
#

Scoring the held in hand glass cards like that is 2x likely to break... so a single Oops! would shatter them.

daring fern
lyric wadi
#

joker thats opposite of oops all sixes

#

Fuck! All Ones!

#

halves all probablity

faint yacht
#

...I already have that.

lyric wadi
#

good

#

what about

#

if you have both that and oops

faint yacht
#

...and a bunch of other mods do too.

upper sundial
#

..why debian?

lyric wadi
#

you can combine them to make A Perfectly Normal Dice

#

after each hand it chooses a random sprite from 1 to 6

faint yacht
#

¯_(ツ)_/¯

lyric wadi
#

and depending on which number it's showing, odds are skewed differently

faint yacht
#

"Stability" was the term I came up for the idea... so, reducing probabilities came out of that..?

#

...and, frankly, I have Oops! as vouchers...

lyric wadi
#

1 is 50%
2 is 75%
3 is 90%
4 is 110%
5 is 150%
6 is 200%

gilded goblet
#

nicel ooking vouchers

lyric wadi
#

funny opportunity is to have the dice affects itself

faint yacht
lyric wadi
#

maybe have it have a 1 in 2 chance to change its face after each hand

#

but of course its own effect is influencing how often it changes faces

gilded goblet
#

okay i need to stop putting random unrelated shit in this chat see yall soon

faint yacht
#

...this is based off of that.

upper sundial
faint yacht
lyric wadi
#

creats two egg???

winter flower
#

how would i make it so that showdown blinds can spawn at any time
or, just every 4 antes or something

lyric wadi
#

what if it turns from creating one egg into creating handful of peas

faint yacht
lyric wadi
#

i think that might be funy

faint yacht
gilded goblet
#

i like that

lyric wadi
#

handful of peas

faint yacht
lyric wadi
#

do you have an egg seals that create seals when scored

frosty rampart
faint yacht
#

No, but a good idea.

lyric wadi
#

stepswitcher joker

#

toggles between buffing Aces and 3 and buffing 2s and 4s each hand

#

or maybe just odd and even if thats too weak

#

Fan Club Monkey joker that triggers if hand contains three of a kind

prisma loom
#

Folks, simple question: this custom seal makes it so that the card the card affected by it creates 2 spectral cards when destroyed. I figured out how to make it generate 1 spectral card, how can I make it gen 2 (without overflowing consumbale slots)?

slim ferry
#

copy from vanillaremade emperor if you havent looked at that yet

prisma loom
#

oh right

#

mb mb

slim ferry
#

also context.destroy_card is whats used to check a card for destruction, not for when a card is destroyed

prisma loom
#

It worked fine so far

slim ferry
#

you should be checking if context.removed contains the card in context.remove_playing_cards

#

and you probably need a hook to Card:can_calculate, since Card.getting_sliced is set on destroying playing cards in a lot of cases

prisma loom
slim ferry
#

lmao

prisma loom
#

you are killing my hopes of finishing it with every new sentence

#

😭

#

ill try to figure it out

slim ferry
#

just push it to main and i'll lock in 🔥

#

oh sure

prisma loom
#

I forgot I have this brilliant mind working with me

cunning valley
#

chat what's context.main_eval for? it doesn't say it on the wiki and the code i found for end-of-round stuff has it

slim ferry
#

context.main_eval is true when no secondary card is being evaluated, im pretty sure its only used to check for the main joker evaluation in context.end_of_round rather than effects on playing cards

cunning valley
#

would you be so kind as to dumb it down a bit for me to understand? i mean no offense when saying this 😭

lyric wadi
#

i think it's basically the main phase of score calc

lyric wadi
#

like when all the number going up actually happen

red flower
cunning valley
red flower
#

yeah so basically both of those contexts run once per card (in play and held in hand)

the reason main_eval exists for end_of_round is that it also runs alongside those contexts so it's basically

end_of_round + main_eval (once)
end_of_round + individual (once per card in hand)
end_of_round + repetition (once per card in hand)

cunning valley
#

oh i think i get it!

#

I got it now!

lucid owl
#

i have a blueprint-like joker that copies another random compatible joker if a hand is played, and keeps copying said joker until the hand is played again (it then switches the joker it's copying)
this works perfectly for the most part, however at the moment i store the copied joker in the card's config as an object which definitely isn't the best way to go about it, and leads to the joker it copies not being saved on run save/load. how should i store the joker object it's copying to go around this?

daring fern
lucid owl
lucid owl
burnt tide
#

How can I make a blind that add 2 ante instead of 1 when it is defeated ?

daring fern
burnt tide
fluid steppe
#

does anyone know how the hell to set up jokerdisplay

#

nothings showing up ingame

#

ok well setting text to a static value doesnt show anything either

#

is it not "j_hypr_test" like the id in the localization file?

faint yacht
#

It is.

#

...you also are referencing card.ability.Xmult and not card.ability.extra.mult

fluid steppe
#

i switched it to just this and nothings showing still

faint yacht
gilded goblet
#

is there a way to access the shop's first voucher card while in a blind?
G.shop_vouchers.cards only works when youre in the shop and theres a vouncher

faint yacht
#

When exiting shop, "store" the key of the voucher somewhere.

fluid steppe
#

i'd look into how cryptid does ://LOG

copper perch
#

I have this card that changes name at a certain time on the game, I wanna make it a chance thing instead. Is there a way I can change the if for that to work? (I'd want it to be a 1/615 chance)

config = {
        xmult_gain = 0.01,
        xmult = 1,
        odds = 615,
    },

loc_vars = function(self, info_queue, card)
        if math.fmod(os.time(), 615) == 0  then
            return {
                key = "j_DRY_Westville",
                vars = { card.ability.xmult_gain, card.ability.xmult }
            }
        end
        return { vars = { card.ability.xmult_gain, card.ability.xmult } }
    end,
slim ferry
#

usually would use pseudorandom for things that affect gameplay but shouldnt matter here

copper perch
#

since I didnt need to use the odds variable would I just delete that?

slim ferry
#

you could also replace 615 with card.ability.odds if you want

#

its still just changing 1 number to modify the chance though

copper perch
#

fair enough

wintry swallow
#

Is there a way to make it so that things that would usually show Badges, don't?

#

I want the Sigils (stickers) to not generate a badge when applied to a card

gilded goblet
daring fern
gilded goblet
#

yeh

fluid steppe
willow scroll
#

how can i check if the player has beaten the small/big blind of the current ante?

daring fern
willow scroll
#

i see, thank you

daring fern
fluid steppe
faint yacht
#

You don't need to do it exactly like that.

fluid steppe
#

aand nothing

faint yacht
#

Just do

local jdef = JokerDisplay.Definitions
jdef['j_modprefix_key'] = {
  ...
}
fluid steppe
#

oh it can be local?

faint yacht
#

Ye.

#

So that you don't type JokerDisplay.Definitions['j_modprefix_key'] each time.

#

I just decided to attach it to my global.

fluid steppe
# fluid steppe aand nothing
local jdef = JokerDisplay.Definitions
jdef["j_hypr_test"] = { -- test
    text = {
        text = "Test",
        colour = G.C.attention
    }
}

still giving this result

faint yacht
#

G.C.FILTER?

#

Those also are case-sensitive.

inner arrow
#

theres a way to let a consumable be used, only when selected a specific joker rarity?

slim ferry
#

check G.jokers.highlighted[1] and G.jokers.highlighted[1].config.center.rarity == <key>

willow scroll
#

personally i just add the joker_display_def inside the SMODS.joker

#

wow my discord did not scroll down

daring fern
slim ferry
#

when did is_rarity get added

#

guh

plucky berry
#

hey i'm having trouble implementing a name change to a custom pokerhand much like royal flush does to straight flush, i copied the code from vanilla remade and updated the localization but it makes my game crash

plucky berry
# daring fern Code?
local briscolaflush = true 
 for j = 1, #scoring_hand do 
  local rank = SMODS.Ranks[scoring_hand[j].base.value] 
  briscolaflush = briscolaflush and (rank.key == 'Ace' or rank.key == '3')   end 
 if briscolaflush then 
  return 'napoli_Briscola Flush House Trentuno' 
  end 
 end 
}```
plucky berry
wintry swallow
#

Anyone know why the badge is saying "error"? I can't find the code to give the badge a different name

fluid steppe
#

ah.

#

aand it still doesnt show

frosty rampart
red flower
frosty rampart
wintry swallow
upper sundial
#

wasn't there an example blueprint reimplementation somewhere

fluid steppe