#💻・modding-dev

1 messages · Page 107 of 1

elder vapor
#

yeah

#

lol

shell condor
#

wild

elder vapor
#

¯_(ツ)_/¯

kind gorge
#

Alright stupid question alert (might be a bit drunk due to christmas ( Happy Christmas btw))

Does anyone know if its possible for steamodded to load files over a path? been trying for a while know...

    local path = SMODS.MODS_DIR .. SMM.config.collection.tagsplus.path
    local mod = require(path)```
throws me ```module 'C:\\Users\\Shinaii\\AppData\\Roaming\\Balatro\\Mods\\SMM\\Collection\\tagsplus.lua' not found```
even tho its obviously available ...
frosty dock
#

steamodded provides a util function to do it

kind gorge
#

ohhh thats what i oversaw then

frosty dock
#
assert(SMODS.load_file('path/to/file.lua'))()

where that path is relative to your mod's root dir

kind gorge
#

I will try that now! Thanks alot !

#

Worked like a charm!!! you are a king aure

gilded narwhal
#

Would that be fixed on the next version of steamodded?

frosty dock
#

I'll check if I need to add it or if the docs are wrong/out of date

#

if it's not in, I shall add it

wintry solar
#

Blinds 100% support keys in loc vars

frosty dock
#

not sure why that is, must be an oversight

wintry solar
#

Did I maybe make it work for myself?

hardy viper
#

yt m6m6t7 mjr5vu4fedf nendsde de de xd erd r xer5tz w zxxc n r5ncvvx sbycjfsxdikop/[
[2:35 PM]
not sure why that is, must be an ]\

#

]\

#

hinjm kuj]

#

]mk hjnu\

#

}i
Oo'] mop'];i

wintry solar
faint yacht
#

Careful about that packet spill, @hardy viper. 😛

wooden nexus
wintry solar
#

I keep forgetting I can just do this in smods

shell condor
#

gonna come back to this after i eat because i am well and truly stumped

#

I can't wrap my head around how deleting cards is supposed to work

wooden nexus
#

Okay, how do I target scored card that has an enhancement (on each card)

autumn coral
#

god fucking dammit

#

dude i can't be bothered i'm going to take a break 😭

#

"card is nil" ok so i test to see if it's nil

#

nope it's not

#

me when the game lies to me

#

i cannot be bothered i take 1 hour procrastination break to play isaac (technically this is related to dev anyway)

weak brook
#

does anyome know if theres an example of a castle-like modded Joker that uses a variable that changes suits each round, but is compatible with modded suits?

#

im trying to make one and i'd like to make it mod compatible and also not crash with the dynamic colors in the description

frosty dock
#

should add that to ModdedVanilla tbh

brisk quartz
faint yacht
wooden nexus
#

i don't see it

#

anyways, thoughts on it?

#

Changing Played to scored

elder vapor
#

rare?

faint yacht
shell condor
#

okay, genuinely, how does one remove a playing card from the deck after scoring, i feel stupid but for the life of me i cant figure it out

gilded narwhal
#

Like destroying it?

shell condor
#

yeah

zenith plover
#

Does anyone know if this is possible?

mystic river
shell condor
#

. its that easy huh

#

i feel dumb now

wooden nexus
faint yacht
zenith plover
#

really cant figure this out on my own would love some help with this

wooden nexus
#

I just realized i had made unintentional Synergy with Roffle, Doc, and Murphy
Murphy creates Blank Cards (enhancements) and Glass Cards (also enhancements)

Scored Enhancements are destroyed by doc giving +5 mult per, and you can use the 1 in 5 of perkeo to copy tarots to make enhancements

#

and if you get the rare 1/1000 chance with Murphy to get literally all the charity money, you can SKYROCKET Roffle's xmult

gilded narwhal
#

Lil showcase of T. Red that includes pretty much every joker rework and also one of the ways to get discards and hands back (beating the boss blind without discarding and in one hand, respectively)

autumn coral
#

new problem: my items are now not showing up on mac and i have no reason why

#

lmfao

#

wait i have an idea of why it might be happening but i doubt it

#

thhhattts why

#

ummm

nocturne garnet
#

(stupid idea)

gilded narwhal
#

I mean that's kind of this one

autumn coral
#

cooollll

zenith plover
#
calculate = function(self, card, context, effect)
        if context.cardarea == G.play and not context.repetition and not context.debuffed then
            effect.x_mult = card.ability.extra.mult
            if context.destroying_card and not context.destroying_card.ability.eternal and math.random(0,1) < G.GAME.probabilities.normal/card.ability.extra.odds then
                return true
            end
        end
    end

why is this code not working, its used within an enhancement, the mult works just fine but the destroy does not

wintry solar
#

I’m not sure destroying card is sent to enhancements

zenith plover
#

how would i go about making an enhancement that destroys the card its on then

frosty dock
#

what are the chances of being able to do that non-breakingly though...

mystic river
#

well let's see how glass does it

zenith plover
#

i've been trying to find the code for glass in the source code but couldnt find it 😦

mystic river
#

it does it during G.FUNCS.evaluate_play and looks like this

        local cards_destroyed = {}
        for i=1, #scoring_hand do
            local destroyed = nil
            --un-highlight all cards
            highlight_card(scoring_hand[i],(i-0.999)/(#scoring_hand-0.998),'down')

            for j = 1, #G.jokers.cards do
                destroyed = G.jokers.cards[j]:calculate_joker({destroying_card = scoring_hand[i], full_hand = G.play.cards})
                if destroyed then break end
            end

            if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then 
                destroyed = true
            end

            if destroyed then 
                if scoring_hand[i].ability.name == 'Glass Card' then 
                    scoring_hand[i].shattered = true
                else 
                    scoring_hand[i].destroyed = true
                end 
                cards_destroyed[#cards_destroyed+1] = scoring_hand[i]
            end
        end
        for j=1, #G.jokers.cards do
            eval_card(G.jokers.cards[j], {cardarea = G.jokers, remove_playing_cards = true, removed = cards_destroyed})
        end
#

i'm... not actually sure how to adapt that to a modded enhancement

#

i guess you could lovely patch it but i feel like there's a better way

shell tangle
zenith plover
frosty dock
shell tangle
#

Yeah, it's meant to be more of a joke, I wouldn't expect it to work at all.

frosty dock
gilded narwhal
#

Sweet

#

Thank you steamodded 🫡

frosty dock
#

also did some other things like actually document the fact that loc_vars support setting a default text scale and color and extended that support to locked stuff

wintry solar
wintry solar
frosty dock
#

yep, doing it sooner didn't work out due to ejwu quitting i guess 🤷‍♂️

wintry solar
#

I wonder what happened to him

#

Got hacked, made a new account, then vanished from the server entirely

frosty dock
#

just moved on to other things, I suppose

zenith plover
shell condor
#

how would you use a seal to destoy a nonscoring card? trying to do this but it isnt working, dont know if seals follow different rules or not

high gulch
#

Just as a double check/clarification, only PC modding is allowed and nothing else? Even mobile?

frosty dock
frosty dock
#

besides we don't have a way figured out to mod any of the other platforms in the same way we can on PC anyways

#

so it wouldn't be of much use for your efforts if it were allowed

wintry solar
#

@shell condor similarly, I don’t think seals are passed destroying card, you’ll have to patch it in

shell condor
#

ah, i see

#

is there a library which helps me with that?

kind gorge
#

Anyone know why this shift to the right happens?

    label = localize('mods_tag_refresh'),
    chosen = true,
    tab_definition_function = function() return {n = G.UIT.ROOT, config = mod_option_config, nodes={
        {
            n = G.UIT.C, config = {align = 'tm'}, nodes={
                create_toggle({label = localize('mods_tag_refresh_enable'), ref_table = SMM.config, ref_value = ''}),
                {n = G.UIT.T, config = {text = localize('mods_tag_refresh_desc'), scale = 0.4, colour = G.C.UI.TEXT_LIGHT}},
                create_toggle({label = localize('mods_tag_refresh_enable'), ref_table = SMM.config, ref_value = ''}),

            }
        }
    }} end
},```
frosty dock
wintry solar
#

Wrap your text nodes in a row

kind gorge
#

Ill try that thanks

zenith plover
wintry solar
#

They inject code directly into the source code. Pattern is a full line to match in the original file, position is set to inject the payload either before, after or at, and match indent just keeps the original indentation so it doesn’t look awful

kind gorge
#

Damn it worked! you guys are a blessing fr

shell condor
#

...so how does one apply a patch?

#

i found a patch in Cryptid for the green seals

#

no idea to actually apply it though

zenith plover
wintry solar
#

For multi line payloads

zenith plover
#

ah so just like in discord?

runic sinew
#

How does the base game handle negative point scores?

zenith plover
wintry solar
#

And then I use it in patterns too so I don’t need to escape single quotes

shell condor
runic sinew
#

Is there any room for the mod loaders to integrate a git(hub) auto-update?

frosty dock
#

so we held off on adding something of the sorts into steamodded

runic sinew
#

Do tell me about the external

hardy viper
#

i need to get this child to stay away from my computer

#

no way

#

she hit the fucking linkedin windows keybind

#

and the onenote one

#

ctrl+alt+win+shift+L and ctrl+alt+win+shift+N

#

AND POWERPOINT

autumn coral
#

Crazy

hardy viper
#

this girl is a pro

autumn coral
#

Damn

teal estuary
hardy viper
#

shed be better than half the current folks

teal estuary
#

true

#

i think anyone would

night pagoda
#

Is there no built-in way to run an update code for a booster pack that hasn't been opened yet?

#

(if it's still in the shop)

nocturne garnet
#

she doesnt know how to read

#

thats a sign of a great balatro player

zenith plover
#

why doesnt this work, this patch should make it so that every fire card thats played gets destroyed

version = "1.0.0"
dump_lua = true
priority = 1

[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then destroyed = true'''
position = 'before'
match_indent = true
payload = '''
    if scoring_hand[i].ability.name == 'Fire card' and not scoring_hand[i].debuff and pseudorandom('glass') < 1 then 
        destroyed = true
    end
'''
frosty dock
#

scoring_hand[i].config.center_key == 'm_modprefix_key' where modprefix is your mod's prefix and key is what you put as a key into SMODS.Enhancement

#

there's some things like this in vanilla code that are deemed bad practice or not viable in modded

zenith plover
# frosty dock `scoring_hand[i].config.center_key == 'm_modprefix_key'` where modprefix is your...

ok so now i have this

[manifest]
version = "1.0.0"
dump_lua = true
priority = 1

[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then destroyed = true'''
position = 'before'
match_indent = true
payload = '''
    scoring_hand[i].config.center_key == 'm_avatar_fire' and not scoring_hand[i].debuff and pseudorandom('glass') < 1 then 
        destroyed = true
    end
'''

but this still wont work :{

wintry solar
#

it needs an if at the start

zenith plover
#

im actually stupid

#

if this works im gonna be so mad

wintry solar
#

🙃

frosty dock
#

just saying, you're also changing glass card RNG

#

you should remove the pseudorandom call, it doesn't do anything

zenith plover
zenith plover
wintry solar
#

change your pattern to this if destroyed then

meager canopy
#

would anyone happen to have a sort of template sprite for making joker cards?

#

or atleast what the default sprite resolution for jokers is

teal estuary
#

71x95 is the size of the entire sprite

meager canopy
#

cheers!

zenith plover
teal estuary
#

np

frosty dock
#

and your pattern isn't the exact line

zenith plover
#

ah

frosty dock
#
  • simpler patterns are better and less likely to cause patch conflicts
zenith plover
#

do you btw know if i can call pseudorandom with any string or if it has to be one of the already used ones?

frosty dock
#

it works with any string

zenith plover
#

nice

frosty dock
#

in fact you should avoid using ones the game already uses as to not alter the game's RNG

wooden nexus
#

Is +5 mult too much for this?

#

i do need to fix the other end

teal estuary
#

seems fine?

#

coukd be OP with midas, but its one joker

frosty dock
#

would have to playtest for balance, seems quite strong but fine for a rare

wooden nexus
#

Aight. I'll let doc have the final say on if it's too powerful or and whatnot

frosty dock
#

destroying cards is a great effect but enhancements aren't always easy to come by

wintry solar
wooden nexus
#

Woo!

frosty dock
#

nice

#

what kind of property is that though

wooden nexus
#

It's a curse

#

They're Ortalab's opposite Seals, but we decided to make them a new type

frosty dock
#

ah so that they're compatible with seals

#

nice

wooden nexus
#

Mhm

#

That and don't want something weird like a curse appearing from Certificate

frosty dock
#

mhm

wintry solar
#

that wouldn't be an issue

#

it's just so they stack

wooden nexus
#

True

#

Tldr, they're for a downside for a good effect for Mythos cards if i remember correctly

#

I'm changing Roffle from 1 in 5 to 1 in 4 for a perkeo effect

frosty dock
#

i should play some ortalab, i've actually never played it smh

wintry solar
#

oh no aure is going to find all my bugs

wooden nexus
#

Aure's gonna make that bugfix section of our todo list long

frosty dock
#

lmao

wooden nexus
#

I changed Roffle's effect a little

#

playing around i felt like the perkeo effect did little to nothing

zenith plover
#

is there a mod to quickly restart balatro after updating your mod?

wooden nexus
#

the alt+f4 key then clicking it on your taskbar

willow quiver
#

hold M

zenith plover
#

how do i make it so that a new card gets added to hand that is the same rank and suit as scoring_hand[i] but with a different enhancement, should copy edition and seal as well but that is'nt as important

willow vessel
#

guys i need help i want to mod balatro a bit and makeit little more clear for me without loosig style points (i dont really like high contrast colours choise) and how hard it would be just to change colours on cards like to make spades black-> dark violet etc. (i know nearly nothing abouit modding and programming)

analog pilot
#

that would probably be pretty simple, im sure there are texture packs or mods out there that do that exact thing

hardy viper
willow vessel
#

Thats the thing i hate this blueish and yellowish choice of colours so i want to my own contrast set

tidal ice
#

I really REALLY did not wanna ask this but I need to know how to make this consumeable to only create a rare card thats compatible with perishable

tidal ice
steep rain
elder vapor
#

h

limpid flint
#

g

steep rain
#

u

scenic sphinx
#

r

hardy viper
#

meow

faint yacht
scenic sphinx
#

bread

steep rain
#

bread

cerulean rose
#

big jeremy

thick panther
mystic river
faint yacht
#

Can I modify and update shown hand_chip and mult values during scoring? It appears to work for chips only if I try to, say, swap the two values around.

analog cypress
#

Cross referencing my joker with Fortune Teller, looks like my message didn't trigger when I used a spectral card

    calculate = function(self,card,context)
        if context.joker_main then
            return {
                card = card,
                chip_mod = card.ability.extra.chips * G.GAME.consumeable_usage_total.spectral,
                message = '+' .. card.ability.extra.chips * G.GAME.consumeable_usage_total.spectral .. ' Chips',
                colour = G.C.CHIPS
            }
        end
        if context.using_consumeable and context.consumeable.config.center.set == 'Spectral' then
            return {
                card = card,
                message = 'Upgrade!',
                colour = G.C.ATTENTION
            }
        end
    end
#

Also it seems to crash whenever I try to play a hand when there no spectral cards were used with my joker to add +10 chips

#

It crashes at the chip_mod part with attempt to index a nil value on consumeable_usage_total

#

It works when I do spawn in a spectral card with debugplus since by then the nil error doesn't happen

hot glacier
#

Anybody know how one would go about making it so that consumable cards in a booster pack have the option to select (like card and buffoon packs where it goes into your deck) instead of being instantly used (like arcana and spectral packs)

#

I'm trying to make a modded booster pack of mine work like this and I'm having difficulty figuring out how to do something like that lol

faint yacht
# analog cypress Cross referencing my joker with Fortune Teller, looks like my message didn't tri...

I've technically done something similiar except with vouchers in terms of calculating the bonus, but you may find this useful.

if context.joker_main then
  local usedspectral = G.GAME.consumeable_usage_total.spectral or 0 -- 0 if nil, use actual number if not.
  local specbonus = card.ability.extra.chips * usedspectral -- this is either 0 or actual multiplied bonus.
  return {
      card = card,
      chip_mod = card.ability.extra.chips + specbonus,
      message = '+' .. card.ability.extra.chips + specbonus .. ' Chips',
      colour = G.C.CHIPS
    }
 end
faint yacht
hot glacier
#

Ooh okay thanks for the lead >:3

faint yacht
#

Attempting to directly influence the scored chips and mult from a function without adding or subtracting via bonuses from cards or jokers... am I meant to modify the G.GAME.current_round.current_hand.chips and G.GAME.current_round.current_hand.mult then and which functions do I call to "update" the values shown with the changes? Basically want to visually and literally swap the two around on trigger.

dusk shoal
#

would g.hand.cards be how many cards are in your hand

#

or like how would i get that value otherwise

spring anvil
#

what event is triggered when a playing card is modified

#

i.e. with tarot cards, hiker, spectral cards, etc

#

I actually have a list of all the times a deck can get modified

  • magician (tarot)
  • empress (tarot)
  • justice (tarot)
  • lovers (tarot)
  • hierophant (tarot)
  • devil (tarot)
  • chariot (tarot)
  • strength (tarot)
  • tower (tarot)
  • death (tarot)
  • star (tarot)
  • moon (tarot)
  • sun (tarot)
  • world (tarot)
  • aura (spectral)
  • sigil (spectral)
  • ouija (spectral)
  • talisman (spectral)
  • deja vu (spectral)
  • trance (spectral)
  • medium (spectral)
  • hiker (joker)
  • vampire (joker)
  • midas mask (joker)
crisp coral
#

change_suit
set_base (both rank and suit)
set_ability (enhancement)
set_seal

spring anvil
#

thank you prayge

#

also what about hiker

#

with permanent chip increase

spring anvil
crisp coral
#

death

spring anvil
#

killin myself

crisp coral
#

you're being converted into a 2 of diamonds

spring anvil
#

I'm also trying to get a joker to preview in the game

#

what's the best way to do this

crisp coral
#

get DebugPlus

spring anvil
#

oh awesome

#

I still don't know how to get a joker to preview though

dusk shoal
#
    if context.cardarea == G.hand then
      if (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) or (context.other_card:get_id() == 6) or (context.other_card:get_id() == 7) or (context.other_card:get_id() == 8) or (context.other_card:get_id() == 9) or (context.other_card:get_id() == 10) or (context.other_card:get_id() == 11) or (context.other_card:get_id() == 12) or (context.other_card:get_id() == 13) or (context.other_card:get_id() == 14) then
        if context.other_card.debuff then
          return {
              message = localize('k_debuffed'),
              colour = G.C.RED,
              card = self
          }
      else
            local bonus = (card.ability.extra.money)
            if bonus > 0 then return bonus end
end
end
end
end```
crisp coral
#

collection > hover over a jonkler > press (ctrl+)3

dusk shoal
#

i assume that bullshit line of code is whats fucking up

#

basically its supposed to treat every card as a gold card

crisp coral
#

what the fuck

dusk shoal
#

the problem (i think) is that "calculate" only happens when its NOT in context.cardarea

dusk shoal
spring anvil
#

the mod is 100% installed

dusk shoal
#

its not ctrl

#

its just 3

spring anvil
#

3 doesn't work either iOS_sob

dusk shoal
#

are you putting your mouse over it?

crisp coral
#

guh

dusk shoal
#

or clicking it

spring anvil
#

let me look at the official keybind things

#

I do have this on

#

but yea no it still doesn't work

#

and yes I am hovering over it

crisp coral
#

i forgot what the other configs are there

spring anvil
#

turned the setting off too

spring anvil
#

I am also on the latest code

crisp coral
#

does it show anything in game if you hold tab

spring anvil
#

yea

crisp coral
#

buh

#

no clue

spring anvil
#

fcuk

dusk shoal
#

for some reason, ``` if context.cardarea == G.hand then

#

keeps crashing

#

whether its in an event or calculate = function or whatever

#

okay its no longer crashing

#

but now its not doing anything

frosty dock
#

pretty sure that isn't a unique context on its own

#

I could be mistaken

dusk shoal
#
    if context.end_of_round and not context.cardarea then
      if context.other_card:get_id() == 2 then
        if context.other_card.debuff then
          return {
          }
      else
        return {
          message = localize('k_debuffed'),
          colour = G.C.RED,
          card = self
        }
      end
    end
    end
    end```
#

this is what we're at rn

#

the 2 was just testing

#

crashes either way

#

the problem is with line 240, aka the context.other_card:get_id()

#

but it specifically said the "context.other_card"

frosty dock
#

that's not how I remember checking for individual end_of_round

dusk shoal
#

i stole it

frosty dock
#

that would be context.end_of_round and context.cardarea == G.hand and context.individual if I'm not mistaken

storm oar
#

if i wanted to start developing mods for the game where should i start?

dusk shoal
#

stupid line 961 for limit

#

this thing keeps popping up

#

LINE 961 IS ABOUT GLASS CARDS

dusk shoal
kind gorge
#

aure you were a blessing the last time. Do you know why it can read enable but not newgame?

            enable = true,
            path = "Collection/TagRefresh.lua",
            newgame = true,
          },
create_toggle({label = localize('mods_tag_refresh_enable'), ref_table = tag_refresh , ref_value = 'enable'}),
create_toggle({label = localize('mods_tag_refresh_newgame'), ref_table = tag_refresh , ref_value = 'newgame'}),

Its just always disabled by default so it can't read it for some reason

dusk shoal
#

wait

#

i think i

#

put something in there on accident

#

nevermind gave the same crash anyways

#

NEVERMIND DID SOMETHING WRONG AGAIN ONE SEC

#

might not fix it but still

dusk shoal
#
    if context.end_of_round and context.cardarea == G.hand and context.individual then
      return {
        context.other_card:juice_up(0.5, 0.5),
        message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.money } },
        colour = G.C.RED,
        card = self
          }
        else
      end
    end```
#

that is causing this

#

and im not sure why

#

from what i can tell, it is detecting everything just fine

frosty dock
dusk shoal
#

instead of card = self?

frosty dock
#

yes

dusk shoal
#

or are you saying card = card because its funny

#

okay cool thanks

kind gorge
dusk shoal
#

CARD = CARD WORKED

#

I DIDNT THINK CARD = CARD BUT HERE WE ARE (here we card)

#

would there be a way to do it 1 by 1

#

like each card has the effect happen one by one

#

instead of all of them shaking at once

frosty dock
#

remove context.other_card:juice_up(0.5, 0.5),

dusk shoal
#

well i do want them to juice up, just one by one

#

or is that what that would do

#

ok that is not what that does

#

im guessing id have to check each card in hand individually for it to happen one by one

frosty dock
#

card = card should already do the juicing up

dusk shoal
#

doesnt

#

unless i have it in the wrong spot

#

its last

#
    if context.end_of_round and context.cardarea == G.hand and context.other_card and context.individual then
      return {
        message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.money } },
        colour = G.C.RED,
        card = card
          }
        else
      end
    end```
#

doesnt send the message either

kind gorge
#

I think i know why it was nil for me... does steamodded or whatever cache configs?

wintry solar
kind gorge
merry raven
#
SMODS.Atlas{
    key = 'Enhancements',
    path = 'Tangle.png',
    px = 71,
    py = 95
}

SMODS.Enhancement{
    key = "tangle",
    loc_txt = {
        name = 'Tangle',
        text = 'The card to the left of a Tangle card and the Tangle card itself can be played as a single card'
    },
    atlas = 'Enhancements',
    pos = {x=0, y=0}
}

Trying my hand to at least get a card in game, but I'm met with this error:

msg = string: "functions/misc_functions.lua:1690: bad argument #1 to 'ipairs' (table expected, got string)"

Any insights on this? I'll provide more of the crash log if needed, I don't want to spam this channel

hardy viper
#

this is how you do text wrapping, each string is on a separate line

merry raven
#

I don't follow, I'm very much new to Lua in general, what does that mean

wintry solar
#

Like this

hardy viper
#

^

merry raven
#

Ah right

frosty dock
#

I just figured out why my runs weren't saving tonight

merry raven
#

Yep, got it working!

frosty dock
#

talisman overrides the save manager and doesn't have the kill signal

merry raven
#

So to update the changes I've made to my main.lua, do I have to exit and reopen the game for every change or is there some kind of hotkey to streamline the process

frosty dock
#

you just need to hold the 'm' key for a second or so

merry raven
#

Gotcha

#

Time for the painful part, actually coding in the mechanic

#

What kind of checks there are that can detect

  • cards that are on the left of the selected card
  • the number of cards played in a hand (My card's ability is to play itself and the card to its left as one card)
#

And also, is there some documentation where I can see what checks are there?

frosty dock
shell tangle
# frosty dock added this to the example jokers mod btw

Thanks a ton for adding it on, definitely a nice one to know about,

I'll probably go over it and elaborate more on the comments later, and maybe add one more joker as well, since I realized I don't have a single info_queue example in there yet.

storm oar
#

i have an idea for a mod but have no idea if it's possible, adding vouchers that will give the possibility to kinda "continue" a run if you lose but with different effects depending on which voucher you purchase

shell tangle
#

Maybe more on the complex side, but, probably not impossible.

storm oar
#

also is it possible to have something show up with a generic sprite and description in the shop if it hasn't been discovered yet?

shell tangle
autumn coral
#

Merry crimbus!!

teal estuary
#

do tarots or planet cards spawn more in a shop (not packs, like the actual cards)? presuming no vouchers or any other changes to spawn rates

proper relic
#

Is orange not a usable color in joker descriptions? I'm just trying to do "Provides a {C:orange}Ruby{}" but it's just showing up as black. G.C.ORANGE is a thing, right?

proper relic
#

Oh that works great, thank you!

sonic bone
#

im pretty sure G.C colors are different than the ones used in description but im not sure where theyre defined

teal estuary
frosty dock
faint yacht
#

...per chance, can the currently scored chips and mult be "swapped" around? I assume some functions will have to be called to "update" after the change of values by the swap.

frosty dock
#

you can look at greyscale from ortalab

faint yacht
#

...unfortunately, I don't seem to see any code that does the swapping of the two values around? Downloaded latest code up there... unless I've used the wrong repo or should have used the release.

frosty dock
#
## Greyscale edition on jokers
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''if edition_effects.jokers.x_mult_mod then'''
position = 'before'
match_indent = true
payload = '''
local card = edition_effects.jokers.card
if card.edition.swap then
    local old_mult = mult
    mult = mod_mult(hand_chips)
    hand_chips = mod_chips(old_mult)
    update_hand_text({delay = 0}, {chips = hand_chips, mult = mult})
    card_eval_status_text(card, 'extra', nil, percent, nil, {message = localize('ortalab_swap'), colour = G.C.PURPLE})
end
'''
crisp coral
#

mult, hand_chips = hand_chips, mult balatrojoker

faint yacht
#

Forgot to swap my filter to *.* from *.lua, oops. 😅

frosty dock
#

*.* isn't even a filter

#

that's just a face

faint yacht
#

Assuming w/o such patches it does not work as intended? mult, hand_chips = hand_chips, mult alone didn't cut it either as I tried earlier.

frosty dock
#

you just need to include the update_hand_text line

cinder elk
#

so to mod balatro i need to unpack the game right; how do i do that

frosty dock
#

you just extract the executable with 7-zip

faint yacht
#

It's not early Minecraft days with direct .jar modding.

#

Localization file confusion... does message = localize('toga_swappy') not pull from the misc.dictionary sub-table that's returned from the loc-file?

frosty dock
#

is toga_swappy the exact key you have in the file?

faint yacht
#

Yet the message returns ERROR.

frosty dock
#

mkay where's the loc file?

faint yacht
#

..\localization\en-us.lua

teal estuary
#

is there a way to transfer over a jokers value to another joker?
i have a scaling joker that has a chance to turn into another joker, is there a way for the new joker it turns into to keep its scaled amount?

#

-# im gonna presume i could do this with botched blueprint code, but might aswell ask

frosty dock
#

relative to what--

faint yacht
#

Root of my mod folder.

frosty dock
#

so it's outside of your mod's folder..?

faint yacht
#

No? TOGAPack\localization\en-us.lua
-# Should've just sent it like this.

violet void
#

Can this

juice_card_until(card, eval, true)

be used with playing cards other than jokers?

tidal ice
#

I would assume so but im unsure how

#

I remember being able to do that with consumables

faint yacht
#

As long as you can pass the right "card" to it, yeah.

violet void
#

I was trying to make some cards shake due to a Joker's effect but it keeps crashing

tidal ice
#

may be best to do card:juice_up() within a G.E_Manager:add_event

#

lemme grab an example

violet void
tidal ice
#

card.ability.extra doesnt exist for one reason or another

#

check your joker's config

violet void
#

its the third picture

tidal ice
#

ah

#

idk what the issue is then, sorry

violet void
#

np, thanks anyways 💪🏽

tidal ice
#

but heres an example of how to make a card juice up, its just that you may have to replace card with other_card

violet void
#

altho its crashing in the eval

faint yacht
#

Are you really making sure that a playing card is not being passed through as card there?

#

Playing cards don't usually have card.ability.extra.

violet void
#

It should be passing the Joker's card in the eval

cerulean rose
# tidal ice bumping this rq

i did something similar in my mod, strange pencil, so you could look at that (specifically for the spectral card Negative Space)

faint yacht
#

wack.

violet void
#

it was like Ali said 👍🏽

hardy viper
violet void
#

x2 feels too fast

#

also that's x1

digital kayak
#

if i wanna get into making mods what modding framework would i ideally look into using

rough furnace
#

Steamodded has most of the tools you will need

digital kayak
#

ty

rough furnace
#

Lovely also does some stuff

#

Generally adding new content use steamodded modifying existing content use lovely

#

But there's decent overlap

hardy viper
night saddle
#

How do I make a joker detect if a certain joker is in possession as well?

#

This is what I had before and I fumbled

if context.other_joker:get_id() == JokerKey1 then
return {
mult = card.ability.extra.mult,
}
end

rough furnace
#

You can use SMODS.find_card

autumn coral
#

weird thing: trying to go through area.highlighted and remove_from_highlighted gives "attempt to index a nil value"

#

imma try to add the cards themselves to an array before i guess?

#

ok now nothing happens

#

siiigh

night saddle
rough furnace
#

Just pass it to the function

autumn coral
primal robin
autumn coral
#

oh wait actually

#

in that case what i'm doing now should theoretically fix it

rough furnace
#

Isn't there a function to remove all?

primal robin
#

Iterate all cards, then remove

rough furnace
#

Or are you just doing some?

autumn coral
#

wait is there a function to unhighlight all?

#

it's for jokers specifically

rough furnace
#

I think so

autumn coral
#

that's why i was confused

#

because normally you can't select more than 1

rough furnace
#

They share the same area code

primal robin
#

Ofc it is. unhighlight_all()

autumn coral
#

oh

rough furnace
#

I think it's used for the hand when right clicking

autumn coral
#

nope it returns a nil value

#

yeah

#

well wait

#

actually

#

i could try G.jokers:unhighlight_all()

#

i just did the card area but that might work

primal robin
#

It will work

autumn coral
#

you are jesus

#

this should work

#

god please can i finally be done with d6 and start another card

#

god fucking FINALLY

#

finally i can sprite this and then easily do ed6 and be DONE with dice

primal robin
#

Try to explore vanilla classes and functions first, maybe they are already contain what you need

robust falcon
#

Hello!

#

I would like to make a mod, where should I start?

fleet schooner
robust falcon
#

Hope it helps

fleet schooner
#

Thanks for sharing

night saddle
faint yacht
autumn coral
#

is there a way to add an eternal negative card to a deck by default

#

i tried doing it like a challenge deck but it didn't work..

#

it's possible that i'm stupid but like

#

is this not exactly what this should look like?

#

it does LITERALLY everything except for add the joker i want

#

do i have to do it in apply?

frosty dock
#

make an apply function

autumn coral
#

gotcha

#

yeah that's what i was thinking

#

just add it to G.jokers.cards?

#

or um g.jokers i meant

nocturne garnet
#

You should subscribe to them!

frosty dock
#

SMODS.create_card supports adding stickers and editions directly

autumn coral
#

i saw that

frosty dock
#

the you just need to add_to_deck and emplace it into G.jokers

autumn coral
#

how do the vars work? is it an object or is it individual?

#

i'm assuming it's an object

#

like {set="joker"}

frosty dock
#

it's a table, yeah

#

unlike vanilla create_card

autumn coral
#

gotcha

#

thank!

frosty dock
#

you can use that too if you like some nil, nil, nil, nil, true

nocturne garnet
#

thunk....

frosty dock
#

m

nocturne garnet
#

localthunk..

frosty dock
#

thonk

#

globalthonk

autumn coral
#

how do i do the eternal enhancement?

frosty dock
#

it's not an enhancement

#

it's a sticker

autumn coral
#

oh

frosty dock
#

stickers = {'eternal'} iirc

autumn coral
#

gotcha

#

thanks!

rough furnace
#

Side note it might be nice to have something like add_joker but with the args of SMODS.create_card

#

So it emplaces and adds to deck for you

autumn coral
#

um this. doesn't work...

#

this gives "assertion failed"

frosty dock
autumn coral
#

1428

rough furnace
#

Old aure name detected

autumn coral
#

should i just like. update steamodded?

#

i can do that too

#

i should do it anyway tbh

rough furnace
#

I mean it's good advice in general

autumn coral
#

now it crashes on like 1404

#

lol

frosty dock
#

so I'd have to track down the commit and check it out to actually find what that means

autumn coral
#

i'm just going to. use the ingame create_card

#

lol

rough furnace
#

What's the new file

#

From the error now?

edgy reef
#

Anyways this is from edition missing 'e_'

rough furnace
#

Someone should give me a good nickname

frosty dock
#

I should add an error message to that

#

and I should make it a warning and just add the prefix if it's missing

autumn coral
#

incredible, it works now

#

thanks

robust falcon
frosty dock
gaunt thistle
hidden timber
#

Let's go guys, loading mods fully works now with steamodded and lovely (ofc it's built in to the mod manager). Steamodded is done. Now working on Balamod jimbo_spin

frosty dock
#

:jimbo_spin:

#

when do we get to test it

#

also why waste your time on supporting balamod

hardy viper
#

balamod is more obsolete than 0.9.8

rough furnace
#

TBH I should make DebugPlus balmod exclusive

hidden timber
# frosty dock when do we get to test it

When everything is done, I'll roll out the mod manager to a few testers which will then give me feedback on what's working and what's (still) broken, so I can make the most stable version of it available

frosty dock
rough furnace
#

Talsiman has code to ensure smods 0.9.8 compat

frosty dock
#

what's a Talsiman

rough furnace
#

Refer to my nsme

frosty dock
#

fine

mellow sable
#

talsiman is that specrtal card that gives a plaiyng card a glod sael

hardy viper
#

glod sael

#

🔥

autumn coral
#

My bf is playtesting my mod 🥹

tepid crow
humble rune
#

whats 766? anyone know?

teal estuary
#

thats line number? im pretty sure?

humble rune
teal estuary
#

im 99% sure thats the line number thats causing/related to the error

humble rune
#

oh so something a mod maybe accidently mistyped or smth

frosty dock
#

lemme have a look

teal estuary
#

possibly? im not smart enough to read balatro error messages, my apologies

humble rune
#

dev*

humble rune
frosty dock
#

yeah I've seen that

humble rune
#

okay

frosty dock
#

your version of FusionJokers is incompatible with latest steamodded

humble rune
frosty dock
#

you should get elbe's version

humble rune
frosty dock
humble rune
#

huh

#

okay

thick panther
#

Merry Balatmas

frosty dock
violet void
#

does context.other_card work for cards held in hand?

frosty dock
#

yeah it should

nocturne garnet
pine nexus
#

is it possible to add unlock conditions to steamodded decks

violet void
teal estuary
#

couldnt you use their name?

#

-# oh wait

violet void
teal estuary
#

i still have no idea what you have to define for half of playing cards stuff

cinder elk
#

yo how exactly do i like. extract balatro’s files and code im curious

#

is there a tool i can use?

teal estuary
#

just zip up its .exe, and then unzip it

frosty dock
#

there's docs for that btw

pine nexus
#

👀

#

send

frosty dock
autumn coral
analog cypress
#

What's the formatting or method used to create the upgrade dialogue when I use a spectral card? This does nothing

        if context.using_consumeable and context.consumeable.config.center.set == 'Spectral' then
            return {
                card = card,
                message = 'Upgrade!',
                colour = G.C.ATTENTION
            }
        end
#

Used Ali's small bit of refactoring but it's still giving me [SMODS GRIZZLETECHJOKERS "main.lua"]:42: attempt to index field 'consumeable_usage_total' (a nil value)

        if context.joker_main then
            local usedspectral = G.GAME.consumeable_usage_total.spectral or 0 -- 0 if nil, use actual number if not.
            local specbonus = card.ability.extra.chips * usedspectral -- this is either 0 or actual multiplied bonus.
            return {
                card = card,
                chip_mod = card.ability.extra.chips + specbonus,
                message = '+' .. card.ability.extra.chips + specbonus .. ' Chips',
                colour = G.C.CHIPS
              }
        end
ancient escarp
#

I'm trying to make a simple spectral card as my first mod, under SMODS.Consumable, what is "atlas"

frosty dock
ancient escarp
#

oh there is literally a page for it

#

sorry I'm genuinely blind

frosty dock
#

this one was 90% documenting vanilla things

rough furnace
#

Thank you Aure

ancient escarp
#

might be another dumb question, where and how do you define what a consumable will do on use?

ancient escarp
frosty dock
ancient escarp
violet void
#

use .json

teal estuary
#

self.base.nominal = on the ranks is how much the card scores when played, right?
(in the source code)

#

currently trying to figure out what i need to call to change how much a card scores

teal estuary
#

cool

violet void
ancient escarp
# frosty dock

I'm trying to figure out how to use the parameters, self is the actual consumable card, I'm guessing area is the cards you draw while in a booster pack or blind, but what is "card" and "copier"

analog cypress
muted kite
#

Fun fact, it was just for me to remember what I was doing when creating the parsing system lol

#

I forgot to remove it in first release, but now JSON Metadata are a way better solution anyway

autumn coral
#

Btw is there any way you could support custom love2d font objects in future releases so i can make specific parts have different fonts?

faint yacht
autumn coral
#

how do i make it so that my custom rarity stops showing up in shops if i already have all of the items in it?

#

like i have the 1 card in the shop and then it just fills it up with jimbo's stupid ass

hardy viper
edgy reef
#

*get_weight

#

Speaking of which the API docs are wrong on this

#

oopsie

autumn coral
#

how would you uh. effectively implement this without taking up half the file?

hardy viper
hardy viper
edgy reef
hardy viper
#

flowwey would it be simple enough to add functionality for shop jokers of certain rarities to just not appear instead of being replaced with jimbos when there's no more in pool

#

@autumn coral unrelated but fire music

analog cypress
# faint yacht Maybe `G.GAME.consumeable_usage_total.spectral or 0` > `G.GAME.consumeable_usage...

Nope, same crash.

        if context.joker_main then
            local usedspectral = G.GAME.consumeable_usage_total.spectral or 0 > G.GAME.consumeable_usage_total and G.GAME.consumeable_usage_total.spectral or 0 -- 0 if nil, use actual number if not.
            local specbonus = card.ability.extra.chips * usedspectral -- this is either 0 or actual multiplied bonus.
            return {
                card = card,
                chip_mod = card.ability.extra.chips + specbonus,
                message = '+' .. card.ability.extra.chips + specbonus .. ' Chips',
                colour = G.C.CHIPS
              }
        end
hardy viper
#

i mean yeah if consumeable_usage_total is nil rewriting your code won't make it any less nil

faint yacht
hardy viper
#

have we considered that it's probably something other than "consumeable_usage_total" because evidently it does not exist

#

what does fortune teller use

edgy reef
#

G.GAME.consumeable_usage_total.tarot

#

Although it makes the check if G.GAME.consumeable_usage_total exists first.

autumn coral
#

That means a lot thanks

#

😭😭😭😭

#

I tryyyy

edgy reef
#

So the likely problem is that you're indexing consumeable_usage_total before it actually exists.

hardy viper
autumn coral
hardy viper
#

oo sick i will be listening

faint yacht
autumn coral
#

I wish lua had like some python features ngl

#

[i for i in i if i[‘rarity’] == 4] in a good ending

#

Would make my life so much easier

hardy viper
#

so it is that it's just not set

hardy viper
#

shoutout pypy for being not slow btw..

#

i can't believe python developers found out what a compiler was

#

oh also why are there like 5 python C translators

#

okay from further inspection everything ive ever known is incorrect

#

i need to start paying more attention when i watch tsoding vods

edgy reef
#

Who even uses python

hardy viper
#

a lot of people apparently

#

it's very useful

#

lots of good libraries

#

i know it's the second-most popular language for statistics, after R of course

#

but both have big communities for that kind of thing

merry raven
#

Are there contexts that check for the number of chips and mults scored?
I'm making a joker that checks whether the total number of chips or mults scored in a hand is higher, and the higher one will have half of its amount sacrificed to be added to the lower amount

#

Like if your hand scored 4x10, the 10 gets halved and the half gets added to the chip score, making it 9x5

hardy viper
#

G.GAME.chips and G.GAME.mult or soemthing

merry raven
#

Gotcha

#

Is there documentation for these contexts?

faint yacht
#

iirc that's actually what I've been messing with by swapping currently scored chips and mult around by swapping hand_chips and mult.

hardy viper
#

but yeah it might be hand_chips, you'll have to check

merry raven
#

Alrighty then

#

And where do I check that? Steamodded's wiki?

#

No wait hold on, I should peer into Balatro's source code for that, right?

hardy viper
#

ya source code

#

theyre probably referenced in evaluate_play() somewhere

merry raven
#

So those modding tutorials that show these global value suggestions, it's because they opened up the source code in VSC or something?

hardy viper
#

you can look at other people's code to see where you can find certain things globally but generally yes you can look at source code

merry raven
#

👍

hardy viper
#

it's just being able to figure out where you can find what you need

merry raven
analog cypress
#

Alright so now I'm trying to lock everything to 0 since without a spectral card played I still get chips added but then it crashes on attempt to perform arithmetic on nil specbonus

    calculate = function(self,card,context)
        if context.joker_main then
            local usedspectral = G.GAME.consumeable_usage_total.spectral
            local specbonus = card.ability.extra.chips * usedspectral -- this is either 0 or actual multiplied bonus.
           
            if usedspectral == nil then usedspectral = 0 end -- Lock the amount of used spectral cards to 0, not nil
            if specbonus == nil then specbonus = 0 end -- Same thing for this, except for the bonus chips
            
            if specbonus == 0 then return end -- Don't do anything if the bonus equals 0
        else
            return {
                card = card,
                chip_mod = card.ability.extra.chips + specbonus,
                message = '+' .. card.ability.extra.chips + specbonus .. ' Chips',
                colour = G.C.CHIPS
              }
        end
pliant dew
#

So I'm trying to make a joker that is meant to increase the hand size by 1 for every 6 diamonds in the deck, but I'm running into a couple issues:
firstly, it's applying the effect additively every blind, (so on a standard deck with 13 diamonds it'll be 10 on one blind, 12 on the next, 14 on the next, and so on)
secondly, it doesn't update the hand size mid-blind if the number of diamonds increases (so making six new diamonds will still only have the hand size at 10 instead of going up to 11, even after playing or discarding).
Would anyone be able to help me straighten things out?

faint yacht
pliant dew
#

I'm pretty new to modding, I had a lot of help with even this much, how would I go about doing that?

cinder elk
#

i dont remember this card.

storm oar
#

it looks weird like the sprite is ai generated or something

cinder elk
#

so how would i program a joker to give +50 chips. by like. default.

faint yacht
# pliant dew I'm pretty new to modding, I had a lot of help with even this much, how would I ...

You're already counting up all diamond cards with the for loop. Remove the if diamonds == 6 check and replace it with setting the card.ability.extra.tally. You may find needing an extra value to store a second copy of it to check (card.ability.extra.compare for example).

In the calculate part, check if card.ability.extra.tally = card.ability.extra.compare. If not, store the result of card.ability.extra.compare - card.ability.extra.tally as a local variable, then set card.ability.extra.tally to be card.ability.extra.compare.

faint yacht
cinder elk
#

oh; nice; for future reference, where does balatro keep all the code for the cards

faint yacht
#

card.lua within executable itself.

cinder elk
#

got it; thanks

merry raven
#
calculate = function(self, card, context)
        if context.after then
            if G.GAME and G.GAME.chips and G.GAME.mult then
                if G.GAME.chips > G.GAME.mult then
                    local halved_chips = G.GAME.chips / 2
                    G.GAME.mult = G.GAME.mult + halved_chips
                    return {
                        message = "Balanced!",
                        colour = G.C.MULT,
                        card = card
                    }
                elseif G.GAME.chips < G.GAME.mult then
                    local halved_mult = G.GAME.mult / 2
                    G.GAME.chips = G.GAME.chips + halved_mult
                    return {
                        message = "Balanced!",
                        colour = G.C.CHIPS,
                        card = card
                    }
                end
            end
        end
    end

Trying my hand to make the Joker I talked about earlier, its ability is when at the end of a hand, it will check whether the chip or mult total is higher, and the higher one will have its value halved and added to the lower one

Unfortunately it's not triggering the joker for me, what am I missing? Do I need joker_main?

faint yacht
#

Tried with context.joker_main as part of the condition of contexts?

cinder elk
merry raven
cinder elk
#

this is. probably the reason why. im still very new to this.-

faint yacht
#

calculate is a function too.

calculate = function(self, card, context)
  if context.joker_main then
    return {chip_mod = 50}
  end
end
cinder elk
#

i'll. work on this some other time once modding becomes a bit more. understandable???

storm oar
#

is it possible to make a voucher appear more rarely or is it just purely a random selection out of however many vouchers?

hardy viper
#

but i don't think theres a way to add a weight

#

regardless the prior will artificially make it 4 times rarer

storm oar
#

that would work, cause i want the vouchers for my mod to be somewhat rare since they may result in crazy builds if luck is on the player's side

merry raven
#
SMODS.Joker{
    key = "balance",
    loc_txt = {
        name = "Facet of Balance",
        text = {
            "If the total Chip or Mult amount",
            "is lower than the other, {C:attention}sacrifice",
            "half of the higher amount{} to be added",
            "to the lower amount"
        }
    },
    atlas = 'Jokers',
    rarity = 2,
    cost = 4,
    blueprint_compat = false,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = true,
    pos = {x=0, y=0},
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                message = "Balanced!",
                colour = G.C.MULT,
                card = card
            }
        end
        
        if not context.before then
            if G.GAME and G.GAME.chips and G.GAME.mult then
                if G.GAME.chips > G.GAME.mult then
                    local halved_chips = G.GAME.chips / 2
                    G.GAME.mult = G.GAME.mult + halved_chips
                    return {
                        message = "Balanced!",
                        colour = G.C.MULT,
                        card = card
                    }
                elseif G.GAME.chips < G.GAME.mult then
                    local halved_mult = G.GAME.mult / 2
                    G.GAME.chips = G.GAME.chips + halved_mult
                    return {
                        message = "Balanced!",
                        colour = G.C.CHIPS,
                        card = card
                    }
                end
            end
        end
    end
}

Hmm alright, I managed to get my Joker to trigger at the end of a hand and display "Balanced!", but it's not going through the calculations so it's basically an empty joker

Maybe my calculation logic is in the wrong place or something? Or am I missing something?

proper relic
hardy viper
#

a = 87
b = 13
87*13 < 43.5*46.5

proper relic
#

Oh wait I'm stupid

#

Yeah as long as one is over double the other it does help

proper relic
merry raven
proper relic
#

I don't think part is really doing anything anyway? Could probably just get rid of it

merry raven
#

Tried following example mods, they all have like card abilities to increase mult, chips, money etc etc with card.ability
However, my Joker modifies the mult and chip score directly instead

proper relic
#

Could just try replacing "not context.before" with "context.joker_main", getting rid of the original "context.joker_main" thing and seeing what that does. (Also I don't think you're actually removing half of the values from the larger value currently?)

#

I'm still pretty new to this too so I'm not sure if that'll actually work lmao

merry raven
#

I just started today LMAO

faint yacht
#

Why not merge the two into if context.joker_main and context.after then?

#

Though, actually, context.final_scoring_step may be needed instead.

merry raven
#

What does that context do?

faint yacht
#

For any deck effects like 'Plasma' merging chips and mult.

merry raven
# faint yacht Though, actually, `context.final_scoring_step` may be needed instead.
calculate = function(self, card, context)
        if context.joker_main and context.after then
            if G.GAME and G.GAME.chips and G.GAME.mult then
                if G.GAME.chips > G.GAME.mult then
                    local halved_chips = G.GAME.chips / 2
                    G.GAME.mult = G.GAME.mult + halved_chips
                    return {
                        message = "Balanced!",
                        colour = G.C.MULT,
                        card = card
                    }
                elseif G.GAME.chips < G.GAME.mult then
                    local halved_mult = G.GAME.mult / 2
                    G.GAME.chips = G.GAME.chips + halved_mult
                    return {
                        message = "Balanced!",
                        colour = G.C.CHIPS,
                        card = card
                    }
                end
            end
        end
    end

I haven't added context.final_scoring_step yet, does it replace context.after?
And also, it's still not able to reach the return statements, and I'm not sure how to rearrange them

faint yacht
#

Replace, yes.

proper relic
#

Does lua evaluate integers as true or false? If not "G.GAME and G.GAME.chips and G.GAME.mult" is probably causing the issue since chips and mult should theoretically both be integers

merry raven
#

If I don't add them, the game crashes since it detects them as NIL

faint yacht
#

Conditionals (such as the ones in control structures) consider false and nil as false and anything else as true. Beware that, unlike some other scripting languages, Lua considers both zero and the empty string as true in conditional tests.

#

Try using hand_chips & mult in place of G.GAME.chips & G.GAME.mult respectively?

proper relic
#

Lua is strange

faint yacht
#

Just wait until you see SRB2's implementation of it, known as BLua. 😂

merry raven
#

Just hand_chips and mult? No prefixes in front of them?

faint yacht
#

No prefixes.

merry raven
#

Gotcha lemme try it out

faint yacht
#

You may need to also use update_hand_text({delay = 0}, {chips = hand_chips, mult = mult}) to update the shown values.

merry raven
#

Is that outside of calculate?

faint yacht
#

No, you call that after modifying the values.

merry raven
#

Lemme give it a go

faint yacht
#

Right after, in fact.

merry raven
#
calculate = function(self, card, context)
        if context.joker_main and context.final_scoring_step then
            if G.GAME and hand_chips and mult then
                if hand_chips > mult then
                    local halved_chips = hand_chips / 2
                    mult = mult + halved_chips
                    update_hand_text({delay = 0}, {chips = hand_chips, mult = mult})
                    return {
                        message = "Balanced!",
                        colour = G.C.MULT,
                        card = card
                    }
                elseif hand_chips < mult then
                    local halved_mult = mult / 2
                    hand_chips = hand_chips + halved_mult
                    update_hand_text({delay = 0}, {chips = hand_chips, mult = mult})
                    return {
                        message = "Balanced!",
                        colour = G.C.CHIPS,
                        card = card
                    }
                end
            end
        end
    end

Ooh boy, it's still not triggering after I've played a hand, sorry for basically making yall do my homework but I'm still lost haha

faint yacht
#

Comment out the if G.GAME and hand_chips and mult then bit with its' end?

#

What of just having context.joker_main on its' own?

merry raven
#

Cheers to all of you who helped me!!

faint yacht
#

🤝

merry raven
#

Well somewhat, I haven't made the subtraction part yet, but it's there

#

There we go!

faint yacht
#

The Balanced! doesn't really fit there... maybe there's a better synonym for it that could fit better. 🤔

merry raven
#

Maybe I could use numbers instead

faint yacht
#

As you're literally taking half away from one and allocating them to the other... Reallocated!.

merry raven
#

I'll think about it!
One down, a couple dozen more to go
Also one more question, if I were to create custom Enhancements (like some of them you see here like Radiant, Volatile, etc), are they just automatically made global? Or do I have to do extra work to make them work?

faint yacht
#

They technically are... but you may need to make a card actually apply them, be it a special Joker or a consumable.

storm oar
#

another question, would it be possible to add an extra modifier type for cards on top of the ones that already exist, or only add to the current types of modifiers?

merry raven
faint yacht
#

If you make it a Tarot or a Spectral card, not necessarily, but also still could be done if custom consumable type.

merry raven
#

Oh yeah they aren't tarot or spectral or planet cards, they're just enhancements like Mult Cards, Wild Cards, etc

Kinda like this

faint yacht
#

If you want these cards to spawn only via Booster Packs, sure.

merry raven
storm oar
storm oar
#

mainly cause I'm wanting to make a thing where, if you purchase a certain voucher, upon losing a run you can continue in a way, but with some extra effects, and one that I was thinking was a "reincarnation" thing where it resets the ante to 1 and resets the deck to its starting condition, but with a chance to keep some of the cards from your deck when you lost, replacing cards in the normal deck, as well as a smaller chance to retain jokers, but with a "Reincarnated" effect for the cards that doesnt replace the edition, seal, or enhancement for the card and makes it so that you cannot destroy, discard, or modify the card without a certain joker

faint yacht
#

I don't have enough knowledge for additional modifiers. Best wait for someone else with more know-how on such things to pop in. 😅

storm oar
#

I just hope its possible to do, or if not now then sometime in the future

mellow sable
steep rain
#

Planning to make a Balatro mod soon, currently jotting down some ideas for stuff I might add in

wintry solar
#

@unique elm also your joker is reallocating wherever it is in joker ordering, rather than at the very end of scoring, don’t know if that’s what you want it to be or not

storm oar
wintry solar
#

I think lobcorp does? @crisp coral

shell tangle
#

I believe it's done using stickers, since stickers can overlap with each other.

wintry solar
#

Then publicly I’m not sure if it exists yet

storm oar
#

but is that only for jokers, or could i make it so any card can have a sticker?

wintry solar
#

But here’s a short preview of the type I’m currently working in for ortalab

storm oar
#

if anything i could probably just experiment and see if i can figure out how to do something like that

wintry solar
#

How much modding have you done so far?

storm oar
#

not much at all, i just started yesterday though i do have a bunch of experience with lua so that helps

crisp coral
storm oar
#

ah so does it add another type or is it one of the other already existing ones?

crisp coral
#

neither i believe, they're not categorized

copper smelt
#

Hi! I wanted to make a joker called "Positive Reinforcement" where it gives you +6 mult when the hand played is your most played poker hand, I was wondering if there was a way to get your most played poker hand? Or will I have to keep track of that myself

crisp coral
#

and not added via smods.gameobject

storm oar
#

hm well then i may need to dig into the code to see how it works then?

crisp coral
#

it's just card.ability.modifier and a lovely patch to draw the modifier sprite

wintry solar
#

Either way, this probably isn’t the easiest place to start modding, it requires a fairly good understanding of the game code to know what you need to do

storm oar
#

eh, I'll see what happens and try to learn as i go, starting with the simpler stuff then doing the more complex things

#

so far all I've started on is adding vouchers

#

honestly the hardest part for me will probably be the sprites

shell tangle
nocturne garnet
#

just set unlocked to false and add an unlock conditions

unreal jolt
#

hello chat, I would like to learn how to mod this game. where do I start? I already have coding experience.

teal estuary
merry raven
teal estuary
#

ahhh, fair enough

#

good luck to you then 😭

merry raven
#

SMODS.Enhancement is severely underdocumented

teal estuary
#

oh yeah, its still wip

kind gorge
#

Anyone here that knows a good way to merge loc files? Hmmge

wintry swallow
kind gorge
merry raven
#

Try making a Joker since that's really nicely documented

teal estuary
#
if context.repetition and context.cardarea == G.play and not context.repetition_only then
      local leftCard, rightCard
        for i, playedCard in pairs(context.scoring_hand) do
        if playedCard == context.other_card then
          leftCard = context.scoring_hand[i-1]
          rightCard = context.scoring_hand[i+1]
      break
      end

where/how would i add a check to this to make sure that leftCard and rightCard are of a specific enhancement? i'd presume it'd be something like:
context.scoring_hand[i-1] and [enhancement check] = "enhancement-name", but i just wanna make sure before i attempt this again 😭

kind gorge
# teal estuary ```lua if context.repetition and context.cardarea == G.play and not context.repe...
    local leftCard, rightCard
    for i, playedCard in pairs(context.scoring_hand) do
        if playedCard == context.other_card then
            leftCard = context.scoring_hand[i-1]
            rightCard = context.scoring_hand[i+1]
            break
        end
    end
    local specific_enhancement = "desired_enhancement"
    if leftCard and rightCard and leftCard.enhancement == specific_enhancement and rightCard.enhancement == specific_enhancement then
        logic here
    end
end```

Thats my thought, when i understood you right ![upsidethinking](https://cdn.discordapp.com/emojis/691982256943661078.webp?size=128 "upsidethinking")
teal estuary
#

that is perfect, ty

#

also helped me figure out where to put my actual enhancement effects, i have no idea what im doing 😭

kind gorge
teal estuary
#

makes sense honestly, same

#

im just using what i've learnt to make jokers, mostly by taking existing code and making it fit 😭

#

no idea how to use lua properly

unreal jolt
#

there is no proper way of using a dynamically typed language

#

the nature of it makes it improper lol

teal estuary
teal estuary
unreal jolt
#

having no types only works when you have very very well made documentation

teal estuary
#

makes sense

#

have you seen factorios documentation? it also uses lua, and the API docs are insane

#

-# its also where i started modding, so maybe im a little biased

unreal jolt
#

factorio devs definitely understand how horrible of an experience Lua is, and so they try to make it as easy as possible. lol

teal estuary
unreal jolt
#

every single time I try a dynamically typed lang, I always end up hating it and stopping what I was doing and also really seriously thinking of starting my own typed embedded language project...

#

but then I remember how hard it actually is to make a programming language after a bunch of books I read

#

balatro is like, the 3rd time on lua

teal estuary
#

honestly i like lua, but as mentioned i've never used it properly so maybe i might hate it and just no know 😭

unreal jolt
#

honestly lua would be so much better if only we could have importable jsDoc style documentation

teal estuary
unreal jolt
#

you could do something like

--import(SMODS.Joker)
SMODS.Joker{
  -- now we have autocomplete yippe
}
#

Sumneko tried it, idk if lua_ls can do it.

teal estuary
#

-# they do use contexts.. hrmmm..

teal estuary
#

the code works

#

it just, doesnt repeat

#

-# although i did have to get rid of context.repetition for it to even print() anything

#

-# do enhancements support retriggers?

unreal jolt
#

they do have docstrings, it works okay. making a mock module with types is feasible

teal estuary
#

fair enough

#

it does seem very useful (the factorio VSC extension uses it), but from the dev of it itself, i've heard it causing a lot of issues

wintry solar
merry raven
#

Example code

wintry solar
#

Oh right there isn’t one in the example mods

#

there are other mods with enhancements you could reference, but also they’re structured like any other object

teal estuary
#

whats the call for modded enhancements? m_[mod-prefix]_[enhancement-key]?

wintry solar
#

Yup

teal estuary
#

hrm.. are there any visible reasons why it wont go past local specific_enhancement = 'm_mjok_copper" then? i can show the entire code if you want, but this seems to be the main issue

wintry solar
#

Because card.enhancement isn’t a thing

teal estuary
#

-# makes sense

wintry solar
#

Use card.config.center_key

teal estuary
#

leftCard.config.center_key == specific_enhancement, or am i interpeting you wrong?

kind gorge
teal estuary
teal estuary
#

cool, ty

frosty dock
teal estuary
#

kid named "i need to look into that, it looked interesting"

#

-# gah why wont this thing just work >:(

frosty dock
#

SMODS.has_enhancement(leftCard, specific_enhancement) ahh util function

frosty dock
#

I love abstracting away vanilla structures instead of changing them when they're bad

teal estuary
frosty dock
#

-# yeah it should be, need to see code to tell what's wrong

teal estuary
#
  calculate = function(self, card, context, effect)
    if context.cardarea == G.play and context.repetition_only then
      print("why so contextious")
      local leftCard, rightCard
      for i, playedCard in pairs(context.scoring_hand) do
          if playedCard == context.other_card then
              leftCard = context.scoring_hand[i-1]
              rightCard = context.scoring_hand[i+1]
              break
          end
      end
      print("why so left and rightcardious")
      if leftCard and rightCard and leftCard.config.center_key == "m_mjok_copper" and rightCard.config.center_key == "m_mjok_copper" then
        print("why so configious")
        card_eval_status_text(card, 'extra', nil, nil, nil, {message = "Zapped!", colour = G.C.GOLD})
        effect.repetitions = card.ability.extra.repetitions
      end
  end
end
#

-# i hate how discord squashes code lines, makes it a pain in the ass

frosty dock
#

looks terrible on mobile

merry raven
#

Are ya makin a custom enhancement?

teal estuary
#

it does

teal estuary
#

trying to, atleast

merry raven
#

Epic
I can observe

teal estuary
#

exactly

wintry solar
#

where is it failing?

teal estuary
#

it wont go past the if leftCard and rightCard and leftCard.config.center_key ==... line

frosty dock
#

have you checked you got the enhancement key right?

teal estuary
#

i.. presume so? first time trying this

#

the key is copper, the mod prefix is mjok

frosty dock
#

ah, logic error

#

this retriggers cards next to two other copper cards exclusively

teal estuary
#

that is what i've been trying it with, but still

wintry solar
#

you're playing 3 copper cards at once?

teal estuary
#

nope, im doing 5, ignore my stupidity

wintry solar
#

and you just get the first 2 print statements 5 times?

teal estuary
#

seems to, yes

nocturne garnet
#

why so copperious

teal estuary
#

😭

#

naming my debugging pritns something stupid is the only thing that keeps me sane

merry raven
#

Nothing beats naming a local variable cockmocker or something

teal estuary
#

one time while working on another joker, every single print was just what the previous line was, with -uzz at the end

#

i have a screenshot somewhere

#

but also, tested it with 3 copper cards, same thing

#

just with 3 prints

wintry solar
#

lemme just check on my end

teal estuary
#

sure

#

should i send the entire enhancement as a codeblock?

merry raven
#

What does context.cardarea == G.play mean, is it a check to see if the card is played?

teal estuary
#

uhhhh, one mo

#

which which card area is being evaulated, G.play is the cards being played(?)

#

theres also G.cards and G.jokers

merry raven
#

I don't follow can you rephrase it haha

nocturne garnet
#

i always name them something something skibidi rizz toilet

wintry solar
#

oh I think I got it

teal estuary
wintry solar
merry raven
#

Ah, gotcha

wintry solar
#

change context.other_card to card

#

other_card isn't sent through repetition checks

teal estuary
#

trying it rn

#

-# should i make it say again to be more clear, r keep it as Zapped! since its.. electricity

wintry solar
#

yes

teal estuary
shell tangle
#

You could play a custom sound if you aren't already to keep the zap effect present.

teal estuary
#

i like the idea a lot more

merry raven
#

Don't mind me copying bits of your code BlackATM
if leftCard and rightCard and leftCard.config.center_key == "m_mjok_copper" and rightCard.config.center_key == "m_mjok_copper" then
This is for checking whether the left and right card of a played card are copper cards, right?

teal estuary
#

oh idm, your free to use my code

teal estuary
merry raven
#

Yeah my Tangle card needs to check its left card and then somehow do some code fucktuckery to make that left card and itself count as one card

teal estuary
#

good luck 😭

merry raven
#

It's either that or scrapping the idea 💀

#

Is there a context or a global value that manages the number of cards played in a hand?

teal estuary
#

i know you can check through how many cards are in a hand, i cannot remeber the code

#

IIRC its a loop over the played hand, or something along those lines

merry raven
#

Do you recall at least some words used, maybe I can scour through this server's chat history to find it

teal estuary
#

urghhhh

#

brain thinking

wintry solar
#

you'd have to cahnge the selected limit, but you'll have to completely rework identifying hands too

merry raven
#

Good lord

teal estuary
merry raven
#

I hope I don't have to directly modify the source code to do that

wintry solar
teal estuary
teal estuary
wintry solar
#

yup

teal estuary
#

wtf

wintry solar
#

I don't know what line in state events that is

shell tangle
#

Update steamodded.

teal estuary
#

OH

wintry solar
#

oh god yes

#

that

teal estuary
#

yeah, tracks

#

hold on

wintry solar
#

and lovely

teal estuary
#

-# i gotta update lovely? Fear

wintry solar
#

you are over 2 months out of date

teal estuary
#

aight, one mo'

#

you havent heard the end of me and my outdated shenagians