#💻・modding-dev

1 messages · Page 182 of 1

grim remnant
#

still trying to figure out the "take the quantity of clubs in a deck as a variable" thing. i basically wanna be able to take this number

spring lantern
neat plover
#

can someone explain to me what the hell are the rules with those hashtags?

opal spade
#

instead of G.jokers you need to have G.jokers.cards

spring lantern
#

wait right i'm dumb

normal crest
#

that's pretty much all there is to it

#

#2# would be the second, and so on

neat plover
#

oh ok

spring lantern
#

i also had the emplace function the wrong way around lmfao

#

works now thanks

#

also how can i add the perishable info card to the info queue of the joker?

#

i have the negative info card but i can't find the reference to the perishable sticker

neat plover
#

how to check if a card is lucky or not?

normal crest
#

SMODS.has_enhancement(card, 'm_lucky')

neat plover
#

how do i put this in an if else?

spring lantern
#

that should return a bool

#

so if SMODS.has_enhancement(card, 'm_lucky') then

neat plover
#

thanks

minor furnace
#

Cannot for the life of me figure out why I can't use this while it's in my inventory when I have full consumable slots

        if #G.consumeables.cards < G.consumeables.config.card_limit or self.area == G.consumeables then
            return true
        end
    end,```
neat plover
#

im trying to add 20 chips when no lucky cards trigger

#

if SMODS.has_enhancement(card, 'm_lucky') then
-- Gives chips if roll succeeds
if not card.lucky_trigger then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod

#

it won't work

minor furnace
#

lucky cards are weird

atomic edge
#

why does it say that "shader uniform "antimatter" doesnt exist"?

#

i mean it throws that error

normal crest
neat plover
#

?

atomic edge
#

i just copy pasted it from the examples in smods github

minor furnace
normal crest
neat plover
#

i don't understand sorry

normal crest
#

Send the entire joker

spring lantern
#

if you don't know what a context or a calculate function are you should go re-read the wiki

atomic edge
normal crest
#

prefix_antimatter

atomic edge
#

to the key?

normal crest
#

in the Edition

#

not in the key

neat plover
atomic edge
#

ohhh

#

makes sense thanks

normal crest
# neat plover

Use context.other_card in has_enhancement instead of card

neat plover
#

ok sorry if i'm stupid

atomic edge
#

?

#

because that is not working

#

or do i have to add it somewhere else

normal crest
#

Oh my bad

#

I don't think you need the prefix there

#

Is your shader in assets/shaders

atomic edge
#

yes

spring lantern
#

okay so i'm creating a negative perishable joker, cool, but then at the end of the round when it's supposed to reduce the perishable counter my game just crashes

#

am i doing something wrong? is there a better way to add perishable to a joker?

normal crest
spring lantern
#

am makes sense

neat plover
normal crest
#

What's your code again

neat plover
#

i think i sent it

normal crest
#

What did you change then

neat plover
#

if SMODS.has_enhancement(card, 'm_lucky') then
-- Gives chips if roll succeeds
if not context.other_card.lucky_trigger then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod

normal crest
#

if SMODS.has_enhancement(card, 'm_lucky') then -> if SMODS.has_enhancement(context.other_card, 'm_lucky') then

neat plover
#

oooooohhhh

normal crest
#

card in your calculate function refers to your joker

#

and your joker is never gonna have an enhancement

neat plover
#

can't thank you enough

grim remnant
#

i um, still need help figuring out how to grab the number of clubs in the current deck

neat plover
#

oh my god it works flawlessly

hushed field
spring lantern
#

GAHH WHY

neat plover
#

i never thought modding could this fun

spring lantern
#

fake negative

neat plover
#

that sucks

spring lantern
#

do i just have to manually increase the joker limit

#

that can't be it

#

oh wait i didn't add to deck

#

oops!

minor furnace
#

So, self.area prints blank when I select the card inside a full consumable inventory, and when I swap out the contents of the print for self.area == G.consumeables it returns false

        print(self.area)
        if #G.consumeables.cards < G.consumeables.config.card_limit or self.area == G.consumeables then
            return true
        end
end```
spring lantern
minor furnace
normal crest
#

self is not a card object

minor furnace
#

ah

#

that'd probably be it then

#

thanks! that fixed it

#

oh yk. it was definitely self.area in the original function because that function was from card.lua

spring lantern
#

MISTAKES HAVE BEEN MADE

#

i guess i'm no longer making this blueprint compatible

grim remnant
#

whoops,

spring lantern
#

also they're still fake negatives 😭

grim remnant
dim dust
past forge
#

how do i make this: if context.joker_main and next(context.poker_hands["High Card"]) then trigger when hand IS a High card, intead of when it contains one

jovial harness
#

Trying to figure out how to remove a card if it's the only card discarded and it's a glass one, but I'm not entirely sure how to wait it just works. colond

wintry solar
grim remnant
# past forge whit a for loop :)

i mean. where do i put it? i'm trying to do something to the tune of G.GAME.round_resets.hands = G.GAME.round_resets.hands + (card.ability.extra.handGain * (card.ability.extra.clubsInDeck / 5)). and then something to handle rounding down, of course

minor magnet
#

can anyone tell me why this isn't triggering?

jovial harness
#

Try removing context.cardarea == G.play if it's a joker

minor magnet
#

still doesn't work

jovial harness
#

I'm pretty new to modding but that line reads to me as "if this joker is in the place where playing cards go" - might be wrong with that

minor magnet
#

context.cardarea == G.play makes it so it only triggers for the cards in the played hand

normal crest
#

that line would read to if the card being evaluated is in the played hand

jovial harness
#

Yeah - I was wrong with that, my bad

normal crest
#

I am not sure why it's not triggering tho

#

Is it a joker

minor magnet
#

yes

normal crest
#

And you're playing kings of hearts with that joker, and they don't do anything

minor magnet
#

yes

jovial harness
#

Can we see the full joker? I think I have an idea what it is

#

I think it's the Xmult_mod = card.ability.extra.Xmult, line

minor magnet
faint yacht
#

Just return xmult = card.ability.extra.Xmult.

minor furnace
#

I'm gonna have a fun time figuring out what lovely injections I need to implement xChip

wintry solar
#

xchip is in smods

minor furnace
#

nevermind we're so back

atomic edge
#

does anyone know how the time variable changes in balatros shader code?

minor furnace
#

so, I don't see xChip as a default Enhancement parameter but I'll keep digging through the documentation

wintry solar
#

we don't use default parameters they are stinky

#

use a calculate function

minor furnace
#

valid

normal crest
# minor magnet

I don't see anything wrong with this, as long as those other mods are installed

wintry solar
#

yeah it all looks good to me, only thing I can think of is its an old save before the config was added properly

past forge
#

i guess that making this effect is impossible without doing an unnecesary complicated patch?

jovial harness
#

betmma jokers has it already iirc

violet void
#

Is there anything wrong about how I'm adding this consumable? Its my first one and it doesnt appear in the collection at all

loc_txt is in loc file

normal crest
#

remove the = after Consumable

#

you're reassigning SMODS.Consumable

violet void
#

dang 🤦🏽‍♂️

minor furnace
#

I do not see xChip on the Calculate function page, but I may be blind

wintry solar
#

it's not on the page

normal crest
#

also you can add max_highlighted in config instead of that can_use function

wintry solar
#

just return xchips = X

wicked spire
#

what the heck does "juice up" mean

normal crest
#

make the card jiggle a bit

minor furnace
minor magnet
#

she works now, what do y'all think of her

#

she also plays fukkireta when you get her

past forge
#

"garbshit" i love it

wicked spire
#

king of hearts more like king of farts

past forge
#

im making this enhancement where any card scored gives +1 mul permanently to the hand played, but it conflicts with the levels/planets, since if you level up with a planet it would just go to the mult of that level

#

any tips or help?

jovial harness
#

"garbshit" lmao, that's a good mod name. I don't know who Teto is but they're a fun card. I feel like X1.5 might be a tiny weak for requiring a specific card

past forge
wintry solar
#

<@&1133519078540185692>

grim remnant
#

yeah, we got nothing.

faint yacht
#

That if context.setting_blind should be in a calculate function.

normal crest
#

That... is so far beyond what lua is

grim remnant
#

all i was told is "use a for statement" and. I don't know how to do that.

#

i want to try to make it so that at the start of every hand (preferrably, i'd want this to be anytime the deck is modified, but i'm taking this one step at a time here), set the variable clubsInDeck to the number of clubs in the deck.

#

what do i use? a for statement. how do i use it? no, seriously, how do i use it

faint yacht
normal crest
#

I think this is more of a lack of lua knowledge than anything steamodded related

grim remnant
normal crest
#

programming is like riding a bike tho, you don't just forget how a for loop works

#

either way, what Ali is saying is what you need to do, your joker's effects should be in the calculate function

grim remnant
atomic edge
#

can you add time to shaders in f# because i cant seem to get it right

normal crest
#

one step at a time remember

grim remnant
#

(not that it would fix the "check for clubs" code but w/e)

normal crest
#

And there's no context for "counting cards"

#

you can do that anywhere

#

looping through G.deck.cards (for current deck) or G.playing_cards (for full deck)

opal plinth
#

what does this mean?

normal crest
#

means TalismanCompat doesn't exist

#

as a variable

cursive glade
#

Making a DeckSkin is a bit more complicated than I thought. Is there any way to override or re-order the layering system for the playing cards? I'm trying to make a rather complicated deck skin...

hardy vessel
#

Hi! I'm having an issue with this effect when I *don't* play a Straight. If I do, even if the desired card is not in the hand, it works fine. But any other kind of hand just crashes the game saying "#context.scoring_hand is nil"

 if context.cardarea == G.jokers and not context.before and not context.after and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
            local mage_check = 0
            for i = 1, #context.scoring_hand do --Game Crash here
                if context.scoring_hand[i]:get_id() == G.GAME.current_round.mage_card.id then
                    mage_check = mage_check + 1
                end
            end
            if mage_check >= 1 and next(context.poker_hands["Straight"]) then
                G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
                local tarot_or_planet = {}
                for i = 1, #G.consumeables.cards do
                    if G.consumeables.cards[i].ability.set == "Tarot" or G.consumeables.cards[i].ability.set == "Planet" then
                        tarot_or_planet[#tarot_or_planet+1] = G.consumeables.cards[i]
                    end
                end
                if #tarot_or_planet >= 1 then
                    print(#tarot_or_planet)
                    G.E_MANAGER:add_event(Event({
                    trigger = 'before',
                    delay = 0.0,
                    func = function()
                            local mage_dupe = pseudorandom_element(tarot_or_planet, pseudoseed('mysteriousmage'))
                            local card = copy_card(mage_dupe, nil, nil, nil, mage_dupe.edition and mage_dupe.edition.negative)
                            card:add_to_deck()
                            G.consumeables:emplace(card)
                            G.GAME.consumeable_buffer = 0
                            return true
                    end}))
                    return {
                        message = localize('k_duplicated_ex'),
                        card = card
                      }
                end
            end
        end
opal plinth
opal plinth
#

i cant seem to find it anywhere

faint yacht
# grim remnant (not that it would fix the "check for clubs" code but w/e)

You had the right idea for iterating through the cards, I'll give you that. But here, this should explain things more. At least, I hope.

calculate = function(self, card, context) -- this is executed whenever a context is triggered and such on a given Object. (Jokers are Objects too.)
  if context.setting_blind then -- check if we are starting a blind.
    local clubfound = 0 -- initiate temporary variable and 0 it.
    for i = 1, #G.deck.cards do -- iterate through the cards in deck.
      if G.deck.cards[i]:is_suit('Clubs') then clubfound = clubfound + 1 end -- if card is of the suit (or Wild, keep this in mind), add 1.
    end
    card.ability.extra.clubsInDeck = clubfound -- set the card's variable to the temporary one.
  end
end,
normal crest
#

and not all contexts have a scoring_hand passed to them

hidden timber
hardy vessel
normal crest
#

that would be context.joker_main

blazing torrent
#

Hey maybe someone knows, i spent awhile digging through chat and saw instances of it, but not sure. I want to destroy played cards, I have it destroying it, but the playing cards seem to end up like a ghost in the deck. So the deck will say 52/49. They also appear in the tarot packs

broken cliff
#

did u add remove = true?

blazing torrent
#

Shucks I thought i saw someone say start_dissovle does that

#

But maybe not

grim remnant
#

okay, the actual club counting aspect works, thank goodness. the main issue is now the giving hands thing--i kinda wanted it to be on a per-blind basis, rather than flat like merry andy's. how do i do that?

snow axle
hardy vessel
normal crest
blazing torrent
#

Appreciate yalls help though

spring lantern
#

hey so i still have the issue where negative jokers i create with this function don't apply the +1 joker slot, i'm totally lost...

normal crest
#

i think you meant to do new_joker:add_to_deck()

spring lantern
#

OH MY GOD

#

why am i so stupid

#

this shit had me stumped for like an hour

blazing torrent
#

So i think wha would help the most is if i explain what i am trying to accomplish plus the issue. So yes I am dealing with the ghosting here is my code, it basically checks to see if you have a three 3s in your played hand then removes them up to 3 times. Each time it is removed you get 3$ so a total of 9 per round. It resets after the round. Everything works except the ghosting.

       calculate = function(self, jokerCard, context)
            if context.individual and context.cardarea == G.play then
                local currentCount = 0
                if context.other_card and context.other_card:get_id() == 3 and self.config.extra.count_destroyed < 3 then
                        self.config.extra.count_destroyed = self.config.extra.count_destroyed + 1
                        currentCount = currentCount + 1
                    local card_to_destroy = context.other_card
                    G.E_MANAGER:add_event(Event({func = function()
                        card_to_destroy:start_dissolve({G.C.RED}, nil, 1.6)
                        return true
                    end
                    }))
                end
                if(currentCount > 0)then
                    return {
                        card = jokerCard,
                        remove = true,
                        delay = 0.45,
                        dollars = currentCount * 3,
                    }
                end
            end
            if context.end_of_round then
                self.config.extra.count_destroyed = 0
            end
        end
#

I think the return is probably wrong but i was checking game code of the Trading Card, and they had something like that in it.

normal crest
#

trading card uses the discard context, where returning remove = true is valid

blazing torrent
#

Ohh okay so since im doing this in the context of the cardarea it wouldnt be valid

normal crest
#

individual is the context you're using here, cardarea is more of a check on where the cards you want your effect to happen to are

#

from what I'm seeing, your intended effect is that it destroys up to three 3s scored

blazing torrent
#

Yeah exactly

#

The context stuff is weird to me, but I see what you had meant about context.destroy_card, it needs to happen in the calculate for the joker

normal crest
#

to start, you shouldn't use self.config, you should use jokerCard.ability

jovial harness
#

Is there a way to make a custom suit but not have it in the starting deck?

grim remnant
#

okay, it at least counts properly, but it doesn't seem to update correctly if cards are modified (e.g. with moon), and to a far lesser extent, it doesn't round down yet. what am i missing here? is having two distinct calculates with if context.setting_blind then breaking the updates somehow?

    key = 'springMushroom',
    loc_txt = {
        name = 'Spring Mushroom',
        text = {
            "When {C:attention}Blind{} is selected,",
            "gain {C:blue}+#1#{} hand for",
            "every 5 {C:clubs}Clubs{} cards",
            "Currently #2#"
        }
    },
    config = { extra = { handGain = 1 , clubsInDeck = 13 } },
    rarity = 2,
    atlas = 'StellationJokers',
    pos = { x = 3, y = 0 },
    cost = 7,
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.handGain, card.ability.extra.clubsInDeck } }
    end,
    
    --calculate clubs in deck (THANK YOU TO theonegoofali ON DISCORD)
    calculate = function(self, card, context) -- this is executed whenever a context is triggered and such on a given Object. (Jokers are Objects too.)
        if context.setting_blind then -- check if we are starting a blind.
            local clubfound = 0 -- initiate temporary variable and 0 it.
            for i = 1, #G.deck.cards do -- iterate through the cards in deck.
                if G.deck.cards[i]:is_suit('Clubs') then clubfound = clubfound + 1 end -- if card is of the suit (or Wild, keep this in mind), add 1.
            end
        card.ability.extra.clubsInDeck = clubfound -- set the card's variable to the temporary one.
        end
    end,
    
    calculate = function(self, card, context)
        if context.setting_blind then
            ease_hands_played(card.ability.extra.clubsInDeck / 5)
        end
    end,
}```
normal crest
blazing torrent
#

OKI that makes more sense, that way i can do the return {remove = true}

normal crest
#

and simply return { remove = true }, tho do note that this marks them to be destroyed after scoring and doesn't destroy them immediately

#

like how glass cards aren't destroyed immediately when scored

#

also destroy_card is called for every card in the specified cardarea so you don't need to loop through the scoring hand

normal crest
#

there can only be one

#

so you put all your logic in one definition

grim remnant
normal crest
#

what would be the purpose of counting the clubs after a card modification is made?

#

Oh I see, you want it to show how many hands you'd get in the description

grim remnant
#

yeah, i wanted a live total on the card itself, and the moon tarot exists (of course)

normal crest
#

all you do is count the cards in your loc_vars function as well

unkempt thicket
#

what file are cards scored again?

grim remnant
# normal crest all you do is count the cards in your loc_vars function as well

wait, is that different from just having the clubsInDeck variable be specified in loc_vars? (also, the problem isn't having issues displaying it, it's the delay in displaying it that comes with how the counting only ever happens at the start of a blind; optimally, i would want it to be whenever the deck is modified)

minor furnace
#

I think I've finally hit the wall that is going to force me to figure out lovely injections. Because I need the regular Emperor to only pull from normal tarot cards, Reverse Emperor to only pull from Reverse tarot cards, but both have a chance to appear in Arcana Packs

normal crest
#

And loc_vars is called whenever you hover over a card

#

so you would not have the displaying issues you mentioned

grim remnant
# normal crest the clubsInDeck variable here is pretty useless here i'm gonna be honest

clubsInDeck is mostly for the sake of actually calculating the resulting hands; i'm having it serve double-purpose for display on the card itself if i can help it. i also don't exactly think i can only calculate it when the card is hovered over, since otherwise, if you summoned it via judgement, it would try to calculate giving the hands without actually calculating the clubs, and Oh No That's An Equation With A Potentially Unset Variable

normal crest
#

I think this will be easier to explain with actual code

#

Give me a second

grim remnant
#

np! honestly at this point if i do release this mod i am gonna have to credit the people in this convo because. WOW this has been a PROBLEM of a joker

desert ore
#

if there's multiple instances of it in the code, do lovely patches patch every instance?

wintry solar
#

yes

hollow marsh
#

when making a pack for malverk, I am having an issue where the floaing head on hologram is not appearing, has anyone else had an issue like this before?

#

the texture is present

desert ore
normal crest
# grim remnant `clubsInDeck` is mostly for the sake of actually calculating the resulting hands...
loc_vars = function(self, info_queue, card)
    -- Loc vars is called every time the card is hovered, so we count the clubs here to show the
    -- most accurate information at all times
    local clubs = 0
    for _, v in ipairs(G.playing_cards) do
        if v:is_suit("Clubs") then clubs = clubs + 1 end
    end

    return { vars = { card.ability.extra.handGain, clubs } }
end,

calculate = function(self, card, context)
    if context.setting_blind then
        -- When setting blind we ALSO count the clubs, since we cannot rely on the user having hovered on the joker
        -- for the counting in loc_vars to be relevant at this point
        local clubs = 0
        for _, v in ipairs(G.playing_cards) do
            if v:is_suit("Clubs") then clubs = clubs + 1 end
        end

        -- math.floor is a function that rounds a number down, so if it was, for example, 5.7, it'd return 5
        ease_hands_played(math.floor(clubs / 5))
    end
end,

I hope this clears things up, note G.playing_cards is your full deck, if you only want to use current deck replace it with G.deck.cards

wintry solar
hollow marsh
wintry solar
#

can you show the alttexture code please

hollow marsh
#

when I use the default textures it appears, but when doing it with my own textures it breaks

wintry solar
#

try adding original_sheet = true to the jokers one

#

actually that wouldn't make a difference

grim remnant
hollow marsh
#

I might have figured it out. It looks like the transparency got squashed at some point and the game might not like that

wintry solar
#

oh yeah the shader won't like that

hollow marsh
#

I redid it and still no hologram bruh

#

oh photoshop is still exporting it without transparency

#

also do u know if there is any way to fix the overstock bug where it's texture doesn't appear

wintry solar
#

update malverk

neat plover
next pivot
#

How do I add localization to a challenge deck?

graceful magnet
#

the if check for seeing if the scoring hand is the most played poker hand doesn't seem to be working

wintry solar
#

scoring hand is a table of cards

#

use scoring_name

graceful magnet
#

I did

#

but it didn't seem to work either

#

I'll try again though

neat plover
wintry solar
#

theres also nothing happeniung in your code

blazing torrent
# normal crest also `destroy_card` is called for every card in the specified cardarea so you do...

I am so confused, lmao. Ah i have been messing with the context.destroy card, but it destroys every card that is a 3. Even when they are being put back into the deck. I assumed I could just make a table that holds the cards it needs to destroy, but I do not understand how i am suppose to pass that to the context.destroy card. Or even if this is suppose to work

Here is my latest iteration but I know it probably is simpiler,

   calculate = function(self, jokerCard, context)
            local cards_to_destroy = {}
            if context.individual and context.cardarea == G.play then
                local currentCount = 0

                if context.other_card and context.other_card:get_id() == 3 and jokerCard.ability.extra.count_destroyed < 3 then
                    jokerCard.ability.extra.count_destroyed = jokerCard.ability.extra.count_destroyed + 1
                    currentCount = currentCount + 1
                    local card_to_destroy = context.other_card
                    table.insert(cards_to_destroy, card_to_destroy)
                    G.E_MANAGER:add_event(Event({func = function()
                        card_to_destroy:start_dissolve({G.C.RED}, nil, 1.6)
                        return true
                    end
                    }))
                end
                if(currentCount > 0)then
                    return {
                        card = jokerCard,
                        dollars = currentCount * 3,
                    }
                end
            end
            if(context.destroy_card) then
                for  i = #cards_to_destroy, 1, -1 do
                    if context.destroy_card:get_card() == cards_to_destroy[i]  then
                        return{remove = true}
                    end
                end
            end



            if context.end_of_round then
                jokerCard.ability.extra.count_destroyed  = 0
            end
        end
graceful magnet
blazing torrent
neat plover
graceful magnet
neat plover
grim remnant
#

silly question, how do i check unplayed cards held in hand?

minor furnace
#

I think I can get away with injecting something like this in get_current_pool(_type, _rarity, _legendary, _append) in common_events.lua. Because by default, when the Emperor uses create_card() it passes 'emp' in for _append even though I don't think it ever actually gets used

elseif v.set == 'Tarot' and (_append == 'emp' and v.order >= 22 or _append == 'remp' and v.order > 22) then
    add = false
spring lantern
#

trying a diff style for this new mod, something a bit more cartoony n childish, not 100% convinced with how it looks so far tho

neat plover
#

amazing

vestal ore
left lance
#

Is there a command for giving yourself money in debugplus?

wintry solar
#

money add X

left lance
#

perfect, many thanks yall

graceful magnet
minor furnace
#

not sure if the issue is with my toml, or where I'm injecting it

[manifest]
version = "1.0.0"
priority = 0

[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = "elseif v.set == 'Planet' then
                    if (not v.config.softlock or G.GAME.hands[v.config.hand_type].played > 0) then
                        add = true
                    end"
position = "after"
payload = '''
elseif v.set == 'Tarot' then
    if(_append == 'emp' and v.order <= 22 or _append == 'remp' and v.order > 22) then
        add = false
        print("testing!")
    end
'''
match_indent = true
times = 1
neat plover
minor furnace
scarlet spire
#

why is this nil?

#

code is from midas mask, as it should work identically but with clubs and stone cards instead of faces and gold cards

minor furnace
red flower
scarlet spire
#

right, true

#

it works now, thanks

faint plank
limpid halo
#

wrote a patch for card size just to realize that display_size and pixel_size exist 💀

sturdy compass
#

oop

limpid halo
#

still doesn't seem to play nicely though, hm.

neat plover
sturdy compass
#

It does not help that you are not giving logs

faint plank
#

im trying to juice my joker when certain cards are selected but idk what to put as a trigger

if #G.hand.highlighted ~= 0 then --what do i even put here?
            local eval = function() 
                if #G.hand.highlighted ~= 0 then
                    for i = 1, #card.ability.extra.cards do
                        for k, val in ipairs(G.hand.highlighted) do
                            if k == card.ability.extra.cards[i] then return true end
                        end
                    end
                end
                return false
            end
            juice_card_until(card, eval, true)
        end
glad osprey
#

what if you split it into train on the water and boat on the track

#

train does mult to chip boat does chip to mult

minor furnace
desert ore
#

how do I have the game check for specific joker's key? there's an SMODS thing for that right?

glad osprey
#

LOCAL THUNK HANGED MAN THEM AT ONCE

gloomy rain
#

can someone teach me how to code my own jokers into the game?

vestal ore
gloomy rain
#

I know very basic lua from roblox and have some ideas

#

I just don't know where to start

carmine burrow
#

there's some information on how to get started with modding on the "wiki" section of that page

gloomy rain
#

thanks

left lance
#

yesterday someone recommended some code to make it so that I couldn't buy a joker that gives -1 joker slots when in hand, when my number of Jokers was at 4... but the code doesn't work. It compiles, but doesn't enforce the requirement... anyone have any ideas what's going on?

carmine burrow
# gloomy rain thanks

if you ever need to know more details about how the game's code works, you can extract the source code from the game by

  • clicking "browse local files " on balatro in steam
  • looking for the "Balatro.love" file
  • creating a copy and renaming the copy to "Balatro.zip"
  • unzipping Balatro.zip
desert ore
carmine burrow
left lance
marble flint
carmine burrow
desert ore
#

that case is covered earlier in the function but yeah probably

#

I'm still trying to figure out how to patch invisible joker 😭 maybe I should just leave those rare edge cases out

limpid halo
#

oh god i think i need a regex patch 😭

left lance
desert ore
#

card.config.center.key needs j_(yourprefix)_unemployment

left lance
#

Oh it needs the j_? may I ask what that does?

desert ore
#

from what I understand that's the thing that tells it to search for a joker?

left lance
#

oh huh, didn't think it'd need the j_ AND the keyword

desert ore
#

you also need your mod prefix before the key

#

without that there it's searching for a base game joker with that key, which there isn't one

left lance
#

mod prefix being the name of the main file being used?

desert ore
#

it's something that you should have set wherever your mod info is held

#

so the steammodded header or .json if you have that set up

left lance
#

prefix.card.config.center.key?

desert ore
#

I'm sorry if I'm doing a bad job at explaining

#

here's what mine looks like

#
G.FUNCS.check_for_buy_space = function(card)
    if card.config.center.key =='j_lank_jumbo' and #G.jokers.cards == G.jokers.config.card_limit +
    ((card.edition and card.edition.negative) and 1 or 0) -1 then
        alert_no_space(card, G.jokers)
        return false
    end
    return check_for_buy_space_ref(card)
end```
left lance
#

nah boss its also on me not being good enough with Lua yet

desert ore
#

yes

left lance
#

ah I understand it now

desert ore
#

whatever your prefix is set as in your header

nova finch
#

how would I get the key of a joker?

stray wing
#
    "j_gift",
    {
        loc_txt = {
            name = "10",
            text = {
                "Gain #2# Xmult for each successive",
                "Big Blind played",
                "Currently #1# Xmult"
            }
        },
        atlas = "Gus",
        pos = {x = 0, y = 0},
        cost = 2,
        config = {extra = {Xmult = 1, Xmult_gain = 0.5}},
        loc_vars = function(self, info_queue, card)
            return {vars = {card.ability.extra.Xmult, card.ability.extra.Xmult_gain}}
        end,
        calculate = function(self, card, context)
            if context.after and G.GAME.blind.boss then
                card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_gain
                return {
                    message = "Charged up!",
                    colour = G.C.CHIPS,
                    card = card
                }
            end
            if context.joker_main then
                return {
                    Xmult_mod = card.ability.extra.Xmult,
                    card = card,
                    message = localize {
                        type = "variable",
                        key = "a_xmult",
                        vars = {card.ability.extra.Xmult}
                    }
                }
            end
        end
    }
)

I'm trying to get this joker working to gain xmult for consecutive big blinds, but I'm getting a crash for trying to perform arithmetic on a table (extra)

manic rune
#

why do you have "vars" in your return in calculation?

gloomy rain
#

cause I am not seeing that

#

in a .love format

#

I also see love.dll

manic rune
#

if you have 7-zip, you can right click Balatro.exe and extract it

gloomy rain
#

yea that's how i've been messing with the resourses

#

thanks

stray wing
nova finch
#

is it possibel to get the actual name of a joker from its key?

manic rune
#

you can

#

use string.gsub and remove "j_(mod_prefix)_"

#

or if its vanilla joker then "j_"

manic rune
#

but ive never seen someone having vars in their return before

nova finch
stray wing
#

There's one other post in here about arithmetic on extra but it didn't seem helpful to my situation

limpid halo
left lance
#

as (hopefully a final question for tonight): anyone have any idea why this adjustment isn't happening when I test in game (code compiles)?

limpid halo
left lance
limpid halo
desert ore
#
[patches.pattern]
target = "card.lua"
pattern = '''
 local jokers = {}
    for i=1, #G.jokers.cards do
        if G.jokers.cards[i] ~= self then
            jokers[#jokers+1] = G.jokers.cards[i]

'''
position = "at"
match_indent = true
payload = '''
 local jokers = {}
    for i=1, #G.jokers.cards do
        if G.jokers.cards[i] ~= self or G.jokers.cards[i].config.center.key ~= 'j_lank_jumbo' and #G.jokers.card >= G.jokers.config.card_limit then
            jokers[#jokers+1] = G.jokers.cards[i]

'''
times = 1``` I've been on this for so damn long. I'm trying to make it so if I'm at max slots, invisible joker can't copy a specific joker. This has to be close, it's gotta be some small dumb thing I don't get
#

like, this is the part of the code that makes it so invisible can't copy itself right?

#

oh my gosh G.jokers.cards is missing an s

#

nope that did nothing

nova finch
#

how do i put these little description things on my jokers?

normal crest
#

in your loc_vars function

#

info_queue[#info_queue + 1] = G.P_CENTERS.m_steel for example

desert ore
#

wait a minute what does dump.lua=true do?

limpid halo
#

dumps the generated lua into /lovely/dump/

#

iirc

desert ore
#

ok that's what I figured then

#

man do I just ignore the edge cases with invisible and ankh and move on, ugh

limpid halo
random sleet
#

chat how cursed is it to have a joker save the run

limpid halo
#

that

#

what

#

thats scary

random sleet
#

what

#

it just draws some cards

limpid halo
#

yeah

random sleet
#

i have it save after its effect so the drawn cards aren't just lost if you exit to menu on the first hand

old bane
crisp coral
#

naw gy is where destroyed cards go

minor furnace
#

anybody off the top of their head know where the function is that calculates what type of hand the selected hand will score as?

chrome widget
#

it's evaluate_poker_hands(hand) in misc_functions.lua

#

It searches through the cards in the hand and returns a table containing all the hands that the current hand qualifies as, in addition to the highest priority hand

normal crest
#

I thought it was G.FUNCS.get_poker_hand_info

stiff locust
#

is there a way to check attributes of a joker when it gets destroyed

random sleet
chrome widget
# normal crest I thought it was G.FUNCS.get_poker_hand_info

get_poker_hand_info gets the results from evaluate_poker_hands and then sends the scoring hand and other display information for the calculation contexts. The only other thing it does is update the name of Straight Flush to Royal Flush contextually

#

So yes, if you need the specific scoring hand, you'd want to use get_poker_hand_info, and that also returns the same poker_hands value that it gets from evaluate_poker_hands

#

(which is also sent to a lot of contexts)

normal crest
gloomy rain
#

effect = ""

how does the game understand the effect of the legendaries if the effect area is blank

#

also where are the effects defined within the code?

normal crest
#

The effects of most jokers happen in card.lua within the calculate_joker function

gloomy rain
#

thank you

#

I am doing mostly self taught stuff so far so all that I have made has been essentially ctrl+C ctrl+V of other code

#

anything about why the legendaries have a blank effect?

#

nevermind I found it in card.lua

chrome widget
#

When you specify colors in loc_vars for the localization text, are you able to specify background colors too?

#

I.E. how the game typically displays xmult?

weak gate
#

Can a sticker object get a reference to the card it is on?

normal crest
#

Yes

weak gate
#

how?

normal crest
#

It's passed as an argument to the relevant functions of the sticker

foggy carbon
normal crest
#

They mean passing it through the loc_vars function

chrome widget
#

What I mean is, when you send variables with loc_vars, I know how to specify text color, by sending it in a table called "colours". Can you do the same for backround colors?

#

The docs list just a background color for the entire ui box

turbid maple
#

Am I doing something wrong or is card_eval_status_text not supposed to display messages under the Blueprint when it's copying the effect

chrome widget
#

Passing in strings with formatting directly doesn't seem to work either. I suppose I can just update the loc_text val entirety

normal crest
turbid maple
#

already have that

#

I just get two messages under the original card

normal crest
#

Are you doing it in an event

turbid maple
#

yeah

normal crest
#

Store a reference to context.blueprint_card before calling the event

#

by the time your event function runs, context was already modified

unkempt thicket
#

how do you get the key to the highlighted joker?

turbid maple
#

oh what the hell

#

that works now thank you

normal crest
#

make sure to include a check for if a joker is actually highlighted

turbid maple
#

lol just tried vanilla jokers that use card_eval_status_text and I guess this bug exists in the base game too

normal crest
turbid maple
#

shout outs to 8 ball which doesn't even try checking blueprint_card

normal crest
#

8 ball doesn't use card_eval_status_text

#

it just returns a message

turbid maple
#

oh im blind

random sleet
#

and then pass in an empty string to the one you dont want displaying

#

or uh i guess that joker would be more like {C:mult}#1#{X:mult,C:white}#2#{C:inactive}#3# Mult

worthy anchor
#

for the in_pool function of SMODS.booster, is that changing when a given joker in the pack can spawn, or when the pack itself is allowed to spawn?

chrome widget
#

Technically this works, but specifically the x_mult background always draws a little sliver even with a blank string

minor furnace
#

Pattern 'if G.hand.highlighted[i].ability.name == \'Glass Card\'' on target 'functions/state_events.lua' for pattern patch from reverse_tarot\lovely\tarot.toml resulted in no matches

What do you mean pattern not found

marble flint
minor furnace
#

ah, good to know

#

Idk why I was not expecting that problem here

marble flint
#

for Lua patterns the full list is ().%+-*?[^$

#

for full regexes it's more

chrome widget
#

Wow the performance on this video is utter garbage. Great

minor furnace
marble flint
minor furnace
#

hmmm

minor furnace
#

maybe because it's multiline?

chrome widget
marble flint
#

I might also be misinterpreting what lovely means by "pattern"

minor furnace
#

excape characters didn't appear to fix the issue (and gave me an invalid escape sequence error)

marble flint
#

You could also be running into an incompatibility with another Lovely patch. Can you ctrl-f for the section in the lovely dump?

minor furnace
#

where would I find the lovely dump? sorry I've only been at this for about two days

marble flint
#

<Mods Folder>/lovely/dump

minor furnace
#

it is not in the dump

#

now it's time to go on a scavenger hunt to see how the lovely patches changed the card shatter mechanic

chrome widget
#

Does SMODS.current_mod only exist when the main.lua file of the mod itself runs the first time?

#

My seeming other option for doing this text thing is by setting SMODS.current_mod.process_loc_text, but it tells me "current_mod" doesn't exist when called from within the joker's file

marble flint
#

how are you loading your joker file?

chrome widget
#

I just have this big batch of include files and then each type of object individually does its own loading

#

That said I do call SMODS.current_mod within a local function so that's might also be an issue

marble flint
#

try this and see if it fixes it:

local current_mod = SMODS.current_mod
local function foo()
  -- use current_mod here
end
chrome widget
#

Hmm yeah seemingly passing it in as a parameter doesn't work either. Gimme a sec to try that

#

Okay yep that finally works

#

grr and still updating the localization doesn't seem to work

#
    G.localization.misc.labels.mod_mylabel = 'My Label' -- assigning to G.localization directly
    SMODS.process_loc_text(G.localization.misc.labels, 'mod_anotherlabel', { -- Util function to handle multiple languages.
        ['en-us'] = 'English label',
        ['de'] = 'Deutsches Label',
        ['it'] = 'Etichetta italiana',
    })
end```
this example is all the documents give me to go off
#

It's possible I'm just not correctly setting the values for this joker so next thing on the list to fix I guess

frigid flame
#

so i'm setting up a github for our mod, and i wanted to ask what are some things i should know when i'm setting this up?

minor furnace
#

next step: hunt down whatever file calculated_destroying_cards() is in

marble flint
chrome widget
#

Geez

random sleet
chrome widget
#

I suppose I could patch the UI functions to not do that to make this little hack possible? Otherwise I can set current_mod.process_loc_text, but I won't have reference to the card it checks to update the description at the time of load

#

Otherwise even then, setting the localization string itself would fail to display correctly if you have more than one of this joker

#

Since they'd both always show the most recent update

minor furnace
chrome widget
limpid wing
#

what is the keyword for consumables?, i guess its "Tarot" but the texture i made is not loaded

old bane
chrome widget
#

(correct, I had to fix that lmao)

old bane
limpid wing
minor furnace
#

so this shatters the card, but immediately as it's being played. It still scores as normal but perhaps it needs a different context?

            if pseudorandom('crystal') < G.GAME.probabilities.normal/4 then
                card:shatter()
            end
        end```
limpid wing
#

jokers works, but consumables dont change

chrome widget
#

Anyway it works now, I'll find substitute sounds for each of its activations later lol

minor furnace
#

eh, it's functional at least

#

I'll worry about making it pretty later

chrome widget
#

Because if it's in the event queue, it'll queue to play after all the other previously queued events for tallying up final scoring

#

Since all the code runs immediately, but it spaces things out in real time using event delays

grim remnant
#

silly question; how can we make a card give money just, up-front like hermit/temperance, instead of being end-of-round like golden joker? tried dollars and nothin'.

        if context.joker_destroyed then
            dollars = card.ability.extra.moneyGain
        end
        
        --check for NOT jokers exploding
        if context.remove_playing_cards then
            dollars = card.ability.extra.moneyGain
        end
    end,```
chrome widget
minor furnace
#

thanks! I hadn't worked with the event queue before but this is very useful to know

chrome widget
#

A good example in-game is the effects for card suit/rank changes

#

In order to do the flip effect, it plays three separate events in a row for each card

  • first event flips the card and juices up
  • second event changes the card's values and sets its suit/rank
  • third event flips the card back and juices up again
minor furnace
#

I have been doing that, but admittedly most of that code was copy/pasted from other segments in the source files

chrome widget
#

I mean that's fair, that's like 90% of programming LOL

grim remnant
minor furnace
#

sometimes you can make things work without fully understanding how

grim remnant
chrome widget
#

I've had to get into some WEEDS because I keep wanting to do really unnecessary shit like a card that makes all adjacent cards glow

#

I am at this point knee deep in the balatro mines

grim remnant
#

shoutouts to the greatest programmer of all time, Larry Tesler, who invented copy + paste to save every other programmer time ;P

old bane
#

how would i implement a blueprint-like joker? would it be like

if context.blueprint then
  // copy x joker here
end
grim remnant
#

iiiii don't think context.blueprint is a valid context? at least, not in base steamodded.

chrome widget
runic pecan
#

Which one looks better?

grim remnant
old bane
chrome widget
chrome widget
minor furnace
grim remnant
#

ease works, though the "if cards are destroyed" function doesn't seem to properly care if multiple cards are destroyed all at the same time; if you use hanged man to wreck 2 cards, it only procs once. what do i do?

        if context.remove_playing_cards then
            ease_dollars(card.ability.extra.moneyGain)
            -- return { message = "Card..." } --placeholder
        end```
chrome widget
#

You can iterate through context.removed and queue an event to ease dollars for each card destroyed

#

Or you should be able to. I'm not sure if it'll play them in the sequence you want I.E. destroy -> money -> destroy -> money versus destroy -> destroy -> money -> money

chrome widget
grim remnant
#

i would prefer destroy -> money -> money. the problem is uh.
-# We have never written an iteration/event queue so I have no idea what we have just been told to do beyond a literal level... ^^;

chrome widget
#

I'm writing this on my phone so bear with me

grim remnant
#

np!

chrome widget
#
    if context.remove_playing_cards then
        for i=0, #context.removed do
G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.1,
        func = function()
      ease_dollars(card.ability.extra.moneyGain)
            return true 
        end
    }))        
        end
    end```
grim remnant
#

did we insert it wrong somehow?

#

okay, i figured it out... the issue is now, it seems to be activating one too many times. destroying one card procs it twice, destroying two cards procs it thrice...

chrome widget
#

OH

#

DUH, my fault

#

i=1, not i=0

#

Lua indexes arrays at 1

grim remnant
#

the ol' Array's Trick...

chrome widget
#

(this is the first language I've ever used that doesn't index arrays at 0 and it's hard to shake the muscle memory)

grim remnant
#

it worked, tysm!

manic rune
#

is there a way to change the sprite pos of only one card of a joker?

chrome widget
#

Hoo boy, yes there is

#

What do you need?

manic rune
#

i want to change the sprite of a joker, but at the same time i dont want that to happen to ALL jokers of that type

#

i researched the code of limball from cryptid and the code actually changes all limball instances (G.P_CENTERS[joker_key]), tried changing card.children.center.sprite_pos but it also changes all instances of a joker

chrome widget
#

Afaik, card.children.center is the entire card data. You'd want card.children.front, card.children.back, etc

#

....I think

manic rune
#

i tried changing card.children.front too

#

doesnt seem to work either

#

in fact, i dont think theres anything in card.children.front

chrome widget
#

Hmmm gimme a little bit to research. Can you show me more of your code so I know what you want to do?

#

It might also help me fix a weird bug that occurs with Half Joker and Photograph for me

manic rune
#

oh, its for a mod which allows cards to have animated sprites

#

heres the entire code lol

#

currently it kind of works, but it affects all instances of a type which can be quite a limitation

normal crest
# manic rune

I vaguely remember jokers not having the front part, could be wrong

#

Not very familiar with ui stuff

wintry idol
manic rune
#

same, im just printing out everything "card" has and see if theres something handling their pos at this point

#

yeah, card.children.front doesnt seem to have anything at all

wintry idol
#

i mean i REALLY hate how there is no continue keyword and you have to use goto but it’s not a big deal

manic rune
#

back is probably the appearance of a joker when its flipped

manic rune
wintry idol
#

that’s actually a fair point

normal crest
# manic rune

I recommend you use debug plus to execute this code so you don't have to restart your game on crash

manic rune
#

oh, you can do that?

wintry idol
#

i’ve majnly used LuaU for 5 years unfortunately so i got very shocked when i found out there was no generalized iteration (looping without needing to add pairs()) or continue keyword

normal crest
#

Yeah just go in a game, open the console and type eval G.jokers.cards[1].children

#

for example

#

that's what I did

manic rune
#

for me, its just 2 years but i was mostly frustrated when a += 1 doesnt work

#

😭

chrome widget
#

NOT HAVING THE INCREMENT OPERATORS KILLS ME

wintry idol
#

i got so mad at that

#

EXACTLY

#

😭😭😭

manic rune
#

a = a + 1 is genuinely so ugly 😭

wintry idol
#

they genuinely need to add it

wintry idol
manic rune
normal crest
#

I've been using lua for like a month and a half and I can confirm that not having += or continue has been annoying

wintry idol
#

honestly**

#

we need += and ++

normal crest
#

Honestly ++ is not that important

#

just +=

wintry idol
#

that’s fair but the less i type the faster i can pump out code

chrome widget
normal crest
#

it'll just print out the children table of the card in the debugplus console

chrome widget
#

Do you have to do this for any card you suspect might crash the game?

manic rune
normal crest
#

No it's just for testing purposes

#

I suggested it so bepis doesn't have to restart the game if code crashes

wintry idol
#

is getfenv and setfenv a thing in lua?

#

i haven’t actually checked

manic rune
#

you mean this?

wintry idol
#

yeah that

#

thank you 🙏🙏🙏

chrome widget
#

Sitting here making my silly Balatro mod because the game design industry is fucked and I can't get a job loved CattoBlush gun

manic rune
#

i might have to make a workaround for my mod

#

since i dont think theres even a way to change one card's sprite

#

😭

random sleet
#

(and also the other thing)

wintry idol
chrome widget
#

So like, there's definitely a way to do it here

#

For example, I set the sprite pos of a card's center when I added it to the deck

#

It's in my joker deck in the second image (you can see it's 1/5), but the set sprite pos makes the actual sprite render out of bounds of the card itself

#

However, the one in my collection (which does render with the same values) is still visible

manic rune
#

...oh, so its a freaking function

#

yeah i will try that, thanks

#

oh also, cool art you got there

chrome widget
#

Thanks!! I hate art but I'm decent at it

plush cove
#

random question: if I want to iterate through an array, but I don't need to use the index variable, what are possible advantages/disadvantages of both of these kinds of for loops?

rose dragon
frosty dock
#

There's a third option:

local i = 1
while i <= #tbl do
  local v = tbl[i]
  -- do stuff
  i = i+1
end
#

This one's different in that it allows you to modify the table you're iterating within the loop

#

The shader's key, file name (without extension) and the shader name used in the GLSL file must be identical.

rose dragon
#

how can i have multiple "souls" (the floating effect over the joker card, ex. The Soul, Legendary Jokers, Hologram)
similarly to how cryptids exotic jokers has multiple "souls"

manic rune
#

finally got it working 💔

runic pecan
#

Does context.before take return {chips=10} or do I have to use other methods?

faint yacht
#

You attempting to add chips before the scoring starts?

runic pecan
normal crest
wintry idol
manic rune
manic rune
#

my first 5*

wintry idol
faint yacht
lucid sun
#

is there a way to fetch the current tags for the blind

neat plover
plush cove
neat plover
#

thanks so f ing much i'll do that

plush cove
#

whenever you're referring to specific keys, you need to do so with its accompanying prefix (i.e. "j" for joker, "c" for consumable, etc)

if it's a modded consumable you also need the mod's prefix (for example Cryptid's is "cry")

neat plover
#

oh

stray warren
#

I'm confused, is that an extension of triple moon goddess?

neat plover
#

no im taking bits from code

#

to learn how the lua works

wintry idol
#

if you don’t know how lua works i’d read up on a basics tutorial before modding the code

#

it shouldn’t take too long but diving into the code might not always be the best idea

#

it can be very overwhelming

stray warren
#

If you haven't yet, the Steamodded wiki is great, as well as looking through the source code of Balatro itself

#

Although the wiki still has some work to do, I feel like

wintry idol
#

i partially agree with the 2nd half

stray warren
#

I learned probably 60% of my knowledge from the source code

wintry idol
#

balatros source code really isn’t the best at in some areas

#

but

wintry swallow
#

hello! anyone knows how i could move the stake sticker to the left to put it on the joker properly? Like the half joker or square etc

wintry idol
#

if you ignore those parts it should be just fine

neat plover
wintry idol
plush cove
#

@neat plover did that fix it?

neat plover
#

im on my phone so i'll tell you soon

wintry solar
neat plover
#

it still crashes

#

is this what i needed to change

manic rune
stray warren
neat plover
stray warren
#

And can you send your full source code for that file

neat plover
#

i based myself on some code

#

from a mod

stray warren
#

Paperback I assume

neat plover
#

yes

proud pier
#

Can malverk thumbnails be set dynamically using settings?

neat plover
# neat plover

im trying to make so that when there is no hands left, the joker has a 1 in 3 chance to create a planet card

stray warren
#

When I copied your code to my editor, it says your calculate function is missing a corresponding 'end'

#

add one and see what happens then

neat plover
#

ok

manic rune
neat plover
#

ok ok

jovial harness
#

Is there a way to change the back of a joker?

pseudo current
#

Guys i want to make a mod, how does that work?

neat plover
#

same thing

stray warren
#

Also probably use a code editor that isn't notepad, if that's what you're using

neat plover
#

i have it but im nostalgic sooo

stray warren
#

It looks like your Event isn't closed

#

You have brackets and parentheses that just never close

neat plover
#

im so f ing stupid

stray warren
neat plover
#

where should i put the parentheses

#

nvm

stray warren
neat plover
#

yeah i was right

#

nah

#

i forgot another one

stray warren
#

The one to close the Joker definition

neat plover
#

OH

#

IT FINALLY WORKS AFTER 3H

#

YES

neat plover
crisp coral
#

technically this has no specific trigger

#

"When using last Discard, ..."

neat plover
#

no it triggers every turn without dicards

stray warren
#

You should probably specify that. Because technically with how you worded it it should be constantly running the 1 in 3 chance as long as there are no discards

#

like every frame

neat plover
#

oh right

neat plover
#

how would you change a value every round (ex mail in rebate) ?

manic rune
#

you can use psuedorandom stuff

#

if you want it to be the same if you replay the seed

#

or use math.random() if you want it to be always random

neat plover
manic rune
#

this is what gros michel 2 does (in examples)

neat plover
#

but gros michel just checks for random values, i want to set them

manic rune
#

oh, if you want the suit to be random then you can take a look at how castle 2 does it

neat plover
#

thanks very much

neat plover
manic rune
#

if vanilla jokers then

#

in card.lua

neat plover
#

ok

manic rune
neat plover
atomic edge
#

how can i increment a jokers ability globally

neat plover
#

?

atomic edge
#

i mean can i somehow get the joker then do .ability on it without it being the card

atomic edge
neat plover
atomic edge
#

and what is giving you trouble in the castle code?

neat plover
#

i don't understand where its setting the value

atomic edge
#

so it has its on variable in G.GAME.current_round.castle2_card.suit

#

its set to be spades by default

#

and in the chunk of code the other guy sent

#

you can see it making a local castle_card, which is a random card taken from all the "valid_castle_cards" with a seed in this case "2cas"

#

when it gets that cards

#

it just checks for its suit

neat plover
#

ok

atomic edge
#

and sets the G.GAME.current_round.castle2_card.suit to be of that suit

#

and its needed suit is stored in that variable

neat plover
#

thanks very much

atomic edge
#

no problem

#

does anyone know how i can globally fetch a certain jokers ability?

plush cove
#

@frosty dock hi, I'm back on my Joker register and I just tested my mod with Cryptid, and found out about a small bug

my workaround solution for displaying placeholder sprites is checking if the joker's atlas is "joker", since I need to do that if I'm using Joker.register (overriding SMODS.Joker didn't have this issue, and using just nil shows Jimbo)

but the problem is that some mods, namely Cryptid, still use the original Joker register for some of their Jokers, so they show up as my placeholder asset instead

what's the best way to work around this so that I can both have my placeholder art AND allow other mods to tap into the base Joker atlas?

ty in advance! (and sorry for the ping 😅)

#

update: nvm, i figured out a workaround

just check if the current mod is the one that's supposed to use the placeholders lol

lavish lake
#

guys how do i make a joker that gains +6 mult per unscored jack?

manic rune
#

i think theres a smods optional feature for checking unscored cards

#

or i could be wrong honestly, i do remembering seeing smt like that somewhere

atomic edge
#

i want to increment a jokers ability from a diffirent function

violet void
rose dragon
atomic edge
#

it actually a consumable but i thought it would be the same, it is a sort of a "quest" which needs 6 cards to change colour in order to activate

#

so i have card.ability.progress on it

#

and i want to increment that

#

i already patched the function set_base()

#

which changes the playing cards suit

#

this is the code

#

but its wrong

violet void
#

SMODS.find_card returns a table, it should be SMODS.find_card("c_janm_quest1")[1]

-# (It would only change the first one though and idk if you need the next there)

atomic edge
#

ohhh

#

the if statement works fine

#

but the other things are the problem

#

thanks that makes sense

runic pecan
#

Would there be error in the game if I juice_up a playing card from G.playing_cards that isn't played(G.play) nor in hand(G.hand)?

violet void
#

No and you would be able to see them shake in the Deck area

runic pecan
#

Does context.hand_drawn go through each drawn card or is it only called once after the hand is drawn?

#

I want to apply effects to certain kind of cards "when drawn".

violet void
#

only once

neat plover
neat plover
runic pecan
violet void
runic pecan
#

Yeah...

violet void
runic pecan
#

Wait, does hand_drawn cover first_hand_drawn?

manic rune
#

can you get negative mult

neat plover
#

i hope so

runic pecan
manic rune
#

the idea of getting negative mult THEN using negative xmult seems fun

manic rune
#

thats a lot of edit

violet void
wintry solar
#

Hand_drawn is a table of the drawn cards btw

#

You can do whatever you want to them within that context

#

No need for events or anything

violet void
wintry solar
#

They’re the same context

#

Just the first hand has a flag

#

You’re just not up to date

manic rune
#

is soul_pos locked with the same atlas the joker is using?

#

oof

runic pecan
#

Draw a bigger atlas

limpid halo
#

You can patch it ™️

manic rune
#

i wish i can patch a dad into my life

limpid halo
#

you can!

manic rune
#

optoins

limpid halo
#

true

runic pecan
#

Am I really unable to define config in SMODS.Sticker?

wintry solar
#

No

runic pecan
manic rune
#

yesn't

#

god damn it ui looks so complicated

#

😭

wintry solar
#

You can do

runic pecan
#

Let me guess: but I won't be able to access it?

#

I just need a way to track how many time a card is arrested.

atomic edge
#

cant you put something on them like the hiker does?

wintry solar
#

I think you just need to add them manually in your apply function maybe?

runic pecan
#

I would also like the counter to be shown to players.

atomic edge
#

is there a way i can remove/add the soul sprite of a joker under some conditions?

manic rune
#

am i the only one whos barely understanding this

wintry solar
#

What UI are you trying to do?

runic pecan
manic rune
#

failing miserably though, everything seems so complicated 😭

runic pecan
manic rune
limpid halo
#

[ bookmark d9ff13d3-cc95-4a31-8f0b-2bccbce8ec30 ]

manic rune
#

wuh

limpid halo
#

i wanna do UI stuff later today so im setting a bookmark for myself to read what u found

manic rune
#

oh lol

#

im guessing in order to create another button for a joker, id need to create a hook which is understandable enough

runic pecan
manic rune
#

yes

manic rune
#

sorry, i dont know that one, passing it to other modders

runic pecan
wintry solar
manic rune
#

...what does the _loc and arg mean?

limpid halo
atomic edge
#

ohh shiet this is nice

#

works for me coz it will be impossible to have multiple copies

wintry solar
#

<@&1133519078540185692>

runic pecan
#

What other terms than Joker=false, do I need to state to make sure only playing cards can be applied with this sticker?

manic rune
#

probably Consumable?

#

oh wait, if its sets then i think Tarot and Spectral

runic pecan
#

My main question is: what is the set of playing cards?

#

Unless the playing cards are always able to be applied with any sticker possible?

random sleet
#

Default or Enhanced

atomic edge
#

does anyone know how i could dynamically change whether a card has a soul sprite or not?

#

or just change soul_pos?

limpid halo
#

i swear i did exactly this accidentally yesterday

atomic edge
#

its in card.lua

#

its patched in

#

dont worry about the print its my language just for debugging

#

i also tried

#

quest.soul_pos

#

and i also tried it in the code of the card

#

in like SMODS.consumable

#

but none of them worked

#

and the soul is in the atlas at x=0, y=0

#

could you maybe send me your code so i can check it out?

#

maybe im making a mistake i dont even see somewhere else

#

and the print is printing

#

so its going into the if

limpid halo
#

i didn't commit yet and im at work rn so i can't give you my code, sorry

atomic edge
#

oh okay

#

no problem

#

thanks for help either way

limpid halo
#

if you print your quest object, does it have a soul_pos in the table?

atomic edge
#

lemme check

#

oh

#

its working

#

it does say soul pos is at x=0, y=0 but for some reason its not changing

#

and the soul is at x=0 y = 0 in the atlas

#

i changed it and it is changing

#

the soul pos that is

#

but nothing visible is happening

#

should i do quest.soul_pos

#

or something else

limpid halo
#

ye but removing the soul_pos property should prevent the floating_sprite from being created :/

#

maybe it's being removed too late? is this before or after the draw calls

#

also if its just for the quest card, maybe do it in the update function for the quest card instead of patching?

atomic edge
#

when is the update function called?

limpid halo
#

from memory, no idea. once per frame though

atomic edge
#

oh okay so i just put update = function() and then everything else?

#

oh no

#

i got it

#

ill try

limpid halo
#

aye aye

atomic edge
#

i did it like this

#

is this ok?

#

i mean its not working again haha

limpid halo
#

use self.soul_pos there

#

card.ability.progress but self.soul_pos

atomic edge
#

wait

#

is the problem that the card is a consumable

#

and it cant have a soul?

limpid halo
#

the soul card?

atomic edge
#

yes

#

its not a joker

#

its a consumable

limpid halo
#

uhhhhhhhhhhhhhhhhh

atomic edge
#

hahaha sorry

limpid halo
#

Most Likely

crisp coral
#

and it has a floating sprite

#

so idk what you're talking about

atomic edge
#

oh

#

i mean i cant get it to work

#

if i do self

limpid halo
#

don't consumables get constructed differently though?

crisp coral
#

self refers to the card's center

limpid halo
#

i haven't screwed with consumables yet so idk

crisp coral
#

so self is effectively card.config.center

atomic edge
#

when i do self.soul_pos

limpid halo
#

progress!

atomic edge
#

hahahaha

crisp coral
#

adding soul_pos assumes the card already has a floating_sprite set up

#

and floating_sprite is created if the card originally has soul_pos

atomic edge
#

i put soul_pos = nil, in the card creation

#

like SMODS.consumable

#

should i put some other value?

crisp coral
#

soul_pos = nil is the same as not having soul_pos

atomic edge
#

ohhhhhh

crisp coral
#

any other value thats not a table with {x = number, y = number} will crash

atomic edge
#

so it would be the easiest to put just some transparent non existant position

limpid halo
#

oh duh

atomic edge
#

that is in the atlas

limpid halo
#

yeah that'd totally work

atomic edge
#

okay thank you so much

#

i know it was painful for you more than me

#

hahaha

limpid halo
#

i am the overcomplicating champion

#

💀

atomic edge
#

hahah now it doesnt crash

#

but the soul is not showing

#

this is the atlas, the soul is the first one and the card is the second one

#

i just used the default sprites so i can overlay correctly

#

is the soul drawn wrong maybe or something?

lavish lake
#

guys how do i make a damn joker that gains +6 mult per unscored jack???? can someone give me clear instructions on how to check for unscored cards during scoring and then check if it's a jack???

#

because i see everyone saying "i think theres a way to check for unscored cards" without actually helping

atomic edge
crisp coral
limpid halo
#

can't you just use context.full_hand and compare with context.scoring_hand

wintry solar
#

Not properly

lavish lake
# atomic edge

yeah but the instructions are still very unclear 🤷‍♂️ how do i loop through the unscored cards? what other context do i use for counting the cards?

#

hello?

wintry solar
#

You don’t loop through them

lavish lake
#

???

atomic edge
#

just look at the code of any other joker that does something for scored cards and copy it and change the context to unscored

lavish lake
wintry solar
#

Use the individual context

lavish lake
# wintry solar Use the individual context
    calculate = function (self, card, context)
        if context.cardarea == 'unscored' and context.individual then
            if card:get_id() == 11 then
                card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.gainMult
            end
        end
    end

so like this?

#

?

#

????

atomic edge
#

why are you so angry?

#

did you try it?

manic rune
atomic edge
#

ths is the code for walkie talkie

#

it gives mult/cips for each 4 or 10

#

you just change the G.play to unscored

#

and the id to 11

#

and remove the chips if you only want mult

manic rune
#

where are those located, are they in smods-main or Balatro?

atomic edge
manic rune
#

how did you even do that to begin with lol

wintry solar
#

You’re modifying the center object

#

Not the actual object

atomic edge
#

oh

#

card.children.center.soul_pos

#

i do this

#

yea

#

and what should i do?

lavish lake
atomic edge
#

when i change it

lavish lake
#

actually nvm

#

i figured it out

manic rune
atomic edge
#

its in UI_defitintions

#

i found it

#

in functions folder

manic rune
#

ooo, thanks!

#

never came to my mind they were potentially there, for some reason

atomic edge
#

haha happens

atomic edge
manic rune
#

card.children.center doesnt work?

wintry solar
#

You need to recreate the sprite iirc

atomic edge
#

oh so basically i would need to make another function like the game has for set_sprite_pos()

#

but only for soul

manic rune
#

likely to be the case, yeah