#💻・modding-dev

1 messages · Page 84 of 1

silent pawn
#

my fucking antivirus deleted version.dll for the 2 millionth time

rough furnace
#

skill issue

silent pawn
#

):

#

forgot a comma

#

im so smart guys

#

forgot another

#

😭

#

its 5am its understandable

#

trust me,,

tidal ice
#

its fine I know someone whos absolutely nuts with coding for a very specific fangame, and they may forget simple stuff like that

silent pawn
#

i forgot to put an end on my if statement im actually cooked chat

cerulean rose
#

i'm trying to use lovely to patch code for ending a blind and it just always says it's not found?? even though it's literally copy+pasted from the source

silent pawn
#

😭

#

i have near to no experience with lovely so i wouldnt be able to help with that

cerulean rose
#

yeah

rough furnace
#

also check the lovely dump sometbhing else could have replaced it before your patch applied

cerulean rose
#

it's near where talisman is doing stuff

#

i've tried both the original and what talisman replaced it with, as well as a hack-around using the line below

#

none work

silent pawn
#

?!?!?!!

#

😭

#

NEVERMIND I MISSED ANOTHER COMMA

#

ill get all the commas at some point

#

give me 600 errors maybe ill get them all

#

nevermind im getting the same error

#

uifhasiuyfyfsdf

tidal ice
#

relatable

cerulean rose
#

can you show the whole line

#

a second pair of eyes goes a long way in situations like these

silent pawn
#

fixed it

#

i forgot the word and somehow?

#

😭

cerulean rose
#

will it say that if there are multiple matches?

silent pawn
#

is there a context for like

#

on play hand

silent pawn
#

IT WORKS YIPEEE

south karma
#

Im a modding virgin and am learning lua through balatro; how would I go about spawning in a joker or card to test?

rough furnace
#

you can use DebugPlus to spawn a joker

stiff locust
#

is there a way to give or take temporary hands/discards

#

or do I just need to reset them at the end of the round

maiden phoenix
#

There's plenty of vanilla jokers that does that

stiff locust
#

yeah it occured to me after writing that

#

that burglar is like exactly what I need

#

i hope this works first try

#

(it didn't work)

#

is there a context for after a hand is played

#

i'm having trouble triggering an effect when there's 1 hand left

#

do I need to use event manager

wintry solar
#

context.after isn’t enough?

stiff locust
#

and it makes no sense to me cause this should be pretty simple to do

#

i made sure it's not in any other contexts that would conflict (it isn't)

wintry solar
#

Can you show the full code?

silent pawn
stiff locust
silent pawn
#

i do remember seeing a joker before that does it but i couldnt remember for the life of me where id seen it - asked here if anyone knew which mod it had come from but didnt get a correct answer

#

it was a joker that like carried over discards between blinds and they stack up beyond max but i cant find it for the life of me

wintry solar
stiff locust
#

none of them have worked

wintry solar
#

What’s it supposed to do?

stiff locust
# wintry solar What’s it supposed to do?

on final hand of round if its chips are above 100 (separate effect that is functional builds chips)
give 5 hands, give xmult equal to remaining discards until end of round, lose all discards

#

i'll probably have to move the xmult return to context.joker_main regardless but none of the other parts are working

wintry solar
#

so it's kind of like an extra chance at the blind?

stiff locust
#

yeah

#

oh and it resets the chips at the end of the round after it triggers

#

that's the easy part

wintry solar
#
if context.after and G.GAME.current_round.hands_left == 1 and card.ability.extra.chips >= 100 then
  print('test')
  card.ability.extra.Xmult = 1 + G.GAME.current_round.discards_left
  ease_discard(-G.GAME.current_round.discards_left)
  ease_hands_played(card.ability.extra.hands)
end
#

does this work

stiff locust
#

nothing else works

wintry solar
#

the hands and discards dont change?

stiff locust
wintry solar
#

huh

stiff locust
#

different problem came up after i triggered the effect

#

I was hoping I could use a table of strings to get new lines in the joker text

#

cause the way this secret effect stuff works is that there's a loc var at the end of the joker description which changes from a little bit of splash text hinting at the effect to the actual effect after you trigger it once

#

but the effect is too long to be put on one line

wintry solar
#

you can change the key of what description it's using in loc_vars

stiff locust
#

huh

#

like you can change the entire description or you can change the loc vars

wintry solar
#

the entire description

stiff locust
#

oh how

wintry solar
#

iirc you return {key = 'key'} in your loc vars return

stiff locust
#

so where do I put the changed description

#

and how do I trigger it

wintry solar
#

in the loc tables

stiff locust
#

what

wintry solar
#

how are you doing your localization?

stiff locust
#

am I supposed to be doing localisation

wintry solar
#

thats how you get any descriptions

stiff locust
#

i just put it in the loc_txt

brisk rose
#

loc stands for localization :P

stiff locust
#

disclaimer i'm fuckin stupid

wintry solar
#

so you either need to use SMODS.process_loc_txt() or set up a localization file properly then iirc

brisk rose
#

loc_txt is a localization table I'm p sure

crisp coral
#

How can I get the width of an UI node before it's created?

brisk rose
wintry solar
#

it adds stuff to the loc tables

crisp coral
stiff locust
brisk rose
#

So to add extra stuff to the loc tables it'd be SMODS.process_loc_txt({thing})?

stiff locust
#

oh jesus i'm fuckin

#

double stupid today

wintry solar
#

yeah there'll be some uses of it in the smods code you can reference

stiff locust
#

how does it know which joker to do it in

wintry solar
#

it doesn't need to, you just need to tell your joker to use that key later on

#

I can send some examples when I'm back home later

stiff locust
#

an example would help yeah

crisp coral
#

Okay uhh, different question.
Any way for an UIBox to be drawn on top of Cards and CardAreas without using .attention_text?

crisp coral
wintry solar
crisp coral
#

I've tried having "UIBOX" and "ALERT" for the instance_type and neither worked

wintry solar
#

Does ’TOOLTIP’?

#

And is it on the root element?

#

I have no idea how instance type works

crisp coral
#

TOOLTIP is not an instance type, no

#

And, it should be on root, I think

#
local blind_hoverref = Blind.hover
function Blind.hover(self)
  ...
  self.config.h_popup = G.UIDEF.blind_h_popup(self)
  self.config.h_popup_config = self:align_h_popup()
  self.children.h_popup = UIBox{
    definition = self.config.h_popup,
    config = {
      instance_type = "ALERT",
      major = self,
      parent = nil,
      xy_bond = 'Strong',
      r_bond = 'Weak',
      wh_bond = 'Weak',
      offset = {
          x = 0.15,
          y = 0.4,
      },  
      type = "cr",
    },
  }
  self.children.h_popup.attention_text = true
  self.children.h_popup.states.collide.can = false
  self.children.h_popup.states.drag.can = false
  ...
end
wintry solar
#

I wonder if it needs to be on the root element inside the definition

crisp coral
#

G.UIDEF.blind_h_popup does return a root node but I'm unsure

crisp coral
#

I'm thinking of making it a global instead, similar to G.achievement_notification or G.debug_tools

#

Then I can simply Lovely patch it into the Game:draw() function

wintry solar
#

yeah that should respect instance type

#

I would ahve though

timid parrot
#

for the purposes of making sure my mod is compatible with other mods that add suits, how do I get a list of all the suits (default {"Spades", "Hearts", "Clubs", "Diamonds"})?

rough furnace
#

I have a hacky way

#

but gimme a sec

#

oh you can just look up the SMODS.Suits table

timid parrot
#

Ah cool

#

And it contains all the vanilla suits too?

rough furnace
#

yeah

timid parrot
#

Alright thanks

teal estuary
#

is there a mod/example i can look at for how to turn one hand into another, using a joker?

rough furnace
#

like shortcut?

teal estuary
#

uhh, no, more like (this is the actual joker idea): if you play pair, it plays two pair

#

(or maybe thats done the same way under the hood? idk)

rough furnace
#

I think you can inject into the two pair poker hand

#

not sure

timid parrot
teal estuary
#

ty kindly

brisk rose
#

np :3

rough furnace
timid parrot
#

I was looping through ipairs(SMODS.Suits)

rough furnace
#

it doesn't use integer keys

timid parrot
#

so then what do I do?

rough furnace
#

use pairs

timid parrot
#

so for k,v in pairs(SMODS.Suits) but which one is the suit string k or v?

rough furnace
#

k is the key and v is the value

timid parrot
wintry solar
#

I imagine it’s the key you need

timid parrot
#

time to find out

rough furnace
timid parrot
#

all this to get this blind to work properly

silent pawn
#

whats the blind icon meant to be

#

squiggle

timid parrot
silent pawn
#

Ei

timid parrot
#

lol

silent pawn
#

anyone know where i can find the editions in the vanilla source?

wintry solar
#

all over the place

#

what are you trying to do?

silent pawn
#

i wanted to make an edition that didnt apply to jokers but i have no idea how

#

i was gonna see how negative stops itself from applying to playing cards

wintry solar
#

you'll have to hook set_edition until I get round to making editions respect in_pool

silent pawn
#

oh right so would i just set the edition to no edition if it has the custom edition?

#

thats a lot of the word edition in one sentence

#

how would you set a card to have no edition is it like you set the edition to nil?

#

also i have no idea how to like check the edition of each card in the buffoon packs

#

like i know i can use if context.open_booster and context.card.ability.name == 'Buffoon Pack' and then each name of each buffoon pack (jumbo etc)

#

but i dont know how to check the edition of cards

#

im guessing its going to be some sort of for loop to check each card but its the actual function for checking the edition that i dont know

wintry solar
#
local set_edition = Card.set_edition
function Card:set_edition(edition, immediate, silent)
  if edition == 'edition_key' and self.set == 'Joker' then return end
  set_edition(self, edition, immediate, silent)
end
#

this will stop your edition being applied to jokers

silent pawn
#

would this be under on_apply orr

#

sorry for so many questions i have literally zero experience with editions 😭

#

i cant even reference any editions because lshtechs card library is like completely bugged so i cant easily find editions to refer to

wintry solar
#

this is just top level of your code

silent pawn
#

oh alright

#

weight affects how often it applies right? is it higher or lower for more common

wintry solar
#

higher for more common

silent pawn
#

is there a max

#

im guessing not

#

im guessing editions use weight as a ratio to compare to other editions probabilities

wintry solar
#

that's how all weights work

#

base game are foil:20, holo:14, poly:3, negative:3

silent pawn
#

the edition is just never appearing

wintry solar
#

can you show the edition code?

silent pawn
#

wait would self.set == 'Playing' be correct or what would the equivalent be for playing cards

wintry solar
#

no

#

is this for a joker only edition now?

silent pawn
#

yeah

#

one for only playing cards one for only jokers

wintry solar
#

you can do self.set ~= 'Joker'

silent pawn
#

oh yeah

south karma
#

Messy AF, but I can't figure out why this is crashing on played hand (attempt to index field 'blind' [a nil value]

#
        calculate = function(self, context)                          
            if context.individual and not context.blind.boss then
                if pseudorandom('curio') < G.GAME.probabilities.normal/self.ability.extra.odds then   
                    G.E_MANAGER:add_event(Event({
                        func = (function()
                            G.E_MANAGER:add_event(Event({
                                func = function() 
                                    local card = create_card('The Chariot',G.consumeables,nil, nil, nil, nil, nil)
                                    card:set_edition({negative = true}, true)
                                    card:add_to_deck()
                                    G.consumeables:emplace(card)
                                    local card = create_card('Deja Vu',G.consumeables,nil, nil, nil, nil, nil)
                                    card:set_edition({negative = true}, true)
                                    card:add_to_deck()
                                    G.consumeables:emplace(card)
                                    return true
                                end})) 
                                    card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_plus_tarot'), colour = G.C.PURPLE})
                            return true
                        end)}))
                end
            end
        end,
#

The small/big blind select is from madness so I don't exactly know what's wrong

rough furnace
#

presuably you have a case where context.indivdual is true but there is no contex.blind

#

actually I don't think individual and a blind in context ever go together

south karma
#

Interesting I wonder where I even got that...
I also got way ahead of myself considering the card generation doesnt even work, certainly due to my table values

wintry swallow
#

Is there a list with explanations for each context?

flat pier
#

Not sure what's going on with things now...
Trying to make a deck start with a joker 'j_leveler'
Everything should be setup correctly, but I keep getting this error when I try to start a run with the deck

#

line 27 is card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_leveler')

rough furnace
#

I suspect your key is wrong

#

It should have your mod prefix in front

mighty stump
#

how do i make it so my custom deck gives you a persistent wee joker on start?

flat pier
rough furnace
#

No. Steamodded adds a prefix to your joker to prevent name collisions.

#

You just need to add the lrefix to the create_card call

flat pier
#

I am struggling to get this fixed, I've done every variation I could think and it's still throwing the error.

rough furnace
#

Do you define a prwfix in your mod header?

flat pier
#

yes, sjmp

rough furnace
#

Then your jokwe should be j_sjmp_leveler

flat pier
#

Appreciate the help.

mighty stump
mighty stump
#

Eternal sorry

#

I am tried after a long day of college heh heh

mighty stump
#

Is there any documentation on how this would be done?

opal spade
#

what does persistent mean

mighty stump
#

i miss spoke

#

I meant to say eternal

#

like cant be sold or destroyed

flat pier
#

One more oddity, now, when scoring the hand, my joker isn't adding it's chips or mult to the score.

mighty stump
flat pier
glossy stone
#

I won the 50/50 AGAIN so expect more work on original sound

crisp coral
#

What

#

How

glossy stone
#

This is how

fair mortar
#

Is context.after not supposed to be after scoring or I do have some deeper misunderstanding? This code is destroying cards before they're scored:

if not context.blueprint and (context.scoring_name=="Straight" or context.scoring_name=="Straight Flush") then
            card.ability.extra.trash_list = context.scoring_hand
            card.ability.extra.straight = true
        end
if context.after and card.ability.extra.straight and not context.blueprint then
            for _, card_to_trash in ipairs(card.ability.extra.trash_list) do
                if not card_to_trash.removed then
                    card_to_trash:start_dissolve(nil, nil, 3)
                    card_to_trash.destroyed = true                
                end
            end
            card.ability.extra.trash_list = {}        
            card.ability.extra.straight = false            
        end
maiden phoenix
#

Maybe try using context.end_of_round instead, careful tho it will trigger context.individual and repetitions so you'll prob have to exclude those

limpid sonnet
#

Hey, Trying to make a personal retexture for myself wondering if its possible to retexture the soul?

Ive tried with no luck to change its little... Floating Stone thing?

languid mirage
tepid sky
#

how can i check for played stone cards again?

timid parrot
#

check that either card.ability.effect == 'Stone Card' or card.config.center == G.P_CENTERS.m_stone (either one should return true for a stone card)

mystic river
#

is there a way to put a wild card (or enhancements in general) into the hand preview thing? i've been considering making a mod that just adds the spectrum hand + related stuff (planets, basic jokers) so suit mods can just require that instead of reimplementing it every time, and since this mod would ideally not add a new suit of its own the obvious preview hand is heart-diamond-club-spade-wild
-# alternately, did someone already make this mod and i just didn't find it

vague island
#

how does blue joker check how many cards are in your full deck?

vague island
#

oh cool thanks

timid parrot
tepid sky
#

ya i know, i looked at that trying to use it

#

for the counting

#

but i ended up creating something better for the counting lol

tepid sky
#

sorry if it sounds stupid

timid parrot
tepid sky
#

hmm

#

return in if .. then

#

thanks!

#

so this should work?

tepid sky
topaz sun
#

Does anyone know, in the game files, where is the part that ends the game with game over if the player doesn't reach the blind goal?

rough furnace
#

I think the function is lose_game

#

end_round is responsible for calling it when you run out of hands

topaz sun
#

Ooh, makes sense

#

Thanks!

hardy viper
#

i guess it can also be called naturally when you run out of handsize

rough furnace
#

Yeah or hit the lose game debug button

hardy viper
#

makes me wonder whether you still beat the blind if you run out of handsize with mr bones and meet the 25% score req

topaz sun
#

lose_game() didn't work, unfortunately

#

I'm trying to make a Russian roulette joker

rough furnace
#

I know end_round will behage as if you are done playing your hand

topaz sun
#

end_round bugs the game out somewhat

rough furnace
#

Just make sure not to call it when your not in the picking cards state or weird stuff happens

topaz sun
#

If saved= true

vague island
#

how do i find specific ranks in the full deck?

hardy viper
rough furnace
#

Does lose_round not exiat or just buf out?

vague island
hardy viper
topaz sun
#

It crashes saying attempt to call global lose_game (a nil value)

rough furnace
#

It must be named something eksw

#

Ley me check

vague island
#

oops

#

sent too soon

rough furnace
#

Oh it doesn't have a function like win_game, the debug button just does if G.STAGE == G.STAGES.RUN then G.STATE = G.STATES.GAME_OVER; G.STATE_COMPLETE = false end

hardy viper
#
local ranks = {}
for i, v in pairs(G.deck.cards) do
 ranks[v.ability.rank] = (ranks[v.ability.rank] or 0) + 1
end

something along these lines @vague island
it's probably not Card.ability.rank i just bullshitted that you'll have to find what actually stores rank yourself

#

huh

#

i can't exactly read the code if you delete it

rough furnace
#

Should probably use get_id

vague island
#

wait holup

rough furnace
#

I think that's what it'd called

hardy viper
vague island
#
        if context.joker_main then
            local deck = #G.deck.cards
            local decktable = G.deck.cards
            for _, v in pairs(G.deck.cards) do
                other_card = v
                if
                    v ~= card
                    and context.other_card:get_id() == 2
                    or context.other_card:get_id() == 3
                    or context.other_card:get_id() == 4
                    or context.other_card:get_id() == 5
                then
                    chip_mod = 35    
                    end
                end
            if deck then
                chip_mod = deck * 3
                end
            end
        end
    }
rough furnace
#

Works with stone cards and some modded shenanigans

vague island
#

i think i see what im doing wrong :P

hardy viper
#

for one get_id() <= 5 would suffice

#

idk why ur checking all of those

wintry solar
#

What are you trying to do exactly?

topaz sun
#

Yeah, I was trying to use G.GAME.GAME_OVER, but then it doesn't interact with jokers like Mr. Bones

vague island
#

good point

rough furnace
vague island
rough furnace
#

Hold on

wintry solar
#

That’s just going to always set the chip mod to deck size * 3

hardy viper
vague island
rough furnace
vague island
#

my brain is soup

vague island
#

idk how to do both lol

tepid sky
rough furnace
hardy viper
tepid sky
topaz sun
#

Thank you so much!

rough furnace
#

Make sure you remove the semicolon variable setting otherwise you'll never lose when cryptid is installed

topaz sun
#

Will do 🫡 . Max compatibility is the goal

rough furnace
#

Also not sure but if thus can go off on the last hand it might end up not activating until you start your next blind make sure that can't happen

topaz sun
#

I'll fiddle around with this a bit, see what's what

wintry solar
# vague island idk how to do both lol

Something like this should work

if context.joker_main then
local chip_mod = 0
  for _, v in pairs(G.deck.cards) do
    if v:get_id() <= 5 then
      chip_mod = chip_mod + 35
    else
      chip_mod = chip_mod + 3
    end
  end
  return {
     chip_mod = chip_mod,
    card = card,
     message = ‘localise the chips here pls’
  }
end```
#

Code might be scuffed, typing in mobile box is hard

hardy viper
#

looks good to me but im on mobile too so 🔥

rough furnace
#

<= 5 matches stone cards (which are random low negatives)

vague island
#

its a feature, not a bug

teal estuary
#

wouldn’t that also get any card below 5? or am i reading the code wrong 😭

vague island
#

thats the point :)

teal estuary
#

OH

#

i getcha

vague island
#

like hack but blue

teal estuary
#

i thought, by what wilson said, it was only going for stone cards

teal estuary
vague island
#

(spoiler: ||its weezer's blue album||)

teal estuary
#

that is such a good idea for the weezer album

#

i wish i thought of that

vague island
#

lol

#

i feel you dude, i tried making frowny face (ortalab took that)

tepid sky
wintry solar
tepid sky
#

quick question, how do i check for the winning hand?

mystic river
#

this is supposed to trigger twice on a 3 of 3s, but it doesn't for some reason
it is triggering correctly on both 3s (suit) and 3s (rank)

    calculate = function(self, card, context)
        if context.cardarea == G.play then
            if context.other_card:is_suit('Minty_3s') then
                return {
                    mult = card.ability.extra.s_mult,
                    card = card
                } end
            if context.other_card:get_id() == 3 then
                return {
                    mult = card.ability.extra.s_mult,
                    card = card
                } end
            end
    end```
rough furnace
#

you can only return from a function once

#

I think you can dispatch an event

#

you could keep a vraible and do 2x for if both are ture

wintry solar
#

Or use SMODS.eval_this()

wintry swallow
#

"Oh Steammodded has a least some comments!" The comments: -- why bother patching when i basically change everything

teal estuary
#

😭

south flume
#

can anyone here help me with how to make jokers blueprint compatible?
i have zero clue where to even start

humble gale
#

Im having a problem that when cards are destroyed by the joker, random spots appear in the hand. Anyone know why?

if context.after then
       G.E_MANAGER:add_event(Event({
           trigger = 'after',
           delay = 0.2,
           func = function() 
               for i = 1,#context.scoring_hand do
                   if pseudorandom('cream') < G.GAME.probabilities.normal / card.ability.extra.odds then
                       local checkCard = context.scoring_hand[i]
                       checkCard:shatter()
                   end
              end
        return true end }))

        return {
            message = "Obliterate!",
            remove = true
       }
end
crisp coral
#

Do not destroy cards during scoring contexts

humble gale
#

what context should i use if i want them to destroy after they are scored

crisp coral
#

Use context.destroying_card (ex. Sixth Sense)

humble gale
#

ah okay

#
if context.destroying_card then
            for i = 1,#context.scoring_hand do --Error
                if pseudorandom('cream') < G.GAME.probabilities.normal / card.ability.extra.odds then
                    local checkCard = context.scoring_hand[i]
                    checkCard:shatter()
                end
            end
                
            return {
                message = "Obliterate!",
                remove = true
            }
        end

im getting an error on the line with the comment saying it is a nil value

#

becuase it tried taking the length

#

i changed it to full hand and it worked

south flume
topaz sun
rough furnace
#

cause your waiting for it to draw the cards before ending the round

tame gale
#

Hey, I'm interested in making a mod. How much coding knowledge do I need to start modding?

spare elk
#

if you have enough mods to copy code from then you pretty much don't need anything /j

tame gale
#

I guess you've got a point there, I could always look at what other mods do to know how to do things. I guess let's start with the... I don't even know if this is basic at all but I think it might be since there's a few mods dedicated to it. How do I add new hands?

lament zealot
tame gale
#

Also the Fibonacci guy and the Blackjack guy.

hardy viper
#

ask the guy and the guy imo

tame gale
#

Alright. Should I DM them or just ask in the mods' forums?

spare elk
#

i'd say you should ask on the forums first and if no one answers after a while send a dm or two

tame gale
#

Okay.

flat pier
#

I'm trying to make a seal that modifies the base scoring of a card, is there any example of tutorial on setting up a seal that changes how the card scores?

flat pier
#

Rather, I'm trying to make a card edition like lucky cards, changing the texture of the card, but I can't find any reference anywhere....

rough furnace
#

I love sitting and writing code for a hour or two without testing it at all

crisp coral
#

Mood

tepid sky
rough furnace
#

Thats why I made watch for DebugPlus

#

I did develop this feature using it mostly

#

but now I'm refacoring it into the codebase

#

and I had to add a bunch of checks

#

anyways moment of truth

tepid sky
#

I. Love. Debugplus

#

:)

rough furnace
#

oh I think I accidently depdned on a mod

#

how do I get the type of card from it's center

#

oh .set

#

not sure why eval didn't show thart

hybrid iris
#

hi!
im,, trying to make a custom poker hand that overrides two pair if it's a dead man's hand (two black aces and eights) and while i have most of the pokerhandpart things down, it doesnt seem to be loading properly (and crashes if i open up the hand list)

#

its, probably a really simple fix, but i cant tell what it is i need to look at djshsdjh

#
    key = 'deadhand',
    func = function(hand)
        local current_cards = {}
        local activated = false
        for i = 1, #hand do
            table.insert(current_cards, hand[i])
        end
        if G.jokers ~= nil then
            for _, v in ipairs(G.jokers.cards) do
                if v.config.center.key == 'j_tma_Gunslinger' then
                    activated = true
                    print("hasGunslinger")
                else
                    activated = false
                    print("noSlinger")
                end
            end
        end
        local ace_black = 0
        local eight_black = 0
        for i = 1, #hand do
            if hand[i]:get_id() == 14 and (hand[i]:is_suit("Spades", nil, true) or hand[i]:is_suit("Clubs", nil, true)) then
                ace_black = ace_black+1
                print("ace", ace_black)
            elseif hand[i]:get_id() == 8 and (hand[i]:is_suit("Spades", nil, true) or hand[i]:is_suit("Clubs", nil, true)) then
                eight_black = eight_black+1
                print("eight", eight_black)
            end
        end
            if eight_black >=1 and ace_black >=2 and activated then
                print("has hand!!!")
                return {hand}
            end
        return {}
    end
}

    SMODS.PokerHand{ -- Dead Man's Hand
        key = 'dead',
        above_hand = 'Flush Five',
        visible = false,
        chips = 0802,
        mult = 1876,
        l_chips = 0,
        l_mult = 0,
        example = {
            {S_8, true},
            {C_A, true},
            {S_A, true},
            {C_8, true},
        },
        evaluate = function(parts)
            return parts.deadhand, parts._all_pairs
        end
    }

code to go with it

tepid sky
#

reverse pareidolia:

local is_face_Ref = G.FUNCS.is_face()
function G.FUNCS.is_face()
  local id = context.other_card:get_id()
    if id == 11 or id == 12 or id == 13 and SMODS.find_card('j_mini_faceblind') then
       return false
    end
local result = is_face_Ref() -- top = before, bottom = after 
return result
end

somehow it just isn't working?

wintry solar
#

Because that’s not what the function is called

#

It’s Card:is_face()

tepid sky
#

does that mean i cannot hook it?

wintry solar
#

No you can hook it, you’re just trying to hook a function that doesn’t exist

flat pier
#

I can't find any info on setting a custom face texture like lucky cards anywhere. I've looked. Are there any examples or tutorials on making an enhancement that changes the face texture?

tepid sky
#

or spesific texture if for example a facecard is gold?

#

or perhaps, making your own enhancement?

flat pier
#

It would be my own enhancement, but one that only changes the texture of the face card. Like how a lucky card looks like old paper.

tepid sky
#

a way to change the looks of ingame stuff without messing with the code

flat pier
#

Not just a texture pack, The enhancement will be a knockoff-clone of a played card that has a unique scoring function. It will be created by a joker I have already made. I'm not looking to change the games texture packs

tepid sky
flat pier
#

I've tried looked into cryptid, to figure out how echo cards were done, but I can't find any reference in the source code where the enhancement is declared, nor can I find any reference on the eclipse deck

tepid sky
#

crypid's code looks just like the base source code

flat pier
#

Looking through the games source code is equally fruitless

mellow sable
tepid sky
#

so i personally find it hard to make sense out of both of them

#

i prefer looking at things like this: simple joker, has name, some text, but does overall nothing

#

the most basic and easiest struckture

rough furnace
#

and then the lovely patch to make it work

hardy viper
#

sounds like my worst nightmare

tepid sky
rough furnace
#

lovely isn't that bad

hardy viper
#

it's just so unnecessary in a lot of cases

rough furnace
#

yes but also the best way to do things in a lot of cases

hardy viper
#

and it makes reading a mod quite a bit harder

rough furnace
#

depends

hardy viper
#

i can't imagine any situation where digging through a patch file would be easier than just reading the code as it appears in a normal file

tepid sky
tepid sky
rough furnace
hardy viper
#

ain't talking about that

rough furnace
#

?

flat pier
rough furnace
#

thats the point of lovely

#

to patch things in

hardy viper
rough furnace
#

well its technically never nessicary but it's better in a lot of cases

hardy viper
#

lovely is sometimes used where it isn't necessary which makes things harder to look at

rough furnace
#

theres a reason SMODS moved to it

hardy viper
#

which no good mod should do without a very good reason

rough furnace
#

I'm confused on what your argument is then?

hardy viper
#

sucks for you I guess

hardy viper
#

idk what you expect me to say I don't want to go through an entirely separate file to find something

#

i would much rather look at the first one even if that lovely patch takes up less space

rough furnace
#

wait until you see how DebugPlus is structured

#

(dev branch)

hardy viper
#

ain't it just like 8 properly organized lua files

#

seems alright to me

rough furnace
#

7 but they some are farily tightly coupled

#

like watcher is pretty much a component of console

hardy viper
#

do while true do repeat until true or false break end if not false and true then end do return end end imo

#

oh wait

#

i didn't structure that right

#

yeah

rough furnace
#

reminds me of this

hardy viper
#

goto moment

#

i use it as a continue keyword and nothing else fore

rough furnace
#

yeah

hardy viper
#

where is my lua longjmp

#

smh !!

mellow sable
#

Didn’t even know Lua has goto

#

That feels really cursed

hardy viper
#

i didn't for awhile either

rough furnace
#

Yeah I didn't but I tried using contiune and it didn't work so I googled it and they were just like use goto

hardy viper
#

i actually figured it out by typing in continue and luals corrected it to goto continue with a ::continue:: at the end of the for loop

rough furnace
#

thats actually the second time I've used goto in DebugPlus

tepid sky
#

can we even do enhancements?

#

my brain is melting

rough furnace
#

yes

tepid sky
#

i tought i knew how to make it but now i am not that sure

rough furnace
#

I'm pretty sure we can do all of those in the screenshot

flat pier
#

My brain is also melting looking for any information on how to change a playing cards atlas when it is enhanced...or change the texture coordinates

rough furnace
#

likw what is your goal?

flat pier
#

I have a joker that makes (poorly) cloned coppies of played cards. I want to give them a different face texture, like a lucky card/echo from cryptid, that makes them look distinguishable from a normal playing card. The joker is done, it makes cards and adds them to the deck, I have seen how to add enhancements to created cards. I just have no reference to changing a playing cards atlas, or texture coordinates when the enhancement is applied. I would like to avoid a shader, if possible.

rough furnace
#

by face do you mean the base of the card?

#

Like these

flat pier
#

yes, lucky card changing the texture to yellowed worn paper

#

like that

rough furnace
#

you should just be able to provide the atlas and pos to the constructor, like you would in a joker

flat pier
#

Hmm, okay. lets give that a shot then.

tepid sky
#

can someone tell me what i did wrong, i got a loda of help from larswijn (thanks!) but it is still not working like i would want it to?

#

expected:
reversed pareidolia:
all facecards are numbered cards

gotten:
face cards are numbered cards BUT numbered cards are face cards

rough furnace
#

your not calling is_faceRef

tepid sky
#

??

rough furnace
#

it's a function

#

you're not calling it

tepid sky
#

how?

rough furnace
#

()

flat pier
#

local result = is_faceRef()

rough furnace
#

You should understand the basics of how lua works

tepid sky
tepid sky
tepid sky
#

oh-

#

smth happend

tepid sky
#

:OOO

#

it works!

#

:D

flat pier
#

How would I go about setting a cards base chips to half the original value

#

This is for an enhancement, I know I have to mess with the nominal. somehow.

humble gale
#

Im trying to reduce the ante by 1 but this code is doing, well 14 times. anyone know why? Im thinking its the ease ante

if context.end_of_round and G.GAME.blind.boss and not context.blueprint then
           local ante_mod = 0
           if to_big(G.GAME.chips) >= to_big(G.GAME.blind.chips) * card.ability.extra.scoreRec then
               ante_mod = ante_mod - card.ability.extra.ante_reduction
               ease_ante(ante_mod)
           end
       end
flat pier
#

Would this result in the cards chip scoring being set to newbase if placed in calculate?

        chips = newbase,
        message = localize({type = 'variable', key = 'a_chips', vars = {chips}}),
})```
crisp coral
#

vars = {newbase}

#

but yes

mellow sable
#

Try printing the contexts it’s calling on

#

I think you might also need to add not context.repetition and/or not context.individual as checks

flat pier
#

I have a joker that does something at the end of round, the contexts string is lua if context.end_of_round and not (context.individual or context.repetition) then

#

also a check for blueprint in there

static cairn
#

help ik this is an error but how do i fix it

flat pier
#

Is there a function that I can use when an enhancement is placed on a card?

wintry solar
#

Card:set_ability() is what puts enhancements on a card

tepid sky
#

is there a context for winning hand?

maiden phoenix
#

winning hand as in the hand you won at or the poker hand you won with?

#

Usually you use end_of_round and check if the goal was reached

tepid sky
maiden phoenix
#

What action do you want to do on the winning hand?

tepid sky
#

i want to- oh? modlitch changed the joker a bit

#

how do i destroy smth from the full deck?

#

@nocturne garnet yk how u help me make silly? and how it destroys a card from the played hand (on last hand)

#

could you please help again? we need to change it a tiny bit to destroy something out of the deck

fast bronze
#

chat uhm

#

i suddenly got an idea

#

for like a cryptid addition

#

or smth

#

just a funni joker

#

that scales off meme jokers

wintry swallow
#

Where do I find the chips scored so far in a hand? The chips part, that is, not the mult. I want to manipulate it with a joker

hardy viper
#

G.GAME.chips iirc

#

might be G.GAME.blind.chips or smth lemme check

#

ok yeah

#

G.GAME.chips

#

G.GAME.blind.chips is the score requirement i guess

wintry swallow
#

No G.GAME.chips is already multiplied by the mult

#

Ooh but maybe I can look what is put into the UI

#

It's G.GAME.current_round.current_hand.chips
I just need the context after hand chips are added

crisp coral
#

dread

#

im tryna modify the returned values but it completely broke calculating lol

timid parrot
torn grove
#

I'm interested in making a mod. How much coding knowledge do I need?

spare elk
#

find enough mods to steal code from /j

slow parcel
#

im just wanting api documentation on balatro

#

like how they learned this:

#
local Calculate_reroll_costRef = calculate_reroll_cost

function calculate_reroll_cost(skip_increment)
    Calculate_reroll_costRef(skip_increment)

    G.GAME.current_round.reroll_cost = 0
end
spare elk
#

i basically forgot everything from my coding class and i was able to create a joker fairly easily

#

just be sure not to forget to close your brackets and such

timid parrot
torn grove
#

absolutely none

timid parrot
#

I mean it depends on what you want to do, but aside from being able to follow instructions, you'll likely need to know:

  • Variables
  • Conditionals (if/else)
  • Boolean Logic
  • Loops (for and while)
  • Tables/Objects in Lua
  • Functions as functions
  • Functions as variables
  • How to read other people's code so you can understand how the framework works

I learned Lua for the first time while doing this, but I've had a decent bit of prior programming experience. I'm not sure if there are Lua tutorials for people who have never programmed before, but if there are, you should go looking for those. Otherwise, it would probably do you good to look into Python to pick up some basic skills and then apply them to Lua.

slow parcel
#

where are game actions stored

timid parrot
primal robin
#

Anywhere ehehe

#

Card creating can be in UI for example pretty easily

slow parcel
#

i tried it in python using opencv, using image identification. my python code successfully identified reroll in the shop, but having it locate cards i wanted was difficult due to images looking similar on tarot cards

#

so, i tried using tesseract ocr instead to get the text then get the x,y coord to send a mouse click event

#

but that also proved painful

timid parrot
#

apparently G.FUNCS.reroll_shop is a function defined in button_callbacks.lua

primal robin
#

It's not enough. You should check can you reroll first

slow parcel
#

it can reroll

#
local Calculate_reroll_costRef = calculate_reroll_cost

function calculate_reroll_cost(skip_increment)
    Calculate_reroll_costRef(skip_increment)

    G.GAME.current_round.reroll_cost = 0
end
timid parrot
#

G.FUNCS.can_reroll is also defined in button_callbacks

slow parcel
#

i found this for setting the reroll to zero. it was shared here on the discord, this works. its cool

slow parcel
#

but this looks like its primarily the math logic behind it (unless im missing something)

#

i saw someone made a bot using this

#
Bot.ACTIONPARAMS[Bot.ACTIONS.REROLL_SHOP] = {
    num_args = 1,
    func = "select_shop_action",
    isvalid = function(action)
        if G and G.STATE == G.STATES.SHOP and (G.GAME.dollars - G.GAME.bankrupt_at - G.GAME.current_round.reroll_cost >= 0) then
            return true
        end
        return false
    end,
}
#

but im not privy enough with the games internals to understand what this means exactly, the select_shop_action looks like a sql query (???), so many its related to this api snippet?

primal robin
#

No it isnt. Most likely it's unique key for bot action or smth

#

Game doesn't have any actions

slow parcel
#

gotcha

primal robin
#

All actions in game controlled by events

slow parcel
#

gotcha, so ui action triggers or fires the event

#
function calculate_reroll_cost(skip_increment)
    if G.GAME.current_round.free_rerolls < 0 then G.GAME.current_round.free_rerolls = 0 end
    if G.GAME.current_round.free_rerolls > 0 then G.GAME.current_round.reroll_cost = 0; return end
    G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase or 0
    if not skip_increment then G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase + 1 end
    G.GAME.current_round.reroll_cost = (G.GAME.round_resets.temp_reroll_cost or G.GAME.round_resets.reroll_cost) + G.GAME.current_round.reroll_cost_increase
end
#

ah i see this in the event handler

#
G.FUNCS.reroll_shop = function(e) 
#

ah, there it is

#

so, i guess my question now, is it possible to loop an invocation of this function?

#

or is that not really a thing with steamodded?

primal robin
#

Let's assume you want reroll a shop and check jokers for buying.
Your code will look like this:

function iterate_shop()
    G.E_MANAGER:add_event(Event({
        func = function()
            for i, card in ipairs(G.shop_jokers.cards) do
                if is_joker_im_looking_for(card) then
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            -- Check for ability to buy card and then buy. Good luck)
                            return true
                        end
                    }))
                end
            end
            G.E_MANAGER:add_event(Event({
                func = function()
                    G.FUNCS.reroll_shop()
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            -- Here, you can call next iteration
                            return true
                        end
                    }))
                    return true
                end
            }))
            return true
        end
    }))
end
slow parcel
#

what the

primal robin
#

welcome to balatro

flat pier
# wintry solar `Card:set_ability()` is what puts enhancements on a card

Let me be a bit more specific. I want to make an enhancement that sets the base chips of a card to half the original value. I want it to only score half the chips the card normally would. I'm not sure how to grab the original chip value from inside the calculate tab, and having a way to grab that value when the enhancement is added and set it for later use would be very helpful.

#

The bulk of the enhancement's code is done. It can be applied to cards, but without the original cards base chips, it isn't going to work

nocturne garnet
#

i'd assume if you destroy a random card in G.deck.cards (or G.hand.cards if theres no cards in deck) then it'd work

#

havent done anything in a while so i might be wrong lol

mighty stump
#

How does one make you start a deck with a joker already in your hand?
I want to make it so where if you select the deck I am making an eternal wee jokers gets put into your hand

tepid sky
nocturne garnet
#

im ngl i forgot all of it

#

the only remnant is the 127 pictures of texts

tepid sky
flat pier
#

It seems I need to make an edition, not a enhancement

#

Editions have on_apply and on_remove abilities

#

sigh

nocturne garnet
#

idfk

tepid sky
#

Lol

#

Alr

hardy viper
#

well, I did it myself, without any balatrobot api stuff

#

but regardless

slow parcel
#

i normally do c++ WINAPI stuff, windows internals stuff

#

so this is outside my realm of study (i also hate it, im weird and dont like lua syntax, it hurts my brain)

hardy viper
# slow parcel how did you accomplish it?

i dont remember exactly, it was pretty much the first thing i did when i started modding
i suppose as a fun little exercise for myself ill write it again from scratch, extensively comment it, and send it here

flat pier
#

Well, I managed to get the enhancement to score, but it still scores the base chips of the card, is there any way to disable the base nominal of the card played, or overwrite it?

#

Would that be something to do in the toml portion?

wintry solar
#

You can either modify the base chips when the enhancement is added, or hook the function that gets that amount and manipulate it if your enhancement is present

hardy viper
#

@slow parcel here ya go, you can edit the specific cards you want it to buy in the file, the defaults i put in there to test it are blueprint, brainstorm, and showman
note that you toggle it on and off with 0, its on by default, and it can crash if you try to exit the shop while its running

slow parcel
#

did it work for u?

hardy viper
#

ya

#

only reason i can imagine it wouldnt work is if you didnt unzip it or smth

#

or if steamodded isnt installed or smth

slow parcel
#

nah, its in there, and its loaded

hardy viper
#

remove freereroll.lua

slow parcel
#

ok

#

sec

#

nah, still not working

#

wait

#

hold on

hardy viper
#

i imagine its still 0

#

since

#

yk

#

freereroll

slow parcel
#

nah hold on, i did an oopsy, that times its on me

hardy viper
#

oh

slow parcel
#

ah now its working

hardy viper
#

nice

slow parcel
#

weird

#

guess it was a conflict

hardy viper
#

freereroll sets the cost of rerolls to 0 24/7, the method that i used to properly wait until it actually can reroll again is to check whether the reroll cost isnt 0 (as an indicator of whether the game has set the reroll cost yet)

#

and of course if the reroll cost is always 0 then itll always be waiting for it to not be 0

slow parcel
#

oh it doesnt actually use the tarot cards though

#

it just buys them

hardy viper
#

ya

#

one sec

slow parcel
#
                    G.FUNCS.buy_from_shop({                                   --then buy it
                        config = {
                            ref_table = card
                        }
                    })
#

guess buy and use?

#

not sure on what functions youd use

hardy viper
#

youd have to differentiate between consumeables and non-consumeables

#

i have somethign working dw

#

should work well enough

slow parcel
#

damn bros cookin

#
Oops! The game crashed:
card.lua:1591: attempt to index local 'eligible_card' (a nil value)

Additional Context:
Balatro Version: 1.0.1m-FULL
Modded Version: 1.0.0~ALPHA-1031a-STEAMODDED
Love2D Version: 11.5.0
Lovely Version: 0.6.0
Steamodded Mods:
    1: Uncap Hermit by Infarctus [ID: Uncap_Hermit]
    2: Choose First Shop Joker by infarctus [ID: choose_first_shop_Joker]
    3: Shop Reroller by cg [ID: shopreroller]
    4: spacereroll by sishui [ID: spacereroll]
Lovely Mods:

Stack Traceback
===============
(3) Lua field 'func' at file 'card.lua:1591'
Local variables:
 over = boolean: false
 eligible_card = nil
 edition = table: 0x12a4c088  {polychrome:true}
 (*temporary) = string: "Hex"
 (*temporary) = nil
 (*temporary) = table: 0x12a4c060  {}
 (*temporary) = nil
 (*temporary) = nil
 (*temporary) = Lua function '?' (defined at line 292 of chunk functions/misc_functions.lua)
 (*temporary) = number: 0.0309498
 (*temporary) = string: "%.13f"
 (*temporary) = number: 0.0309498
 (*temporary) = string: "0.0309497880069"
 (*temporary) = string: "attempt to index local 'eligible_card' (a nil value)"
(4) Lua method 'handle' at file 'engine/event.lua:55'
Local variables:
 self = table: 0x133a3d88  {start_timer:true, timer:TOTAL, blockable:true, trigger:after, func:function: 0x133a3d60 (more...)}
 _results = table: 0x128a68f8  {blocking:true, pause_skip:false, time_done:true, completed:false}
(5) Lua method 'update' at file 'engine/event.lua:182'
Local variables:
 self = table: 0x12cc5cc0  {queue_last_processed:49.399999999998, queues:table: 0x12cc5ce8, queue_dt:0.016666666666667 (more...)}
 dt = number: 0.0166407
 forced = nil
 (for generator) = C function: next
 (for state) = table: 0x12cc5ce8  {unlock:table: 0x12cc5d10, other:table: 0x12cc6188, tutorial:table: 0x12cc5d60 (more...)}
 (for control) = number: nan
 k = string: "base"
 v = table: 0x12cc5d38  {1:table: 0x129dc2d0, 2:table: 0x133a3d88, 3:table: 0x133a4090, 4:table: 0x133a4300 (more...)}
 blocked = boolean: false
 i = number: 2
 results = table: 0x128a68f8  {blocking:true, pause_skip:false, time_done:true, completed:false}
(6) Lua upvalue 'gameUpdateRef' at file 'game.lua:2502'
Local variables:
 self = table: 0x126cd5e0  {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x1313fb40 (more...)}
 dt = number: 0.0166407
 http_resp = nil
(7) Lua method 'update' at Steamodded file 'core/ui.lua:81' 
Local variables:
 self = table: 0x126cd5e0  {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x1313fb40 (more...)}
 dt = number: 0.0166407
(8) Lua upvalue 'oldupd' at file 'main.lua:965'
Local variables:
 dt = number: 0.0166407
(9) Lua field 'update' at file 'shopreroller.lua:81' (from mod with id shopreroller)
(10) Lua function '?' at file 'main.lua:909' (best guess)
(11) global C function 'xpcall'
(12) Love2D function at file 'boot.lua:377' (best guess)
Local variables:
 func = Lua function '?' (defined at line 880 of chunk main.lua)
 inerror = boolean: true
 deferErrhand = Lua function '(Love2D Function)' (defined at line 348 of chunk [love "boot.lua"])
 earlyinit = Lua function '(Love2D Function)' (defined at line 355 of chunk [love "boot.lua"])
slow parcel
#

never seen balatro implode before locally. p cool

#

thank god its got a copy to clipboard function

hardy viper
slow parcel
#

1 its working
2 its taking over 9000 rerolls to get the card i wanted

#

lmfao

#

but ya, it works flawlessly, this is so sick

#

tysm @hardy viper

hardy viper
#

nice

tepid crow
slow parcel
#

and go for inf with it

#

without cheating too much

#

and also getting tons of pluto cards

tepid crow
#

ah okay 😅

slow parcel
#

i once tried going for inf by doing x mult per card in deck

#

but once i had like, 250 cards, my game was dying of resource exhaustion

nocturne garnet
#

oh man i sure do love sucking at coding

#

why cant i do the simplest thing

slow parcel
mental nacelle
#

what are you trying to do

nocturne garnet
#

all i did was try to put a function in a table......

#

table being G.GAME.....

#

well atleast being inside g.game

#

unfortunately i kinda suck ass and i probably did something wrong

edgy reef
#

The game cannot save a function

#

and G.GAME is saved iirc

nocturne garnet
spare elk
#

is there a way to check whenever a card is played instead of scored? trying to make a scaling joker off of 3s but i dont wanna make it too op with hack and stuff like that

nocturne garnet
#

ubiquity's evil twin

nocturne garnet
#

(in context.before obv)

spare elk
#

this is not so obv to me im still very new to this stuff

nocturne garnet
#

it works yippee

spare elk
#

why did i think the negative one was this for a second (warning, spoopy trollge)

nocturne garnet
spare elk
gilded narwhal
slow parcel
#

thanks to shop reroll, naneinf was easily achieved

#

v cool

#

but, the game is laggy as hell. has any experienced this, or seen this?

cerulean rose
#

i'm trying to make a new booster pack, but the cards are showing up squished together, can anyone figure out why?

SMODS.Booster({
    key = "workshop",
    kind = "Tarot",
    no_doe = true,
    pos = { x = 1, y = 0 },
    config = { extra = 3, choose = 1 },
    weight = 0,
    draw_hand = true,
    -- update_pack = SMODS.Booster.update_pack,
    loc_vars = SMODS.Booster.loc_vars,
    ease_background_colour = function(self)
        ease_background_colour_blind(G.STATES.TAROT_PACK)
    end,
    create_UIBox = function(self)
        -- G.GAME.pack_size = 3
        return create_UIBox_arcana_pack()
    end,
    particles = function(self)
        G.booster_pack_sparkles = Particles(1, 1, 0, 0, {
            timer = 0.015,
            scale = 0.2,
            initialize = true,
            lifespan = 1,
            speed = 1.1,
            padding = -1,
            attach = G.ROOM_ATTACH,
            colours = { G.C.WHITE, lighten(G.C.PURPLE, 0.4), lighten(G.C.PURPLE, 0.2), lighten(G.C.GOLD, 0.2) },
            fill = true
        })
        G.booster_pack_sparkles.fade_alpha = 1
        G.booster_pack_sparkles:fade(1, 0)
    end,
    create_card = function(self, card, i)
        if i == 1 then
            return create_card("Tarot", G.pack_cards, nil, nil, true, true, "c_death")
        elseif i == 2 then
            return create_card("Tarot", G.pack_cards, nil, nil, true, true, "c_hanged_man")
        else
            return create_card("Tarot", G.pack_cards, nil, nil, true, true, "c_hermit")
        end
    end,
    group_key = "k_tarot_pack",
})
flat pier
#

I'm using set_ability to apply my enhancement, but the game keeps throwing an error and I'm not sure what is going on

timid parrot
# gilded narwhal

looks cool. I wonder if you could have an alternate version for high contrast cards (would probably require code injection)

timid parrot
flat pier
#
        card.ability.extra.hnum = card.ability.extra.hnum + 1
        if card.ability.extra.hnum > 0 then
          for i = 1, card.ability.extra.hnum - 1, 1 do
            G.playing_card = (G.playing_card and G.playing_card + 1) or 1
            local _card = copy_card(context.full_hand[1], nil, nil, G.playing_card)
            _card:set_ability('coppied_card')
            _card:add_to_deck()
            G.deck.config.card_limit = G.deck.config.card_limit + 1
            table.insert(G.playing_cards, _card)
            G.deck:emplace(_card)
            _card:start_materialize()

    end``` 
The rest of the function works fine, creating a copy of the card and adding it to the deck
timid parrot
#

what's the code for that look like?

flat pier
#

steammodded and there is an accompanying toml

timid parrot
flat pier
#

sjmp

timid parrot
#

so the full center key I believe would be 'c_sjmp_coppied_card'

#

try passing that into set_ability

mellow sable
timid parrot
#

man just reinvented cookie clicker

flat pier
#

It is now throwing a completely different error for config

timid parrot
mellow sable
flat pier
timid parrot
#

oh right it's m_ not c_

#

I'm pretty sure

flat pier
#

The enhancement had been placed on a card by another card previously, so I know that functions.

#

But when I go to add it on it errors

timid parrot
#

strange

#

what's the code creating the enhancement look like?

flat pier
#
local copy_card = SMODS.Enhancement {
  key = 'copied_card',
  atlas = 'sprotsAtlas',
  loc_txt = {
        name = "Coppied card",
        label = "Coppied card",
        text = {
            "Earn half base {C:chips}chips{} when",
            "this card is scored"
        }
    },
  unlocked = true,
  discovered = true,
  pos = { x = 2, y = 0 },
  config = { 
    newbase = 0,
  },
  replace_base_card = false,
  no_suit =  false,
  no_rank = false,
  weight = 0,
  overrides_base_rank = false,
  any_suit = false,
  always_scores = false,
  loc_vars = function(self, info_queue, card)
    return { vars = { self.config.newbase } }
  end,
}```
timid parrot
#

oh copied_card not coppied_card

flat pier
timid parrot
#

I do believe copied is the correct spelling btw

flat pier
#

same error, though it was a typo

flat pier
#

removing the set_ability call returns it to working order.

nocturne garnet
tepid sky
#

anyone know if something is wrong with context.selling_self?

tepid sky
tepid sky
nocturne garnet
tepid sky
tepid sky
nocturne garnet
#

random one

stiff locust
#

alright time to try this again

#

how do I add temporary hands and discards

#

ease_discard and ease_hands_played aren't working

wintry solar
stiff locust
#

in context.after and with two other conditions which are triggering normally

#

the code gets to the lines in question, but doesn't change hands/discards

#
ease_discard(-G.GAME.current_round.discards_left, nil, true)
ease_hands_played(card.ability.extra.hands)
#

it doesn't crash either, they just don't happen

wintry solar
#

If you throw a 1 in there does it work?

stiff locust
#

oh hold on i'm getting an atlas crash

#

do mod atlases need to use the mod prefix now?

wintry solar
#

No

stiff locust
#

this crash doesn't make sense to me

#

didnt happen last time i tried this, so I do think its a steamodded update that changed how something worked

#

and idk how to fix it

wintry solar
#

Did you change a path or delete a file by mistake?

stiff locust
#

i got busy suddenly

#

a-

#

wait

#

the

#

the atlas is GONE

#

how did that happen

crisp coral
#

is target = "=[SMODS _ \"core/overrides.lua\"]" supposed to be the correct target for patching smods files?

hardy viper
#

that doesnt work rn iirc

#

at least, not for the nested smods files

#

lemme see if i can find that conversation

meager canopy
#

im interested in looking how to make my own deck for balatro, is there any sort of community guide for looking how to get started in modding

crisp coral
#

explode

hardy viper
#

💥

crisp coral
#

okay then uhh can someone assist with making this. Actually Run

hardy viper
#

seems like something youd hook eval_card for idk

#

im unsure though i never worked w scoring

crisp coral
#

i already have an eval_card hook, but mult_mod does not go through that

spare elk
#

ok so i've got up to here but i have no idea why it doesn't work now
im trying to make a joker that scales every 3 played (not scored)
tells me theres something wrong with line 69 (nice) but from the little balatro code i understand i dont see why it doesnt work

wintry solar
#

You don’t need the next in that line

spare elk
#

"69: attempt to index field 'other_card' (a nil value)"

#

even after removing the next

maiden phoenix
#

I don't think other_card exists in context.before?

spare elk
#

oh

#

in that case what should i use in exchange

maiden phoenix
#

use context.before and iterate over context.scoring_hand, and if it finds a 3, you break and upgrade the mult

teal estuary
#

question: how do you check for stone cards in a played hand? i wasnt sure if i should check for its ID, or if its something like is_enhancement()

wintry solar
#

You can check the center key

spare elk
#

ok so i replaced some of the code with some from Weebonacci of the Cryptid mod, now there's no error on line 69 but for some reason it doesn't like the } on line 80, which doesnt make sense cause the code doesn't add any {} things

zealous glen
#

This was cool

golden lake
#

balatrostuck is balatroback

zealous glen
#

:0

#

Thus ends the Gigapause

#

Now the next hiatus can begin

mental nacelle
golden lake
#

first new joker

wooden nexus
#

dang

mental nacelle
#

i should read homestuck

golden lake
#

yesss...

teal estuary
#

god damn

#

purdy

zealous glen
#

I have been thinking about getting back into Balatro modding

teal estuary
#

i love it when code works EXACTLY how you planned it to clueless

versed swan
#

Does anyone know what "dissolve_mask" is in shaders?

fair mortar
#

just figured out why none of my lovely patches have been applying... this whole time I've been working in Mods/modname/modname

hardy viper
weak brook
#

trying to do some experimentation with the title screen card
is it not possible to replace the initial card in the logo (the Ace of Spades) with an SMODs Joker?

#

put in the key for one of mine and it crashes every time

#

the center is there in the table, and i'm using the same logic that the vanilla game uses to load jokers in that position, but for some reason it doesnt wanna work with an SMODS joker

spare elk
#

you should check the cryptid code since it replaces the ace with a cryptid spectral card

crisp coral
#

no, it adds the cryptid spectral next to the ace

weak brook
#

im studying that code

spare elk
weak brook
#
    local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, G.TITLE_SCREEN_CARD, G.P_CENTERS.c_base)
elseif type(G.TITLE_SCREEN_CARD) == "string" then
    local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, G.P_CARDS.empty, G.P_CENTERS[G.TITLE_SCREEN_CARD])
else
    local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, C_A, G.P_CENTERS.c_base)
end```
using this code in a lovely patch, this code doesnt work at all for some reason.
but if i just do ```local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, G.P_CARDS.empty, G.P_CENTERS[G.TITLE_SCREEN_CARD])``` it works perfectly
#

the crash says card is nil when it tries to emplace it, somehow

#

G.TITLE_SCREEN_CARD is currently a string but somehow it comes out unable to set the card

#

and i'm like 99.99% sure this is the correct syntax for if else so whats the deal here, game

#

ok I put the if else into a function I put in the mod code and then had the lovely patch code call that and now it works. dunno what the deal with that was but hey got it working now

zealous glen
#

But the main shader used in the game is the dissolve shader I think

#

I don’t know exactly but I think between rendering a card normally or rendering it disappearing is one of the inputs it takes

languid mirage
#

it's a function that only does card burn effect when card is being dissolved

flat pier
#

What is the string to get / change the base nominal of a card?

languid mirage
#

e.g. when you use a consumable

#

or dagger eats a joker

#

you need to have dissolve_mask() run last, since it would have to be on top of your shader

#

very annoying implementation imo, but yeah

#

and you have to keep the function because otherwise compiler optimization will yell at you for having unused externs

versed swan
#

Ah, okay, thank you

nocturne garnet
wintry solar
#

There’s something wrong with how you’re adding that I think

tribal umbra
#

does anyone have a guide to start modding the game

#

i want to make a mod but idk how

spare elk
#

steamodded has good example mods to help you understand the basics of code

mystic river
#

if my mod added a joker Prosopagnosia: No cards count as face cards, how would you expect the game to behave when you had it alongside Pareidolia

languid mirage
#

whichever is left most

tribal umbra
#

that might work

mystic river
#

Prospagnosia: No cards count as face cards. X5 Mult if played hand contains a face card. and Pareidolia overrides Prosopagnosia
that would probably get some amusing reactions from the seeming self-contradiction before people figure out the trick

tribal umbra
#

funny situation

#

you cant have any face cards, but if you do..

glossy stone
#

Whoops, iirc*

#

How did i mix those up...

mystic river
#

yeah probably, it seems obvious enough
i haven't played whichever mod(s) it's in myself, though :p

nocturne garnet
#

probably wont do anything much anyways

teal estuary
#

how do you have a joker specifically add mult to a playing card? this is the code i currently have, its a little rough but it adds chips to stone cards, not mult:

calculate = function(self, card, context)
    if context.individual and context.cardarea == G.play then
      if context.other_card:get_id() <= 0 then
        card.ability.extra.mult = math.min(card.ability.extra.mult + card.ability.extra.mult_gain, card.ability.extra.max)
        context.other_card.ability.perma_bonus = (context.other_card.ability.perma_bonus or 0) + card.ability.extra.mult
        return {
            extra = {message = localize('k_upgrade_ex'), colour = G.C.MULT},
            colour = G.C.MULT,
            card = card
        }
      end
      if context.joker_main then 
        return{
              message = localize{type = "variable", key = "a_mult", vars = {card.ability.extra.mult}},
              colour = G.C.MULT,
      }
    end 
    end
  end
  }
#

im presuming its something to do with perma_bonus, but i wasnt sure what to try or do about it 😭

nocturne garnet
#

but it doesnt show up sadly

#

still works tho

teal estuary
#

ty

#

do you know of a way to make it show up? that does work, but it is annoying to not be able to see it 😭

nocturne garnet
#

no idea sadly 😭

teal estuary
#

fair enough

tepid sky
#

😵‍💫

#

i wanted to make it 1 in 8 instead of 0.5 in 4 lol, iguess both work

nocturne garnet
royal ridge
tepid sky
#

lol

#

also anyone know how to check if a chance thing sucsessfully happend?

tepid sky
tepid sky
#

anyone know what is wrong with my chance scaling?

#

it looks good

teal estuary
teal estuary
#

honeslty? no clue, wanna say it might be the return missing something, but i wouldnt know what :so

tepid sky
#

lmk just post the error rq

#

its smth with arithmetic

#

whatever it means

crisp coral
#

is this how you hook it now????????

#

like what the fuck is going on with calculate_joker now

tepid sky
humble gale
#

is this the correct way to call a config file?

--Making variable for Config
jojoker_config = SMODS.current_mod.config
--Calling Setting
jojoker_config.part_seven
--config.lua
return {["part_seven"]=true}

it is returning nil

wintry solar
nocturne garnet
wintry solar
#

Is that the entire use function of your consumables?

humble gale
#

is there a way to make a joker always activate last no matter what position it is in?

nocturne garnet
wintry solar
#

What’s the rest?

teal estuary
#

question - is there a specific context to use for only affecting jokers? im attempting to make a joker that directly effects and boosts other jokers, but i wasn’t sure what to use 😭

#

(i wanna say its joker_main but, wanted to check)

humble gale
#

Is context.cards_destroyed supposed to run after a card is destroyed? because this code doesnt run after the card is destroyed

if context.cards_destroyed then
   print("ran")
   for i,val in ipairs(context.removed) do
       if pseudorandom('crazydiamond') < G.GAME.probabilities.normal / card.ability.extra.odds then
            table.insert(card.ability.extra.cardToRestore,val)
       end
   end
end
torn grove
#

Hi, I wanna get one of my cards in a mod, but how much coding knowledge do I need?

#

(this is sepia joker, it's like the reverse of blackboard, triggering with hearts and diamonds instead)

maiden phoenix
#

Do you know how to code and if so in lua?

teal estuary
#

or shouldn’t be, at the very least?

#

but this is balatro modding so fuck knows

torn grove
teal estuary
#

yeah, thats all gkod

#

as long as you can read your own code, and understand what it does, you are good

torn grove
#

and how do I take the code from another card then?

#

where is the code stored?

teal estuary
#

do you have access to the source code of balatro?

torn grove
#

no, how do I get it?

teal estuary
#

im pretty sure theres a guide somewhere, but if i remember correctly:

  1. find the .exe of balatro (should be in steamapps)
  2. zip it, recommended to use 7zip but you dont have to
  3. extract that zip
  4. that should do it?
torn grove
#

okay, did it

vague island
#

yall know how i could choose a random joker to retrigger?

vague island
torn grove
#

okay

teal estuary
#

cant help you more then that unfortunately 😭

narrow pollen
#

so... i'm trying to set up a localization file for a mod, and it doesn't seem to be loading; even though i've put en-us.lua in a "localization" subfolder of the mod's root folder.
mind telling me what i'm doing wrong?

wintry solar
#

what does it look like inside?

ember stratus
#

would anyone here be able to help me with installing mods?

wintry swallow
#

Since I don't know much LUA, in this Cryptid Epic Joker code, hand_chips is global. Is that a LUA thing? A balatro thing?

local sync_catalyst = {
    object_type = "Joker",
    name = "cry-Sync Catalyst",
    key = "sync_catalyst",
    pos = { x = 5, y = 2 },
    rarity = "cry_epic",
    cost = 12,
    order = 54,
    blueprint_compat = true,
    atlas = "atlasepic",
    calculate = function(self, card, context)
        if context.cardarea == G.jokers and not context.before and not context.after then
            local tot = hand_chips + mult
orchid thunder
#

what is a copier

#

for consumables

narrow pollen
#

i wanted to offer to help the pokermon team convert their code to be more localization friendly, but already i'm running into problems that i haven't run into on my personal mod

#

i think i'm using localize right, but i'm getting ERROR and confirming through debug lovely injections that the variables i'm trying to add aren't getting added...

loc_txt = {
      name = localize("safari","labels"),
      text = localize("safari_desc","labels")
    },```
#
return {
  ['misc'] = {
    ['labels'] = {
      ['safari'] = "Safari",
      ['safari_desc'] = {
        "Can only be obtained",
        "through {C:attention}Evolution{}",
        "or certain {C:attention}Pokeball Items{}"
      }
    }
  }
}```
#

i understand that this may not be the way it's "supposed" to be organized, but i'm just trying to get some variable input

#

i thought i understood how to make a localization file... 😞

crisp coral
narrow pollen
#

now i'm getting this instead...?

narrow pollen
#

i swear, it's gonna take me more time to code my own workaround localization for it than get an answer on how localization file structure works

mellow sable
#

i would take a look at how cryptid does it

#

your contents seem fine, make sure it's in Pokermon/localization/en_us.lua or similar

rough furnace
#

has anyone tried chaniging seals before hand (such as what midas masks does for enhancementes)?

#

I tried just calling v:set_seal(seals[k], true, true)

#

but it still has it's old effect

#

If i set it outside the event it wokrs

#

but then the sprite changes too soon

wintry solar
#

Not sure if loc txt supports the localize function like that, I’d suggest structuring your loc file into objects with their keys

teal jackal
nocturne garnet
# wintry solar What’s the rest?
use = function(self, card, area, copier)
        if area then area:remove_from_highlighted(card) end
        if pseudorandom('antiparticle') < G.GAME.probabilities.normal*2/card.ability.extra.odds then
            for i = 1, #G.hand.highlighted do
                G.hand.highlighted[i]:set_edition({negative = true},true)
            end
        else
            for i = 1, #G.hand.highlighted do
                G.hand.highlighted[i]:start_dissolve()
            end
        end
    end,```
#

literally all there is

wintry solar
#

huh, do you run any other mods that are trying to add negative playing cards?

mystic river
#

i want my mod to have a joker named "phase bus" but i don't know what its effect should be
all I've got is "it's a bus, it could be like ride the bus but different" and "it's a cat related injoke and my mod has some cat related stuff in it, maybe it could interact with those somehow"

tribal umbra
#

well phasing is a very ghostly thing

#

so i would implement spectral cards somehow

mystic river
#

maybe something like "every 3 consecutive hands without a face card, create a spectral card"?
looks at how much coding knowledge i actually have (not very) that idea might have to go on the back burner for a bit

teal estuary
#

doesnt sound the hardest, but yeah that will take some code

nocturne garnet
#

steamodded just made negative playing cards WEIRD

wintry swallow
#

I want to create the joker as always negative - is there a field for that? Or what do I call where/when with set_ability? Nothing I find in code works around set_ability or set_edition. Is there a callback function on creation?

nocturne garnet
wintry swallow
humble gale
#

I didn't know that was there, thanks!

wintry swallow
wintry swallow
tribal umbra
#

some amazing ones but also some pretty mid ones

mystic river
#

true, but i'm not going for "amazing"
i'm going for "exists in the same game as seance without either making the other entirely pointless"

teal estuary
#

is there a specific way to make "X+ extra Y" appear on playing cards? i cannot get it to show up when i add mult to stone cards 😭

magic dawn
#

Idk if this is the right place or not, but I'm trying to use immolate (seed finder program) to try and find a seed that has blueprint + stuntman + brainstorm after a skip tag + jumbo buffoon pack in the first shop. I've never coded in c++ before, but I have done coding with text before, and I'm looking at both the example filters and the documentation and I'm noticing that the function names seem to be different between the docs and the example codes?

tribal umbra
magic dawn
tribal umbra
#

sorry i can't help im just super interested

#

thank you

magic dawn
#

I've made a script that lets me find blueprint + stuntman by modifying the four deadly jokers example, but for this I don't think I can just modify an example

#

Basically, is the documentation just out of date, or is there something I'm missing

mellow sable
#

Docs are out of date

#

I think it uses the wrong casing

magic dawn
#

Yeah, I noticed there was a function that wasn't really listen inside the docs inside of the examples
buffoon_pack(jokers, 4, inst, 1);

#

(jokers is a variable declared earlier)

#

So then does next_shop_item return joker_data as part of the item that's rolled? Because I've been trying to get the rarity of the first joker in the shop, and it keeps telling me there's no member named joker_data

mellow sable
#

You have to use next_joker_with_info

wintry solar
mystic river
# mystic river maybe something like "every 3 consecutive hands without a face card, create a sp...

thinking about it, i kinda basically know how to construct this by just copying pieces from existing jokers
after every hand, check if a face card was played (copied from ride the bus)
if so, set a counter (copied from invisible joker) to zero
if not, increase the counter by one
if the counter is now three, create a spectral card (copied from seance) and set the counter to zero
i could probably implement this without much trouble at all

#

the coding methodology of victor frankenstein, i guess :v

teal estuary
#

botching is a magical art in balatro, in the way that it sounds piss easy and turns out to be brain surgery when connecting them

wintry swallow
#

The message is: If you code in LUA/Love, remember people can look at your code

tribal umbra
#

im thinking of a joker card that when sold destroys 13 random cards from your deck but gives permanent 2x mult

#

or something

#

tips on how to make this more balanced?

stiff locust
tribal umbra
#

i thought so

#

how to debuff

#

the cards are random tho

stiff locust
#

so is immolate, the spectral is still insanely strong for thinning your deck

#

making it random just means you can't take it towards the end of a run if you have a card-focused deck

#

13 destroyed cards is crazy good random or not

tribal umbra
#

so what would you do?

stiff locust
#

what's the intent of the joker

#

is its effect trying to reference something or does it have a specific theme to follow

tribal umbra
#

it's meant to remove a bunch of random cards to make hands like straights harder to play

#

oh also i kind of want to make another spectral which is charmstone

#

which increases odds for stuff to happen more than oa6 but also has a penalty

teal estuary
#

how would you check for how many cards have been played in a hand? i wasnt sure where to find a joker that does that, so thought i'd ask here 😭

stiff locust