#💻・modding-dev

1 messages · Page 623 of 1

loud summit
#

wdym

frosty rampart
#

like i don't think there's any distinct difference in loading the file vs having the contents of that file directly in the main file

#

what's your goal

loud summit
#

and i wanted to also make it calculate the pos offset and use it in the object pos's

#

but i dont want it to regen the spritesheets when the game starts (mosty because the raw files are only on my harddrive)

frosty rampart
#

don't put that script somewhere where the mod will automatically load it? or rewrite the way your mod loads files to avoid the script

loud summit
#

oh wait i could just check if SMODS is set right?

frosty rampart
#

oh yea you could do that

loud summit
#

oke wow i was overthinking it :D

weary merlin
#

what would i call to retrieve the number of vouchers currently purchased in a run?

faint yacht
#

#G.vouchers.cards

frosty rampart
#

(note that this is the number of vouchers the player currently owns, which is subtly different from the number of vouchers purchased if there are mods installed that can give you vouchers without directly buying them or make the player lose vouchers. e.g. cryptid does both via the Trade spectral card)

loud summit
#

also for mod wide globals that shouldnt be used outside of it

#

is it ok to add it to SMODS.current_mod.whatever

red flower
#

yes but i think it's better to use your own table so you don't accidentally clash with an smods mod object field

#

also keep in mind those don't get saved

loud summit
faint yacht
young leaf
#

is there any way to do something like midas touch but with an edition?
i tried just replacing m_gold with e_foil but uh
it did some very strange things until it eventually crashed

#

given the fact it turned the sprites into jimbo i want to say the problem is that e_foil only works on jokers
but im not sure how to change that

frosty rampart
#

use set_edition, not set_ability

#

set_ability only works for enhancements, not editions

young leaf
#

ah alright

vagrant raft
#

Yo guys how do i change the texture of one specific joker?

weary merlin
#

what would i use in localization to add the side panel for edition descriptions

weary merlin
tired kestrel
vagrant raft
daring fern
weary merlin
tired kestrel
vagrant raft
final jewel
#
local seal_them = Card:get_seal()
function Card:get_seal()
    local ret = seal_them()
    
    return ret
end
```Is my hook for :get_seal is good
frosty rampart
#

it needs to be local ret = seal_them(self)

#

otherwise yea it's good

final jewel
#

I can't figure out how to make that a certain seal can also be consider as a red seal

tired kestrel
#

I decided to try and see how it would look with other mods as I have yet to make that splash and background as an option yet.

daring fern
frosty rampart
#

oh right i forgot about bypass debuff

final jewel
#

oh

#

ok

frosty rampart
final jewel
#

Oh cause I figured it out with enhancement but I wasnt knowing if it was possible for seal cause get_seal doesnt have an argument tu specify the seal

frosty rampart
#

yea it works with enhancements because smods has a whole quantum enhancements setup

final jewel
#

yeah

stoic void
daring fern
stoic void
#

just noticed lol

#

thx

final jewel
#

Do you think that smods can make a thing that make seal like enhancement like a SMODS.get_seal(card, key) can be very cool

young leaf
fleet reef
#

idk abt the code side but is it conceptually possible to "predict" the next ante's boss blind? since its not technically random

#

like if i wanted a joker that could "predict the future" and see next ante's boss blind, or the next card youre gonna draw or something like that

frosty rampart
#

yes, i know people have made similar things that predict e.g. the contents of a booster pack
and misprint already predicts the next card you're gonna draw

#

also not sure about the code side but there was a conversation about it in here recently

fleet reef
#

alr i can dig, thanks!

final jewel
chrome widget
chrome widget
tired kestrel
chrome widget
#

No I have been indisposed (see: depressive episode). Let me get up and I can look at them today

tired kestrel
daring fern
#

weary merlin
#

would this be used to run upon opening a spectral pack? some of this stuff isn't obvious in the documentation so i have to guess a bit

    calculate = function(self, card, context)
        if context.open_booster and not context.blueprint then
            if card.kind == "Spectral" then
                card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.gain
            end
        end
        if context.joker_main then
            return { vars = { card.ability.extra.Xmult } }
        end
    end,
frosty rampart
#

you're nearly there, but you should be checking if context.card.kind == "Spectral"

#

and you're returning the xmult wrong in the joker_main section, it should be return { xmult = card.ability.extra.Xmult }

fleet reef
chrome widget
frosty rampart
daring fern
weary merlin
#

trying to run an unlock if the player has bought 5 vouchers by ante 4, this crashed my game

    unlocked = false,
    check_for_unlock = function(self, args)
        if args.type == 'round_win' and args.ante < 4 and #G.GAME.used_vouchers >= 5 then
            return true
        end
    end,
daring fern
#

Also it's #G.vouchers.cards

weary merlin
#

attempt to compare nil with number

daring fern
weary merlin
#

on a different joker i'm working on i need an unlock condition for when the player loses against a finisher blind

#

any way to also allow this to pass upon buying a voucher?

    check_for_unlock = function(self, args)
        if args.type == 'round_win' and G.GAME.round_resets.ante < 4 and #G.vouchers.cards >= 5 then
            return true
        end
    end,
#

this is broken too haha

    loc_txt = {
        name = "Voucher Joker",
        text = {
            "Each {C:attention}voucher{}",
            "redeemed this run",
            "gives this Joker",
            "{X:mult,C:white} X#1# {} Mult",
            "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult){}"
        },
        unlock = {
            "Buy {E:1,C:attention}5{E:1,C:attention} Vouchers{} by Ante 4"
        }
    },
    
    config = { extra = { xmult = 0.5 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.xmult, 1 + card.ability.extra.xmult * #G.vouchers.cards } }
    end,

attempt to index field vouchers (a nil value)

frosty rampart
#

you need a nil check for G.vouchers because it might not exist (e.g. if you open the collection on the main menu)

#

if G.vouchers is nil you should set a default value

daring fern
versed swan
#

More of a Lua question than anything, but if I have the following table:

local mu = {1="test", 2="test", 4="test", 5="test"}

And I iterate with for c,str in pairs(mu), will the order be 1 -> 2 -> 4 -> 5?

#

Dangit afk

frosty rampart
frosty rampart
daring fern
#

It would be {[1]="test", [2]="test", [4]="test", [5]="test"}

versed swan
#

I'm asking bc i can't test it rn :( at work

frosty rampart
hardy viper
#

anyways no you won't get a consistent order out of that

#

if you want one make there not be holes or use some sort of default value that isn't nil to fill the holes

#

i mean you May or May Not get a consistent order out of it but writing code that expects a consistent order from that table is incorrect

hardy viper
tepid crow
#

close enough for most usecases in my experience

hardy viper
#

im pretty sure mycompiler uses 5.2 which will have an implementation closer to luajit but still different

hardy viper
versed swan
tepid crow
quasi pike
#

Hi, I'm doing my first mod I don't really understand an error that I'm recieving

hardy viper
#

essentially, pairs boils down to the next function which takes the table and greedily looks for the next value after a specific one (which using pairs the "specific one" is always the last one yielded by the iterator)

the values are always in some order, but since associative arrays are not objectively ordered by their keys the order that key/value pairs are returned by next is completely undefined

quasi pike
hardy viper
#

as far as luajit is concerned, pairs does actually return key/value pairs in order of the key for normal arrays

#

but it could technically return them in any order if it wanted to, like if it decided it would be faster to store the array part in the hashmap part (which it is allowed to do)

#

so you should use ipairs and a holeless array when you need to see things in a consistent order

daring fern
tepid crow
quasi pike
tepid crow
#

yeahhhhh I was hoping I didn't have to 😭

daring fern
# quasi pike like, retrigger

if context.repetition and context.other_card.edition and context.other_card.edition.foil then return {repetitions = 1} end

broken rivet
versed swan
quasi pike
tepid crow
fluid steppe
#

is there a general "when this joker is removed" context

frosty rampart
#

not a context, a separate remove_from_deck function

fluid steppe
#

ah ok

daring fern
fluid steppe
#

what arguments does it have

tepid crow
frosty rampart
quasi pike
fluid steppe
#

oh uh

quasi pike
#

):

fluid steppe
#

you need to do card:juice_up(x,y)

quasi pike
#

inside the return?

fluid steppe
#

no hold on lemme look

tepid crow
quasi pike
quasi pike
tepid crow
#

Don't, use card = card instead

daring fern
quasi pike
#

ohhh

tepid crow
#

or just remove it yeah

quasi pike
#

thx

#

my bad

#

I copypaste too much from the original code

red flower
ocean sinew
#

I'm trying to run a function that resets the player's profile but it doesn't work

#

can someone help me

#

this is the code:

#
local function reset_profile(n)
    n=n or G.SETTINGS.profile
    print("current profile:",n)
    print("profiles:",G.PROFILES)
    love.filesystem.remove(n..'/'..'profile.jkr')
    love.filesystem.remove(n..'/'..'save.jkr')
    love.filesystem.remove(n..'/'..'meta.jkr')
    love.filesystem.remove(n..'/'..'unlock_notify.jkr')
    love.filesystem.remove(n..'')
    local _name = nil
    if G.PROFILES[n].name and G.PROFILES[n].name ~= '' then
        _name = G.PROFILES[n].name
    end
    G.E_MANAGER:clear_queue()
    G.FUNCS.wipe_on()
    G.PROFILES[n] = {}
    G.SAVED_GAME = nil
    G.DISCOVER_TALLIES = nil
    G.PROGRESS = nil
    G.FILE_HANDLER.force = true
    G:load_profile(n)
    G.PROFILES[n].name = _name
    G.FUNCS.wipe_off()
    return n
end
#

it resets the player stats however the cards unlocked and discovered aren't reseted for some reason

versed swan
#

pretty sure this is already a vanilla function (though I cant check rn)

#

I.e. one of the functions that is run when you click the button that resets your profile

ocean sinew
#

It's

#
  G.SAVED_GAME = nil
  G.E_MANAGER:clear_queue()
  G.FUNCS.wipe_on()
  G.E_MANAGER:add_event(Event({
    no_delete = true,
    func = function()
      G:delete_run()
      local _name = nil
      if G.PROFILES[G.focused_profile].name and G.PROFILES[G.focused_profile].name ~= '' then
        _name = G.PROFILES[G.focused_profile].name
      end
      if delete_prof_data then G.PROFILES[G.focused_profile] = {} end
      G.DISCOVER_TALLIES = nil
      G.PROGRESS = nil
      G:load_profile(G.focused_profile)
      G.PROFILES[G.focused_profile].name = _name
      G:init_item_prototypes()
      return true
    end
  }))
#

at button_callbacks.lua
G.FUNCS.load_profile

normal crest
#

what vanilla jokers would look like when made using SMODS

#

better to take those as examples rather than the vanilla code

quasi pike
#

ohh, that's really usefull

quasi pike
#

How do I make a joker that changes the music? I've been searching in the yahimod files because it has a joker that does that, but I couldn't find it

red flower
quasi pike
#

ok thx

weary merlin
#

how can i make the backside of custom jokers reflect modified transparent pixels?

#

i got one voucher-shaped that i need a custom backside for

quasi pike
slim ferry
#

in the sound

#

not the calculate

quasi pike
#

sorry, I only did some pretty basic jokers

faint yacht
slim ferry
#

it just needs to go in there

quasi pike
slim ferry
#

see image above

#

with what N' sent

quasi pike
#

okay, thanks

solid salmon
#

hey guys this is only making tarots, how am i supposed to make it give spectrals

red flower
solid salmon
#

lemme guess

#

swap first with second?

red flower
red flower
red flower
#

idk check out a boolean logic tutorial

solid salmon
#

can i just

#

change this so it can either create tarots or spectrals?

red flower
#

no

#

well yeah actually

#

you would need something like pseudorandom_element({"Tarot", "Spectral"}, "seed") but it's a bit harder if you want it weighted

solid salmon
#

i dont want it weighted

young leaf
#

hi everyone
im attempting to load a custom image in the likes of yahimod (as in i got the code straight from yahimod)
specifically just
when a certain joker activates
it puts an image on screen
so far I havent gotten it to load, but its not crashing so im happy about that
here's the code, if any of you would like to help

            return {
                xmult = card.ability.extra.Xmult
            }
        end
        if context.post_trigger then
            G.macorner = 1
        end
    end,
}


local drawhook = love.draw

function love.draw()
    drawhook()

    local function loadThatImage(fn)
        local full_path = (clo.path .. "customimages/" .. fn)
        local file_data = assert(NFS.newFileData(full_path),("Epic fail"))
        local tempimagedata = assert(love.image.newImageData(file_data),("Epic fail 2"))
        return assert(love.graphics.newImage(tempimagedata),("Epic fail 3"))
    end
    if G.macorner then
        if clo.macorner == nil then 
            clo.macorner = loadThatImage("Macorner.webp") 
        end
        love.graphics.setColor(1, 1, 1, 1) 
        love.graphics.draw(
            clo.macorner,
            200 * _xscale * 2,
            100 * _yscale * 2,
            0,
            _xscale,
            _yscale
        )
    end
end```
red flower
#

but i guess they're the same

young leaf
#

i wasnt able to find anything on the wiki for this
but im sure its out there somewhere

copper perch
#

Is there a way to prevent a type of card enchantment from appearing in standard packs?

red flower
copper perch
#

I made the enchantment

red flower
copper perch
#

Got it, thank you

jovial wave
#

does anyone know an alternative to get_id() which works with custom ranks?

daring fern
slim ferry
#

Card:get_id() == SMODS.Ranks['modprefix_key'].id

#

Iirc

red flower
#

you can also use card.base.value

slim ferry
#

But

#

Rankless

#

And stuff

#

Not good practice i dont think

red flower
#

you can check for has_no_rank

slim ferry
#

I guess

#

get_id hooks do also exist though

red flower
#

and they will not be relevant once quantum ranks come out :3

jovial wave
#

Great thx

obtuse silo
#

can you store a card reference in another card's config?

red flower
#

no(t easily)

#

what do you need to do

obtuse silo
#

basically
a "treasure hunt"
a random card in the deck is assigned as the "treasure"
if that card is scored, give the money and consume the consumable that started this hunt since it hangs about in your consumable slots

obtuse silo
#

i see i see

twilit tundra
#

whats the function for checking whether a card is a consumable again?

#

card:foo()
or whatever

how do i check agian

red flower
#

card.ability.consumeable

copper perch
#

I know I've been here with this card before but I am confused...I'm going for a loyalty card-like joker, where it makes either a Cavendish or a Gros Michel and I'm having troubles resetting my variable cooking_process and it ticking down again. It does it once then stops and I'm unsure why

        if context.joker_main then
            card.ability.extra.cooking_process = (card.ability.extra.every - 1 - (G.GAME.hands_played - card.ability.hands_played_at_create)) % (card.ability.extra.every + 1)
            card.ability.extra.xmult = 1 + ( #SMODS.find_card("j_gros_michel") + #SMODS.find_card("j_cavendish") ) * card.ability.extra.xmult_gain
            if card.ability.extra.xmult > 1  then
                return {
                    xmult = card.ability.extra.xmult
                }
            end
            if not context.blueprint then
                if card.ability.extra.cooking_process == 0 then
                    local eval = function(card) return card.ability.extra.cooking_process == 0 and not G.RESET_JIGGLES end
                    juice_card_until(card, eval, true)
                end
            end
            if card.ability.extra.cooking_process == card.ability.extra.every and not context.blueprint then
                if #G.jokers.cards < G.jokers.config.card_limit then
                    if SMODS.pseudorandom_probability(card, "DRYDina", 1, card.ability.odds, "DRYDina") then
                        SMODS.add_card ( {key = "j_cavendish" } )
                        return {
                            message = 'Potassium.', colour = G.C.YELLOW
                        }
                    else
                        SMODS.add_card ( {key = "j_gros_michel" } )
                        return {
                            message = 'Order up!', colour = G.C.YELLOW
                        }
                    end
                end
            end
        end
arctic spire
#

hi I'm new to balatro moding and I'm trying to make a tarot card play a music when use, but it just crash saying that the delta time is at a "nil" value. can someone help me. the following screen shot about my code has only the "use" function and the path.

umbral zodiac
#

so put [prefix]_ before it, depending on what you pput the prefix of your mod as in the json file

red flower
arctic spire
umbral zodiac
#

if that's what you set the prefix to, then yes

#

you should probably shorten it tbh

#

you use the prefix very often so having a shorter one is a lot more convenient

arctic spire
copper perch
# red flower once you have the food cards it returns for xmult and never does what is below t...

Followup then, why does this one work??

        if context.joker_main then
            card.ability.extra.birdbrain = (card.ability.extra.every - 1 - (G.GAME.hands_played - card.ability.hands_played_at_create)) % (card.ability.extra.every + 1)
            if not context.blueprint then
                if card.ability.extra.birdbrain == 0 then
                    local eval = function(card) return card.ability.extra.birdbrain == 0 and not G.RESET_JIGGLES end
                    juice_card_until(card, eval, true)
                end
            end
            if card.ability.extra.birdbrain == card.ability.extra.every then
                return {
                    chips = card.ability.extra.chips
                }
            end
        end
frosty rampart
#

because that return is at the end of the block
it can do the rest of that code you just pasted because it comes before the return

copper perch
#

okayy, so I need to put my return at the bottom of the other one and it should work...?

red flower
#

no because the other conditions also return

#

you need to either combine the returns or change the logic a bit

#

personally i would create the jokers in context.before and only apply the xmult in joker_main

copper perch
#

How does context.before work? Never had to use that one so I'm clueless

red flower
#

basically the same way joker_main does but it happens earlier

frosty rampart
#

timing-wise it happens at the same time as when space joker levels up the played hand

copper perch
#

okay

arctic spire
daring fern
arctic spire
copper perch
# red flower personally i would create the jokers in context.before and only apply the xmult ...

Correct me if I did something wrong but something like this?

        if context.joker_main then
            card.ability.extra.cooking_process = (card.ability.extra.every - 1 - (G.GAME.hands_played - card.ability.hands_played_at_create)) % (card.ability.extra.every + 1)
            card.ability.extra.xmult = 1 + ( #SMODS.find_card("j_gros_michel") + #SMODS.find_card("j_cavendish") ) * card.ability.extra.xmult_gain
            if card.ability.extra.xmult > 1  then
                return {
                    xmult = card.ability.extra.xmult
                }
            end
            if not context.blueprint then
                if card.ability.extra.cooking_process == 0 then
                    local eval = function(card) return card.ability.extra.cooking_process == 0 and not G.RESET_JIGGLES end
                    juice_card_until(card, eval, true)
                end
            end
        end
        if context.before then
            if card.ability.extra.cooking_process == card.ability.extra.every and not context.blueprint then
                if #G.jokers.cards < G.jokers.config.card_limit then
                    if SMODS.pseudorandom_probability(card, "DRYDina", 1, card.ability.odds, "DRYDina") then
                        SMODS.add_card ( {key = "j_cavendish" } )
                        return {
                            message = 'Potassium.', colour = G.C.YELLOW
                        }
                    else
                        SMODS.add_card ( {key = "j_gros_michel" } )
                        return {
                            message = 'Order up!', colour = G.C.YELLOW
                        }
                    end
                end
            end
        end
daring fern
arctic spire
obtuse silo
red flower
#

lua indexing starts at 1 btw

red flower
daring fern
copper perch
# red flower only ```lua card.ability.extra.xmult = 1 + ( #SMODS.find_card("j_gros_michel") +...

Sorry I keep asking, but this then?

if context.joker_main then
            card.ability.extra.xmult = 1 + ( #SMODS.find_card("j_gros_michel") + #SMODS.find_card("j_cavendish") ) * card.ability.extra.xmult_gain
            if card.ability.extra.xmult > 1  then
                return {
                    xmult = card.ability.extra.xmult
                }
            end
        end
        if context.before then
            card.ability.extra.cooking_process = (card.ability.extra.every - 1 - (G.GAME.hands_played - card.ability.hands_played_at_create)) % (card.ability.extra.every + 1)
            if not context.blueprint then
                if card.ability.extra.cooking_process == 0 then
                    local eval = function(card) return card.ability.extra.cooking_process == 0 and not G.RESET_JIGGLES end
                    juice_card_until(card, eval, true)
                end
            end
            if card.ability.extra.cooking_process == card.ability.extra.every and not context.blueprint then
                if #G.jokers.cards < G.jokers.config.card_limit then
                    if SMODS.pseudorandom_probability(card, "DRYDina", 1, card.ability.odds, "DRYDina") then
                        SMODS.add_card ( {key = "j_cavendish" } )
                        return {
                            message = 'Potassium.', colour = G.C.YELLOW
                        }
                    else
                        SMODS.add_card ( {key = "j_gros_michel" } )
                        return {
                            message = 'Order up!', colour = G.C.YELLOW
                        }
                    end
                end
            end
        end
red flower
#

yeah

copper perch
#

alright, I'll run a test

#

Perfect, you honestly fixed 2 problems in 1 so thank you :D

obtuse silo
young leaf
#

is balatro just like
not allowed to work in quarters
i want to do X1.25 mult but it always rounds up to X1.5

red flower
#

no it can

young leaf
#

then how would i do it D:

red flower
#

like you would do 1.5

#

idk what the error is if you don't show me code

young leaf
#
   calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play and context.other_card:is_face() then
            return {
                xmult = card.ability.extra.Xmult
            }
        end
    end
}```
red flower
#

that seems fine
are you restarting the run

young leaf
#

yep

#

i have had this problem with most things i try to do quarters with
like i had a legendary that gained a quarter of a cards sell value in XMult
but it always did half instead

red flower
#

i think your lua interpreter is cursed

wintry solar
#

What’s your mod list?

young leaf
#

i have debugplus and lovely
and my mod i guess
thats it

wintry solar
#

Weird

tranquil gull
#
[[patches]]
[patches.pattern]
target = '=[Cryptid "lib/overrides.lua"]'
pattern = "function calculate_reroll_cost(skip_increment)"
position = "after"

is this how you would do this

red flower
#

=[SMODS Cryptid

tranquil gull
#

i seeee

red flower
#

(also if you're doing a patch after the first line of a function it might be a better job for a hook)

tranquil gull
#

i mean true but

balmy spire
#

ive been working on my own mod and i have no prior coding experience other than this mod 😭 and this is the code for my joker (Medusa: On final hand of round, turn all scoring cards to stone. For every stone card scored, this joker gains x0.2 mult)

#

a notable issue i have is that the first card changes, yet it doesn't give chips as a stone, but will trigger the upgrade as if being triggered as a stone

red flower
copper perch
#

Are there versions of G.GAME.hands_played and card.ability.hands_played_at_create that can apply to blinds played?

red flower
#

G.GAME.hands_played is a global

#

for the other one there isn't afaik

#

you would need to count them manually

copper perch
#

Ah, I see

twilit tundra
#

is there a function to add an extra card to a booster pack?

red flower
faint yacht
#

And G.GAME.modifiers.booster_choice_mod for more choices.

twilit tundra
#

i want it to happen after the booster is opened though

#

not before

red flower
#

then no

twilit tundra
#

because its something you can trigger inside of one

red flower
#

you can probably add to the cardarea but idk if that handles everything

twilit tundra
#

im able to edit G.GAME.pack_size , but modifying G.GAME.pack_choices doesnt do anything :(

faint yacht
#

...I mean, technically, adding to the G.pack_cards is possible...

twilit tundra
#

wait other way around

twilit tundra
faint yacht
#

Just that you won't be respecting the pool of the pack itself by default.

red flower
#

yeah you would need to add to that area using the booster's create_card if you want it to be part of the pack

red flower
twilit tundra
red flower
#

context.card.config.center:create_card()

#

but idk if it works for vanilla cards

#

boosters*

#

probably not

#

oh but smods takes ownership so maybe

twilit tundra
#

isnt doing anything in vanilla or modded boosters

#

would i also need to add whatever it returns to G.pack_cards

daring fern
twilit tundra
#

is Card supposed to be capitalized in :is(Card)

#

whats that even

balmy spire
#

i fix tomorrow

copper perch
#

Know I kinda asked this earlier but how would I be able to subtract 1 from every for every blind played and not every hand played? Know hands played is a global but I would need to keep track of blinds.
card.ability.extra.cooking_process = (card.ability.extra.every - 1 - (G.GAME.hands_played - card.ability.hands_played_at_create)) % (card.ability.extra.every + 1)

twilit tundra
#

<@&1133519078540185692>

lament agate
#

im still confused with this

#

can you elaborate

daring fern
# lament agate can you elaborate
return {
    descriptions = {
        Back={},
        Blind={},
        Edition={},
        Enhanced={},
        Joker={},
        Other={},
        Planet={},
        Spectral={},
        Stake={},
        Tag={},
        Tarot={},
        Voucher={},
    },
    misc = {
        achievement_descriptions={},
        achievement_names={},
        blind_states={},
        challenge_names={},
        collabs={},
        dictionary={
            b_consumabletypekeywithoutmodprefix_cards = 'Consumable Cards'
        },
        high_scores={},
        labels={},
        poker_hand_descriptions={},
        poker_hands={},
        quips={},
        ranks={},
        suits_plural={},
        suits_singular={},
        tutorial={},
        v_dictionary={},
        v_text={},
    },
}
lament agate
#

thanks

lament agate
frosty rampart
#

what is this exactly, i'm not up to speed on what you're trying to do here

lament agate
#

idk if you can see ut

#

but it says errir

frosty rampart
#

ah ok

#

gimme a sec to reference my mod

daring fern
frosty rampart
#

yea that should be it
for a second i was gonna say you do need the mod prefix but i have prefix_config set to true in my consumable type lmao

lament agate
#

in dictionary too?

daring fern
lament agate
#

thanks

copper perch
#

Sorry for so many questions tonight, I took a break from coding my mod and everything is slipping lol
With that said, how would I go about changing the variable clove_xmult every hand played and it not changing every time I hover over the card? I want it to be able to display what xmult it currently is too in the description of the card. I have that now, it just changes whenever I hover over it

loc_vars = function(self, info_queue, card)
        card.ability.extra.clove_xmult = pseudorandom('DRY_Clove', card.ability.extra.min, card.ability.extra.max)
        return {
            vars = {
               card.ability.extra.clove_xmult
            }
        }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                xmult = card.ability.extra.clove_xmult
            }
        end
    end
daring fern
copper perch
#

And I'd still be able to return that into my Joker's description, even if it returns in context.before?

copper perch
#

Alright, thank you

copper perch
# daring fern Yes.

Its returning a nil at the moment

calculate = function(self, card, context)
        if context.before then
            card.ability.extra.clove_xmult = pseudorandom('DRY_Clove', card.ability.extra.min, card.ability.extra.max)
            return {
                vars = {
                       card.ability.extra.clove_xmult
                }
               }
        end
        if context.joker_main then
            return {
                xmult = card.ability.extra.clove_xmult
            }
        end
    end
daring fern
copper perch
# daring fern Remove the `return {vars = {}}` also you need to set `clove_xmult` be something ...

So this?

    config = {
        extra = {
            clove_xmult = 1,
            max = 10,
            min = 1
        }
    },
    rarity = 2,
    blueprint_compat = true,
    eternal_compat = true,
    atlas = "DRY_Jokers",
    pos = { x = 8, y = 0 },
    cost = 5,
    calculate = function(self, card, context)
        if context.before then
            card.ability.extra.clove_xmult = pseudorandom('DRY_Clove', card.ability.extra.min, card.ability.extra.max)
        end
        if context.joker_main then
            return {
                xmult = card.ability.extra.clove_xmult
            }
        end
    end
copper perch
#

Still nil

lament agate
#

how do you apply hologram shader to a card

daring fern
copper perch
#

or would I just have to settle that 1st call won't be random but every one after will?

lament agate
#

it doesnt seem to be missing anything

daring fern
lament agate
lament agate
daring fern
lament agate
# daring fern Code?
use = function(self, card, area, copier)
    for i = 1, card.ability.extra.count do
        G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.4,
            func = function()
                play_sound('timpani')
                card:juice_up(0.3, 0.5)

                local types = {
                    function() SMODS.add_card({ set = 'Joker' }) end,
                    function() SMODS.add_card({ set = 'Tarot' }) end,
                    function() SMODS.add_card({ set = 'Planet' }) end,
                    function() SMODS.add_card({ set = 'Spectral' }) end,
                    function() SMODS.add_card({ set = 'Standard' }) end
                }
                local choice = pseudorandom_element(types, 'everything')
                choice()
                return true
            end
        }))
    end
    delay(0.6)
end,
can_use = function(self, card)
    return true
end
lament agate
#

shit

lament agate
daring fern
daring fern
obsidian spear
#

how would one make it so that when a joker scores, if whats returned is just a number with no index that it'll use a variable in the joker?

#

patching obviously

#

where would the file for scoring of jokers be

ashen drift
#

what

#

can you elaborate

obsidian spear
#

specifically from jokers

ashen drift
#

no the first part

#

what do you mean whats returned

#

in the calculate function?

#

which returns a number instead of a table?

#

am i reading it right

obsidian spear
#

I want to be instead of

return {
  mult = 4
}```
to be

```lua
  -- In the joker
  scoring = "mult"


  -- later
return {
  4
}
#

unless you can return a variable name instead

frosty rampart
#
scoring = "mult"
-- ... later in the joker ...
local ret = {}
ret[scoring] = 4
return ret

you have to construct the return table a bit more tediously, but in exchange, you can change scoring to chips or dollars or whatever

ashen drift
#

cant you do return {[card.ability.extra.scoring] = 4}

hybrid iris
#

just armchair coding here but i think if i understand it correctly you could do
[scoring] = 4

frosty rampart
#

yea now that i think about it you can do the bracket stuff inside the table itself fine lol
my bad

ashen drift
#

bro went straight to patching 💔

copper perch
#

Making a Joker that has a chance to retrigger specifically only steel cards, yet it does not seem to be working (or I'm extremely unlucky with my 1/2's)

loc_vars = function(self, info_queue, card)
        local probabilities_normal, odds = SMODS.get_probability_vars(card, 1, card.ability.odds, "Sithe")
        return { vars = { probabilities_normal, odds, card.ability.retriggers } }
    end,
    calculate = function(self, card, context)
        if context.repetition and context.cardarea == G.hand and SMODS.has_enhancement(card, 'm_steel') then
            if SMODS.pseudorandom_probability(card, "Sithe_steel_retrigger", 1, card.ability.odds, "Sithe_steel_retrigger") then
                return {
                    repetitions = card.ability.extra.repetitions,
                    retriggers = card.ability.retriggers + 1
                }
            end
        end
    end
daring fern
copper perch
daring fern
lament agate
#

but do you have any idea on how to apply the hologram shader into a card

copper perch
frosty rampart
#

you aren't actually incrementing retriggers

daring fern
frosty rampart
lament agate
copper perch
daring fern
frosty rampart
#

outside of the return, right above it, just put card.ability.retriggers = card.ability.retriggers + 1 (assuming that you actually put retriggers just directly in the config table and not in the extra table)

daring fern
lament agate
obsidian spear
#

okay so what's wrong here?

calculate code

        -- earlier
        local scoring = G.tlj.WeightRnd(G.tlj.scoring)
        print("Num ",scoring)
        scoring = G.tlj.scoring[scoring]["r"]
        print("scoring", scoring)
        
            -- loc txt
        loc_txt = {
            name = G.tlj.adj[math.random(1, #G.tlj.adj)].. " ".. G.tlj.animals[math.random(1, #G.tlj.animals)],
            -- good enough for now ^^
            
            text = string.sub(scoring,0,1) ~= "x" and "{C:"..scoring.."}+5{} ".. scoring or "{X:"..scoring..",C:white}+5{} ".. scoring
        },
        
        -- calc (short for calculator)
        calculate = function(self, card ,context)
            if context.joker_main then
                return {
                   [scoring] = 5
                }
            end
        end
#

ignore name of the loc_txt sinceits irrelevant

daring fern
obsidian spear
#

ihml

#

i was too locked in on one thing

#

okay different problem, scoring = G.tlj.scoring[scoring]["r"] can sometimes return nil?

#
G.tlj.scoring = {
    {r="chips",w=2},
    {r="xchips",w=0.1},
    {r="mult",w=2},
    {r="xmult",w=0.5},
    {r="dollars",w=1},
}```
scoring table
#
G.tlj.WeightRnd = function(weightTable) -- wightedTable will have a table of tables that have values and weights
    local totalWeight = 0
    
    for _, weight in pairs(weightTable) do
        totalWeight = totalWeight + weight.w
    end
    
    local Random = math.random(1, totalWeight)
    local currentWeight = 0
    
    for item, weightData in pairs(weightTable) do
        currentWeight = currentWeight + weightData.w
        if Random <= currentWeight then
            if item then
                return item
            else return G.tlj.WeightRnd(weightTable)
            end
        end
    end
end

weighted random

#

INFO - [G] oh shit | failed to load Scripts/JokerGenerator.lua | Reason: [SMODS TooLilJkrs "Scripts/JokerGenerator.lua"]:33: attempt to index a nil value

#

does the lua version balatro use old and cant return functions

#

there should be no reason for it being nil, i've checked the prints, and aparently item is nil 🤷‍♂️

#

after the G.tlj.scoring[scoring] line?

#

since G.tlj.WeightRnd returns a number

#

which is the index

daring fern
obsidian spear
#

INFO - [G] Num 3
INFO - [G] scoring mult
INFO - [G] AAAA | made number 1
INFO - [G] Num 5
INFO - [G] scoring dollars
INFO - [G] AAAA | made number 2
INFO - [G] Num 3
INFO - [G] scoring mult
INFO - [G] AAAA | made number 3
INFO - [G] Num 3
INFO - [G] scoring mult
INFO - [G] AAAA | made number 4
INFO - [G] Num nil
INFO - [G] oh shit | failed to load Scripts/JokerGenerator.lua | Reason: [SMODS TooLilJkrs "Scripts/JokerGenerator.lua"]:33: attempt to index a nil value

#

aaaa is printed at the end of creation

#

    local scoring = G.tlj.WeightRnd(G.tlj.scoring)
    print("Num ",scoring)
    scoring = G.tlj.scoring[scoring]["r"]
    print("scoring", scoring)

line that prints

daring fern
obsidian spear
#

oh okay!

#

seems to work

copper perch
#

How would I change the xmult of steel cards with a joker? I have a variable with the new xmult but unsure what to do with it

daring fern
copper perch
#

yes

fluid steppe
#

me when i'm bored but don't want to work on my mod so i code an entire solitaire variant minigame for the debugplus console

lament agate
#

is it possible to make info_queue contains dynatext

fluid steppe
#

i'm 63% sure you have to go a step above info_queue and use whatever it uses

#

but again thats only 63% sure that's barely passing i'm not very confident in that statement

lament agate
#

its nothing crazy

fluid steppe
#

this is outside of what i know how to do

#

sry

obtuse wraith
lament agate
#

i see

chrome widget
#

(actually I'm pretty certain N' was the one who did this)

These patches, to enable main_start nodes in edition loc_vars:
https://github.com/BarrierTrio/Cardsauce/blob/main/lovely/corrupted_display.toml

And this code:
https://github.com/BarrierTrio/Cardsauce/blob/main/items/editions/corrupted.lua

GitHub

A Balatro mod made for Vinesauce! Contribute to BarrierTrio/Cardsauce development by creating an account on GitHub.

GitHub

A Balatro mod made for Vinesauce! Contribute to BarrierTrio/Cardsauce development by creating an account on GitHub.

sweet nimbus
#

Is there anyway to dynamically update ante_scaling mid run?

daring fern
#

You modify G.GAME.starting_params.ante_scaling

daring fern
#

copper perch
#

How would I make a card jiggle like invisible when its 2 rounds are done? I'm assuming its juice_card_until but I'm unsure

copper perch
#

Alright, thanks

#

No I just need to figure out how to place a joker after one is sold...once again kinda like Invis but its a determined Joker

#

currently have

remove_from_deck = function(self, card, from_debuff)
        if card.ability.extra.retriggers >= 13 then
            SMODS.add_card ( {key = "j_DRY_Sithe_NEO" } )
        end
    end,

but returns a nil every time

daring fern
copper perch
#

Thanks again :)

#

Okay, 1 final issue it seems. My counter here is a bit wonkey. It retriggered cards 3 times, yet its at 6
card.ability.retriggers = card.ability.retriggers + 1

copper perch
#
loc_vars = function(self, info_queue, card)
        local probabilities_normal, odds = SMODS.get_probability_vars(card, 1, card.ability.odds, "Sithe")
        return { vars = { probabilities_normal, odds, card.ability.retriggers } }
    end,
    calculate = function(self, card, context)
        if context.repetition and context.cardarea == G.hand and SMODS.has_enhancement(context.other_card, 'm_steel') then
            if SMODS.pseudorandom_probability(card, "Sithe_steel_retrigger", 1, card.ability.odds, "Sithe_steel_retrigger") then
                card.ability.retriggers = card.ability.retriggers + 1
                return {
                    repetitions = card.ability.extra.repetitions,
                }
            end
        end
        if context.joker_main and not context.blueprint then
            if card.ability.retriggers >= 13 then
                local eval = function(card) return not card.REMOVED end
                juice_card_until(card, eval, true)
            end
        end
        if context.selling_self then
            if card.ability.retriggers >= 13 then
                SMODS.add_card ( {key = "j_DRY_Sithe_NEO" } )
            end
        end
    end
#

The variable retriggers starts at 0, if that means anything

daring fern
copper perch
#

how would I go about that (sorry I'm so clueless)

copper perch
lament agate
#

thanks alot

#

girl*

#

FUCK

lament agate
#
calculate = function(self, card, context)
    if context.retrigger_joker_check and not card.ability.triggered then
        card.ability.triggered = true
        return {
            repetitions = card.ability.extra.repetitions
        }
    end
    if context.end_of_round then 
        card.ability.triggered = nil end
end
#

any idea why this doesnt work

balmy spire
lament agate
balmy spire
#

the idea of a misprint tarot card in general would be pretty cool\

lament agate
balmy spire
lament agate
balmy spire
#

it could have the meta data of a random consumable

#

then it changes every use

lament agate
#

since i was also thinking about that right

#

and code wise holy shit, its gonna be complicated

lament agate
obsidian spear
#

and eval card.ability.triggered if possible

obsidian spear
#

print?

lament agate
#

yes

#

i forgo

obsidian spear
#

before the if statement (yea with debugplus ur screen is filled) but its important to see if it exists

#

print("String" or smth that can be a string)

#

nil and true and false can be made strings by print

#

if you wanna print a table do tprint() its a balatro only thing tho

obsidian spear
#

calculate goes every time smth happens, so like constantly, enter a shop calculate play hand calculate card counted calculate

bold gyro
#

hey y'all, when attaching an attention text or uibox to major (eg. major = G.ROOM_ATTACH), where within the table is its position stored?

obsidian spear
#

you should like do

calculate = function(self, card, context)
    print(context.retrigger_joker_check, not card.ability.triggered) -- So then the prints will have a bunch of nil, but one has to be true eventually, and not blah blah is so we can see if thats the problem
    if context.retrigger_joker_check and not card.ability.triggered then
        card.ability.triggered = true
        return {
            repetitions = card.ability.extra.repetitions
        }
    end
    if context.end_of_round then 
        print("reset triggered on ", card.label)
        card.ability.triggered = nil 
    end
end

you should find the way cards have their name since im just smth chair coding

#

cant remeber the word

#

armchair*

#

i personally (since i cant read alot) put alot of comments so i can under stand what im looking at

lament agate
#

might be just me but whenever i see a code filled with a bunch of comments i just think of AI writing it

#

probably because they scraped all documentations on the internet

obsidian spear
#

true

#

i just cant read so i require it 😭

#

i'll kinda black out, go back read my code and like

#

vomit or smth idk

#

and i've made several 300 line scripts that work (ish)

#

so i constantly think im making bad not neat code

#

@lament agate lmk what the prints are, ima be a minute brb

obsidian spear
#

when you play it does it ever go true

#

like true true

lament agate
obsidian spear
#

what a name, uuh

lament agate
obsidian spear
#

odd

#

oh, in if context.end_of_round then add in and card.ability.triggered

#

but uhh

#

that means that retrigger_joker_check doesnt exist

#

where did you get this from?

lament agate
#

ruby

#

i swear that context existed

obsidian spear
#

from specifically cryptid?

lament agate
#

from new smods

obsidian spear
#

i have a funny feeling thats added by cryptidlib

obsidian spear
lament agate
#

1016c

obsidian spear
#

maybe download from src

#

the big blue code button since that one is on like 1118a

#

but is buggy*

lament agate
#

im asking ruby hold on

obsidian spear
#

ruby's definitely far above me in balatro coding

lament agate
obsidian spear
#

rip

lament agate
#

but if it wasnt valid

#

it will have yellow line

obsidian spear
#

thats

#

no?

lament agate
#

wait shit

obsidian spear
#

you have lua installed. not smods/balatro

#

so it'll flag it

#

since its a slightly changed lua

lament agate
#

i also have balatro and smods in my workspace

obsidian spear
#

needs to be an extension that manages lua

lament agate
#

fair enough

#

hold on

#

@daring fern does context.retrigger_joker_check exists?

obsidian spear
#

wait

obsidian spear
#

let me check cryptid for it

#

it does!?

#

what?!

lament agate
#

it does 😭

#

see

#

idk why it isnt working

#

do i need to turn on optional settings?

obsidian spear
#

im still checking cryptid so i can see how its used

#

maybe

lament agate
#

like how quantum enhancement and stuff

obsidian spear
#

it does need to be enabled

#

OMG THE FUCKIN THING I NEEDED RETRIGGER_JOKER WAS IN BASE SANFGHBAERY HNUFIJHUGGJWEGSF

#

I spent 2 days looking how to add it

#

asking everyone

#

and no one said that

lament agate
#

😭

obsidian spear
#

so annoying

lament agate
#

alright hold on

obsidian spear
#

i gotta make a joker now

#

wait

#

no

#

nonono

#

yes?

#

no.

lament agate
obsidian spear
#

just do table

#

they're just two dif versions

#

so top one is easier

lament agate
#

i see

#

god please

red flower
#

this is for not reading the vremade wiki smh

lament agate
#

WELL

#

actually you know what

#

valid

lament agate
#

it works btw

daring fern
#

hardy viper
#

fine ill solve your riddles

#

3:

calculate = function(s, c, ctx)
   if ctx.post_trigger and ctx.other_context.joker_main then
       SMODS.calculate_effect(ctx.other_ret, ctx.other_card)
   end
end
daring fern
hardy viper
daring fern
hardy viper
#

im struggling to figure out how that's different from a normal retrigger

#

oh i see

subtle storm
#

Hello, i'm having issue with my joker, that when you sell a showman, the joker gain +1 xmult but i can't get it to work, can sombody help me please?

 sell_joker = function(self, card, context)

        if context.card and context.card.ability.name == "Showman" then
            if not context.blueprint then
                card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.x_mult_mod

                return {
                    card = card,
                    message = localize('k_upgrade_ex'),
                    colour = G.C.RED
                }
            end
        end
    end,
    calculate = function(self, card, context)
        if not (context.individual or context.repetition) and context.other_joker and context.other_joker.ability.name == "Showman" and self ~= context.other_joker then
            shakecard(context.other_joker)
            return {
                message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}},
                colour = G.C.RED,
                x_mult = card.ability.extra.x_mult
            }
        end
    end,

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

}
twilit tundra
#

want to make an erosion-like that gives discards based on cards in deck instead of mult

what context do i use to get it to live-update when cards are added or removed?
the loc works of course, but

what the hell do i put in the calculate i got no clue its completely empty rn 😭

daring fern
twilit tundra
#

ty

daring fern
#

Also sell_joker doesn't exist.

subtle storm
subtle storm
#

thanks!

subtle storm
#

And is there something wrong with my en-us.lua localization file? cause it doesn't shows the description of my joker, (Sorry i'm asking a lot of questions)

return {
    descriptions = {
        joker = {
            j_tsmc_theshow = {
                name = "The Show",
                text = {
                    {
                        "Each Showman gives {X:mult,C:white} X#{x_mult}# {} Mult.",
                        "When another Showman Joker is {C:attention}sold{}",
                        "incrases by x1",
                        "{C:inactive}(Currently {C:x_mult}+#1#{C:inactive} x Mult)",
                    }
                },
            }
        }
    },
    misc = {   
        -- do note that when using messages such as: 
        -- message = localize{type='variable',key='a_xmult',vars={current_xmult}},
        -- that the key 'a_xmult' will use provided values from vars={} in that order to replace #1#, #2# etc... in the localization file. 
        dictionary = {
            a_chips="+#1#",
            a_chips_minus="-#1#",
            a_hands="+#1# Hands",
            a_handsize="+#1# Hand Size",
            a_handsize_minus="-#1# Hand Size",
            a_mult="+#1# Mult",
            a_mult_minus="-#1# Mult",
            a_remaining="#1# Remaining",
            a_sold_tally="#1#/#2# Sold",
            a_xmult="X#1# Mult",
            a_xmult_minus="-X#1# Mult",
        }
    }
}
subtle storm
#

Thanks you!

umbral spire
#

i have this config thingy for my mod which changes what is displayed on some stickers, but how do i reload it without having to restart the game to apply the effects, is that possible?

like i have this in every joker that has the sticker:

    set_ability = function(self, card, initial)
        SMODS.Stickers.flags_stats_afghanistan:apply(card, true) 
    end,  
#

and then in my localization file

#

i have flags_stats_afghanistan = make_flag_stats('Afghanistan'),

#

and there's this function above the return {...} in the localization file:

local function make_flag_stats(country)
    local additional = {}
    if FLGTRO.config.show_hidden_stats then 
        additional[#additional+1] = 'Intentional Homicides {C:inactive}(per 100K people){}: {C:attention}' .. data[country][data_keys.homicides] .. '{}'
    end
    if FLGTRO.config.show_other_gdp_stats then 
        additional[#additional+1] = 'GDP per capita: {C:attention}' .. data[country][data_keys.gdp_per_capita] .. '{}'
        additional[#additional+1] = 'GDP growth {C:inactive}(annual %){}: {C:attention}' .. data[country][data_keys.gdp_growth] .. '{}'
    end   
    if FLGTRO.config.show_all_stats then 
        table.insert(additional, 'Access to electricity {C:inactive}(population %){}: {C:attention}' .. data[country][data_keys.electricity_access] .. '{}')
        [[minimized]]      
       
    local text = {
        'Population: {C:attention}' .. data[country][data_keys.population] .. '{}',
        'GDP {C:inactive}(US$){}: {C:attention}' .. data[country][data_keys.gdp] .. '{}',
        'Inflation {C:inactive}(annual %){}: {C:attention}' .. data[country][data_keys.inflation] .. '{}',
        'Forest area {C:inactive,s:0.9}(% of land area){}: {C:attention}' .. data[country][data_keys.forest_area] .. '{}',
        'CO2 Emission: {C:attention}' .. data[country][data_keys.co2] .. '{}',
    }
    
    for _, v in ipairs(additional) do 
        text[#text + 1] = v
    end 
    return {
        name = country,
        text = text
    } 
end 
primal robin
#

wtf is this an enconomy simulator in balatro

umbral spire
delicate pivot
#

I'd figure I try to ask something again here. Does the Texture Pack mod called Malverk allow you to change the textures for the playing cards? Like the cards in your hand? I am making a texture pack and I don't know if you can change them or not. If it is not possible, is there a way to do this differently?

delicate pivot
tepid crow
#

No, that's done using deckskins

red flower
tepid crow
#

they're like friends of jimbo, but they can change the textures of all playing cards, not just face cards

delicate pivot
#

So I could do it through SMODS or DeckSkins, do you know which is easier?

tepid crow
#

deckskins is SMODS

red flower
delicate pivot
#

Oh ok, I'll try that, thanks. Does it interfere with Malverk at all?

red flower
#

nope

delicate pivot
#

But if someone were to install it, they would have to install the Malverk pack and then the deckskin, right? Just making sure, I am going to open a repository for it. Thanks again!

red flower
#

you can have both in the same mod afaik

#

they would only need malverk as well

tepid crow
# umbral spire anyone...?

you could reload the localization, but that's usually an indicator you should be using localization variables instead

delicate pivot
#

Like put it all in one folder to install? I didn't know that. It just needs the dependencies I see. That makes sense now. Neato

umbral spire
#

what are localization vars ;-;

red flower
tepid crow
#

thanks N

#

it's the #1# things in localization that get replaced by e.g. numbers

umbral spire
#

but like it shows/hides certain stuff in the sticker. the config doesn't simply "change" the values

red flower
#

i would use the key parameter to change to another description or use generate_ui if the logic is more complicated

rotund sable
#

Hello Guys

#

Cool pfp N'

normal crest
#

Hello

#

cool pfp farmer

rotund sable
#

🥺 it's the same for almost 2 years

umbral spire
#

how do you get a factorial of something

hardy viper
#

depends whether you want the exact value or an approximation

red flower
hardy viper
#

one is much cheaper than the other

hardy viper
#

you need to actually compute it

#

the intuitive way

umbral spire
#

wait does talisman have factorial?

hardy viper
#

yes and it uses approximation for large N

#

above like 1000 or something

umbral spire
hardy viper
#

let me check

chrome widget
hardy viper
#

nvm talisman doesn't have this

#

i saw it in some codebase maybe cryptlib or vallkarri

umbral spire
#

will this work?

function fact(n)
    local result = 1
    for i = 2, n do
        result = result * i
    end
    return result
end
hardy viper
#

it'll work

lament agate
umbral spire
#

also how can I make a function in say ./functions/utils.lua and then access it from another script

hardy viper
#

everything runs in the same space so you can write function something() somewhere and call something() in an entirely different file

#

what most people do is have a single global for their mod and put all the functions in that

umbral spire
#

oh

umbral spire
hardy viper
#

MyMod.something = function() but yes

umbral spire
#

oh ok

hardy viper
#

sometimes people do MyMod = SMODS.current_mod

#

which has it's benefits

umbral spire
#

i think there is a better way to do this ;-;

    config = { extra = { mult = MC.factorial((G.playing_cards and (#G.playing_cards) or 52)) } },

    loc_vars = function(self, info_queue, card)
        return { vars = { MC.factorial((G.playing_cards and (#G.playing_cards) or 52)) } }
    end,

    calculate = function(self, card, context)
        card.ability.extra.mult = MC.factorial((G.playing_cards and (#G.playing_cards) or 52))
        if context.joker_main and not context.blueprint then 
            return {
                mult = card.ability.extra.mult
            }
        end 
    end
#

also i have big numbers like 100

#

will that function from earlier lose precision, or will it be fine.

#

maybe i should use the bigint lib?

hardy viper
#

it won't lose precision until you hit infinity at which point yeah it'll lose precision

umbral spire
#

if it loses precision

hardy viper
#

if you want to use factorials you should be using talisman

umbral spire
hardy viper
#
function fact(n)
    local result = to_big(1)
    for i = 2, n do
        result = result * to_big(i)
    end
    return result
end
umbral spire
hardy viper
#

it works

#

it could be rewritten to calculate the factorial less but it's fine if it's based on how many cards there are

umbral spire
#

also what's the hidden bool property do in an smods game object

#

i think i asked this before

#

but i forgot;-;

#

also how do i create a specfic joker

#

-# for a consumeable

umbral zodiac
hardy viper
hardy viper
#

congrats on your very postpartum gender reveal party

umbral zodiac
#

hello

umbral spire
#

what's the timpani sound?

#

i see this in like every consumeable ; - ;

versed swan
#

Associated with selecting a blind, creating cards

#

Like a very quick "thoomp" sound

umbral spire
umbral spire
umbral zodiac
#

soul_rate controls the percent rate of a card to spawn (used best alongside hidden otherwise it’ll also spawn normally)

primal robin
#

soul_rate have no effect without hidden iirc

slim ferry
#

1 = 100% chance

umbral zodiac
#

iirc soul_rate w/o hidden makes it spawn like hidden in packs but also be spawnable by consumable generation but i could be wrong

slim ferry
#

0.003 (default soul rate) = 0.3%

primal robin
#

accoring to code it cant because without hidden card is not added to legendary pool

umbral spire
#

so this is fine?

    key = 'test',
    set = 'Spectral',
    pos = { x = 0, y = 0 },
    soul_pos = { x = 1, y = 0 },
    soul_rate = 0.01,
    hidden = true,
    soul_set = 'Tarot',
red flower
#

yeah i was gonna say the vremade shouldnt be there lol

versed swan
#

<@&1133519078540185692> scam bot

#

Oh

#

Right when I send that message they get sniped

umbral spire
#

they were a lil' late in modding-chat 🤷‍♂️ /hj

stoic void
#

I dont have a character tho, so i cant really

umbral spire
#

i can even just screenshot your pfp

#

and it'll be the Gud joker

#

or consumeable or blind, etc.

#

and then you can think of any ability

stoic void
#

oh ok?

#

well i have 2 mods to make

umbral spire
#

someone said ultrakill for theirs 🤷‍♂️

stoic void
#

which sucks becuase then most ideas go to those 2 first

umbral spire
stoic void
#

Abilities are hardest for me

umbral spire
stoic void
#

I could do code or art easier

umbral spire
#

well im doin that fool

stoic void
#

and this isnt my invitation to do so

umbral spire
#

if you have any random/OP/weak asf ability, just lmk

#

also ddoes anyone know how I can increase every config value of the, per se, leftmost Joker? (specifically multiply the values)

twilit tundra
red flower
#

no but in that case cant you just add them

#

both contexts have the cards added or removed

strong plume
#

Does anyone have any good examples on how to implement custom challange rules?

umbral spire
#

bc

#

idk

#

how to use this ;-;

strong plume
umbral spire
chrome widget
#

My entire mod I guess

twilit tundra
#

why does dna update it but not cryptid? shrug

chrome widget
#

Cryptid's code is occasionally a nightmare

twilit tundra
#

i meant the spectral card

#

that creates 2 copies of a card

chrome widget
#

Oh

#

Lmao

versed swan
#

tbh the code for the cryptid spectral is still a nightmare because its placed in the tower of booleans that is Card:use_consumeable

chrome widget
#

TRUE

#

It's possible it's a vanilla inconsistency in general

twilit tundra
#

yeah

in which case how the hell do i account for it

chrome widget
#

I haven't noticed it in regular gameplay, but occasions where I've failed to update G.playing_cards for a modded card I notice it sometimes doesn't fully update until the next draw

#

It's also possible it's handled elsewhere

#

Though off the top of my head I don't know where

twilit tundra
timid parrot
#

Does the joker Erosion have the same problem?

twilit tundra
#

no, because its +mult only actually triggers when a hand is played, it seamlessly hides the problem

#

and it calculates it on the fly

#

i cant calculate it on the fly i have to store the value

#

since im not doing something that only impacts scoring

strong plume
#

I'm trying to find what file stuff like extra_blind_active custom modifiers is; do you know what file it's on? @chrome widget

#

Doing just this isn't helping hah

chrome widget
#

It has a whole system for creating extra blind effects

strong plume
#

ohhh it's in a different api, thank you

chrome widget
#

Yeah sorry, the blind stuff is handled by Arrow. However the rest of the challenges do implement some custom rules here and there

strong plume
#

I'll poke around more, thanks!

umbral spire
#

i just want to multiply all values of a joker by x1.01 ;-;

#

🥀

chrome widget
#

For example the Fanquisitw Corpse challenge has rules for pinning all jokers and making eternal all jokers but the leftmost joker eternal, which is implemented in CardArea:align_cards() in inclides > hooks > CardArea.lua

#

Unfortunately there's not a lot of framework for challenge rules. Even in vanilla, a lot of challenge rules are just kinda slotted in in various parts of code and not centralized anywhere

#

So you're gonna have to hook/patch a lot

#

Maybe that'd be a fun thing to add to my API, some centralized handling for them to change values

strong plume
#

oooof that'll be roughh

#

Thank you for the help, by the way

umbral spire
#

-# i kinda have to go in 30 that's why i'm asking sm ;-;

chrome widget
#

I've got a function for that

umbral spire
#

:0

#

without cryptlib?

chrome widget
#

Yeah

umbral spire
chrome widget
#

Basically, call this function and pass in card.ability as the table and your mod as 1.01

    --- Recursively modifies number values in a table given a multipliative mod, or a reset table and comparator conditions to reset from.
    --- If no parameters but a table are provided, the function returns a deep copy of all non-object values
    --- @param table table A table to modify.
    --- @param mod number | nil A modifier value (such as 0.5 or 2). Default is 1
    --- @param reset_table table | nil Table to reset directly comparable values from based on comparator
    --- @param compare string | nil A comparator to determine when to reset ('pos', 'neg', or 'dif', default is 'neg')
    --- @return table # A modified copy of the given table
    recursive_mod = function(table, mod, reset_table, compare)
        local val_type = type(table)
        local mod_copy = nil
        if val_type ~= 'table' then
            -- modify number values
            if val_type == 'number' and (not reset_table or type(reset_table) == 'number') then
                -- default value
                mod_copy = table * (mod or 1)

                if not compare then
                    compare = 'neg'
                end

                -- reset if a reset table is provided
                if reset_table and ((compare == 'neg' and table < reset_table)
                or (compare == 'pos' and table > reset_table)
                or (compare == 'dif' and table ~= reset_table)) then 
                    mod_copy = reset_table
                end

                return mod_copy
            end

            -- weird scenarios with a table mismatch
            return table
        end

        -- recursive to arbitrary depth
        mod_copy = {}
        for k, v in next, table, nil do
            if (k == 'order' and type(v) == 'number') or (type(v) == 'table' and v.is and (v:is(Card) or v:is(Cardarea))) then
                -- don't copy certain values
                mod_copy[k] = v
            else
                if mod and mod ~= 1 and type(v) == 'number' and (k == 'x_mult' or k == 'Xmult' or k == 'x_chips' or k == 'Xchips') then
                    if v == 1 then
                        mod_copy[k] = math.max(0, recursive_mod(0, mod, reset_table and reset_table[k] or nil, compare))
                    else
                        mod_copy[k] = math.max(0, recursive_mod(v - 1, mod, reset_table and reset_table[k] or nil, compare))
                    end
                else
                    mod_copy[k] = recursive_mod(v, mod, reset_table and reset_table[k] or nil, compare)
                end
                
            end
        end

        return mod_copy
    end,
chrome widget
#

It also has extra functionality that can be used to reset a table based on the original center which I use sometimes

copper perch
#

My counter here is a bit wonkey. It retriggered cards 3 times, yet its at 6

    calculate = function(self, card, context)
        if context.repetition and context.cardarea == G.hand and SMODS.has_enhancement(context.other_card, 'm_steel') then
            if SMODS.pseudorandom_probability(card, "Sithe_steel_retrigger", 1, card.ability.odds, "Sithe_steel_retrigger") then
                card.ability.retriggers = card.ability.retriggers + 1
                return {
                    repetitions = card.ability.extra.repetitions,
                }
            end
        end
umbral spire
#

also what is card.ability.retriggers?

#

3?

#

in config i mean

#

by default

copper perch
#

I start it at 0

umbral spire
umbral spire
#

so add that check

#

and that may or may not fix the issue

copper perch
umbral spire
#

i mean you are doing it ONCE (the repetition) for each card

#

that's what i meant

#

just try it atleast

copper perch
#

okay, makes sense

#

So like this?

        if context.repetition and context.cardarea == G.hand and SMODS.has_enhancement(context.other_card, 'm_steel') and context.individual then
            if SMODS.pseudorandom_probability(card, "Sithe_steel_retrigger", 1, card.ability.odds, "Sithe_steel_retrigger") then
                card.ability.retriggers = card.ability.retriggers + 1
                return {
                    repetitions = card.ability.extra.repetitions,
                }
            end
        end
umbral spire
copper perch
#

alright :)

copper perch
# umbral spire

Also, I'd check Cryptid for 'Clicked Cookie', that may be a good start :)

copper perch
#

Its not retriggering the steels anymore

#

wait wait, I think I figured it out. It does the initial hit whenever the card hits the chance to retrigger, then when it does it goes up again because the probability is still in the range, so its adding again

#

Unsure what to do with that info though-

umbral spire
chrome widget
#

Not it's config (which is on the prototype) but on the ability table,n which are its instanced values

chrome widget
#

However I'd recommend storing the factor somewhere else, because by doing this, it will also multiple the factor itself by 1.01

#

Because it's within a table under the ability table

umbral spire
umbral spire
chrome widget
#

I don't know the circumstance this is being used in

#

But you do the .ability table for whatever card object

#

I would not recommend doing it on the highest level card table

daring fern
#

wintry solar
copper perch
daring fern
copper perch
#

Yippee, it works! Thank you

#

now I just need to figure out how to change the xmult all current and future steel cards have with a joker

viscid talon
#

everything is fucked

#

IM STILL GETTING THE SAME SOUND ERROR

#

WHAT AM I DOING WROOOOOOOOOOOOOOOOOOOOONGGGGGGGGG 😭 😭

#

THE PATHS ARE ALL CORRECT

#

WHY AM I GETTING BAD ARGUMENTS

#

SCREAMS

willow scroll
#

doesnt the path need the extension

#

aka path = "mega.ogg" instead of mega

viscid talon
#

,,,,,,,,,,,wait

willow scroll
#

make sure you dont get fooled by windows hiding file extensions

#

because its off by default and i will explode microsoft hq everytime for that

viscid talon
#

there's no fucking way it works

#

oh my god

#

OH MY GOD

#

😭 HTANK YOU

willow scroll
#

lmao

#

happy to help

copper perch
daring fern
copper perch
#

I'm assuming this would be in calculate and under joker_main?

daring fern
copper perch
#

so add to deck probably would be best huh

daring fern
copper perch
# daring fern Yes.

So like this?

    add_to_deck = function(self, card, from_debuff)
        for k, v in pairs(G.I.CARD) do if v.config.center.key == 'm_steel' then v.ability.h_x_mult = card.ability.steel_xmult end end
    end,
viscid talon
#

i know i have to use attention text, but i dont know where

daring fern
viscid talon
#

so would this work?

faint yacht
#

You could move the sound into the SMODS.calculate_effect by also specifying sound = 'hatch_mega' as part of the table where message is.

copper perch
daring fern
copper perch
viscid talon
daring fern
# viscid talon ?

SMODS.calculate_effect({message = 'Evolved!', sound = 'hatch_mega'}, card) also move it out of the event.

viscid talon
#

wait yeah, that makes more sense

faint yacht
#

For forcing Flush as part of current poker hand, do I use context.evaluate_poker_hand or do I hook get_flush(hand)?

copper perch
daring fern
daring fern
wintry solar
#

Be careful with forcing hand types though, you’ll need to make sure the table of cards you assign to it is the correct size

faint yacht
#

SMODS.four_fingers will be involved.

copper perch
faint yacht
#

...will it update the scoring hand type if Flush ends up the highest by order though? 🤔

daring fern
copper perch
#

okay, does work with old steel cards but not new ones

viscid talon
#

hmm, it works but its not what i want

#

for starters id want it to shatter, not dissolve

#

secondly, i dont want the message to be normal, it's supposed to be like wheel of fortune's "nope"

#

jokerforge used to support that but now they dont for some reason????

#

i want it to work like this

faint yacht
# faint yacht ...will it update the scoring hand type if Flush ends up the highest by order th...
if context.evaluate_poker_hand and context.poker_hands then
    local minh = SMODS.four_fingers('flush')
    local schand = context.full_hand or {}
    if #schand < minh then return end
    local isallstone = true
    for i, v in ipairs(schand or {}) do
        if not SMODS.has_enhancement(v, 'm_stone') then isallstone = false; break end
    end
    if isallstone then
        table.insert(context.poker_hands['Flush'], context.scoring_hand)
    end
end

Doesn't seem to update the scoring name by order.

copper perch
daring fern
viscid talon
#

gotcha

#

i found an older lua file

faint yacht
#

-# Probably would be easier for me to hook get_flush(hand)...

daring fern
faint yacht
#

Will that respect higher order hands should those be present?

#

-# Also apparently triggers 3x...

viscid talon
#

it no worky

daring fern
viscid talon
#

oke

#

uh thats not good

daring fern
viscid talon
#

which line

daring fern
viscid talon
#

this looks right but i cant tell

#

i dont know what im doing

#

im genuinely lost

#

ITS JUST A SIMPLE CONSUMABLE HOW CAN IT BE THIS HARD 😭

daring fern
viscid talon
#

this is one hell of an error

daring fern
# viscid talon

The event is still not in the use function also you are not returning true

viscid talon
#

what event

#

the can use event?

daring fern
viscid talon
#

o h hm

daring fern
solid mesa
daring fern
solid mesa
faint yacht
#

Was easier for me to just hook get_flush and do my checks there if said Joker is present. 😅

tired kestrel
stoic void
#

its an nes joker 😨

tired kestrel
stoic void
#

idk

obtuse silo
#

apparently the issue is at line 90

daring fern
obtuse silo
#

ah
thx

tired kestrel
final monolith
#

hey! are there resources to make mods on talisman?

red flower
#

talisman doesn't have many docs sadly, what do you need to know

final monolith
#

I have modded balatro but never with talisman so I just wanna start and see if it's any easier

red flower
#

ohh talisman is not a modding api

wintry solar
#

Talisman just makes making mods more annoying

red flower
#

it's a mod for high numbers that needs special compatibility basically

final monolith
#

yes I know but many mods have dependencies on talisman so I assume they're working with it

wintry solar
#

it's not easier or harder, it's just busy work

red flower
final monolith
#

and Xchips as I saw

red flower
#

that's in smods

final monolith
#

then google just lied lol

red flower
#

it used to be only talisman but a long time ago

versed swan
final monolith
daring fern
red flower
versed swan
#

praying rn that one of those forks of talisman that doesnt make lua whine abt comparing differently typed values will be merged into main

slim ferry
#

it will eventually

versed swan
#

(i genuinely do not understand this design choice for lua - operator metamethods work with differently typed values, there shouldn't be a reason for comparison metamethods to not work with differently typed values)

slim ferry
viscid talon
#

ok so the code is moreorless solid, just one small question - how do i have the joker have an edition with it? i want to give it the divine edition

solid mesa
viscid talon
#

permanently

#

i want it so every divine joker has a forced divine edition

#

and that it cant have its edition changed

solid mesa
#

makes sense

viscid talon
#

i think ive figured it out?

daring fern
viscid talon
#

nope i have not figured it out

sharp arch
viscid talon
#

what is hooking

daring fern
viscid talon
sharp arch
# sharp arch please help me

ok so from what I got, its either:
A some messed up code in my booster packs
or B: some messed up code in my editions

#

ok nevermind i fixed it

normal crest
#

an ide like vscode can

#

And you really should use some kind of code formatter

wintry swallow
#

What is the card id for an ace?

daring fern
daring fern
wintry swallow
viscid talon
#

its fine i think ive figured it out

#

i have a new error now

#

i made a new edition with a shader that i commissioned @terse merlin for

terse merlin
#

hi

viscid talon
#

theres the edition