#💻・modding-dev

1 messages · Page 148 of 1

minor gyro
#

thanks anyway

orchid thunder
knotty wren
#

how do I make it so that the joker starts with a base X1 mult and then gains mult everytime the context is applied ?

minor gyro
#
  config = { extra = { Xmult = 1, Xmult_mod = 0.1 } },
  loc_vars = function(self, info_queue, card)
    local glass_count = 0
(line 120) for _, v in pairs(G.playing_cards) do
      if v.config.center == G.P_CENTERS.m_glass then glass_count = glass_count + 1
      end
    end
    local current_multiplier = glass_count * card.ability.extra.Xmult_mod
    return { vars = { current_multiplier } }
  end,
  calculate = function(self, card, context)
    if context.joker_main then
      local glass_count = 0
      for _, v in pairs(G.playing_cards) do
        if v.config.center == G.P_CENTERS.m_glass then
          glass_count = glass_count + 1
        end
      end
      local total_multiplier = glass_count * card.ability.extra.Xmult_mod
      if total_multiplier > 0 then
        return {
          Xmult_mod = total_multiplier,
          message = localize { type = 'variable', key = 'a_xmult', vars = { total_multiplier } },
          card = card
        }
      end
    end
  end
}

why is it crashing when trying to read line 120 tho?

#

the locl var needs to be an self ability?

frosty dock
#

-# yes i just pushed a sizeable wiki update

ivory coral
#

hello chat, brand new to modding and lua here, how can i see exactly how vanilla's jokers are coded? I'm trying to copy some functionality from them. I've found the card.lua file but i cant really work out how it does what it does there (to be specific im trying to make a joker that retriggers played cards if you play a flush/flush variant)

frosty dock
#

the calculate function you'd want for this is actually pretty simple, it'd look something like

config = { extra = { repetitions = 1 } }, -- because we don't like to hardcode config values
calculate = function(self, card, context)
  if context.repetition and context.cardarea == G.play and context.poker_hands['Flush'] then
    return {
      repetitions = card.ability.extra.repetitions,
      message = localize('k_again_ex'),
      card = card
    }
  end
end
knotty wren
#

can I not have 2 of these? it doesn't work

frosty dock
#

what doesn't work?

knotty wren
#

game doesn't start

#

if i only keep the if context.joker_main then it starts

frosty dock
#

well you do have a syntax error

#

why is there a comma

knotty wren
#

oh, it WAS the comma

#

damn

minor gyro
#

Hey, John smods

slow ocean
#

huh

minor gyro
#

@frosty dock

frosty dock
minor gyro
#

120

ivory coral
frosty dock
#

i have no idea what that means

#

i can't magically see the line numbers from a snippet of a file

minor gyro
#

I wrote that tho

#

and this

slow ocean
#

its probably better to just post the actual line in question

#

like, copy paste, instead of snipping it

frosty dock
#

yeah that's extremely easy to miss

minor gyro
#

for _, v in pairs(G.playing_cards) do
if v.config.center == G.P_CENTERS.m_glass then glass_count = glass_count + 1
end
end

slow ocean
#

protip: you can surround your message with triple graves (`), found usually next to your 1 button in order to format it in a nice block.
like this

#

makes stuff easier to read (in my opinion)

frosty dock
minor gyro
slow ocean
#

fair

minor gyro
slow ocean
#

i couldn't give you direct pointers but perhaps look at the drafting mod to see how that's done?

minor gyro
#

it crashes when I try to hover on the joker to see it's text

slow ocean
#

in that case that's more of tags being processed first

minor gyro
#

oh

#

oh

#

i got it

#

LMAO

#

idk why i did not see that

frosty dock
#

yeah you need a fallback

#

also uh

#

is this supposed to be a downside when you have 10 or less glass cards?

minor gyro
slow ocean
#

trying to link the actual drafting mod i'm thinking of

frosty dock
#

you're just passing the amount*0.1 as the mult

slow ocean
#

it's just a deck that gives you 10 "draft tags" at the start of the run

frosty dock
#

you'd want to add card.ability.extra.Xmult (or 1) to it

minor gyro
#

Can i just send you the file in your dm? I'm new at coding and it would be simpler I think

slow ocean
#

troubleshooting in a public forum is a skill

#

one just as important as coding

minor gyro
#

I just don't want to flood things here

slow ocean
#

its what the channel is (mostly) for

frosty dock
#

this is literally what the channel is for though

#

I'd rather not give DM support where it can be avoided

slow ocean
#

thats why we have modding-chat

minor gyro
minor gyro
frosty dock
#

besides all you really need is to change glass_count * card.ability.extra.Xmult_mod to card.ability.extra.Xmult + glass_count * card.ability.extra.Xmult_mod

#

and check if G.playing_cards exists before trying to count glass cards

minor gyro
slow ocean
#

yeah you might be missing a nested conditional

#

ive definitely had issues where the fix was to nest it under some conditional checking if the appropriate zone was active/exists

minor gyro
#

the only thing is the 'k'

#

and Idk where it's used

frosty dock
#
  loc_vars = function(self, info_queue, card)
    local glass_count = 0
+   if G.playing_cards then
      for _, v in pairs(G.playing_cards) do
        if v.config.center == G.P_CENTERS.m_glass then glass_count = glass_count + 1
        end
      end
+   end
-   local current_multiplier = glass_count * card.ability.extra.Xmult_mod
+   local current_multiplier = card.ability.extra.Xmult + glass_count * card.ability.extra.Xmult_mod
    return { vars = { current_multiplier } }
  end,
  calculate = function(self, card, context)
    if context.joker_main then
      local glass_count = 0
      for _, v in pairs(G.playing_cards) do
        if v.config.center == G.P_CENTERS.m_glass then
          glass_count = glass_count + 1
        end
      end
-      local total_multiplier = glass_count * card.ability.extra.Xmult_mod
+      local total_multiplier = card.ability.extra.Xmult + glass_count * card.ability.extra.Xmult_mod
      if total_multiplier > 0 then
        return {
          Xmult_mod = total_multiplier,
          message = localize { type = 'variable', key = 'a_xmult', vars = { total_multiplier } },
          card = card
        }
      end
    end
  end
}
manic grotto
#

bumping this

#

nvm

frosty dock
manic grotto
#

just struggling with descriptions

#

yeah probably do

#

thanks

frosty dock
#

i should maybe change those to not use loadstring, the buffer names being the string length is ridiculous

minor gyro
#

u just added a condicional

frosty dock
#

G.playing_cards only exists when you're in a run

minor gyro
frosty dock
#

so this just acts as a fallback for when you're not

minor gyro
#

okkk

#

thanks

#

ur an angel

frosty dock
#

(in which case it's safe to assume you don't have any glass cards)

#

ty

knotty wren
#

I'm trying to add an upgrade feature but idk what I'm doing

#

can someone point me to the right direction please?

knotty wren
#

this did not work

#

bwahhh

faint yacht
# knotty wren I'm trying to add an upgrade feature but idk what I'm doing

Adjust your "config" for this, but if you want the Joker to upgrade every time there's a 4-card hand played...

if context.before and #context.scoring_hand == 4 then
  card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_gain
  return { message = localize('k_upgrade_ex') }
end

if context.joker_main then
  return {
    card = card,
    x_mult = card.ability.extra.Xmult
  }
end
knotty wren
#

mmmmmhhh I get it now

#

that's how variables work on LUA then?

faint yacht
#

Also, loc_vars... that should have function(self, info_queue, card), really, not center.

knotty wren
#

the game crashes when I score

crisp coral
#

center is a cryptid moment

knotty wren
frosty dock
#

certified cryptidm oment

noble frigate
#

is this a known glitch?

faint yacht
noble frigate
#

idk what could be causing it

minor gyro
noble frigate
#

it's base game

#

all stakes are ERROR and nothing works xd

knotty wren
#

nvm fixed it

#

am smart

knotty wren
faint yacht
#

...huh, bizarre, but if it works, it works... just not the usual method on latest SMODS and what not.

frosty dock
# knotty wren

well you'd need to change both the argument (self, info_queue, card) and its usage card.ability

frosty dock
noble frigate
#

when i won again on white stake it didn't update either

frosty dock
#

yeah sounds like outdated galdur

noble frigate
#

for /d %s in (*) do (cd %s && git pull)

#

if anyone wants to like

#

update all subfolders

#

am i stupid or can i not find the galdur repo

frosty dock
noble frigate
#

danke

frosty dock
#

np

noble frigate
#

oh hey it works now

#

thank you kind internet stranger

#

oh wait damn you're the actual john smods?

#

good shit, thanks for the smod

wintry solar
#

saint aure doing my work in troubleshooting galdur bugs

frosty dock
noble frigate
#

no way it's eremel galdur

#

im surrounded by celebrities

noble frigate
#

no way

frosty dock
tight thistle
#

does anybody know how to make the text box durations more streamlined? not sure why the first one has such a huge empty space after it

gritty dirge
#

currently going crazy trying to make a custom card deck for someone but getting stuck, so trying my luck here 🙏
i have changed the suits to custom art with their own colours but i cant for the life of me find where in the .lua s the colour of the name of the suit that shows up when hovering over the playing card in hand is defined (in hex or from the global colour variables)
Anyone knows where i can find those? (i´ve found the one for the joker text already in the high contrast ones in global.lua but no dice for this one)

#

(pretty sure it´s not connected to the global colour variables, because i´ve already tried changing them but only got flashbanged by pastel colours in the main menu but the names were still the same ^^)

frosty dock
#

globals.lua

#

note you need to change the SO_1 (low contrast) and SO_2 (high contrast) and not the SUITS

#

also need to start a new run for the change to apply iirc

night pagoda
#

Aren't the SUITS one is just picking from SO_1 and SO_2

gritty dirge
minor gyro
#

thanks allot loll

night pagoda
frosty dock
#

right

gritty dirge
minor gyro
#

is there a way to break the text without having to rewrite all the {c}, {s:} etc?

tepid crow
#

you mean a newline right?

minor gyro
#

yh

frosty dock
#

no, these are per line

minor gyro
#

okk

#

thanks

#

just to make sure

tepid crow
#

seems like other events are happening at the same time (the cashout screen)

#

what trigger are you using?

#

a different question related to my own code - can I not return a message from context.remove_playing_cards?

tight thistle
tepid crow
#

either change the trigger or take a look at the blockable property (this might break when pausing the game using esc? idk you'll have to try it out)

tight thistle
#

ohhh i didnt think to use the blockable/blocking stuff

tepid crow
frosty dock
#

uhhhhh

#

are the cards being destroyed from a consumable?

tepid crow
#

yes

#

I didn't think to test anything else other than consumables/debugplus' delete

frosty dock
#

because for some reason this was missed in Card:use_consumeable

#

debugplus delete might just not be updated to use calculate_context

tepid crow
#

oh lol it works when using joker's delete haha

#

wait is it specifically hanged man? 🤔

#

oh also immolate

#

but familiar grim and incantation work for some reason

frosty dock
#

doesn't seem like they should

tepid crow
#

looks like SMODS takes ownership of familiar, grim and incantation and properly creates the right contexts

frosty dock
#

oh right, it does

#

f1xed

tepid crow
#

lemme check

#

seems to work, thanks 👍

tight thistle
tepid crow
#

hmm, the messages still seem to be fighting some other events?

tight thistle
#

yeah, its strange

tepid crow
#

what approach did you use / what's your code looking like right now?

tight thistle
#

oh i just stacked a bunch of G.E_MANAGER:add_event on top of eachother which is probably not ideal

#
 G.E_MANAGER:add_event(Event({
                    trigger = 'after',
                    delay = 0.0,
                    blocking = true,
                    func = function()
                        local text_key = 'erlking_end_1'
                        local align = nil
                        local loc_vars = {quip = true}
                        local n = 5
                        card:jcbb_add_speech_bubble(text_key,align,loc_vars)
                        card:jcbb_say_stuff(n,false)
                        play_sound('jcbb_letmeseeyoureyes')
                        return true,
                        G.E_MANAGER:add_event(Event({
                            trigger = 'after',
                            delay = 5,
                            blocking = true,
                            blockable = true,
                            func = function()
                                card:jcbb_remove_speech_bubble()
                                local text_key = 'erlking_end_2'
                                local align = nil
                                local loc_vars = {quip = true}
                                local n = 5
                                card:jcbb_add_speech_bubble(text_key,align,loc_vars)
                                card:jcbb_say_stuff(n,false)
                                return true,```
#

this is, like, only 20% of what the code is looking like

#

is there a way to do consecutive events without having to keep stacking G.E_MANAGER:add_event over and over?

tepid crow
#

wait so what did you change in your code since your first message?

tight thistle
#

i set blocking from false to true

minor gyro
#

Dumbass question here, but when the joker has triggered, how should I make it "shake"?

tepid crow
crisp coral
#

oh false blockable might also work, but might also interfere with base game

tight thistle
#

or uh, the code for making a joker wiggle when it triggers

tight thistle
tepid crow
#

yeah in a row instead of containing one another

tight thistle
tepid crow
zealous glen
#

you could also

tepid crow
#

but make sure to test it

zealous glen
#

create an event that persists while the message exists

#

and when it dies it fires the destruction

tight thistle
tepid crow
hollow charm
#

hey, i'm new to balatro modding and need some help
Is there any way to add a different card back to different suits? i have these uno card numbers (sprites by @scarlet spire) and i want to add colored card backs to them instead of the default white one?

zealous glen
#

You can make the blank texture black and add a colorful part to each rank

tender gale
#

how to make a joker add extra discards? Copying drunkard's code doesn't work

scarlet spire
#

I'm the one doing the sprites for this, and i'll elaborate a little: having the colored part of the uno card as part of the sprite for the rank doesn't work too well, as most enhancements get covered up partially or almost entirely by those colored sections

#

so the idea is custom images for the enhancements themselves, so that they can be better incorporated into the designs of the uno cards

#

as an example

zealous glen
#

maybe the draw method for SMODS.Centers helps idk

#

or otherwise patching or hooking the draw pipeline

tight thistle
tepid crow
#

yeah

#

though it might be harder to time that way

tight thistle
#

when i do it like this the joker plays the sound and instantly deletes itself with no animation

hollow charm
# zealous glen or otherwise patching or hooking the draw pipeline

i'm just starting out with balatro modding and i can't really find anything on what or where this refers to
i'm also checking the steamodded github wiki i can't find SMODS.Center as a page (though i swear it once was)
any help with what this'd mean or how it'd work

zealous glen
frosty dock
#

the SMODS.Center page sucked

#

way too unorganized

tepid crow
#

oh they got refactored? niiceeee

zealous glen
#

Everything else is ordered alphabetically

#

except these two

frosty dock
#

good question

frosty dock
#

probably because they're ordered that way in the code and I didn't think to change the order

tepid crow
#

is there any real reason those 2 should be on 1 page?

zealous glen
# hollow charm ah

anyways there is also a draw method for Ranks and Suits under "Suit and Rank"

#

Unfortunately no one knows how draw works

#

because it's never explained

#

-# keku and someone else have supposedly used it

frosty dock
#

what you do is you look at how Card:draw works in vanilla code

zealous glen
#

-# keku's seemed slightly jank

zealous glen
frosty dock
#

tbf I should document that properly

zealous glen
#

as exemplified by self and card confusion

zealous glen
hollow charm
#

i see

frosty dock
#

also draw might need a better system if we don't want to have anything advanced having to rely on lovely patches

zealous glen
#

agreed

frosty dock
#

it's a 300 line function so I'm scared to refactor it completely but I might have to

edgy reef
#

I already looked through it, you'll be forced 😄

frosty dock
#

I figured

zealous glen
#

aure (and other Steamodded contributors) supporting an unpaid project like Atlas holding up the heavens

edgy reef
#

It doesn't particularly do much, it basically just "draws shadow, draws main sprite or card back, draws addition sprites/shaders".

zealous glen
#

but in the right order

edgy reef
#

And it's spaghetti

zealous glen
#

thunk discovered to be part italian part chinese

#

part eminem

edgy reef
#

It is technically simple but alas even that can be made hard via LocAltHunk coding.

#

And also this isn't precise; I don't actually know what each line of code does.

frosty dock
#

might need it to look something like this API-wise

draw = {
  {
    type = 'after_center',
    func = function() end
  }
}
#

I'll have to blueprint uhh brainstorm that one

hollow charm
# zealous glen

is self, card, and layer each different arguments to pass through?
i'm looking at Card:draw in the vanilla code right now and i only see draw(layer) and i'm not sure what exactly that'd mean when calling the method when defining the suit

frosty dock
#

from there, self gets turned into card because the method is now on a different object

tight thistle
frosty dock
#

and we insert another self to represent the object this is actually being called on

#

in this case, self is the suit and card is what's self in Card.draw originally

frosty dock
edgy reef
#

layer is practically meaningless anyways it's always either "both" or "card" because the function code only gets executed when it's one of those two.

#

It does functionally nothing different other than some shadow logic not being performed on the latter.

frosty dock
#

there's also "shadow" but I think it's never called with that?

edgy reef
#

yea

zealous glen
#

I don't remember how to write or read

frosty dock
#

yap

zealous glen
#

can you repeat that louder I can't read

hollow charm
zealous glen
#

no

frosty dock
#

no you'd have to define it as a function like draw = function(self, card, layer) ... end

hollow charm
#

i see

zealous glen
#

don't you mean

#

👁️

willow quiver
#

yeah sorry

zealous glen
#

smh my head fake fan

warm maple
#

(was told to put this here instead)

zealous glen
tight thistle
#

i dont know how to format it, though

zealous glen
#

what part

tight thistle
#

the is_talking part

zealous glen
#

me neither

#

but the textbox exists somewhere attached to the card

ionic verge
#

how would you get the level of the last hand played

#

i know how to get the name

zealous glen
#

last hand is tracked by blue seal

hollow charm
zealous glen
#

then you access the hand level repository

zealous glen
#

it's not automatic

ionic verge
#

i tried doing something like this

hollow charm
#

ohhh i see

ionic verge
#

(hand index = 1 as a fail safe)

zealous glen
ionic verge
#

because i need it after scoring is done

tight thistle
#

im just gonna keep the effect as it is and just forget about it

ionic verge
#

does it reset

zealous glen
#

but again you can just use the one used by blue seal

ionic verge
#

imma be real i dont think i can, cus i dont see anything giving a level in the code that triggers blue seals

#

cus i need specifically the level

zealous glen
#

you don't get it

#

blue gets you the hand name

#

the hand name allows you to access the level

#

if you don't need the name you don't need context.scoring_name

ionic verge
#

ok

#

i think i get what to do, but i just want to post my problem rq

zealous glen
#

although I'm confused about what name you need

#

since you want to remember the last hand but also forget it immediately

ionic verge
#

the level doesnt appear right away in the hand text thing

#

and i would like for it to

#

because thats how any hand level up looks like

zealous glen
#

I mean that's just how vanilla does it

#

It displays the level only at the end

ionic verge
#

it does?

foggy carbon
#

yep

ionic verge
#

i thought it showed the old level before it got updated

#

no

foggy carbon
#
  • chips
  • mult
  • level
    is the order
ionic verge
#

one sec lemme get a vid

zealous glen
#

you're using the function that updates hand levels right

#

that's vanilla

foggy carbon
#

is that joker supposed to, like, level up whatever is in the consumables slot?

ionic verge
#

the old level appears before the new level takes its spot

#

so yes, it does in fact show the old level and i need to get that level

#

i dont know why it aint calling it in the first place

#

but it is

zealous glen
#

are you using update_hand_level?

ionic verge
#

which is used i believe in burnt joker

#

one sec

#

yeah level up hand is used in burnt joker

#

space joker is weird because it just uses return { level_up = true }

runic pecan
#

what about the code in card:use_consumeable and if ability set == planet
(currently not by my pc, let me take a moment to go to check)

zealous glen
#

my bad

#

I mixed up two function names in my head

#

But yes that's vanilla

#

so if it doesn't work properly the issue is elsewhere

#

why isn't the level there in the first place

ionic verge
#

good question.

zealous glen
#

I think that's your issue

#

either you broke it elsewhere, or another mod did

foggy carbon
#

but it works fine with the planet card he used just afterwards

zealous glen
#

The issue is that the level text isn't present when it first levels up

#

Then it remains there

ionic verge
foggy carbon
#

my point is that the proper behavior is still present within the code that is running (as seen with the second video) but for some reason something else happens with the joker

zealous glen
#

No I don't think it's the Joker unless they're messing with the UI

ionic verge
#

(im not)

#

this is the code surrounding the level up

#

the two updates are to set the hand right and then reset it right after

#

(because it wasnt resetting either)

#

i dont know what to put in the level field in #1

zealous glen
#

have you tried commenting out the first line

ionic verge
#

yes.

#

it was like this before that line existed

zealous glen
#

right now you're overriding the current level text with an empty string

ionic verge
#

yes i know

zealous glen
#

look you don't need to manually update the hand text

ionic verge
#

thats a temporary thing

zealous glen
#

so you can remove that

#

Both of them

ionic verge
#

it happens without that level = '' line

zealous glen
#

good

ionic verge
#

no i mean

zealous glen
#

but with the line it'll make debugging confusing

ionic verge
#

the problem does

zealous glen
#

because the line also introduces the same issue

ionic verge
#

i was gonna put the level there

zealous glen
#

don't

ionic verge
#

the fact its blank is temporary

zealous glen
#

fix the actual issue ;P

ionic verge
#

alright.
how the fuck would i fix this.

#

because i dont know what the fucking issue is

zealous glen
#

first, remove the update hand text

#

to find what the issue is

finite patio
#

question...how easy is it to make mods for balatro like making a simple skin mod for playing cards

zealous glen
#

again you're either changing the level line elsewhere, doing something in the wrong timing, or it's a Steamodded issue (@frosty dock)

zealous glen
crisp coral
ionic verge
#

outside what.

crisp coral
#

outside return

finite patio
ionic verge
runic pecan
crisp coral
#

also why is it context.card

#

and not just

zealous glen
crisp coral
#

card

crisp coral
#

lmao

zealous glen
#

Because it should display the level already

ionic verge
#

im done with this shit, this was very frustrating

zealous glen
#

You can read what I said too

#

I said it shouldn't be necessary because the game should already display the level

#

If it isn't displaying the level the bug is elsewhere

ionic verge
#

yeah well it fucking doesnt

zealous glen
#

this doesn't fix the bug

#

it just sweeps it under the rug

ionic verge
#

i literally do not care

zealous glen
#

If your mod is broken it will break other people's mods

#

Or if it's Steamodded then the issue should be fixed globally

ionic verge
#

waaaa

zealous glen
#

also I had told you how to access the hand level

ionic verge
#

im muting this channel for a bit cya

runic pecan
zealous glen
#

My modded Balatro also does it

zealous glen
#

If theirs doesn't, they either have introduced a bug, are doing something wrong, or it's a Steamodded issue

#

This fix sweeps the actual bug under the rug

crisp coral
#

theirs doesn't because they specified the level to be an empty string

#

what

runic pecan
#

This is what I screenshot from card.lua

zealous glen
#

They said they had the issue prior to introducing that line

#

I told them to remove it

#

and they refused because "it was already causing problems before"

runic pecan
zealous glen
#

What does that mean

crisp coral
#

???????????

zealous glen
#

Their problem was the lack of level number

runic pecan
#

Because RadDealer's level number problem is solved... isn't it?

zealous glen
#

No?

#

It's swept under the rug

zealous glen
#

From their description, it seems like displaying the level number before a level up was broken, so this fix only addresses this specific instance instead of everything that can level up a hand

#

like other Jokers

runic pecan
#

Then what do you think RadDealer meant for "it worked"?

zealous glen
crisp coral
#

idk what else to tell you man

crisp coral
zealous glen
minor gyro
zealous glen
#

They said they already didn't have the level before introducing that line with the empty string

#

Which shouldn't be the case because selecting a hand displays its level

#

So they broke something elsewhere

runic pecan
#

Maybe we resume this arguement when Rad Dealer is back so we can ask further question? I have sprites to draw.

zealous glen
#

I only really care if it's a Steamodded issue

#

and also because you both are criticizing me without reading the logs

#

the first thing I explained was how to retrieve the current hand level

#

then I told them to get rid of the line that removed the hand level

tepid crow
#

I don't think Rad Dealer's coming back lol

crisp coral
#

iunno man if it works it works

zealous glen
runic pecan
crisp coral
#

i'm leaving

zealous glen
#

if they don't want their Joker to lack a level, why should other modded Jokers lack a level

zealous glen
#

I was trying to get them to figure it out

#

but they refused

ionic verge
runic pecan
#

After all, it's just a string.

minor gyro
# crisp coral ``card:juice_up()``

It does not work how i want... If it ads +5 mult per card played, how can I make it shake when it gives +5 mult? that's the question

    calculate = function(self, card, context)
      if context.individual and context.cardarea == G.play then
        if context.other_card:is_suit(G.GAME.current_round.joker_random_suit.suit) then
          return {
            Xmult_mod = card.ability.extra.Xmult,
            message = localize { type = 'variable', key = 'a_xmult', vars = { card.ability.extra.Xmult } },
            card = context.other_card,
+           card:juice_up(0.3, 0.4)
          }
        end
      end
    end
```should i put here?
crisp coral
#

not in return, before it

minor gyro
#

but in calc?

#

okk

#

not working... I want so everytime a card uses the ability the jk jumps

runic pecan
minor gyro
#

I know how to print bro 😭

runic pecan
minor gyro
#

npp

runic pecan
#

The position looks fine to me, but I recommend juice_up(0.5,0.5) or just juice_up()

tepid crow
runic pecan
tepid crow
#

huh, weird

#

oh phone would kinda make sense

#

pc is weird though 🤔

minor gyro
#

yh

weak gate
#
    key = 'phj_sub25',
    loc_txt = {
      name = 'Sub25',
      text = {
        "{X:mult,C:white} X#1# {} Mult",
        "if the sum of ranks",
        "in the played hand",
        "is lower than {C:attention}25{}",
      }
    },
    config = { extra = { Xmult = 3 } },
    rarity = 1,
    atlas = 'Pokerholm',
    pos = { x = 3, y = 0 },
    cost = 5,
    discovered = true,
    loc_vars = function(self, info_queue, card)
      return { vars = { card.ability.extra.Xmult } }
    end,
    calculate = function(self, card, context)
        if context.before then
            local rank_sum = 0
            for k,v in ipairs(context.full_hand) do
                rank_sum = rank_sum + v:get_id()
            end

            if rank_sum < 25 then
                return {
                    Xmult = card.ability.extra.Xmult
                }
            end
        end
    end
  }```
How'd I fix my joker to do what it says, boosting hands where the sum is under 25?
tepid crow
runic pecan
weak gate
#

A good question. I think as 1

#

face cards as 10

tepid crow
#

how about stone card?

#

0?

weak gate
#

I think stone would count as 50 in this case

runic pecan
#

Then you have to add if v:get_id()==14 then rank_sum = rank_sum + 1 for Aces

tepid crow
#

really? 🤔

#

I'd argue 0 since stone says "has no rank or suit"

weak gate
#

that is also valid; how do I check for a stone card anyhow?

merry raven
#

How would I go about making it so that only one instance of a Joker can be in my Joker hand at a time

runic pecan
#

And then elseif v:get_id()<=13 and v:get_id()>=10 then rank_sum = rank_sum + 10

tepid crow
#

yeah I don't think you should be using :get_id at that point

tepid crow
runic pecan
tepid crow
#

nice example haha

tepid crow
runic pecan
weak gate
#

interesting, hmhm

merry raven
#

No copies yeah

#

No copies, or if you manage to stumble upon a second Joker in a shop or booster packs you can't obtain it

runic pecan
#

Fun Fact:
:get_id() returns a random number between -100 to -1000000 when it's a stone card.

weak gate
zealous glen
orchid thunder
#

Is it possible to call the calculate function with a custom context

zealous glen
#

you could hook or patch into that

merry raven
#

Gotcha, but what about duplication prevention

tepid crow
zealous glen
#

for copies it sounds a bit trickier. The dumb solution is to hook/patch create_card and not create anything if it tries to create the card

#

The smarter solution needs to know how copies are made

#

which I don't

orchid thunder
#

Using calculate(self, card, custom context)
Then have in the function have if context.custom context then
End

merry raven
tepid crow
#

stopping duplicates from showing up is a lot easier

#

rather than preventing the player from buying a second copy if it does show up

merry raven
#

Mmmm gotcha, where can I look into for this?

zealous glen
#

Duplicates already shouldn't show up except with Showman

#

But other mods could have similar effects so Idk

tepid crow
#

yeah just as confirmation, you know how showman works right jitjet?

zealous glen
#

similar to Showman

merry raven
#

I forgog

#

I spent more time modding than actually playing the game

weak gate
#

is there a way to reload the mods that's faster than quitting and reloading, or disabling and enabling the mod?

merry raven
#

Oh yeah it's that one with a slightly confusing description

tepid crow
merry raven
#

Jokers, etc etc may appear multiple times but not sure where it appears multiple times, shops, my Joker hand, booster packs, I dunno

zealous glen
#

yes

zealous glen
tepid crow
#

holding M I think, unless it changed

weak gate
#

M did it yes

zealous glen
#

I remember there were discussions about trying to do that faster but IIRC there wasn't another way to avoid side effects

tepid crow
#

reloading mods? yeah hard to keep track of

tepid crow
merry raven
#

I wish it's a different keybind because if I quit with VSC in the background I just get mmmmmmmmmmmmmmmmm

minor gyro
#

i just do not know why

ivory coral
#

Trying to make a joker but it isnt exactly working, the joker doesnt even have a texture, name, or text, can someone point out whats breaking in my code because i cant figure it out

    key = 'bubbleuniverse',
    loc_text = {
        name = 'Bubble Universe',
        text = {
            '{C:green}#1# in #7#{} chance for',
            'one random {C:attention}Joker{} to become',
            '{C:dark_edition}Negative{} when selecting {C:attention}Blind{}.'
        }
    },
    blueprint_compat = true,
    eternal_compat = true,
    atlas = 'Jokers',
    pos = {x = 1, y = 0},
    rarity = 4,
    cost = 20,
    config = {extra = {odds = 2}},
    loc_vars = function(self, info_queue, card)
        return {vars = {(G.GAME.probabilities.normal or 1), card.ability.extra.odds}}
    end,
    calculate = function(self, card, context)
        if context.cardarea == G.play and context.poker_hands['High Card'] then
            if pseudorandom('seed') < G.GAME.probabilities.normal / card.ability.extra.odds then
                local chosencard = pseudorandom_element(G.Jokers.cards, pseudoseed('seed')),
                chosencard:set_edition('e_negative', true)
            end
        end
    end
}```
tepid crow
tepid crow
# minor gyro i just do not know why

Magic ✨
(the real reason is card = card lets steamodded know which card to jiggle - the playing card will automatically jiggle because of the individual context)

tepid crow
merry raven
#

Something like that yeah, just any means necessary of stopping cloning and not having more than one instance of that specific Joker

tepid crow
#

ooh, also stuff like invisible joker then 🤔

ivory coral
merry raven
#

Yeah Invisible Joker, Showman, some Spectral cards

tepid crow
merry raven
#

And that's not accounting for any mods that add Jokers or other card types that clones Jokers

ivory coral
ivory coral
#

ive looked that part over so many times 😭 darned monkey brain

tepid crow
#

you're not the first haha, no worries

tepid crow
#

it's not that hard to delete 1 of the 2 if a second ever shows up, but it also kinda sucks for the player if it's not communicated clearly or when invisible joker randomly picks that one

merry raven
#

To be honest, the reason why I want to do this is because my Joker has a soul sprite that can change, but someone pointed out that if there are multiples of that Joker, when a soul sprite changes for one Joker, others will change as well

#

So instead of delving deep into the very foundations of soul sprite rendering I thought it'd be easier to do duplication prevention

zealous glen
#

handles it

#

but I'm gonna guess it's just an extra variable

tepid crow
#

I can see why. You might want to think about what the best approach is. This seems difficult to pull off as well haha. Unfortunately I gotta go 😅
If you do want to do it this way, my suggestions would be to:

  • use in_pool to prevent any duplicates from showing up when using showman
  • use add_to_deck to delete a secondary copy if it ever shows up
  • use some lovely patches to make sure invisible joker/ankh/etc cannot pick your joker nor can be used when it is your only joker
    docs for those first 2 methods
zealous glen
#

I think making each one track the sprite separately is easier

tepid crow
#

probably

merry raven
#

You mean like create multiple instances of Jokers for each change?

weak gate
#
calculate = function(self, card, context)
        if context.before then
            local rank_sum = 0
            for k,v in ipairs(context.full_hand) do
                local _rank = v.base.nominal
                if _rank > 13 then _rank = 1 
                elseif _rank >= 10 and _rank <= 13 then _rank = 10 end
                if SMODS.has_enhancement(v, "m_stone") then _rank = 0 end
                rank_sum = rank_sum + _rank
            end

            if rank_sum < 25 then
                return {
                    Xmult = card.ability.extra.Xmult
                }
            end
        end
    end```
1) Not applying any xmult yet, am I in the right context?
2) Is there a way to print variables during this calculate code block?
3) How do you folks make this code block in discord have syntax highlighting?
zealous glen
zealous glen
merry raven
#

Man so I have to create 8 Jokers, 1 original, 7 with different soul sprites?

zealous glen
#
  1. … it might be xmult or x_mult or x_mult_mod or xmult_mod
weak gate
#

ahhh Xmult_mod according to the examplejokersmod, I see

tight thistle
#

is there a way to encapsulate all the G.E_MANAGER:add_event instances into one block?

#

so that they play one after the other without letting outside events play, maybe? i dunno

zealous glen
#

Maybe

#

Although for talking Jokers I thought allowing other events to play was better

#

to not stall the game

#

but I had many, medium to long messages

knotty wren
#

How can I add a dependency to a SMOD mod?

zealous glen
tight thistle
zealous glen
#

for my implementation, based on Bunco's, based on vanilla, that should theoretically work

tight thistle
#

bunco uses speech bubbles?

weak gate
#

Ahh, the right context for me seems to be context.final_scoring_step. I hadn't noticed it, but in context.before, the xmult WAS applying but it was being reset in the scoring phase

zealous glen
tight thistle
#

huh, interesting

knotty wren
#

thankss, where can I see a list of joker IDs ?

zealous glen
zealous glen
#

I think at the beginning of card thunk defines all loc_vars, or maybe wherever the data to build all prototypes is written

#

the latter should be complete

knotty wren
#

i searched through the archives and didn't find a file with the jokers bwahh

zealous glen
#

starting from 368

knotty wren
#

wooop found it

#

thank youu

#

can i add the rule of all chips requirement doubled for a challenge?

nocturne garnet
wild patrol
#

Man ppl really thought of everything

nocturne garnet
#

all the ideas are taken

#

sorry

wild patrol
#

Well time to steal ideas

slow ocean
#

no more ideas

#

sorry

zealous glen
#

lyman

#

lemon

#

long time no see

wild patrol
#

It's no longer your ideas it's our ideas

merry raven
#

I'm not even safe from accidentally implementing an existing vanilla Joker

zealous glen
zealous glen
slow ocean
#

meow]

#

that was lywoman

zealous glen
slow ocean
#

just recreate lusty joker 10 times

zealous glen
ionic verge
#

what's the key for a blue seal / seals in general, i need it for the infoqueue table thing

#

or window like these

rough furnace
#

iirc it's just blue

ionic verge
#

damn not even like what consumables get with c_inserttarothere?

#

damn

zealous glen
#

I recall aure mentioning that sometimes the correct way to write now should be providing the Center directly

rough furnace
#

I don't think seals have centers

#

unless smods adds them

ionic verge
#

mhm

#

it doesnt to my knowledge

zealous glen
ionic verge
rough furnace
zealous glen
ionic verge
zealous glen
#

which should be providing the "Center"(?)

rough furnace
#

seals do not have centers

ionic verge
zealous glen
#

I agree

#

But according to aure that's the correct way to do it in Steamodded now

ionic verge
#

the code, to be safe

rough furnace
#

no yu'd need the object

#

I'd have to check what set seals are under

#

sorry I haven't done info queue stuff in a while

ionic verge
#

s'all good

ionic verge
rough furnace
#

no

zealous glen
rough furnace
#

for the table

zealous glen
#

The prototypes are in P_SEALS

#

I dunno if SMODS reuses it

#

actually those are the prototypes, not sure if there's another one

#

no I think it should be that one

#

like P_CENTERS

rough furnace
#

oh that might work

#

give it a try

ionic verge
#

P_CENTERS.what?

#

blue?

rough furnace
#

G.P_SEALS.Blue

zealous glen
#

not P_CENTERS, P_SEALS

ionic verge
#

not appearing now

zealous glen
#

Blue

#

not blue

#

I think

rough furnace
ivory coral
#

hello again chat, why am i getting this error for global variable, it looks like its defined as local?

chosencard:set_edition('e_negative', true)```
ionic verge
#

i changed it from the copy paste bc i thought it was an error

zealous glen
ionic verge
#

seeing that most things are in all upper or all lower case

zealous glen
#

does it work without it

rough furnace
#

if that doesn't work try {key = "blue_seal", set = "Other"}

ionic verge
#

it worked

willow quiver
#

thanks to @topaz sun , I merged a localization file PR https://github.com/kcgidw/kcvanilla/pull/9 so now I have english and portuguese
I've pulled it in, what steps do i need to take to integrate it? Do I just need to delete my Jokers' hardcoded loc_txt's or smth? That didnt seem to work

GitHub

Hello there!
I'm on a quest to translate all my favorite mods to Brazilian Portuguese. For this mod, there wasn't a localization folder, so I created one and put the pt_BR.lua loc f...

zealous glen
rough furnace
#

seals my beloved

ivory coral
#

stops the crash at least

orchid thunder
zealous glen
zealous glen
knotty wren
#

I get this when I try to play my custom challenge

willow quiver
zealous glen
#
local a, b = 1, 2
zealous glen
#

anyways see if the dump in the lovely folder helps identify the troubling line

knotty wren
zealous glen
zealous glen
#

I don't know how assigning a default loc_txt works; I only work through localization files

#

so switching languages works for me

knotty wren
wild patrol
#

So the Yu-Gi-Oh cards I'm making the pot of greed destroys itself when u use it

#

You think it should go back into the deck

zealous glen
wild patrol
#

Or just destroy itself

#

Since it gets added to the deck

zealous glen
#

destroy the player for playing an illegal card

wild patrol
#

Lol

zealous glen
wild patrol
#

The funny this is I need to rework the draw effect

#

It's a +3 not 2

knotty wren
wild patrol
#

Because it counts as discarding the card when I activate it so the game gives u 3 instead of just 2

knotty wren
zealous glen
#

for most things it's like… it's easier to do jokers: j_PREFIX_KEY

#

consumeables are c_PREFIX_KEY

#

etc.

knotty wren
#

so it should be something like

#

j_pestrica

#

or j_pesjkr_pestrica

#

?

zealous glen
#

probably the second one

knotty wren
#

lemme try it !

#

hmm nop

willow quiver
#

definitely missing smth here

zealous glen
#

have you added an English localization file already?

wild patrol
#

Hopefully nobody done this idea yet has anyone made a joker card that is a monkey that synergizes with the banana cards

willow quiver
#

might just wait for the guy to come online and see if he is able to see any translations

wild patrol
#

So is there any way to increase the limit of how many times a joker card can appear in ur pack?

#

Instead of just once

#

Some cards I'd like there to be more than just 1 of

lilac whale
#

hello chat room ! fully new to modding/lua stuff, please assume i don't know things unless stated otherwise. started looking into implementing the custom jokers i've concepted/sprited, and i've got some extremely basic stuff down (getting it to display the proper text and sprite, formatting the text correctly etc) but now i want to learn how to properly write abilities. i've bashed my head into a wall trying to find the proper things to reference, let alone properly write something functional for them, and atp i've conceded that if this little project is going to go anywhere i need Help help lmao.

so! the joker i've started with gains xmult every time a playing card or joker is destroyed, and every time a debuffed card gets "scored". what would be the first steps to getting that in place?

wild patrol
#

¯_(ツ)_/¯

#

Can't learn if u never try

#

Lua is pretty simple to work with just need to get a general understanding of how it works with the game

#

Start with a basic card mod work ur way up

#

What I've been doing started with a basic card mod when I had more than 3 I tried making a booster now making custom cards

#

Everyone here is more happy to help if ur running into issues my dumbass was using the wrong prefix for a card and a single character typo was crashing my game

lilac whale
#

that's

#

what i was asking about LMAO

#

i've already tried, but i've only gotten so far by myself

wild patrol
#

Pretty sure @frosty dock might be able to help u with ur question tho

#

I'm still learning myself but sounds like something to ask them

#

Everyone been helping me might just be offline atm

runic pecan
lilac whale
#

i see i see, i'm def willing to ax the destroyed joker clause. glad to know i was on the right track

viscid field
#

you can search for the joker names in the code to see how and where their abilities are implemented and patch those spots

#

e.g. if you want to make "destroy joker to the right" effect check dagger

#

search for the english name e.g. Ritual Dagger

lilac whale
#

i've tried that, to very poor results. a lot of it is utterly incomprehensible to me even if i do manage to find the joker i'm looking for

#

like, i need to stress that i am Brand Damn New to lua stuff and coding generally lol

lilac whale
viscid field
#

lua is a confusing language, even more so than JS

lilac whale
#

i'm tryin my best o7 i'm not letting this intimidate me even if i can't really find results myself a lot of the time

viscid field
viscid field
#

so! the joker i've started with gains xmult every time a playing card or joker is destroyed, and every time a debuffed card gets "scored". what would be the first steps to getting that in place?

#

ah, I see

wild patrol
#

Don't expect it to be an overnight success give it time and it'll come together

#

And it's no where near as cool some shit seen ppl make

topaz sun
topaz sun
#

Rn it's 3am and imma get some sleep

viscid field
# lilac whale let's start with this one

I will try to explain the thought process as well:

First of all, we need to make the effect to make it gain xmult

-- Two dashes marks a comment.
-- This means anything in the same line after the
-- two dashes are not run as code.

-- This makes a piece of code reusable.
-- Whenever you call the function by writing
-- "my_joker_gains_mult()", the code within
-- gets run again.
function my_joker_gains_mult()
    -- We need to check every joker,
    -- if it is my joker, update it.
    for i,joker in ipairs(G.jokers.cards) do
        -- Repeat for every joker:
        -- "i" is the ordinal of the joker
        -- (1 for 1st, 2 for 2nd, etc.)
        -- "joker" is the actual joker itself.
        if joker.ability.name == "My Joker's Name" then
            -- "extra" is extra information about your joker.
            -- You can use this to store the Xmult increase of
            -- the joker, making it easier to change later.
            joker.ability.x_mult = joker.ability.x_mult + joker.ability.extra
            -- Alternatively, you can "hard-code" it: (using 0.2 as an example)
            -- joker.ability.x_mult = joker.ability.x_mult + 0.2
        end
    end
end

Debuffed card:

  • eval_card is apparently used to calculate a card score
  • G.FUNCS.evaluate_play(state_events.lua#571) uses it and seems to calculate a hand
    scrolling through it... Oh!
  • state_events.lua#655 runs for every debuffed card.
  • Insert my_joker_gains_mult() right there. (after the if)
willow quiver
topaz sun
#

Will do 🫡

lilac whale
wild patrol
#

smod wiki helps to

#

Usually read that ask questions about it here

narrow pendant
#

I think i've got this remove_from_deck function wrong

runic pecan
#

What is the SMODS' version of
context.consumeable.ability.name == 'The World'?

plain apex
#

is there a way for a mod to check if you have a different mod installed and if you dont disable content that only works with that mod rather than listing that mod as a dependency?

wild patrol
#

Dumb idea but has anyone tried making a joker card that runs balatro within a joker card lol

plain apex
narrow pendant
#

Alright i dont understand the remove_from_deck thing, i've got this function set up wrong

sturdy compass
#

yes your remove from deck is not set up right. you should defining it as so:
remove_from_deck = function(self, card, from_debuff)
You should also end off calculate before that definition

narrow pendant
#

i knew it was something like that

#

i was looking at the other functions and thinking about it

wild patrol
#

Question you think the anime style card look is better or the official TCG look would work better in a Yu-Gi-Oh mod

#

Thinking of swapping to the anime style

#

But not sure

narrow pendant
runic pecan
#

Is next() a lua built-in or a Balatro global?

sturdy compass
narrow pendant
#

Chaos the clown only gives you 1 free temp reroll

#

after the free roll it goes back up

sturdy compass
#

Yes, and that functionality can be adapted to your card

narrow pendant
#

I'm not giving free rolls tho, it's closer to the d6 tag

sturdy compass
#

Rerolls starting at $0 sounds like a free reroll

narrow pendant
#

It's technically 1 free reroll, but then the cost climbs from 0, rather than going back up to 5

#

so 0, 1, 2, 3, 4 etc

viscid field
#

I just spent 2 hours debugging, and still couldn't figure out why somehow my patched function apparently returned an infinitely deep UI definition (there are probably circular references)

#

I even wrote a function to diff two tables

sturdy compass
narrow pendant
#

rolls = 5, i'm just minusing from the cost

viscid field
#

error(tdiff(nret.nodes[1].nodes[1].nodes[1].nodes[1].nodes[1],c.ret[1].nodes[1].nodes[1].nodes[1].nodes[1].nodes[1],"",7))

sturdy compass
narrow pendant
#

after 3 rounds it removes itself

sturdy compass
#

But when? As in what context?

narrow pendant
#

oh, ending shop

sturdy compass
#

That might be why. I think reroll costs reset when the shop ends, and when you add that extra +5 from your card on top of it, you're getting the 10

#

I'm not 100% on that but it's a decent hunch

narrow pendant
#

Nah that looks to happen everytime i roll

#

i think also after the shop ends, but also when i roll

sturdy compass
#

Well yeah of course it'd change when you roll, but that sounds like it's working fine. It's after it's being removed that's the problem, yes?

narrow pendant
#

Without the remove_from_deck function, the rerolls work as intended, but the cost doesn't reset to normal after the card is gone

#

may have solved it

#

hmm, nevermind

runic pecan
#

When hand_type is lv.1, would G.GAME.hands[hand_type].level be 0 or 1?

sturdy compass
narrow pendant
#

i dont think the adding 5 works, because it just overwrites any vouchers and sets the cost to 5 forever lol

#

Thanks for the help anyway

#

have a good sleep

sturdy compass
viscid field
#

OH MY

#

There was a stub that returned nil for an unimplemented functionality since I assumed it never existed

#

that apparently caused all sub function calls used as table values to be deleted

#

for example

function original_function()
    return {get_one(),get_two()}
end
function patched_function()
    return {nil,nil}
end
runic pecan
#

This feels kinda cursed even though it works without causing any issue so far.

cedar bronze
#

if it works it works yippee

viscid field
#

Is it just me or does print not write to the console

#

love's console is always empty except for the steam API debug info

sturdy compass
sturdy compass
wild patrol
#

If it works it works

#

I should probably learn to organize my code now

#

Instead all of it in same main.lua file

viscid field
sturdy compass
#

The first

cedar bronze
#

why would u organise code when u can have it all in one place :]

wild patrol
#

True

sturdy compass
wild patrol
#

But I'm planning on expanding it into more than just Yu-Gi-Oh cards now

#

So probably be better to have everything organized

viscid field
#

and I just found io.open

cedar bronze
#

also ive searched in this chat for a bunch of answers but none of them have worked for me.
trying to scale a joker like square joker / photograph / etc, and the only progress ive made is un shrinking the sprite??? if anyone knows how to do this oTL

wild patrol
#

Gonna try making a similar mod to cardsauce

#

But one for joel

sturdy compass
cedar bronze
#

🤝

#

ive tried like 3 peoples old 'fixes' and nothing changes (and it also doesnt even crash) lmaoo

sturdy compass
#

Instead of making mine more square tho mine needs to be more skinny

cedar bronze
#

atlas is 71w 62h, and in the smods joker ive set the display and pixel size to those numbers

#

originally tried having it w the other jokers and leaving it at the top left but made no progress so its a seperate sprite now

runic pecan
cedar bronze
#

still appears stretched to normal size

#

def have the transparent margins

runic pecan
#

What is the size of sprite itself

cedar bronze
#

with the margins, 71 wide and 62 tall

runic pecan
#

and without?

cedar bronze
#

i imagine 69x60

#

file itself in the x1 assets

runic pecan
cedar bronze
#

where would i set the margins :0

runic pecan
#

just make the transparent margins those size

#

if square joker can keep being square, so should yours be able to.

cedar bronze
#

this works but its not centred, and the hitbox is normal size

violet void
#

the art is cool

cedar bronze
#

made by a friend of mine, im putting our dnd characters in the game as jokers :]

runic pecan
cedar bronze
#

ya i can grab it

runic pecan
#

Yet the square one and the torn one don't have such feature... 🤔

#

Kinda beats me.

cedar bronze
#

i know theres a bunch of hard coding for those in the card.lua file in base game but unsure how i'd replicate it

#

i'll live w it as is for now

runic pecan
#

Centre issue should be solvable by adjusting the sizes of up-down margins, such as make them 17-18 instead of 1-34.

viscid field
#

check code for half joker

#

maybe that will be of use

cedar bronze
runic pecan
#

I assume you've also tried giving your joker T={h=62,w=71}?

cedar bronze
#

just tried it, didnt change anything oTL

wild patrol
#

So I'm going to change the sprites of the Yu-Gi-Oh cards to anime theme so I can take more creativity with changing card text

#

What do u think

runic pecan
cedar bronze
runic pecan
#

OK...

cedar bronze
wild patrol
#

Of course

#

well 3 because technically it counts as a discard so the game draws 3 lmao

crisp coral
# cedar bronze like

You will need to do math to get the multiplier, but use set_sprites for that

set_sprites = function(self, card, _front)
    card.T.h = ... -- height
    card.T.w = ... -- width
end
wild patrol
#

Probably gonna add card destruction to

violet void
#

Im not good at assigning rarities

wild patrol
#

I mean at this point I think just making cards op is fine

#

Unless u actually want to make a balance mod that works with vanilla game

violet void
#

I dont want it to be op no

wild patrol
#

Everyone just likes breaking the score at this point lol

wild patrol
#

Then just start assigning rarity then

#

What I'm doing

#

All them have 100% chance spawn rates just for testing

violet void
#

cant you spawn them with debugplus

cedar bronze
violet void
wild patrol
#

For some reason

wintry solar
#

How so?

rough furnace
#

Yeah how so?

wild patrol
#

Doesn't let me buy them

rough furnace
#

That shouldn't be the case

#

Sure you have enough money?

wild patrol
#

It is for me so I dunno

#

Won't let me select them

rough furnace
#

works here

wild patrol
#

Maybe issue with custom booster packs then

#

Because doesn't work for me

rough furnace
#

possibly

#

I don't have any custom boosters installed rn

#

I'll have to investiagte

wild patrol
#

When I get off work I can send u a video

#

When I spawn my custom pack into the slot won't let me select it

rough furnace
#

you can run the resetshop command to at the very least rereoll the boosters

wild patrol
#

And if I leave the game come back sometimes it's there to buy and works sometimes it's not

#

I just have the booster set ton100% spawn rate lol

#

So no big deal for me rn

wintry solar
#

It works for custom packs

viscid field
#

debugging LuaJIT bytecode with imhex

rough furnace
#

Why?

viscid field
# rough furnace Why?

I'm making a mod to patch function bytecodes instead of replacing the function entirely if you want to patch in the middle

rough furnace
#

Ah

viscid field
#

but after reassembling everything broke

#

function calls were randomly replaced with nil

rough furnace
#

Interesting

#

I'll have to see how the bytecode works sometime

viscid field
#

I'm not even incorrectly parsing the instructions, I'm just failing to parse the constants(with local table = {1,2,3,foo()}, table's value is cached separately rather than built at runtime(except for the foo call))

wild patrol
viscid field
#

Oh my god

#

I kept looking at my code making 64-bit ints and my brain kept thinking "lua's doubles have only 52 bits of mantissa, they can't store 64 bits" but I thought "that's such a rookie mistake I could not have possibly made that when I first wrote code"

#

When I first wrote the code I was probably looking at the type annotations being foo: integer and thinking "Oh, Lua must has int support like Python"

#
import type.leb128;
using uleb = type::uLEB128;

struct ktabk{
    uleb tag;
    if(tag == 3){
        uleb i32;
    }else if(tag == 4){
        uleb lo32;
        uleb hi32;
    }else if(tag >= 5){
        char string[tag-5];
    }
};
struct khash{
    ktabk key;
    ktabk value;
};
struct ktab{
    uleb arr_sz;
    uleb tab_sz;
    ktabk arr[arr_sz];
    khash tab[tab_sz];
};
struct kgc{
    uleb tag;
    if(tag == 1){
        ktab table;
    }else if(tag == 2 || tag == 3){
        uleb lo32;
        uleb hi32;
    }else if(tag == 4){//complex type, but lua has no built-in complex type
        char ERROR[-1];
    }else if(tag >= 5){
        char string[tag-5];
    }
};

If anyone wants to debug the bytecode with ImHex, here are the patterns for kgc

#

YES

#

FINALLY

#

I managed to replace the final create_UIBox_generic_options call with a call to whatever function I want in create_UIBox_options

#

WITHOUT replacing the whole function

#

Here's the patch code:

function aml.globals.__inject_mod_button(args)
    local contents = args.contents
    contents[#contents+1] = ui.button("Mods",ufa.register_ui_callback(show_mod_list),ui.config():min_width(5))
    return aml.globals.create_UIBox_generic_options(args)
end
aml.patch(aml.globals,"create_UIBox_options",aml.reassemble,function(d)
    local func = bp.parse_chunk(d.chunk)
    func.protos[2].constants[3].value = "__inject_mod_button"
    d.chunk = bp.write_chunk(func)
end)
#

func.protos[2].constants[3].value is the "magic location" storing the name of create_UIBox_generic_options. I could probably replace it with a table search for better future-proofing

wild patrol
#

Is this already included in smod?

#

For the mod option

viscid field
wild patrol
#

Ah

viscid field
#

smod uses source injection

#

which changes the lua code

#

I just directly patch out the bytecode

#

which will stay working even when line numbers move around

viscid field
viscid field
misty cape
#

Could I add in something to my mod to make it so the game disables and re-enables the High Contrast Cards option in the menu upon launch? The color changes I've added to tooltips don't appear unless I manually disable and re-enable the option when i open the game every time. not the most important thing since i finally got the config working, but a slight annoyance

frosty dock
frosty dock
#

😲

misty stratus
#

Hey i have a question. Can anyone give me a little rundown of how mods for balatro are made? I have a little knowlegde of Lua and i really want to get into making mods for the game.

frosty dock
crisp coral
#

i don't remember my longest nodes chain, prolly this
t.nodes[1].nodes[1].nodes[1].nodes[1].nodes[3].nodes[2].nodes[1].config = { object = G.shop_booster }

frosty dock
viscid field
royal ridge
#

may be a stupid question but is it possible to :draw() something, adding transparency

viscid field
#

But really, I think the great potential with bytecode patching is you can patch functions you don't know about

misty stratus
wild patrol
#

Honestly I think smod probably better for beginners than byte coding

viscid field