#💻・modding-dev

1 messages · Page 670 of 1

dapper sun
#

?

#

i may just

#

look at how debugplus does it

#

oh that isn't a hook

#

at least not a love.textinput one

#

local input = ui.TextInput.new(0)

local orig_textinput
local function textinput(t)
    if not consoleOpen then
        if orig_textinput then
            orig_textinput(t)
        end -- That way if another mod uses this, I don't clobber it's implementation
        return
    end
    input:textinput(t)
end```
frosty rampart
#

yea i tried looking at debugplus too, it's a bit strange

dapper sun
#

yea

#

hmmm

#

is it possible it can't hook bc there's no prior love.textinput function?

vague ravine
#

yes

frosty rampart
slim ferry
#

you should probably hook something like SMODS.injectItems and do it in there then

#

i doubt the event manager is initialized that early in loading

frosty rampart
#

true

vague ravine
#

what are mods i should install?

#

or where can i browse for them?

slim ferry
#

is where most mods are

dapper sun
slim ferry
#

i dont think its documented anywhere

#

but its usually hooked if something needs to be done later in loading

dapper sun
#

so what would the hook look like,,?

slim ferry
#
local inj = SMODS.injectItems
function SMODS.injectItems(...)
    inj(...)
    --hook love.textinput here
end
dapper sun
#

ok

#

it still doesn't like that

slim ferry
#

huh

#

try just printing love.textinput at various points in loading ig?

dapper sun
#

should prob also mention,, it only happens when i click a key, not at startup

slim ferry
#

oh

frosty rampart
#

well yea that makes sense
the game doesn't actually try to call the nil value until love.textinput is run

dapper sun
#

so yea

#

it does this even in injectItems

#

another weird thing

#

it's definitely a problem with the local variable since the traceback shows that it is running love.textinput correctly otherwise

rigid solar
frosty rampart
#

bmm stinky
you can use the "ingame mod manager" instead

dapper sun
#

and a print shows that love.textinput is nil when the hook is made

#

i may just make a slight hacky solution and if there's nil then it makes an empty love.textinput before the hook

frosty rampart
#

worth a try

dapper sun
#

okay that worked

rigid solar
#

works well for me

slim ferry
#

most mods arent on there

#

because its hell for devs

#

also it downloads a wierd useless patch folder for no reason

#

which has only caused issues in the past

rigid solar
#

how is it hell for devs
i've submitted 2 mods to it it's very simple

frosty rampart
#

it's frequently caused issues while updating steamodded, it installs its own useless "BMM-Compat" mod that does nothing smods doesn't already do, and yea it's missing a lot of mods as per eris

slim ferry
#

instead of just a proper upload form or something

hidden aspen
red flower
#

my biggest problem is the install issues

slim ferry
#

and also very slow

#

and yeah it also frequently has issues installing mods

red flower
#

to me the initial upload is not the unfriendly part but wanting to update afterwards

#

or even requesting removal

#

like yes, you dont have to upload mod updates manually but if you want to change the description you need to pr again afaik

rigid solar
#

you do yeah

slim ferry
#

that is very annoying

#

for no real reason

umbral zodiac
#

i also think it was lazy of the devs of it to supposedly never consider actual dependency management when that is very feasible

rigid solar
#

so what's imm then, because when you google it all you get is bmm

slim ferry
umbral zodiac
#

instead its just Does your mod need steamodded or talisman
like great what if my mod needs something else

slim ferry
#

its a mod manager thats ingame

wintry solar
#

the fact that bmm has a webpage to upload mods that nobody knows about speaks volumes

slim ferry
#

also yeah webpage isnt ever mentioned anywhere as far as i can tell

#

not on the bmi repo or the bmm website

#

or bmm repo

umbral zodiac
#

im so geeked i have to implement brainfuck in lua

#

im not going to copy from elsewhere that would be boring

rigid solar
#

looking at imm
isn't it based on bmi, making it basically the same as bmm

umbral zodiac
#

it pulls from a ton of different places

slim ferry
#

it also uses thunderstore (and i think photon?)

umbral zodiac
#

not just the BMI

slim ferry
#

photon is also great

umbral zodiac
#

point is if your mod can be managed elsewhere it can be managed via IMM basically

wintry solar
#

the imm dev is also an active member of the community and easily contactable

red flower
umbral zodiac
#

i don't know what the fuck i expected

red flower
#

while true do end indeed

umbral zodiac
#

i was originally going to do something else but i think today is Brainfuck Joker Day

slim ferry
#

try wrapping it in another pcall perhaps balatrojoker

rigid solar
#

one thing i like about bmm is being able to boot the game without starting steam lol, kinda minor but i like it

faint yacht
#

...you can just make a shortcut to the executable yourself and do it that way too.

slim ferry
#

kid named shortcut to the balatro.exe file

#

yeah

umbral zodiac
#

you probably deserve it anyway

reef bobcat
#

ok so

#

i wanna do an effect

#

that chooses 2 card ranks randomly every round

#

like mail in rebate

#

is that a thing i can do?

rigid solar
reef bobcat
#

no i have that code but

#

i tried copying it

#

seems not to be working

slim ferry
reef bobcat
#

ugh im still stuck D:

#
     loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.dollars, localize(SMODS.current_mod.reset_game_globals(run_start)) } }
    end,
    calculate = function(self, card, context)
        if context.discard and not context.other_card.debuff and
            context.other_card:get_id() == SMODS.current_mod.reset_game_globals(run_start) then
            G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.dollars
            return {
                dollars = card.ability.extra.dollars,
                func = function() -- This is for timing purposes, it runs after the dollar manipulation
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            G.GAME.dollar_buffer = 0
                            return true
                        end
                    }))
                end
            }
        end
    end
}```
#

so this is just the mail in rebate code

#

but i replaced the stuff that specifically said mail in rebate

#

just doing this as a start

#

it's causing the game to crash tho

slim ferry
#

why are you doing == SMODS.current_mod.reset_game_globals(run_start)

#

that is the function that changes the value. not the value itself

#

plus current_mod doesnt exist after load

reef bobcat
#

what should i replace it with? :[

slim ferry
#

with whatever value youre setting in the reset function

reef bobcat
#

im not getting it ;-;

slim ferry
slim ferry
#

yes

#

but change vremade_mail_card to something else

reef bobcat
#

i dont think im gonna mess around with random ranks for a while

#

this stuff is just not computing with my brain

fallen topaz
#

can someone playtest my mod?

frosty dock
#

this is the wrong channel pal, 98% of mod devs don't play the game

rigid solar
#

this is so real lol

rapid stag
#

can someone modtest my play

ivory socket
#

thats a lot to ask, im not sure if i possibly could

frosty dock
#

can some mod play one my test?

ivory socket
#

can some test one mod my play?

dawn knoll
#

Can someone tell me how would I make a sticker for jokers that, when specific ranks are played, has a 1/2 chance of triggering the joker it’s applied to?

slim ferry
#

You probably want to look into forcetrigger functionality from spectrallib

#

If youre willing to add additional dependencies to your mod that is

#

Since there isnt really a way to generically trigger any joker normally

ivory socket
#

my code still doesn't work i want to DIE, if you do have instructions please try to be a little bit more specific please! SMODS.Joker {
key = "Universe",
loc_txt = {
name = "Universe",
text = {
"retrigger all played cards {C:attention}2{} times",
"if all played cards have",
"the {C:attention}same{} Enhancement"
},
},
config = {extra = {repetitions = 2}},
--unlocked = true
rarity = 3,
blueprint_compat = true,
eternal_compat = true,
Atlas = "jokerimage",
pos = { x = 0, y = 0 },
cost = 7,
loc_vars = function(self, info_queue, card)
return { vars = {context.repetiton} }
end,
message = localize('k_again_ex'),
calculate = function(self, card, context)
if context.repetition and context.cardarea == G.play then
local enhancement = context.full_hand[1].config.center_key
for i = 2, #context.full_hand do
if context.full_hand[i].config.center_key ~= enhancement then
return nil
end
end
return {
repetitions = card.ability.extra.repetitions,
}
end
end
}

frosty dock
#

can you please codeblock that

ivory socket
#

i kinda dont know how since im new to coding...

rapid stag
#

triple ` either side

frosty dock
#

```lua
-- code goes here
```

#

not really coding, just markdown

#

` not '

ivory socket
#
SMODS.Joker {
    key = "Universe",
    loc_txt = {
        name = "Universe",
        text = {
            "retrigger all played cards {C:attention}2{} times",
            "if all played cards have",
            "the {C:attention}same{} Enhancement"
        },
    },
    config = {extra = {repetitions = 2}},
    --unlocked = true
    rarity = 3,
    blueprint_compat = true,
    eternal_compat = true,
    Atlas = "jokerimage",
    pos = { x = 0, y = 0 },
    cost = 7,
    loc_vars = function(self, info_queue, card)
        return { vars = {context.repetiton} }
    end,
        message = localize('k_again_ex'),
    calculate = function(self, card, context)
         if context.repetition and context.cardarea == G.play then
            local enhancement = context.full_hand[1].config.center_key
            for i = 2, #context.full_hand do
                if context.full_hand[i].config.center_key ~= enhancement then
                    return nil
                end
            end
            return {
                repetitions = card.ability.extra.repetitions,
            }
        end
end
}```
frosty dock
#

the only thing I'm spotting that's wrong with this is Atlas instead of atlas, which would cause the sprite to be wrong

#

also this is both wrong and completely irrelevant as you've put no variables in your description

#

neither of these things should concern the functionality of your joker though

#

so what's not working exactly

ivory socket
#

its supposed to retrigger cards played if they all have the same enhancement, but the retriggers never occur, even if they are of the same enhancement

frosty dock
ivory socket
#

no let me go test this

frosty dock
#

that'd be it. you always need to do that. config just holds default values, a pre-existing card will continue to have the old values

ivory socket
#

still nothing...

#

yes even after a new run

frosty dock
#

can i see that

ivory socket
#

sure gimme a minute

#
SMODS.Joker {
    key = "Universe",
    loc_txt = {
        name = "Universe",
        text = {
            "retrigger all played cards {C:attention}2{} times",
            "if all played cards have",
            "the {C:attention}same{} Enhancement"
        },
    },
    config = {extra = {repetitions = 2}},
    --unlocked = true
    rarity = 3,
    blueprint_compat = true,
    eternal_compat = true,
    atlas = "jokerimage",
    pos = { x = 0, y = 0 },
    cost = 7,
        message = localize('k_again_ex'),
    calculate = function(self, card, context)
         if context.repetition and context.cardarea == G.play then
            local enhancement = context.full_hand[1].config.center_key
            for i = 2, #context.full_hand do
                if context.full_hand[i].config.center_key ~= enhancement then
                    return nil
                end
            end
            return {
                repetitions = card.ability.extra.repetitions,
            }
        end
end
}```
frosty dock
#

i meant can i see it not working

ivory socket
#

oh okay lemme screen record some footage

rapid stag
#

would SMODS.get_enhancements help here any cirThink

#

something like

  local enhancement = SMODS.get_enhancements(context.full_hand[1])
  for i = 2, #context.full_hand do
    if SMODS.get_enhancements(context.full_hand[i]) ~= enhancement then
      return nil
     end
  end
#

...hm no, that shouldn't change it not working

frosty dock
#

that's not how get_enhancements works

rapid stag
frosty dock
#

good point about it not supporting quantum enhancements though

#

for that to work, you'd have to check if there's any enhancement they all share

rapid stag
frosty dock
#

the code still looks right to me

ivory socket
#

sorry the footage is taking forever to get, realized i didn’t have a screen recorder on my new computer yet

wintry solar
#

press win+shift+s

frosty dock
ivory socket
#

yes i tried closing, restarting, opening the game again

rapid stag
#

now that i look closer, it might actually just be better and simpler to do something like move the check to context.before, store the result in a config variable and then rely on that config variable for repetition. something like

calculate = function(self, card, context)    
    if
        context.before
        and context.main_eval
    then
        card.ability.extra.sameEnhance = true
        local enhancement = context.full_hand[1].config.center_key
        
        for i = 2, #context.full_hand do
            if context.full_hand[i].config.center_key ~= enhancement then
                card.ability.extra.sameEnhance = false
                break
            end
        end
    end
    
    if
        context.repetition
        and context.cardarea == G.play
        and card.ability.extra.sameEnhance
    then
        return { repetitions = card.ability.extra.repetitions }
    end
end
hidden aspen
#

hows that thing called where you override existing game objects? i want to change vanilla joker/tag

frosty dock
#

that does sound more efficient, but either should work, i see no reason why it wouldn't

#

take_ownership?

hidden aspen
#

yessss

#

ty

rapid stag
#

i mean, it probably shouldn't

frosty dock
#

i've never heard of such a thing

rapid stag
#

but the only thing i can think of is if it's not working, then that condition isn't being fulfilled for whatever reason

frosty dock
#

for testing I'd put some debug logs before this return

rapid stag
#

mhm, that's why i said to try putting a print in that condition

frosty dock
#

but full_hand is definitely not being weird here

rapid stag
#

i did also think that context.full_hand[i] might be going out of the scope of full_hand, but then i realised that it'd be causing crashes if it did

also, that's going to cause crashes with high cards

ivory socket
#

ignore the tenna mouse cursor and deltadeck cards

rapid stag
#

can you print something from the enhancement condition and see if that prints anything to the lovely console?

#

like just stick a print after
if context.full_hand[i].config.center_key ~= enhancement then

#

before the return

frosty dock
#

okay you're definitely doing something wrong

#

i just tested the code on my end and it works

rapid stag
#

same

frosty dock
#

can you make sure you've saved everything and restart the game again?

ivory socket
#

okay i just realized i made a mistake, I was editing the code for the joker, but i specifically edited it in a secondary copy that wasnt actually attached to balatro. now that placed the new version in balatro, the game crashes as soon as i try to discover it

rapid stag
#

nice

ivory socket
#

i feel so stupid

rapid stag
#

that is probably because of the atlas thing aure said

#

atlas needs to be lowercase

#

unless you did do that

frosty dock
#

if I had a penny for every time I edited the wrong file, I would have quite a lot

ivory socket
#

it is lowercase

frosty dock
#

don't feel stupid because of it

#

oh also this is out of place and you might want to remove it, but that also won't crash the game

#

the only crash I see is if the atlas is wrong

#

that doesn't include it not existing due to being uppercase

rapid stag
#

could we see your joker code again please

#

and also where you declare that atlas (your SMODS.Atlas call)

ivory socket
#

give me a minute

#

okay, some weird stuff is happening, when i paste the new code into balatro, it opens the old code that didnt work, even though i saved the new code already

frosty dock
#

wot

#

are we still having that old code somewhere in the mods folder?

rapid stag
#

are your files set up correctly

ivory socket
#

i deleted the old folder, pasted the new folder with new code, and it opens the old code

rapid stag
#

what's your file structure like?

frosty dock
#

ok no i'm out of here, i'm too tired for ts

#

y'all will figure it out

rapid stag
#

yeah, i got this. i think

#

i'm intrigued at the very least

ivory socket
#

i fixed it, i copied the code from the newer verison, pasted it into the old one, deleted the old code, and then saved it

frosty dock
#

has to be just a files problem at this point, i'm sure

rapid stag
#

nice

ivory socket
#

the joker still doesnt work tho

rapid stag
#

huh

frosty dock
#

how so

ivory socket
#

the correct code opens, but when i enter balatro and interact with the joker, it crashes since atlas is a "nil value"

frosty dock
#

the atlas probably doesn't match

rapid stag
#

yeah, need to see your joker and atlas code to figure out what's going wrong there

ivory socket
#

thanks for reminding me, got distracted

frosty dock
#

anywho simple stuff, good night

ivory socket
#

sleep well, thanks for the help!

#

this is the joker code ```lua

SMODS.Joker {
key = "Universe",
loc_txt = {
name = "Universe",
text = {
"retrigger all played cards {C:attention}2{} times",
"if all played cards have",
"the {C:attention}same{} Enhancement"
},
},
config = {extra = {repetitions = 2}},
--unlocked = true
rarity = 3,
blueprint_compat = true,
eternal_compat = true,
atlas = "jokerimage",
pos = { x = 0, y = 0 },
cost = 7,
message = localize('k_again_ex'),
calculate = function(self, card, context)
if context.repetition and context.cardarea == G.play then
local enhancement = context.full_hand[1].config.center_key
for i = 2, #context.full_hand do
if context.full_hand[i].config.center_key ~= enhancement then
return nil
end
end
return {
repetitions = card.ability.extra.repetitions,
}
end
end
}```

#

heres the atlas code for it lua SMODS.AtLAS{ key = 'jokerimage' , path = 'Universe.png' , px = 71, py = 95 }

#

I imagine its something to do with atlas

faint yacht
#

...why AtLAS?

rapid stag
#

i think SMODS.Atlas here is case-sensitive

ivory socket
#

i changed it to SMODS.Atlas it still crashes

rapid stag
#

is your atlas definition before your joker definition

slim ferry
#

That does not matter

rapid stag
#

oh, right

ivory socket
#

my atlases are in a different file from my jokers, i have for atlas's and one for jokers

#

they are still in the same folder, obviously

frosty dock
#

are both being loaded though

#

you can just put files places and have them loaded automatically

ivory socket
#

I made 2 jokers before this and both work with the format i have so i assumed it wasnt the issue

#

yes they still work after the edits i made

frosty dock
#

can we see your file structure and how you load the files

ivory socket
#

so a screenshot of inside the folder?

frosty dock
#

yes, and the code where the loading happens

#

the joker's image file including its location, as well

ivory socket
#

im pretty sure the image file isnt the issue, the two jokers i made before this don't images yet, and they still work

frosty dock
#

it's crashing because of the atlas though?

rapid stag
#

but your error is that the atlas is nil

frosty dock
#

or is the crash different now

ivory socket
#

heres an image of the files, and yes the crash is still a nil value

frosty dock
#

Also that atlas file looks pretty lonely. you said there were other files being loaded there

#

the main file is loaded because it's... well, the main file

#

the fact that SMODS.AtLAS wasn't crashing tells me that file is probably not being loaded to begin with

ivory socket
#

heres the code for my atlas then ```lua
SMODS.Atlas{
key = 'jokerimage' ,
path = 'Red.png',
px = 71,
py = 95
}

SMODS.Atlas{
key = 'jokerimage' ,
path = 'Blue.png' ,
px = 71,
py = 95
}

SMODS.Atlas{
key = 'jokerimage' ,
path = 'Universe.png' ,
px = 71,
py = 95
}

SMODS.AtLAS{
key = 'jokerimage' ,
path = 'Frog.png' ,
px = 71,
py = 95
}

SMODS.AtLAS{
key = 'jokerimage' ,
path = 'ATM.png' ,
px = 71,
py = 95
}```

frosty dock
#

uh

#

all of these have the same key...?

#

that's not how these work

ivory socket
#

thats a bad thing i imagine

frosty dock
#

there's also more AtLAS, so this would definitely crash if it were loaded

frosty dock
rapid stag
#

do you have anything loading this code, or is that just the entire lua file sitting in your mod directory - and your intuition was that it was loaded by virtue of it just being in your mod folder? cirThink

#

no SMODS.load_file anywhere?

#

you could try doing assert(SMODS.load_file('atlas.lua'))() in your main lua file

ivory socket
#

it works now

#

I CHANGED THE KEYS AND NOW IT WORKS

rapid stag
#

...huh?

ivory socket
#

they all used to be the same, so i made them unique and messed around a little bit and now it works perfectly fine

#

the keys that is

rapid stag
#

huh, so the lua file does just load cirLost

ivory socket
#

yeah it loads

frosty bone
#

how would one code this in lua

red flower
#

carefully

#

do you need tips on anything specific?

twilit hearth
#

I have about 80 lines of code that I got to stop crashing, but I cannot figure out why the logic for this joker will not work. If i dump the code into this chat, would I possibly be able to get some guidance?

red flower
#

that is what the channel is for yes

twilit hearth
#

I just didnt wanna start dumping

#

for the life of me i cannot figure out why I cannot actually "steal" other jokers

red flower
#

you should put that in a codeblock

twilit hearth
#
SMODS.Joker {
    key = 'shoplifter_hook',
    atlas = "hr_jokers",
    pos = { x = 8, y = 0 },
    rarity = 3,
    cost = 8,
    blueprint_compat = false,
    discovered = true,
    config = { extra = { used_this_shop = false } },

    loc_txt = {
        name = "Shoplifter's Hook",
        text = {
            "Right-click a {C:attention}Joker{} in the shop",
            "to add it to your inventory.",
            "Deletes a {C:red}random{} owned Joker.",
            "{C:inactive}(Once per shop){}",
            "{C:inactive,s:0.8}Cannot delete itself{}"
        }
    },```
#
    calculate = function(self, card, context)
        if context.ending_shop or context.skip_blind or context.setting_blind then
            card.ability.extra.used_this_shop = false
        end
    end
}

-- The Logic Injection
function SMODS.current_mod.post_process()
    local old_secondary = Card.states.release.secondary
    Card.states.release.secondary = function(self)
        if G.STATE == G.STATES.SHOP and self.area == G.shop_jokers then

            local hook_key = "shoplifterhook"
            local hook = nil

            for , v in ipairs(G.jokers.cards) do
                if v.config.center.key == hook_key then
                    hook = v
                    break
                end
            end

            if hook and not hook.ability.extra.used_this_shop then
                local sacrificepool = {}
                for , v in ipairs(G.jokers.cards) do
                    if v ~= hook then 
                        table.insert(sacrifice_pool, v) 
                    end
                end

                if #sacrifice_pool > 0 then
                    hook.ability.extra.used_this_shop = true

                    attention_text({
                        text = 'STOLEN!',
                        scale = 1.2, hold = 1, bg = G.C.RED,
                        align = 'cm', major = self
                    })
                    play_sound('cash_register', 1.2, 0.6)

                    local victim = pseudorandom_element(sacrifice_pool, pseudoseed('hook_kill'))
                    victim:start_dissolve()

                    self:add_to_deck()
                    G.jokers:emplace(self)
                    self.area:remove_card(self)

                    return
                end
            end
        end

        return old_secondary(self)
    end
end```
twilit hearth
red flower
#

yeah yeah, you can add ```lua in the top one so it has highlighting

twilit hearth
#

ahhh okay

red flower
#

was this ai generated

twilit hearth
#

I resorted to drastic measures

#

yes

#

how on earth could you tell

red flower
#

well of couse its not going to work if half the things in your code are nonsense lol

twilit hearth
#

I guess that's why I needed some pointers. Trying to figure out what went wrong and half the stuff im googling doesnt matter lol

viscid talon
twilit hearth
#

oh god

red flower
#

i would personally recommend starting with easier stuff first, the first part of the ability doesnt seem that hard but eben i wouldnt know straight away how to do it without looking into the code a bit first
for the right click in JokerDisplay i hook Controller:queue_R_cursor_press, the idea would be to check what is hovered there (G.CONTROLLER.hovering.target) and remove the joker from the shop area similarly to how the code you have does it (but i believe you would need to destroy the shop ui)

reef bobcat
#

i put in_pool = function() return false at the end of my joker's code but it still shows up in the shop D:

twilit hearth
#

Okay I gotcha. I'll just have to put it on the back burner for now. I made a few jokers before but those were pretty simple. xMult and whatever. I was able to piece together a joker that destroys cards but thats about as complicated as I got with it

#

Thank you @red flower for helping me out. I'll have to come back to this idea

round lion
reef bobcat
#

no just regular red deck

round lion
#

i think it'd be

return false
end,``` near the start of the joker's code
#

after the loc txt and config and unlock and allthat

reef bobcat
#

ok that seems to have worked

#

how do i also make it so that

#

a joker doesnt spawn

#

if you have another specific joker

#

already

red flower
#

return not next(SMODS.find_card("j_modprefix_otherjokerkey"))

reef bobcat
round lion
#

as long as you keep it in a tabl

rapid stag
#

keep it in a talbe

rapid stag
red flower
rapid stag
#

if you return this from in_pool cirDerp

red flower
#

if in_pool returns false the joker cant show up, if it returns true it can as long as you dont have a copy or you have showman

rapid stag
#

...so i don't know why, but i had it in my had that if you have in_pool return false, then it's treated the same as when you already have the joker

mostly because i was thinking of my joker upgrading consumable and how if you use it to turn a joker into its upgraded version, you can encounter the unupgraded version in later shops

rigid solar
#

How can I check which stakes are applied?

red flower
rigid solar
#

thx

#

wait it's numbers? urgh (i have an additional modded stake on top of gold stake, hence the 9th)

red flower
rigid solar
#

yeah i just wanted an easy way to get if gold stake is applied for example, but ig i have to iterate over all applied stakes and check for each of them if it's gold

red flower
reef bobcat
#

how do i make it so that, before the hand scores, certain suit cards turn into another suit

rigid solar
#

that was an example, technically i want to check for black, orange or gold (aka if eternal, perishable and rental jokers can appear)

red flower
#

isnt it easier to check if those can appear? or do you specifically need the stakes?

rigid solar
#

i just need the sticker
i guess there's a flag that sets if those can appear? that'd make sense now that i think about it

red flower
#

G.GAME.modifiers.enable_eternals_in_shop
G.GAME.modifiers.enable_perishables_in_shop
G.GAME.modifiers.enable_rentals_in_shop

rigid solar
# reef bobcat how do i make it so that, before the hand scores, certain suit cards turn into a...
if context.before and context.cardarea == G.jokers then
      -- turn cards to club
      local clubs_trigg = false
      for _, v in pairs(context.scoring_hand) do
        if not (v:is_suit("Clubs")) then
          clubs_trigg = true
          local rank = v:get_id()
          if rank > 9 then
            if rank == 10 then rank = "T" end
            if rank == 11 then rank = "J" end
            if rank == 12 then rank = "Q" end
            if rank == 13 then rank = "K" end
            if rank == 14 then rank = "A" end
          end
          v:set_base(G.P_CARDS["C_"..rank])
        end
      end
      if clubs_trigg then
        card_eval_status_text((context.blueprint_card or card), 'extra', nil, nil, nil, {message = localize('maelmc_clubs')})
      end
    end

I did this to turn cards to clubs, checking if they aren't already clubs beforehand

reef bobcat
rigid solar
#

then check for that

daring fern
rigid solar
#

oh, of course there's a smods function for it lol

daring fern
hidden aspen
#

how can i make a SMODS.Challenge where you die in game you die in real life ?

wanton jolt
#

local current_tier = next(SMODS.get_enhancements(G.hand.highlighted[i])) or ""
would return the enhancement right

red flower
#

it could be a quantum

wanton jolt
#

how would i grab the main one then? G.hand.highlighted[i].config.center.key?

red flower
#

yes

hidden aspen
#

yeah i see it in the lsp i dont thunk it was in the docs

#

my b

dapper sun
#

how do i check if the card's usual sprite isn't being used

#

i can't use card.discovered bc if i do

daring fern
frosty rampart
#

nope, even undiscovered cards still have their usual atlas stored in the center like that

#

i actually need to figure this out too for high roller

dapper sun
#

i've been given a solution on the hotpot server

#
function slimeutils.card_obscured(card)
    return not card.config.center.discovered and (card.ability.consumeable or card.config.center.unlocked) and not card.bypass_discovery_center
end```
#

and i put it in this function

frosty rampart
vital wren
#

can someone help me figure out why my info_queue is just not working?

#

the code:

-- The Inverted Magician
-- Chance to destroy or add foil to 1 selected card
SMODS.Consumable
{ 
    key = 'inverted_magician',
    set = 'Tarot', 
    atlas = 'inverted-arcana-tarots',
    pos = {x=1, y=0},
    config = {
        max_highlighted = 1,
        remove_card = true,
        mod_conv = 'e_foil',
        extra = {
            odds = 3,
        },
    },
    loc_vars = function(self, info_queue, card) 
        info_queue[#info_queue + 1] = G.P_CENTERS.e_foil
        local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, self.key)
        return { 
            vars = { 
                numerator, 
                denominator, 
                card.ability.max_highlighted,
                localize{type = 'name_text', set = 'Edition', key = card.ability.mod_conv}
            }
        } 
    end,
    use = function(self, card, area, copier)
        use_inverted_tarot(self, card, area, copier)
    end,
}```
#

the result: the info_queue flyout just isn't there?

#

same is true for the tarot cards that should be displaying enhancements and seals. just no flyout at all, no crash

rapid stag
red flower
#

is there an easy way to add temporary handsize but for the next round
or do i have to save it and apply it on shop start

keen blaze
#

ive been having trouble with making an enhancement, im trying to make it so it doesnt take up space in the hand (by having it increase hand size by 1 when held in hand) but theres two exceptions ive found where i cant get that to work the way it should (blind is defeated -> doesnt decrease hand size properly even when i use context.blind_defeated and then switching off of enhancement -> doesnt decrease hand size properly because by the time context.setting_ability is called the enhancement is no longer running the code)

i know using the negative edition would work but its important for this enhancement that it be an enhancement, i could post the code here but id worry about it taking up a bunch of space (although its not SUPER long) so if i should post it just lemme know and i will, but i was wondering if anyone had any advice on how to go about handling this

rapid stag
red flower
#

i just did what i said

wanton jolt
red flower
keen blaze
#

i tried that but then it crashed

red flower
#

what was the crash

keen blaze
#

hang on ill do it again rq so i can post it

#

do i have to return it in loc_vars btw i dont remember if i gotta do that

red flower
#

no, in config

keen blaze
#

alr yaya i threw it in config i was just wondering if i had to put it through loc_vars too

red flower
#

no

keen blaze
#

weird

#

it hasnt crashed

#

and it works

#

okay wow idk what the problem was then but 😭 if it works it works

#

thanks !

near coral
#

So both reroll surplus and reroll glut lower the reroll price by $2, making it only $1 initially

#

Naicigam also lowers the reroll price by $2, so all them together make 5-6, making the price say $-1

#

Is it possible to make the reroll price floor at $0 without possibly breaking anything

#

Also it gets worse when there are multiple naicigams, is it possible to make an effect non-stackable

sturdy monolith
#

fun bug

near coral
sturdy monolith
steady mulch
#

how would i go about incrementing a joker's chips/mult/whatever when a joker of a specific rarity is purchased?

red flower
daring fern
steady mulch
#

i have the first and im pretty sure i know how to implement the second

steady mulch
#

i didnt realize there was a context for rarity

#

thats nice

#

ty

sturdy monolith
#

imgui-love works with balatros love version raaaahhhhhhh lfg

steady mulch
#

would there be a way to include that as well

sturdy compass
#

You’d use context.card_added and context.card.ability.set == ‘Joker’ instead of context.buying_card

steady mulch
#

ah ok

daring fern
sturdy compass
#

Yes that’s what they’re asking about

#

Is it not

#

😭

steady mulch
#

honestly i dont know

#

are there other scenarios for getting a joker into your slots besides shop and booster pack

#

probably

frosty rampart
#

shop, booster pack, judgement, the soul

#

riff raff

steady mulch
#

yeah

frosty rampart
#

top-up tag

steady mulch
#

i guess having it be added in any way works i would just have to reword the current description which says "when a common joker is purchased"

sturdy compass
#

“When a common joker is acquired” or smthn like that

steady mulch
#

yeah

steady mulch
#

is there a difference between = and == in lua

#

or can i just use whatever

sturdy compass
#

Yeah, = is for setting values and == is for conditionals

steady mulch
#

ohh ok

#

alright it works now

steady mulch
rapid stag
#

how do i convert this to work with SMODS.scale_card cirThink

sturdy compass
steady mulch
#

would cards with no rarity still trigger the joker with the rarity check?

#

im down to add the set check i just dont really understand what it is i suppose

sturdy compass
#

I’m honestly not 100% sure how is_rarity works with non-jokers nor do I know if there’s a fallback, but if there is I’d assume the fallback is 1. If there’s not a fallback I’d bet it crashes lol

sturdy compass
steady mulch
#

ah

#

i see

daring fern
sturdy compass
#

A boolean was the last thing I would have expected

steady mulch
#
if context.card_added and context.card.ability.set == "Joker" and context.card:is_rarity("Common") then
#

so like this?

sturdy compass
#

Yep that should work

steady mulch
#

cool

daring fern
sturdy monolith
#

i've got a bit of the functionality of the baladev mod done :D

#

definitely needs some polish

sturdy compass
#

Clearly not

frosty rampart
#

it's is_rarity, not get_rarity

sturdy compass
#

That’s where I was getting confused

#

My ass is too used to using get_rarity lmao

steady mulch
#

ah hang on

#

sorry to keep asking questions about this but how to i change the message from the default Upgrade to displaying the Chips increase

#

i tried adapting the code from flash card but it didnt seem to work

sturdy compass
#

Are you using the scale card function?

steady mulch
#

i am yeah

sturdy compass
#

Ok gotcha

#

I believe what you wanna do here is add a message_key field to your function call and have it be ‘a_chips’

sturdy monolith
steady mulch
#

apologies for the confusion im just very new to programming so im not familiar with the terminology

sturdy compass
#

Nah all good, welcome to coding lmao

#

Basically when you’re using a function, it’s called “calling” the function

steady mulch
#

oh no no i get that, i was just wondering which function you were referring to

#

cus i have loc_vars, calculate, and the whole if/then statement

#

so i wasnt really sure where to put the message key

sturdy compass
#

Wait are you or are you not using SMODS.scale_card?

sturdy monolith
#

rld

sturdy compass
#

I’m confused now lol

steady mulch
#

ye i am

sturdy compass
#

Ok then I mean in that

steady mulch
#

ah ok

sturdy compass
#

Here’s an example of what I mean

steady mulch
#

ohhhh ok

#

and will that make the message "+20 Chips" or just "+20"

frosty rampart
#

it might be just "+20", but that's consistent with vanilla I think
if it were mult it'd definitely be "+20 Mult"

steady mulch
#

interesting

#

yeah it is just +20

#

but if thats how it looks in vanilla then its probably fine?

daring fern
frosty rampart
sturdy monolith
steady mulch
#

oh wee joker just does Upgrade

#

weird

frosty rampart
#

oh weird

sturdy compass
#

Tf is wee doin’ 😭

#

That’s goofy

#

But yeah only numbers showing is (usually) consistant with vanilla

steady mulch
#

Runner does Upgrade too

#

why doesnt flash card then

#

whatever

daring fern
steady mulch
#

good to know

timid zinc
#

i'm pretty sure most jokers that scale during the hand do "Upgrade!"

vital wren
#

is there a way to hook or wrap Card:shatter()? I want to keep a tally of how many glass cards break as a global

daring fern
vital wren
#

how do i do it and still let the original function though? it doesn't have any args i can pass

daring fern
vital wren
#

ohhh, you return the original passing self. thanks

vital wren
gilded blaze
vital wren
#

thank!

bright ivy
#

Anyone know if there is a context for last hand drawn?
I know DNA uses context.first_hand_drawn, but I was wondering if there was a last hand drawn

bright ivy
#

Is there a way to hook it or smth any way for me to change this code so it works as the last hand?

-- RNA
SMODS.Joker {

    key = "rna",
    blueprint_compat = true,
    rarity = 2,
    cost = 6,
    pos = { x = 0, y = 0 },

    loc_txt = {
        name = "RNA",
        text = {
            "If {C:attention}last hand{} of round",
            "has only {C:attention}1{} card, add a",
            "permanent copy to deck",
            "and draw it to hand",
        }
    },
    atlas = "rna_atlas",

    calculate = function(self, card, context)

        -- Juice effect like DNA
        if context.first_hand_drawn and not context.blueprint then
            local eval = function()
                return G.GAME.current_round.hands_played == 0 and not G.RESET_JIGGLES
            end
            juice_card_until(card, eval, true)
        end

        -- Copy condition
        if context.before
        and G.GAME.current_round.hands_played == 0
        and #context.full_hand == 1 then

            local card_copied = copy_card(context.full_hand[1])

            -- Add ONLY to hand
            G.hand:emplace(card_copied)
            card_copied.states.visible = nil

            G.E_MANAGER:add_event(Event({
                func = function()
                    card_copied:start_materialize()
                    return true
                end
            }))

            return {
                message = "Copied!",
                colour = G.C.CHIPS
            }
        end

    end
}
vital wren
#

instead of hands_played you can check that the current remaining hands is zero. to do the wiggle, you could use context.after and just check if hands remaining is zero and have it stop when playing another hand

frosty dock
gilded blaze
#

if context.hand_drawn and G.GAME.current_round.hands_left <= 1 then

fading rivet
#

if I extend SMODS.Center will my new card type automaticly go into the other section of the collect or do I have to patch/hook something

slim ferry
#

Idk how it exactly works but you do have to create the collection page yourself yes

fading rivet
#

any mods I could look into for details, I tried card sleeves but I couldn't make anything out

slim ferry
#

Idk

#

Paperback i guess? That isnt for a center type but it is a collection page with cards

thorn basin
#

Small question: how can I set my mod icon (the one that appears in the mods section that looks like a tag) to a custom icon I made?
Should I make an atlas for it?

slim ferry
#

create an atlas with the key modicon

sleek valley
#

add an atlas with the key modicon

thorn basin
slim ferry
#

Yea

thorn basin
#

aight

#

thanks!

slim ferry
#

why does this juice twice?

primal terrace
#

For JokerDisplay, is there a way to make the tooltip disappear entirely when a condition is not met, instead of only changing the values?

long sun
#

i'm struggling to come up with a way of doing this, but i'm gonna rubber duck and see if it helps

#

if you have any suggestions, feel free

#

i'm working on a necessary update to Flipbook that will allow individual cards to show different animations

#

(as before, cards could only animate their Centers, meaning if one card wanted to do an animation but another didn't, they'd clash)

#

it's therefore necessary to change how the center DrawStep works

#

but i'm not sure what the best approach would be

#

i'm gonna have each animated card have a flipbook_pos

#

but, should i patch the DrawStep, or take ownership of it, or something else? and how would i change the pos that a card is rendering with?

#

actually i may not even need to patch the DrawStep if i'm clever

#

okay yay the rubber ducking worked ^u^ better question

#

how do i change the pos that card.children.center renders with?

#

i'd previously just been changing the pos of the centers in G.P_CENTERS

gilded blaze
#

utilizing empty strings to get the desired effect is DEAD

primal terrace
#

I believe that was my first instinct, but it doesn't work if it's Xmult, because the red outline is still there

gilded blaze
#

use style_function and set the box's colour to G.C.CLEAR

shrewd cobalt
#

Is there a way to automatically give a joker the highest stake sticker?

gilded blaze
#

start a run with the highest stake difficulty, spawn the desire joker in, and call set_joker_win()

red flower
red flower
long sun
#

AAA I DIDN'T EXPECT THAT TO ACTUALLY WORK WHAT???

#

[these cards are at different points in their animations]

#

[in the old version, they would've been synced]

#

another example, look at the Visionary's cross

long sun
#

okay a more clear example :3 these are the same card

#

if i have two Hint Coins, their events will play immediately, one after the other. how can i get their events to wait for the other Jokers to return values?

if context.before and G.GAME.current_round.hands_played == 1 then
      G.E_MANAGER:add_event(Event({
        func = function()
          if not context.blueprint then
            play_sound("phanta_hintcoin", 1, 0.9)
            card:flipbook_set_anim_state("collect")
          end
          return true
        end
      }))
      card.ability.extra.given = true
      return { dollars = card.ability.extra.money }
    end```
#

i'd try returning extra with a func, but the func triggers after the message, which i don't want

#

also i realise i put a context in an event, i've fixed that now

red flower
long sun
#

ya, it's currently doing that

#

(i think)

red flower
#

hmm seeing the code it seems like it shouldnt

long sun
#

i'll test it more in a mo, but i found a crash to fix ^^;;;;

red flower
#

testing similar code it goes event > return > event > return like it should
if the things inside the event also add another event then it would make sense that it does return > return > event > event (since the events will be adding another event to the queue for later)
but event > event > return > return would be strange

long sun
#

hmm i see

#

okay i think i understand the crash, lemme fix that then test

#

of course, this crash could've been avoided if i wrote better code :3

#

weird, it looks like it's working now

#

;u;

#

sorry to bother

fickle gust
#

hi! how can i detect if the player owns a specific joker from the vanilla game?

fickle gust
#

ty!

prisma loom
#

Folks, what are the % and/or weights of the packs?

#

in vanilla

prisma loom
#

Thanks!

rapid stag
#

in calculate, how can i detect a steel/gold card trigger and do something in response?

#

like i was looking at vanillaremade's mime implementation, but i'm wondering if i could also do some kinda trigger_obj stuff

slim owl
#

i have accidentally removed the hologram's face and idk how to not do that (i'm using carrotton's dark pack as a base for my pack incase that helps)

#

also pasting fully opaque jimbo over the hologram's jimbo vaporizes the entire hologram jimbo i figured out earlier

sturdy monolith
granite jay
#

How do you add extra modifiers to challenges?

#

Like banning modded items that would break these challenges?

fickle gust
#

alr i'm having a crash because of this line:
SMODS.create_card{key = "fixed", set = Joker, skip_materialize = true, no_edition = true}
isn't this how SMODS.create_card is supposed to work?
-# the crashlog says that "center" is a nil value

red flower
#

the key is missing the prefixes

fickle gust
#

switched to SMODS.create_card{key = "j_fixed", skip_materialize = true, no_edition = true}, still crashes for some reason

red flower
#

you're missing the mod's prefix

fickle gust
#

ah i'm dum ty

thorn basin
#

How can I add a custom joker card to the title screen like most ppl in their mods do?
note: I said "add", not "replace the ace card"

fickle gust
#

jokers not doing joker things even if i specify their set and area to be jokers?
SMODS.create_card{set = Joker, area = G.jokers, key = "j_cash_out_fixed", skip_materialize = true, no_edition = true}

red flower
#

add_card instead of create_card

fickle gust
#

i can't read my bad

fickle gust
#

alr i've tried to understand myself using the documentation but i can't figure it out anymore, this crashes when context.post_joker fires

if context.post_joker then
            if next(SMODS.find_card("j_half")) then
                --destroy "j_half" and "j_half_2"
                self.remove_from_deck()
                local half_cards = SMODS.find_card("j_half")
                local target = half_cards[1]
                target.remove_from_deck()

                --create "j_fixed"
                SMODS.add_card{set = Joker, area = G.jokers, key = "j_cash_out_fixed", skip_materialize = true, no_edition = true}
            end
        end
slim ferry
#

its target:remove_from_deck()

#

and same for self

#

also remove_from_deck isnt how you destroy a card to begin with

#

if thats what youre trying to do

frosty rampart
#

yea you should use SMODS.destroy_cards(card) instead

thorn basin
#

how do I put credits in my mod?

red flower
thorn basin
red flower
#

this is mine

thorn basin
thorn basin
#

ok so I was normally trying my mod and then this happened, not sure why but it never happened before.
the crash showed when I clicked on next round
is there a way I can fix this?

daring fern
rapid stag
daring fern
rapid stag
wintry solar
thorn basin
rapid stag
#

i did initially test context.individual and found that it didn't work for whatever reason cirDerp i guess i can try it again now that i've refined all the involved conditions

red flower
thorn basin
#

yeah

red flower
#

check if the atlas is correct for those

frosty dock
#

the error would suggest something has something like atlas = false

wintry solar
#

tag_SM_scienceful_tag this one

thorn basin
#

well, that explains the error

rapid stag
daring fern
rapid stag
#

...right. that was leftover from when i was using context.repetition. what should i check for instead

red flower
#

crazy

slim ferry
#

crazy

keen blaze
#

something im trying to do rn is make a joker that copies the edition of the joker to the right AND copies the ability of a randomly selected joker, ive managed to fairly easily get the edition selection and random selection down and the jokers stored into their respective values, but i cant seem to get it to work for some reason. the first two of these screenshots make the joker do basically nothing while the third makes it copy the joker ability, but not the edition. with all three, the correct things are printed from the three print functions within the first if statement, but printed far too early. is there something about the pre_joker and post_joker contexts that im missing?

red flower
#

pre_joker and post_joker are not sent to jokers iirc

keen blaze
#

aw man

red flower
#

hmm but if theyre printed then maybe they are?

keen blaze
#

weirdly its printed like right when the hand is played

red flower
#

yeah thats normal

keen blaze
#

but that also seems to happen if i use the context of joker_main so idk whats up with that

red flower
#

all code is executed when you play the hand

#

then all the animations

keen blaze
#

ohhh that makes sense

red flower
keen blaze
#

i see

red flower
#

anyway, another thing is that you shoudnt save a card to card.ability

#

it is not going to work on reload most likely unless you do custom loading

keen blaze
#

aw man ive been doing that a lot 😭

red flower
#

ah i see the issue

#

return SMODS.merge_effects{ return_table or {}, ret or {} } should work

#

you are basically merging the tables incorrectly

#

edit for nil checking

keen blaze
#

fair fair

#

it is still not working

red flower
#

can i see the code now

keen blaze
red flower
#

the prints work, right?

keen blaze
#

yup

red flower
#

this will only return if it's copying something

#

you should put the bottom return outside the condition unless thats what you want

keen blaze
#

it is copying a joker at least but i see how that could be a problem later down the line

red flower
#

idk why it isnt working then lol

keen blaze
#

oh

#

it just suddenly decided to work

red flower
#

nice

keen blaze
#

i just had to switch it to joker_main again

#

does the order of the returned table matter? like if it returns { return_table, ret } does that make return table trigger before ret while { ret, return_table } makes ret trigger first?

red flower
#

yes

#

exactly that

keen blaze
#

okay cool so for polychrome i can switch the order n stuff

#

sweet ! everything works now

#

thanks for the help ! and by the way where should i store the cards so that i dont have to keep using the ability table thing

red flower
#

if the cards are still in the joker slots you can put a flag in them

#

like card.ability.modprefix_flagname = true

#

when are you getting the jokers?

keen blaze
#

whenever this thing goes off

#

so at the end of the round, when the copied joker is sold, or when there isnt a joker being copied

red flower
#

ah ok then what i said

keen blaze
#

so wait is that something i have to put in separate jokers ? because this is meant to be a blueprint type thing that just works for

#

any joker

#

it just needs to save the joker its currently copying to a variable so that it stays consistent n all that

#

(this is the code i use to get a joker)

red flower
#

it is a bit more complicated if you need to consider multiple copies of the same effect

keen blaze
#

ohhh i see

frigid cargo
#

hi N`

red flower
#

hello

frigid cargo
#

Its been a while since I've actually been here and have done stuff. I actually posted the mod I have been working on, although we aint dropping mod yet. Just posting lol

rigid solar
#

Can anybody tell me which part of the code is responsible for dropping the shop menu when using a card plz

rigid solar
#

it's just that? huh, ok thx

keen blaze
#

i made this function in my joker but for some reason ive tried like 10 different ways to access it and none of them have worked, whats the correct way to access this

#

i know this is kind of a stupid question but 😭

red flower
#

card.config.center.find_copy()
?

keen blaze
#

ohh i was forgetting the config.center

#

my bad im pretty new to this

#

thanks !

#

and everything works now too !

red flower
keen blaze
#

fair lol

long sun
#

okay so i've got a really strange bug that i can't find the cause of

#

lots of code though, so if anyone wants to help, i'll DM you the code i have

#

(actually it'd probably be easier for me to stream it)

#

(would be at least somewhat good if this server had VCs)

long sun
#

it's so annoying when you code something for ages and it doesn't work right :(

#

I wanna stay up all night fixing it, but I have to go to bed

#

grr

tidal hemlock
#

oop did not mean to ping

wintry swallow
#

how could I detect when a card is destroyed and save it's stats?

#

don't give me the answer just help me figure it out

faint yacht
#

Playing card or Joker-type?

wintry swallow
#

I just added purple guy to my stuff and it would be a great combo for another card to have that ability

#

here's the idea I had:

wintry swallow
#

Purple guy destroys 3 cards every played hand. each 19 cards destroyed gives him +87 extra chips
My other card is Greed
For each card destroyed, you get them back but foil (Or smth) After every boss blind

wintry swallow
faint yacht
#

Keep that wiki handy whilst devving. ✌️

wintry swallow
slim owl
#

trying and failing to replace green joker's name and description, what am i doing wrong (five ending brackets condensed for brevity)

return {
    descriptions = {
        Joker = {
            j_green_joker = {
                name = "\"Green\" Joker",
                text = {
                    "i probably picked a bad palette",
                    "{C:inactive}(Currently {C:mult}+#3#{C:inactive} Mult)",
}}}}}
umbral zodiac
#

i think its just j_green iirc

#

nvm sorry

thorn ingot
#

Hey guys. Do you know if the gate for a purple seal would be:

seal_gate = 'purple'

Also, how do you signal you want the gate to be for any seal?

wild escarp
#

How would I go about manipulating the score requirement of a boss blind?

daring fern
tepid crow
rapid stag
#

were there new smods functions to change hand count and hand size? i forget

sturdy compass
#

G.hand:change_size(int) for handsize, not sure what you mean by count tho

tepid crow
#

I don't think smods has anything for that? Unless you meant the play/discard limits

rapid stag
#

the same value that grabber and nacho tong increments

#

hand count

sturdy compass
#

Oh like the amount of hands you have

rapid stag
#

yes

sturdy compass
#

that would be ease_hands_played(int) iirc

#

and then you also have to change the round_resets value if you wanna keep that number permanent

rapid stag
#

ok so i'm just thinking of the play/discard limit funcs, thanks

thorn ingot
sturdy compass
#

You can add an in_pool function to your joker

#

Here's an example of that which searches for Gold Cards

#

Just add it to your Joker like you would calculate and whatnot

rapid stag
#

looking back at my code, i'm sure there's a way better way to do this using SMODS.add_card, no? like i could just get the key and then put that in a table in add card, and specify negative edition.

actually nvm, that wouldn't be faithful to the joker description text i wrote, now that i think

thorn ingot
sturdy compass
thorn ingot
#

Thanks. balatroheart

faint yacht
#

You'd probably want to check for v:get_seal(), no has_seal function. 🙃

tulip pecan
#

Does anybody know what function in the base game creates the Joker collection menu? I want to make a UI for my mod that looks exactly like the collection menu as a pop-up in-game that has a custom set of cards the player can choose from to add to their run

rapid stag
#

i think it's soomething like "create ui collection box"

tulip pecan
#

I found create_UIBox_your_collection_jokers() but all it does is add the first page of jokers at the bottom of the screen

unkempt thicket
thorn ingot
tulip pecan
thorn ingot
mystic river
#

G.playing_cards is numerically indexed iirc so "properly" it would be for i,v in ipairs(G.playing_cards) but the only difference in this context is that pairs doesn't respect order

#

(the variables k,v or i,v can be named whatever you want; those are just the conventional "defaults" when you don't have a specific thing you want to call them)

thorn ingot
rapid stag
#

my patch is no longer changing this cycler colour to blue. the lovely console isn't saying that it didn't result in any matches and the lua dump shows that the patch took?

what changed

vital wren
#

when making new stickers or taking ownership of existing stickers, should_apply seems to ignore all the normal restrictions the sticker has like needing to be enabled by stake or only appearing on jokers. is there a way to make it not ignore those restrictions? or is there an easier way to make two stickers not be compatible?

daring fern
#

Also all vanilla stickers don't use should_apply

vital wren
#

okay, so i could use and instead of or to add additional restrictions while keeping the normal ones, yeah?

faint yacht
#

return condition1 and condition2 or condition3, ye.

vital wren
daring fern
vital wren
#

so how do i change what they're compatible with?

daring fern
vital wren
#

im trying to do that with this, but it's not working

    should_apply = function(self, card, center, area, bypass_roll)
        return SMODS.Sticker.should_apply(self, card, center, area, bypass_roll) and (not card.ability.perishable and not card.ability.rental)
    end,

i also want to make rental not appear with eternal

naive agate
versed swan
#

is there a function that formats text with formatting ("{C:red}+4 {}Mult") into corresponding UIBox elements, for use outside Joker descriptions?

red flower
#

despite the name it localizes a line

#

oh and you need loc_parse_string too

versed swan
#

tried looking in source and I don't understand how to use it, can't find any docs on it too

red flower
#

SMODS.localize_box(loc_parse_string("{C:red}+4 {}Mult")) should work as is, i think

#

it returns a list of nodes so you would need to do like {n=G.UIT.R, config={align = "cm", padding = 0.03}, nodes=localize_box_return}

versed swan
#

works, but args needs to be provided, i.e. SMODS.localize_box(loc_parse_string("{C:red}+4 {}Mult"), {})

#

So for clarification it only goes through one line at a time?

vital wren
versed swan
#

gotcha

#

thanks for your help

naive agate
red flower
red flower
vital wren
daring fern
red flower
#

the problem is that vanilla stickers are applied after yes

#

its realy hard to make them incompat, you would need patches i think

#

hard with the api i mean

vital wren
#

i just have to patch create_card with lovely then?

red flower
#

i think so yeah

vital wren
#

does rate work on the vanilla stickers ?

red flower
#

only if you re-add their should_apply functions, else they're hardcoded

vital wren
#

okay, ill just have to do it in lovely or hook create_card and do the stickers myself. thanks

wild escarp
#

How would I prevent a joker from being removed, aside from selling it?

thorn ingot
vital wren
#

how do i use a sticker's apply method?

daring fern
thorn basin
#

Was trying out some UI stuff but for some reason there's always those white borders in the angles.
how do I remove them?

gilded blaze
#

you used the template, which doesn't have rounded corners

thorn basin
#

uh, hello?

gilded blaze
#

the r field

thorn basin
#

the "r" field specifies how much rounded the corners should be?

vital wren
#

how do i set the text of the badge?

daring fern
gilded blaze
thorn basin
#

And I if I remove it, the white corners disappear but the box doesn't have rounded corners

gilded blaze
#

wait

#

huh

#

the template contains 2 root nodes

#

why

thorn basin
#

that's.... where I was looking while I was making my custom window...

gilded blaze
#

I suggest using it to understand the core components

thorn basin
#

that's.... what I was doing....

gilded blaze
#

you can copy Balatro's existing UI elements tho

#

it's better to start with a well-made template

#

go to Mods/lovely/dump/functions/UI_definitions.lua

thorn basin
gilded blaze
#

start from the Mods folder

thorn basin
#

oh true

gilded blaze
#

I'm not really a UI wizard myself tho
take a look at this half-ass save states UI I modified from challenge list

#

I had no idea what to put in the center so I just copied the continue screen's deck info 😭

thorn basin
#

alright, thanks still for the help!

#

I'll see if someone else knows more about it

vale grove
#

im reading up on how to do enhancements and im a little confused on how to make a tarot give an enhancement

#
-- The Hierophant
SMODS.Consumable {
    key = 'heirophant',
    set = 'vremade_Tarot',
    pos = { x = 5, y = 0 },
    config = { max_highlighted = 2, mod_conv = 'm_vremade_bonus' },
    loc_vars = function(self, info_queue, card)
        info_queue[#info_queue + 1] = G.P_CENTERS[card.ability.mod_conv]
        return { vars = { card.ability.max_highlighted, localize { type = 'name_text', set = 'Enhanced', key = card.ability.mod_conv } } }
    end,

this is vanilla remade hierophant but what does mod_conv stand for?

vital wren
#

mod_conv is a variable that gets processed by the game automatically to apply the enhancement listed. in this example it will be applying bonus. if you change that key to a different enhancement's key, it will give that enhancement instead

fickle gust
#

target:SMODS.destroy_cards(card, nil, nil, true) doesn't work either

thorn basin
#

@dreamy thunder
I'm trying to make a credits UI window but for some reason when I make a node for the black window, these white corners always show up...
how can I remove them and make the black window like the other windows (with the dark shade underneath)?

dreamy thunder
#

Gimme a sec

dreamy thunder
#

in it's config

thorn basin
dreamy thunder
#

you should also be able to build your UI in root

thorn basin
dreamy thunder
#

instead of making another seperate black box

thorn basin
#

oh I see

dreamy thunder
#

maybe that might be it cuz i honstly dont know 😔

#

this is what i did with the root of my config ui

#

-# tho i must mention you don't need the G.UIT.R part here

thorn basin
#

........wrong channel dude

#

...

#

of course he deleted it

dreamy thunder
scarlet vector
#

(:

thorn basin
scarlet vector
#

ok

#

mb

#

:p

thorn basin
#

I guess I can build my UI in the root then

#

thx for the help Revo!

dreamy thunder
#

No worries

sleek valley
#

does anyone know how i could make a config toggle that adds or removes content (blinds, jokers, etc.)?

agile narwhal
#

does anyone know how i can still run calculate on a debuffed joker

mystic river
frosty dock
frosty dock
#

yw

wanton jolt
#

for Voucher requires, can i set a global variable?

#

as in

SMODS.Voucher {
    key = "peltmarket",
    atlas = 'inscryptionVouchers', pos = { x = 0, y = 1 } ,

    requires = { 'v_felijo_beartrap', G.GAME.felijo_pelts_enabled}, -- HERE

    cost = 10,
    config = {},

    loc_vars = function (self, info_queue, card)
        return {}
    end,
    redeem = function (self, card) 
        G.GAME.felijo_pelts_sale  = true
    end,
    unredeem = function (self, card) 
        G.GAME.felijo_pelts_sale  = false
    end,
}
mystic river
#

i don't believe that would work, but you can define an in_pool function

#

right, that would definitely fail, because it would assign the current value of G.GAME.felijo_pelts_enabled (probably nil) to requires[2] and then never look at it again after the voucher was initialized

wanton jolt
#

oh right

#

it said it couldnt index GAME

mystic river
#

that would happen if G.GAME wasn't a table when the voucher was initialized. which doesn't surprise me

wanton jolt
#

how do i check if a voucher has been redeemed? i can't find it in the VR wiki FAQ

mystic river
#

you can use SMODS.find_card on vouchers

blazing helm
#

how do i add custom extra info boxes to a joker like white stake in this case? (idk what its called so i can look it up in the docs >.<)

mystic river
#

info queue

wanton jolt
#

that would be on an area like G.jokers no?

mystic river
wanton jolt
#

i dont even remember such an area

mystic river
#

i don't remember what it's called, but redeemed vouchers are stored there so they can use their calculate functions if they have one

wanton jolt
#

ohhh

#

ohhhhh its a smods one

#

thats nice

mystic river
#

dlc_toggle is probably the wrong name for the value

sleek valley
#

i mean, it's the name i gave the toggle in my config file

mystic river
#

yes, but configs aren't stored as naked globals

sleek valley
#

oh yeah, true

mystic river
#

you want SMODS.Mods[your mod id].config.dlc_toggle

frosty dock
#

naked globals...

#

I have to steal that name

sleek valley
mystic river
#

currently there's not an elegant way to do that
smods could update how no_collection works to take a function though

sleek valley
#

that'd be nice
shame i'm not experienced enough to add the functionality myself lol

mystic river
#

that said, if this option requires a restart anyway for some reason, then you could just add no_collection = not SMODS.current_mod.config.dlc_toggle

#

this won't work very well if the option is intended to be toggleable without a restart

sleek valley
#

info_queue messages

mystic river
#

in your loc_vars function, append to info_queue

#

i'm still not 100% sure how it works but i know you can append a center directly

sleek valley
#

e.g:
info_queue[#info_queue+1] = [G placement of thing here]

mystic river
#

if you want arbitrary text, you can put a description in the localization at descriptions.Other[key] (in the form key = {name = "string", text = {"table of strings", "each line is another string"}}, just like a joker desc) and then append {set = "Other", key = key}

#

(if you want to be needlessly extra, you can lovely patch in handling for a custom set like i did. but this isn't really necessary since you can put it in Other)

sleek valley
#

I keep seeing stuff abt lovely patches, but that always seems so complicated and confusing ngl

#

Hooks i can understand, patches i dont at all

umbral zodiac
#

patches are just
hey game, look for this bit of code, insert new code before/replacing/after it

#

the syntax is a little strange but in practice they’re fairly straightforward

mystic river
#

lovely patches just modify the game code directly
this is sometimes more elegant than a hook, e.g. if you just want to do one small thing in the middle of a larger function

umbral zodiac
#

that’s pretty much it yeah

sleek valley
#

Damn, i been confused for nothing then lol

blazing helm
dreamy thunder
mystic river
elder rune
#

how do you make a Joker do something every second

gilded blaze
frosty dock
#

(affected by game speed, there's a way to get real dt that I can't name of the top of my head, use that if you don't want that)

umbral zodiac
#

i have such paranoia with adding update functions for fear of bad performance

#

even though it’s literally fine

elder rune
mystic river
frosty dock
#

it's G.real_dt

elder rune
#

close enough

wanton jolt
#

does the card being sold count as a destruction for context.joker_type_destroyed

elder rune
#

How do you make a variable change its values live when hovering over a description

wanton jolt
#

i checked it doesnt

wanton jolt
#

how do i trigger this after the card has been sold? so i can properly enforce the joker limit
(card materializes before card gets sold so if there was already 5 jokers and i enforced a check then it can't make the new joker)

#
G.E_MANAGER:add_event(Event({
                delay = 0.4,
                trigger = 'after',
                func = function()
                    ouroboros:start_materialize()
                    return true
                end
            }))

red flower
#

have you tried another event

elder rune
wanton jolt
slim ferry
#

event inside the event i assume?

wanton jolt
#

like a condition event?

slim ferry
#

what

#

no like

#

wait

#

idk actually

red flower
wanton jolt
#

i just made it so the initial card doesnt take space instead

primal robin
frosty dock
#

it's not bad in isolation, what makes it bad is running expensive calculations every frame

#

like how Cloud Nine works in vanilla, you shouldn't be doing that all over the place

long sun
#

is Phanta too big now 😭

#

or is my computer failing

#

probably the latter

#

reboot time

red flower
#

download more ram

long sun
#

(i suspect it's failing, as it randomly changed to the lowest resoution earlier for no reason with no input)

#

and then discord crashed

#

okay i'm gonna commit my changes first, juuuuuuust in case

#

this'll spoil some things i did for Cold Beans, but it's coming out this week anyway so whatevs

rapid stag
#

anyone got the documentation on the arguments that SMODS.add_card() supports?

daring fern
loud summit
#

how do you animate a card moving to a specific screen location

long sun
thorn basin
#

hey @red flower
So I tried out the code you sent me for the credits and I see that it looks way more efficient than normally making every single G.UIT.T
But I was wondering if it was possible to add a node before the modNodes
Tried like this but sadly it doesn't work

loud summit
long sun
#

ah, you should draw from G.discard in that case

rapid stag
loud summit
long sun
#

unsure what you mean

#

which area is this card in?

loud summit
#

have you played cloverpit

loud summit
rapid stag
#

okay well my patch is working, it's just not... working?

long sun
#

oh like so you mean you want to slide a card in from G.discard

loud summit
#

yeah

long sun
#

what happens after?

loud summit
#

without actually moving it

loud summit
#

then it slides back

long sun
#

ohhh so you're adding a card to G.play to score

#

and then returning it

#

like, When hand scores, a previously discarded card counts in scoring

loud summit
#

yeah

#

im making it look cooler

#

and also for a joker im planning

long sun
#

ah i see ^^

#

you may need to make a cardarea for that then

#

i wouldn't know though

loud summit
#

dam

rapid stag
red flower
rapid stag
#

how do you do this custom cardarea stuff n cirPls

thorn basin
red flower
#

yes

thorn basin
# red flower yes

I tried like this but it doesn't show up
(at least it doesn't crash now)

red flower
#

it shouldnt be a text node but also it shoud be nodes = modNodes like in the code i sent

thorn basin
#

what type of node should it be?

red flower
#

row or column

thorn basin
#

it works now, thank you so much!

steady wind
#

how would i go about making a deck that doesn't allow certain booster packs to appear? say i want to remove all buffoon packs from appearing like in jokerless? (nvm i figured it out)

loud summit
#

how do i make a 100% fake card thats just for visuals

#

ie creating or destroying it wont trigger anything

rapid stag