#💻・modding-dev

1 messages · Page 689 of 1

bold eagle
#

like the cube in cryptid but also negative

hidden notch
#

I don't know the key but something like this would work;

set_ability = function(self, card, initial, delay_sprites)
  if card.config.center.discovered and initial then
    G.E_MANAGER:add_event(Event({
      func = function()
        card:set_edition('KEY_HERE') --> NEGATIVE EDITION KEY
        return true
      end
    }))
  end
end,
bold eagle
#

sweet, thank you

uneven drift
#

e_negative I think is negative edition

bold eagle
#

ok

hidden notch
#

Sounds right lewxen_ok

uneven drift
#

I know cuz I always get editions wrong by not putting e_ prefix lol

#

im not good with adding prefixes

bold eagle
#

what would be the command for eternal?

uneven drift
#

still 50-50 on whether I want kerry to be eternal

primal robin
#

Honorable mention of Flowire opop

uneven drift
#

lol I dont know how hook interacts with kerry

#

probably LAMEly

uneven drift
#

can confirm its lame

#

no angy kerry

uneven drift
hidden notch
bold eagle
#

wait is that it

#

does that just straight up do it

hidden notch
#

-# Or also in 'set_ability' and apply it with the sticker command adding thingy lol

hidden notch
bold eagle
#

dang ok im doing that thats easy

slim ferry
#

you can do card:add_sticker("eternal", true) in set_ability

#

which is probably better practice

hidden notch
#

That is much better lewxen_Noblewoman_Laugh

bold eagle
#

ok

uneven drift
#

my code is made with spit and duct tape and im proud of it

#

until it bugs out

bold eagle
#

hell yeah

#

ive only made one joker without significant amounts of help

uneven drift
#

I made gold bot fuck it we ball

bold eagle
#

and i highly doubt it work properly all the time

uneven drift
#

this one gave me no trouble making lol

#

the rest of em I needed some amount of help for

#

It's a collaberative effort

#

yapping petyr I dont think required that much help

#

spent more time making lines for his yaps then actually implementing his ability

#

(if hes not talking a lot, hes not using his ability)

silk latch
#

how would I filter for cards in hand that are also not highlighted?

frosty rampart
#

card.highlighted is set to true for any card that's highlighted

#

so just go through the cards in hand and check for if it's false

wanton jolt
#

i'm throwing the towel on this one

hidden notch
#

Fair enough, don't be too hard to yourself over it grannylaugh

uneven drift
bold eagle
#

is there a list of G.STATES ?

#

I’m trying to make something not happen when you’re in a shop

#

nevermind forgot the vanilla remade faq exists

uneven drift
#

vanilla remade faq the goat

bold eagle
#

fr

silk latch
frosty rampart
silk latch
#

thanks

viscid talon
#

how do i give a joker -$20 sell value

#
-- Swindler
SMODS.Joker {
    key = "swindler",
    config = { extra = { mult = 20, dollars = 20 } },
    pos = { x = 9, y = 0 },
    cost = 5,
    rarity = 1,
    blueprint_compat = false,
    eternal_compat = false,
    perishable_compat = true,
    unlocked = true,
    discovered = false,
    atlas = 'HLJokers',

    calculate = function(self, card, context)
        if context.cardarea == G.jokers and context.joker_main then
            return {
                mult = card.ability.extra.mult
            }
        end
        if context.selling_self then
            return {
                dollars = -card.ability.extra.dollars
            }
        end
    end
}
#

this mostly works, but it gives a sell value of $2 after taking away the $20

#

set_cost() hmmmm

#
-- Swindler
SMODS.Joker {
    key = "swindler",
    config = { extra = { mult = 20, price = 20 } },
    pos = { x = 9, y = 0 },
    cost = 5,
    rarity = 1,
    blueprint_compat = false,
    eternal_compat = false,
    perishable_compat = true,
    unlocked = true,
    discovered = false,
    atlas = 'HLJokers',

    calculate = function(self, card, context)
        if context.cardarea == G.jokers and context.joker_main then
            return {
                mult = card.ability.extra.mult
            }
        end
        if context.selling_self then
            card.ability.extra_value = card.ability.price
            card:set_cost()
        end
    end
}
#

this did NOT work lol

slim ferry
#

this just makes it sell for $20 more

#

you should hook Card:set_cost to force sell value to -20 for this joker specifically

viscid talon
#

how do i hook it

wanton jolt
#

is there a reason why the consumeable (totem head of the printer) tooltip is not showing up?

wanton jolt
# viscid talon how do i hook it

this is what i used to set copied card sell costs as 0

local cardSetCostHook = Card.set_cost
function Card:set_cost()
    local ret = cardSetCostHook(self)
    if self.ability.felijo_copied then
        self.cost = 1
        self.sell_cost = 0
    end
    return ret
end
silk latch
wanton jolt
#

try if not playing_card.edition

wanton jolt
silk latch
#

I did, but it still had the [i] and crashed

#

so just remove it i guess

wanton jolt
#

yeah remove the [i]

viscid talon
wanton jolt
#

you're trying to something you already have

#

i think that would set every card's cost to 20 if you own swindler

viscid talon
#

i need to make it so that swindler specifically has a sell value of -20

wanton jolt
#

what you're checking is
if you own swindler

#

not if the card is swindler

daring fern
wanton jolt
#

yeah so

#

do what somethingcom did because i stopped typing when i saw the message

#

this would be better because you're hooking something i didnt know existed (set_sell_value())

wanton jolt
viscid talon
#

o i see i see

#

thank

#

s

#

truth be told i dont really know how hooks work so this is useful info

#

ive looked at the vanillaremade guide

#

still makes little sense to me 😭

wanton jolt
#

basically what you're doing is wrapping the function you are hooking with your code

uneven drift
#

the real hooks was the imposters we made along the way

viscid talon
#

so if i had a function that told the program "print hello world" the hook would come in and say "actually print goodbye world instead"

uneven drift
#

Yeah, basically

wanton jolt
#

i mean it would print both

uneven drift
#

I'm pretty sure it doesn't if you dont return the original function

daring fern
wanton jolt
#

this

uneven drift
#

yeah, my b, im confusing terminology

#

a hook says both an override says ur new thing

#

spy going "also do this" instead of "do this instead" in my analogy

#

its still a good analogy I think

#

😭

#

override is the evil spy

#

(usually you don't wanna override functions)

slim ferry
#

intruder alert

#

red spy in the base

uneven drift
#

the real hooks were the red spy's we made along the way

wanton jolt
uneven drift
#

we love being stupid

wanton jolt
#

this shouldnt happen though

#

not working because of a space should not happen

silk latch
#

It still doesn't actually do anything as far as I can tell

wispy falcon
#

How do I change the mult of the current hand? Like the Mult from Chips x Mult

wanton jolt
#

@wispy falcon ^

wispy falcon
#

Thank you :3

wanton jolt
#

check this page for FAQ in modding

#

very useful

wispy falcon
#

Where do I use that? This doesn't work

        if context.main_scoring then
            mult = mod_mult(0)
        end
    end,```
uneven drift
#

yeah vanillaremade is the goat

slim ferry
#

wait

#

nvm

#

im blind

daring fern
silk latch
# daring fern Code?
if Cryptid then
    SMODS.Voucher {
        key = 'developer_console',
        atlas = 'vouchers',
        order = 32657,
        dependencies = {
            items = {
                "set_cry_tier3",
            },
        },
        pools = { ["Tier3"] = true },
        pos = { x = 2, y = 0 },
        requires = { 'v_mannpower_squad_surplus' },
        calculate = function(self, card, context)
            if context.create_booster_card and context.booster.config.center.group_key == "k_cry_program_pack" and pseudorandom("developer_console") > 0.8 then
                return { set = "Mannpower", key_append = "ar2" }
            end
        end
    }
end
daring fern
wispy falcon
daring fern
wispy falcon
#

It's the calculate of an edition

daring fern
wispy falcon
#

Wait, am I missing a context or why does it trigger so many times?

            SMODS.pseudorandom_probability(card, 'cstorm_glitch', 1, card.edition.odds) then
            card.glass_trigger = true
            return { remove = true }
        end```
#

Also, what does card.glass_trigger do? I didn't find out

daring fern
timid zinc
#

is there a way to make it so a tag can only appear on skip blinds selection and not from any other thing that generates tags, like how legendaries and hidden spectrals are excluded from pools

wispy falcon
daring fern
# wispy falcon The edition has a 1 in 4 to destroy a random amount of cards currently in hand
if context.after and SMODS.pseudorandom_probability(card, 'cstorm_glitch', 1, card.edition.odds) then
    return {func = function()
        local destroyed_cards = {}
        local temp_hand = SMODS.shallow_copy(G.hand.cards)
        table.sort(temp_hand, function(a, b) return not a.playing_card or not b.playing_card or a.playing_card < b.playing_card end)
        pseudoshuffle(temp_hand, 'seed')
        for i=1, pseudorandom('seed', 1, #G.hand.cards) do table.insert(destroyed_cards, temp_hand[i]) end
        SMODS.destroy_cards(destroyed_cards)
    end}
end
viscid talon
#

for some reason my sephirot cards arent showing up

#

lemme update my repository and show you all the code i have written so far

minor magnet
#

it doesn't even destroy cards

viscid talon
#

sephirot cards seemingly dont exist

#

im aware that some jokers lack localisations, which is okay becasue ill add those later

#

the sephirot card set itself shows up

#

but no cards ;-;

minor magnet
#

the script is not loaded

#

check main.lua

viscid talon
#

oh shit

#

ur right

minor magnet
#

ur welcome :)

viscid talon
#

LMAO IM SO DUMB 😭

#

yeppers they show up now

daring fern
minor magnet
#

have the cards be discarded after any hand is played

dapper sun
daring meteor
#

guys can yall hepl

#

how can i activate on-sell effects???? context.selling_self doesn't work

frosty rampart
#

show code, because context.selling_self is literally the context designed for on-sell effects

daring meteor
#
calculate = function(self, card, context)

        local extra = card.ability.extra
        if not extra then return end

        if context.individual and context.other_card then
            local c = context.other_card

            if c.ability and c.ability.set == "Enhanced" then
                extra.counter = (extra.counter or 0) + 1

                if extra.counter >= 15 then
                    local gain = math.floor(extra.counter / 15)
                    extra.counter = extra.counter % 15
                    extra.X = (extra.X or 0) + gain

                    return {
                        message = "+1 X",
                        colour = G.C.CHIPS,
                        card = card
                    }
                end
            end
        end

        if context.selling_self then
            print("sell")
            extra.sold = true
        end
    end,
#

idk how to format

dapper sun
#

```lua
--like this

#
--like this
daring meteor
#

k

#

did we all just leave?

dapper sun
#

hmm

#

try putting the context.selling_self stuff at the top of the calculate function

daring meteor
#

alr

#

still nothjing

dapper sun
#

weird

#

maybe uhhh

#

print(inspect(context)) at the top of the calculate function and check what it prints in debugplus when you sell the card

daring meteor
#

OOOOOOOOH IT PRINTS IN DEBUGPLUS?? ok

#

ok it says selling_self

#

alr so i just have to fix the code

near coral
#

Are shader colors like in polychrome decided by hexes or hues

frosty rampart
#

rgba format by default, with each value going from 0 to 1
there are lots of shaders out there with functions to convert between rgb and hsl tho, you can just steal that if that makes more sense to you

near coral
#

I work in hsv mostly

rapid stag
#

am i doing this correctly? because i'm not getting dupes in testing

#

why did i not show the whole hook

#

@red flower i'm following the vremade example but idk what's happening

red flower
#

looks correct to me

rapid stag
#

i'm not getting dupes

#

nvm i got a dupe

#

rng was just being reeeeeeeeally weird

gilded blaze
#

did you not open a mega arcana pack
it's a lot easier to get dupes there than mindlessly rerolling the shop

red flower
#

you should have just given yourself every tarot

rapid stag
#

... cirDerp

#

right

trim marten
#

Does anybody know how to specifically change the background of the game? just started modding textures and I'm not sure how to do it.

fading rivet
#

the background is a shader iirc

#

so making it into an image would take a bit of work

trim marten
#

It can't be that hard 🤷‍♂️

#

if you know anything i'd be grateful for the knowledge

gilded blaze
trim marten
#

thank crodie

quasi comet
#

i'm making stakes for my mod and it appears in the menu and all but it's unselectable ? (its above gold stake, and gold stake was beaten)

bold eagle
#

how do i make a joker randomly disable other jokers

#

i cant find anything about disabling jokers/cards

#

debuff i mean

faint yacht
bold eagle
#

ok thank you

#

yeah i dont really know how to apply all that

#

is truthy/falsy value just like true or false

gilded blaze
#

falsy = false or nil
truthy = true or any value

bold eagle
#

oh ok

#

thank you

naive coral
#

How could i create a random joker of a certain rarity?

daring fern
naive coral
#

Wait nvm

#

Im dumb

wispy falcon
#

How easy would it be to make Balatro's UI change transparency when something happens?

#

Would probably need to patch that

primal robin
wispy falcon
#

How do I hide the stickers on a card, when a specific edition is on it?

silk latch
#

dude why isn't this set's soul card working man

slim ferry
#

why dont you set the soul rat to 1 for testng

silk latch
#

idk how to do that

wanton jolt
#

soul_rate = 1

silk latch
#

on the card itself or the set definition?

slim ferry
#

the card

wanton jolt
#

card

silk latch
#

okay cool it does work I guess OFFBYONE is just a fraud

slim ferry
#

its still a 0.3% chance

#

by default

silk latch
#

yeah but I opened like a dozen packs with dozens of slots each

gilded blaze
#

you underestimated 0.3%

silk latch
#

I'm contemplating splitting this effect between two soul cards
PowerPlay for the Polychrome, and Godmode for the Negatives

gilded blaze
#

yea, do it

#

both are strong enough standalone

knotty solstice
#

which mod is the best for stacking cards jokers consumables etc

#

so I can get to insane amounts like 1 trillion jokers 1 trillion consumables

shell timber
#

you are not going to get to 1 trillion jokers

rapid stag
#

yeah this is balatro, we call it 1e12 jokers

tidal hemlock
#

this is talisman, we call it e1.2e1 jokers

shell timber
#

wouldnt it be ee1.079 or something

thorn ingot
#

Guys. How do I increase the weight of all spectral packs using the object poll thing?

#

The code I used to use doesn't work anymore, sadly.

shell timber
#
if context.modify_weights and context.pool_types.Booster then
    for _, pack in pairs(context.pool) do
        if pack.key == "p_spectral_normal_1" or
            pack.key == "p_spectral_normal_2" or
            pack.key == "p_spectral_jumbo_1" or
            pack.key == "p_spectral_mega_1" then
            pack.weight = pack.weight * whatever
        end
    end
end
thorn ingot
#

Also, does the option to introduce weights mess up the seeds too bad?

shell timber
#

what was your old code actually

tidal hemlock
#

because mods that add any amount of content screw up seeds

thorn ingot
#

Yeah, I guess that's true. thanks.

thorn ingot
#

I think it was like that, I deleted this morning, haha. nvm, it is correct.
I think it got messed up in the last update or two.

shell timber
#

oops

frosty dock
#

all sixes

mystic river
sturdy compass
#

Probably hook the Stickers drawstep?

thorn ingot
#

Guys, guys. How do I hide my mod's label on my new stake?
Doing },true) at the bottom doesn't work.

mystic river
#

you can't silently create an object

thorn ingot
#

oh. okay

slate turtle
#
                     delay = 0.1,
                    func = function()
                        G.hand.highlighted[i].ability.perma_x_chips = G.hand.highlighted[i].ability.perma_h_x_mult or 0
                        G.hand.highlighted[i].ability.perma_x_chips = G.hand.highlighted[i].ability.perma_h_x_mult + 0.1
                        return true``` 

GRAAAHHHHH WHY IS IT GIVING XCHIPS INSTEAD OF HELD XMULT
frosty dock
#

it's literally right there

slate turtle
#

oh

#

uhh

#

wtf

#

i think i forgot to save

#

feel free to throw tomatoes at me

#

or sum

frosty dock
#

🍅

rapid stag
#

lua really needs an increment/decrement operator 😭

slate turtle
knotty solstice
slim ferry
#

this reeks of cryptposting

shell timber
#

what the fucking kind of mod is this

distant junco
#

does add_to_deck work for setting a cards enhancements?

#

as in if an enhacement has add_to_deck in its abilities, will that trigger when a card is set to the enhancement?#

viscid talon
#

when i try to decrease the card rank it just

#

crashes

#

idk why

#

it used to work but it no worky

tidal hemlock
viscid talon
#

idk

#

its fine i got it fixed

#

i had to import some older code

rapid stag
#

how do i get the least played hand

#

do i just do most played hand code but

local hand_name, play_count = 'High Card', math.huge -- how max integer get?
for hand_key, hand in pairs(G.GAME.hands) do
    if hand.played < _played then
        play_count = hand.played
        hand_name = hand_key
    end
end
local most_played = hand_name
uneven drift
#

I'm experiencing a bug with one of my jokers:

if (context.joker_type_destroyed and context.card == card) and not context.blueprint_card then
local editionType = nil
if self.edition ~= nil then
editionType = "e_" .. card.edition.type
end
SMODS.destroy_cards(card)
if editionType ~= nil then
SMODS.add_card { key = "j_goob_Kerry_rage", edition = editionType }
else
SMODS.add_card { key = "j_goob_Kerry_rage", no_edition = true }
end
end
if ceremonial dagger destroys the joker, I get 2 copies of "j goob kerry rage" and not 1

#

gonna troubleshoot other destroying methods

#

nah it just seems to be dagger

#

wait no madness does it too

#

but not the spectral card

#

oh

#

its because the card is already being destroyed

#

duh doi

#

smods.destroy card is redundent

#

nevermind

#

I am not sure why that wasnt an infinite loop

#

riddle me that one batman

daring fern
uneven drift
#

why would it only repeat one additional time

prisma wind
#

hello people, i wanna start modding balatro, where do i start?

uneven drift
versed swan
#

Get used to reading the SMODS doc as well - don't let it scare you, take your time reading it

prisma wind
#

awesome, thanks, but where do i actually code? like in the game's direct source code or do i make a new file from scratch?

uneven drift
#

New files from scratch

#

the vanillaremade guide and smods docs will explain things

prisma wind
#

thanks, yall are a big help

#

👍

rapid stag
#

how increase discards? cirLost ok it is just ease_discard

daring fern
rapid stag
#

that's fine, it's just for the blind 👍

rapid stag
#

am i correct in thinking that this would get me the name of both the hand played - and the hand that was discarded?

prisma wind
#

SMODS.Joker {
key = "susjoker"
atlas = "placeholders",
pos = {
x = 0,
y = 0
},
config = {
extra = {
chips = 6152018
}
},
rarity = 1,
cost = 0,

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

}

#

my joker wont appear

#

is there something wrong with this code or is it somewhere else

idle plaza
# prisma wind SMODS.Joker { key = "susjoker" atlas = "placeholders", pos = { ...

There are multiple syntax errors here. If your game loads despite that, then that implies this code is never even seen by the game. Where did you put this? If it's in a file separate from your main lua file, you need to load that separate file manually using assert(SMODS.load_file("your_filename_here.lua"))()

As for syntax errors:

  • Missing comma after key = "susjoker"
  • There should be two ends before the final } of your code here, not just one end
prisma wind
#

oh damn, i suck at coding, thanks for your help!

idle plaza
#

It's fine, everyone has to start somewhere.

bold eagle
#

how does SMODS.recalc_debuff(card) work, recalculates debuff doesnt tell me much

bold eagle
#
local jcard = pseudorandom_element(jokers,"zwp_random")
#

how would I get the key of the joker output by this

daring fern
bold eagle
#

ok thank you

#

and that will return "j_modprefix_key" correct?

bold eagle
#

cool, thank you

#

what does this error mean

fading rivet
#

use it if you make a change to what cards should be debuffed outside of the debuff context

distant junco
#

i just realised i could

#

fr

#

it does not

faint yacht
#

set_ability function does get called when enhancement is applied.

distant junco
#

thanks!!

silent sail
#

whats the infoqueue for editions?

faint yacht
#

G.P_CENTERS.

silent sail
#

foiled by englishh difference once again

gilded blaze
#

blame thunk for inconsistencies

#

center
colour

mystic river
#

i assume that's how they do it in canadia

silk latch
#

How would I check for the amount of times a seal has triggered this run?

mystic river
#

i don't think that function is built in anywhere, but you can add it to the mod calculate (if you mean any seal, or any seal of type X) or the seal calculate (if you mean a specific seal object)

cloud wraith
#

Yall know if the game has an internal timer that counts how much time have you spent in a run or do I have to built that from the ground up

silk latch
#

Is there a way for a challenge deck to ban all of a specific card type except for a specific whitelist or do I have to ban everything outside of the whitelist by hand?

cloud wraith
silk latch
mystic river
#

doesn't matter where you put it as long as it gets loaded

analog slate
#

yea uhhh one question, how is the square joker set up in like height and width wise, i wanna make a card of its size..

distant junco
#

you can do this width too

analog slate
#

i was also asking cuz liike to get templ8s i take the joker.png from the files copy it into my mod and crop, so should it be 71 X 71

distant junco
#

sorry i dont understand could you explain that again lol

analog slate
#

like you take the joker.png file from the game (this image) and crop said item, square joker, whats its width naturally?

mystic river
#

every joker image in that file is 71x95 px

analog slate
#

except for square..

#

if im correct

#

no w8 nvm

#

theres some space

silk latch
mystic river
#

do you know how variables in lua work

analog slate
#

i understand partially what context.joker_main and G.GAME.hands[context.scoring_name] and G.GAME.hands[context.scoring_name].played_this_round > 1 means but how can i change context.scoring_name to refer to a rank

silk latch
analog slate
mystic river
#

why do you want context.scoring_name to refer to a rank

#

that's the name of the poker hand

analog slate
#

i dont i want a replacement

#

something similar to it

#

for ranks

mystic river
#

you want context[something that refers to a rank]?

#

i don't know what would be "similar to this but for ranks"

#

try explaining it directly

analog slate
#

yea pretty much but more like context[something that refers to a rank].played_this_round > 1

#

like essentially how can i get if said rank was already played

mystic river
#

broader stats like cards played in a round are not tracked in context

#

that's what G.GAME is for

analog slate
#

oh....

#

but how come?

mystic river
#

context is the immediate context of what's currently being calculated

analog slate
#

ohh.. yea makes sense

mystic river
#

it's temporary and will be lost when calculation completes

analog slate
#

oh yea.. but i wanna know if the rank was played THIS ROUND

#

so wouldnt it be context?

mystic river
#

no

#

same reason number of discards remaining isn't in context

analog slate
#

ohhh

#

ok i get that and all but what would be the syntax to write, would it be like G.GAME.rank.already_played = True?

mystic river
#

G.GAME.rank isn't a variable that exists
also true is the boolean value, not True

analog slate
#

oh.. i get confused with how its used because i do python

#

and have some knowledge with lua

#

but how can i write it

mystic river
#

to assign a boolean to a variable you do variable = true

#

the same way you assign any other value

analog slate
#

no more like get if rank was played but that helps too
w8 dont variables start like local variable = "string" or soemthing like that or am i confusing it with robloxs terrible lua

mystic river
#

you don't have to declare global variables in advance, only locals

#

i don't believe there's anything in vanilla or smods that tracks whether a given rank has been played this round; you'd need to build that yourself

analog slate
#

oh dang..

#

i could do a list/dictionary

#

rite?

#

im used to roblox lua and not as much as balatro engine lua, would i write lists/dictionarys/whatever its called like local list = {thing,thing2}

#

and i forgor how to addd

mystic river
#

thunk didn't change any of the basic lua syntax

analog slate
#

ohhhh okie

mystic river
#
SMODS.current_mod.calculate = function(self, context)
  if context.individual and context.cardarea == G.hand and not SMODS.has_no_rank(context.other_card) then
    G.GAME.ranks_played_this_round = G.GAME.ranks_played_this_round or {}
    G.GAME.ranks_played_this_round[context.other_card:get_id()] = (G.GAME.ranks_played_this_round[context.other_card:get_id()] or 0) + 1
  end

  if context.end_of_round and context.main_eval then
    G.GAME.ranks_played_this_round = {}
  end
end
#

(though i'd double check the end of round part, i'm not sure mods do main_eval)

analog slate
#

that is way to complex for me, could you add like comments to it or explain..

#

please

frosty rampart
#

(i'd recommend naming the variable something like G.GAME.modprefix_ranks_played_this_round but with your actual mod prefix, so that it doesn't collide with any other mods that might do the same thing)

mystic river
analog slate
mystic river
#
if we're in whatever context that cares about cards scored this round
  if table[rank id] then that rank has been scored this round, do whatever we care about this for
analog slate
#

alright

#

can i print a value into that console in balatro modded

mystic river
#

did you try it?
do you have debugplus? you can just use the in-game console to test something that simple

analog slate
#

oh..

#

ok so i have my code right? and essentially where can i insert the thing it does

#

for this example my item will give 4 dollars in game if the rank was played, i dont think i need help with the giving money but i will need help with the like where i put it

mystic river
#

have you looked at the smods wiki at all?

GitHub

A Balatro Modding Framework. Contribute to Steamodded/smods development by creating an account on GitHub.

#

when someone asks "where do i put my code" there are several values of "where" they could be referring to depending on how much they understand about basic code ideas

analog slate
mystic river
#

vanillaremade is great for examples, but if you want explanations of basic structure, you should look at the actual documentation

analog slate
#

alright im more asking like i have the thing right? but now how am i going to add the like
if this is contained in this list
give four dolla

mystic river
#

do you mean: a calculate function?

analog slate
#

kinda yea

mystic river
#

i know vanillaremade has many examples of calculate functions

analog slate
#

but like now im askign whats the difference between calculate = function(self,card,context) and SMODS.current_mod_calculate = function(self, context)

mystic river
#

well. you see. your mod isn't a card.

analog slate
#

yea...

mystic river
#

so it doesn't take a card parameter.

#

(also it's current_mod.calculate, not current_mod_calculate, that was a typo)

analog slate
#

oh okie

#

do i keep it outside the smods.joker?

#

or do i keep looking like an idiot

mystic river
#

the mod calculate??? yeah you declare a mod calculate outside a joker

analog slate
#

so where can i put it now, at the top?

#

thats rhetorical

#

yea i can

#

or atleast i think

#

ok.. now i add it all

mystic river
#

it mostly doesn't matter what order you do it in, as long as you don't try to call any functions or reference any variables that don't exist yet (but declaring a function now that calls something which doesn't exist yet is fine, if you know it won't be called until the thing exists)

analog slate
#

i have it like this? do i have to declare the variable somewhere

mystic river
#

you don't have to declare that you're adding to a table that already exists, which SMODS.current_mod is

analog slate
#

w8 is current_mod a placeholder where i put my prefix

mystic river
#

no

analog slate
#

oh ok

mystic river
#

when smods loads your mod, it sets SMODS.current_mod to your mod's table

analog slate
#

ok..

#

now how do i get if the rank was already played with this list and newfound knowledge

mystic river
#

well, based on what you've typed so far, what will be true if a rank has been played at least once this round?

rapid stag
#

you can also get SMODS.Mods.your_mod_id

#

which is a permanent and stable reference to your mod's table

analog slate
#

rank is contained in the G.GAME.epicerMod.ranks_played_this_round

#

thats played

mystic river
#

so
check what's there

#

and compare it to the card currently being scored

analog slate
#

ok lemme enable debugplus

#

alright but did we add a calculate = function(self,card,context)?

mystic river
analog slate
#

now what would i put in debugplus

mystic river
#

eval 2+2

analog slate
#

alr

#

that just adds four

mystic river
#

yeah
now you know what that command does

analog slate
#

evaluates

#

can add

mystic river
#

G is a table full of globals
you can look at them

analog slate
#

how

mystic river
#

well you see. variables have names. try typing the name of a variable

analog slate
#

ok uhhmmm would i write in full like

#

G.GAME.epicerMod.ranks_played_this_round

mystic river
#

that's the name of the table yes

#

you know that's the name of the table because that's what you named the table

analog slate
#

it cant find it because i use prefix "epicerMod" do i remove it?

mystic river
#

what exactly is it saying

analog slate
#

attempt to index field 'epicermod' (nil value)

#

something like that

mystic river
#

oh i see
you misunderstood what meta meant by "prefix"
she was suggesting that you change the name of the variable
what you did was not that

analog slate
#

nvm i think i got it lemme see

#

no i dont it says nil when i write it as a command XD

mystic river
#

prefix_name is the variable named prefix_name
table.name is the variable named name inside the table named table. but you can't declare variables in a table that doesn't exist yet

analog slate
#

so i type like G.GAME.table.ranks_played_this_round

mystic river
#

what

analog slate
#

would i type in eval G.GAME.table.ranks_played_this_round wheres tables significance in the text to find it

mystic river
#

i'd recommend naming the variable something like G.GAME.modprefix_ranks_played_this_round
please note that meta did not say G.GAME.modprefix.ranks

analog slate
#

ohhhhhh ok

mystic river
#

you will have to change it in the mod calculate too

analog slate
#

wdym

mystic river
#

your mod calculate is currently going to crash when you play any card

analog slate
#

ok...

#

i haevnt put code in yet

mystic river
#

what do you mean you haven't put code in

analog slate
#

like the calculate in the card that does the function.. havent done that yet

mystic river
#

you can't check whether your code works if you don't. use. your code.

#

your code to do a thing will not do a thing if you don't do the code

analog slate
#

oh yea..

#

in short what am i writing in eval

mystic river
#

these are not magic passwords that extract desired behavior from the aether, these are instructions to a computer

analog slate
#

ok sorry

mystic river
analog slate
#

im starting to understand it now

#

we can say that G.GAME.epicerMod.ranks_played_this_round wont exist because it cant collectively read the mod prefix.. and without it its nothing
but i can still find variables!

mystic river
#

G.GAME.epicermod doesn't exist because you never declared it. this is the default state of all variables
because it doesn't exist, you can't declare G.GAME.epicermod[some subvalue], because this would require first indexing G.GAME.epicermod, which is nil

analog slate
#

ohhhhhh so its G.GAME.epicermod[ranks_played_this_round] and not exactly G.GAME.epicerMod.ranks_played_this_round

mystic river
#

not remotely

analog slate
#

ok.. am i getting there though?

mystic river
#

table.value is shorthand for table["value"], that is, the value inside table indexed at the string "value"

silk latch
mystic river
#

table[value] would be indexing at the contents of the variable named value

#

which leads to my favorite cursed fact about lua

local table = {}
table[table] = table

this table consists of a single index, itself, which contains a single value, also itself

analog slate
#

OH W8 I THINK I GET IT

#

if ranks_played_this_round is a table then i can say like ranks_played_this_round[1]

mystic river
#

you can, yes
that would get the value indexed at the number 1

#

(not to be confused with the string "1", which would be a different value)

silk latch
analog slate
#

alright alright

#

idk if im being just an idiot but im essentially saying eval G.GAME.epicerMod.ranks_played_this_round[1] or it has to be said differently

mystic river
#

probably useful context: Card:get_id() returns a number, the id of the card's rank (or a random massively negative number if the card has no rank, e.g. Stone)

#

what rank has the id 1?

analog slate
#

hmmmmmmmmm

#

wehere am i finding it in eval

#

im slowly getting confused i think i might need a break at some point.....

mystic river
#

well, dp.hovered contains whatever you're hovering over, if you want to look at the numbers in a card object

#

(if you're running debugplus)

analog slate
#

alright..

mystic river
#

so you could do eval dp.hovered:get_id() on any card you can hover over

analog slate
#

ok we have the id

#

thats nice knowing card ids

mystic river
#

also. i've tried saying this a few ways but i don't think you've even noticed?
you don't want epicerMod.ranks_played_this_round. you want epicerMod_ranks_played_this_round

analog slate
#

OHHHH

mystic river
#

the first one tries to find a variable named ranks_played_this_round inside a table named epicerMod (which is a problem, since you've never declared such a table)
the second one just tries to find a variable named epicerMod_ranks_played_this_round

analog slate
#

i get nil but its probably because im not specifying. if i write it like eval epicerMod_ranks_played_this_round its gonna come as nil but if i specify like eval epicerMod_ranks_played_this_round[1] ill get something right?

#

no

mystic river
#

if you eval an empty table you should get something like

Table:

if you eval a variable that doesn't exist you'll just get nil

analog slate
#

alright makes sense

mystic river
#

the difference is important, because empty_table.index is just nil (which is generally fine in if checks, it's basically just false), but nonexistent_table.index gets you an error

analog slate
#

ok.. so that means our table does exist because it doesnt give us an error

mystic river
#

which table?

analog slate
#

the table were trying to get answers from when trying to eval

mystic river
#

name

analog slate
#

epicerMod_ranks_played_this_round

mystic river
#

if you fixed and implemented your mod calculate i would expect that table to exist

#

though i would not expect that if you did not do so

analog slate
#

i did insert it

mystic river
#

you don't appear to have fixed it

#

that code will crash the moment a card is scored

analog slate
#

it hasnt tho.. its probably because i havent fully set the thing up..

#

what do i fix however

#

oh w8

analog slate
#

i was thinking that too

#

lemme test it

#

ok so i might be trying to type it in wrong but im not so sure

#

well get back to it l8r

silk latch
#

okay wait so would something like this work?

SMODS.current_mod.calculate = function(self, context)
    if context.individual and context.cardarea == G.hand and context.other_card.seal == "mannpower_strange" then
        G.GAME.mannpower_strange_counter = G.GAME.mannpower_strange_counter or 0
        G.GAME.mannpower_strange_counter = (G.GAME.mannpower_strange_counter or 0) + 1
    end
    if G.GAME.mannpower_strange_counter >= 10 then
        check_for_unlock({ type = 'strange_threshold1' })
    end
end
SMODS.Achievement {
    key = "strange1",
    bypass_all_unlocked = true,
    unlock_condition = function(self, args)
        if args.type == "strange_threshold1" then
            return true
        end
    end,
}
tranquil gull
#

so chat

#

i wonder how hard it would be to put expantanum into talisman

rapid stag
#

by default, check_for_unlock isn't called during a seeded run, right? or do i have to account for that in a hook

rapid stag
#

question, SMODS.Enhancement can into add_to_deck? cirThink

frosty rampart
#

nope

rapid stag
#

hmm. what calculate context(s) should i use to substitute for that, then

#

i'm trying to implement a deck effect that changes the amount of held xmult steel cards have

frosty rampart
#

in that case, i'd actually recommend just taking ownership of the steel enhancement to give different xmult if the deck is active

#

but if you do want to just go the route of modifying steel cards as they appear, context.setting_ability is used when a card changes its ability, which usually includes applying an enhancement. and you can check context.new to see which enhancement it is
pair that with context.playing_card_added to account for cards that are created as steel already (e.g. cards found in standard packs or from familiar), and you should be good

queen crescent
#

am i layering patches correctly

#

ok i figured that out, but now i need to plug my atlas on there

viscid talon
#

im trying to modify these booster packs

slim ferry
#

all of the packs appear to be lacking a create_card function

viscid talon
#

whoops

#

willf ix

knotty solstice
#

someone that understands shader

#
    vec4 tex = Texel(texture, texture_coords);
    
    float gray = (tex.r + tex.g + tex.b) / 3.0;
    vec3 gold = vec3(0.85,0.8,0.43);
    float factor = smoothstep(0.0,3000.0,time);
    tex.rgb = mix(tex.rgb,vec3(gray)*gold,factor);
#

why does this is always same color

#

instead of being animated

#

both have same edition

wintry solar
#

time is a fixed value

silk latch
#
    check_for_unlock = function(self, args)
        return args.type == 'strange_threshold1' and (G.P_CENTER_POOLS.Stake[G.GAME.stake].key == "red" or
            G.P_CENTER_POOLS.Stake[G.GAME.stake].key == "blue") and true 
    end

Why isn't this working for unlocking my deck?

knotty solstice
wintry solar
#

what's your shader name?

knotty solstice
#

which value should I use for color animations?

knotty solstice
wintry solar
#

that's the name of the vec2 inside your shader, right>?

knotty solstice
#

yes

wintry solar
#

use golden_shader.g instead

#

that's actually the time

knotty solstice
#

thanks

#

that helped a lot

#

I was breaking my mind trying to understand

wintry solar
#

yeah I don't know why thunk named that value time when it isn't a time value

slim ferry
#

what does that actually equal

wintry solar
#

well, it is the time in the CRT shader

slim ferry
#

oh

#

genius!

silk latch
wintry solar
#

but otherwise its this G.SHADERS[_shader or 'dissolve']:send("time",123.33412*(_draw_major.ID/1.14212 or 12.5123152)%3000)

frosty rampart
#

genius!

prisma wind
#

i feel like i'm doing my folder loop wrong, can someone help?

frosty rampart
#

this crash is unrelated to the folder loop
the atlas with the key "sussy" is attempting to load an image file that doesn't exist

cinder elk
viscid talon
#

could someone check over a part of my localisation? the sephirot cards arent having their localisation show up

#

all of the other localisations work fine

#

but the localisation wont show up

daring fern
viscid talon
#

o

#

how do i fix this

daring fern
viscid talon
#

which means...?

#

sorry, i suck at understanding context clues and such

#

i need visual explanations for this sorta stuff

#

oh i found this in main.lua

#
    key = 'sephirot',
    primary_colour = HEX('0ebab2'),
    secondary_colour = HEX('0ebab2'),
    collection_rows = { 4, 5 },
    shop_rate = 0,
    loc_txt = {
        name = "Sephirot",
        collection = "Sephirot Cards",
    }
}
#

hmmm

#

needs adjusting i think

#

anyways looks like i fixed it

silk latch
wanton jolt
cinder elk
wanton jolt
#

are they jokers or blinds

silk latch
# silk latch I don't get why this isn't working

Okay I've changed it to

    check_for_unlock = function(self, args)
        if args.type == "strange_threshold1" then
            if G.P_CENTER_POOLS.Stake[G.GAME.stake].key == "red" or
                G.P_CENTER_POOLS.Stake[G.GAME.stake].key == "blue" then
                return true
            end
        end
    end

and it works without the part where I check the stake, but doesn't if I include the stake check.

mystic river
rapid stag
#

nvm i'm dumb

silk latch
#

Also uh this doesn't work at all

SMODS.Voucher {
        key = 'developer_console',
        atlas = 'vouchers',
        dependencies = {
            items = {
                "set_cry_tier3",
            },
        },
        pools = { ["Tier3"] = true },
        pos = { x = 2, y = 0 },
        --    unlocked = false,
        requires = { 'v_mannpower_squad_surplus' },
        calculate = function(self, card, context)
            if context.create_booster_card and context.booster.config.center.group_key == "k_cry_program_pack" and pseudorandom("developer_console") > 0.8 then
                return { booster_create_flags = { set = 'Mannpower', key_append = 'ar2' } }
            end
        end
    }
rapid stag
#

ok, i have string A which is a hand name and string B which is also a hand name
just from those strings, how can i tell if the hand that A describes, contains B?

#

like i know that say, if A is a three of a kind and B is a high card, A would absolutely contain B

daring fern
cinder elk
rapid stag
frosty rampart
#

yea you don't need to do what somethingcom gave you
just do G.FUNCS.get_poker_hand_info(context.full_hand)["High Card"] (to see if it contains high card)

#

i think just wrapping that in next(...) should be enough to properly check

rapid stag
frosty rampart
#

yes, both of those contexts have context.full_hand

rapid stag
#

oh, it does have context.full_hand

#

ok

#

doesn't get_poker_hand_info return like 5 things though

frosty rampart
#

well yea
that's why you index it with the ["High Card"] at the end to get just the hand you're looking for, and then wrap it in next(...) to check if any of that specific hand actually exists in the original hand

rapid stag
#

oh, i was substituting high card with my variable

frosty rampart
#

ye that's correct (i think)

#

as long as it's the proper name of a poker hand

rapid stag
frosty rampart
#

yea sorry i dunno how exactly get_poker_hand_info works off the top of my head

#

use debugplus to interact with the function and see how it's all laid out

daring fern
rapid stag
#

could you elaborate on it not working? like it doesn't show up in G.P_CENTERS?

silk latch
#

The mannpower cards don't show up in the code packs

rapid stag
#

well based on the pseudorandom("developer_console") > 0.8, it's a 20% chance, right? if you're making sure it works, have you tried without that check
might just be bad luck

#

although i'm not entirely sure that's how that works cirLost

cinder elk
daring fern
silk latch
rapid stag
#

does updating to current release work

quick scarab
#

good or not?

daring fern
uneven drift
#

Kerry has weird interactions with cryptid mod but idc 🔥

#

Rework card destroys a joker but doesnt trigger kerry destruction

#

maybe for the best

inland vessel
#

I have elected to change the global color values of the High Contrast mode hex codes

#

works great, though I'm sure it's not a very versatile solution

uneven drift
#

Is there a way to increase the odds that your modded jokers appear in the shop?

#

thinking about making a joker along that line, so I dont want it to be like 100% lol

gilded blaze
#

enable object weights

rare minnow
#

anyone know why this doesn't work?

faint yacht
#
if context.joker_main then return { xmult = card.ability.extra.Xmult } end
normal crest
#

Put that inside calculate ^

#

Instead of what you have

rare minnow
#

thank you

uneven drift
#

is there a way to check if a skipped blind was a small blind, specifically?

#

G.GAME.blind:get_type() im assuming?

obtuse wraith
daring fern
uneven drift
#

alright

#

basically if skipped context and blind_on_deck is big

silent sail
#

how do i do animatied jokers?

#

ik i put the sprites on the sheet but how do i code it

faint yacht
#
atlas_table = 'ANIMATION_ATLAS', -- set atlas to be animated
frames = 10, -- how many frames
fps = 4 -- optional, how fast it animates

when using SMODS.Atlas to define an atlas.

silent sail
#

i seee

#

does it need to be its own atlas or just need to all be together

faint yacht
#

In theory, you can point to same file, but keep in mind that animated atlases will ignore the x value of pos.

silent sail
#
pos = { x = 0, y = 0 },
atlas_table = 'draugratlas',
frames = 10,
fps = 2,
#

wait

#

i think i forgot teh .png

#

nope nvm it just isnt working

frosty dock
silent sail
#

wrong thing

#

oops

frosty dock
silent sail
#
SMODS.Atlas({
    key = "draugratlas", 
    path = "draugratlas.png", 
    px = 71,
    py = 95, 
    atlas_table = "ANIMATION_ATLAS"
})
frosty dock
#

where is frames

#

looks fine otherwise

silent sail
#

frames is in the top one

#
pos = { x = 0, y = 0 },
atlas_table = 'draugratlas',
frames = 10,
fps = 2,
#

im definately doing something wrong but i cant figure out what

slim ferry
#

frames is part of the atlas definition

#

and so is fps

silent sail
#

ah

#

put them both in and it still isnt working

faint yacht
#
SMODS.Atlas({key = "TOGAJokersUpdate", path = "togajokerupdate.png", px = 71, py = 95, atlas_table = 'ANIMATION_ATLAS', frames = 10, fps = 4})

Something like such.

silent sail
#
SMODS.Atlas({
    key = "draugratlas", 
    path = "draugratlas.png", 
    px = 71,
    py = 95, 
    atlas_table = "ANIMATION_ATLAS",
    frames = 10,
    fps = 2,
})
pos = { x = 0, y = 0 },
atlas_table = 'draugratlas',
faint yacht
#

It's just atlas for use in SMODS.Joker.

silent sail
#

this is a consumable

#

turns out that works aswell

#

yay

fading rivet
#

is the last played hand type stored somewhere or do I have to track it

frosty dock
#

not sure that exists when you need it to

fading rivet
crystal perch
#

is there a way i can make an enhancement cause a card to never score? like the opposite of stone?

slim ferry
#

never_scores = true iirc

broken rivet
#

does anyone here have any idea of what's going on here (there should be 8 sprites arranged in a 4x2 grid)

#

the sprites are all handled by an extension of Moveable

frosty dock
#

are the sprites missing or just empty?

broken rivet
frosty dock
#

too little info then

broken rivet
crystal perch
#

show the code

broken rivet
#

hold on

#

vs code gave the ui function wonky indentation when i copypasted it 😭

#

honestly i'm not even sure how to go about finding where the error even is

frosty dock
# broken rivet

can't look at all of this on mobile, but one thing that seems problematic is self.children.sprite.states = self.states

#

it makes both states tables the same table

broken rivet
#

i will note the sprite that does appear also flies in from the top of the screen

broken rivet
#

so i might want to do copy_table(self.states)?

frosty dock
#

mhm

broken rivet
#

didn't fix the collection issue but good to know anyway

frosty dock
#

yeah I wasn't confident that's the issue. just the first thing I noticed

broken rivet
#

kinda wondering if it might be something here

#

idk if the moveable being local is fucking things up

#

i noticed the blind moveable gets added to G.I.CARD

#

but doing that doesn't seem to help

#

i had previously used SMODS.create_sprite for this which worked fine

frosty dock
broken rivet
frosty dock
#

which are made cards by smods

broken rivet
#

wait huh

#

it creates them as cards???

broken rivet
#

oh it's in src/overrides 😭

cloud wraith
#

Yo guys!!! I need help!! Yall know how can I change normal binds (small, medium) to random boss binds? I wanna do a joker inverse to the luchador kinda thing where when you sell the joker the next ante is just boss binds for x2 money. Help will be super appreciated! Thxs!!

wintry solar
#

With a lot of patching

cloud wraith
#

If u can explain id love to thxs

gilded blaze
fading rivet
#

the most important file to mess with is gonna be functions/state_events.lua

cloud wraith
fading rivet
cloud wraith
slim ferry
#

theres also some jank with ante changes

#

since the game is hardcoded somewhere to always reset blinds and increase ante after a boss

fading rivet
#

yeah

#

that and putting blinds where they shouldn't be also leads to skipping them

wintry solar
#

There’s also a load of save stuff you need to account for

past spade
#

do deck backs have draw functions like jokers, or some equivalent? trying to apply a shader to one

ivory field
#

how do i get started in modding

frosty rampart
cinder elk
rare minnow
#

How would I make a joker shrink hand size?

keen totem
keen totem
#

looking at it
G.hand:change_size(-1)

#

for -1 hand size

rare minnow
keen totem
#

can you ban things from existing challenges or do mods and challenges just not really work well together?

frosty rampart
#

you can probably take ownership of vanilla challenges

silk latch
#

how do you make a boss blind debuff multiple ranks?
because

    debuff = { value = '2', '3', '4', '5', '6', '8', '7', '9', '10' },

isn't working

frosty rampart
#

you can't use that debuff shortcut, you'll have to use the blind's calculate function

calculate = function(self, blind, context)
  if not blind.disabled then
    if context.debuff_card then
      local rank = context.debuff_card:get_id() -- context.debuff_card is itself a card object being checked to see if it should be debuffed
      if rank == 2 or rank == 3 or ... then -- i'm sure there's a more efficient way to do this but i don't feel like figuring it out lol
        return { debuff = true }
      end
    end
  end
end
silk latch
#

Do score, xscore, blind_size, and xblind_size returns just not work when called by blinds???

bold eagle
#

how would i remove a joker from the judgement pool?

#

like

#

using the in_pool in the SMODS.Joker

silk latch
silk latch
#

wait I used my reflect card on a 4 and it didn't apply the xblindsize

#

I think it might just not work at all for some reason????

#

in the latest version of smods

daring fern
silk latch
#

that doesn't explain regen not working

#

I think they may have just broken the effects too? My Reflect consumable was working perfectly fine before I updated and now it just does nothing

silk latch
bold eagle
daring fern
silk latch
daring fern
silk latch
silk latch
idle plaza
# silk latch Tried to fix it and now it softlocks

Events softlock when they don't return true. That's happening in the event that used to hold the return score value. When it was there, it was close enough to return true as far as Balatro's event code was concerned.

silk latch
idle plaza
# silk latch I put the normal return true back where I had moved the return score from and IT...

I think you should use context.before instead of context.press_play here. The issue with your current method is that you only increase your numberofthings in an event, which is ran after your return. If you use context.before instead, you can loop through context.full_hand outside of an event to juice the cards. You can also just use #context.full_hand in your return, instead of manually re-counting the cards in numberofthings.

silk latch
# idle plaza I think you should use `context.before` instead of `context.press_play` here. Th...

so then something like this?

calculate = function(self, blind, context)
        if not blind.disabled then
            if context.before then
                for i = 1, #G.play.cards do
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            G.play.cards[i]:juice_up()
                            return true
                        end,
                    }))
                    numberofthings = numberofthings + 1
                    delay(0.23)
                end
                return {
                    blindsize = math.floor((get_blind_amount(G.GAME.round_resets.ante) * 0.1)) * numberofthings
                }
            end
        end
    end
idle plaza
# silk latch so then something like this? ```lua calculate = function(self, blind, context) ...

Kinda. It's better to use context.full_hand in place of G.play.cards. In addition, #context.full_hand/#G.play.cards is already the number of all played cards, so you don't need your own count of numberofthings at all.

As-is, you'll crash just because you don't set any starting amount for numberofthings before increasing it, it's easier and more efficient to just do without entirely.

silk latch
#

oh i forgot to finish getting rid of that lol
so just

calculate = function(self, blind, context)
        if not blind.disabled then
            if context.before then
                for i = 1, #G.play.cards do
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            G.play.cards[i]:juice_up()
                            return true
                        end,
                    }))
                    delay(0.23)
                end
                return {
                    blindsize = math.floor((get_blind_amount(G.GAME.round_resets.ante) * 0.1)) * #G.play.cards
                }
            end
        end
    end
idle plaza
#

Yeah that'll work

#

(Probably)

silk latch
#

okay cool it does

#

now just to figure out why Regeneration isn't working

SMODS.Blind {
    key = "regen",
    atlas = 'mannpowerblind',
    pos = {
        y = 5
    },
    boss = { min = 4 },
    config = {
        blind_mod = 0.25,
    },
    loc_vars = function(self, info_queue, card)
        return {
            vars = {
                number_format(lenient_bignum((get_blind_amount(G.GAME.round_resets.ante) * 0.25))),
            },
        }
    end,
    collection_loc_vars = function(self)
        return {
            vars = {
                "(" .. number_format(0.25) .. "X base)",
            },
        }
    end,
    boss_colour = HEX("ED712B"),
    calculate = function(self, blind, context)
        if not blind.disabled then
            if context.after then
                return {
                    score = get_blind_amount(G.GAME.round_resets.ante) * -0.25,
                }
            end
            if G.GAME.chips < 0 then
                return {
                    score = G.GAME.chips * -1,
                }
            end
        end
    end
}
#

because by all means it should work

#

It sends the message but doesn't actually lower the score

idle plaza
# silk latch now just to figure out why Regeneration isn't working ```lua SMODS.Blind { k...

When happens if you remove the if G.GAME.chips < 0 then half of the calculate function?

Because it's outside of a specific context, it'll be repeatedly and sporadically checked, and may immediately override the initial score decrease. I don't know for sure if it's the issue (as it sounds like the score just isn't decreasing at all from the context.after part), but it's likely an issue.

uneven drift
#

SMODS.ObjectType({
object_type = "ObjectType",
key = "goob",
weight = 10,
default = "j_goob_Petyr",
get_weight = function(self)
if next(SMODS.find_card("j_goob_Boblin")) then
return self.weight * 1.25
elseif not next(SMODS.find_card("j_goob_Boblin")) then
return self.weight
end
end,
cards = {}
})
this would be painstaking to debug, but I did correctly make it so if I have joker "j_goob_Boblin", "goob" type objects are 25% more likely to show up right?

#

the object type works correctly I already know that from another joker I just added weight and get_weight

rapid stag
silk latch
uneven drift
#

I guess to debug it I could just make the number 9000% lol

#

tho I'd probably wanna put the increased weight clause in calculate

#

tho, guess theres no point really

#

aside from that one cryptid card maybe? im not sure how that interacts with debuffed cards

#

hmm

#

I mean it would be funny if I dont know this is working

#

Boblin IS supposed to be a meme, after all

zenith quarry
#

someone please help ive tried abunch of stuff and im trying to make a deck that only lets legendary jokers spawn like in rarrans video i cant figure it out SMODS.Back{ key = 'LG', atlas = 'LG', pos = {x = 0, y = 0}, config = { }, apply = function(self) end } https://youtu.be/R_uCfxzwSK0?si=XjU2X-E1uPz1-gfM

Subscribe and Like the video :)
Checkout: @BeanBalatro

You should watch me live on Twitch:
https://twitch.tv/rarran
▶Discord: https://discord.gg/AYThPma
▶Twitter: https://twitter.com/RarranHS
▶TikTok: https://www.tiktok.com/@ytnarrar

Edited By: Wolti
Thumbnail By: Rarran

#Hearthstone #Rarran #balatro

▶ Play video
daring fern
uneven drift
#

something did I do my implementation right or no

zenith quarry
#

do i just put that in the apply

#

?

daring fern
uneven drift
#

ah

daring fern
zenith quarry
#

oh ok

#

so can i get rid of the function

daring fern
zenith quarry
#

that didnt work

uneven drift
#

hmm

zenith quarry
#

@daring fern i tried that could and nothing happened

zenith quarry
#

yeah it didnt work\

uneven drift
#

The easy implementation would just be make every joker have a weight and have a get_weight for boblin checking

#

eh fuck it im lazy

#

and also, its boblin

#

Stupid implementations make sense

#

hmm, dont know if that worked

#

:/

#

gonna implement this a little differently then just affecting weight

daring fern
silk latch
rare minnow
#

So I'm trying to make it so every 2 gives +14 mult, but it wont work. doesn't crash, just wont work.

mystic river
#

context.repetition is for calculating retriggers

idle plaza
idle plaza
uneven drift
#

y'know this is way too annoying so im just gonna give boblin one of the other effects I was thinking about

lyric wadi
#

chat any ideas why pseudoshuffle is failing?
card.ability.extra.unrevealedindex is just a list of the number 1 to 45

silk latch
#

And, moreover, worked completely fine before updating

daring fern
silk latch
#

So then I just update it to

        for i = 1, #G.hand.highlighted do
            G.E_MANAGER:add_event(Event({
                trigger = 'after',
                delay = 0.1,
                func = function()
                    local _card = G.hand.cards[i]
                      if G.hand.highlighted[i].ability.perma_x_blind_size == 0 then
                        G.hand.highlighted[i].ability.perma_x_blind_size = card.ability.extra
                            else
                    G.hand.highlighted[i].ability.perma_x_blind_size = (G.hand.highlighted[i].ability.perma_x_blind_size or 1) *
                        card.ability.extra
                            end
                    return true
                end
            }))
        end

?

daring fern
silk latch
#

(0 + 1)*0.95 - 1

uneven drift
#

after implementing that joker I have a better lengthier idea that shouldnt be undoable 🔥

#

however, im coded out for today

daring fern
silk latch
#

(blind_size + 1)*0.95 - 1

#

(0 + 1)*0.95 - 1
1*0.95 - 1
0.95 - 1
-0.05

daring fern
silk latch
#

That's fucking weird

#

I assume it's just to keep shit like Cryptid's Glitched edition from affecting it

daring fern
daring fern
# lyric wadi bump?

It's because pseudoshuffle doesn't check if list[1] is a table before checking if list[1].sort_id exists.

lyric wadi
#

ok then i dont understand how its implemented

#

like is list in this case not just the input list? if so why would it check that the first element is a table

#

it worked perfectly fine shuffling a list of strings, so why does it fail when it's a list of numbers?

daring fern
lyric wadi
#

what the fuck

#

so how do i fix this?

#

do i have to make it not a list of number?

lyric wadi
#

how to i check for skipping the small blind specifically? like i want it to trigger when skipping small blind but not big blind

#

i know theres a context for skipping blind and there's a global var for skips that throwback uses

fading rivet
#

where should my localization entry be for providing a key to the saved return in game_over

daring fern
lyric wadi
#

so like if i put that in the skip check it'd mean you skipped from small to big?

#

and if you skipped big G.GAME.blind_on_deck would return boss instead?

#

is that how it works?

keen totem
#

is it possible to set the scalar_value of an SMODS.scale_card call to a local variable, instead of pulling it from a table?

fading rivet
#

like

scalar_table = {val},
scalar_value = 1
keen totem
#
scalar_table = {points},
scalar_value = 1
#

so would this tell it to use the first value from that table?

fading rivet
#

yeah

keen totem
#

alright

daring fern
keen totem
#

why?

#

i just need to use a value thats not in a table as the scalar_value

#

what does .getting_sliced mean?

#

i was looking at something in vanillaRemade and it says that you should set it to true for cards that are being destroyed

lyric wadi
#

basically you're just giving the card a flag that you can check for later

daring fern
wanton jolt
#

i'm sure context.joker_type_destroyed bypasses that

silk latch
rigid solar
#

it's for all joker destruction effects im pretty sure

#

that'd include ankh and hex for example, but yeah dagger and madness

gilded blaze
hearty lagoon
#

Is there a way to modify the bonus an enhanced card gives? For instance i want to make a joker that makes bonus cards score x1.5 chips instead of +30 chips

gilded blaze
#
SMODS.Enhancement:take_ownership("bonus", {
    config = {bonus = 30, xchips = 1.5},
    update = function(self, card, dt)
        if next(SMODS.find_card("j_modprefix_key")) then
            if not card.ability.old_bonus then
                card.ability.old_bonus = card.ability.bonus
            end
            card.ability.bonus = 0
        elseif card.ability.old_bonus then
            card.ability.bonus = card.ability.old_bonus
            card.ability.old_bonus = nil
        end
    end,
    calculate = function(self, card, context)
        if context.main_scoring and context.cardarea == G.play then
            if next(SMODS.find_card("j_modprefix_key")) then
                return {
                    xchips = card.ability.xchips,
                }
            end
        end
    end,
})
#

do you need explanations for the snippet

hearty lagoon
gilded blaze
#

put it anywhere but inside another SMODS.GameObject

#

it's fully complete, there's no need to modify it in any way

hearty lagoon
#

right, tysm

gilded blaze
#

just replace j_modprefix_key with whatever your joker key is

#

that's obvious tho

hearty lagoon
#

yeah

#

anything that i should keep in mind or be careful about?

gilded blaze
#

it's Cryptid-proof
meaning any value manipulation to card.ability.bonus is temporarily stored as card.ability.old_bonus

normal crest
gilded blaze
#

no

#

elseif won't run if the previous condition is satisfied

normal crest
#

Yes but the first branch always sets old bonus to bonus

#

Which becomes 0

gilded blaze
#

ah

#

😭

hearty lagoon
#

i was just testing that lol

gilded blaze
#

alr, fixed

hearty lagoon
#

previously scored bonus dont score the old one

gilded blaze
#

man, that slipped under the radar because I didn't test it myself

#

wait

#

man, this sucks

#

I should be more careful when updating something every frame

#

now it should work

fading rivet
median veldt
#

i know that cryptid lets you manupilate joker values

#

but how do u Set them

fading rivet
#

like in general

#

or do you have a specific target in mind

median veldt
fading rivet
#

note this will only affected modded cards iirc

#

vanilla stores their stuff in card.ability

median veldt
#

I could iterate through both?

fading rivet
#

also the number check isn't explicitly needed but will stop crashes caused by setting stuff like suits to 3

fading rivet
median veldt
#

Mm.

#

I see.

fading rivet
#

iirc all vanilla jokers are defined in game.lua

grand junco
#

question. Does anyone know how to take a high quality picture and resize to fit the tarot cards? I'm asking for a personal mod I'm making for myself

#

got an image size of 800X1582

fading rivet
#

71x95 is recommended for stylistic consistency, along with being at the correct aspect ratio, but anything works

#

I have a card that's 142x190 in mine

grand junco
#

so theortically could half the size of my current file work?

#

or something like 200px wide?

fading rivet
grand junco
fading rivet
#

the way the game works (from what I've observed I havent actually looked into this)
is that it draws the entire atlas on the screen, scales it down based on the size you told it the cards where, and the crops out the excess

grand junco
uneven drift
#

how do I make a variable for G.Game, im trying to make a michel/cavendish relationship where it is saved whether or not a joker got destroyed