#💻・modding-dev

1 messages · Page 613 of 1

broken rivet
#

jokerforge(tm)

tired otter
broken rivet
#

i'd honestly recommend learning it

tired otter
broken rivet
#

just get a hold on very basic things

hallow slate
#

How come this doesn't work:

[patches.pattern]
target = "cardarea.lua"
pattern = '''if self.ARGS.invisible_area_types[self.config.type] or
        (self.config.type == 'hand' and ({[G.STATES.SHOP]=1, [G.STATES.TAROT_PACK]=1, [G.STATES.SPECTRAL_PACK]=1, [G.STATES.STANDARD_PACK]=1,[G.STATES.BUFFOON_PACK]=1,[G.STATES.PLANET_PACK]=1, [G.STATES.ROUND_EVAL]=1, [G.STATES.BLIND_SELECT]=1})[state]) or
        (self.config.type == 'hand' and state == G.STATES.SMODS_BOOSTER_OPENED) or
        (self.config.type == 'deck' and self ~= G.deck) or
        (self.config.type == 'shop' and self ~= G.shop_vouchers) then'''
position = "at"
payload =  '''    if self:can_draw() then'''
overwrite = true
match_indent = true```
native bone
#

So what context should I use to retrigger Jokers. I was using context.before, but that didnt work for specifically Jokers. Do I need to do it again for specifically context.joker_main?

wind steppe
#

context.retrigger_joker_check

#

make sure the optional feature is enabled

native bone
#

What I mean is what context should I put the retrigger = true?

wind steppe
native bone
#

Okay, sure, I'll try that

slim ferry
#

also its repetitions = <amount>

#

like playing cards

vale grove
#

is there a universal context check? like one that always checks

native bone
#

context.before? It checks before anything happens with your whatever

daring fern
timid zinc
#

is there any context for after discarding

slim ferry
vale grove
#

but i want a joker that turns your gamespeed to 8

#

and most of it already works

slim ferry
#

and just keep it that way?

vale grove
slim ferry
#

you would set it in update repeatedly

vale grove
#
            if G.GAME.normalgamespeed then
                G.SETTINGS.GAMESPEED = 8
               G.GAME.normalgamespeed = nil
            end
            if not G.GAME.normalgamespeed then
                G.GAME.normalgamespeed = G.SETTINGS.GAMESPEED
            end
            G.SETTINGS.GAMESPEED = 8
   
        if context.remove_from_deck then
                 G.GAME.normalgamespeed = 4
        end
dusty fractal
#

yo gang

vale grove
#

i have it like this currently

dusty fractal
#

i just realized i was in the wrong chat BUT

#

how do you mess with hand calc

daring fern
vale grove
#

and the only thing that doesnt work is the remove from deck

dusty fractal
#

i want to make flushes playable with one off suit card

#

but smeared joker is hardcoded

#

do i need to patch

slim ferry
#

is that not just four fingers

dusty fractal
slim ferry
dusty fractal
#

yeah it would be but question still stands

#

ive not used hooks b4

#

thats why im asking

#

is there any good documentation on how they function

slim ferry
#

check four fingers vanillaremade

#

and

#

one moment

slim ferry
vale grove
#

so like this?

slim ferry
#

just do G.SETTINGS.GAMESPEED = 8 and keep the old game speed saving in add_to_deck

vale grove
#

why would i keep the old game speed in add_to_deck?

slim ferry
#

well because update runs every frame

#

and you dont need to save the old game speed every frame

vale grove
#

yeah i get that

#

but why would i save the old game speed in add to deck

#
        update = function(self, card, dt)

              G.GAME.normalgamespeed = 8
        remove_from_deck = function(self, card, from_debuff)
            G.GAME.normalgamespeed = 4
        end
#

wouldnt this work?

slim ferry
#

i assume you meant G.SETTINGS.GAMESPEED

#

but yeah that also works

vale grove
#

the issue i have with this currentl

#

is that when i put the gamespeed down

#

it just

#

goes down

slim ferry
#

wdym

vale grove
#

well if i go into my settings

#

and set gamespeed to 4

#

it stays at 4

#

previously it would go back to 8 (unless you were playing a hand)

slim ferry
#

update should prevent that though

vale grove
#

but it doesnt

vale grove
slim ferry
#

shouldnt those be G.SETTINGS.GAMESPEED

#

both of them

vale grove
#

well when i obtain the joker the gamespeed does go up (nvm it doesnt me when i lie)

#
    calculate = function(self, card, context)
        update = function(self, card, dt)
            G.SETTINGS.GAMESPEED = 8
            remove_from_deck = function(self, card, from_debuff)
                G.SETTINGS.GAMESPEED = 4
            end
            if context.end_of_round and G.GAME.current_round.hands_played == 1 and context.main_eval then
                card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_mod
                return {
                    message = 'Vroom',
                    sound = 'YA_calcium'
                }
            end
            if context.end_of_round and G.GAME.current_round.hands_played >= 1 and context.main_eval then
                card.ability.extra.Xmult = 1
            end
            if context.joker_main then
                return {
                    card = card,
                    Xmult = card.ability.extra.Xmult,
                    colour = G.C.MULT
                }
            end
        end
    end

this is what the full joker looks like right now (ignore the other stuff its for a different function)

slim ferry
#

yeah because update and remove_from_deck are in calculate lol

#

they should be outside

vale grove
#

ohhh

#

ive never used either lol 😭

slim ferry
#

all seperate functions should go outside of calculate

native bone
#

I've been trying to get this to retrigger Jokers that are eternal(I removed the eternal condition for testing), but it has never seemed to actually retrigger Jokers.

vale grove
#

ahh yeah now it works

#

thank you kind stranger

sour garden
#

i have a joker that is supposed to unlock if you win a run without having any consumables, but i'm not sure the best way to do it.
i have something like:

check_for_unlock = function(self, args)
    if args.type == 'win' and G.GAME.modname.never_held_consumable then
      return true
    end
  end,
update = function(self, card, dt)
    if G.consumeables then
      if #G.consumeables.cards > 0 then
        G.GAME.modname.never_held_consumable = false
      end
    end
  end,

but it's not triggering, probably cuz update only happens when you have the joker spawned in. how do i do a global update function when you get a consumable?

slim ferry
#

hook Card:add_to_deck to check when a consumable is added

#

or use SMODS.current_mod.calculate and check for a consumable being added in context.card_added

vale grove
#

i wanna make a joker that changes the langauge

#

that should probably also go in update shouldnt it?

slim ferry
#

probably

#

but for where you reload localization after the change do check if the current language isnt already the language youre changing to

#

since idk if its a good idea to reload localization every frame unconditionally

vale grove
#

maybe maybe

#

first i need to figure out how to actually change the language

#

ive been doing alot of digging and reading but i cannot find a single thing about how to do it outside of the main way

sour garden
slim ferry
#

the line above has to use . and not :

#

also its not stored in G.FUNCS

daring fern
tired otter
#

soo HOW do i fix it if i can

sour garden
#

so like this?

slim ferry
slim ferry
sour garden
#

i've formatted it like the example, but vsc is still yelling at me

slim ferry
#

yeah the syntax with : only works if you do function Card:add_to_deck(...) and not if you do Card:add_to_deck = function(...)

sour garden
#

ah okay, that's what i missed

#
local card_add_to_deck_ref = Card.add_to_deck
function Card:add_to_deck(self)
  local ret = card_add_to_deck_ref(self)
  if self.ability.set == 'Consumable' then
    G.GAME.modname.never_held_consumable = false
  end
  return ret
end

what did i mess up this time

#

this happens when i buy a consumable from the shop

#

oh wait, it also happens when i buy jokers too

normal crest
#

the : syntax is for skipping the self argument in the function

sour garden
#

ah, okay

normal crest
#

I'd recommend just doing Card.add_to_deck = function(self, e) if it's confusing with :

normal crest
#

🤷 just took it from their screenshot

wintry solar
#

It doesn’t matter what it’s called

normal crest
#

we know, but I'd suggest naming it the same as the original function to be consistent if for no other reason

crimson echo
#

does anyone know how to bypass the character limit on a joker? or just in general?

native bone
#

You can just make new lines by doing [x] = "This is a description", where x is the line you want

#

replace the string with whatever you want

#

inside of your loc_txt

crimson echo
normal crest
#

you want the name to be multiple lines of text?

wind steppe
#

\n is your friend

crimson echo
native bone
#

Yeah, use \n to make a new line

normal crest
wind steppe
#

try name = "Joker That's Been Crumpled Up, Torn Slightly, Soaked In The Lagoon And Kissed With Coral Blue\n#2 Semi Gloss Lipstick"

crimson echo
#

so like this

wind steppe
#

i wouldnt put the space before the \n

#

itll move the first line left a bit instead of centering it

crimson echo
#

imma load it now

sharp arch
#

This is good code, right

daring fern
sharp arch
#

thanks

#

are non-scoring card checkscontext.cardarea == unscored
or context.cardarea.unscored

daring fern
viscid talon
#

ok gamers uh

#

ive decided to code a joker semi-manually for the first time

#

in the sense that i make a blank joker in jokerforge with no functions, nothing

#

and i do everything else manually in vscode

#

so far its working well, i just need help with a scoring issue

#
    key = "wheelbarrow",
    config = { extra = { mult = 8} },
    loc_vars = function(self, info_queue, card)
        local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds,
            'vremade_wheelbarrow' .. G.GAME.round_resets.ante)
        return { vars = { numerator, denominator }, card.ability.extra.mult }
    end,
    loc_txt = {
        ['name'] = 'Wheelbarrow',
        ['text'] = {
            [1] = '{C:green}1 in 2{} cards get drawn face down',
            [2] = 'All {C:attention}facedown{} cards give {C:red}+8{} Mult when scored'
        },
        ['unlock'] = {
            [1] = ''
        }
    },
    pos = {
        x = 6,
        y = 3
    },
    display_size = {
        w = 71 * 1, 
        h = 95 * 1
    },
    cost = 4,
    rarity = 2,
    blueprint_compat = true,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = false,
    atlas = 'CustomJokers',
    pools = { ["hatchet_hatchet_jokers"] = true },

    calculate = function(self, blind, context)
            if context.stay_flipped and context.to_area == G.hand and
                SMODS.pseudorandom_probability(blind, 'vremade_wheelbarrow', 1, 2) then
                return {
                    stay_flipped = true
                }
            end
            if context.individual and context.cardarea == G.play and
            context.stay_flipped then
            return {
                mult = card.ability.extra.s_mult
            }
        end
    end,
}
#

the idea is that cards that are flipped give +8 when scored

river grail
#

Is it possible for a suit to naturally count as two other suits? I wanna make a suit that acts like a smeared joker card (without smeared joker, of course)

viscid talon
#

how so?#

viscid talon
#

its not giving da extra mult 😔

#

at least it runs without any crashes LMAO

slim ferry
viscid talon
#

i see, so how do i make it so that when a card is flipped, it sends out some sort of variable that the joker can recognise and provide +8 mult ? if that makes sense

#

also i just realised loc_vars literally means "local variables" LMAOOOOO

slim ferry
#

it means localization variables

#

im fairly certain

viscid talon
#

o

#

😭

#

i have so much 2 learn,,

zealous glen
slim ferry
viscid talon
viscid talon
#

uhh

#

i dont know how to set a flag,,

#

arent flags the g.game thing

slim ferry
#

not specifically

viscid talon
#

oh

zealous glen
viscid talon
#

also i cant find context.pressplay

slim ferry
#

press_play

zealous glen
viscid talon
#

boolean is anumber thing right

#

oke

#

oh wait no

#

its the opposite

#

it can only hold true or false values

slim ferry
#

yeah

zealous glen
#

Yes

slim ferry
#

so you would loop over G.play.cards, check for each card if their facing value is "back", and set a flag on the card if true

zealous glen
viscid talon
#

okay hm

gusty compass
#

Can I per chance attach a custom effect for an edition other than the normal ones, as if it was calculate, since I can only infer about on_apply, on_remove and on_load

slim ferry
#

you can put a calculate on an edition

gusty compass
#

For a minute I believed that was not possible via the smods wiki

daring fern
crimson echo
daring fern
# crimson echo explain?
name = {
    "Joker That's Been Crumpled Up, Torn Slightly, Soaked In The Lagoon And Kissed With Coral Blue",
    "2 Semi Gloss Lipstick"
}
viscid talon
#

ok chat im gonna admit

#

I dont know what im doing

#

like at all

#

i dont know how to make this

#

SOBS

#

im trying to lock in and i just cant

zealous glen
#

What have you tried so far

viscid talon
#

i think its just having no idea how lua works

zealous glen
viscid talon
#

IDK HOW ANY OF THIS WORKSSSSSS

#

loc variables are fine and all but flags are like

#

so confusing

zealous glen
#

Take a look at the wiki page for calculation

#

Not all contexts exist at the same time

#

The way it works is that sometimes the game processes calculation, which passes some contexts to some objects

#

You can think of these as timings when abilities can activate

#

First, you want an ability that flags face down cards during a context where the press_play flag is true

viscid talon
#

so press_play is a flag then?

zealous glen
#

Something like this is what you want

viscid talon
#

ohh interesting interesting

#

so context is used for flags then?

zealous glen
#

I fixed it

zealous glen
#

Context is Balatro lingo

viscid talon
#

i see,,

zealous glen
#

Again sometimes the (modded) game will call calculate_context with a table as argument

viscid talon
#

whats a loop then?

#

yeah, ive seen calculate_context be used

frosty rampart
# viscid talon so press_play is a flag then?

a joker's calculate function is called many times over the course of a single hand, and even outside of when hands are played. each time, it's called with a different set of values in context. some of them are flags, like context.press_play. some of them store more information than just true or false, like context.full_hand contains the full played hand when it's relevant to the current context that is being calculated.

zealous glen
#

This table is nicknamed context and has variables players can access

#

Typically one of these variables is something like key = true, which is like the name of the context

#

For example, press_play = true only in the "press_play" context

frosty rampart
# viscid talon whats a loop then?

a loop is a programming structure that repeats itself multiple times so that you don't have to rewrite a bunch of code to do the same task on a number of things, e.g. going over the full hand being played and marking which ones are face down

viscid talon
#

oh right okay

viscid talon
frosty rampart
#

it's a very important concept to grasp

viscid talon
#

ofc, im not disagreeing

#

im just trying to break it down in my head

#

so calculate is what a joker does

#

im guessing

#

like lusty joker calculates if a suit flag is heart then returns with extra mult

#

and hand_size is a flag that isnt a boolean but rather carries a specific value

zealous glen
# viscid talon thats,,, confusing

The Balatro system isn't the best but it's good enough. Here, you can think of each Joker knowing what they can do and when, so a worker has to visit each Joker individually with whatever raw materials they have and ask the Joker to do their thing. Most of the time the Jokers do nothing

frosty rampart
#

you're too hung up on what a "flag" is

viscid talon
frosty rampart
#

it's just a variable

zealous glen
frosty rampart
#

if that helps

viscid talon
#

global or local?!?!?!

viscid talon
#

^ used scratch as a kid

zealous glen
native bone
#

A flag is just a variable that can be accessed by any other Joker, but it is only true or false

viscid talon
#

i see,, 🤔

#

so flags are exclusively boolean then

native bone
#

Yes

viscid talon
#

they cant go beyond true or false

native bone
#

Nope

viscid talon
#

hmm

frosty rampart
#

again
a "flag" is not a strictly defined thing
it's literally just a special name some people use for a boolean variable

#

it's very willy nilly in lua because lua variables don't do any strict sort of type checking, so you can have a variable equal to true and then you can immediately just set it to 5.3 or "Hello world!" or whatever you want

zealous glen
#

Have you played visual novels or history games

#

not history

#

games with a story

#

multiple-choice stories makes more sense

#

testg

viscid talon
#

yeah i played ddlc

#

and ace attorney

zealous glen
#

Sorry my internet went ballistic

zealous glen
#

Anyways, in DDLC depending on the poems you write you have scenes with different girls

#

In programming and visual novel player slang this is called setting a flag

#

Because you took a decision or made an action that set you along a specific path in the game

#

There’s a specific variation of this slang, “death flag”, from when you end in a route where a character dies

#

Maybe the character says something like “I sure love being alive and not being dead” and that’s like the game yelling at you this character is gonna die; players will call this a “death flag” I think

viscid talon
#

AHHHH

#

okay i think i get it now

zealous glen
viscid talon
#

flag = type of variable known by other jokers that can only be true/false

frosty rampart
viscid talon
#

i have smth like this rn

#
                hand.flipped = true
             end```
frosty rampart
#

you've got a vague idea of where you're headed

zealous glen
frosty rampart
#

well both tbh
that's why i said ostensibly, the actual chr files in the code just contain various spooky images/sounds/messages

#

but the existence or absence of the files can be considered "flags" in that the removal of the chr file denotes monika killing the relevant character

zealous glen
#

True

#

But also I just noticed this is unrelated to what I said

frosty rampart
#

true, perhaps i went too fast

zealous glen
#

Unless you imagine a more complicated structure behind the game

frosty rampart
#

my understanding is that the chr files are meant to be interpreted by the average layman as containing actual data about the characters

zealous glen
#

For example, instead of directly setting you on a path, your actions change the characters' happiness, and then the game decides your path based on which character is happiest

frosty rampart
#

but we're way off topic now lol

viscid talon
#

i think the issue is that i cant find context.press_play on the wiki

#

so its confusing me even more

#

i dont even know what it does

#

im guessing its used for defining when a round starts

zealous glen
#

Yeah I guess it's only listed on an old commit

primal robin
#

whats happening here, teaching someone what's programming is?

viscid talon
#

yeah, im very new to it

frosty rampart
#

oh yea calculation documentation is. limited
but context.press_play is for calculation during the instant that the player presses the button to play a hand

viscid talon
#

okay, im starting to get it a little

#

is there a when thing in lua

normal crest
viscid talon
#

like when context.press_play if cards_flipped = true return ability.extra.mult

wind steppe
#

you're looking for if

frosty rampart
#

you're just looking for if context.press_play

zealous glen
vale grove
#

how do you remove something from every pool?

#

a joker specifically

frosty rampart
#

when the play hand button is pressed, a calculation is run with context.press_play set to true

native bone
primal robin
#

by flipped you mean face down

viscid talon
#

yeas

zealous glen
#

For example, Cavendish isn't removed, it's just unavailable

native bone
vale grove
#

and i want the three jokers to not be in the normal pool

#

only available through that one joker

viscid talon
vale grove
#

some of it is still accurate

normal crest
vale grove
#

but when i started couple months ago some of it was not up to date

zealous glen
vale grove
#

i want these to not be in the pool at all

primal robin
#
local flipped_count = 0
for _, card in pairs(G.play.cards) do
    if card.facing == "back" then
        flipped_count = flipped_count + 1
    end
end
if flipped_count > 0 then
    return {
        mult = flipped_count * card.ability.extra.mult_per_flipped
    }
end
zealous glen
primal robin
#

Probably this?

vale grove
zealous glen
#

I just wanted to know if you wanted to make something like Cavendish, which this does

vale grove
#

but for this specific question it doesnt really matter

sharp arch
#

hanging chad is j_chad right

viscid talon
#

what does in pairs do

#

what is for _ 😭

sharp arch
normal crest
sharp arch
#

in pairs find how many are in

zealous glen
# vale grove kinda its a little complicated tho

Cavendish is always in the Joker pool it's just there as you can see there's an in_pool function that can flag it as unavailable. You can think of Jokers like Stone Joker as functioning similarly.

Showman involves something similar in the sense it's another part of the check to see if a Joker is available, but they're always in the pool before being processed

viscid talon
#

hmm

sharp arch
#

and then for_ is the loop

primal robin
#

You better learn basics of Lua first rather then guessing things

normal crest
viscid talon
#

true,, i normally just use jokerforge for stuffs

#

the knowledge i have of programming is still quite new

primal robin
#

I see, someone provide video about what is lua and how it works

viscid talon
#

i only started development on the mod like

#

two months ago

vale grove
normal crest
timid zinc
#

how do i shorten this patch, it'd be easy to make it just recognize the first line of the pattern but how would i add the two ends

vale grove
#

oh now that i think about it

#

is there a universal key for food jokers?

#

or something i can use to identify all of them

zealous glen
#

@wintry solar was working on it

timid zinc
#

also it doesn't work with cryptid at all

red flower
#

you could use goto instead of wrapping everything in a condition

normal crest
#

oh no...

timid zinc
#

goto?

zealous glen
red flower
# timid zinc goto?
-- before the code
if condition then goto skip_voucher end

-- after the code
::skip_voucher::
slim ferry
#

and a lot of mods use a food pool

#

so it should be usable

timid zinc
#

That's scary......

normal crest
wind steppe
#

just steal another mod's code for it

red flower
#

or rather it's less patches because you don't need to match to add the ends

normal crest
#

but you need to match to add the goto locations, no?

red flower
#

yeah

timid zinc
#

the original code is left untouched but it would be an issue if another mod patched the same location in a non-goto way which is an improvement

normal crest
#

so it'd be 4 matches in total still

red flower
#

oh yeah that's right

#

i still think it's cleaner

primal robin
#

goto meh

normal crest
#

it might look as cleaner code in the dump i guess

vale grove
#

wait you can shorten context to ctx?

red flower
#

no

#

you can change any argument to any name

normal crest
#

yeah the argument doesn't have to be called context, so you can name it ctx if you want

vale grove
#

hmm i see i see

#

also mr Vanilla remade is this a typo?

wind steppe
#

no

#

well not on vanillaremades part

#

thunk calls it selzer in the code

vale grove
#

oh lol

#

do we know why

#

or is that just

#

something that is a thing now

red flower
#

thunk

#

i added a (sic) to the other typos but i didnt notice that one lol

vale grove
#

oh its no big issue im just looking through food jokers because i need them for smth and i find that typo

timid zinc
# wind steppe just steal another mod's code for it

This is how I do it (Code partially from other mods, obviously):

  j_gros_michel = true,
  j_ice_cream = true,
  j_cavendish = true,
  j_turtle_bean = true,
  j_diet_cola = true,
  j_popcorn = true,
  j_ramen = true,
  j_selzer = true,
  j_egg = true,
}

-- Initialize pool of food jokers if it doesn't exist already, which may be created by other mods.
-- Any joker can add itself to this pool by adding pools = { Food = true } to its code
-- Credits to Cryptid for the idea and Paperback for this code
if not SMODS.ObjectTypes.Food then
  SMODS.ObjectType {
    key = 'Food',
    default = 'j_joker',
    cards = {},
    inject = function(self)
      SMODS.ObjectType.inject(self)
      -- Insert base game food jokers
      for k, _ in pairs(Cracker.vanilla_food) do
        self:inject_card(G.P_CENTERS[k])
      end
    end
  }
end```
normal crest
#

btw the inject function in that code is no longer needed, you can just do cards = copy_table(Cracker.vanilla_food)

timid zinc
#

the = true part is completely unneccessary

normal crest
#

that was cus of an old bug in steamodded

timid zinc
#

what kind of bug would make tables not be made properly if you dont do that

normal crest
timid zinc
#

ah

normal crest
timid zinc
#

so like this:

  j_gros_michel = true,
  j_ice_cream = true,
  j_cavendish = true,
  j_turtle_bean = true,
  j_diet_cola = true,
  j_popcorn = true,
  j_ramen = true,
  j_selzer = true,
  j_egg = true,
}

-- Initialize pool of food jokers if it doesn't exist already, which may be created by other mods.
-- Any joker can add itself to this pool by adding pools = { Food = true } to its code
-- Credits to Cryptid for the idea and Paperback for this code
if not SMODS.ObjectTypes.Food then
    SMODS.ObjectType {
        key = 'Food',
        default = 'j_joker',
        cards = copy_table(Cracker.vanilla_food)
    }
end```
vale zinc
#

Blue Joker uses G.deck.cards to keep track of all cards remaining in deck -- which includes cards in hand. Is there a G.<???> thing that returns all cards except those held in hand, or must I first loop through G.deck.cards and then prune all the cards in G.hand.cards?

slim ferry
vale zinc
#

My bad.

umbral zodiac
#

yea, G.deck is just your deck, there is no trickery in what cards it contains

spiral crown
#

does anyone know if there is a context specifically for leveling up a hand type/poker hand

red flower
timid zinc
#

i have an issue with creating Jokers, if i create a joker using a pool besides Joker (Like object type Food), it doesn't respect challenges that do "All Jokers are [Sticker]"

spiral crown
red flower
red flower
timid zinc
wintry solar
crimson echo
wintry solar
#

the actual version is more helpful when someone asks

crimson echo
wintry solar
#

then your code is wrong

spiral crown
crimson echo
red flower
#

for leveling up a hand you can use the smods one

wintry solar
#

well I don't know what your specific code looks like, but what you were told to do is correct

crimson echo
#

...do you want to look at the code yourself?

dusty fractal
#

how do you format localized description

#

ie loc_txt in a joker

red flower
dusty fractal
#

not what im asking about

#

the localization area in smods wiki is right there, too.

#

i was looking for something in particular but i found it just looking there

red flower
#

ok

dusty fractal
#

now i just need to know how prefixes are appended

brave blade
#

Is add_tag(Tag('tag_' + string.lower(context.card.edition))) the most elegant way to create an edition tag according to context.card's edition or is there a better way?

slim ferry
#

its .. for concatention

red flower
#

also .edition is a table

slim ferry
#

also card.edition is a table

#

yeah

red flower
#

and it won't work for modded editions

slim ferry
#

you probably want context.card.edition.key:gsub("e_", "tag_") instead too

#

i assume thats what youre going for

civic solstice
#

uhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

red flower
#

lmao

slim ferry
#

what

civic solstice
#

i coded a joker to crash the game when bought LOL

brave blade
slim ferry
#

and probably also check if it exists first

brave blade
#

I did that in a separate condition

slim ferry
#

check if the tag exists i mean

brave blade
#

Can I just use Tag(context.card.edition.key:gsub("e_", "tag_")) as a condition?

red flower
#

i dont think so

#

G.P_TAGS[key] might work

obsidian spear
#

wtf is there more than one jimbo? is it from pools? no. cuz there wasnt any before i added a pool i rthink

red flower
#

yes if a pool runs out it uses the default, which is jimbo for vanilla jokers

#

your pool might also use jimbo

lyric maple
#

for some reason my seal localizations don't have locvars???

i'm trying to change gold seals into Filipino Seals (inside joke, long story)
and this code works:

        Other={
            gold_seal = {
                name = "Filipino Seal",
                text = {
                    "Earn {C:money}$3{} when this",
                    "card is played",
                    "and scores",
                },
            },
        },

but this doesn't, as it indexes an empty var:

        Other={
            gold_seal = {
                name = "Filipino Seal",
                text = {
                    "Earn {C:money}$#1#{} when this",
                    "card is played",
                    "and scores",
                },
            },
        },

i thought seals had variables??

red flower
#

are you adding the loc_vars yourself?

lyric maple
#

no

red flower
#

well

#

as you can see there the vanilla one is hardcoded

lyric maple
#

ohhhhhhh

#

say for example if a mod changes that number is there a way to make some sort of internal if/else that gives the hardcoded value if no loc_var is present and the loc_var otherwise

red flower
#

it's easier in that case to just give it a loc_vars but the problem is that if another mod changes the value it will also probably change the localization

#

i personally wouldn't worry about it

lyric maple
#

ah ok then

brave blade
#

Reroll cost is staying the same, did I do something wrong?

#

Nvm, I just set reroll_discount to -2 instead

fluid steppe
#

chat how do you get the localized name of a joker

#

localize('j_joker') isnt working

daring fern
fluid steppe
#

thank you

civic solstice
#

why did my if statement stop if statementing

#

it thinks if is a context when it just isnt

wind steppe
brave blade
normal crest
fluid steppe
#

hii

wind steppe
#

i think if you want debug help you should probably. get rid of the unicode bit for a second

#

hard to see

wind steppe
#

show more of the code also

#

looks like the error is higher up

brave blade
civic solstice
primal robin
#

formatting Trolge

civic solstice
wind steppe
civic solstice
#

it worked before so idk what happened

wind steppe
#

also what is a

obsidian spear
#

a

wind steppe
#

i dont see it defined anywhere

civic solstice
normal crest
#

if the goal is to crash the game then you're doing good

wind steppe
#

should be card.ability.extra.a

normal crest
#

keep it up

civic solstice
#

now that i think about it yeah

wind steppe
#

also that for loop doesnt do anything

#

either one

wind steppe
#

and SMODS.cost is. not a thing

#

and the first for loop will actually crash i think

slim ferry
#

if you want to force the game to crash just do a for i = 1, math.huge or a local function x() x() end; x()

#

Instant stack overflow

wind steppe
#

G = nil

slim ferry
#

Or do {} > 0

civic solstice
# civic solstice

basically what im tryna do since this is supposed to be a joker that makes it seem like it shouldnt exist is to make the price go haywire

wind steppe
willow scroll
#

anybody know why my scoring calculation crashes if i use a planet card?

wind steppe
#

show us the code

willow scroll
#

huh

#

i pasted my code fym

wind steppe
#

huh???

willow scroll
#

again??/

wind steppe
#

third time's the charm

willow scroll
#

they hate me

wind steppe
#

third time was not, in fact, the charm

willow scroll
#

they hate me

#

screensots it is ig fml

civic solstice
#

okay i fixed the majority of the things suggested anyways what tf is happening with my if statement???

willow scroll
civic solstice
willow scroll
civic solstice
#

i needa change the for i loop rq

wind steppe
willow scroll
#

wait no the indents are fucked mb

civic solstice
wind steppe
slim ferry
# willow scroll they hate me

Your message could not be delivered. This is usually because you don't share a server with the recipient or the recipient is only accepting direct messages from friends. You cant see the full list of reasons here

wind steppe
#

remove the fourth end

wind steppe
#

Your message could be delivered. This is usually because you share a server with the recipient or the recipient is accepting direct messages from anyone. You can't see the full list of reasons here

slim ferry
#

They stop when discord works

civic solstice
willow scroll
#

anyhow anybody know why?

#

i have a color right there

#

am i required to define hand level ups for my parameter?

vale grove
#

i have a very unique bug

card.ability.extra.h_size = card.ability.extra.h_size + 1
 G.hand:change_size(card.ability.extra.h_size)

This joker has a way of increasing the hand_size, i want it to go up by ` everytime this happens (asin it happens twice handize goes up by 2 total) however what it does is go +1 everytime the methoc is called (so if i were to do the method twice it would go to 3 total handsize for a third time would but the total handsize at 6 etc) how do i fix this

slim ferry
#

Change size by 1

#

Instead of the h_size value

vale grove
slim ferry
#

G.hand:change_size(1)

#

Instead of what you have now for that

civic solstice
#

oh yeah also idk if this is smth i can fix or not but the game just doesnt process the unicode text properly like at all

slim ferry
#

Thats probably expected

#

Since the game doesnt support every character

civic solstice
#

fair

slim ferry
#

And its fucky unicode shenanigans

civic solstice
#

so i assume no it cant be fixed

vale grove
# slim ferry G.hand:change_size(1)

okay yeah that works but how do i display it in my loc_txt?

card.ability.extra.h_size,
{C:attention}#3#{}

i previously had this display it (accurately despite the value itself being inaccurate) how do i change that?

wind steppe
#

you could try a custom font

#

that would work still

slim ferry
#

Since it increases hand size by the same amount as the actual joker config value increases by now

slim ferry
#

For loc_vars

#

I assume youre already doing that though

vale grove
#

but i dont use extra.h_size anymore

wind steppe
#

what happens when it's removed from deck

slim ferry
#

Dont you use it to get rid of the hand size in remove_from_deck

#

Yeah

wind steppe
#

you should still scale that value for display reasons

vale grove
#

i didnt even test that yet lol

#

gimme a minute

naive agate
#

adding a custom rank and having a card similar to baron with it. the ids for jack and 10 are 11 and 10 and I wanna sandwich this rank's id in between, how can this be done?

civic solstice
#

its telling me it cant index this line here, do i need all of this to make it not do that

river grail
# daring fern Hook `Card:is_suit`

surprisingly there wasnt documentation for this so i was staring at it for like, 30 minutes and now i think i understand what it does
then again i dont know anything about lua

obsidian spear
#

i assume thats how you do it

wind steppe
#

is that meant to be accessing something on the card

#

if so use card.ability

civic solstice
#

oh right

gaunt folio
wind steppe
#

and then is that an integer?

obsidian spear
#

and put it as 11 or wht ever

wind steppe
#

if so you want for i=1, card.ability.extra.repeatThisManyTimes do

civic solstice
#

i did it anyways

gaunt folio
#

It seems like Leon just needs it to identify the rank, changing it to a string even would work like ‘prefix_rank’

obsidian spear
#
SMODS.Rank:take_ownership("[rank]",
  nominal = [the right nominal]
)

you could also do this with tables

local ranks = {
  [1] = {key='king', nominal=new nominal}
}
for _,v in pairs(ranks) do
    SMODS.Rank:take_ownership(v.key,
        nominal = v.nominal
    )
end
#

whoops forgot to reply

naive agate
#

i see

obsidian spear
#

cut down 2 lines per rank is pretty nice

#

it mightnt work thats just what I think would work

gaunt folio
#

Kw We’ll figure it out but will try that just in case (he and I co-develop lmao)

obsidian spear
#

uh can someone just help me quick, it's smth easy and i cant be bothered looking for it

how do i get the seal thats on the card? like key

#

nvm found it

civic solstice
#

i tried reworking the entire list randomization and bro this has to be the most overcomplicated list ever conceived by human hands

#

i mean i think it makes some kinda sense

fluid steppe
#

chat where do i see saved logs

#

balatro's crashing w/o breadcrumbs

civic solstice
red flower
#

Mods/lovely/log

fluid steppe
#

thanks

#

ok it left nothing in the console either

#

fun

obsidian spear
#

please 😢

maiden phoenix
obsidian spear
maiden phoenix
#

self references the card in the seal calculate function iirc

obsidian spear
#

ight

maiden phoenix
#

Never made seals myself so I'm not 100% sure

obsidian spear
#

ah alr

#

@maiden phoenix im in limbo

#

nothing changing

#

wait i forgot to save

maiden phoenix
#

show your code

obsidian spear
#

🐴

maiden phoenix
#

oh

obsidian spear
#

nvm

#

still in limbo

#
calculate = function(self, card, context)
        if context.repetition then
            return {
                repetitions = card.ability.seal.extra.retriggers,
                message = "Melted!",
                func = function()
                    G.E_MANAGER:add_event(Event({
                        trigger = "after",
                        delay = 1,
                        func = function()
                            card.seal = nil
                        end
                    }))
                end
            }
        end
    end,
#

i tried it in different contexts

#

they didnt work before

#

but ig i can try them

#

oh wow wheres the documentation for
context.playing_card_end_of_round

#

🙏

viscid talon
#

this is what i got

#
    key = "wheelbarrow",
    config = { 
        extra = { 
            mult = 8, flippy = 0
        }
    },
    loc_vars = function(self, info_queue, card)
        local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds,
            'vremade_wheelbarrow' .. G.GAME.round_resets.ante)
        return { vars = { numerator, denominator }, card.ability.extra.mult }
    end,
    loc_txt = {
        ['name'] = 'Wheelbarrow',
        ['text'] = {
            [1] = '{C:green}1 in 2{} cards get drawn face down',
            [2] = 'All {C:attention}facedown{} cards give {C:red}+8{} Mult when scored'
        },
        ['unlock'] = {
            [1] = ''
        }
    },
    pos = {
        x = 6,
        y = 3
    },
    display_size = {
        w = 71 * 1, 
        h = 95 * 1
    },
    cost = 4,
    rarity = 2,
    blueprint_compat = true,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = false,
    atlas = 'CustomJokers',
    pools = { ["hatchet_hatchet_jokers"] = true },

    calculate = function(self, blind, context)
        if context.stay_flipped and context.to_area == G.hand and
                SMODS.pseudorandom_probability(blind, 'vremade_wheelbarrow', 1, 2) then
                card.ability.extra.flippy = (card.ability.extra.flippy) + 1
                return {
                    stay_flipped = true
                }
            end
            if context.individual and context.cardarea == G.play then
                if (card.ability.extra.flippy or 0) >= 1 then
                    return {
                        mult = card.ability.extra.mult
                    }
                end
            end
        end
}```
#

for wheelbarrow

#

index global nil value error

obsidian spear
#

stuck in limbo

maiden phoenix
#

Yea idk sorry

obsidian spear
#

prob
SMODS.pseudorandom_probability(blind, 'vremade_wheelbarrow', 1, 2) then
with blind??

#

@viscid talon

#

i think

viscid talon
#

henlo

#

hmm

#

also thats not what it is

#

here is the error

normal crest
#

and you have to change where you used pseudorandom_probability to use card instead of blind

stuck ore
#

Quick question, whats the context.other_card that detects the rank of the card? I want to make a joker gain chips based on the cards rank

normal crest
#

When do you want your joker to gain chips

stuck ore
#

on trigger of the card

normal crest
#

it's context.individual

#

context.individual and context.cardarea == G.play

stuck ore
#

I have that as the overarching if statement but what would i put in place of chips_gain if I want the joker to gain based off of the cards rank?
if context.other_card:is_suit("Clubs") then card:juice_up(1,0.5) card:juice_up(1,0.5) card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chips_gain return { message = "+1", colour = G.C.CHIPS, card = card } end

#

I think I did the lua thing wrong

normal crest
stuck ore
#

That worked a treat thank you

#

I guess follow up question, how do you make a message include a variable? or I guess in this instance just a integer. I know how in other forms of code with f'{variable}' but here I'm confused
return { message = "+context.other_card.base.nominal", colour = G.C.CHIPS, card = card }

normal crest
#

simplest way would be message = "+" .. context.other_card.base.nominal

stuck ore
#

Also just so I understand for future reference, what is .. ? and also if I were to put something after the variable would it be "+" .. context.other_card.base.nominal .. "+"?

wind steppe
#

.. is concatenation

#

so "a" .. "b" becomes "ab"

#

and "a" .. "b" .. "7" becomes "ab7"

stuck ore
#

ah gotcha I understand it now thank you

brave blade
#

Which basically gets this key from the localization table and inserts your variable

normal crest
#

Yeah long term you always wanna use localized stuff

#

But if you're just testing it's fine for now

stuck ore
#

Btw is there a way to make a joker create a message when a card is scored or can it only produce a message from itself (I.E. how do I write card = card to make the message originate from the joker instead)

normal crest
#

message_card = card inside the return table

#

you can change the message to appear on any card like that

stuck ore
#

It seems like when I try that the message appears on the card when it is scored but I was curious if there was a way to make the joker itself create the message when the card is scored?

normal crest
#

it should just be that tho, what is your current code?

stuck ore
#

oh my god

#

I'm a moron

#

Thank you I had just changed the message of something that wasn't trigger so I didn't see the difference

unkempt bronze
#

Has anyone made answerable trivia in Balatro?

small wigeon
#

chat i know this is a rreally silly question but

#

i played modded ONCE and now i cant turn my achivemnts back on..,. how do i do it

#

OOPS

#

WRONG CHAT

#

AAAA

rocky plaza
small wigeon
rocky plaza
small wigeon
#

can i swear

#

can we do that here

rocky plaza
#

swearing is fine here
as long as its not hate speech lmao

small wigeon
#

FUCK!!!!!

rocky plaza
#

mood

small wigeon
#

man wtf am im gonna do

granite jay
#

Hey so I want a separate pop up to indicate when the played hand is set on fire (Like what was done with the black sticker)

#

How do I do this for things that aren't related to things like stickers?

stuck ore
#

whats the ease for discards?

#

nvm its ease_discard

turbid solstice
small wigeon
turbid solstice
#

They are very talented

normal crest
rocky plaza
granite jay
granite jay
normal crest
#

Or am I misunderstanding

granite jay
#

I just use info_queue[info_queue + 1] = blah blah blah

normal crest
#

Oh I did misunderstand

#

in your localization file add a new entry in descriptions.Other.whatever_name

#

just like a joker whatever_name = { name = "something", text = { "line1", "line2" } }

#

and in your joker's loc_vars do info_queue[#info_queue + 1] = { set = "Other", key = "whatever_name" }

granite jay
#
        g_onfire = {
            name = "Hand On Fire",
            text = {
                "Occurs when played hand",
                "scores greater than Blind",
                "score"
            },
        },
    },```
This is in the localisation under descriptions
#

Oh wiat

#

I just realised it isn't in descriptions lmfao

normal crest
#

:D

chrome widget
#

Holy shit im doing it (this probably doesn't look impressive without code)

#

I'm a fucking genius

#

To explain: this credits tab is being generated programmatically, rather than manually
Given some basic information, my loaded items have built a table of credit sections, "Concept", "Artists", and "Programmers", and based on whether or not there are tagged information on items, it sets out the columns as necessary. If I only have artist listed, it's one column, since only the Artists section is valid. With two tags, two columns. With three tags, three columns

#

Now that I have the sectioning and the lists of contributors working, all that remains is adding rows of names with some reasonable scaling based on the number provided

normal crest
#

we're witnessing the ascension of a new ui wizard

chrome widget
#

Let me see if I can get my custom provided data tables working too

stuck ore
#

is there a context.other_card for enhancements? In my instance I'm looking for a way to detect if the card is a wild card

stuck ore
#

I found a work around nvm

chrome widget
#

I AM A FUCKING GENIUS

#

Automatically built from this table

wintry solar
#

That artists logic seems wrong, or is it supposed to automatically fill a dimension if you give it 0?

chrome widget
#

It still fills the dimension if you give it nothing. It's establishing the sections/categories to use for the credit, to which loaded items will add to the contributors table

#

The provided contributors here are for things not easily associated with a single item

#

So you can add an entry directly for a slight bit of manual control for more abstract things (at least I think it would be weirder to create my "direction" table based on putting "direction" tags on some items. Like duh I directed it, I'm the co-creator of the mod)

chrome widget
#

Not 100% certain why this second column is weirdly small

latent perch
#

oh god ui

chrome widget
#

Not just UI. Procedural UI

latent perch
#

no

#

dear god

chrome widget
#

I've made well enough progress today and hopefully I can finish this tomorrow!!!

#

All this was basically because I was sick of doing UI trees for the credits of my mods, so this automates the process

latent perch
#

I need to do some procedural UI too (help)

#

do you perchance know what function(s) change the children's position/size?

chrome widget
#

like in general?

latent perch
#

yup

#

(I'm trying to make a pannable container)

#

(so a container that doesn't align it's children but moves them when panning)

#

(like a map or somethin)

chrome widget
#

At a node level, it'd just be the Moveable:move_xy function I'd think

latent perch
#

mhm mhm taking notes

#

also wth is up with UIBox and UIElement?! a UIBox creates a self.UIRoot which is a UIElement right? why? what for? To what end?

zealous glen
latent perch
zealous glen
latent perch
#

sure!

primal robin
#

Guy basically invented web's display: grid, not bad

zealous glen
# latent perch sure!

Take a look at my Blinds with tooltips on them; I remember adjusting the horizontal offset so the tooltip wouldn’t cover the Blind selection column

zealous glen
#

@latent perch here’s something to look for

latent perch
#

👍🦐

elder rune
#

How do you get the description of a joker

#

I tried card.config.center.text but it didnt work

slim ferry
#

localize{ type = "name_text", key = card.config.center.key, set = card.ability.set}

#

oh wait description

#

uhhhhh

#

just try that but without the type = "name_text" ig

daring fern
elder rune
#

im doing ipairs on it btw

wintry solar
#

What are you trying to do

elder rune
#

+1 mult for every vowel in the description

wintry solar
#

Ewwww
Anyway, you need to use string methods on it instead

elder rune
#

yeah thats why im doing ipairs

#

I changed how I did it and it worked

neon plank
#

anyone know how to check if another modded joker is owned?

#

(i want to make a joker so that you get 10x if another specific joker is owned)

wintry solar
#

next(SMODS.find_card('j_modprefix_key'))

neon plank
#

thanks!

primal robin
#

@wintry solar maybe make sense for SMODS.process_loc_text return value it sets?
Like yk I can manually select it, but why not just add 1 line of code to make life a bit easier?

#

Like because of this missing return I need to do this

#

And if any changes will happen in future for this function, I'll be sad!

umbral spire
#

im tryna give x5 mult when chips and mult are (exactly) equal, this just does nothing?

    calculate = function(self, card, context)
        if context.joker_main then
            if G.GAME.current_round.current_hand.chips == G.GAME.current_round.current_hand.mult then
                return { xmult = 5 }
            end
        end
    end,
umbral spire
daring fern
umbral spire
#

Ah ok

vale grove
#

how do i make a joker retrigger itself?

daring fern
vale grove
daring fern
vale grove
#

alr thank youi\

umbral spire
# daring fern It would be exactly that.

still didn't work, should it not be in an if context.joker_main then?

    calculate = function(self, card, context)
        if context.joker_main then
            if mult == hand_chips then
                return { xmult = 5 }
            end
        end
    end,
#

or is it the way I'm testing?
im using the plasma deck and then just playing a hand, but after the 'balanced' message it doesn't do anything

wintry solar
#

Are you 100% sure they are equal

wintry solar
#

Then its the way you are testing, the balance from plasma happens after joker main

umbral spire
#

oh, then how would I test it.

umbral spire
daring fern
umbral spire
daring fern
umbral spire
#

oh

vale grove
# daring fern `if context.retrigger_joker_check and context.other_card == card then return {re...
    calculate = function(self, card, context)
        if context.setting_blind and not context.blueprint then
            G.E_MANAGER:add_event(Event{func = function()
                (context.blueprint_card or card):juice_up(0.8, 0.8)

                for _, j in ipairs(G.jokers.cards) do
                    if j ~= card and not j.getting_sliced then
                        local key = j.config and j.config.center and j.config.center.key
                        if key then
                             elseif key:find("selzer") then
                                 card.ability.extra.repetitions = card.ability.extra.repetitions + 1
                                j.getting_sliced = true
                                j:start_dissolve({G.C.RED}, nil, 1.6)
                            end
                            
                        end
                    end
                end

                return true
            end})

            return {
                message = "His hunger grows...",
            }
        elseif context.joker_main then
            return {
                mult = card.ability.extra.mult,
                chips = card.ability.extra.chips,
                Xmult = card.ability.extra.Xmult,
            }
        else if context.retrigger_joker_check and context.other_card == card then return {repetitions = card.ability.extra.repetitions} end
        end

i currently have this and idk why it isnt working (the full method has every food joker but its too long for a discord message lol)

daring fern
vale grove
# daring fern Do you have retriggers enabled?
    config = {extra = {mult = 0, chips = 0, dollars = 0, Xmult = 1, h_size = 0, price = 2, repetitions = 0 }},
        return {vars = {card.ability.extra.mult, card.ability.extra.chips, card.ability.extra.h_size, card.ability.extra.dollars, card.ability.extra.Xmult, card.ability.extra.repetitions}}

this is currently all it has lol

#

i know it says zero but destroying the selzer does make the number go up in my loc_txt

slim ferry
#

enabled as in the optional feature for retriggering jokers

vale grove
#

SMODS.current_mod.optional_features = {
retrigger_joker = true,
post_trigger = true,
quantum_enhancements = true,
cardareas = {
discard = true,
deck = true
}
}

#

or well

slim ferry
#

well only retrigger_joker

vale grove
#

only the retrigger joker

#

yeah\

slim ferry
#

yeah

#

you need to just put that somewhere

#

main file is what people usually do

vale grove
#

probably main.lua right

#

yeah

vale grove
#

oh yeah @slim ferry

#

update = function(self, card, dt)
G.SETTINGS.GAMESPEED = 8
end,
remove_from_deck = function(self, card, from_debuff)
G.SETTINGS.GAMESPEED = 4
end

#

this works

#

but sometimes even when i dont have the joke the gamepseed just goes up

slim ferry
#

uh

#

try adding if card.area ~= G.shop_jokers and card.area ~= G.pack_cards to the update

#

so it doesnt trigger when its in the shop or in a booster

vale grove
#

how do you add an ifstatement to something outside of calculate?

#

or do i do it inside of update?

#

inside of update got it

#

it still happend when i hover over it in the collection 😭\

slim ferry
#

eyah

#

oh

#

uhh

#

actually

#

you should check if card:can_calculate()

#

that probably works better

vale grove
#
            update = function(self, card, dt)
         if card:can_calculate() then
            G.SETTINGS.GAMESPEED = 8
            end

so like this right?

slim ferry
#

yeah

#

though idk if it likes running can_calculate every frame but 🤷 youll see ig

vale grove
#

lol

slim ferry
#

if it doesnt like that just make it G.SETTINGS.GAMESPEED ~= 8 and card:can_calculate()

vale grove
#

it still does the game speed up when i hover over it sadly

slim ferry
#

oh

#

fuck idk then

slim ferry
#

uhhh just check for not the collection cardarea

#

idk what that one is tho

vale grove
#

does that even exist?

slim ferry
#

yeah

vale grove
#

also its not even over hovering just seeing it in collection

vale grove
#
            update = function(self, card, dt)
         if card.area ~= G.shop_jokers and card.area ~= G.pack_cards then
            G.SETTINGS.GAMESPEED = 8
            end
            remove_from_deck = function(self, card, from_debuff)
                G.SETTINGS.GAMESPEED = 4
            end
        end
```because this is what the full thing looks like
#

but couldnt i added a check on if its on in deck?

slim ferry
#

actually thats a good idea

#

just set like

#

card.ability.extra.active in add_to_deck or smth

#

and then check that in update

vale grove
#

so instead of update do add_to_deck?

#

wait but then you can just change it cant you?

slim ferry
#

no like

#

keep update

#

just set some value on the joker in add_to_deck

#

and check if that value is set in update

#

so it only does something if the card is in your deck

vale grove
#

ohhh so like

#

in add to deck i add local test = true

#

and then remove from deck local test = false

#

and then in update if local test = true then gamespeed up

slim ferry
#

well you would have to store it in card.ability since local variables dont exist outside of the function where you create them

vale grove
#

wait wdym store it in card.ability?

slim ferry
#

do like

slim ferry
#

and then check that value in update

vale grove
#
            add_to_deck = function(self, card, from_debuff)
                 card.ability.extra.active = true
            end
```so like this?
#

and then set update to if card.ability.extra.active = true then game speed up?

slim ferry
#

yeah

lament agate
#

how would you check if a player played on a certain dec

#

deck

maiden phoenix
lament agate
slim ferry
#

.effect.center.key

lament agate
#

that too?

slim ferry
#

G.GAME.selected_back.effect.center.key

#

is the think

#

thing

#

afaik

lament agate
#

also how would you detect the first joker trigger

bleak shore
#

hi guys , i was wondering why the message didn't show , is it because "add_card" erase it ?

slim ferry
#

you shouldnt return SMODS.add_card regardless

#

also is the joker even triggering at all

bleak shore
#

yup is it triggering , else i wouldn't be here

bleak shore
#

nvm , found the problem

turbid igloo
#

is there a way to check what number you scored??

obtuse silo
#

ok so i need a way to identify the current deck in use

obtuse silo
maiden phoenix
daring fern
obtuse silo
#

oh right

dusty fractal
#

how does card.facing work

slim ferry
#

if card.facing is "back" then the card is face down

#

if its "front" then its face up

fluid steppe
slim ferry
#

do you have "only show commands" turned on in the debugplus settings

fluid steppe
#

lemme check

#

no

dusty fractal
slim ferry
#

it should be

dusty fractal
#

oh hmm it is but its not being read properly

wicked heron
#

Has anyone had any experience adding/removing keys from a joker.config.extra table dynamically during gameplay? I know config doesn't play well with tables sometimes

slim ferry
#

joker config tables should work just fine with tables in them

#

all that doesnt work is storing functions and gameobjects in them

wicked heron
#

ok, g2k, ty

obtuse silo
#

hold on
is there a way to identify when a run has been won?

slim ferry
#

hook win_game

#

is probably the best option

turbid igloo
normal crest
fluid steppe
#

uh one sec

#
        card.ability.ijhpool = {}
        local random_seed = (G.GAME and G.GAME.pseudorandom.seed or "")..G.hypr.ijhpsr
        for i=1,4 do
            local a = 'dgfhkasdgfashf'
            local fl = true
            while fl or where(card.ability.ijhpool,a) do
                fl = false
                random_seed = random_seed..pseudoseed(random_seed)
                a=pseudorandom_element(G.hypr.ijhjokers,pseudoseed(random_seed)).key
            end
            card.ability.ijhpool[i]=a
        end
#

where() is defined dw

#

where(v,t) is a function that returns where v is in a table t, or nil if it's not in there

fluid steppe
#

actually wait

#

hold on

#
function where(t, thing)
    if not t then return end
    for k, v in ipairs(t) do
        if v == thing then
            return k
        end
    end
end
#

i misremembered how my own function works

#

or wait

normal crest
#

Are you trying to pick 4 different jokers from a list of jokers

fluid steppe
#

no that should work

fluid steppe
#

that's what card.ability.ijhpool is

#

it's the keys not the joker prototypes themselves but that should work

normal crest
#

I don't think that code is the source of the crash

#

what is after that?

fluid steppe
#

actually lemme not clog chat

fluid steppe
#

oh uh

#

oh i should prob get rid of dblog()

#

its not doing anything

obtuse silo
slim ferry
#

none

neon plank
#

Can you add another "friends of Jimbo" like skin to the cards if you have the textures for one made?

fluid steppe
neon plank
#

oh shit thanks

normal crest
fluid steppe
#

its fine

normal crest
#

if I had to guess the problem is with the ijhmanage function

fluid steppe
# normal crest if I had to guess the problem is with the ijhmanage function

nnnope

                func = function()
                    if not G.hypr.ijhpsr then G.hypr.ijhpsr = 0 end
                    G.hypr.ijhpsr = G.hypr.ijhpsr + (G.GAME and pseudoseed(G.GAME.pseudorandom.seed) or math.random())
                    local random_seed = (G.GAME and G.GAME.pseudorandom.seed or "")..G.hypr.ijhpsr
                    ijhmanage(card,pseudorandom_element(card.ability.ijhpool))
                    play_sound('tarot2')
                    card:flip()
                    assert(false,'Breakpoint Reached!')
                    return true
                end

this reaches the breakpoint

neon plank
#

how would you destroy a specific card in hand via a joker if context.individual and context.cardarea == G.play function?

#

sorry for all the surface level questions, im quite new to lua 😅

#

also is there a way to make it so that sounds don't increase in pitch with each card played?

gaunt folio
#

I made a custom rank, how do i make this card identify it? (its supposed to be like a baron clone)

umbral spire
#

is there a "register all" function for assets like there is for sounds?

neon plank
#

is there a way to quick refresh a mod in smodded?

#

(dont want to have to reboot every time imakea small change)

chrome widget
neon plank
#

👍

daring fern
neon plank
#

thank you

gaunt folio
#

nvm i got it

neon plank
turbid solstice
#

Is there some type of method or function that can be used to influence a rarities weight in the shop including Legendaries? (Basically, I want a very low chance for legendaries to always be in the shop) I've been trying to find it on my own but can't find any documentation or messages here that helps me.

daring fern
gaunt folio
#

weirdly i did just rank "15" and it worked

#

but that might be a better solution ngl

daring fern
gaunt folio
#

yeah ill fix that

#

k it works thanks

viral steppe
#

Hey! Is there some beginner documentation or templates to help with learning to mod Balatro?

viral steppe
#

Thank you!

distant junco
#

yo would
if card.ability.extra.lines[card.ability.extra.tries][i] ~= (11 or 12 or 13 or 14) then

#

do what i think it would

daring fern
distant junco
#

alright then ill do it the big way then

daring fern
distant junco
#

could you explain what thats doing please

daring fern
distant junco
#

why do they all =1

neon plank
#

how would i destroy a random card from the played hand?

daring fern
neon plank
distant junco
daring fern
distant junco
#

would it

daring fern
distant junco
#

psa: never follow my advice ever

neon plank
#

is SMODS.destroy_cards(pseudorandom_element(full_hand, pseudoseed('sqarefrom128'))) correct?

viscid talon
#

back on my bullshit

#

the wheelbarrow joker gives +8 mult when there are flipped cards present