#💻・modding-dev

1 messages · Page 153 of 1

native pebble
#

Thanks

hardy viper
#

it does python interface stuff

native pebble
#

I'll look into it

weary jungle
#

how do i do.. 2 dialog????

hardy viper
#

you'll probably have to modify it to be able to have it fetch the data you want

#

considering it was initially made for tasing and whatnot

tepid crow
weary jungle
#

dialog then dialog

#

2 dialog

tepid crow
#

so 2 different messages?

weary jungle
tepid crow
#

yeah no clue sorry

#

I've only ever done a single message

tight thistle
weary jungle
#

2 dialogs is too powerful

tepid crow
#

doesn't the tutorial do that? maybe check the code for that

weary jungle
#

what if i un dialog the dialog then dialog

faint yacht
#

...oh yeah, I was meant to ask about the other "effects" for text besides C:, s: and such.

tepid crow
#

that should probably be on the wiki somewhere tbh

wild patrol
#
    key = "Jinzo",
    loc_txt = {
    name = 'Jinzo',
    text = {
        'Binds, and their effects',
        'during the round, cannot be activated.',
        'Negate all binds on the board.'      
        },
    },
        config = { xchips = 2.5 },
    rarity = 1,
    pos = { x = 6, y = 0 },
    atlas = "TCGyugioh",
    cost = 5,
    unlocked = true,
    discovered = true,
    pools = { TCG_Yugioh = true },
    blueprint_compat = true,
    calculate = function(self, card, from_debuff)
        if G.GAME.blind and ((not G.GAME.blind.disabled) and (G.GAME.blind:get_type() == 'Boss')) then 
            G.GAME.blind:disable()
        end
    end,
})
#

so I should use calculate for the disable blind function?

#

I tried adding this card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('ph_boss_disabled')})

#

because i wanted the message boss blind disabled to appear

#

but it's considered a nil value when I addd it

tepid crow
#

you should be able to just do return { message = ... } instead of all of that

#

(if you're unlucky you might need a card = card too but my assumption is you don't)

wild patrol
tepid crow
#

🤨

#

do you have the full error instead of a single line?

wild patrol
#

that's the error

snow valve
#

trying to make lucky cards guaranteed

#

obviously doing something wrong, I think variable access?

#

not really sure why it's upset tbh

tepid crow
#

calculate doesn't magically know what context you're looking for

wild patrol
tight thistle
wild patrol
tepid crow
tepid crow
tepid crow
wild patrol
#

return after the messages?

tepid crow
tepid crow
# snow valve

Theoretically, yes. Though that context filter still seems a bit broad on first glance and might still crash with the same error

snow valve
#

did crash with the same error

#

i want it to check when a card is played

#

and see if the card is lucky

#

then guarantee probabilities (set to 1)

tepid crow
#

pretty sure that exact context is documented in the link from earlier

snow valve
#

but isnt that what im using?

#

G.play?

tepid crow
#

like I said, too broad

snow valve
#

oh okay

#

so how am I supposed to write it?

#

legitimately brand new sorry lol, me and a buddy "learned" lua last night by brute forcing custom jokers until 8am last night lol

wild patrol
#
            return ({message = localize('jinzo_boss_disabled')})
            G.GAME.blind:disable()```
#

like this because it returns an error that need } to close

tepid crow
#

this joker might be a bit too advanced tbh

snow valve
#

really? 😭

tepid crow
#

yeah, because instead of applying a new effect

snow valve
#

i assumed the precedent already existed and I'm just doing it wrong no?

tepid crow
#

you're modifying an already existing effect

#

(lucky cards)

snow valve
#

well kind of

#

i took code precedent from Oops all 6's

#

to modify probability

#

but the effect should apply the same way right?

tepid crow
#

I wouldn't

#

since G.GAME.probabilities is used for anything chance-based

snow valve
#

and jokers like golden ticket check if a card is gold

tepid crow
#

so then you need to be real careful when you set-unset it

snow valve
#

ngl I know it's a bad idea to use the global variable and I was just too lazy to find specifically the lucky modifier in the code

tepid crow
#

instead I'd take a look at how the lucky card is implemented and throw a check for your joker in there

#

lot less messy

snow valve
#

basically all i want my code to do is:
Step 1 (golden ticket precedent): check if card is lucky
Step 2 (oops all 6's precedent): manipulate probability

snow valve
#

If I want the mod to be a separate file don't I have to do it locally?

tepid crow
#

do you know what return does?

tepid crow
snow valve
#

hmm

#

so what's preventing me from just doing this?

#

but with lucky

tepid crow
#

you're not adding +$4 (which can be done at basically any point, at any time) when gold cards are scored, you'd be modifying how lucky cards work internally

#

a really easy way would be to just give the lucky card bonus and let the lucky card roll anyway

wild patrol
#

I fixed it

#

but now the message is too fast lol

snow valve
#

is that the best way?

tepid crow
tepid crow
snow valve
#

well the probability in this game is a little hard to mess with

#

because everything is expressed as 1 / (value)

#

and then each odd in the game has (value)

tepid crow
#

yea

snow valve
#

so wheel is expressed as 1 / (value) and (value) is 4

tepid crow
#

.extra yes

snow valve
#

so while the joker is active we set value to like 2 billion

#

then when sold reset it

#

but i cant find the extra value for luckies lol

#

m_lucky = {max = 500, order = 9, name = "Lucky Card", set = "Enhanced", pos = {x=4,y=1}, effect = "Lucky Card", label = "Lucky Card", config = {mult=20, p_dollars = 20}},

#

they say this

tepid crow
#

yeah theoretically would work for luckies too (though it seems like a tad hacky approach)

tepid crow
#

luckies don't have that (value) stored internally though

snow valve
#

yeah thats what im finding

#

how would I go about doing that for luckies?

wild patrol
#
        if G.GAME.blind and ((not G.GAME.blind.disabled) and (G.GAME.blind:get_type() == 'Boss')) then 
            return ({message = localize('jinzo_boss_disabled')})
            end
            G.GAME.blind:disable()
    end,```

so this works but the disable blind doesn't work

but this crashes the game?
```calculate = function(self, card, from_debuff)
        if G.GAME.blind and ((not G.GAME.blind.disabled) and (G.GAME.blind:get_type() == 'Boss')) then 
            return ({message = localize('jinzo_boss_disabled')})
            G.GAME.blind:disable()
        end
    end,```
tepid crow
tepid crow
snow valve
#

for wheel I set the value to 2 billion because it's close to a 0% chance of triggering, and I needed to natively apply the effects of wheel rather than letting the wheel apply them itself at 100% chance to hit, because wheel effects don't stack and the point of the joker is that it can stack the editions. For this joker, the lucky triggers can stack as much as they want, so I figured it would be a lot easier to just set the probability to 1 so it always triggers natively instead of doing +20 mult and +20 dollars myself

#

this is how I handled the wheel

tepid crow
#

oh it stores it on the shiny joker? interesting

snow valve
#

yeah

#

I found where luckies are handled

#

and there is no varibale to modify I think

#

just math built in to the function

#

so I'm not sure how I do it lol

tepid crow
#

like I said, hook or lovely patch the function

snow valve
#

idk how to do those so I'm trying to see if there's som eroundabout way I can do it natively

#

but I'll learn if necessary lol

wild patrol
#

wrong video

#

the correct one

gaunt thistle
#

ew discord lets you do that with links? cursed

#

lovely patching is maybe the most "native" way to do it?

tepid crow
#

🪄

snow valve
tepid crow
# wild patrol

you can use delay = <number> to hold the message for longer - I suggest trying a delay of around ~1.5?

tepid crow
wild patrol
#

return ({delay = 1.5, message = localize('jinzo_boss_disabled')})

#

gonna assuming delay goes in with the message

tepid crow
#

yup

snow valve
#

Do i need any imports or anything for lovely patching or if I have lovely I can just do that code in my mod file?

wild patrol
# tepid crow yup

now the message doesn't appear and the disable blinds doesn't work?

#

but the game doesn't crash

tepid crow
snow valve
#

I'm so cooked

tepid crow
#

like I said, not really starter friendly

tepid crow
gaunt thistle
#

I mainly just show up when you're talking though

wild patrol
snow valve
#

okay, so the easiest way I can interpret this is that I need two very simple injections, one that finds the lucky calculation in the mult function and replaces "probability/5" with "probability/1", and another that finds the lucky calculation in the money function and replaces "probability/15" with "probability/1"

#

and then it should work?

tepid crow
#

well I wouldn't replace it with probability/1 since then it'll always happen (even if you don't have the joker)

snow valve
#

can't I just trigger those injections on "add_to_deck"

#

and revert them on "remove_from_deck"

#

then it's just a static guarantee while I have the joker

wild patrol
#

now the blind disable works but text doesn't appear?

tepid crow
#

no, those lovely injections either exist or don't

wild patrol
#

but i haven't change the code yet

snow valve
#

so then maybe I just make the luckies always fail and add the 20 mult and dollars myself?

#

hmm

#

but then theyre messed even when i dont have the joker

tepid crow
snow valve
#

I have a theory

wild patrol
#

sometimers the code works sometimes it doesn't

snow valve
#

I do the above injections but instead of having them replace 5 and 15 with 1, I just implement my own random function, and my function checks whether or not you have this joker, and if you do it guarantees probability, and if you don't it uses 5 and 15 like normal

#

that's probably the best way to do it?

sharp blade
#

just used this to make a wee joker-sized joker and it fixed all my problems

#

it's a jank as hell solution but it's also really funny

tepid crow
#

lmao

#

finally a use-case for name

sharp blade
#

whoops sorry for ping

snow valve
#

okay so im editing a toml file

sharp blade
snow valve
#

target is the file i need to change

#

pattern is the words i want to replace

#

position is where i want to inject

#

payload is the replacement text

#

that's all right?

sharp blade
#

here's a good example from smods itself:

#

[[patches]] [patches.pattern] target = "card.lua" pattern = ''' if center.name == "Wee Joker" and (center.discovered or self.bypass_discovery_center) then H = H*0.7 W = W*0.7 self.T.h = H self.T.w = W end ''' position = "after" payload = ''' if center.display_size and center.display_size.h and (center.discovered or self.bypass_discovery_center) then H = H*(center.display_size.h/95) self.T.h = H elseif center.pixel_size and center.pixel_size.h and (center.discovered or self.bypass_discovery_center) then H = H*(center.pixel_size.h/95) self.T.h = H end if center.display_size and center.display_size.w and (center.discovered or self.bypass_discovery_center) then W = W*(center.display_size.w/71) self.T.w = W elseif center.pixel_size and center.pixel_size.w and (center.discovered or self.bypass_discovery_center) then W = W*(center.pixel_size.w/71) self.T.w = W end ''' match_indent = true

snow valve
#

and since I'm looking to patch the circled section, target is just "card.lua"?

snow valve
#

just gonna edit it and use it as boilerplate

normal crest
#

Yes target is card.lua

sharp blade
#

nice

snow valve
#

okay cool

#

this is maybe not that hard then?

normal crest
#

It really isn't, it's just specifying where you want your code to be

snow valve
#

i assume this refers to something specific in the repo

#

and has nothing to dowith my code?

normal crest
#

Yeah don't touch that

#

And I think it's not recommended to use position = "at"

snow valve
normal crest
#

You need that

snow valve
tepid crow
snow valve
#

doesn't that just replace it at the position you evacuated?

snow valve
normal crest
#

Its just how toml files are structured

#

that's just saying you're adding a patch

tepid crow
#

those [[]] tell lovely what type of patch it is

snow valve
#

okay cool

#

and dump lua and priority

#

priority i assume doesnt matter for me if this is my only injection

#

so i can just make that 0?

tepid crow
#

I suggest setting it to 0

snow valve
#

okay

#

and dump lua i dont have any idea what that is

normal crest
#

dump lua will put your code in the lovely dump under mods/lovely/dump

#

So you can see the result of your patches

snow valve
#

oh sure

normal crest
#

Priority does matter, your mod isn't the only one doing patches

#

Leaving it at 0 is fine tho

snow valve
#

okay

normal crest
#

If you're not worried about that then go ahead

snow valve
#

i am using vanilla balatro with smods and my custom jokers exclusively

#

is it fine for that?

normal crest
#

If your mod is meant to be used without any others then you don't have to worry

#

also to look at the game's source I recommend looking at the lovely/dump instead of the extracted exe

#

Since the dump includes the patches steamodded does

sturdy compass
#

Is it possible to take ownership of PokerHands?

snow valve
#

do you see any problems with this or should this work?

#

emme_check will get +1 upon buyingthe joker

#

and -1 when it leaves

wild patrol
#

seemsgood everything looks good so far

#

I think it's just debug menu being debug menu

mild night
#

would anyone be willing to work on a little pet project of mine with me? I have a few ideas I'd like to implement into a QoL/Ideas mod but I'm unfamiliar with modding

tepid crow
normal crest
#

It does not

tepid crow
#

that's what I thought lmao

snow valve
#

i am brand spankin new to lua

#

all I know is it has local

#

so I just assumed

gaunt thistle
#

that's a good start

snow valve
#

do I just leave out local then?

tepid crow
#

yeah

snow valve
#

defining the variable defaults to global?

tepid crow
#

but you can use SMODS.find_card to find your joker instead of a global

#

yeah

normal crest
#

Yeah the default is global

snow valve
#

oh cool

#

so exact same image but delete "global "

#

works?

normal crest
tepid crow
#

I should start saying "run the code and find out" more often

normal crest
#

Its just true

snow valve
normal crest
#

Also when comparing use ==, not =

#

And you might want to use multiline strings in your toml instead, aka """ instead of "

snow valve
#

should I just put the toml in its own folder in the same folder as my mod?

#

here

tepid crow
#

top level of your mod

normal crest
#

either a lovely.toml file in your mod folder, or under your mod/lovely/whatever.toml

snow valve
sturdy compass
snow valve
#

still not exactly sure

#

sometimes my brain just needs to see a thing and be like, "you mean right here? okay cool."

normal crest
#

Lovely will load all toml files under mod/lovely

sturdy compass
#

I haven't because I'm lost on what the syntax is, though now I think my brain is starting to work it out

normal crest
#

Or a single toml file at mod/lovely.toml, mod here being your mod name

tepid crow
snow valve
#

okay so

#

here? or inside the "lovely" folder

normal crest
#

Mods/your mod/lovely/blahblahblah.toml

tepid crow
#

top level of your mod

normal crest
#

Or Mods/your mod/lovely.toml

tepid crow
#

Balatro/Mods/Akrones-mod/lovely.toml or Balatro/Mods/Akrones-mod/lovely/<whatever>.toml

snow valve
#

oh I just have lovely in my game files but I also need to put it in my mod specifically you mean?

normal crest
#

Not both, only one

snow valve
#

and does it need to be named anything specific? it's currently nmed lovely.toml

normal crest
sturdy compass
#

So I'm trying to change how Four of a Kind works, is this all the evaluate function that I would be taking over be?

snow valve
#

im in my mod folder

#

those are just all my different jokers and crap

#

right here then?

normal crest
#

That's not your mod folder

normal crest
snow valve
#

oh you mean like

#

yeah okay I see

#

thank you

#

my specific mod

#

thoguht you meant my folder for mods

normal crest
#

Yeah each folder in Balatro/Mods is a different mod

snow valve
#

yeah gotcha

tepid crow
sturdy compass
#

Yes, here's the functionality I'm after

tepid crow
#

neat

#

uhh

#

probably do whatever the straights do for shortcut/four fingers?

sturdy compass
#

Yeah kinda

#

I know how I want to do it, I just wanna make sure I'm changing the right things

normal crest
#

you will definitely have to patch/hook into whatever function decides what hand is played

#

maybe get_poker_hand_info, I think it's called

#

But I'm not sure

snow valve
#

okay well the game is no longer crashing when I play a card however it didn't give me any mult

#

my suspicion is that it's not crashing because I deleted my old function that was a problem, and the injection just didn't work

normal crest
#

To see if your injection worked look at the dump

tepid crow
normal crest
#

Mods/lovely/dump/card.lua

snow valve
#

im in my dump and i dont see anything that I made

#

i think

normal crest
#

Then your pattern is wrong

snow valve
#

wait is it card

#

hold on

normal crest
#

go to the file you modified

#

you said target card.lua right, then look at that file

snow valve
#

okay yeah it did not modify

normal crest
#

Then your pattern is not correct

snow valve
#

this is the game code

#

this is my pattern

#

I just copy pasted

normal crest
#

Use multi line strings

#

Aka

snow valve
#

oh right yes

#

""""

#

right?

normal crest
#

pattern = """
function.....
"""

snow valve
#

okay

sturdy compass
#

Sweeeeeeet

normal crest
tepid crow
#

niiice

tepid crow
#

cool idea for a joker

snow valve
#

sadge

#

oh wait

#

i should probably use multiline for the payload too huh

#

my dumb ass

#

dang still didnt work

normal crest
#

Could you send your entire toml file

snow valve
#

yep

#

okay wait I think I fixed the insertion

#

now I need to fix the code I'm inserting

normal crest
#

nice, good luck

#

also what you're trying to do does not need a lovely patch

#

could be done with a hook

#

Let me write an example

snow valve
#

idk how to do that either lolol

#

this is te current problem

#

i think im an idiot and im missing really obvious syntax

sturdy compass
snow valve
#

full code for reference

normal crest
#

remove the "end" above "else"

#

also this is what I meant by a hook

#
local get_chip_mult_ref = Card.get_chip_mult
function Card.get_chip_mult(self)
  if Emme_check == 0 then
    return get_chip_mult_ref(self)
  elseif Emme_check == 1 then
    -- your code
  else
    -- your code
  end
end
snow valve
#

oh i was redundant with the return

snow valve
normal crest
#

this is modifying the original function

#

first it stores a reference to the old function, to not lose it

#

then you redefine it, adding whatever code you need, and at some point you call the reference you saved to ensure that the original code remains there

#

and you can add that hook anywhere in your code, wherever you need it

snow valve
#

oh neat

#

so what you're saying is that is way easier

#

lmao

normal crest
#

yeah, doesn't hurt to learn how lovely patches work tho

#

you just gotta know in what scenario to use a hook or a lovely patch

#

in this case your patch is just wrapping around the original code, not adding anything between the original, so you can just use a hook

snow valve
#

what was the function you said I could use instead of emmecheck?

#

i think my current problem is that emmecheck is redefining itself as 0 before it runs the mult function'

#

just a function to see if i own a joker

snow valve
#

so in this case it's "
if SMODS.find_card(Emme) == True then...."

#

or how do I implement that

tepid crow
snow valve
#

and do I include the single quotes with the key?

dusk shoal
#

I had a mod idea, not really coding anything yet but I really like it, yet it hinges on one little thing:

#

Is there a way to check, for a joker, what deck you’re using?

snow valve
#

i.e. my key is 'emme_joker'

SMODS.find_card('emme_joker')

snow valve
#

why does this happen

tepid crow
tepid crow
# snow valve

pretty sure that's balatro saying "you ran out of memory"

snow valve
#

like this?

#

prefix is FRND

#

key is Emme_Joker

tepid crow
#

yeah, but the check == false doesn't seem right

snow valve
#

oh i assumed it returned a bool

tepid crow
#

The docs! The magical docs!

snow valve
#

so I just have to say if one of the array values matches?

#

see*

tepid crow
#

I think you just have to check if the table is empty or not

snow valve
#

oh cool

#

ngl I do not know how to write that

#

would you mind showing me how to check that?

tepid crow
#

if it's a numbered array you can do #array to check it's length

#

(with numbered array I mean {[1] = "a", [2] = "text", etc})

snow valve
#

if #array.SMODS.find_card('j_FRND_Emme_Joker') <= 1 then

#

like this?

#

=*

tepid crow
#

array was an example name

snow valve
#

ohhhh

#

right I learned this syntax earlier for cards in hand

#

if #SMODS.find_card('j_FRND_Emme_Joker') >= 1 then

#

like that?

tepid crow
snow valve
#

I pray man damn

dusk shoal
tepid crow
dusk shoal
#

i'll need you to elaborate if you dont mind

is it like, "if G.GAME.selected_back == red_deck then;" ?

#

i dunno the exact in game terms for each deck

tepid crow
#

just print it out and you should be able to see what you want to check

#

(I don't actually know from the top of my head)

dusk shoal
#

im still a little confused

#

like are you saying to

#

ahem

#

create a joker and make it so the joker prints whatever G.GAME.selected_back is?

#

and then that tells me

tepid crow
#

sendDebugMessage(tprint(G.GAME.selected_back), "skybox")

snow valve
#

this is my payload as it stands

#

I am getting the memory error again

tepid crow
snow valve
#

presumably that means I messed something up here

tepid crow
# snow valve

pretty sure this lovely patch isn't the thing giving you a memory error 🤔

dusk shoal
#

also is skybox supposed to be whatever the mod's key is? or literally just whatever lol

snow valve
#

this is the whole file

#

I think it's like

#

correct now

tepid crow
dusk shoal
#

you might need to explain it to me like im 5 lol

tepid crow
dusk shoal
#

you misunderstand my misunderstanding, i mean explain EVERYTHING like im 5 😭

#

im admittedly not the best coder

tepid crow
dusk shoal
#

yes please

snow valve
#

this is all of the code in my mod

#

very small joker code in main.lua

#

and then the lovely patch

#

really not sure why it's having a memory error lol

tepid crow
# dusk shoal yes please
  • G.GAME.selected_back is a Lua table (almost everything in lua is either a table, a string or a number)
  • tprint() turns a table into a string, so instead of printing table: 0x55e44c737da0 (how could this possibly be the default Lua wtf went wrong in development), you get a nice { key = value, etc }
  • sendDebugMessage allows you to send a string to the console
dusk shoal
#

OKAY I SEE NOW

#

THANK YOU !!!

tepid crow
#

did you try restarting your computer yet?

snow valve
#

next step i gues

#

s

wild patrol
#

Dumb question can we use the pop up box that lovely uses

#

When u click the game during the crash log

#

I got a funny idea

tepid crow
#

@gaunt thistle would be the one to ask about that 🙃

gaunt thistle
#

it's a native window so it'll look identical

wild patrol
#

was gonna add this card

#

and whe u lost a boss blind

#

the pop up box would come up say youn lost ur soul crash the game

snow valve
#

its working

#

i fell to my knees

tight thistle
#

anyone know where the source code for the event manager is? i want to know why the hell its working so badly with eachother

snow valve
#

if I want to do two patches do they need to share a folder or both be loose in the mods folder

#

alternatively I could also do two patches in one file right?

iron iron
#

damn im gonna have to learn how to mod balatro

gaunt thistle
#

you absolutely should

gaunt thistle
iron iron
gaunt thistle
iron iron
#

wait i dont have balatro on steam can i even do this 😭

nova finch
#

How would I make a joker trigger when only when a certain card of the played hand is scored (e.g. first scored card, second scored card, etc.)

random sleet
#

game boylatro

iron iron
nova otter
#

Hello, I want to get started making mods for Balatro. Where would be a good place to start? Are there any guides I could follow?

tight thistle
tiny shale
#

heyo everybody, I am starting to mod and I wonder, what is the resolution of the joker card?

tiny shale
#

thankies!

slender island
#

How do i create a texture pack through steammodded? I have textures but i don't understand what i should put in lua file

violet void
#

Do Vouchers really have a calculate function?

#

Im thinking of turning a Joker I have into a voucher and if thats the case it'll be quite easy

crisp coral
#

newly added

violet void
#

21 Jan, I gotta update my version 😢

random sleet
#

you can also access the voucher cardarea, G.vouchers

wild patrol
#

You think a multi based on how many cards u have in your hand would work?

violet void
#

high card moment

wild patrol
#

how many cards you think is the limit for a booster?

#

Before it becomes too many

frosty dock
#

7

violet void
wild patrol
#

I'm basically just slapping yugioh card effects into balatro with a balatro equvelant

#

so some cards probably gonna have better effects than others

random sleet
#

each card held in hand gives +1000 chips

wild patrol
#

I wonder if it's possible to make cards spawn only during an endless run

wild patrol
iron iron
#

kinda underpowered imo

wild patrol
#

I could do a 3rd of 1000

frosty dock
#

high card supremacy

wild patrol
#

maybe 333 per card?

#

so if u want it to be super broken gotta pare it with a card that repeats the effect

iron iron
#

h*gh c*rd brainrot

random sleet
#

slifer as a legendary that gives +1000 chips per card in hand seems aight

wild patrol
#

Would 1000 per card pretty much guarantee you win all 8 antes?

iron iron
#

no because you need mult smh

wild patrol
#

Ok

#

I see

iron iron
#

what if you run into a seed whre you only have chips

iron iron
#

this will absolutely guarantee a win

wild patrol
#

If u paired this with Jinzo you'd pretty much win

#

Jinzo disables boss blinds

#

Not sure how to balance it then lol

#

other than being a endless only card

#

or a card with such a low change of spawning

#

you'd never really see it unless u got more luck than a full odds shiny pokemon

random sleet
#

me when legendary is sitting right there

wild patrol
#

What is a legendary spawn rate?

random sleet
#

0

#

only from the Soul card

wild patrol
#

hmmm

#

ok idea

#

a card where u have to destroy 5 joker cards

#

🤔

#

So you'd have to have 5 cards already bought and get lucky to get the summoning card to get slifer

#

if you're gonna get a broken card might as well have to put some effort into it

#

I also have the other two cards

#

so I could just combine it into a 1/3 dice roll card of what u get is what u get

#

with winged dragon of raw I can easily used sphere mode

#

Have to wait until you beat boss blind to Turn it into Ra and requires u to destroy 3 random jokers to get this card into ur joker zone

solar eagle
#

how does one lock a joker? like how the pair/trio/family/tribe require you to win a run without playing their respective hands

#

i looked at game.lua and found

unlock_condition = { type = "win_no_hand", extra = "TWT_polycule" },```
but they do not work
frosty dock
#

it's unlocked = false

solar eagle
#

right here

frosty dock
solar eagle
#

man idk what to tell you

#

its in mine

frosty dock
#

what version of balatro would that be

solar eagle
#

1.0.7

#

according to CFBundleVersionString

frosty dock
#

according to what

#

that's not a version that exists

#

i would assume it has to be some 1.0.0 version though, 1.0.1f also doesn't have it

solar eagle
#

got it from apple arcade+ since its easier to browse

frosty dock
#

that... makes more sense

#

i can't tell if you if it does anything there, but it doesn't exist on the steam version

#

and even then unlocked = false is the important part

solar eagle
#

yea figured that out

#

how do you then display the unlock message?

#

and/or set the condition if its custom

frosty dock
solar eagle
#

ooooh

frosty dock
merry raven
#

El gato

frosty dock
#

you should know that modding balatro is based almost exclusively around the steam version, so the arcade version can and will have issues

solar eagle
#

im not modding the arcade version

#

i just have a copy and its easier to browse the src

#

ty!

frosty dock
#

how is it easier

#

you literally just extract the executable for the steam version

solar eagle
#

yea and this was already done for me in the arcade version

#

thats it

frosty dock
#

just be aware that you'll keep running into code differences like this

solar eagle
#

so far there havent been any issues with doing so aside from start_locked which we just discovered

violet void
#

Is there a way to lock back a card without having to change the key?

#

I guess the save data

spring lantern
#

what's the right way to copy a joker's ability? rn all im doing is softlocking the game without even copying anything 😭

#

im talking blueprint type behavior

violet void
atomic edge
#

can i separate my code into multiple lua files? because i see i need to name one main in a json file

#

and i dont know how to execute the other files

frosty dock
#

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

maiden phoenix
#

I thought assert wasn't necessary anymore

frosty dock
#

sure it's not "necessary", it just makes crash logs completely useless when you don't use it

sick sparrow
#

made the old transparency method

sick sparrow
frosty dock
#

i should specify, crash logs from failing to load the file

atomic edge
frosty dock
#

yes

atomic edge
#

thanks

wooden badge
#

can seals access the before/after contexts? - wondering if it's possible to have a sealed card's effect take place after the hand in which it is played

wooden badge
#

currently can only get it to activate when it's scored, through 'calculate' obviously

violet void
#

with new calc

wooden badge
#

im pretty behind with updates tbf

violet void
#

I think any version of new-calc

wooden badge
#

ok cheers, i'm on old-calc

#

should probably update and get used to the new quirks and such

#

just a github jobby?

violet void
#

it has lots of improvements

wooden badge
#

ok cool, will it be labeled 'new-calc' or is it just the most recent commit on the main smods repo?

violet void
#

most recent one will work

wooden badge
#

ok great thanks

#

i seem to remember a reason I switched to old-calc because something was bugged (annoyingly can't remember exactly what) so I assume that's fixed now

atomic edge
#

im looking at a code from another mod and he uses self.config.type == 'something' but that something is never used again / i cant find it, any thoughts?

wintry solar
#

which mod?

wooden badge
#

unless it's actually in something used?

atomic edge
#

oh never mind my bad it was in the lovely file

#

but thanks

wooden badge
#

@violet void imagine me spending all night trying to figure how to activate the damn seal after the hand and coming up short, only to not have updated the c***. smh

minor gyro
#

how do I check for modded jokers?

limpid flint
minor gyro
# limpid flint what do you mean by "check"

local negative_joker_count = 0
for _, v in ipairs(G.jokers.cards) do
if v.edition and v.edition.key == 'e_negative' then
negative_joker_count = negative_joker_count + 1
end
end

here i check for negative jokers

wooden badge
minor gyro
limpid flint
frosty dock
#

find_joker uses names

minor gyro
frosty dock
#

(v.config.center.mod or {}).id would give you the corresponding mod ID if the mod exists

limpid flint
#

-# I'll leave this to the professionals

minor gyro
frosty dock
#

-# time to be unprofessional

wooden badge
#

shucks, i guess I'll replace my find_joker calls with find_card then

frosty dock
#

you might be under the impression that it works with keys, but that's because smods defaults names to keys for some reason i don't remember

minor gyro
#

holy shit I forgot about .json

frosty dock
#

i think it was 0.9.8 compat

#

it may be removed when 0.9.8 compat is, and it's inconsistent with how it works for vanilla jokers vs. modded

wooden badge
#

is the logic the ssame as find_joker? Like just pass as an argument the key I'm looking for @frosty dock

#

I can just omit the second arg most of the time

frosty dock
#

yeah it's a drop-in replacement for find_joker

wooden badge
#

ok epic thanks

frosty dock
#

second arg isn't needed unless you have a reason for looking for debuffed versions of the card

wooden badge
#

sorry is it a '==' check against the respective key instead, because I'm using #find_joker() > 0 atm to check if the table regarding that joker is not empty essentially

#

so if SMODS.find_card() == _my key_ then?

violet void
#

its the same youve been using the other

frosty dock
#

no it works exactly the same way

wooden badge
#

oh ok literally just pick up and replace the words find_joker

frosty dock
#

if #SMODS.find_card('j_mod_yourkey') > 0 then is one way to check

wooden badge
#

ok great thanks

frosty dock
#

I prefer if next(SMODS.find_card('j_mod_yourkey')) then personally but either works

wooden badge
#

yeah the > 0 feels a bit hacky

wooden badge
#

that's more succinct, just a straight boolean to return

frosty dock
#

mostly because it always accurately reports if the table is non-empty instead of just checking numeric keys

#

it's not a bool, really it's just the "next element" of some sort

#

which means it's nil/falsy iff there is no element

wooden badge
#

ah ok should probably look at the next code

#

see it a bit

frosty dock
#

unless you're dealing with a table of bools i guess, in which case you'd have to check ~= nil

wooden badge
#

oh it's a lua intrinsic

violet void
#

kinda wish lua considered empty tables falsy

royal ridge
#

i think lua should consider "0" falsy 😃

wooden badge
#

wouldnt next(emptytable) return falsy? (nil to be specific) @violet void

frosty dock
violet void
royal ridge
wooden badge
#

oh right, just a concision thing

frosty dock
minor gyro
#

"Gains {C:white,X:mult}2X multiplier",
Idk why this happens, but it does. With multiple jokers.

violet void
#

shouldnt you close the brackets

wooden badge
#

you need a close pair of braces

#

{} after the multiplier

minor gyro
#

OH

#

i didn't see i forgot those

#

mb mb

wooden badge
#

or sorry after the 2x if you want the multiplier out of it

wintry solar
#

it strips spaces too fyi

minor gyro
#

it happens here too... I see them braces

minor gyro
wooden badge
#

generally you only want the numerical text to be altered by the colours

#

so just enclose the number with the second brace pair

frosty dock
#

fyi there isn't really "closing" these and they don't work in pairs

#

{} just resets the modifiers to null

minor gyro
atomic edge
#

is there a tutorial on how i could make a new area like the consumeable area for example

frosty dock
#

no but multiple mods do it

violet void
atomic edge
#

betmma mods has it but its just so complicated for me and i cant seem to get it working haha

frosty dock
#

reverie also has a custom area

#

at some point you just run out of space to not overlap which is kind of a problem

maiden phoenix
#

Gotta make an area that takes the whole screen balatrojoker

lethal stratus
#

trying to make this without errors like these

wintry solar
#

all the basic context checks are literally written out

lethal stratus
#

i might be dumb

#

i dont entirely know how to check for a SPECIFIC card

#

/ value

wintry solar
#

just out this first

lethal stratus
#

most of those are implied no?

wintry solar
#

the check at the top

lethal stratus
#

oh doy

wintry solar
#

it set out as "here's a check you can use to get this context" and "heres what the context contains"

minor gyro
lethal stratus
#

whats the variable for card value?

wintry solar
#

get_id() is correct for value

storm kraken
#
      evaluate = function(parts, hand)
        if next(parts._flush, parts._high_card) then
            local fibaflush = true
            local _flushed = SMODS.merge_lists(parts._flush, parts._high_card)
            for j = 1, #_flushed do
                local rank = SMODS.Ranks[_flushed[j].base.value]
                fibaflush = _flushed and (rank.key == 'A' or rank.key == '2' or rank.key == '3' or rank.key == '5' or rank.key == '8')
            end
            if fibaflush then return {_flushed} end
        end
    end,

trying to make a custom hand that checks for an ace, 2, 3, 5, 8 flush but obviously as you see here the code doesnt work because you only need two of the 5 cards to make the hand activate
how would i make it check if all the cards are present in the scored hand edegabudgetcuts

lethal stratus
#

the card is not triggering now

wintry solar
#

show code now

lethal stratus
#

but it doesnt crash on entry ig

#

idr how to write the return

frosty dock
#

xmult = card.ability.extra.Xmult and remove the message parts

wintry solar
#
return {
  xmult = card.ability.extra.Xmult
}```
lethal stratus
#

does that pop up the X3 on screen?

frosty dock
#

yes

wintry solar
#

yes

#

assuming you're running an up to date smods build

lethal stratus
#

didnt trigger

frosty dock
#

if you're running old calc, only x_mult will actually work

#

but you should update

maiden phoenix
wintry solar
#

ah the silly quirks of old calc

lethal stratus
#

how do i update?

wintry solar
#

download this

frosty dock
#

unless you know anything about git, just delete the smods folder you have and redownload ^

lethal stratus
#

do i replace the lua?

#

i already downloaded the most recent but the lua inside my git mod didn't change

#

because of course it didnt thats not how computers work

#

alright it completely works now

frosty dock
lethal stratus
#

what is it then

#

😭

frosty dock
#

some mod

#

there should be a steamodded folder in your mods

lethal stratus
#

there is

#

i might be doopid

frosty dock
#

that's what you replace

storm kraken
#

where can you find the uhh
things for poker hands in the game files
-# like the things that define what cards they need

frosty dock
#

get_straight is overridden by smods

minor gyro
#
SMODS.Joker {
  key = 'revenant_jk',
  atlas = 'Jokers',
  loc_txt = {
    name = "Revenant",
    text = {
      "Gains {X:mult,C:white}#2#X{} for",
      "each {C:purple}modded joker{}",
      "in your hand.",
      "{C:inactive}(Currently: #1#{})"
    }
  },
  loc_vars = function(self, info_queue, card)
    return { vars = { card.ability.extra.Xmult, card.ability.extra.Xmult_mod } }
  end,
  config = { extra = { Xmult = 0, Xmult_mod = 3 } },
  rarity = 2,
  pos = { x = 7, y = 0 },
  cost = 5,
  calculate = function(self, card, context)
    if context.joker_main then
      local modded_jokercount = 0
      for _, v in ipairs(G.jokers.cards or {}) do
        if (v.config.center.mod or {}).id == 'phasmo_cards' then
          modded_jokercount = modded_jokercount + 1
        end
      end
      return {
        Xmult = modded_jokercount * card.ability.extra.Xmult_mod
      }
    end
  end
}
```if u want to take a look at the whole code
frosty dock
#

what smods version?

frosty dock
#

the smods patched version gets X or more

lethal stratus
#

i dont know how to make this calculate function

storm kraken
lethal stratus
#

:3

#

vimvid stasis

storm kraken
#

so like

#

abstract joker but xmult?

lethal stratus
#

basically

#

its going to be a legendary i think

frosty dock
#

uhh

lethal stratus
#

so if thats too weak let me know

storm kraken
#

i did this with an update function

frosty dock
#

+1 X1 for each Joker held?

lethal stratus
#

you got me hold on

frosty dock
storm kraken
storm kraken
frosty dock
#

there's no need to count jokers every frame

lethal stratus
#

lmao 😭

frosty dock
#

realistically you only need to do it in calculation and loc_vars

storm kraken
#

oh

#

💀

lethal stratus
#

i dont know how to do it at all though tbh

storm kraken
#

you need:
a count of all the jokers
a value to times by that count
the amount you get itself

#

i think

lethal stratus
#

well whats the easiest way to count jokers?

#

is there a way to just check how many jokers you have based on the joker slot counter?

crisp coral
storm kraken
#
 for i = 1, #G.jokers.cards do
lethal stratus
#

would i just create a variable to do x = x + 1 or something

#

😭

frosty dock
#

#G.jokers.cards

lethal stratus
#

oh my god im going to kill lua

#

with hammers

storm kraken
#

honestly i think this is a minor skill problem (/j)
-# says as im struggling to make a custom hand

lethal stratus
#

well the main question that i have is mostly just

#

the location of the loop, and how to apply it to the Xmult variable

lethal stratus
#

holy lobcorp

storm kraken
#

abomonation

crisp coral
#

oh it says custom hand not custom blind

#

bye

storm kraken
#

😭

lethal stratus
#

thats it

#

price of silence

#

smh

#

can i just see abstract jokers code actually

#

idk where it is in the base game

lethal stratus
#

😭

#

i dont know what the checks would be for the if statement 😭

atomic edge
#

is there any docuentation for SMODS.ConsumeableType

crisp coral
lethal stratus
#

i needed to see the if statement damn you thunk

#

😭

night pagoda
#

Is there no way to scale a node tree?

wintry solar
#

This will give you 1 Xmult per joker

lethal stratus
#

oh my

#

im so stupid

#

got her working

#

should i make saturday bp compat

night pagoda
#

How do I properly manage the nodes created by localize()? This is what I'm currently doing, but this doesn't seem like a right thing to do

sonic cedar
#
calculate = function (self, card, context)
        if context.joker_main and G.GAME.current_round.hands_left == 0 then
          return{
            mult_mod = card.ability.extra.mult,
            message = localize{type = 'variable', key = 'a_mult', vars = {card.ability.extra.mult} }
          }
        elseif context.end_of_round then
            if context.individual then
                if not context.blueprint_card then
                    if card.ability.extra.c_rounds >= card.ability.extra.rounds then
                        card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
                        return {
                            message = 'Yum!',
                            colour = G.C.MULT,
                            card = card
                        },
                        card.ability.extra.c_rounds == 0
                    else
                        card.ability.extra.c_rounds = card.ability.extra.c_rounds + 1
                    end
                end
            end
        end
    end

what's wrong with my calculate function? it's supposed to trigger the joker gaining 2 mult every 3 rounds (starts from 8), but instead it does it each round and the mult gain is like 10?? (went from 8 to 18) is it set up incorrectly? did i miss a line?

#
    loc_vars = function (self, info_queue, card)
        return{vars = {card.ability.extra.mult, card.ability.extra.mult_gain, card.ability.extra.rounds, card.ability.extra.c_rounds}}
    end,```
forgot the loc vars
lethal stratus
#

how to check if a card is a stone card?

wintry solar
sonic cedar
#

is it actually that easy

wintry solar
#

Assuming the rest of your code is correct, yeah it’s just an incorrect context check

sonic cedar
#

i guess i messed something else up then

#

cause now it wont do the increase at all

wintry solar
#

It’s hard to read on mobile, can you screenshot?

lethal stratus
vocal verge
#

i think

#

there's probably a better way to check it

nocturne sentinel
#

are there any guides or any way to learn how to make mods for balatro (steammodded) sorry if im asking a stupid question

vocal verge
lethal stratus
#

its a joker check so i dont think self works

wintry solar
vocal verge
#

or just look through the game files/other mods and see if it works

sonic cedar
wintry solar
vocal verge
wintry solar
vocal verge
#

or what eremel said

sonic cedar
#

oh ok

wintry solar
#

No reason not to update

sonic cedar
#

i mean the only reason i WAS on oldcalc was i think cryptid?? iirc

crisp coral
#

one reason not to update

sonic cedar
#

a small price to pay for a functional mod,,,

wooden nexus
sonic cedar
gloomy adder
wintry solar
nocturne garnet
gloomy adder
#

ohh alr

languid bay
#

Hello, I'm trying to have a joker retrigger playing cards that have already retriggered, afaik I can't check if there has already been retriggers in context.repititions. I may need to patch a new context to game.lua? Not sure where tho.

sharp blade
#

maybe you could set a a tag on the card to true in context.repetitions and read that value later?

atomic edge
#

sell = {n=G.UIT.R, config={align = "tr"}, nodes={ {n=G.UIT.R, config={ref_table = card, align = "tr",padding = 0.1, r=5, minw = 0.3, minh = 0.3, hover = true, shadow = true, colour = G.C.UI.BACKGROUND_INACTIVE, one_press = true, button = 'sell_card', func = 'can_sell_card'}, nodes={ -- {n=G.UIT.B, config = {w=0.1,h=0.6}}, {n=G.UIT.C, config={align = "tm"}, nodes={ {n=G.UIT.R, config={align = "cm", maxw = 1.25}, nodes={ {n=G.UIT.T, config={text = localize('b_sell'),colour = G.C.UI.TEXT_LIGHT, scale = 0.3, shadow = true}} }}, {n=G.UIT.R, config={align = "cm"}, nodes={ {n=G.UIT.T, config={text = localize('$'),colour = G.C.WHITE, scale = 0.3, shadow = true}}, {n=G.UIT.T, config={ref_table = card, ref_value = 'sell_cost_label',colour = G.C.WHITE, scale = 0.3, shadow = true}} }} }} }}, }}

#

this is the code for a sell button on a consumeable

#

can someone tell me how i can move it a bit to the left?

sharp blade
sharp blade
atomic edge
#

it is already behind the card like this

#

i want to move it so it is not behind

sharp blade
#

ohh

atomic edge
#

this is how it looks

#

its behind the beer

sharp blade
#

looking at the shadow you would probably have to move the beer down rather than move the sell button up

#

is the hitbox of the card the entire square?

atomic edge
#

yes

#

its formated like a joker but transparent background

sharp blade
#

then you probably could just move the sprite down in your atlas so that the beer covers the sell button

atomic edge
#

you mean leave space at the top of the beer eg. make it smaller?

sharp blade
#

instead of leaving space at the bottom leave space at the top

atomic edge
#

yea smart but the problem is that the sell button is like directly above the use button

#

its a bad screenshot so you cant see

#

but its directly behind the beer

sharp blade
#

ohhh

minor gyro
vital rapids
#

Just wanted to ask again if its possible to increase the chances of another joker being found in shop

#

Like gros michael and Cavendish but idk if gros Michael actually makes cavendish more common or just makes it avaliable

faint yacht
#

Cavendish will be available in the pool of possible Jokers to appear if Gros is eaten.

nocturne garnet
frosty dock
vital rapids
#

I hope I'm not 😭

sharp blade
#

line 1963 in common_events.lua

frosty dock
vital rapids
frosty dock
#

that is possible

runic pecan
#

Is this effect enough for a Legendary-like?
Also, is this wording OK?

frosty dock
#

Gain mult gained?

#

that sounds confusing

runic pecan
#

Like accelerate instead of velocity

frosty dock
#

yeah i get it, you want quadratic scaling

runic pecan
#

And I'm asking if there's better wording because I was like 84% sure it is confusing before posting the ask.

minor gyro
#

thank god u wasn't 85%

vital rapids
#

Gain mult per mult gained

#

Slightly less confusing

#

Or of

#

Gain mult% of mult gained

frosty dock
#

nah ur making it more confusing

vital rapids
#

Well im stumped

hardy viper
#

im rooted

frosty dock
#

im trunked

minor gyro
#

hey Mr. Johohon smods

hardy viper
#

the real john from smods

runic pecan
#

Maybe "Mult gained next hand increased by X0.25"?

frosty dock
#

jhon

minor gyro
#

is there a git page talking about message?
message = localize { type = 'variable', key = 'a_chips_minus', vars = { card.ability.extra.chip_loss } },
like this?

frosty dock
#

isn't that auto supported

minor gyro
frosty dock
#

like iirc you can just return { chips = -10 }

hardy viper
frosty dock
#

i guess there's stuff like ice cream

#

where you really just want the message

#

in which case that does look correct

minor gyro
#

cuz is prettier CatCute

frosty dock
#

sounds like a use for context.other_joker

#

I'd advise you also score the xmult at that time though, additive xmult per thing is confusing when done like this

minor gyro
#

change to context.other_joker instead joker main?

runic pecan
#

How about this?
(This is, in some way, inspired by Ride the Bus)

frosty dock
#

then context.other_joker is the other joker you use to check if it's modded rather than checking for all jokers

hardy viper
tepid crow
#

scaling is a weird word

frosty dock
#

here's something wacky
Each hand, this joker gains X0.25 Mult per consecutive hand played with at least one scoring face card
-# maybe that's too dense to not be confusing

tepid crow
#

maybe

frosty dock
#

the scaling scaling is constant

runic pecan
tepid crow
#

it's just derivatives all the way down

runic pecan
#

0.25 is the second derivative.

tepid crow
#

exactly

frosty dock
#

I consider the:

  • value to be the mult given
  • scaling to be the amount the value gains (constant for something like bus unless resets), i.e. first derivative
  • scaling scaling to be the amount scaling gains, i.e. the sceond derivative
runic pecan
#

but you said scaling thrice

frosty dock
#

i guess if you consider scaling to be the mult given, what you said makes sense

tepid crow
#

I do

#

since it... scales?

frosty dock
#

but the value isn't the scaling

#

the scaling is how the value changes

runic pecan
#

For reference, here's my code

tepid crow
#

🤣

#

why are you card_eval_status_texting

frosty dock
#

me when I Xmult_mod_mod_mod

runic pecan
frosty dock
#

i don't see how that doesn't work here

tepid crow
#

meaning what 🤔

#

oh wait that's not a calculate function?

runic pecan
#

For example, returning Xmult value overwrites my desired message colour to G.C.MULT.

frosty dock
#

you can put a colour in your return...

runic pecan
tepid crow
#

yeah okay so then a return should work fine?

runic pecan
tepid crow
#

hold on lemme test that then

runic pecan
tepid crow
#

I don't think it's that 😬

frosty dock
#

wait you're doing an Xmult return?

#

if you do a message return, colour works normally

#

for Xmult, it needs to be in xmult_message

runic pecan
tepid crow
#

I mean smods shouldn't get a final say on the colour?

frosty dock
#

it doesn't

#

this is just card_eval_status_text being passed x_mult type, this is easily overridden with xmult_message

#

it's just that normal colour only works for a normal message

tepid crow
#

so what, balatro itself isn't allowing it?

frosty dock
#

if you had both an Xmult and a different message, would you want to only be able to set the colour for both at the same time??

runic pecan
#

Oh, by the way, card_eval_status_text also allow me to display message when no return is required.

frosty dock
#

when would that be

#

every calculation context supports it

runic pecan
#

When I need to do calculation after message is shown.

#

Wait, lemme find the code that had bugged me into start using card_eval_status_text

spring lantern
#

why is the last card allegedly being calculated twice? i must've goofed up big time somehow

tepid crow
frosty dock
#

no

#

xmult_message = { message = 'test', colour = G.C.GREEN }

tepid crow
#

ah

frosty dock
#

the docs need to be more precise on this

tepid crow
#

the docs still say

Use chip_message = 'text' to change the text (this maintains default timings)

#

but yeah the table works

frosty dock
#

@wintry solar huh

tepid crow
frosty dock
#

was that ever accurate?