#💻・modding-dev

1 messages · Page 621 of 1

queen crescent
#

😭 how do people screw up this badly

exotic gull
#

anyways yeah i deleted it

stoic void
exotic gull
queen crescent
exotic gull
#

yh it works

stoic void
#

:P

exotic gull
#

also pretty sure that appeared only after i updated steammodded in the mod manager

queen crescent
tired kestrel
#

Can'T blame ya I had been triyng to like, make balatro shaders and well..

#

right now most of em are like %90 done but just major issues

stoic void
tired kestrel
#

wait

#

there we go

#

the only issue is trying to understand the way how Balatro handles shaders and also how to like import custom images into a shader.

#

and also try to figure out coords every single time since most coords might turn out wrong

stoic void
#

although this is my biggest concern rn

spring lantern
#

okay so uh i'm getting this error when trying to apply a shader to a card

cerulean rose
#

mod prefix

spring lantern
#

bruh

azure ember
#

i dont think its the consumable type or the consumable. i can get it to use the set, but it has an error and tries to use the default one. i think the bad code is in the booster. heres what i do to create a card

#
    local _card
    _card = {
        set = "gspectral",
        area = G.pack_cards,
        skip_materialize = true,
        soulable = false
    }
       
    return _card
    end,
queen crescent
#

hmmm, i haven't worked on any boosters yet personally

red flower
tired kestrel
red flower
umbral spire
#

is it possible to define a specific list of cards for SMODS.Back? like you can do with challenge decks

umbral spire
#

also how would you make custom deck art, like additions to the Customize Deck... selections (in Options)

slim ferry
#

SMODS.DeckSkin

bold oar
#

I can't even define a local variable properly, it seems

slim ferry
#

Probably because the local is directly in a table

#

You also do not need the self in the function

faint yacht
#

...why the ,?

slim ferry
#

Which is not where it should go

bold oar
#

progress has been made: the game now launches and VS Code has stopped yelling at me in red

umbral spire
#

how do i make a badge have a description? like how enhancements do on playing cards?

#

i know you can add a badge with

    set_badges = function(self, card, badges)
        badges[#badges + 1] = create_badge("(something)", G.C.INACTIVE, G.C.WHITE, 1.0)
    end,
bold oar
umbral spire
#

which context check is true when blind is defeated (using this in SMODS.Joker)

slim ferry
#

context.end_of_round

#

Use alongside context.main_eval for single trigger effects or context.individual for on held playing cards

umbral spire
#

at the end of round if you defeated the blind

slim ferry
#

Okay that code is the exact same

umbral spire
slim ferry
#

Yes

#

But

#

The adding card code is the same

#

Why would it be different

umbral spire
#

i meant the main check

#

the context check*

slim ferry
#

Well thats what i just said

umbral spire
#
    calculate = function(self, card, context)
        if context.end_of_round and context.main_eval then
            local card = SMODS.create_card { set = "Base", rank = 'K', area = G.discard }
            G.playing_card = (G.playing_card and G.playing_card + 1) or 1
            card.playing_card = G.playing_card
            table.insert(G.playing_cards, card)

            G.E_MANAGER:add_event(Event({
                func = function()
                    G.play:emplace(card)
                    return true
                end
            }))
            return {
                message = localize('k_plus_card'),
                colour = G.C.MONEY,
                func = function()
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            G.deck.config.card_limit = G.deck.config.card_limit + 1
                            return true
                        end
                    }))
                    draw_card(G.play, G.deck, 90, 'up')
                    SMODS.calculate_context({ playing_card_added = true, cards = { card } })
                end
            }
        end
    end
#

?

slim ferry
#

Should work

umbral spire
slim ferry
#

If not idk im on mobile i cant read this code very well

umbral spire
#

Yeah it works

real night
#

how do you change

#

the amount of jokers

#

you can select

daring fern
plush depot
#

if i were to try to retexture the regular joker using malverk what would that code look like

mental nacelle
#

if i extended an SMODS object with only a change to the inject function, would the extended object effectively just be the original with a different inject function?

mental nacelle
#

ok thanks :3

stoic void
#

crash on line 14, the loc_vars "xmult"
someone be smart please

daring fern
stoic void
#

do i do [self.key] ?

#

or do i replace it with smth

daring fern
stoic void
#

k

real night
plush depot
#

trying to retexture jokers using malverk can someone give me the code pretty please

daring fern
#

Because G.jokers wouldn't exist yet.

rugged crown
#

is there a way for decks to have certain boss blinds on antes

solid salmon
#

uhhh

#
SMODS.Joker {
    key = 'balatrue',
    loc_txt = {
        name = 'Balatrue',
        text = {'when a probability succeeds retrigger the source of it'}
    },
    rarity = 2,
    discovered = false,
    config = {extra = {repetitions = 1}},
    loc_vars = function (self,info_queue,card)
        return {vars = {card.ability.extra.repetitions}}
    end,
    calculate = function (self,card,context)
    if (context.repetition or context.retrigger_joker_check) and SMODS.post_prob and SMODS.post_prob[1] then
        local passed = false
        for _, v in ipairs(SMODS.post_prob) do
            if v.trigger_obj == context.other_card then
                passed = true
                break
            end
        end
        if passed then
            return {repetitions = 1}
        end
    end
end
}```
#

im trying to make this work for probability jokers and playing cards

#

thats it

daring fern
solid salmon
#

like this

daring fern
solid salmon
daring fern
# solid salmon
local oldevalcard = eval_card
function eval_card(card, context)
    local g, post = oldevalcard(card, context)
    G.modprefix_poster_prob = SMODS.shallow_copy(SMODS.post_prob)
    return g, post
end
solid salmon
#

how exactly am i supposed to use this now

daring fern
solid salmon
daring fern
solid salmon
daring fern
# solid salmon

No, replace all of them also replace modprefix with your mod prefix.

solid salmon
#

i did

#

oh wait actually this isnt even my joker

#

im making it for someone else

umbral spire
#

do you get a card's suit with .suit or ?

#

also is if variable ~= nil same as if variable if you explicitly set variable to nil

daring fern
daring fern
solid salmon
#

haha no

#

i dont even know why im making this for someone else

solid salmon
#

hey guys how do i display a stat

#

(like how it shows hands and discards)

stoic void
solid salmon
#

no i mean

#

like

#

as a run stat

#

yk like rounds and ante, etc.

stoic void
#

hm

#

well, thats out my league

slim ferry
#

Try looking at entropy

#

It adds an extra thing to show the entropy counter on a specific deck

fleet thorn
#

I've dug through this code so many times now and I still can't find what part I'm missing... scouring the documentation isn't helping either, though I could just be blind as a bat--

daring fern
fleet thorn
#

Isn't that at the bottom?

chrome widget
#

@manic rune @ionic cobalt @bold sleet Hey, wanted to reach out and ask if you'd be okay if I incorporated Tonsmith as a provide for my own API mod, Arrow. I'd been working on a music pack selection, but since someone else has already done a bunch of work on this front I might as well ask

weary merlin
#

decrement should also scale alongside prob_base for the tooltip but doesn't,
and the decrement part of the code isn't triggering from context.after

any fixes?

slim ferry
#

you should actually return the numerator and denominator instead of the base values in loc_vars

#

also, context.cardarea doesnt exist in context.after

weary merlin
#

yeah when i tried that before it just printed nil and nil

slim ferry
#

afaik

slim ferry
slim ferry
#

yeah thats

bold sleet
#

-# also don't ping bepis for tonsmith. I think they no longer work on it, nor they are interested in the development or state of the mod

weary merlin
#

doesn't resolve the issue of "chance decreases by x" not scaling from Oops!

#

is decrementing now though

slim ferry
#

yeah thats because it is a different variable in loc_vars

chrome widget
weary merlin
#

haha text says "ERROR" in context.after

bold sleet
#

I mean, they did work some part of the menus.

#

Anyways, do answer to my question.

weary merlin
bold sleet
#

Can I see your work, by any chance?

chrome widget
bold sleet
#

Ah

chrome widget
#

I mostly ended up doing a similar thing, drawing off Malverk

bold sleet
#

Can I see your work?

chrome widget
#

If you'd like?

bold sleet
#

It is mostly curiosity, more than anything.

#

-# tonsmith doesn't have a license, you could quite literally steal it and call it yours of you wanted. Not that I'd be happy you doing that.

#

-# or anyone, for that matter

weary merlin
#

additionally card.ability.extra.prob_base = card.ability.extra.prob_base - card.ability.extra.decrement is being triggered twice despite it only occuring once

chrome widget
#

All sound stuff is currently heavy WIP and not used anywhere

#

api > music.lua, lovely > music_pack.toml and api > hooks > ui_definitions.lua

bold sleet
#

So, does your mod mainly implement cardsauce's mechanics?

#

at least the groundwork for that?

chrome widget
#

It's the framework that Cardsauce uses, separated into its own mod. I'm currently in the process of reworking Cardsauce to properly use/provide for Arrow itself

#

Since it's gotten a ton of upgrades since then

bold sleet
#

Ah.

chrome widget
#

Keku was the one who suggested an expansion on music selection versus just a config toggle, which led me to find yours

bold sleet
#

-# so you are the one behind cardsauce?

chrome widget
#

I'm one of the directors of Cardsauce, and a lead programmer from 2.0 onward

bold sleet
#

Ah, great.

#

Now this is more akward for me.

chrome widget
#

Oh?

plush depot
#

any help

bold sleet
# chrome widget Oh?

Because I assume you are like, relatively somewhat sort of popular, or at least somewhat know in the balatro community?

Anyhow, so again, exactly what did you want to do with Tonsmith?

chrome widget
#

I wouldn't consider myself popular or known at all

#

Cardsauce is semi-popular, I am not

bold sleet
#

At least your mod gets played.

#

Unline the bs I make.

#

No matter, that's not the point of this conversation.

chrome widget
#

Anyway, as I mentioned, I want to implement tonsmith as a provided API by my own mod
per smods metadata docs:

"provides": [
    "SomeAPIMod (1.0)"
], // ! Use this if your mod is able to stand in for a different mod and fulfill dependencies on it. This allows the usage of a different ID so both mods can coexist. If you don't specify a valid version, your mod's version is used instead.
bold sleet
#

reading...

#

So that means if you have Tonsmith it will be in charge of handing the music (in this case), and if it's absent, Cardsauce will do that instead?

plush depot
chrome widget
bold sleet
#

-# can't help, I haven't touched malverk dev ever.

chrome widget
#

Otherwise, if you have tonsmith, tonsmith takes priority

chrome widget
#

Sure. I'll add a credits section for the three credited on tonsmith

bold sleet
#

Alright.

plush depot
bold sleet
#

-# *not completely probalby the part that concerns defining a soundpack is going to stay the same, we'll see.

chrome widget
#

If you want I can also improve the code and send back to you if you like

#

If I'm gonna be using it for my own purposes, might as well

bold sleet
#

Like, the crimes that go in there to make it work are just horrid.

chrome widget
#

Honestly it's probably not that bad, it doesn't look substantially odd at a glance

bold sleet
#

Trust me, it's really bad.

#

TNSMI.Pack will remain intact, probably, tho.

#

Since that part is actually decent.

#

Which is probably what should concern you the most.

wintry swallow
#

How can i test a joker i made?

bold sleet
wintry swallow
#

Thanks

bold oar
#

pretty sure my ogg file does exist

#

"crit_" is my mod's prefix

frosty rampart
#

don't put the prefix in the definition of the sound itself

#

smods automatically does that for you

bold oar
#

in play_sound or Sound.lua? removing it in the lua file didn't fix the issue

weary merlin
#

Why do lines 293 and 294 trigger as if they're context.before?

frosty rampart
#

because calculation of the whole hand completes before any animations happen. SMODS.destroy_cards and calculate function returns properly add behaviors to the event queue, but the code in those two lines you mentioned execute immediately
the easiest way to get the timing right is probably to add this to your return table on 295:

func = function()
  --move lines 293 and 294 in here
end
weary merlin
frosty rampart
#

no

weary merlin
#

even with the changes, the tooltip still updates before the text animation is played

frosty rampart
#

hm maybe i misunderstood how returning the function worked
ok undo that, you'll probably need to manually write the event. i am. not in a great headspace to explain how events work rn sorry lol

obsidian spear
#

okay now im having difficulties probably based off this, how do i change the atlas of it so it copies a different joker

red flower
#

ah that's harder

#

i have a joker that changes atlas but it has some problems

weary merlin
#

gonna try this

return {
  message = tostring( (-1 * card.ability.extra.decrement) * (numerator / card.ability.extra.prob_base) ),
  colour = G.C.FILTER,
  func = function()
    G.E_MANAGER:add_event(Event({
      func = function()
        numerator = card.ability.extra.prob_base - card.ability.extra.decrement
        card.ability.extra.prob_base = card.ability.extra.prob_base - card.ability.extra.decrement
        return true
      end
    }))
  end
}
weary merlin
bold oar
#

I might not be getting delays correctly

daring fern
obsidian spear
obsidian spear
twilit tundra
#

does rental on a playing card work by default, or do you need to do some patches to get it to actually drain money?

obsidian spear
#

or just try it

daring fern
#

But no you don't need patches to fix it either.

twilit tundra
#

oh huh

spring lantern
#

sooooo why is my stake not applying all stakes up to gold or appearing above gold stake

red flower
faint yacht
spring lantern
#

thanks

solid salmon
#

is there a way to make my cards have more than 1 config

#

well not really

#

but like

#

context

#

like if context 1 then config = mult and if context 2 then config = mult, chips

solid salmon
red flower
#

yeah

#

vars = { card.debuff and 1 or 2 } would make #1# 1 if it's debuffed and 2 if not

solid salmon
#

uh

#

im going to be more specific

#

i feel like making a thing called miracle rank

#

so for example

#

lucky cards start getting xmult after it reaches a certain rank

red flower
#

that made it less clear actually

#

do you want the description to be different?

#

or just the values?

solid salmon
#

descriptions and the actual values

#

im pretty sure descriptions alternate automatically

red flower
#

ok then the issue is the values?

solid salmon
#

well yeah

red flower
solid salmon
#

i just wanna know how to alternate em

red flower
#

idk how to be more clear without having an example from your code

solid salmon
#

i made up the system

#

if i had a variable called G.GAME.othe_miracle_rank

#

and that if its value is greater than or equal to 3

#

then it would give xmult

#

(this is for lucky)

red flower
#

vars = { G.GAME.other_miracle_rank > 3 and card.ability.xmult or card.ability.mult }?

solid salmon
#

but what about config?

red flower
#

you can save anything you want in there, you don't need to change it between levels

solid salmon
#

oh yeah right

solid salmon
#

uhhhh

#

the description and loc vars isnt changing

#

chat

#

i know how to change descriptions and stuff but like

#

i dont at the same time

twilit tundra
#

how would i make a blind disable your ability to rearrange your jokers?
want to make an amber acorn-like which shuffles your jokers and also prevents you from unshuffling them

#

i know theres the pinned sticker, but...

frosty rampart
#

i feel like i looked into this a while ago for a starspace sticker; there's a property on cards that toggles whether they can be rearranged iirc?
maybe the cardarea as a whole would also have a similar set of properties (other properties that cards can have include selectability and hoverability), but if not, you'll have to disable rearranging for all jokers when the blind activates and re-enable rearranging for all jokers when the blind is defeated/disabled

twilit tundra
#

yeah uh
how do i disable it

twilit tundra
frosty rampart
#

you'll just have to track that too, in the blind's calculate via context.card_added i think? (the documentation on that is really weird to me, it describes it as "when a non-playing card is added to the deck")
anyway you can disable dragging with card.states.drag.can = false (where "card" is the card object), and re-enable it by setting the same value back to true

#

actually yea i'm pretty sure it's context.card_added, the function for when any card/joker/etc is acquired is add_to_deck

twilit tundra
#

how do i reset a global variable on starting a new game? so it doesnt persist

daring fern
twilit tundra
#

... no... should i be doing that?
does that just do that automatically

daring fern
twilit tundra
#

got it
and would it also automatically persist after exiting and reopening balatro?

twilit tundra
#

ty

reef belfry
#

where the hell are you getting these

pastel kernel
#

how do i check for if immutable.tp = 100?

torn latch
daring fern
pastel kernel
#

ok so, all values should not be affected by cryptid.manipulate, ralsei gains random(1-10) tp by using spectral cards, filling up tp meter to 100 multiplies values of jokers adjacent to ralsei by x2.

#

that's the purpose

#

what i'm currently trying to figure out is the tp meter system

tranquil gull
#

..is there niot a context for held in hand effects

pastel kernel
#

am i doing this wrong```lua
if card.ability.immutable.tp == 100 then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
if i > 1 then
Cryptid.manipulate(joker, { value = card.ability.immutable.valueincrease })
end
if i < #G.jokers.cards then
Cryptid.manipulate(joker, { value = card.ability.immutable.valueincrease })
end
end
end
end

#

i stole it from cotton_candy

tranquil gull
#
if
    context.repetition and context.cardarea == G.hand and SMODS.has_enhancement(context.other_card, 'm_gold') then
    return {
        repetitions = 1
    }
end

nvm got it

daring fern
torn latch
#

anyone have the x1 joker sheet on hand

pastel kernel
#

Dogshit wifi

#

Uhh

#

That’s the joker’s key?

torn latch
#

what

pastel kernel
#

What’s joker?

#

OHHH

#

i should've been looking for i

twilit tundra
#

@moderator

#

how do i ping mods

#

@Moderator

#

why dont i have the ping perms

#

<@&1133519078540185692>

#

first try

torn latch
#

oop

#

urrr

#

its just for a reference as a joke

karmic creek
#

it's not don't do it again

pastel kernel
#
calculate = function(self, card, context)
  if context.using_consumeable and not context.blueprint and context.consumeable.ability.set == "Spectral" then
    local tpincrease = pseudorandom(pseudoseed("busterb_ralsei"), 1, 10)
  card.ability.immutable.tp = card.ability.immutable.tp + tpincrease
  SMODS.calculate_effect({ message = "+TP", colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card)
  if card.ability.immutable.tp == 100 then
            for i = 1, #G.jokers.cards do
                if G.jokers.cards[i] == card then
                    if i > 1 then
                        Cryptid.manipulate(i, { value = card.ability.immutable.valueincrease })
            SMODS.calculate_effect({ message = "X" ..card.ability.immutable.valueincrease, colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card)
                    end
                    if i < #G.jokers.cards then
                        Cryptid.manipulate(i, { value = card.ability.immutable.valueincrease })
            SMODS.calculate_effect({ message = "X".. card.ability.immutable.valueincrease, colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card)
                    end
                end
            end
        end
    card.ability.immutable.tp = card.ability.immutable.reset 
    SMODS.calculate_effect({ message = "TP Reset!", colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card)
    end
end
}```
pastel kernel
#

rip

#

do i just write card or

daring fern
pastel kernel
#

in place of card or i or joker or whatever is in the 1st of the parenthesis?

twilit tundra
#

does next(get_X_same(2, hand)) return nil for a 3 of a kind?????
it seems to be, is that.. the intent behind get_X_same? because that does. not seem right at all

#

oh my fucking god i ran the eval and it does

#

why.

#

ok how do i tell whether a hand contains a pair because i thought this would work but it doesn't check for a 3oak apparently :/

#

i can't use context.poker_hands because this is before hand calc, that'd make it infinite loop

pastel kernel
# daring fern `G.jokers.cards[i-1]` and `G.jokers.cards[i+1]`

does this work nowlua calculate = function(self, card, context) if context.using_consumeable and not context.blueprint and context.consumeable.ability.set == "Spectral" then local tpincrease = pseudorandom(pseudoseed("busterb_ralsei"), 1, 10) card.ability.immutable.tp = card.ability.immutable.tp + tpincrease SMODS.calculate_effect({ message = "+TP", colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card) if card.ability.immutable.tp == 100 then for i = 1, #G.jokers.cards do if G.jokers.cards[i] == card then if i > 1 then Cryptid.manipulate(G.jokers.cards[i+1], { value = card.ability.immutable.valueincrease }) SMODS.calculate_effect({ message = "X" ..card.ability.immutable.valueincrease, colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card) end if i < #G.jokers.cards then Cryptid.manipulate(G.jokers.cards[i-1], { value = card.ability.immutable.valueincrease }) SMODS.calculate_effect({ message = "X".. card.ability.immutable.valueincrease, colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card) end end end end card.ability.immutable.tp = card.ability.immutable.reset SMODS.calculate_effect({ message = "TP Reset!", colour = SMODS.Gradients["busterb_universalgradient"], instant = true}, card) end end

reef belfry
#

what could I POSSIBLY be doing wrong

frosty rampart
reef belfry
#

I just basically copied the util functions from my last mod (where it didnt have a problem)

twilit tundra
#

ty!

frosty rampart
# twilit tundra why.

the reason it has an option to not do what you're looking for is because it uses the function to gather parts._2/parts._3/etc for poker hand evaluation, and those are only exactly pairs/3oaks/etc

twilit tundra
#

ah

#

oh right because a four of a kind isnt a two pair

frosty rampart
reef belfry
#

yeah

frosty rampart
#

you need an extra () at the very end of that line

#

otherwise the game will not actually run any of the code you load

reef belfry
#

oh my god

#

i need new glasses

pastel kernel
#

THE JOKER WORKS

obsidian spear
reef belfry
#

how do people go about making something like The Fool but using custom consumable types instead

obsidian spear
#

when using a custom consumable make it set a value in G.GAME for last used ____ consumable

#

then do SMODS.add_card({key = G.GAME.variable_name})

obsidian spear
reef belfry
#

bleh

#

that seems like alot of work-ish

#

but I dont wanna patch stuff

daring fern
obsidian spear
#

@red flower I got it, but my original joker is wrong size, so uuh close enough 🤷‍♂️

reef belfry
daring fern
reef belfry
#

ah i forgot

daring fern
#

Also you should put your mod prefix on that variable.

reef belfry
#

should it be other_card then?

daring fern
reef belfry
#

I see

reef belfry
#

war is over

chrome widget
#

Feel free to peruse. it's a draft PR because the UI is currently borked as I'm reworking it

daring fern
#

bold oar
#
        if context.end_of_round and not context.repetition and context.game_over == false and not context.blueprint then
            play_sound('crit_terminalbootup')
            G.E_MANAGER:add_event(Event({
                blockable = false,
                func = function()
                card.children.center:set_sprite_pos({x = 7, y = 0})
                delay(1)
                    G.E_MANAGER:add_event(Event({
                        blockable = false,
                        func = function()
                        card.children.center:set_sprite_pos({x = 8, y = 0})
                        delay(1)
                            G.E_MANAGER:add_event(Event({
                            blockable = false,
                            func = function()
                            card.children.center:set_sprite_pos({x = 9, y = 0})
                            return true;
                            end
                        }))
                    return true;
                    end
                    }))
                return true
                end
            }))
        end
#

the game doesn't crash anymore, but the delay doesn't work

rigid solar
#

Is there some function to get all stickers on a card, or do you need to check them manually one by one?

umbral spire
#

how do you make animated sprites, I looked into the subway surfers joker in YAHIMOD, but I couldn't really find what does the anim.

ashen drift
#

probably just hooking Game:update is fine

umbral spire
#

If i have all of the soul art (for use in soul_pos in SMODS.Joker) in a different image, and the card art in a different image, how do i use 2 atlases in 1 game object??

#

like i think balatro (vanilla) does this, the soul thing is in Enhancers.png and the card is in another image.

red flower
#

check the soul in vanillaremade

umbral spire
red flower
#

no

umbral spire
#

the hidden bool?

red flower
umbral spire
red flower
#

yes

#

or just.. put them in the same atlas

umbral spire
red flower
#

i dont see the problem

umbral spire
#

🤷‍♂️

bold sleet
umbral spire
#

will this work or do i have to manually put in soul_pos

    pos = { x = 0, y = 0 },
    soul_pos = { pos.x + 10, pos.y},
#

All of my jokers soul_pos is {pos.x+10, pos.y}

#

Is there an easier way to just do that for all of em?

umbral spire
#

this doesn't work either :\

    local _pos = { x = 0, y = 0 },
    pos = _pos,
    soul_pos = { _pos.x + 10, pos.y},   
#

probably bc i don't think you can define local variable in SMODS.Joker outside of a function;-;

#

or what if i create a table at the top, like:

local positions = {
    'Joker1': {x=0,y=0},
    'Joker2': {x=1,y=0},
    ..etc..
}

and then use it someway in SMODS.Joker

#

but idk how to

umbral spire
#

or for each joker i could switch _pos to the position then use it like

local _pos

_pos = {x=0,y=0}
SMODS.Joker{
    key = 'joker1',
    pos = _pos,
    soul_pos = { _pos.x + 10, _pos.y },
}

_pos = {x=1,y=0}
SMODS.Joker{
    key = 'joker2',
    pos = _pos,
    soul_pos = { _pos.x + 10, _pos.y },
}
#

that didn't work ;-;

gilded blaze
gilded blaze
#

oh

#

you got it wrong

#

it should be

local _pos
_pos = {x=0,y=0}
SMODS.Joker{
    key = 'joker1',
    pos = _pos,
    soul_pos = { x = _pos.x + 10, y = _pos.y },
}

_pos = {x=1,y=0}
SMODS.Joker{
    key = 'joker2',
    pos = _pos,
    soul_pos = { x = _pos.x + 10, y = _pos.y },
}
#

your soul_pos was acting like an array, not a key-value table

tired kestrel
#

Welp, I figured on how you can replace backgrounds like that.

minor magnet
#

share the knowledge

primal robin
#

Is this bg with parallax?

meager canopy
#

I finished drawing and implimenting all 8 of the base lunar cards for catsino!
I felt the art was a bit too samey for each one, so to differentiate them a bit more i added the roman numerals 1 through 8 as shadows on top of the moon. I think im gonna turn the transparency of it down a bit but i think it adds a bit to the look

minor magnet
tired kestrel
wintry solar
#

Yeah you can just change the shader that anything in game uses pretty easily

tired kestrel
#

then I usually convert the shadertoy thing into a balaltro shader with the thanks of the background.fs thing and well also I had to like make custom noise shader

vale grove
#

    config = { extra = { chipamt = 1, chiptotal = 0 } },

    loc_vars = function(self, info_queue, center)
        return { vars = { center.ability.extra.chipamt, center.ability.extra.chiptotal, } }
    end,

    update = function(self, card, dt)
        if not G.jokers or #G.jokers.cards == 0 then return end

        local total_letters = 500

        for _, j in ipairs(G.jokers.cards) do
            if j ~= card then
                local desc_text = ""

                local loc_txt = j.config.center and j.config.center.loc_txt
                if loc_txt then
                    if type(loc_txt.text) == "table" then
                        for _, line in ipairs(loc_txt.text) do
                            desc_text = desc_text .. " " .. tostring(line)
                        end
                    elseif type(loc_txt.text) == "string" then
                        desc_text = loc_txt.text
                    end
                end

                if desc_text == "" then
                    desc_text = tostring(j.config.center.key or j.ability.name or "")
                end


                local _, letter_count = string.gsub(desc_text, "[A-Za-z]", "")
                total_letters = total_letters - letter_count
            end
        end

        card.ability.extra.chiptotal = total_letters * card.ability.extra.chipamt
    end,

    calculate = function(self, card, context)
        if context.joker_main then
            return {
                color = G.C.BLUE,
                message = "+" .. card.ability.extra.chiptotal,
                chip_mod = card.ability.extra.chiptotal,
            }
        end
    end,

}

i have this joker that gives -1 chip for every letter in other jokers, which works great with other modded jokers, however in base balatro jokers it doesnt work

meager canopy
#

good call!

shell timber
#

oh those look cool

zealous glen
#

I know there's some differences between the shader language love has built-in but I mean in other terms

zealous glen
twilit tundra
#

feeling like my brain's in a bit of a knot thinking about lua code so i'm gonna ask for help here

how do i generate a random rank, but not including a specific rank?
doing a while loop to just.. generate again if it rolls that would work but uh. feels very dumb

is that the best way? every other way i can think of feels kinda awkward

red flower
#

that's a fine way to do it

#

personally i dont like it so i would just make a new list with all ranks but that one

#

but they're both ok

chrome widget
#

There are cheaper hacks you can do than this, but most of them result in a non-uniform distribution

tepid eagle
chrome widget
#

You could, if you know the index of the rank, do a pseudorandom result of the total number of ranks minus the one you're removing, and then if result >= removed rank index, increment the index by one, and then just access by index

#

But only if you remove one element, else the logic gets more complicated

solid salmon
#

Hey guys how do i make a context where a global variable i made up gets changed?

chrome widget
#

You could use mod calculate

#

If it's some global that has global effects

#

Otherwise I'll need more info to advise

daring fern
tired kestrel
#

now this is looking better.

solid salmon
#

What the helly

tired kestrel
#

Well, if you didn'T know I'm testing out custom background shaders.

#

while I wait to see on how the texture offset as well as texture importing can be helped by someone as I tried my best to like get the texture coords as well as others to work

twilit tundra
#

when does the set_blind() function of a blind trigger?
had it trigger a couple times during testing but now its not triggering anymore and im not sure why?

#

oh wait does it only trigger when you enter the blind

#

is there a function that could trigger when the blind first gets placed down

for an ox-like, but without needing to have a global for that because i'm gonna want to run a whole function for when the blind appears to lock in a value and just having a global that constantly gets set with that function seems uh. like it might be too much so id prefer it only happen when the blind shows up

daring fern
twilit tundra
#

yeah, or if the blind is rerolled into it from something like director's cut

twilit tundra
#

not really something that makes sense to put into a global like all the other "specific effect determined when blind is generated"s like the Ox, so im kinda stumped as i havent seen anything like this anywhere else

frosty rampart
#

maybe Eta or Iota in entropy would have something similar? i'm not sure if that actually picks the random suit/blind beforehand or not tho

viscid talon
#

trying to code a custom challenge into my mod and although it kinda loads, it comes up with a weird error

twilit tundra
viscid talon
#

loading it in, i get this

#

then i get this error

twilit tundra
#

show the code for the challenge?

viscid talon
#

i made an src folder

#
SMODS.Challenge {
    key = 'silverhatchet',
    jokers = {
        { id = 'hatchet_hatchet', eternal = true },
        { id = 'j_certificate', eternal = true },
    },
 restrictions = {
        banned_cards = {
            { id = 'p_standard_normal_1', ids = {
                'p_standard_normal_1', 'p_standard_normal_2',
                'p_standard_normal_3', 'p_standard_normal_4',
                'p_standard_jumbo_1', 'p_standard_jumbo_2',
                'p_standard_mega_1', 'p_standard_mega_2' }
            },
        },
        banned_tags = {
            { id = 'tag_standard' },
        }
    },
}```
red flower
#

the first joker is missing the j_ prefix

viscid talon
#

i added assert(SMODS.load_file("src/challenges.lua"))() to main.lua

#

oh hm

red flower
#

also do you have a localization file

twilit tundra
#

yeah
as for it saying ERROR you need to put it in your localization file

viscid talon
#

whats that

twilit tundra
#

en_us.lua

viscid talon
#

jokerforge doesnt have challenge support, so i made this myself

#

uhh

twilit tundra
#

wait not .json, .lua

viscid talon
#

doesnt seem like it, no

twilit tundra
#

its where all the names of your stuff goes

viscid talon
#

i have boosters.lua and main.lua and hatchet.json

#

its jokerforge code

red flower
#

or use loc_txt

twilit tundra
#

oh wait does jokerforge just use loc_txt for everything thats probably it then

red flower
twilit tundra
#

how do you use loc_txt for a challenge again

viscid talon
#

yeah it uses loc_txt

twilit tundra
#

ah then yeah you gotta do that to make your challenge name show up

#

otherwise it'll just say ERROR

#

the lack of the j_ prefix is why it was crashing though, thats an easier fix

viscid talon
#

would loc_txt = { ['name'] = 'Silver Hatchet', ['text'] = { [1] = 'Hatchet and Certificate are eternal', }, ['unlock'] = { [1] = 'Unlocked by default.' } }, work

red flower
#

text and unlock wouldn't do anything afaik

twilit tundra
#

it'd already immediately show the eternal sticker anyways, dont think you need that

#

but yeah i think the name part would work? somebody else double check though im not entirely sure

red flower
#

that's what it says on the link i posted

twilit tundra
red flower
#

i think you're overthinking it

#

it's fine to run a function at the start of the ante even if the blind is not selected

#

you could do it in get_new_boss tho

twilit tundra
twilit tundra
frosty rampart
red flower
#

if you want each reroll to be different then yeah you probably need to hook get_new_boss

frosty rampart
#

yea if you go for the start-of-ante route, it'll be the same rank if someone manages to reroll so much they roll into the blind twice

twilit tundra
#

yeah, but i think thats fine

#

so what function do i hook into/otherwise add to

red flower
#

it's sad that reset_game_globals doesn't have an end of ante check

#

the ox does it at end of round when the blind was a boss blind

#

i would just use mod calculate with the new ante end context

viscid talon
#

oke it works

#

arigatou

solid salmon
#

SMODS.calculate_context(G.GAME.othe_miracle_rank_changed = true})

#

Would this work as a custom context?

red flower
#

no

solid salmon
#

Damn

red flower
#

i think you misunderstood something's answer

#

you use calculate_context to create a context but it can't detect when the value changed

#

you need to call the function each time the value changes (it's easier to make a function specifically for this)

solid salmon
#

Ok

#

Uhhh

#

So how i make the said function

twilit tundra
red flower
#

it wouldn't

#

you can use reset_game_globals for that

twilit tundra
#

is there an ante start context?

red flower
#

not afaik

frosty rampart
#

just use context.ante_change

twilit tundra
#

wouldnt that fire on taking a heiroglyph

#

dont want that

red flower
#

does that work ante 1

frosty rampart
#

oh good point

#

both of them

#

uhhh

red flower
#

i would just use reset_game_globals for start of run and ante_end for the rest

frosty rampart
#

the real solution is for smods to add an add_to_deck function to blinds

hardy viper
#

i mean you're told in context.ante_change by how much it changes

#

just check if it's positive

twilit tundra
#

still doesnt work on ante 1 though

twilit tundra
red flower
#

no

hardy viper
twilit tundra
#

is there a list of every context somewhere or something

solid salmon
#

Sooooo

#

How do i make a context or function for when a custom variable is changed

twilit tundra
#

cant find it on the wiki

frosty rampart
solid salmon
#

A function that if the said variable is changed

#

Like for lucky card

#

Id want to use this context/function to adjust its variables

daring fern
solid salmon
#

Yea i guess

red flower
solid salmon
red flower
#

so in the place where you modify the variable you replace it with a function so it also runs the context

#

and this also allows you to do other checks with that variable more easily

solid salmon
#

Ok

twilit tundra
#

where are crashlogs stored?
feeling like ive done something horribly wrong as the game is just closing itself without popping up a crashlog

twilit tundra
#

ty

#

uh
theres no crashlog the log just. ends concern

#

how am i supposed to figure out what went wrong

daring fern
obsidian spear
#

what is G.shared_soul

#

and how do i make smth like it

daring fern
twilit tundra
#

damn do i not even get a stack log to see what was looping 😔

obsidian spear
#

also i meant is it a card

#

or smth else

daring fern
willow scroll
obsidian spear
#

ok

faint yacht
#

Sometimes the game gets to a "stack overflow" reason of crash screen, otherwise, a loop like that tends to bypass the error handler and close out.

obsidian spear
#

how do i make a smth like that

daring fern
# obsidian spear how do i make a smth like that
local oldmainmenu = Game.main_menu
function Game:main_menu(change_context)
    local g = oldmainmenu(self, change_context)
    G.shared_sprite = Sprite(0, 0, 71, 95, G.ASSET_ATLAS["modprefix_atlaskey"], {x = 0, y = 0})
    return g
end
twilit tundra
#

hey question
how come prints seem to usually fire off twice?

obsidian spear
twilit tundra
viscid talon
#

boss icon not showing up

#

this is blinds.png

#

this is the code (ignore that its set to "the wall" rn, ill fix that)

#

this is main.lua

solid salmon
twilit tundra
daring fern
viscid talon
#

o oke

#

lemme fix that

daring fern
#

Also why is y 31 if there are only 3 blinds?

viscid talon
#

idk i counted from violet vessel onwards

twilit tundra
#

its based on the position in your sprite atlas, not the position of every blind ever

#

so no need to account for that

viscid talon
#

oke

#

this is what the code looks like rn

#

the new atlas

#

ruh roh

#

i also still get "small blind"

#

idk what to do

#

it seems to launch fine

#

but checking it from, the menu breaks the game

solid salmon
daring fern
viscid talon
#

oke

daring fern
viscid talon
#

owo

#

yaayy it work thankies

#

YOOOOOOO

#

IT WORKS 😭

rocky plaza
#

whats a good way to have all hearts debuffed while you own a specific joker
and if the joker gets removed in some way i want to remove the debuff from that source while still preserving the debuff if you are in the boss that debuffs hearts

red flower
rocky plaza
red flower
#

also just to get ahead of it, ante_end also needs to check for ante_change

#

or whatever the other context is called

daring fern
twilit tundra
#

is there a function for converting a numerical rank ID (e.g. 11) into a rank string (e.g 'Jack'), or vice versa?

daring fern
twilit tundra
#

i

#

so would it be SMODS.Ranks[id]?

daring fern
#

But for key to id you can do SMODS.Ranks[key].id

twilit tundra
#

okay next question is there a function for directly getting a rank string from a card

red flower
twilit tundra
#

yeah from a card

red flower
#

yeah card.base.value

twilit tundra
#

ty!

solid salmon
#

Im just feeling a little confused

viscid talon
#

ok uh

#

im trying to figure out how to downgrade a scored card by one rank

#

for a boss blind

#
        if context.individual and context.cardarea == G.play  then
            assert(SMODS.change_base(context.other_card, -1))
            return {
                message = "Downgrade!"
            }
        end
    end
}

this is the code

#

its saying that -1 isnt a rank

#

which is true

daring fern
viscid talon
#

lemme test that

#

it work!

#

thankes

red flower
plush depot
#

is there a way to make playing card skins using malverk

#

or not skins but retexture

viscid talon
#
SMODS.Blind {
    key = "h_gun",
    dollars = 5,
    mult = 2,
    pos = { x = 0, y = 2 },
    boss = { min = 1 },
    boss_colour = HEX("cbb9a3"),
    atlas = 'CustomBlinds',

    loc_txt = {
        ['name'] = 'The Gun',
        ['text'] = {
            [1] = 'A random rank is debuffed',
            [2] = 'every played hand',
        },
    },

    loc_vars = function(self, info_queue, card) 
        return {vars = {localize((G.GAME.current_round.rankvar_card or {}).rank or 'Ace', 'ranks')}}
    end,

    set_ability = function(self, card, initial)
        G.GAME.current_round.rankvar_card = { rank = 'Ace', id = 14 }
    end,

    calculate = function(self, card, context)
        if context.individual and context.cardarea == G.play  then
            if context.other_card:get_id() == G.GAME.current_round.rankvar_card.id then
                return {
                     debuff = true
                }
            end
        end
        if context.cardarea == G.jokers and context.joker_main  then
            if G.playing_cards then
                local valid_rankvar_cards = {}
                for _, v in ipairs(G.playing_cards) do
                    if not SMODS.has_no_rank(v) then
                        valid_rankvar_cards[#valid_rankvar_cards + 1] = v
                    end
                end
                if valid_rankvar_cards[1] then
                    local rankvar_card = pseudorandom_element(valid_rankvar_cards, pseudoseed('rankvar' .. G.GAME.round_resets.ante))
                    G.GAME.current_round.rankvar_card.rank = rankvar_card.base.value
                    G.GAME.current_round.rankvar_card.id = rankvar_card.base.id
                end
            end
        end
    end
}```

it not worky
#

it launches, but the random rank doesnt get debuffed per hand

red flower
red flower
viscid talon
#

oe

#

how to fix

sharp arch
#

does anyone know how to change the amount of joker slots a joker takes up?

daring fern
sharp arch
daring fern
solid salmon
red flower
#

i don't know what you mean by top part

#

the function would be used like mod_variable(2)
this increments it by 2

#

of course don't just call it mod_variable because that's too generic

#

after you set that up you can use context.variable_mod in any calculate function

sharp arch
#

how do i make this not trigger per animation
like its funny but i need help

    card.ability.extra_slots_used = card.ability.extra_slots_used - 0.5
if context.repetition and context.cardarea == G.play and not context.other_card:is_face() and SMODS.pseudorandom_probability(card, 'jabong_sock', 1, card.ability.extra.odds) then
return {
repetitions = card.ability.extra.repetitions,
message = "Ag",
}
end
end
}```
frosty rampart
#

don't set it in the calculate function at all
you should do it in the config table, i.e.

config = {
  extra_slots_used = -0.5,
  extra = {
    -- whatever other variables the joker has
  }
},
sharp arch
#

that works actually

meager canopy
#

Straight boostin it

sharp arch
#

key = card.ability.negative and "j_jabong_jimbyramid_alt" or nil
is fine for my config, right?

wintry solar
#

no

sharp arch
#

so the card.ability.negative is fucked then ok got it

#

also how would I change the language of one specific joker
like just the joker in specific

red flower
#

also it's card.edition and card.edition.negative

sharp arch
sharp arch
daring fern
sharp arch
#

oh

tranquil cypress
#

do enhancements have an equivalent to on_remove for when the enhancement is no longer on the card?

solid salmon
#

@red flower

#

am i doing this right

daring fern
solid salmon
#

but the variable is called G.GAME.othe_miracle_rank

solid salmon
#

for some unknown reason creating the thing that modifies the miracle rank closes the game

daring fern
solid salmon
#

ok

#

lemme show you the code that i changed it to

#

do you know why this may close the game?

red flower
#

you are calling the function in calculate which calls the context function which calls calculate which calls the context function etc etc

solid salmon
#

so stack overflow

red flower
#

yes

solid salmon
#

which pic

red flower
#

1

#

you don't want to use that with no context check

solid salmon
#

ok

red flower
#

even without the overflow it will just increase the rank all the time

kindred zephyr
#

how do i have a joker show multiple text boxes in sequence

frosty rampart
#

wherever you normally have their localization, just do this

text = {
  {
    "Text box 1",
    "goes here"
  },
  {
    "Text box 2",
    "goes here"
  }
}

so instead of text just being a table of strings, it's a table of tables of strings

kindred zephyr
#

ah i see

#

tysm

solid salmon
umbral zodiac
red flower
solid salmon
#

ok

kindred zephyr
#

i meant like when the joker is being triggered

solid salmon
red flower
kindred zephyr
#

i see

red flower
solid salmon
red flower
#

what's the part where you use the function

solid salmon
#

right below the calculate function

red flower
solid salmon
#

you mean anaglyph joker?

kindred zephyr
red flower
solid salmon
#

this one?

red flower
#

<@&1133519078540185692>

solid salmon
#

<@&1133519078540185692>

red flower
kindred zephyr
#

ty mods

solid salmon
red flower
#

huh weird then

plush depot
red flower
#

i think it's crashing with the blinds

#

does malverk have blind support

plush depot
#

im pretty sure

#

lemme take out the code rq

#

wow it is the blinds

wintry solar
#

it does have blind support

plush depot
#

ohhhhh i have to add the frames = 21

wintry solar
#

yeah it needs the frame count

plush depot
#

does malverk have edition support

granite jay
#

Anyone know how to change the textures of Small and Big blind specifically for a mod?

rocky plaza
#

Is it possible to rotate the orientation of a UI node through a config table?

near coral
#

For edition visuals do you have to write lines of code like you would with a mechanic or is simpler

rocky plaza
#

I'm not too familiar with making shaders so I can't help you with actually learning the shader language

near coral
#

Do you have to know how to code to do it

red flower
#

i know how to code and i dont know how to do it

rocky plaza
#

Also
Making cool shaders will most likely involve some intensive math

near coral
#

The only ways to make cool shit is to do something I despise

rocky plaza
#

Since a shader essentially can calculate the color of a pixel based off its position and external variables like time if so desired

near coral
#

Everything in high school ruined math for me

#

I'll probably just draw a mockup and hope someone who knows how to do it can put it in

rocky plaza
#

Or want to make

near coral
#

It's basically putting plasma's ability into an edition

#

Or some variation of that

rocky plaza
#

Hmm
So a plasma-like effect

#

I don't think the math will get too terribly bad

#

3d shader math makes me want to end myself

near coral
#

This is the design mockup

#

Idk if it's not translucent enough

rocky plaza
#

OK no that's basically as easy as shaders get

#

At least in terms of math complexity

near coral
#

At least I know it'll be easy for whoever hypothetically codes it in

rocky plaza
#

Give me 2 business days and I will figure out how to make functional balatro shaders

kindred zephyr
#

uhh

#

somethings wrong with my joker

SMODS.Joker {
    key = 'spinner',
    loc_txt = {
        name = 'Spinner',
        text = {
            "Retrigger all {V:1}#1#{} cards,",
            "suit changes every round"
        }
    },
    config = {repetitions = 1},
    loc_vars = function(self, info_queue, card)
        return {
            localize(G.GAME.current_round.spinner_card.suit, 'suits_singular'),
            colours = { G.C.SUITS[G.GAME.current_round.spinner_card.suit] }
        }
    end,
    blueprint_compat = true,
    perishable_compat = false,
    eternal_compat = true,
    rarity = 2,
    atlas = 'placeholders',
    pos = { x = 1, y = 0 },
    cost = 5,
    calculate = function(self, card, context)
        if context.cardarea == G.play and context.repetition and not context.repetition_only then
            if not context.other_card.debuff and context.other_card:is_suit(G.GAME.current_round.spinner_card.suit) then
                return {
                    message = 'Again!',
                    repetitions = card.ability.extra.repetitions,
                    card = context.other_card
                }
            end
        end
    end
}
daring fern
kindred zephyr
#

?

daring fern
# kindred zephyr ?
return {vars = {
    localize(G.GAME.current_round.spinner_card.suit, 'suits_singular'),
    colours = { G.C.SUITS[G.GAME.current_round.spinner_card.suit] }
}}
kindred zephyr
#

OHH

#

i see now tyvm

vivid eagle
#

is it possible to make a deckskin mod that has compatibility with modded suits and ranks?

kindred zephyr
#

not sure

vivid eagle
#

specifically, i'm trying to make one for paperback

#

hmm

twilit tundra
#

psure you can, i know theautumncircus comes with a deckskin for grab bag's eyes

#

huh its.. really that simple

#

suit = "gb_Eyes"
all you gotta do is use the id of the modded suit (plus the mod prefix)

#

if you're getting errors or its not working, probably you're just forgetting the mod prefix or smth

vivid eagle
#

oo thanks!
i'll look at this and try to figure things out

cloud gorge
twilit tundra
#

she's asking about deck skins, not a deck itself

cloud gorge
#

ahh yea then that, forget deckskins is a thing

twilit tundra
vivid eagle
#

that's exactly what im going to do actually xD

spiral pivot
#

Dont know what is wrong with it

twilit tundra
#

okay. really stupid question here but whats the function for checking if a card.. is a joker

tepid crow
daring fern
spiral pivot
#

this is it

tepid crow
#

It's probably one of those mods. When does it crash?

spiral pivot
#

it starts when its only steamodded and regals

spiral pivot
#

I will try thanks Lars, it is working now but no talisman I guess

bold gyro
#

hey y'all, trying to do ui stuff but i think i've missed something and i need a sanity check. why is my ui not being drawn? "wow" is printed when i call suika_bg().

function G.UIDEF.suikamain()
  print("wow")
  local t = { -- example from the ui guide
      {n = G.UIT.ROOT, config = {r = 0.1, minw = 8, minh = 6, align = "tm", padding = 0.2, colour = G.C.BLACK}, nodes = {
        {n = G.UIT.C, config = {minw=4, minh=4, colour = G.C.MONEY, padding = 0.15}, nodes = {
          {n = G.UIT.R, config = {minw=2, minh=2, colour = G.C.RED, padding = 0.15}, nodes = {
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}},
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}}
          }},
          
          {n = G.UIT.R, config = {minw=2, minh=1, colour = G.C.RED, padding = 0.15}, nodes = {
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}},
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}}
          }}
        }}
      }}
  }
  return t
end

suika_menu_node = {n=G.UIT.O, config={object = suika_menu}}

function suika_bg()
  local suika_menu = UIBox{
      definition = G.UIDEF.suikamain(),
      config = {align='cm', offset = {x=G.ROOM.T.x,y=0},major = G.ROOM_ATTACH, bond = 'Weak'}
  }
  return suika_menu
end
wind steppe
#

takes a function not the output

bold gyro
#

oh my god

#

thank you very much 🙏

tired kestrel
bold gyro
#

are there any mods that have a good example of adding a completely new ui feature, that acts independently of other UI? (eg. DebugPlus's debug menu, HotPot ads)

bold gyro
#

I'm having some trouble understanding what this part of the UI page on the wiki means. I want to create a new UI feature, but how exactly would I place it in an object node? I get the crash message "engine/ui.lua:242: attempt to index local node (a function value)" when i attempt to eval the suika_bg() function below:

function G.UIDEF.suikamain()
  local t = { -- example from the ui guide
      {n = G.UIT.ROOT, config = {r = 0.1, minw = 8, minh = 6, align = "tm", padding = 0.2, colour = G.C.BLACK}, nodes = {
        {n = G.UIT.C, config = {minw=4, minh=4, colour = G.C.MONEY, padding = 0.15}, nodes = {
          {n = G.UIT.R, config = {minw=2, minh=2, colour = G.C.RED, padding = 0.15}, nodes = {
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}},
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}}
          }},
          
          {n = G.UIT.R, config = {minw=2, minh=1, colour = G.C.RED, padding = 0.15}, nodes = {
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}},
            {n = G.UIT.C, config = {minw=1, minh=1, colour = G.C.BLUE, padding = 0.15}}
          }}
        }}
      }}
  }
  return t
end

function suika_bg()
  menu = UIBox{
      definition = G.UIDEF.suikamain,
      config = {align='tmi', offset = {x=0,y=0},major = G.ROOM_ATTACH, bond = 'Weak'}
  }
  return menu
end
chrome widget
#

A UIBox requires a full UI definition tree, so you need to call your UI def function to feed the return. It's trying to create a UI tree without that. But beside that, I believe you have an extra wrapping parenthesis. The root node should be the outermost table

#

@bold gyro

wintry solar
#

People who don’t understand UI trying to help with UI smh, thanks for the good explanation winter 👍

tired kestrel
#

Indeed. although I thought want to ask WIN'ter about the texture issue I've been dealing with recently not sure if WIN'ter has an answer to this but yeah. 'Im also still learning about shaders and right now there is soemthing wrong when I try to make a shader that involves with the texture.

tired kestrel
chrome widget
#

Just winter is fine, the N' is a gag on another user

#

What's the texture issue

tired kestrel
#

Well one I have made a jpeg shader which it did work. however the texture atlas acted weird as it wasn't rendering exactly what I thought dispite it did only work for the 1st which is a regular joker.
And the other one I had tried to make the deltarune profency with custom textures but it doesn't render the texture but instead it only displays the mixed color version of it. (the 1st two are the issues while the other two are what they supposed to be)

#

also another thing is it possible for the prophency one to render outside of it's card borders and such?

#

if you want I can provide the shader code so you can have a look.

#

the 1st one is supposed to be a jpeg compressed and the other one is obvious to be deltarurne prophency panels

chrome widget
#

Yes and no. You can manipulate the overall rect of the shader via the vertex shader which can extend beyond the borders of the original card, but I'd you want something that looks more pixel-perfect, you're better off just doing pixel shader effects

#

The simplest explanation for the first one is probably just that you're using incorrect UV coordinates or not transforming them correctly

#

Show me your shader code

tired kestrel
chrome widget
#

Fwiw you can remove the compressed extern and the dummy block with it

#

The default Balatro shader format won't crash if you don't have the filename extern, it only sends the extern if it exists afaik
Source: have made multiple shaders that don't use it

tired kestrel
#

I see.

#

oh one more thing:

local depth_blue_path = (TestMod3.path 
        .."assets/images/depths_blue.png")
local depth_blue_data = assert(NFS.newFileData(depth_blue_path),("Epic fail"))
TestMod3.depthblueimagedata = assert(love.image.newImageData(depth_blue_data),("Epic fail 2"))
TestMod3.depthbluepng = assert(love.graphics.newImage(TestMod3.depthblueimagedata),("Epic fail 3"))
TestMod3.depth_blue_width, TestMod3.depth_blue_height = TestMod3.depthblueimagedata:getDimensions()


local depth_dark_path = (TestMod3.path 
        .."assets/images/depths_darker.png")
local depth_dark_data = assert(NFS.newFileData(depth_dark_path),("Epic fail"))
TestMod3.depthdarkimagedata = assert(love.image.newImageData(depth_dark_data),("Epic fail 2"))
TestMod3.depthdarkpng = assert(love.graphics.newImage(TestMod3.depthdarkimagedata),("Epic fail 3"))
TestMod3.depth_dark_width, TestMod3.depth_dark_height = TestMod3.depthdarkimagedata:getDimensions()

SMODS.Shader({ key = 'compressed', path = 'compressed.fs' })
SMODS.Shader({
key = 'prophecy',
path = 'prophecy.fs',
send_vars = function(sprite, card)
        return {
        textureFront = TestMod3.depthbluepng, 
        textureBack = TestMod3.depthdarkpng,
        textureFrontSizeWidth = TestMod3.depth_blue_width,
        textureFrontSizeHeight = TestMod3.depth_blue_height,
        textureBackSizeWidth = TestMod3.depth_dark_width,
        textureBackSizeHeight = TestMod3.depth_dark_height,
        useLinearRGBA = true
        }
    end,
})

I made this image importing thing so it can load the texture for the prophecy one.

#

and here are the textures I made for the prophency shader edition thing:

#

but I will remove that dummy block

chrome widget
#

Okay so I probably do not have the ability to properly debug the jpeg shader given the time and me being on my phone, but my first question on the prophecy shader is that there's a call to clamp a value at the end between 1 and 1, which would result in the final color alpha always being 1

#

I assume that's unintended

tired kestrel
chrome widget
#

Did you also remove the extern declaration for it at the top of the file?

tired kestrel
#

plus I don't think "compressed" is used anywhere but that dummy thing is what makes the shader usable if I recall correctly

#

dunno why it's the cause of that

#

or even when I add back it wouldn't find any workflow of the compressed

chrome widget
#

That's what I mean, I've used shaders before that specifically avoid this unused variable

tired kestrel
tired kestrel
#

than being unused

chrome widget
#

Just put the block back for now I suppose. I don't have access to vanilla code right now to look at draw_shader

pastel kernel
#

How do I do this

chrome widget
#

Other than that I unfortunately did not expect the shaders to be this complicated which is not something I think I'm in a position to look into right now, since I'd probably need to implement the code myself to give you a better look

#

Sorry orz

chrome widget
#

Basically both of these are def solvable problems, and I'm probably the person to ask, I'm just in bed in my phone at 2 AM so my faculties are limited

#

The thing that strikes me about the jpeg shader is that the simulated compression effect is for Jimbo joker, but slid to the left

reef belfry
chrome widget
#

Which tells me that there's some scaling issue with how you're using the UV coordinates, since that would be expected if you're not scaling it correctly to the full atlas width for whatever pixels you're finding with the texel function

tired kestrel
#

there are few examples I found on shadertoy that had managed to make the jpeg compresison shaders

#

Also even though I tried my very best to port the one that wold actually worked and it did work besides that scaling issue that I never encountered before

chrome widget
#

Off the top of my head, I'd look at how you're using those width and height mod values since the purpose of those values is to get you a UV between 0 and 1, but for larger atlases, your usable UV coordinates are in some smaller range. I used a similar thing specifically to match pixels for shaders of varying atlases to textures I was passing in that were exactly one unit in size

tired kestrel
#

cause last time when I try to port a shadertoy jpeg shader into the gmae somehow it doesn't render.

wintry solar
#

I think the problem is that you’re just ripping shader toy shaders so you don’t know what the code does

tired kestrel
#

MAybe it is a problem but right now I am still learning about trying to port shaders into other ways since apperently when I also saw the tutorial of shadertoy shaders it might be a first step to understand the kind of shaders to work around.

tired kestrel
pseudo furnace
#

Is it possible to detect the highest possible hand type in a given hand, or do I just have to iteratr through all possibilities? If so, how would I have to iterate it?

slim ferry
#

G.FUNCS.get_poker_hand_info(cards) gets a bunch stuff with the highest ranked hand type in those cards being one of them

surreal geode
#

hello everyone. im trying to reskin the backgrounds of the default boss blinds, how can i do?

pastel kernel
#

how do i check for if a poker hand is lv. 20

daring fern
pastel kernel
#

i think i can just replace modprefix_key with "high card"

daring fern
pastel kernel
#

oh yeah, how do i make sure this only works when a certain mod is enabled

#
next(SMODS.find_mod("starspace")) then```?
pseudo furnace
pseudo furnace
#

Is it not the third point here? Or am I mistaken?

daring fern
pseudo furnace
solid salmon
#

@red flower good news the context works, bad news is that it only affects an individual lucky card

red flower
solid salmon
#

I think i should just give them global variables

red flower
#

then the context logic is wrong

#

it's literally just a basic multiplication

solid salmon
#

..what?

#

(Sorry i just woke up)

red flower
# solid salmon ..what?

instead of doing mult = card.ability.extra.mult just do something like mult = card.ability.extra.mult * G.GAME.variable

#

or mult + number * variable

solid salmon
#

Oh wait

#

You mean for the variables or the calculation?

red flower
#

in the return values

solid salmon
#

Oh no i didnt

#

But even if i did

#

What about the description?

#

Also also

#

Im trying to make it have an alternate description once the variable reaches 3+

red flower
solid salmon
#

Uhhh

red flower
solid salmon
#

Dam

solid salmon
red flower
#

can i see the current loc_vars

solid salmon
#

Ok

slim ferry
#

Why would your laptop be set on fire

solid salmon
solid salmon
#

...

red flower
#

ok you see how it says card.ability.extra.mult at the bottom?
instead of that you do card.ability.extra.mult * G.GAME.variable

solid salmon
#

dam this image blurry

final jewel
#

I dont understand why its always triggering the thing even if there is a 1 in 2 chance

solid salmon
red flower
#

(/j)

red flower
#

/j

solid salmon
#

o wait

#

i gotta do 2*(G.GAME.var or 0)

#

yep it works

#

yippee

mystic salmon
#

how can I change the sell values? I want this one to add its sell value to all other owned jokers

red flower
solid salmon
#

(this is the said code)

#

OH

#

nevermind guys im an idiot

#

i found it

mystic salmon
charred widget
#

Hi friends! I have a bit of a complicated ability this time around, but I'm hoping we'll be able to make it work.

#

The idea I have for Zamazenta is that it detects the least played poker hand and levels it up. However, since there can be (and often are) multiple hands that have been played the least, I want it to level up all that apply. How would I make this work?

solid salmon
#

guys what am i doing wrong, the deck aint alting

#

*enhancement

mystic salmon
slim ferry
#

Because

#

You put loc_vars arguments and not calculate arguments

slim ferry
#

Not you

mystic salmon
solid salmon
#

yay it works

#

(its pink because i made a gradient of green and miracle sonic pink)

mystic salmon
solid salmon
#

also i changed it again

#

(just found out gradients work for x colors)

#

now to rework the rest of the vanilla

rigid solar
#

Coming once again to ask if there's an easy way to get all stickers on a joker
otherwise i'll just check for the stickers i care about manually lol

rigid solar
#

like some sort of Card:get_stickers() that'd return a table with all the stickers on the card

#

perish, rental etc

solid salmon
#

i dont wanna burst your bubble

#

but i dunno

#

welp

#

its time to rework the wheel of fortune

#

and make it trigger thrice

mystic salmon
wintry solar
#

I should maybe make a Card:get_stickers() at some point

solid salmon
#

trigger twice

#

at best

#

and the odds at best is 1 in 3

mystic salmon
#

oh

#

nice

#

👍

#

you make some kind of a vanilla remake?

mystic salmon
solid salmon
#

For example

#

Space joker could now have a 1 in 20 chance to level up all hands

#

Or hallucination can now have a 1 in 2 chance to either create a tarot or a spectral

#

Im also going to apply this system to my stuff as well

final jewel
#

how do I create a card from a pool ?

#

SMODS.add_card({pools = 'rare_food_pool', edition = 'e_negative'})

red flower
#

set instead of pools

solid salmon
#

what am i doing wrong

wise jetty
#

hello, my game keeps crashing with steam modded and tailsman loaded, nothing else, game runs perfect without them

bold sleet
#

Hello. Quick question. Is there a way to tell if the player is in a blind or not?

wise jetty
#

in what?

#

mutliplayer?

bold sleet
#

No.

#

Just vanilla balatro

wise jetty
#

are you playing or what?

hardy viper
#

check G.STATE

bold sleet
#

k

red flower
bold sleet
#

ty

hardy viper
#

cursed

solid salmon
wise jetty
red flower
tired kestrel
#

decided to try to mofidy the splash screen with a new shader code and....

#

it didn't show the shader I want it to show

umbral spire
tired kestrel
#

who exactly is making this?

red flower
wind steppe
umbral spire
#

i thought like

#

;-;

#

mb

hardy viper
#

🍅