#💻・modding-dev

1 messages · Page 509 of 1

manic rune
#

how did you make it worse 😭

dreamy thunder
#

😭

manic rune
#

/j /j

oak meadow
#

" upg
rade"
and
"ugprade"

lament agate
#

REVO ALREADY ANSWERED

#

just do what revo said

subtle merlin
#

not exactly, after an amount of time it changes a random thing negatively, and the time before the next negative thing is shortened. Eventually the timer will shorten to 0 seconds and that ends your run

manic rune
#

another tip, fix your dang indentation vro 🥀

wintry solar
#

hmmm bepis this is not the way I would have gone about making an easing progress bar 🤣 I'd have just made the current version work with easing

oak meadow
#

ok i formatted

wintry solar
lament agate
subtle merlin
manic rune
#

you can actually change all progress_bar to ease_progress_bar and there wont be any issue i think

#

haya

oak meadow
#

me when my entire joker says chips, but the dastardly mult_mod wasn't changed:

manic rune
#

mult_mod??

#

use chips and mult instead pls :3

slim ferry
#

mult_mod is ancient

#

afaik

oak meadow
#

its in the examples okay

wintry solar
#

I would just make progress_bar ease by default and have a flag to make it not ease

slim ferry
oak meadow
#

do i just replace mult_mod and chips_mod with chips and mult

slim ferry
#

yeah

oak meadow
#

kk

ancient mango
#

wtf are these

slim ferry
#

well if its +chips and mult yes

#

unused

lament agate
#

mult_mod is for some message or sound fuckery

manic rune
slim ferry
#

well right one is just orange stake

subtle merlin
ancient mango
#

but they arent in game

slim ferry
#

the right one is orange stake wdym

ancient mango
#

ik theyre stakes

wintry solar
#

well considering there are only 4 uses of it and they can't actually change when you can see them I don't think it'll matter 😂

manic rune
#

i think progress bars should always have easing anyways

wooden badge
#

Returning to modding after a little hiatus so a bit rusty - I'm making a new deck, how can I modify the spawn rate for certain booster packs?

#

It's easy to access regular card types in the shop eg G.GAME.tarot_rate but what about specific booster pack types. Is there a way to eradicate certain ones from a run entirely?

manic rune
#

probably remove them from G.P_CENTER_POOLS.Booster

wooden badge
#

would that be through a lovely.toml edit?

#

or in my mods actual script

subtle merlin
#

now that the tangent about my horrid code is done, may i ask abt the "ROOT node without a parent" thing again?

slim ferry
oak meadow
#

why does the scaling effect not happen twice when i have both jokers (it happens once on ante end no matter what, but is supposed to happen twice when you have the sweden joker)

slim ferry
#

you can only return once i think?

manic rune
slim ferry
#

yeah its used by challenges

manic rune
#

yeah what he said then

wooden badge
oak meadow
#

ok i think i get it

oak meadow
#

it didnt

manic rune
#

you can do this??

slim ferry
#

i think it might just basically ignore the do because theres no for loop

#

but yeah that shouldnt be there

oak meadow
#

vscode told me to do it

subtle merlin
#

anything after a return will not run unless the return is in a false if statement

slim ferry
manic rune
#

u might want to use SMODS.merge_effects in this case

oak meadow
#

now it tells me to remove it

#

how do i use smods.merge_effects

manic rune
#
if context.end_of_round and context.main_eval and context.beat_boss and not context.blueprint then
  local ret = {{message = localize("k_upgrade_ex"), colour = G.C.MULT, card = card}}
  card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
  if next(SMODS.find_card("j_tmod_sweden")) then
    card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
    ret[#ret+1] = {message = "Teamwork!", colour = G.C.CHIPS, card = card}
  end
  return SMODS.merge_effects(ret)
end
#

probably smt like this?

oak meadow
#

how unexpected: 4 more errors have just shown up
and the one that balatro immediately throws at me makes 0 sense

manic rune
#

i can already tell you are missing an end

oak meadow
#

ok ty

slim ferry
#

before hand scores

#

like midas mask, to-do list, space joker

manic rune
#

that exists?

slim ferry
#

ive never heard of context.start

manic rune
#

same

#

are you sure this is not a custom context

slim ferry
#

i feel like it is

daring fern
slim ferry
#

this has a list of everything that gets put after context. near the top

manic rune
#

its not all documented, which is annoying

oak meadow
#

yay it all works excellently

subtle merlin
wintry solar
#

we would never add a context.start that's remarkably vague as to what it does

manic rune
dreamy thunder
#

find the event you're trying to create a context for and slap a SMODS.calculate_context() in there

red flower
#

<@&1133519078540185692>

manic rune
#

<@&1133519078540185692>

#

damn it im slow

livid scroll
#

🔫

manic rune
#

thanks :3

floral narwhal
distant junco
#

whyd i get kicked

#

wtf

#

anyways

#

i tried a different idea and le crashe

slim ferry
#

there is already a context for drawing cards

distant junco
#

yeah i know thats the one i used

red flower
slim ferry
#

oh yeah lmao 😭

#

thats the loc_vars arguments

distant junco
#

OH YEAH

slim ferry
#

it should be self, context, card

distant junco
#

im so bad at this sometimes

red flower
#

self card context

slim ferry
#

oh

#

or that

red flower
#

i recommend setting up lsp it autocompletes it for you

distant junco
#

lsp?

red flower
distant junco
#

yeah ive got that

#

i just forgor

slim ferry
distant junco
#

it gives suggestions at the very least

#

you have to make it autocomplete by pressing tab and stuff

slim ferry
#

literally all it ever did was be annoying turn my true's into tonumber when i try to press enter

distant junco
#

even then, not everything shows up

wintry solar
#

lsp just ate my RAM and made my autocomplete super slow

red flower
slim ferry
#

where am i supposed to set that up

red flower
#

it's in the link i just sent 😭

distant junco
#

it doesnt autocomplete bro

red flower
#

well your vscode is cursed then

distant junco
#

i think yours is rigged

#

hacker noob

rotund sable
#

Then is mine rigged too?

distant junco
#

yeah

#

youre all hacker noobs

slim ferry
distant junco
#

ok another question: in

update = function(self, card, dt)

what does dt refer to

slim ferry
#

deltatime

red flower
#

delta time, time since the last frame

distant junco
#

ah ok

red flower
slim ferry
#

is the path to smods the path to smods from the location of the luarc file or just the file path from the top directory

red flower
#

it's relative to the luarc yeah

red flower
slim ferry
#

this is what i get for having my mod on my desktop huh

#

.. gaming 🎉

#

also where is lovely/dump

red flower
#

in the mods folder

slim ferry
#

because i did the smods stuff but now its complaining about that there is no global SMODS already

red flower
#

that means the path for smods is probably not correct then

#

i think it can also be the absolute path

#

also let it load for a bit because it takes some time to load all the lsp stuff lol

slim ferry
red flower
#

im not sure tho i use the relative one because i just code in the mods folder lol

feral topaz
#

where should print() messages show up?

red flower
#

the lovely console or the game itself if you have debugplus

feral topaz
#

ok thanks

rotund sable
feral topaz
#

will debugplus override lovely displaying the prints()?

red flower
#

no

feral topaz
#

ok good

rotund sable
# rotund sable I swear I had it being in absolute paths

this is my luarc.json

{
    "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
    "workspace.library": ["C:\\.lib/smods", "C:\\.lib/balatro","C:\\.lib/JokerDisplay", "${addons}/love2d/module/library"],
    "runtime.version": "LuaJIT",
    "runtime.special": {
        "love.filesystem.load": "loadfile"
    },
    "workspace.checkThirdParty": false
}
slim ferry
#

yeah i also did end up doing absolute paths]

#

which worked

red flower
#

oh yeah i removed the runtime version because it was complaining a lot for some reason

worthy stirrup
#

I have this a code, How would go with adding an extra button but for only one specific joker?

red flower
#

wrap the if condition in if self.config.center.key == "j_modprefix_key" then

#

also i recommend making the menu function a local or giving it a more unique name

worthy stirrup
#

yea, i meant to do that

#

I should also start with actaully coding a second button to appear

modest dock
#

hi, what can i do to stop a vanilla blind from appearing in pool?
i would like only certain blinds to appear if a specific joker is owned

#

Boss blinds at least

worthy stirrup
#

Currently the code just spawns the sell button

daring fern
modest dock
#

Thank you!

daring fern
#

Also you should probably hook get_new_boss instead.

modest dock
#

Ok ill look into that

#

Ty

worthy stirrup
#

Ive got this which i know is wrong as a second button isnt appearing but im not sure why

#

wait its overlapping

#

1s

worthy stirrup
# worthy stirrup

chaning the second button to br didnt help so im not sure how to fix it

oak meadow
#

what would i have to do to alter Judgement to only pull jokers from a specific pool
what i have:

    key = 'boxofcats',
    set = 'tarot',
    atlas = 'carrot',
    pos = { x = 0, y = 2 },
    use = function(self, card, area, copier)
        G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.4,
            func = function()
                play_sound('timpani')
                SMODS.add_card({ set = 'Joker' })
                card:juice_up(0.3, 0.5)
                return true
            end
        }))
        delay(0.6)
    end,
    can_use = function(self, card)
        return G.jokers and #G.jokers.cards < G.jokers.config.card_limit
    end
}```
daring fern
oak meadow
#

kk

#

how do i make pools i dont know that but ive seen it before

worthy stirrup
daring fern
toxic hound
#

even when pixel smoothing is off there is still some blurring between pixels, does any know why this is or where it comes from in code?
(found it its G.CANVAS:setFilter('linear', 'linear'))

gusty iron
#

How would I make a voucher make it so that all Mult Gained is +50% more?

daring fern
gusty iron
#

okay fire

#

what's the original function so i can have a reference?

faint yacht
#
SMODS.calculate_individual_effect = function(effect, scored_card, key, amount, from_edition)
    -- ...
    if (key == 'mult' or key == 'h_mult' or key == 'mult_mod') and amount then
        if effect.card and effect.card ~= scored_card then juice_card(effect.card) end
        mult = mod_mult(mult + amount)
        update_hand_text({delay = 0}, {chips = hand_chips, mult = mult})
        if not effect.remove_default_message then
            if from_edition then
                card_eval_status_text(scored_card, 'jokers', nil, percent, nil, {message = localize{type = 'variable', key = amount > 0 and 'a_mult' or 'a_mult_minus', vars = {amount}}, mult_mod = amount, colour = G.C.DARK_EDITION, edition = true})
            else
                if key ~= 'mult_mod' then
                    if effect.mult_message then
                        card_eval_status_text(effect.message_card or effect.juice_card or scored_card or effect.card or effect.focus, 'extra', nil, percent, nil, effect.mult_message)
                    else
                        card_eval_status_text(effect.message_card or effect.juice_card or scored_card or effect.card or effect.focus, 'mult', amount, percent)
                    end
                end
            end
        end
        return true
    end
    -- ...
end
plucky zenith
#

I'm having an issue with multiples of my tag. Just one processes fine, but if there are more than one then they all process before the first finishes, which causes booster packs that come from them to open over the top of each other instead of processing one at a time. What am I missing?

apply = function(self, tag, context)
    if context.type == 'shop_start' then
        local logger = adc_get_logger()
        local lock = tag.ID
        G.CONTROLLER.locks[lock] = true
        tag:yep('+', G.C.ADC.PLUM, function()
            local booster = SMODS.add_card( { set = 'Booster', area = G.play })
            booster.T.x = G.play.T.x + G.play.T.w / 2 - G.CARD_W * 1.27 / 2
            booster.T.y = G.play.T.y + G.play.T.h / 2 - G.CARD_H * 1.27 / 2
            booster.T.w = G.CARD_W * 1.27
            booster.T.h = G.CARD_H * 1.27
            booster.cost = 0
            booster.from_tag = true
            G.FUNCS.use_card({ config = { ref_table = booster } })
            booster:start_materialize()
            G.CONTROLLER.locks[lock] = nil
            return true
        end)
        tag.triggered = true
        return true
    end
end
manic rune
dreamy thunder
#

the vanilla ones use new_blind_choice

#

idk if it makes a difference though

plucky zenith
dreamy thunder
#

well even if they come from a joker

#

why'd you need them to process in the shop?

manic rune
dreamy thunder
#

you could probably add a check for it to not trigger when a booster pack is already open

plucky zenith
#

They're won at the end of the round. I'd actually RATHER them be opened then, but someone here suggested moving it to shop_start because of this issue. It made no difference though - happens in both places.

plucky zenith
manic rune
#

ic

plucky zenith
#

Thanks

red flower
#

i think that context specifically re-checks after each booster but im not sure

oak meadow
#

this is either something about the pools (bottom) or catner (top of jokers)
i cant tell

#

please help me fix

manic rune
#

its object type yeah

#

pretty sure rarity's key is modprefix_raritykey

oak meadow
#

yeah that makes sense

#

still no worky, same error

#

ok wait no i just dont listen

#

ok i did it how you told me to
and yeah still no worky same error

manic rune
#

have you even made the rarities yet

oak meadow
#

wdym

manic rune
#

thats a custom rarity, isnt it

#

you have to make it first

oak meadow
#

no

manic rune
#

check SMODS.Rarity

manic rune
plucky zenith
# plucky zenith I'll give this a try

So when I try to check G.STATE to make sure we're not in a booster pack, it's always G.STATES.SHOP and never G.STATES.SMODS_BOOSTER_OPENED.

Am I checking this wrong, or is there a stack of states that I need to be checking?

if context.type == 'shop_start' and G.STATE ~= G.STATES.SMODS_BOOSTER_OPENED then```
stiff quiver
#

I have a question, is it possible to apply a shader to the whole screen?

oak meadow
#

i thought i could do that for individual jokers
im just stupid

manic rune
stiff quiver
#

I'll look into it, thanks

oak meadow
#

(boxofcats is near the end)

manic rune
#

its set = "Tarot", not "tarot"

oak meadow
#

huh, it let me autofill to "tarot"

manic rune
#

shrug

gilded blaze
#

😭 why is this function not called

#

it's clearly right there, yet print failed

#

if I'm not wrong, this function handles setting usage count and last card used for Fool to work
yet Fool still works, while my modded Fool doesn't

#

wtf

manic rune
#

are you sure its set is Tarot

#

🤔

gilded blaze
#

its set is Divinatio

#

the condition should check for Tarot, Planet or Divinatio

#

I even put print right there

#

but print did not work

red flower
#

can i see the check

gilded blaze
oak meadow
#

the joker catner only procs for once cat joker
(itself)
no more than itself is having any effect for some reason

manic rune
#

just a guess but maybe modded sets should have the mod prefix too?

gilded blaze
#

the thing is

#

print did not work

#

I tested with Tarot and Planet as well

manic rune
#

oh yeah its outside that check, hm

gilded blaze
#

but G.GAME.last_tarot_planet_divinatio remained nil

red flower
gilded blaze
#

what doesn't print

#

I just put print('working')

red flower
#

the print lol

#

does it say working if you use a normal tarot

gilded blaze
#

print is outside the check

red flower
#

thats not what i asked tho

gilded blaze
#

print never worked

manic rune
#

N' meant whether the print works when you are using a normal tarot card

gilded blaze
#

so it seems to me that the function is never called

#

wtf

red flower
#

it might be another mod messing with it

gilded blaze
#

how does Fool even work

#

if the function doesn't

#

yet it works

#

that's driving me nuts

red flower
#

it works for me

#

i used aiko's patch lol

gilded blaze
#

oh

#

there's more on that?

red flower
ripe kestrel
#

how can i check the final chips of the current hand so basicly check if theres fire

manic rune
#

mult * hand_chips?

#

no wait, i think thats only during scoring, hm

gilded blaze
#

print is not inside any checks wtf WHY IS IT NOT PRINTING

#

feels like anything but my patch inside the function works

#

nvm I found the culprit: Incantation

#

damn

red flower
#

lol

gilded blaze
#

absurd Ig

#

Incantation completely overrides the function

#

for quantity parameter to work

red flower
#

does overflow do the same

gilded blaze
#

fortunately it doesn't

#

I'm keeping this comment for my mentality sake

simple locust
#

lmao

manic rune
#

why r there two huy

simple locust
manic rune
#

true

distant junco
#

gurh why is do_reset underlined on 604

subtle merlin
gilded blaze
#

Huy is the second most common first name in Vietnam lmao

simple locust
distant junco
manic rune
#

which black color does descriptions use

distant junco
subtle merlin
distant junco
#

what the fuck

#

why is the comma so inconsistent

manic rune
#

you only need commas in tables

hidden sable
#

only needed in tables lol

distant junco
#

oh that makes sense

distant junco
#

i guess pretty much everything is tables and i just didnt realise

manic rune
#

our universe is a table

#

YOU are a table

hidden sable
#

table here, please don't be tableist

manic rune
#

i follow chairism

hidden sable
#

fuck is charism

#

lol

manic rune
#

im sorry but take your table out of here.

hidden sable
manic rune
hidden sable
#

it's a term for charisma

#

bros rizzing up tables like what

distant junco
#

pleas eno

manic rune
#

in order to master ui you must learn to rizz tables

subtle merlin
brittle yacht
#

ok so what should it look like? lol

hidden sable
#

good table organization is like key to making ui

#

so you don't make a ui gun and shoot your ui self

manic rune
#

mhm

hidden sable
#

or make a ui truck to run over a ui family of ui four

manic rune
#

my favourite way of organizing ui nodes is only dropping a line when its nodes

rocky plaza
manic rune
#

it looks organized enough

hidden sable
#

that's how i do it too

#

still unreadable as shit but

#

it's slightly less unreadable

manic rune
#

true

rocky plaza
# brittle yacht ok so what should it look like? lol

this should be correct now

calculate = function(self, card, context)
  local other_joker = nil
  local has_diamond = false
  if context.before then
    for _, playing_card in ipairs(G.play.cards) do
      if playing_card:is_suit(card.ability.extra.suit) then
        has_diamond = true
        break
      end
    end
  end
  if has_diamond then
    -- blueprint copy effect here
  end
end
#

unless i forgot something again

subtle merlin
#

even leaving and coming back to it later didn't help 😭

brittle yacht
rocky plaza
brittle yacht
#

ok nvm then

brittle yacht
#

oop

#

nvm i put it in the wrong file

brittle yacht
#
    key = 'diamond',
    loc_txt = {
        name = 'Diamond',
        text = {
            'Copies ability of {C:attention}Joker{} to the right if played hand contains a {C:diamonds}#1#{} suit'
        }
    },
    atlas = 'diamond',
    pos = { x = 0, y = 0 },
    rarity = 3,
    cost = 9,
    unlocked = true,
    discovered = true,
    blueprint_compat = false,
    config = { extra = { suit = 'Diamond' }, },

    loc_vars = function(self, info_queue, card)
        if card.area and card.area == G.jokers then
            local other_joker
            for i = 1, #G.jokers.cards do
                if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i + 1] end
            end
            local compatible = other_joker and other_joker ~= card and other_joker.config.center.blueprint_compat
            main_end = {
                {
                    n = G.UIT.C,
                    config = { align = "bm", minh = 0.4 },
                    nodes = {
                        {
                            n = G.UIT.C,
                            config = { ref_table = card, align = "m", colour = compatible and mix_colours(G.C.GREEN, G.C.JOKER_GREY, 0.8) or mix_colours(G.C.RED, G.C.JOKER_GREY, 0.8), r = 0.05, padding = 0.06 },
                            nodes = {
                                { n = G.UIT.T, config = { text = ' ' .. localize('k_' .. (compatible and 'compatible' or 'incompatible')) .. ' ', colour = G.C.UI.TEXT_LIGHT, scale = 0.32 * 0.8 } },
                            }
                        }
                    }
                }
            }
            return { main_end = main_end }
        end

        return { vars = { localize(card.ability.extra.suit) } }

    end,

    calculate = function(self, card, context)
          local other_joker = nil
          local has_diamond = false
          if context.before then
            for _, playing_card in ipairs(G.play.cards) do
                  if playing_card:is_suit(card.ability.extra.suit) then
                       has_diamond = true
                    break
                  end
            end
          end
          if has_diamond then
            local other_joker = nil
            for i = 1, #G.jokers.cards do
                if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i + 1] end
            end
            return SMODS.blueprint_effect(card, other_joker, context)
        end
    end
}```
rocky plaza
brittle yacht
#

yeah

#

idk if it's just cause of the diamond suit not detecting or something

rocky plaza
#

after the first for loop put a sendDebugMessage(has_diamond)

brittle yacht
#

ok hold up

rocky plaza
#

see if has_diamond is true

subtle merlin
brittle yacht
#

i didnt even get a debug mesage vro 😭

rocky plaza
#

ok then just print it then

#

do you have debugplus?

#

it should make seeing the prints a lot easier

brittle yacht
#

false

manic rune
rocky plaza
#

oh

brittle yacht
#

uhhh

rocky plaza
#

yeah i think it keeps on getting reset

#

hold on

#

i think it might be better to put the has_diamond inside config.extra

#

so that way it doesnt continuously get reset to false

manic rune
#

probably this

#

you dont want to use context

brittle yacht
#

this still dont work 😭

#

ts pmo

manic rune
#

what joker r u using to test the blueprint effect

brittle yacht
#

joker

#

jimbo

manic rune
#

hm

#

put a print inside if has_diamond then to see if it ever runs

#

OH WAIT

#

your card.ability.extra.suit is Diamond

brittle yacht
#

?

manic rune
#

it needs to be Diamonds

#

dob

#

sob

brittle yacht
#

.

rocky plaza
#

well that would explain why has_diamond was false

manic rune
#

mhm, but limiting it to context.before wasnt a very good idea anyways

rocky plaza
#

oh my god i just realized why it would limit the copy effects to jokers that use context.before

#

fml

brittle yacht
#

it works now

#

thanks guys 🙂

long sun
#

is there a way to check if the player is in a round?

#

or do i need to keep track of that manually

sturdy compass
#

There’s definitely a G.STATE for it

long sun
#

ohai astra :D

sturdy compass
#

I just forget which one

#

-# also hi Ghost :D

long sun
#

hi :3

#

will check it out

rocky plaza
#

G.GAME.blind i think?

long sun
#

will give that a go

long sun
rocky plaza
#

does anyone know why in the update function, i always get 0 when printing dt?

slim ferry
#

if i had to guess its probably because the number is very smalll

sturdy compass
#

I’d imagine it gets rounded up yeah

slim ferry
#

if it gets rounded up it would always be 1

sturdy compass
#

Down*

rocky plaza
#

ok i tried this and it still kept on printing 0 even after a few seconds

#

is dt really that small?

#

im running balatro on a smooth 288 fps so 1/288 on average shouldnt be too small for it to print out

red flower
#

after a few seconds the total dt should be equal to those few seconds

#

do you have any other mods that could be messing with it

rocky plaza
#

no, just debug plus and steamodded

red flower
#

try G.real_dt as well

rocky plaza
#

it worked

formal parrot
#

Delta time crisis

red flower
#

idk what's up then
you want to use real dt anyway if youre animating something

rocky plaza
#

ok good to know then

modern kindle
#

Good schmorning chat

red flower
#

hi silly

modern kindle
#

Hi n

#

How was the stray gaming

#

Dd you get good progress in

slim ferry
#

what??? i made this card so long ago, why is it coming with this now?

red flower
#

it was good i think im halfway through

red flower
slim ferry
#

but what does it even mean with need check nil

modern kindle
#

I should set up lsp stuff i still haven't

#

How do you even do that again

subtle merlin
#

how can i display a message like the one The Psychic displays but at any time with a custom message?

red flower
# slim ferry but what does it even mean with need check nil

im guessing youre using pseudorandom_element, that can return an element or nil if none, so you need to check if the result is nil or the function might crash
maybe you dont actually need to because your logic makes it so it's never nil but vscode doesn't know that

slim ferry
#

im using pseudorandom element yeah

#

but the consumable's can_use should make that always have something

red flower
#

yeah but vscode doesn't know balatro

#

it only sees that function

slim ferry
#

i think it should learn balatro then smh

modern kindle
#

True

red flower
modern kindle
#

Thanks bestie

#

Ill roll out of bed soon

chrome widget
#

Me too lol

red flower
#

hi winter!!

modern kindle
#

no..i dont think it is..

red flower
#

u are lacking love

modern kindle
#

why dont you fix that

ripe kestrel
#
SMODS.Joker {
    key = 'RBand',
    loc_txt = {
        name = 'Runald\'s Band',
        text = {
            "{C:chips}+#4#{} chips",
        }
    },
    rarity = 1,
    atlas = 'RiskOfJokes',
    pos = { x = 2, y = 1 },
    cost = 5,
    eternal_compat = false,
    config = { extra = { chips = 0, chip_mod = 4 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.chips, card.ability.extra.chip_mod } }
    end,
    calculate = function(self, card, context)
        if context.final_scoring_step and (hand_chips * mult > G.GAME.blind.chips) and not context.blueprint then
            card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod
            return {
                message = localize('k_upgrade_ex'),
                colour = G.C.CHIPS
            }
        end
        if context.joker_main then
            return {
                chips = card.ability.extra.chips
            }
        end
    end,
}

why does it appear as nil?

proven adder
#

"{C:chips}+4{} chips"

modern kindle
#

is meant to represent the value in loc vars, so #1# is the first value in loc vars and etc

#

oop

#

'#'

#

i forgot discord formatting

#

im not yellinhg

#

im sorry

ripe kestrel
#

excatly i want it to show chips, since it scales

subtle merlin
modern kindle
#

yes, but '4' doesnt exist you have up to 2 in loc vars

#

you have extra chips and chip mod

ripe kestrel
#

Ahhh

#

i though it was the config extra mb

#

Got it thx

long sun
#

is the has_no_rank check necessary here?
if context.individual and context.cardarea == G.play and not SMODS.has_no_rank(context.other_card) and context.other_card:get_id() == 8 then

normal crest
#

nop

long sun
#

gotcha :D

#

thanks

normal crest
#

Cards with no rank have a random id

long sun
#

wait does that mean they could coincidentally have an ID of 8? ^u^;

normal crest
#

nu, it's a random negative id

#

you can look at Card:get_id

long sun
#

ah i see ^u^

#

thanks

knotty orchid
#

Is there any mod that adds a new collection section to get references?

red flower
#

cardsleeves?

frosty rampart
#

paperback adds paperclips to the "Other" section

long sun
#

hiya! i have a Joker that needs to trigger between discarding cards and drawing new ones

#

is that context.discard?

distant junco
#

yes

long sun
#

it's currently if not context.blueprint and context.hand_drawn and card.ability.extra.active then but that's not right

#

okay ^u^ thanks!

distant junco
#

no problem!

long sun
#

wait that doesn't seem right

distant junco
#

why

long sun
#

that applies for all discarded cards — i want it to happen after they're discarded

#

it'll happen 5 times if i discard 5 cards, eg.

distant junco
#

ah pre_discarded

long sun
#

not that either

distant junco
#

oh

long sun
#

that's before the cards are discarded

#

i need a context that's between discarding all the cards and drawing the new ones

frosty rampart
#

I don't think there's a post_discard unfortunately

long sun
#

mm :<

#

highly unfortunate

verbal ermine
#

is there no draw function?

distant junco
verbal ermine
#

yeah i was going to say if there's a draw check you could just use that along with the discard

long sun
#

hand_drawn is after the cards are drawn

#

i was using this previously but it's not what i need

distant junco
#

sozzers

gaunt thistle
#

<@&1133519078540185692>

karmic creek
#

ok

jolly shadow
long sun
#

it's not on the wiki ^^;

distant junco
#

try this!

frosty rampart
#

smods documentation strikes again (iirc context.initial_scoring_step isn't on the wiki either, which I had to use recently)

long sun
#

aha :D!

distant junco
#

thank you please ping reply twin

long sun
#

OMG HEHEHE

#

not working :<

distant junco
#

fuck

verbal ermine
long sun
distant junco
#

why does the first true just end instantly

frosty rampart
verbal ermine
#

shucks!

distant junco
long sun
#

it's setting itself active, i needed that when it used draw_to_hand

#

as that happens with plays and when the blind is selected, too

errant arrow
#

im struggling with getting alternate calculations to happen.
i want my jokers to detect when a specific joker is next to it, and get empowered by it.

verbal ermine
#

not sure if i'm reading up on documentation correctly but from my understanding this would check individual cards that are currently in play right?

#

or individual would call for specific effects then other card would the check itself

jolly shadow
#

yes, goes once for every played card

#

i believe

verbal ermine
#

alright sick

#

just needed second thought

#

sweeeet yeah that worked perfectly

ocean sinew
#

ngl

#

I should release that brainrot mod

#

I did it as a joke but It's 🔥

#

Do you agree edward robinson

jolly shadow
ocean sinew
#

Your bestfriend

#

from childhood

#

steve

#

from minecraft

errant arrow
#

here's the code

maiden phoenix
# errant arrow here's the code

It's G.jokers.cards[i-1].config.center.key, also is_next_to_wateringcan should be initialized to false after the context check

errant arrow
#

if im understanding you right, then this should work for checking toward the left?

faint yacht
#

Check if G.jokers.cards[i-1] exists first.

#

But also the .key is j_modprefix_key format.

wind steppe
#

why doesn't my code work properly with telescope?

SMODS.Booster:take_ownership_by_kind('Celestial', {
        create_card = function(self, card, i)
            local _card, spect, scope, _planet
            if (G.GAME.used_vouchers.v_telescope) and i == 1 then
                local _hand = PSI.mostplayedhand(false)[1]
                for _, v in pairs(G.P_CENTER_POOLS.Planet) do
                    if v.config.hand_type == _hand then
                        _planet = v.key
                    end
                end
                _card = {
                    set = "Planet",
                    area = G.pack_cards,
                    skip_materialize = true,
                    soulable = true,
                    key = _planet,
                    key_append = "pl1"
                }
                return _card
            end
            for _, v in ipairs(SMODS.find_card("j_para_garagefork", false)) do
                if SMODS.pseudorandom_probability(card, 'para_garagefork', v.ability.extra.numerator,
                v.ability.extra.denominator, 'para_garagefork') then
                    spect = true
                    break
                end
            end
            if spect then
                _card = {
                    set = "Spectral",
                    area = G.pack_cards,
                    skip_materialize = true,
                    soulable = true,
                    key_append =
                    "ar2"
                }
            elseif not scope then
                _card = {
                    set = "Planet",
                    area = G.pack_cards,
                    skip_materialize = true,
                    soulable = true,
                    key_append =
                    "ar1"
                }
            end
            return _card
        end,
    },
    true
)
#

the most played hand function btw:

PSI.mostplayedhand = function(format)
    local _hand, _tally = "Straight Flush", to_big(0) -- ty vanillaremade for giving me all this code
    for _, handname in ipairs(G.handlist) do
        if SMODS.is_poker_hand_visible(handname) and to_big(G.GAME.hands[handname].played) > to_big(_tally) then
            _hand = handname
            _tally = to_big(G.GAME.hands[handname].played)
        end
    end
    if format then
        return {
            _hand,
            number_format(to_big(G.GAME.hands[_hand].chips)),
            number_format(to_big(G.GAME.hands[_hand].mult)),
            number_format(to_big(G.GAME.hands[_hand].l_chips)),
            number_format(to_big(G.GAME.hands[_hand].l_mult))
        }
    else
        return {
            _hand,
            to_big(G.GAME.hands[_hand].chips),
            to_big(G.GAME.hands[_hand].mult),
            to_big(G.GAME.hands[_hand].l_chips),
            to_big(G.GAME.hands[_hand].l_mult)
        }
    end
end
ebon shell
#

what's happening here? I've already defined and set xmult_gain but it's saying it's a nil value

wind steppe
#

i'd assume you're probably using xmult_gain instead of card.ability.extra.xmult_gain though

ebon shell
#

it also gives nil in the joker description even though I have it in the loc_vars field

wind steppe
#

which line specifically is line 43?

#

btw card.ability.extra.Xmult_mod doesn't exist in that return

#

and also that'd just be a number instead of something like "x6.25 mult"

#

rq actually. are you sure you saved the file

ebon shell
ebon shell
#

and yeah i did save the file

normal crest
#

After changing the config

wind steppe
#

yeah try that

#

the specific joker you have probably has xmult_gain as nil in its config

#

instead of the correct 0.5

ebon shell
#

ill try this

wind steppe
#

why are you savestating in balatro

wind steppe
ebon shell
wind steppe
#

whenever you want to test something new you should start a new run

#

also do you not have debugplus or something

ebon shell
#

anyway it worked the answer was in fact to start a new run

wind steppe
ebon shell
wind steppe
proven adder
#

for some reason I get a stack overflow error for using the second tarot, could someone help cus I have no clue 🙏🙏 (yes it was too long to fit in the message)

distant junco
#

hello again modding-dev chat

im trying to get my joker to display a message during gameplay after certain durations. I have got the counting fine and its all working but im not sure how to get the messages to display.

update = function(self, card, dt)
        if not G.SETTINGS.paused and G.GAME.blind and G.GAME.blind.in_blind then
            card.ability.extra.time_spent = card.ability.extra.time_spent + dt
            card.ability.extra.in_seconds_kinda = card.ability.extra.time_spent / 200 * 58
            if card.ability.extra.in_seconds_kinda <= card.ability.extra.S_rank then
                return {
                    message = 'S Rank!'
                }
            end
            if card.ability.extra.in_seconds_kinda == card.ability.extra.A_rank then
                return {
                    message = 'A Rank!'
                }
            end
            if card.ability.extra.in_seconds_kinda == card.ability.extra.B_rank then
                return {
                    message = 'B Rank!'
                }
            end

...and so on.

im guessing messages dont work in the update section since these dont do anything

i also tried

 
context.cardarea 
red flower
distant junco
#

so instead of doing return i do that

red flower
#

yes

distant junco
#

alright

#

thanks

red flower
proven adder
#

yes

red flower
#

if so it's because you're missing a strict context check

#

what happens is that youre checking the globals (which you shouldnt save directly to a global variable, use G.GAME.modprefix_variablename instead) in every context, so when both globals are true it adds the card in the next context called and every context after that
what's worse is that there is a card_added context so every time you are adding a card its creating another one because you don't reset the globals

proven adder
#

ohhh ok thanks

modern kindle
#

N is so smart

unkempt thicket
#

How can i check if the played hand contains another hand with blinds?

maiden phoenix
unkempt thicket
#

Like with a blinds code, they don't have context

maiden phoenix
#

Dont they?

dreamy thunder
#

They should support calculate iirc

unkempt thicket
#

They do?

#

I haven't made much blinds, and calculate isn't in the docs.

maiden phoenix
#

I see mentions of blind calc on the SMODS discord

dreamy thunder
#

By they definitely do

faint yacht
#

...had they not, I'd probably pull my hair out.

ebon shell
#

how do I make the message appear before the card is destroyed? simply putting start_dissolve() after the return gives this error

rotund sable
#

ok so i have

return {
    Xmult = card.ability.extra.money + (math.floor(G.GAME.dollars / 5)) * 0.1
}

and i have no idea why the talisman "attempt to compare number with table" happens here
removing the math.floor fixes this tho

maiden phoenix
#

You got a to_big func? Not sure where exactly it would be placed, maybe for the division

red flower
#

oh but if removing math.floor fixes it might be something else

rotund sable
#

wrapping it all in lenient_bignum fixed it

red flower
#

i love talisman

royal carbon
#

Is it known if there's a way to, with the recent smods probability stuff, make a probability whose chances can't be modified by Oops and the like? I want to make absolute chances for balance reasons, would just plugging 1 into the numerator field of pseudorandom_probability work?

maiden phoenix
#

I think a hardcoded value would work best

red flower
#

you can't do it with pseudorandom_probability unless you hook stuff to prevent the context
you can just do pseudorandom("seed") < 1 / odds

royal carbon
#

Oh I can still do the old way, good to know

slim ferry
#

also if youre destroying playing cards, use SMODS.destroy_card

red flower
#

if youre destroying playing cards during scoring use context.destroy_card

ebon shell
#

the system for destroying cards works fine so i don't really wanna mess with it. unless SMODS.destroy_card lets you put the message to display before card is destroyed?

slim ferry
#

youre still missing an end somewhere which is causing the crash

ebon shell
slim ferry
#

thats during scoring

#

fire effect goes during scoring

red flower
ebon shell
red flower
#

even if not i would add a stricter context check

slim ferry
ebon shell
distant junco
slim ferry
#

thats because it cant load the file

#

not anything to do with your joker

#

do assert() around your file loading line to get a more detailed error

red flower
distant junco
#

yep

sonic cedar
#

i have returned to bring up my ijiraq issue again, in which it does not mimic yorick properly

this (safe_set_ability function) was made by somecom so id be better off asking him, but it doesnt hurt to ask for help because you never know

do note that the yorick itself works fine, but once it's ijiraq with his effect it does not track, even after discarding 5 hands

printing the table shows that the initial values are indeed stored, but any changes ijiraq would make to them aren't, it isnt tracking the states

slim ferry
#

yo, rick

red flower
distant junco
#

yes

red flower
#

dunno then, it should work

distant junco
#

i will keep messing around

#

i forgot the math floor

ebon shell
#

what's the syntax for SMODS.destroy_card?

red flower
#

the only argument is either a single card or an array of cards

#

oh i forgot it has other arguments now

#

i added that lmao

#

it's cards, bypass_eternal, immediate

sonic cedar
runic pecan
#

I just suddenly have a seal idea:
"Creates a Spectral card when discarded, but has 1 in 4 chance to be destroyed. (Must have room)"
Has this one been done before?

ebon shell
#

also i can tell what bypass_eternal is but what does immediate do?

maiden phoenix
#

Optionals, immediate skips any anim and sound

runic pecan
ebon shell
#

it's giving this error, did I do something wrong?

vestal magnet
#

how do i make a joker move to a random position (shuffle itself basically) in the joker slots

distant junco
nova violet
#

if i want to take ownership of a joker to add some functionality but I still want the original functionality to work as it did, do I need to recreate the original functionality in the calculate function? or is there a way to patch new functionality without overriding the old.

frosty rampart
runic pecan
ebon shell
runic pecan
vestal magnet
#

doesnt that like shuffle all jokers

runic pecan
nova violet
ebon shell
#

why is it saying it expects end to close the if at line 42 when it clearly is there

maiden phoenix
runic pecan
runic pecan
ebon shell
#

is there any way to display the message before the card is destroyed?

runic pecan
sonic cedar
#

this crash consistently happens if i start a blind with burglar as my effect

apparently mod is being taken as a table in ease_hands_played?

#

god i wish i knew how this ability table worked

ebon shell
modern kindle
sonic cedar
#

putting the effect of burglar in him manually just crashes the game anyway

runic pecan
nova violet
#

^is there a library that can be installed to give some descriptions of functions?

sonic cedar
hidden sable
#

is it possible to make a value that can be returned in a calculate table like mult or chips

hidden sable
#

sorry i meant how

runic pecan
hidden sable
sonic cedar
hidden sable
#

get the cat version with 3 downloads

maiden phoenix
sonic cedar
modern kindle
#

Or am I misremembering

maiden phoenix
sonic cedar
runic pecan
# runic pecan And then this

The downside of this is that the extension's diagnostic system has a lot of opinions against localthunk's codes.

maiden phoenix
normal crest
sonic cedar
maiden phoenix
#

Im on phone I dont see the crash (too lazy to dl)

sonic cedar
oak meadow
#

why is this only registering one cat joker if i have it and another cat pool joker

    key = 'catner',
    loc_txt = {
        name = 'catner',
        text = {
            "Gives {C:money}+$1{}, {C:chips}+20 Chips{}, {C:mult}+15 Mult{}, and {C:mult}+x0.2 Mult{} for each cat joker.",
            "{C:inactive}Currently #1# cats.",
            "{C:inactive}'i like this cat. its a good cat.'"
        }
    },
    cost = 5,
    rarity = 2,
    pools = {
        ["cat_shop"] = true,
        ["cat"] = true
    },
    atlas = 'spr',
    --pos = { x = , y = ,}
    config = { extra = { money = 0, chips = 0, mult = 0, xmult = 1} },
        calculate = function(self, card, context)
    catcount = 0
    for i = 1, #G.jokers.cards do
        if G.jokers.cards[i].config.center.pools and G.jokers.cards[i].config.center.pools.cat then
            catcount = catcount + 1
        end
    end
    print = catcount
    card.ability.extra.money = catcount
    card.ability.extra.chips = catcount * 20
    card.ability.extra.mult = catcount * 15
    card.ability.extra.xmult = (catcount / 5) + 1
    if context.joker_main then
    return {
    money = card.ability.extra.money,
    chips = card.ability.extra.chips,
    mult = card.ability.extra.mult,
    xmult = card.ability.extra.xmult
    }
    end
end
}```
nova violet
#

got that working. thank you, its going to help a lot. one more question before i stop bugging the chat for at least 20 minutes: how did you know about Card.calculate_joker? it isnt in the documentation afaik

runic pecan
nova violet
#

gnarly

#

thanks a lot all

oak meadow
#

i made it local and nothing changed

daring fern
sonic cedar
#

yes

#

if mod < 0 then

#

and then it crashes trying to compare a number with a table

#

so for some reason mod is a table

daring fern
normal crest
# vestal magnet andddd how

if you wanted to swap position 1 and 2 you can do it this way

local swap = G.jokers.cards[1]
G.jokers.cards[1] = G.jokers.cards[2]
G.jokers.cards[2] = swap
sonic cedar
vestal magnet
#

tnks

runic pecan
oak meadow
#

look i copied the cat counting code from yahimod
idk how to change that

daring fern
sonic cedar
oak meadow
nova violet
#

i lied another question. If i want to use calculate_joker, I need to pass in context. i am going to wager that this context is the joker that i want to calculate. Is there a "get_joker_by_name" style function that I can use to get the required context?

#

im dumb, scratch that. If i am replicating the existing jokers function, i have the context

runic pecan
# oak meadow why is this only registering one cat joker if i have it and another cat pool jok...

My suggestion:SMODS.Joker { key = 'catner', loc_txt = { name = 'catner', text = { "Gives {C:money}+$1{}, {C:chips}+20 Chips{},", "{C:mult}+15 Mult{}, and {C:mult}+x0.2 Mult{}", "for each cat joker.", "{C:inactive}Currently #1# cats.", "{C:inactive}'i like this cat. its a good cat.'" } }, cost = 5, rarity = 2, pools = { ["cat_shop"] = true, ["cat"] = true }, atlas = 'spr', --pos = { x = , y = ,} config = { extra = {} }, calculate = function(self, card, context) if context.joker_main then local catcount = 0 for _,J in ipairs(G.jokers.cards) do if J.config.center.pools and J.config.center.pools.cat then catcount = catcount + 1 end end return { money = catcount, chips = catcount * 20, mult = catcount * 15, xmult = (catcount / 5) + 1 } end end }

normal crest
# sonic cedar

can you print card.ability.extra right before you calculate_joker and after you set_ability

oak meadow
#

it still only counts 1 cat joker

normal crest
#

odd

sonic cedar
#

124 lines of 3

normal crest
normal crest
runic pecan
sonic cedar
oak meadow
#

the joker im testing with it is this one:

SMODS.Joker {
    key = 'Kat',
    loc_txt = {
        name = 'cat.',
        text = {
            "I am cat. I am cat. I am cat card. I am only cat.",
            "{C:inactive}'help im stuck getting tons of cat. jokers from my box of cats'"
        },
        atlas = 'spr',
        --pos = { x = , y = ,}
        cost = 5,
        rarity = 1,
        pools = {
            ["cat"] = true
        }
    }
}
normal crest
sonic cedar
vestal magnet
#

nvm it worked

vestal magnet
#

it just decided to swap itself with itself the first time

runic pecan
normal crest
oak meadow
#

where would i even add it (if u feel like adding it yourself the prefix is tmod)

sonic cedar
inland silo
#

could i perchance get some help debugging?

normal crest
sonic cedar
runic pecan
inland silo
#

do i just paste the code or is there a certain way to send it?

oak meadow
#

i think half of the people here need help debugging
and the other half is helping debugging
also just send the file or if its isolated to just one part send the joker or wtvr

runic pecan
vestal magnet
oak meadow
inland silo
#
    key = "creep_josh",
    name = "Joshua the Creepy",
    unlocked = true,
    discovered = true,
    rarity = 2,
    cost = 6,
    atlas = "Joshs Jokes",
    pos = {x = 4, y = 0},
    config = { mult = 0 }, 
    
    loc_txt = {
        text = {
            'Gain +1{X:mult,C:white} Mult{} per discard left',
            'at round end. Lose {C:money}$1{} per 2 discards.'
        }
    },

    
    calculate = function(self, context)
        if context.end_of_round and not context.blueprint then
            local discards = G.GAME.round_resets.discards_left or 0
            self.ability.mult = (self.ability.mult or 0) + discards
            ease_dollars(-math.floor(discards/2))
            return {
                message = localize{type='variable',key='a_mult',vars={discards}},
                mult_mod = discards
            }
        end
        if context.joker_main then
            return { message = "Rain!", Xmult_mod = self.ability.mult or 0 }
        end
    end
}
normal crest
#

also describe the issue or send the crash log if there is one

inland silo
#

im trying to get it to gain 1 mult per remaining discard at end of round and deduct $1 per two remaining

#

it isnt crashing but it just does nothing

sonic cedar
#

self.......

oak meadow
#

pretty sure its self, card, context not just self, context

runic pecan
oak meadow
#

how do i print something

sonic cedar
#

print()

runic pecan
oak meadow
#

ok i just didnt know the syntax for it

gray horizon
#

Yo guys how can make a Card that gain chips reset after a specific action in jokerforge?

runic pecan
oak meadow
#

jokes on you, im throwing a variable into it

sonic cedar
#

still works

inland silo
sonic cedar
normal crest
sonic cedar
inland silo
#

so it is setting the hands mult to 0 when scoring and at end of round it activates with +0 mult and does so on every card in hand while granting $0 for every card in hand

sonic cedar
#

it's just burglar

normal crest
#

did you add some code to do something specifically when it's burglar?

sonic cedar
#

oh and

sonic cedar
oak meadow
#

ok so
why is this joker (catner) not counting the amount of jokers you have in pool cat
the joker im testing it with is the second joker, kat/cat.

SMODS.Joker {
    key = 'catner',
    loc_txt = {
        name = 'catner',
        text = {
            "Gives {C:money}+$1{}, {C:chips}+20 Chips{},",
            "{C:mult}+15 Mult{}, and {C:mult}+x0.2 Mult{}",
            "for each cat joker.",
            "{C:inactive}Currently #1# cats.",
            "{C:inactive, s:0.8}' 'catner catner catner; catns the amount of catners that catn catners in this encatner' when'"
        }
    },
    cost = 5,
    rarity = 2,
    pools = {
        ["cat_shop"] = true,
        ["cat"] = true
    },
    atlas = 'spr',
    --pos = { x = , y = ,}
    config = { extra = {} },
    calculate = function(self, card, context)
        if context.joker_main then
            local catcount = 0
            for _,J in ipairs(G.jokers.cards) do
                if J.config.center.pools and J.config.center.pools.cat then
                    catcount = catcount + 1
                end
            end
            print("catcount")
            return {
                money = catcount,
                chips = catcount * 20,
                mult = catcount * 15,
                xmult = (catcount / 5) + 1
            }
        end
    end
}

SMODS.Joker {
    key = 'Kat',
    loc_txt = {
        name = 'cat.',
        text = {
            "I am cat. I am cat. I am cat card. I am only cat.",
            "{C:inactive}'help im stuck getting tons of cat. jokers from my box of cats'"
        },
        atlas = 'spr',
        --pos = { x = , y = ,}
        cost = 5,
        rarity = 1,
        pools = {
            ["cat"] = true
        }
    }
}

the print in catner is reached, but if i set it to the variable catcount instead of the word, it prints nothing for some reason
tell me if you need more info for anything

normal crest
oak meadow
#

i have it

#

"{C:inactive, s:0.8}' 'catner catner catner; catns the amount of catners that catn catners in this encatner' when'"

#

wrong copy paste

normal crest
#

oh I see

#

your Kat joker has everything inside loc_txt

oak meadow
#

god damn it

loud root
#

hey guys, so I was looking into the card sc and found this random parameter in the set_ability function called center

#

can someone tell me what it is please?

slim ferry
#

you can use it to find some card properties

#

card.config.center.key is the key, and i think you can do card.config.center.rarity too?

#

and probably some other stuff

oak meadow
#

ok now its working

loud root
#

I still don't get it, is it a table that contains the stats of the card?

slim ferry
#

center contains important stuff

#

like the key

#

and some other things

#

stats go in card.ability, though they more often go in card.ability.extra

loud root
#

what is "the key" you mention?

normal crest
#

a center is what defines the behavior of cards

#

at least in SMODS

oak meadow
#

how do i change the amount of money the player has when a joker triggers
"money = " isnt working

normal crest
#

it's dollars =

slim ferry
#

or any item for that matter

oak meadow
loud root
#

sry I'm new to modding and trying to figure it out slowly

normal crest
#

and the effects are hardcoded into the Card functions

loud root
slim ferry
normal crest
#

SMODS centers contain both the stats and behavior of jokers/consumables and whatever else

slim ferry
#

stats arent in card.config.center though?

#

they go in card.config or card.config.extra i thought

normal crest
#

The stuff in the center's config is copied into the card's ability table

#

It holds the initial stats would be better wording

#

at least for jokers

oak meadow
#

should i make the sprite size for my consumables the same as my jokers

normal crest
#

yes

slim ferry
#

yes, consumables just get scaled down in-game

loud root
#

btw I want to ask about how joker abilities are handled? does every joker have its own file?

misty radish
#

Can someone please help me with a thing?
Basically, I need to take the message function out of a Joker from Mayhem which says "Upgraded!" every time any valid scoring context happens. I need to put this function into my Joker that I generated from Joker Forge. How would I do this?
Here is the code for the Mayhem Joker:

    key = 'taimuresu',
    loc_txt = {
        name = 'Taimuresu',
        text = {
            "{C:attention}Gains{} {X:mult,C:white}X#1#{} Mult when",
            "{C:attention}any scoring context{} happens",
            "{C:inactive}Currently{} {X:mult,C:white}X#2#{} {C:inactive}Mult{}",
            "{C:inactive,s:0.5,E:1}This is gonna take a while...{}"
        }
    },
    rarity = 'cry_exotic',
    atlas = 'cry_joker1',
    pos = { x = 6, y = 0 },
    soul_pos = { x = 8, y = 0, extra = { x = 7, y = 0 } },
    blueprint_compat = true,
    config = { extra = { Xmult = 1, Xmult_gain = 0.0004 } },
    cost = 50,
    loc_vars = function(self, info_queue, card)
        return {vars = { card.ability.extra.Xmult_gain, card.ability.extra.Xmult } }
    end,
    calculate = function(self, card, context)
        if context and not context.joker_main and not context.blueprint then
            local myself = card
            card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_gain
            return {
                message = 'Upgraded!',
                colour = G.C.MULT,
                card = myself
            }
        end
        if context.joker_main and card.ability.extra.Xmult > 1 then
            return {
                Xmult_mod = card.ability.extra.Xmult,
                message = 'X'..card.ability.extra.Xmult..' Mult',
                colour = G.C.MULT,
                card = card
            }
        end
    end
}```

I also need to get rid of the mult function.
Here's the code for my Joker:
#
    name = "Boowomp",
    key = "boowomp",
    config = {
        extra = {
        }
    },
    loc_txt = {
        ['name'] = 'Boowomp',
        ['text'] = {
            Not putting the text here because there are 270 lines
        }
    },
    pos = {
        x = 0,
        y = 0
    },
    cost = 1,
    rarity = "boowomp_boowomp",
    blueprint_compat = true,
    eternal_compat = true,
    unlocked = true,
    discovered = false,
    atlas = 'CustomJokers',

    set_ability = function(self, card, initial)
        card:set_eternal(true)
    end
}```
slim ferry
#

as long as you load the file in some way

loud root
normal crest
#

in Mods/lovely/dump/card.lua under the Card:calculate_joker function

#

yes, all in one file, in one function

loud root
#

oh god

#

is it optimal that way or more files are more optimal?

normal crest
#

I'd suggest using multiple files, ultimately it's at your discretion

#

Putting everything into one file is not a good idea in my opinion

slim ferry
#

a lot of mods use one per item, some big ones like cryptid just make a few big files with a bunch of stuff, anything works basically

loud root
#

will go with multiple files then

#

thanks for the info

sonic cedar
#

sending these as images, maybe something missing. maybe it's the same reason yorick doesn't work either

idk im losing it

#

those images are way too big actually

verbal ermine
#

any tips on destroying specific cards on hand play? i'm struggling a tad with the documentation with it

oak meadow
#

what code would i use to put lucky cat in a pool

normal crest
#

in your objecttype add cards = { j_lucky_cat = true }

sonic cedar
verbal ermine
#

oh OH that's what i was doing wrong i was messing up the get id portion

#

1 second i'll report back

verbal ermine
#

ah wait this is a me ended thing perhaps

sonic cedar
#

Lowercase P

verbal ermine
#

1 moment

#

FAIL

#

it was also the fact i forgot save it

sonic cedar
#

thats also for specifically queens

verbal ermine
#

bless your heart

#

oh yeah i'm aware i just debugged myself queens

sonic cedar
#

oh I see

verbal ermine
#

appreciate ur help very very much isaac_grin

#

works all well

sonic cedar
#

No prob!

oak meadow
#
    key = 'eepy',
    blueprint_compat = true,
    loc_txt = {
        name = 'eepy cat',
        text = {
            "Sleeps for 3 antes, then gives  {C:chips}+300 Chips{}.",
            "#1#/3 Antes",
            "{C:inactive}'can this little goober WAKE UP ALREADY??????'"
        }
    },
    rarity = 2,
    config = { extra = { antes = 0 } },
    atlas = 'spr',
    pos = { x = 0, y = 0 },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.chips, card.ability.extra.antes } }
    end,
    calculate = function(self, card, context)
-- next line is 248
        if context.joker.main and card.ability.extra.antes == 3 then
            chips = 300
        end
        if context.end_of_round and context.beat_boss and context.main_eval and not context.blueprint then
            if not card.ability.extra.antes == 3 then
                card.ability.extra.antes = card.ability.extra.antes + 1
            end
        end
    end
}```
ok im just confused on this one (error occurs when selecting joker)
frosty rampart
#

it's context.joker_main, not context.joker.main

oak meadow
#

yeah im stupid

chrome widget
#

how dangerous is it to change a card's sort id

sonic cedar
slim ferry
#

what even is a sort id..

sonic cedar
sonic cedar
slim ferry
#

it doesnt sound like anything to me

sonic cedar
#

it's a reference id for sorting/assignment

slim ferry
#

when would that even be relevant

#

like the only place i can think of with sorting is the hand sort buttons

sonic cedar
daring fern
slim ferry
#

well yeah i figured

#

but like sorting what?

sonic cedar
#

the...the cards?

slim ferry
#

where??????

#

where would sorting cards be necessary?

jolly shadow
#

does it matter?

#

it's what they wanna do

slim ferry
#

its a vanilla thing

#

thats also not my point

#

i just want to know what the point of it is

sonic cedar
#

distinction between cards

jolly shadow
daring fern
sonic cedar
slim ferry
#

doesnt pinned sticker just put things on the left

#

or does it use the sort id to determine the order of the pinned cards

daring fern
slim ferry
#

interesting development decision

sonic cedar
#

a necessary one imo

slim ferry
#

wouldnt it make more sense to just be able to drag around pinned cards among each other

sonic cedar
#

how would it drag them?

slim ferry
#

wdym

#

i mean the player

#

you

slim ferry
#

if you have multiple pinned cards it doesnt make sense to have them in a fixed order

#

tho

#

it just says its forced to the left

#

not that you cant move them

sonic cedar
#

the left most position

#

not just left

slim ferry
#

yeah thats what i mean by forced to the left

#

all the way to the left

sonic cedar
#

if you can move them, they can be moved from the leftmost

slim ferry
#

yeah?

#

i mean like move only among other pinned cards

#

instead of having a fixed order of pinned cards

sonic cedar
#

let's say there's 2 pinned jokers

#

the joker on the very left is in the leftmost position

#

the joker next to it is ALSO in the leftmost position because that's the area it's given

#

the first pinned joker is going off of 5 cards, while the second is going off of 4

daring fern
#

How does one make it so after the cards are unhighlighted in G.play, scoring triggers again?

slim ferry
#

oh so theyre both in position 1 but the sort order seperates them?

slim ferry
#

so the sort id is just like an object key but a number?

sonic cedar
#

leftmost is relative to the area

slim ferry
#

so you can sort things

sonic cedar
#

that
that is in fact what i said at the beginning 😭

slim ferry
#

yeah but i didnt know the point of that??

sonic cedar
#

fair
but you get it now?

slim ferry
#

i do get it now

sonic cedar
#

nice

slim ferry
#

i dont see why you would want to change it though

sonic cedar
#

or do you literally just mean retriggers

slim ferry
#

you can do anything its coding

#

but i dont think its a built-in smods feature

daring fern
sonic cedar
#

ohhhhh

slim ferry
#

bunco does something thats very similar

#

try looking at that maybe?

sonic cedar
#

i know what youre talking about but i forget the card

slim ferry
#

copper cards

daring fern
sonic cedar
#

right yeah

slim ferry
#

copper cards can do the entire hand

#

its adjacent ones

#

if your entire hand is copper it rescores all of them

#

and you literally NEED at least 2

daring fern
slim ferry
#

it does that though?

sonic cedar
slim ferry
#

it even does stuff like hanging chad, retriggers, position based stuff again

sonic cedar
#

or do you mean specifically the cards IN the hand

daring fern
slim ferry
#

oh so repeating the ENTIRE scoring sequence?

sonic cedar
#

ohhh

daring fern
slim ferry
#

yeah you probably need to do fancy stuff for that

sonic cedar
#

yeah

slim ferry
#

red seal play hand

faint yacht
chrome widget
#

So hopefully manually resetting the sorting ids won't hurt me, since I only ever need to do it for jokers

sonic cedar
#

non...leftmost?

slim ferry
#

story???

sonic cedar
#

but theyre... all pinned....

slim ferry
#

balala lore?

rapid stag
#

how can i make a joker change its own sell value?

sonic cedar
#

egg

rapid stag
chrome widget
chrome widget
sonic cedar
sonic cedar
chrome widget
#

That said the sort_id thing was about pinned jokers because unfortunately, if all cards being sorted are pinned, they're sorted by sort_id, which is also the order they're created (very unintuitive, pinned is clearly not built to be used with more than one pinned card). So it means pinned cards from the shop will be added and then sorted always to the left, and then in reverse order from their shop position

#

So for the purpose of this challenge at least I made it so they're still added to the right as expected, and "leftmost" is relative to any non-pinned jokers to their right

sonic cedar
#

does it work okay? any issues so far?

chrome widget
#

No it works fine

#

Really the only annoyance is the one leftover from vanilla. If you have multiple pinned jokers, the "pinned" description makes less sense, as you implied

#

Only one joker can technically be absolute leftmost at a time

sonic cedar
#

WELL

slim ferry
#

i mean localthunk did say it was only added for the one challenge

chrome widget
#

but like

#

that's vanilla's problem, not mine

sonic cedar
#

unless you read it as leftmost RELATIVELY

chrome widget
#

it is, it's leftmost relatively

#

and a player can pretty easily figure out what's going on with the challenge despite that

sonic cedar
#

yeah ik im saying in terms of making sense

#

tldr you cooked

slim ferry
#

some leftmosts are more left than other leftmosts or whatever

#

jorjor well

chrome widget
#

Regardless the point of the challenge is that a card can't be sold unless you sell all other cards left to it in sequence

#

meaning changing your jokers is a lot riskier

#

It does however make certain effects more predictable (anything that randomly destroys will always target the leftmost joker)