#💻・modding-dev

1 messages · Page 179 of 1

normal crest
#

In apply_to_run then

lethal mural
#

where the starting values change each time

#

o

normal crest
#

Same concept

lethal mural
#

i tried setting it there but it didnt do anything

normal crest
#

Also you should use pseudorandom so ingame seeds are applied

normal crest
maiden river
#

is there a way to watch a file with debugplus in my code?
I get kind of tired typing the thing in

lethal mural
normal crest
#

Good luck

grim remnant
#

hey, it's me again. uh. i realized it wasn't giving chips earlier but couldn't tell you why. i think i narrowed down why, but is there a better answer to it than just. a second line in the calculate function?

        -- Tests if context.joker_main == true.
        -- joker_main is a SMODS specific thing, and is where the effects of jokers that just give +stuff in the joker area area triggered, like Joker giving +Mult, Cavendish giving XMult, and Bull giving +Chips.
        if context.joker_main then
            -- Tells the joker what to do. In this case, it pulls the value of mult from the config, and tells the joker to use that variable as the "mult_mod".
            return {
                mult_mod = card.ability.extra.mult,
                -- This is a localize function. Localize looks through the localization files, and translates it. It ensures your mod is able to be translated. I've left it out in most cases for clarity reasons, but this one is required, because it has a variable.
                -- This specifically looks in the localization table for the 'variable' category, specifically under 'v_dictionary' in 'localization/en-us.lua', and searches that table for 'a_mult', which is short for add mult.
                -- In the localization file, a_mult = "+#1#". Like with loc_vars, the vars in this message variable replace the #1#.
                message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
                -- Without this, the mult will stil be added, but it'll just show as a blank red square that doesn't have any text.
            }
        end```
lethal mural
#

i tried setting the values as variables in a function and running the function each time in apply_to_run but it still has the same issue

normal crest
#

Did you modify 'back' in apply to run

#

That was my idea

lethal mural
#

back?

plush cove
#

"back" is the internal name used for decks

normal crest
#

the 2nd parameter of apply to run, should be your deck instance

past forge
#

bump

lethal mural
#

i didnt know that was a thing you could do

lethal mural
#

this is what i tried originally

#

it successfully randomized the initial variables but it just picks the same numbers every time until you restart the game so that was a bust

past forge
red flower
# past forge bump

idk if your patch will work but the way you do conditions in tables is
condition and value_1 or value_2

lethal mural
#

typo but i dont think thats the reason ist not working ol

normal crest
lethal mural
normal crest
#

Modify 'back'

#

back.config.smt = smt

lethal mural
#

o

normal crest
#

Might not be structured like that exactly

lethal mural
#

i tried that with self originally lol oops

#

nope

#

attempt to index a nil value

normal crest
#

And I thought it was apply to run, not just apply

lethal mural
#

in smods documentation its apply

red flower
grim remnant
normal crest
lethal mural
#

yes

grim remnant
#

(tho i mean. it's an edit of a sample mod dfgjks)

normal crest
#

Try print(inspect(back))

#

And see how it's structured

red flower
scarlet spire
#

okay, what am I doing wrong with the event manager?
this calculate function (for a seal) is supposed to score all cards, apply random seals to all cards except the card it is on, wait a moment, destroy the card, wait a bit more (to show you what happened), then the cards go away as normal. instead, it waits a bit, applies the seals, destroys the card, and instantly ends the hand, making it really hard to tell what's going on

normal crest
#

You have your inner add event outside func

scarlet spire
#

ah, they should be nested in the funcs

#

okay

grim remnant
past forge
normal crest
grim remnant
normal crest
#

You need to update

red flower
#

do you want to change the chance?

past forge
#

im trying to do this effect

#

i already have the lucky card part

red flower
#

I would probably patch out where it calculates the probability

past forge
#

but i can not find where it calculates the probability 😭

broken cliff
plush cove
red flower
lethal mural
#

holy shit

#

i figured it out

#

config is basically entirely worthless here

#

what i actually have to do here is modify G.GAME.starting_params directly

past forge
red flower
#

i know, I mean look for when it's called

grim remnant
# normal crest You need to update

okay, THAT much worked. for whatever reason though, on scoring, it displays an extra mult pop-up that's yellow??? NO idea what that's about, frankly.

red flower
#

you don't need the messages

#

it does it automatically now

grim remnant
#

oh!

#

uh. what if i want a custom one on purpose though. (this may have given me a dastardly idea to replace the duplicate +1 Mult with just. "Paul.")

red flower
#

well in that case yes
if you change them to mult_mod and chips_mod they don't get the automatic message i think

grim remnant
#

would i just replace the two specified messages with like. what, message = 'Paul.'?

lethal mural
#

trying to find what other starting params there are though because it doesnt seem to be listed in game.lua where i thought it'd be

scarlet spire
past forge
#

i think i found it

#

but im not sure how to patch it, will try a couple things

red flower
red flower
sturdy compass
#

This might be a bit of a technical question, but how would I get DebugPlus to spawn a card with a custom set in a new card area? (Art is a placeholder, it is not a Planet card in code)

red flower
#

i don't think you can without modifying it but i would also like to know if there's a way

sturdy compass
#

The waiting game we shall play then lol

red flower
#

i just give myself infinite rerolls to find my custom cards lol

lethal mural
#

IT WORKS

#

FINALLY

#

basically if anything is super large it comes at the cost of another stat

scarlet spire
#

delay(...) isn't doing anything no matter where I put it

past forge
#

I think the patch is not able to get the scoring hand

#

should i put it inside the joker?

#

this is the patch btw, i dont know if its right:

G.FUNCS.evaluate_play = function ()
    if not G.GAME.blind:debuff_hand(G.play.cards, poker_hands, text) then
        for i=1, #G.jokers.cards + #G.consumeables.cards do
            for i=1, #scoring_hand do
                if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and not (SMODS.find_card("j_toyr_four_leaf_clover") and self.base.id == 4) and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then 
                    destroyed = true
                end
            end
        end
    end
end
maiden river
#

is there a nice way to make a joker automatically win a blind?

red flower
#

yeah you're just deleting the entire function
a hook is going to be hard, you should try a lovely patch

plush cove
past forge
sturdy compass
past forge
#

today i made my first patch and it was a very small function so i dunno how to patch bigger functions

maiden river
#

this is what I use

#

just add your set name

hallow slate
#

It's a great concept

sturdy compass
maiden river
#

I have both

sturdy compass
#

Oh I see

maiden river
#

and it works that way

sturdy compass
#

Gotcha

past forge
#

i know it should be something like this but i really have no idea

sturdy compass
#

Alright that did it, thank ya

#

Now to get the actual sprite there lol

maiden river
#

no problem

#

😭

#

does it not go in there?

red flower
# past forge honestly, i dont know how to do that

something like this

[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = "if destroyed then"
position = 'before'
match_indent = true
payload = '''
if scoring_hand[i].ability.name == 'Glass Card'  and (SMODS.find_card("j_toyr_four_leaf_clover") and scoring_hand[i].base.id == 4) then
    destroyed = false
end
'''
past forge
#

whats exactly the pattern?

maiden river
red flower
past forge
#

and should i put the patch just like a hook in the main.lua?

red flower
#

no, you make a .toml file

red flower
grim remnant
#

so uh, stupid question. how do i make a joker give an extra joker slot (like it's negative, even if it isn't actually negative)? is that a function in smod, orrrr? (asking because i have a good few ideas that involve joker slot shenanigans)

maiden river
#

G.jokers:change_size(1), I believe

sturdy compass
maiden river
#

oh!

past forge
plush cove
sturdy compass
#

Well yes but actually no

past forge
maiden river
sturdy compass
#

Who knows, maybe (probably) there's a part of the CardArea that I messed up

atomic edge
#

is there a mod i can look at that has a joker/card that checks wether something happens at any point in the game (like a card that needs three tarots to be played for it to work) or something like that

sturdy compass
#

Here are the three injects I'm doing for it (not counting the hook that you just recommended to me)

maiden river
#
[manifest]
version = "1.0.0"
priority = 15

[[patches]]
[patches.pattern]
target = '=[SMODS _ "src/utils.lua"]'
pattern = "-- TARGET: add your own CardAreas for joker evaluation"
position = "before"
match_indent = true
payload = "table.insert(t, 1, G.weapons)"

# Emplace weapons in their own area
[[patches]]
[patches.pattern]
target = "functions/button_callbacks.lua"
pattern = '''
elseif card.ability.set == 'Booster' then
'''
position = "before"
payload = '''
elseif card.ability.set == 'Weapon' then
    card:add_to_deck()
    G.weapons:emplace(card)
    play_sound('card1', 0.8, 0.6)
    play_sound('generic1')
    dont_dissolve = true
    delay_fac = 0.2
'''
match_indent = true

# Add Pool and Global Object
[[patches]]
[patches.pattern]
target = "main.lua"
pattern = '''function love.load()'''
position = "before"
payload = '''
FVB = {}
FVB.cards = {}
'''
match_indent = true
#

this is my whole toml file 😭

sturdy compass
#

Oh my goodness LOL

wintry solar
#

I’m pretty sure the cardarea functions don’t support new types without rewriting them

past forge
#

so this patch should work?

[manifest]
version = "1.0.0"
priority = 0

[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = "if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then"
position = 'at'
match_indent = true
payload = '''
"if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and not (SMODS.find_card("j_toyr_four_leaf_clover") and self.base.id == 4) and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then"
'''
wintry solar
#

But you also shouldn’t really need a new one

grim remnant
sturdy compass
wintry solar
sturdy compass
#

alr

sturdy compass
scarlet spire
#

but the played hand won't stay on screen long enough, and the cards go offscreen even though an event is still happening

wintry solar
#

Unnest them

wintry solar
scarlet spire
#

fully? someone else just told me to nest the second event inside the func of the first one

wintry solar
#

No if you do that it’ll only add it to the event stack when the first event is run, so it goes after all the following events

#

You want to add them consecutively

sturdy compass
#

Oh huh that's a weird one lmao

scarlet spire
plush cove
#

ignore how long it took me to do that

sturdy compass
#

lmfao

grim remnant
#

uh, sorry to nag about this; how can i make a joker give an additional joker slot or otherwise influence joker slots? like, where would i put that in the code of the joker?

    key = 'paulJoker',
    loc_txt = {
        name = 'Paul',
        text = {
            "{C:chips}+#2#{} Chips",
            "{C:mult}+#1#{} Mult",
            "+1 Joker Slot",
            "Paul."
        }
    },
    config = { extra = { mult = 1, chips = 1 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.mult , card.ability.extra.chips } }
    end,
    -- 1 common, 2 uncommon, 3 rare, 4 legendary.
    rarity = 1,
    atlas = 'StellationJokers',
    pos = { x = 0, y = 0 },
    cost = 1,
    -- G.jokers:change_size(1), --idk if i put it in the right place lol
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                mult = card.ability.extra.mult,
                chips = card.ability.extra.chips,
                message = 'Paul.'
            }
        end
    end
}```
sturdy compass
#

You should probably add an add_to_deck and remove_from_deck function

#

Change the size there

scarlet spire
#

okay... this is a bit odd, but i'm now getting smods related crashes? in this video, I have two debugplus savestates. I load the second one, play a hand with the beige seal, and then load the first save state, which crashes the game

#

it's crashing at line 304 in smods src/utils.lua, which is the SMODS.find_card function

obtuse silo
#

okay so i'm gonna be going to bed rn so i'm putting some code here, could someone unscrew this because I am too tired to learn how to refer to the length of a lua array

left lance
#

What is supposed to go in the main.lua type file referenced in line 8 of the example code of https://github.com/Steamodded/smods/wiki/Mod-Metadata ? Looking at examples that's where people seemingly put their Atlas, but also I've seen other things loaded in there as well

GitHub

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

past forge
#

if your name file is called projansky.lua, then you put that there

left lance
maiden river
past forge
#

jokers, seals, editions, etc

#

while you learn and you write more code, youll figure out if you need more files and how to use them

left lance
plush cove
grim remnant
past forge
#

i dont really know Lua so that way is how i do it for the momment, but if you manage to do it better just go for it

past forge
#

as im learning how to code ill organize everything, but for now im not doing that big of a project

#

i just have this

maiden river
#

you'd just put G.jokers:change_size(-1) in the remove_from_deck

#
add_to_deck = function(self, card, from_debuff)
  -- Changes a G.GAME variable, which is usually a global value that's specific to the current run.
  -- These are initialized in game.lua under the Game:init_game_object() function, and you can look through them to get an idea of the things you can change.
  G.GAME.round_resets.discards = G.GAME.round_resets.discards + card.ability.extra.discard_size
  G.hand:change_size(card.ability.extra.hand_size)
end,
-- Inverse of above function.
remove_from_deck = function(self, card, from_debuff)
-- Adds - instead of +, so they get subtracted when this card is removed.
  G.GAME.round_resets.discards = G.GAME.round_resets.discards - card.ability.extra.discard_size
  G.hand:change_size(-card.ability.extra.hand_size)
end
grim remnant
#

so wait, smth like

        if context.joker_main then
            return {
                jokers:change_size(1)
            }
        end```
and obviously an opposite for this?
left lance
grim remnant
#

i assume not EXACTLY this syntax

maiden river
#

what you're after is basically the same, except for joker slots

past forge
maiden river
left lance
maiden river
#

lua's ~= thing still annoys me, even though I'm a few hundred hours in 😭

past forge
#

good luck then, lua is pretty easy but you have to get use to a lot of singularities

past forge
#

or arrays starting at 1

maiden river
#

also that their exponent operator is the caret symbol

#

which makes the most sense of anything I've learned so far

#

but it's still of

plush cove
past forge
maiden river
#

I must've missed every language that did that then 😭

past forge
#

what other way did you do it?

chrome widget
#

How would you apply a shader effect to the entire screen, like if I wanted to put like a sepia filter on somethin?

grim remnant
#

here's source with line numbers for reference

maiden river
maiden river
past forge
#

thats fair

maiden river
#

the caret symbol is usually bitwise stuff for my choice languages

chrome widget
#

For the record, using a carat is an accepted way to represent exponents if you're doing like real life paper mathematics

maiden river
#

yeah

#

that's why I said it makes sense, technically

#

that is also how I wrote one of my cards' description

past forge
#
[manifest]
version = "1.0.0"
priority = 0

[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = "if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then"
position = 'at'
match_indent = true
payload = '''
"if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and not (SMODS.find_card("j_toyr_four_leaf_clover") and self.base.id == 4) and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then"
'''
#

Is this patch correct?

red flower
#

delete the quotes before the if and after then

past forge
#

or both?

maiden river
#

in the payload

red flower
#

oh payload

past forge
#

glass 4s still break 😭

red flower
#

check the lovely dumps to see if the patch worked

past forge
#

how?

red flower
#

oh and it should be scoring_hand[i].base.id

red flower
grim remnant
past forge
#

i dont have a lovely folder lmao

red flower
#

no, not your specific mod

scarlet spire
#

mods/lovely

red flower
#

that one

past forge
#

ah okay

scarlet spire
#

it just dumps all the code, but with all patches applied

red flower
left lance
#

wait as a final thing for now y'all, is there a guide/method for making the png file used for the atlas for custom jokers (aka, the files in asset folders)? I understand that there's a single png that stores all custom card sprites, but is there a template/guide for actually making that file?

past forge
#

should balatro be open?

plush cove
left lance
past forge
#

the state_event that lovely dumps is like 300 lines shorter

plush cove
past forge
left lance
#

lfg thanks y'all, really appreciate the help

grim remnant
# red flower #SMODS.find_card("yourjokerkey")

stupid question but i am so rusty with lua. how would i put that into an equation? like, if i wanted to try and find out if there are more than 1, would i use if #SMODS.find_card("yourjokerkey") > 1?

red flower
#

yes

past forge
#

im going to sleep for tonight, thank you for all the help

#

probably tomorrow ill figure out about the patches and the glass 4s

grim remnant
#

rather unsurprisingly the game did NOT like this but it honestly complained far sooner.
(yes, i am trying to make it so that, if you have multiple paulJoker, they exponentiate your mult based on how many paulJoker you have. i didn't say this idea was balanced, or smart, just that i wanted to do it)

red flower
#

you can't put if in tables
the syntax is condition and value1 or value2

#

also you need the full joker key i think so j_youmodsprefix_paulJoker

#

mult = card.ability.extra.mult ^ (#SMODS.find_card('...') > 0 and #SMODS.find_card('...') or 1) is probably what you want

grim remnant
red flower
#

yes that's correct, that was for the default prefix idk if it's still like that

grim remnant
#

also, what's the API for exponent stuff, come to think of it? if there even is one, mind you.

red flower
#

talisman

grim remnant
#

i mean like, displaying exponents as their own thing

#

not. Handling exponential numbers in score. (unless the former is also handled by talisman)

red flower
#

you mean like giving ^mult?

grim remnant
#

like ^mult, yeah. ik a few mods have cards with exponential effects (both for chips and mult) and they all use the same sorta desaturated purple color to depict that.

red flower
#

yes that's talisman too

#

the color is from cryptid i think

hardy viper
#

see talisman/big-num/notations/balatro.lua

red flower
#

i think they meant exponentiation not scientific notation

grim remnant
#

yeah, exponentiation in the actual calculation.

#

since what i'm trying to do is, on top of the +1 chips and +1 mult, it gives ^(the number of paulJoker).

#

USUALLY, this will resolve to be ^1. But it will be very funny when it doesn't thanks to smth like Showman or Invis Joker or Third Example Of Duplicate Jokers.

#

and in mods like cryptid, when an exponent is calculated, it displays that exponentiation as like, its own message (square pop-up).

red flower
#

oh the color is just the vanilla dark_edition

grim remnant
#

okay. the display on the card text works, but the calculation... doesn't. it just doesn't display an exponential mult, and it doesn't calculate one either.

        if context.joker_main then
            return {
                mult = card.ability.extra.mult,
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult ^ (#SMODS.find_card('j_cwss_paulJoker') > 0 and #SMODS.find_card('j_cwss_paulJoker') or 1),
                message = 'Paul.'
            }
        end
    end,```
red flower
#

delete the first mult

grim remnant
#

this should resolve to a LOT more than 6 mult.

#

removing the first one didn't work

red flower
#

oh wait i don't understand how much you want it to give

#

1^5 is 1

maiden river
grim remnant
#

it's meant to add 1 mult, and then after that, check how many paulJokers there are. then, exponentiate the current mult by how many there are.

#

thusly, if you play a hand of exactly 1 mult, it gets boosted to 2, then exponentiates off that.

red flower
#

so the entire current mult? you need talisman for that

grim remnant
#

ah, that makes sense. how would i go about that?

#

(adding talisman as a requirement ain't a dealbreaker just bc i use it anyways fgdsjk)

red flower
#

ah i can't really help with that, I would ask in the cryptid discord maybe

nova finch
#

how do i check the type of card that is purchased from the shop, like when a joker is bought?

worn belfry
#

Quick question, how to see modded jokers after launching game?

hushed briar
#

is there a way to have a card's sprite be larger than normal but still have the same hitbox as a normal card?

nova finch
worn belfry
#

ye i loaded my own basic joker that is just negative and cost $10

nova finch
worn belfry
#

but cant see it in collection

#

yes?

nova finch
#

check ur mods list and see if its enabled

worn belfry
#

MODS LIST

#

elaborate :>

nova finch
#

on the title screen

#

there should be a buttled that says mods

#

button*

worn belfry
#

i just used the lovely loader no modded client

nova finch
#

oh

#

idk then

worn belfry
#

what modded client do people use?

nova finch
#

steammodded

worn belfry
#

ok

nova finch
worn belfry
#

tytytytyty ❤️

plush cove
#

@worn belfry PLEASE DOWNLOAD FROM THE SOURCE
Do not download from Releases, that is a severely outdated version

weak depot
#

been scared of making joker art but i'm proud of this art i made :>

frigid flame
#

Is there anything I should know in terms of setting up a github page for a balatro mod?

cursive glade
#

What's the global variable for the final round score chip amount during context.end_of_round?

grim remnant
#

okay. having transplanted some code directly from how cryptid handles giving exponents, i at least ended up with. Whatever this is? (exponents currently set to 5 as a placeholder)

    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.mult , card.ability.extra.chips , card.ability.extra.Emult } }
    end,
    -- 1 common, 2 uncommon, 3 rare, 4 legendary.
    rarity = 1,
    atlas = 'StellationJokers',
    pos = { x = 0, y = 0 },
    cost = 1,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                chips = card.ability.extra.chips,
                mult = card.ability.extra.mult,
                message = localize{type='variable',key='a_powmult',vars={number_format(card.ability.extra.Emult)}},
                Emult_mod = card.ability.extra.Emult,
                colour = G.C.DARK_EDITION,
                message = 'Paul.'
            }
        end
    end,```
#

ig my questions are twofold:

  1. what am i doing that's causing it to fail to actually grab the number of Emult?
  2. how can i set the variable "Emult" to be equal to the amount of paulJokers?
cursive glade
#

For #1, pay attention to when it show's an error. I believe that return shows messages in order on your joker. I'm not 100% sure on that one.
For #2, you'd have to count how many times your joker's key j_[prefix]_[key] shows up in G.jokers.cards.

grim remnant
#

i mean, for 1, the issue isn't just that it's failing to grab it for the message, it's also not calculating it at all. as far as it's concerned, there is no exponent.

cursive glade
#

Ah, i have no idea, then. /shrugs

grim remnant
#

do you have any idea how to count for j_stla.paulJokers in G.jokers.cards as a variable, at least?

cursive glade
#

I do something similar for a joker that destroys other jokers. Hang on.

cursive glade
# grim remnant do you have any idea how to count for `j_stla.paulJoker`s in `G.jokers.cards` as...
function getCardKey(card)
    if type(card.key) == "string" then
        return card.key
    elseif card.config and type(card.config) == "table" then
        local center = card.config.center
        if center and type(center) == "table" and type(center.key) == "string" then
            return center.key
        end
    end
    if type(card.label) == "string" then
        return card.label
    end
    return "unknown"
end
local paulJokerCount = 0
for i = 1, #G.jokers.cards do
    local current = G.jokers.cards[i]
    if getCardKey(current) == 'j_stla_paulJoker' then paulJokerCount = paulJokerCount + 1 end
end

I don't know if there's a SMODS internal way to grab the string of the key of a target card, but I made my own function for that. Using the above code, you could push paulJokerCount back to your loc_vars or directly back to your card.ability.extra.Emult

grim remnant
#

where would i put this in the lua? :o

cursive glade
#

in your calculate

chrome prawn
#

I'm trying to make a joker similar to raised fist when the game selects the lowest ranked in your hand but for some reason this code either doesn't work or it targets every single card instead of the lowest ranked one
can someone please help me?

timid parrot
#

Might be a concurrent modification issue

chrome prawn
#

hm?

rose dragon
grim remnant
#

i do have talisman, yes.

#

talisman should also be set as a dependancy, in fact. i'm starting to wonder if it's somehow not calling for it, though???

timid parrot
#

What’s the joker supposed to do?

rose dragon
rose dragon
timid parrot
grim remnant
#

what's talisman's priority?

grim remnant
rose dragon
chrome prawn
timid parrot
#

When?

chrome prawn
#

at the final hand of the round

timid parrot
#

Before or after scoring finishes?

chrome prawn
#

after

grim remnant
#

it's 100% an issue with talisman not being recognized; having slapped the paulJokerCount to the flat mult, it works just fine

timid parrot
#

Use context.end_of_round. Find the lowest rank card. Destroy it. context.destroy_card is not what you’re looking for I believe

chrome prawn
#

no not the end of the round the final hand of the round

#

like dusk and acrobat

timid parrot
#

Yeah and if that hand loses then the joker shouldn’t trigger anyway

rose dragon
timid parrot
#

So at end of round, see if hands left is 0

modern kindle
#

is there a context for the start of a round? i dont remember what it is off of top of my head

timid parrot
#

Yes

#

Granted I’m unfamiliar with new calc so maybe some things have changed

grim remnant
#

i set priority WAY up high and WAY down low, and it did nothing? "priority": 2147483647, "priority": -2147483647, either way, Emult_mod does nothing...

#

like. am i doing this wrong somehow?

    "id": "CWS-Stellation",
    "name": "Stellation",
    "author": ["Camwoodstock"],
    "description": "An intentionally zany mod made as a companion to Cryptid. Adds a new class of jokers, and some other stuff too.",
    "prefix": "stla",
    "main_file": "Stellation.lua",
    "priority": 2147483647,
    "badge_colour": "cc00ff",
    "dependencies": [
        "Steamodded (>=1.0.0~ALPHA-1225a)",
        "Talisman (>=2.0.0)"
    ],
    "version": "0.0.1"
}```
lavish lake
#

How do I check that the blind is a boss blind at the end of round?

heady quail
#

Ok quick question, is there a way to recolor the pre-existing blinds? I see the color code in blind.lua about editing the existing colors to have more black hues, but not the info on the base blind colors themselves

#

Like in terms of these text boxes and the background colors

grim remnant
cursive glade
tall wharf
heady quail
#

Maybe just a default for the collection screen since theres no odds in place atm?

paper zealot
# heady quail Ok quick question, is there a way to recolor the pre-existing blinds? I see the ...

I'd hook get_blind_main_colour(blind) in misc_functions.lua and return a custom colour, depending on what kind of behaviour you're after
Something like:

local get_blind_main_colour_ref = get_blind_main_colour
function get_blind_main_colour(blind)
    local original_colour = get_blind_main_colour_ref(blind)
    --example changing result
    if blind == 'Big' then
        return G.C.RED
    else
        return original_colour
    end
end

heady quail
#

Huh, weird

#

I didnt change anything for that yet lol

paper zealot
#

G.P_BLINDS['bl_pillar'].boss_colour = G.C.EDITION, for example

runic pecan
#

Do I need to prevent it from pulling a blackhole or the soul?

rose dragon
#

is there a calculate function for blinds?

plush cove
#

hey all! i'm trying to figure out how to make a joker that destroys unscored cards in the first hand, and there's such limited explanation in the calculate tutorial that i'm kinda just fucking around and finding out

this is how much progress I've made so far, and it's not quite where I want it to be at. any tips?

rose dragon
lavish lake
plush cove
lavish lake
rose dragon
rose dragon
# plush cove still trying to figure this out
SMODS.Joker({
    calculate = function(self, card, context)
        if context.after then
            local safes = {}
            for s_idx = 1, #context.scoring_hand do
                local c = context.scoring_hand[s_idx]
                table.insert(safes, c.ID)
            end -- full_hand
            for c_idx = 1, #context.full_hand do
                local c = context.full_hand[c_idx]

                local found = false

                for _,id in pairs(safes) do
                    if id == c.id then
                        found = true
                        break
                    end
                end
                if not found then
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            if G.jokers then
                                c:juice_up(0.8, 0.8)
                                c:start_dissolve({ HEX("63f06b") }, nil, 1.6)
                                return true
                            end
                        end,
                    }))
                end
            end
        end
    end
})

this code is kinda bad, but it partially works
the visual of the card dissolving happens before the scoring animation finishes, so add that to the event manager EDIT: made it listen to the event queue

rose dragon
lavish lake
rose dragon
lavish lake
# rose dragon yeah, you would replace `JOKER` with the card you'd like to destroy

Weird. The joker doesn't crash the game but doesn't debuff by 0.25X

SMODS.Joker {
    key = "letter_h",
    loc_txt = {
        name = "H",
        text = {
            "{X:mult,C:white}X#1#{} Mult,",
            "loses {X:mult,C:white}X#2#{} Mult every {C:attention}Ante{}"
        }
    },
    config = { extra = { Xmult = 3, lostXmult = 0.25 } },
    rarity = 2,
    atlas = "alphabet_atlas",
    pos = { x = 1, y = 0 },
    loc_vars = function (self, info_queue, card)
        return { vars = { card.ability.extra.Xmult, card.ability.extra.lostXmult } }
    end,
    calculate = function (self, card, context)
        if context.end_of_round and context.cardarea == G.jokers then
            if G.GAME.blind.boss then
                if card.ability.extra.Xmult > 1 then
                    card.ability.extra.Xmult = card.ability.extra.Xmult - card.ability.extra.lostXmult
                else
                    G.E_MANAGER:add_event(Event({
                        func = function ()
                            self:juice_up(0.8, 0.8)
                            self:start_dissolve({ HEX("63f06b") }, nil, 1.6)
                        end
                    }))
                end
            end
        end
        if context.joker_main then
            return {
                Xmult_mod = card.ability.extra.Xmult,
                message = localize { type = "variable", key = "a_xmult", vars = { card.ability.extra.Xmult }}
            }
        end
    end
}
#

@rose dragon

lavish lake
#

probably just gotta restart the run

lavish lake
plush cove
lavish lake
#

I probably just need to switch to steamodded main

lavish lake
rose dragon
plush cove
#

i actually did have my code at a similar state earlier, but i ended up dumping it because I was running in final_scoring_step (aka the timing I want to have), but then I'd try reloading the game and it would crash and give me an error

#

hence why I sought to rework it into the new context

lavish lake
# plush cove

Yooo!!! Do you use the cryptid placeholders? Me too. 3Dcool

lavish lake
# plush cove

Also I think this joker should be rare because oh my god it seems OP for deck thinning

lavish lake
# rose dragon

What if the deck is all aces? Will it destroy random aces?

wise crown
#

I feel like it would be racist to diamonds

rose dragon
lavish lake
#

anyways im really struggling with ideas for my mod "alphabet jokers" since there's not much ideas that can come out from a single letter
can anyone think of ideas for the joker "i"?

lavish lake
rose dragon
lavish lake
runic pecan
lavish lake
#

i mean

#

sure

runic pecan
rose dragon
lavish lake
#

ok

rose dragon
lavish lake
rose dragon
runic pecan
lavish lake
#

What about J now?

plush cove
# rose dragon ```lua SMODS.Joker({ calculate = function(self, card, context) if co...

update: I cut down on a few lines by using the new "in_scoring" function that SMODS has (as part of the unscoring calcs)

        if context.after and G.GAME.current_round.hands_played == 0 and not context.blueprint then
            for c_idx = 1, #context.full_hand do
                local c = context.full_hand[c_idx]
                if not SMODS.in_scoring(c, context.scoring_hand) then
                    add_event(function()
                        if G.jokers then
                            c:juice_up(0.8, 0.8)
                            c:start_dissolve({ HEX("63f06b") }, nil, 1.6)
                            return true
                        end
                    end, nil, nil)
                end
            end
        end```
rose dragon
lavish lake
rose dragon
lavish lake
#

Uh oh, when the H joker tries to juice up, it crashes the game
Oops! The game crashed:
[SMODS alphabet_jokers "main.lua"]:217: attempt to call method 'juice_up' (a nil value)

Additional Context:
Balatro Version: 1.0.1n-FULL
Modded Version: 1.0.0~ALPHA-1415c-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.6.0
Platform: Windows
Steamodded Mods:
1: Alphabet Jokers by Runtem [ID: alphabet_jokers, Version: 1.0.0]
2: Talisman by MathIsFun_, Mathguy24, jenwalter666, cg-223 [ID: Talisman, Version: 2.0.2, Uses Lovely]
Break Infinity: omeganum
3: DebugPlus by WilsontheWolf [ID: DebugPlus, Version: 1.3.1, Uses Lovely]
Lovely Mods:

Stack Traceback

(3) LÖVE method at file 'boot.lua:352'
Local variables:
errhand = Lua function '(LÖVE Function)' (defined at line 553 of chunk [lovely debugplus.console "console.lua"])
handler = Lua function '(LÖVE Function)' (defined at line 553 of chunk [lovely debugplus.console "console.lua"])
(4) Lua field 'func' at file 'main.lua:217' (from mod with id alphabet_jokers)
Local variables:
(*temporary) = nil
(*temporary) = table: 0x3938cf70 {alerted:true, loc_vars:function: 0x3939f7b8, _saved_d_u:true, original_key:letter_h (more...)}
(*temporary) = number: 0.8
(*temporary) = number: 0.8
(*temporary) = number: 5.90174e-06
(*temporary) = string: "attempt to call method 'juice_up' (a nil value)"
(5) Lua method 'handle' at file 'engine/event.lua:99'
Local variables:
self = table: 0x3bc03cc8 {start_timer:true, timer:TOTAL, blockable:true, trigger:immediate, func:function: 0x3967cf28 (more...)}
_results = table: 0x3978dde8 {blocking:true, pause_skip:false, time_done:false, completed:false}
(6) Lua method 'update' at file 'engine/event.lua:182'
Local variables:
self = table: 0x38e4a2c0 {queue_last_processed:745.18333333298, queues:table: 0x38f4dc78, queue_dt:0.016666666666667 (more...)}
dt = number: 0.013352
forced = nil
(for generator) = C function: next
(for state) = table: 0x38f4dc78 {unlock:table: 0x38f4dd68, other:table: 0x38f4de08, tutorial:table: 0x38f4ddb8 (more...)}
(for control) = number: nan
k = string: "base"
v = table: 0x38f4dd90 {1:table: 0x391a0878, 2:table: 0x3bc03cc8, 3:table: 0x39105b18, 4:table: 0x3b5dd6c0 (more...)}
blocked = boolean: false
i = number: 2
results = table: 0x3978dde8 {blocking:true, pause_skip:false, time_done:false, completed:false}
(7) Lua upvalue 'gameUpdateRef' at file 'game.lua:2631'
Local variables:
self = table: 0x38dd9c10 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x39bcf3a8 (more...)}
dt = number: 0.013352
http_resp = nil
(8) Lua upvalue 'upd' at Steamodded file 'src/ui.lua:84'
Local variables:
self = table: 0x38dd9c10 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x39bcf3a8 (more...)}
dt = number: 0.013352
(9) Lua method 'update' at file 'main.lua:1761'
Local variables:
self = table: 0x38dd9c10 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x39bcf3a8 (more...)}
dt = number: 0.013352
(10) Lua upvalue 'oldupd' at file 'main.lua:996'
Local variables:
dt = number: 0.013352
(11) Lua field 'update' at file 'main.lua:1788'
Local variables:
dt = number: 0.013352
(12) Lua function '?' at file 'main.lua:935' (best guess)
(13) global C function 'xpcall'
(14) LÖVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 906 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(LÖVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])

rose dragon
marble flint
runic pecan
#

Which letter A looks better than others?

rose dragon
marble flint
#

first but make the T thicker

manic rune
#

T is too thin ngl

#

but if T is thicker then leftmost A looks the best

marble flint
#

you should also kern the T a pixel or two closer to the A

random sleet
#

kern on the kerb

runic pecan
#

The under-dash is for alignment

marble flint
#

yeee

#

love it

manic rune
#

scrumptious

runic pecan
#

Shout out to reiruka

manic rune
#

actually never mind, its probably meant to be closer to the black line

manic rune
#

oh dang, my bad

runic pecan
rose dragon
runic pecan
marble flint
#

not every joker needs a five page essay for an effect (and in fact most should be as simple as possible)

marble flint
#

and? onyx agate exists

rose dragon
marble flint
#

disagree

#

that cycle defines what makes the suits unique in vanilla, and onyx agate gives clubs quite a clear one

runic pecan
#

It's up to me, and I decide to keep its effect this way for now.
End of discussion.

#

But I might tune it down to Common instead.

marble flint
#

imo uncommon is correct

#

(I'm comparing to greedy joker et al and onyx agate)

manic rune
#

wikipedia incident

marble flint
#

(but also a plurality of jokers are uncommon, they make the core of the game)

sharp cliff
#

Hey, I'm trying to create a joker that effective just makes glass cards go from a 1/4 shatter chance to 1/5, but I can't seem to find a way to affect the probability of only glass cards

#

Would anyone have any knowledge on where to start?

sturdy compass
#

You'd probably need to make a lovely patch. The code for Glass Card Chance Checks are in functions/state_events.lua

sharp cliff
#

thanks! I'll give it a look

scenic loom
#

I'm making a new joker for the first time, how can I find it in game to test it works properly?

plush cove
sturdy compass
#

Get the DebugPlus mod first and foremost

#

lmfao

paper zealot
#

Anyone have any examples of mods that support both Balamod and Lovely/Steamodded?

frosty dock
#

but no one cares about or uses balamod these days

paper zealot
#

Bit of a vicious cycle, that one

scarlet spire
#

it appears that the newly implemented unscored calculation crashes the game if you beat any blind while it's enabled

plush cove
#

what were you using the unscoreds for?

frosty dock
scarlet spire
#

it doesn't matter if I use unscoring cards or not, just having the optional feature enabled causes blinds to crash the game when beaten

#

the actual unscoring calculation itself works perfectly as far as I've tested, it just also happens to crash the game when beating a blind

plush cove
#

i was using it to try and destroy unscored cards, but it crashed the game

but i thought that was mostly because of what I was doing because the game also crashed if I destroyed unscoring cards in the final_scoring_step (for some reason. even if I do the exact same thing in the after context, it doesn't crash)

frosty dock
plush cove
runic pecan
#

Should I use context.main_scoring and context.cardarea == G.play
or context.individual and context.cardarea == G.play?

paper zealot
frosty dock
#

old calc isn't being promoted to a release

#

cryptid refactor should be getting promoted to main shortly anyway

sturdy compass
#

Here's a weird thing I'm running into. SDM_0 gave me this implementation so I'm a little confused as to why the button is lining up so weirdly

maiden phoenix
#

Show your consumable's code?

sturdy compass
#

Ah fuck I just got in bed lol

#

The actual card I take it?

maiden phoenix
#

(oops) yea

sturdy compass
#

Gimme a sec I can get it rq

#

Here we are

maiden phoenix
#

There's no other modification you do on your consumable/button?

sturdy compass
#

nope, just the hooks

maiden phoenix
#

Mmh, maybe I forgot to give you something for that

#

What's the consumable type atlas size?

sturdy compass
#

71 x 95

maiden phoenix
#

If you got a github for it rn I can look at it and submit a pr to fix it, wouldn't want to ruin your sleep scheldule

sturdy compass
#

I do, but be warned it's quite the hell to trudge through. Just need to push rq

#

I appreciate ya Prayge

scarlet spire
#

crashes on function SMODS.calculate_end_of_round_effects in src/utils.lua

maiden phoenix
#

@sturdy compass Uhm I dont see the consumable type

plush cove
sturdy compass
plush cove
#

@wintry solar

maiden phoenix
#

Oh oops

sturdy compass
#

Lmao

maiden phoenix
#

Didn't know there was another branch

sturdy compass
#

All g

sturdy compass
maiden phoenix
#

Oooh I didn't know it was in its own cardarea, maybe it's what screwing it up

sturdy compass
#

Ah maybe then

#

Didn’t realize it was specific to the cardarea

maiden phoenix
#

Ok found a fix

#

Change the padding value here between -0.2 ~ -0.25 see which you prefer

sturdy compass
#

Will do. Thank ya plenty

wintry solar
wintry solar
plush cove
wintry solar
#

Use context.destroying_cards and check if the card is in scoring or not

#

@scarlet spire never mind, should be fixed now

scarlet spire
rose dragon
#

does this need rebalancing?
-# ??? is a placeholder for the suit that changes

#

-# will adjust rarity later

wintry solar
#

That’s at most a 2X for one round that then decays

#

And you have no way to check what the suit is without making it worse

crisp coral
#

you kinda have to look at the tooltip to even buy it lol

#

without the decay this is good wild card support

wintry solar
#

Yeah I don’t think it needs the end of round decay at all

plush cove
bold sleet
#

help the shit is not doing the shit

manic rune
bold sleet
#

I'll try.

crisp coral
#

pairs is fine, it's just gonna be unordered

bold sleet
#

Another question: Is there a way to check the player's chip score after everything has been calculated?

#

I need it for a joker

#

woo shit is not working i don't know anymore

manic rune
#

i have no clue why it doesnt work tbh, everything seems fine

bold sleet
#

Exactly.

#

Did SMODS got updated in the past 2 weeks or so?

#

With mod-breaking changes and stuff?

prisma loom
#

I wanna make a planet card that tracks the amount of Stone cards played during the current ante and lvls up the its hand for each scored stone card respectively
Do I need a lovely patch for this?

bold sleet
#

What the fuck am I doing wrong?

#

Shit is displaying as nil

manic rune
#

i always put loc_vars below loc_txt, idk if thats the issue

stiff locust
#

do decks have calculate function

prisma loom
# prisma loom I wanna make a planet card that tracks the amount of Stone cards played during t...

Can someone tell what's the issue here?

        return { vars = { (G.GAME and G.GAME.stonesscoredthisante or 0) } }
    end,
    use = function(self, card, area, copier)
        local scored_stones = copier or card
        --Get amount of Stone cards scored this run or set to 0 if nil
        G.GAME.stonesscoredthisante = G.GAME.stonesscoredthisante or 0

        --Add +1 to amount of stone cards scored this run
        G.GAME.stonesscoredthisante = G.GAME.stonesscoredthisante + 1

        --level up once for each stone card scored this run
        level_up_hand(scored_stones, neutronhand, nil, G.GAME.stonesscoredthisante)
        update_hand_text(
            { sound = "button", volume = 0.7, pitch = 1.1, delay = 0 },
            { mult = 0, chips = 0, handname = "", level = "" }
        )
    end,
    bulk_use = function(self, card, area, copier, number)
        local scored_stones = copier or card
        G.GAME.stonesscoredthisante = G.GAME.stonesscoredthisante or 0

        local handstolv = {}
        local neutronhand = "n/a"
        for i = 1, number do
            G.GAME.stonesscoredthisante = G.GAME.stonesscoredthisante + 1
            neutronhand = "Stone Ocean"
            handstolv[neutronhand] = (handstolv[neutronhand] or 0) + G.GAME.stonesscoredthisante
        end
        for k, v in pairs(handstolv) do
            update_hand_text(
                { sound = "button", volume = 0.7, pitch = 0.8, delay = 0.3 },
                {
                    handname = localize(k, "Stone Ocean"),
                    chips = G.GAME.hands[k].chips,
                    mult = G.GAME.hands[k].mult,
                    level = G.GAME.hands[k].level,
                }
            )
            card_eval_status_text(
                scored_stones,
                "extra",
                nil,
                nil,
                nil,
                { message = "+" .. tostring(v), colour = G.C.BLUE }
            )
            level_up_hand(scored_stones, k, nil, v)
        end
        update_hand_text(
            { sound = "button", volume = 0.7, pitch = 1.1, delay = 0 },
            { mult = 0, chips = 0, handname = "", level = "" }
        )
        G.E_MANAGER:add_event(
            Event({
                trigger = "after",
                func = function()
                    handstolv = nil
                    return true
                end,
            })
        )
    end,
}```
wintry solar
wintry solar
prisma loom
#

using cryptid's code is just 😭

wintry solar
#

What are you struggling with?

frosty dock
random sleet
#

-# reference my mod

frosty dock
#

cryptid's code isn't the easiest to follow

#

I like to recommend ortalab as reference

prisma loom
#

sure let me check other mods first

wintry solar
#

How are you tracking stone cards scored?

prisma loom
random sleet
#

no lol

prisma loom
#

Im just trying to modify it

wintry solar
#

But that’s an entirely different situation?

prisma loom
#

Im just trying everything

wintry solar
#

Because using a planet and scoring a stone card aren’t the same thing

#

Why would you think they are?

prisma loom
#

idk how Balatro functions

random sleet
#

everything is possible but everything is not the same

random sleet
#

truly

manic rune
#

someone should turn this gif into a joker ngl

prisma loom
manic rune
#

+1 chip

manic rune
prisma loom
#

what name

random sleet
#

ok so like

#

you're going to need to do some esoteric bullshit

manic rune
#

doing bullshit in your mod sounds like balatro modding

random sleet
#

and since i'm the one you're parasitically attached to at the moment i guess i have to explain how to think

#

you need to tally every time that a stone card is scored

frosty dock
#

98% of Balatro players can't think?

random sleet
#

this needs to happen even if you dont have the planet card, so you need to do this outside of the planet card itself entirely

manic rune
#

thats not wrong, most of us only know that big numbers = goog

prisma loom
wintry solar
#

Count

frosty dock
#

"count"

manic rune
#

tnuoc

prisma loom
#

Thanks!

random sleet
#

you'll need:
a global variable to serve as the counter that gets saved to the save file (anything put in G.GAME gets saved iirc)
a function that hooks card calculation in some way to count each stone card that gets scored to the above counter
another function that resets that counter at the end of a boss blind (when the ante increases)
then you can use that global variable to be the amount of times you level the hand

#

there i think that's everything
code part's up to you kid i'm not writing your mod :)

frosty dock
#

"kid"

random sleet
#

wee bab

frosty dock
random sleet
#

yes

manic rune
#

im my dad's sperm

royal ridge
manic rune
#

about to participate a race soon

prisma loom
manic rune
#

heard its life-changing or smt

royal ridge
#

everything before this was just lore

manic rune
frosty dock
#

I think I might just not exist yet

prisma loom
#

You actually really helped me with just explaining how planet cards work

manic rune
#

actually, am i gonna get banned for that diabolical statement

#

💀

frosty dock
#

if I'm not real

royal ridge
#

i'm silently judging you

manic rune
#

damn.

royal ridge
#

(well not silently any more)

frosty dock
#

steamodded is still on 0.7.1 or some shit like that

royal ridge
#

if aure didn't exist imagine the balatro modding community

#

it would be like

#

bunco

#

or something

frosty dock
#

crazy timeline

wintry solar
#

Would we be using balamod without aure

#

Or maybe that aml crap

frosty dock
#

could have been balamod if there never was a 1.0 rewrite

manic rune
#

whats the difference between balamod and steamodded anyways

random sleet
#

raw lovely

maiden phoenix
#

People would modify the exe and every mod would be a standalone balatrojoker

manic rune
#

if there wasnt any john smods, we would all be coding using ngl

frosty dock
#

I mean 0.9.8 was dominant enough but I already had plenty of influence at that point

wintry solar
#

Hmmm, should I make shop functionality for smods today? 🤔

frosty dock
#

we'd be diverging off 0.7.1 which is total infancy

maiden phoenix
#

Just wondering Eremel is the returning level up calculate still on your todo list? 🙏

frosty dock
#

by we I mean you

#

because I don't exist

wintry solar
maiden phoenix
#

I guess, as long as the UI doesn't break I'm happy with anything

wintry solar
#

Oh that bit too

maiden phoenix
#

Yea 😅

random sleet
#

aure did you see my six suits compat

frosty dock
#

ooh nice

runic pecan
#

Can I use var:lower() instead of string.lower(var)?

limpid halo
#

hmmm 60 seconds per blind is probably too much right?

#

(starts at 300 aka 5 minutes)

random sleet
#

balatro but you have 5 chess clock jokers

#

from 5 different mods

limpid halo
#

yeah~

#

look im just trying to get familiar 😭

random sleet
#

i think its funny asf

past forge
#

hello guys

minor magnet
#

bump just in case there are any teto fans who can make the teto balatro cover

minor magnet
runic pecan
#

"if your entire deck has more cards with Diamond suit than cards with non-Diamond suits."
How do I word this better?

limpid halo
#

"If more cards in deck with diamond suit than other suits combined" ?

#

maybe? idk

runic pecan
#

"than other suits combined"
I'm taking that part

#

"if Diamond cards in your entire deck are more than other suits combined"
How about this?

limpid halo
#

i'd say to do "if more Diamond cards" instead of "are more than"
idk might otherwise think to add up the values of each card or something?

runic pecan
#

"if your entire deck has more Diamond cards than other suits combined"

limpid halo
#

yeah thats good imo

runic pecan
#

Since the context would be at end_of_round, "entire" might be unnecessary.

limpid halo
#

Probably

#

I wouldn't worry too much about it, you can always change it later

frosty dock
merry raven
#
create_card = function(self, card, i)
        local rng = pseudorandom('void_pack')
        if rng > 0.9 then
            return {
                set = "Enhanced", 
                area = G.pack_cards, 
                skip_materialize = true,
                no_edition = false,
                enhancement = "m_fm_transcendent"
            }
        else
            local void_enhancements = {
                "m_fm_overshield",
                "m_fm_volatile",
                "m_fm_devour"
            }
            local selected_enhancement = void_enhancements[math.random(#void_enhancements)]
            
            return {
                set = "Enhanced", 
                area = G.pack_cards, 
                skip_materialize = true,
                no_edition = false,
                enhancement = selected_enhancement
            }
        end
    end

Trying to make a custom Booster Pack that only spawns my mod's enhancements, it works, but for some reason it doesn't grant any editions or seals whatsoever, anything I'm missing?

past forge
#

does somebody know why this patch is not working?

[manifest]
version = "1.0.0"
priority = 0

[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = "if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then"
position = 'at'
match_indent = true
payload = '''
if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and not (SMODS.find_card("j_toyr_four_leaf_clover") and scoring_hand[i].base.id == 4) and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then
'''
#

i know balatro detects it because ir gave some error that I resolve

#

but if i check the dump in the lovely folder there is nothing in there

past forge
hushed field
past forge
#

this is how the folder looks

past forge
wintry solar
#

Smods deletes almost the entirety of the default calculation code

past forge
wintry solar
#

Probably yeah

past forge
#

every time i try a new approach to do the effect that i want, it gives me a different reason to make it undoable 😭

hushed field
#

are there any good examples of the usecase for the quantum enhancements?

past forge
#

Is there a function to make cards count also as other ranks?

wintry solar
#

There isn’t

past forge
#

:(

obtuse silo
#

the idea of this joker is that it checks the cards played for unique ranks each cycle
it's only checking once for some reason

#

(haven't implemented the mult function yet though)

red flower
#

maybe I'm misreading something but I think it'll never enter the for loop

#

it will always be for x=0, 0 do

#

oh no, sorry it will do one loop

#

I think you might need a while loop for your case

frosty dock
#

you do need a while loop

obtuse silo
#

over which for loop?

frosty dock
#

also if numberarray == {} never hits

honest oyster
#

im trying to make a joker that gains 2 mult for each 2 scored but it keeps crashing when i play a 2 ("attempt to index field "other card" [a nil value]
this is my code rn (be nice pls, first time coding anything xd)

loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.mult, card.ability.extra.mult_mod } }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                mult_mod = card.ability.extra.mult,
                messege = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
            }
        end
        if context.other_card:get_id() == 2 then
        card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_mod
        return {
            messege = 'Upgraded!',
            card = card,
            mult = card.ability.extra.mult
        }
        end
    end
frosty dock
frosty dock
#

anyhow you're missing a context check before accessing context.other_card

#

in your case, if context.cardarea == G.play and context.individual and context.other_card:get_id() == 2 would be the correct check

#

also you misspelt message

#

(your current code also gives mult both when the joker triggers and when the 2 scores)

honest oyster
#

oh because of the context.joker_main ?

pulsar flower
#

does smods allow for changing a consumable set's materialize color? i don't see it documented but i figured i'd make sure before resorting to patches

weak gate
#

is there a context for when you enter the shop?

past forge
#

i mean i cold do an ENORMOUS patch to it to make effect

#

but if i can not even do the glass card patch i doubt i can do this yet

pulsar flower
#

the way rank is checked doesn't allow for the same effects as pareidolia or wild card unfortunately

past forge
#

i see

pulsar flower
#

in theory it could be changed, but then it would require a patch to every part in the game's code where a rank is retrieved and checked

past forge
#

and it would make incompatible with other mods

pulsar flower
#

yeah but you probably wouldn't be able to do it in the first place

#

bc of smods very likely patching over some of those parts

#

it's unfortunate but it is what it is

past forge
#

im currently having a even more simple problem because of that

#

i trying to patch a function in state_events but smods seems to cut like 300 lines of code in that file

pulsar flower
#

yeah i've run into the same problem before

#

it's possible to work around it, what do you have in mind

red flower
past forge
#

the glass part, ive already made a hook for the lucky card part

pulsar flower
#

ah, that's tough

past forge
#

ive wrote this patch

[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = "if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then"
position = 'at'
match_indent = true
payload = '''
if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and not (SMODS.find_card("j_toyr_four_leaf_clover") and scoring_hand[i].base.id == 4) and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then
'''
#

but that part doesnt exist in the lovely dump

pulsar flower
#

yeah, bettercalc stuff i think

pulsar flower
frosty dock
#

bettercalc stuff indeed

crisp coral
#

patching works if your prio is higher

weak gate
#

yes smods changes that part of the code @past forge

frosty dock
#

smods moves card destruction checks to its own util function

atomic edge
#

is there a mod i can take a look at that has some kind of a "quest" that is constantly checking for its conditions to be met?

frosty dock
unkempt thicket
#

what's the better calc version for this?

crisp coral
#

because you don't want to constantly check if possible

wintry solar
atomic edge
#

i wanted to make a quest type card that gets activated after you change the suits of 3 cards

limpid halo
#

Just store the progress in a extra var for the card tbh

unkempt thicket
atomic edge
limpid halo
#

neither because i realize thats not what you were asking 💀

atomic edge
#

hahahahaha

wintry solar
pulsar flower
#

this will make my two jokers that act on unscored cards very happy

limpid halo
#

dunno if that'd cover all methods to change cards like that?

past forge
fickle quail
#

How would I go about checking to see if a card is facing down? self.facing == 'back' ain't working for me.


function Card:init(...)
    
    original_card_init(self, ...)
    
    if G.GAME.selected_back ~= nil and true then
        self.sticker = get_deck_win_sticker(G.GAME.selected_back.effect.center)
    end
    
end```
wintry solar
#

For the glass effect you can just handle it in your jokers calculate function

fickle quail
wintry solar
#

You don’t need to actually change the roll, you can just force destroy them

#

Oh it’s never break

#

Nvm

crisp coral
unkempt thicket
red flower
frosty dock
#

why do I see so much card.SMODS.thing

fickle quail
wintry solar
limpid halo
#

This text feels a little awkward..

[X1] per hand and discard
Sets hands to 1 and discards to 0 for the blind
(Currently [X#])

Any ideas?

past forge
# frosty dock

so this should work?

[manifest]
version = "1.0.0"
priority = 0

[[patches]]
[patches.pattern]
target = '=[SMODS _ "src/utils.lua"]'
pattern = "if scoring_hand and SMODS.has_enhancement(card, 'm_glass') and not card.debuff and pseudorandom('glass') < G.GAME.probabilities.normal/(card.ability.name == 'Glass Card' and card.ability.extra or G.P_CENTERS.m_glass.config.extra) then"
position = 'at'
match_indent = true
payload = '''
if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and not (SMODS.find_card("j_toyr_four_leaf_clover") and scoring_hand[i].base.id == 4) and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then
'''
hushed field
past forge
#

it gives me this crash

stiff locust
crisp coral
#
When Blind is selected, sets hands to 1 and discards to 0
+X1 Mult for each hands and discards removed this Blind
(Currently X1 Mult)
#

reword if scaling

past forge
#

DONE IT

hushed field
limpid halo
#

Settling on this for now, thanks Myst and Marie

atomic edge
limpid halo
atomic edge
#

ohhh thanks so much

merry raven
#

Excellent

#

i am making a destiny 2 mod if you wanna check that out

limpid halo
merry raven
#

It's called Fatemaker you can find it in the modding forum

limpid halo
#

i'm still fighting burglar on the extra hands which is annoying

main mica
#

Where does the game save G.playing_cards to file?

dim dust
#

Is there a way to disable and enable Suits accordingly to the chosen deck ?

vapid cloak
#

how can i get started modding? i know java and python, and have never modded before

frosty dock
vapid cloak
#

thank you!

#

no way bro is john steammodded

#

where should i code it? notepad, visualcode?

dim dust
#

Visual Studio Code is friendly beginner

#

So yeah

vapid cloak
#

thanks!

main mica
#

vsc 🗣️

frosty dock
#

yeah vscode works well enough, make sure to install a lua extension

vapid cloak
#

thanks, any links to a lua extension i can get from ghere?

dim dust
vapid cloak
#

tyt

#

y

dim dust
#

LMAO

#

SORRY

#

Go to extensions

frosty dock
#

you can just search for lua in the extensions tab

dim dust
#

Search for Lua

#

And you'll get some extension

vapid cloak
#

kk

wooden nexus
#

Before I just make a new Strength, is there a way for me to modify the original strength to make it so that if it's a certain suit and rank to go to a different one.

Example: For Mahjong, can I change it so that instead of 9 -> 10, it's 9 -> 1?

frosty dock
#

I guess you could change the rank's strength effect on the fly, maybe that needs a more flexible system too

atomic edge
#

what does nominal mean here (conntext: its in the card:set_base function

frosty dock
#

base chips

wooden nexus
#

so how would i do that? A lovely patch?

woeful portal
#

Hi guys, just wondering would making an addon mod for a mod be possible/easy
like i mean using rarities, types and other things from another mod

frosty dock
normal crest
woeful portal
#

o thanks

wooden nexus
#

Also, is it possible to just disable the suit-changers? I think I could just do the banned items like in a challenge deck but thought I'd ask

#

Or like... "If Rank = Invalid" then make it impossible to use

main mica
#

Where does the game save G.playing_cards to file?

past forge
#

now im trying to figure out if there is a way to show a message on the joker card when it prevents shattering or when it triggers the lucky card

hushed field
#

that should be really doable if you've managed to already do those checks

#

just check if the joker's present and pop a card_eval_status_text()

past forge
#

card_eval_status_text() works the same as the message?

hushed field
#

no, it'll contain message

past forge
#

ive just seen it in the card.lua

#

will try it rn

hushed field
#

i have my editor closed, so I can't grab a quick example, but if you look for it, there should be good examples in the lovely dump!

past forge
#

done, it was easier than I though :)

hushed field
#

Great

#

What's the mod you're working on btw? Just joker ideas you've had, or is it themed?

past forge
#

he knew how to draw, i knew how to code, and we teamed up to make this set of jokers

limpid halo
past forge
#

i was scared to patch

#

but now, im patched

#

(i just wrote 17 lines in the .toml)

hushed field
#

It's luckily not that difficult, it just seems scary, haha

dreamy thunder
#

at some point i gotta learn lovely patches too

limpid halo
#

it's pretty easy just gotta find where to put your act of vandalism

past forge
#

true

#

the worst part about patching is that smods does patch the code before you, so youll have to work like you are working a patched code

honest oyster
# frosty dock anyhow you're missing a context check before accessing `context.other_card`
SMODS.Joker{
    key = 'twostep',
    config = { extra = { mult = 2, mult_mod = 2 } },
    loc_txt = {
        name = 'TwoStep',
        text = {
            'Gains {C:mult}+#2#{} Mult',
            'for each scored {C:attention}2{}',
            '{C:inactive}(Currently {C:mult}+#2#{C:inactive} Mult)'
        }
    },
    atlas = 'twostep',
    pos = {x = 0, y = 0},
    rarity = 2,
    cost = 6,
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.mult, card.ability.extra.mult_mod } }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } },
                mult_mod = card.ability.extra.mult
            }
        end
        if context.cardarea == G.play and context.individual and context.other_card:get_id() == 2 then
        card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_mod
        return {
            message = localize('Upgraded!'),
            colour = G.C.MULT,
            card = card
        }
        end
    end
}

i got the joker to work as i wanted it to, but how do i update the mult in the description? also the message thing doesnt work.. sorry to bother u again :s

past forge
limpid halo
past forge
#

you should put #1# in the second variable i think

honest oyster
honest oyster
#

#1# where?

#

ohhh wait instead of the #2#?

past forge
#

so #1#, #2# and so on are the order in which the variables appear in loc_vars

honest oyster
#

OHHHhh

past forge
#

so #1# would be the mult, and #2# would be the mult_mod

#
        text = {
            'Gains {C:mult}+#2#{} Mult',
            'for each scored {C:attention}2{}',
            '{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)'
        }

I think you want your description to be like this

honest oyster
#

yeah that worked thanks alot :D

past forge
#

:)

#

im also a beginner and i started this week so i like to help when i can

limpid halo
#

uhh,, adding custom calculate_joker calls shouldn't break anything using correct context checks right (i apply a custom context variable)

honest oyster
#
        if context.cardarea == G.play and context.individual and context.other_card:get_id() == 2 then
        card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_mod
        return {
            message = localize('Upgraded!'),
            colour = G.C.MULT,
            card = card
        }
```lua
#

any idea how i get the Upgraded to pop up when 2's are scored?

past forge
#

a lot of people helped me here, so dont fear to ask your dumbest questions

left lance
#

question for y'all; how are you debugging jokers/spawning them in?

limpid halo
honest oyster
past forge
past forge
past forge
past forge
#

if you press T, it would give you a menu when you can spawn any card by hovering it and pressing c

limpid halo
past forge
#

my timing on flipping, changing ranks and messages is horrendous

#

btw, how do you guys screen record? my obs just lags the shit out of my humble laptop

limpid halo
#

for short clips i use sharex

#

for the rest, obs

limpid halo
left lance
#

would this not be how to make 1/2 odds, and display it properly? This card seemingly repeats 100% of the time atm, and also displays as "1/+nil"

minor furnace
#

Gotta love attempting to create a new joker for the first time just to test to make sure I actually am able to, and getting an error when I try to hover over it in the collection. Didn't crash unitl I added the loc_vars bit, got the following error:
attempt to index field 'extra' (a nil value)

SMODS.Joker{
    key = 'Rekoj',
    loc_txt = {
        name = 'Rekoj',
        text = {
            'Gives {X:mult,C:white}#1#{} Mult'
        }
    },
    atlas = "Rekoj",
    pos = {x = 0, y = 0},
    cofig = {extra = {mult = -4}},
    loc_vars = function(self,info_queue,center)
        return {vars = {center.ability.extra.mult}}
    end
}
honest oyster
left lance
minor furnace
#

Not sure. Still crashed when I made it positive though

limpid halo
#

wait what

#

oh neat

past forge
#

no... not neat

#

you can see the card changing even before they flip

limpid halo
#

what i did to fix that is to put the actual card change before the unflip call

main mica
limpid halo
#
-- effects :3
local percent = 1.15 - (i-0.999)/(#context.scoring_hand-0.998)*0.3

scored_card:flip();
play_sound('card1', percent);
card:juice_up(0.3, 0.3);

-- Flip the card back
G.E_MANAGER:add_event(Event({
    trigger = "after",
    blockable = false,
    delay = 0.2,
    func = function()
        SMODS.change_base(scored_card, nil, new_rank)
        play_sound('card1', percent);
        scored_card:flip();
        scored_card:juice_up(0.3, 0.3);
        return true
    end
}))
return true
past forge
#
                G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.14, func = function()
                    v:set_base(G.P_CARDS[suit_prefix .. rank_suffix])
                    return true
                end}))

                local percent = 0.85 + (i-0.999)/(#G.hand.cards-0.998)*0.3 
    
                G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0, func = function()
                    v:flip() 
                    play_sound('tarot2', percent, 0.6)
                    v:juice_up(0.3, 0.3)
                    

                    G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.15, func = function()
                        v:flip() 
                        play_sound('tarot2', percent * 0.9, 0.5) 
                        return true
                    end}))

this is what i did

#

maybe is the order?

#

should the fist flip be before the set_base?

limpid halo
#

your first event where you change the base, gets called first
it waits for that to return to call the second, and then the third

#

if you remove the first G.E_MANAGER:add_event and move the v:set_base to the last G.E_MANAGER:add_event (before the v:flip) it should work

minor furnace
bold sleet
#

Hello, quick question: Is there a way to access vanilla balatro's files from a mod?

limpid halo
#

in what way? code? assets?

bold sleet
#

assets

#

Sounds.

minor furnace
#

you can access the vanilla files without mods, by unzipping the application with 7zip

bold sleet
#

I know.,

#

Without having to copy and paste balatro's sounds.

limpid halo
#

Just call them the same way the base game does?

bold sleet
#

If I try to call it by the file name the path isn't right.

limpid halo
#

What are you trying to do, play a sound?

bold sleet
#

Snce it tries to look though the mod's path instead of balatro's path.

#

Ye.

limpid halo
#

its just like this play_sound('paper1')

orchid thunder
#

I need help figuring out card areas and ui elements they make no sense

past forge
#

since the matter is on the table

#

how do i play a sound that i have in my assets>sounds folder?

orchid thunder
bold sleet
#

It looks in my mods directory instead of balatro's.

limpid halo
#

why is it trying to open paper_1.ogg instead of paper1.ogg

#

did you put the name right?

bold sleet
#

because i stupid

limpid halo
#

happens

orchid thunder
wintry solar
#

That’s also not your mod directory path and if your mod is structured that way it won’t work anyway

limpid halo
orchid thunder
#

Oh

bold sleet
#

ah it works now ig?

limpid halo
orchid thunder
#

Paper_1 is a vanilla sound?

bold sleet
#

my bad then

past forge
bold sleet
#

sorry for the inconvenience

limpid halo
orchid thunder
#

Oh

past forge
#

thanks

minor furnace
#

I love typing when I think I have the search bar open

limpid halo
#

in: 💻・modding-dev g.STATE
be like

orchid thunder
#

Card areas are stupid

past forge
#

i dont even understand cardareas

orchid thunder
orchid thunder
past forge
#

is the path isnt it?

orchid thunder
#

It's a localisation problem

past forge
#

wow

#

no thanks

orchid thunder
#

Ok get the mods

orchid thunder
#

<@&1133519078540185692>

#

Thanks

past forge
#

what were we talking about

#

ah yes

#

i dont have that in loc

#

oh wait

dreamy thunder
#

missing

#

","?

past forge
#

the problem is the message, not the sounds

orchid thunder
manic rune
#

ngl should i work on an API to simplify the additions of animated images (through sprite sheets)

orchid thunder
#

Tables are for multiple values

hushed briar
#

is there a way to apply a sprite directly on top of a joker, without it floating above like a soul sprite

past forge
hushed briar
#

well the issue is that i want the sprite to be partially off of the joker itself

#

but i still want the hitbox to be that of a normal sized card

past forge
#

how do I make the sound look in my mod folder instead of balatros?

hushed briar
#

so i either need to apply the sprite on top or figure out a way for a normal sized card to use a larger sprite

frosty dock
# past forge

Remove the assets/sounds/ from path, it's added automatically

past forge
#

its looking for a resources instead for an assets folder

frosty dock
#

that means your sound isn't registered properly

#

any other logs about it?

past forge
#

then i access it like this

frosty dock
#

oh

#

you need to add the mod prefix when referencing the sound like this