#💻・modding-dev

1 messages · Page 673 of 1

tranquil echo
#

oh lovely

#

new file it is

red flower
#

yeah but if those can appear in the shop for example you would need logic for that

tranquil echo
#

ohhh

#

for it to like
go into that spot?

#

that makes sense okay

ill figure it out trust

red flower
#

i have that in my mod but its pretty spread out between a bunch of files so its not easy to link to as an example lol

tranquil echo
#

alright 😓

#

ill pokea round

#

thank you though!

sleek valley
#

would there be any way for an achievement to track how many times check_for_unlock has run? and then the achievement only pops if the tracker reaches a certain number?

red flower
#

you can hook it to add a counter to it probably

sleek valley
#

actually on second thought, there's probably an easier way to make my idea
just an achievement that only unlocks after all other achievements are collected

#

would prolly still need hooks one way or another but i feel like i'm thinking about the achievement tracker all wrong

timid zinc
#

what's the best way to have a pool other mods can add onto if the object isnt part of smods.center?

red flower
timid zinc
#

like how smods does?

#

does smods do something specific outside of just defining a table? i was just thinking it would be used as a restriction of like "if this is true, only this type of tag/blind can appear"

timid zinc
tender blade
#

Does anyone know a mod/reference with a UI aligned on the bottom like the shops and blind selects? aligning always seems to put the top of the ui peeking out the bottom but growing it vertically seems to grow it downwards?

red flower
red flower
sleek valley
#

is there any way for a blind to destroy a held card?

red flower
sleek valley
#

after a hand/discard is used, like the Wheel

red flower
#

well the problem is that the wheel has its own context for flipping cards lol

#

what's the exact effect?

sleek valley
#

well i want a 1 in 4 chance for held cards to get destroyed after a hand or discard is used

red flower
#

you would need to loop through G.hand.cards and check the probability for each card

#

idk what context tho, there isn't really a good context for after a hand or discard is used, the closest is context.hand_drawn but that only happens if a card is drawn

sleek valley
#

what about context.destroy_card?

red flower
#

that happens during scoring

#

or when discarding

#

so immediately before when you want

sleek valley
#

ah, i see

#

in that case, i can honestly get behind hand_drawn tbh

timid zinc
#

could you get behind it happening as soon as you click discard?

sleek valley
#

i mean, i could
but it's better imo for the player to watch it burn away infront of them

#

to really sell the fact that it's gone for good

#

the discard animation would be too fast for you to even notice

timid zinc
#

actually i think i did something similar but with discarding cards instead of destroying, let me check

near coral
#

How do I cap the -score requirement on a rekoj that scales it to -50%

frosty rampart
#
if card.ability.extra.minus_score < 0.5 then
  -- scale code
end
#

it's basic programming logic

near coral
#

Does the < 0.5 equate to -50%

#

Or just -0.5 score requirement

rapid stag
#

if i wanted to make a joker effect that does something like give bonus chips to cards converted by a specific tarot, how would i go about doing that

i imagine i could do something with context.using_consumeable...? or however it was called, i forget. i haven't messed with this context in a while

frosty rampart
# near coral Does the < 0.5 equate to -50%

i mean i dunno how you have it actually implemented
but i assumed the stored value was a decimal that equated to a percentage. if it's not that then your coder should know what to do

#

whatever corresponds to -50%

near coral
#

Let me send the lua of one of the scaling rekojes for reference

frosty rampart
#

ok yes so 0.5 does equate to 50%
you'll need some extra code when it actually scales to make sure that it doesn't go over 0.5

near coral
#

What would that look like

#

If -score requirement = -50% then don't scale any more?

frosty rampart
#

put some critical thinking to use
it's currently scaling by 0.2, or 20% each time
so it can jump straight from 40% to 60%

#

how do you prevent that

near coral
#

It scales by -0.2% for every $ spent during the ante

frosty rampart
#

<@&1133519078540185692>

near coral
rapid stag
#

interesting, i've never heard of a balatro mod called 'girls' before

frosty rampart
near coral
#

Alright

sleek valley
near coral
#

I wonder if riske is a misspelling or a regional spelling cuz it looks like it could be both

rapid stag
#

regional variant from upstate new york

near coral
#

Alright I actually fell for that one

sleek valley
#

i will say the origins are from the french /gen

rapid stag
#

oh not in utica, no, it's an albany expression

near coral
#

I learned it as 'risque'

wanton jolt
#

riske doesnt exist in the english language

wanton jolt
#

its unaccented version though "risque" is

sleek valley
wanton jolt
#

its fine since its something you hear but not write often

#

lol

near coral
#

It would've been funny if you spelled it as fortay on purpose

wanton jolt
#

it would be very funny

sleek valley
near coral
#

[Insert bizarro hack emoji]

sleek valley
#

you want it to give bonus chips to cards that have been affected by tarot cards??

#

is that right?

rapid stag
#

as an example, yes
the important part is specific tarot cards. so going by consumable key, not type

wanton jolt
rapid stag
#

damn.

i was hoping it would have the cards used on

daring fern
wanton jolt
#

oh true

rapid stag
#

ooooh

#

-# ...i also forgot how to get the consumable itself in context.using_consumeable

rapid stag
#

...or i could look at the calculate functions wiki tab that i've had open for the past week. that'd be good if i did that

did you know that the smods wiki has really useful info?

final jewel
#

is it normal that when I change a seal through the before context it doesnt update like it keep the effect of the previous seal

final jewel
#

yeah but I though that it will update between before and the next context

red flower
#

the entire calculation cycle happens before any event is ran

#

so anything you put in an event happens after calculation, putting an event in context before only makes it play the animation before events in later contexts

final jewel
#

yeah its working if I remove the event but my animation is wacky

#

do u know how I could fix this

red flower
#

im pretty sure theres a way to delay the application of the seal for that like there's for enhancements and editions but idk what it is sorry

final jewel
#

@daring fern he could probably know that since Seals On Every ?

daring fern
final jewel
# daring fern Yes, you would just do `card:set_seal('modprefix_key')`

yeah I know but like I change a seal during the context.before like its effect need to happen during the main scoring and like after it change back to its original seal in the context.after but I cant use event cause the effect wont happen and its just the previous seal effect that will trigger and by not using an event my animation isnt working

#
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.4,
        func = function()
            _card:juice_up(0.3, 0.5)
            return true
        end
    }))
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.15,
        func = function()
            _card:flip()
            _card:juice_up(0.3, 0.3)
            return true
        end
    }))
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.2,
        func = function()
            _card:set_seal(G.P_SEALS[_card:get_seal()].giga_data.seal_upgrade, true)
            return true
        end
    }))
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.15,
        func = function()
            _card:flip()
            _card:juice_up(0.3, 0.3)
            return true
        end
    }))
    G.E_MANAGER:add_event(Event({
        trigger = 'after',
        delay = 0.2,
        func = function()
            G.hand:unhighlight_all()
            return true
        end
    }))
    delay(0.5)
end```thats my original animation
daring fern
final jewel
#

oh

#

ok lets try it out

#

ok its near its just that the previous seal disappear before setting the new one

daring fern
final jewel
#

oh ok nice

#

but what do I put in this

frosty rampart
#

i wouldn't bother with that
just set up some events to flip the card while the seal gets changed, like how the spectral cards do it

daring fern
frosty rampart
#

ok
point still stands

final jewel
#

yeah thats the problem

#

my animation when upgrading a seal is that its flipping the card

#

cause just setting a new seal when upgrading isnt cool

frosty rampart
#

hm, ok

final jewel
#

do you think I should just change the animation entirely

vital wren
#

is there an SMODS method i should be using instead of the vanilla Tag(key) to create a new tag?

wanton jolt
vital wren
#

that suggests no

red flower
#

i agree with whoever wrote that website

vital wren
#

thanks. i think it would have been nice to find info about what related methods exist in the relevant SMODS wiki pages. i've seen often someone will say something like "you should use this SMODS method instead" but the method isn't mentioned in the wiki for that type of card or object

tranquil echo
#

does anybody know the background colour of the vanilla cardareas

red flower
red flower
tranquil echo
#

oh peak ok

vital wren
red flower
#

now that im an smods team member wiki things will get merged so dont be afraid to post an issue or PR there :3

gilded blaze
red flower
#

that too

vital wren
tranquil echo
# red flower

lowk
how do i use this im so genuinely lost
bg_colour = {0,0,0,0.1} does not work as expected

red flower
#

why do you need to do that?

#

it is that color by default

tranquil echo
#

well then its just displaying wrong 😭

red flower
#

what's the code

#

and how is it wrong

tranquil echo
#

why are you not clear

red flower
#

😭

wanton jolt
#

well that is neither 000000 or 0.1 alpha

tranquil echo
#

and the code is just a direct copy of the code here wiuth the bg_colour = G.C.RED line removed, and the position changed

red flower
#

this is how that exact code with that line removed shows up for me

tranquil echo
#

what

wanton jolt
#

yo let me try it

red flower
#

did you restart the run?

tranquil echo
#

yeah

red flower
#

it kept the color to me on reload

#

can i see the code you have?

final jewel
#

like I tried this but it doesnt work

tranquil echo
#

i fixed it!!!

wanton jolt
#

what was the issue

tranquil echo
#

no fucking idea

#

i restarted my entire pc

#

and it worked!

wanton jolt
#

works on your machine

wanton jolt
#

yo now that i made a card area, is there a way to hide it

final jewel
#

it wasnt from my end

#

idk

#

but now it is

gilded blaze
daring fern
final jewel
#

oh ok

daring fern
#

Using self.seal = seal not self:set_seal(seal)

final jewel
#

like so

daring fern
# final jewel like so

No, seal would be the seal that it had, which you would get by setting a variable on the card before you set the seal, and you would use that.

final jewel
#

oh ok yeah mb i am dumb

timid zinc
#

when defining a collection page, how do i apply a shader to every object in that page, like vouchers?

#

Currently i'm just using SMODS.card_collection_UIBox to define the page

gilded blaze
#

take a look at joker collection

wanton jolt
#

i guess i could make a totem

#

system

final jewel
#

like .prev_seal is set to :get_seal of the card at start

rapid stag
# wanton jolt i guess i could make a totem

i am curious about the upcoming additions/changes to smods' custom cardarea support in respect to where multiple mods all decide to put cardareas in the same or overlapping locations

red flower
#

i dont know how smods could solve that tbh

#

my opinion is that anyone playing more than one mod at the time should be excommunicated

daring fern
timid zinc
#

Yeah that makes sense

wanton jolt
timid zinc
red flower
#

yes

#

anyone running jokerdisplay deserves jail

formal vessel
red flower
#

hell

formal vessel
#

does that mean anyone using lovely AND steamodded at the same time should go to jail?

formal vessel
red flower
#

did you add mine

formal vessel
red flower
#

joyousspring

#

it will have 650 jokers next update

formal vessel
#

i dont think ive gotten to tht one yet

timid zinc
#

handy and unblind? also jail

formal vessel
#

steamodded, lovely, galdur, joker display, carto, handy, and unblind? go to hell

formal vessel
pastel kernel
#

how do you keep track of how much money is spent

daring fern
pastel kernel
daring fern
elder rune
#

<@&1460584319486791871>

left sonnet
#

Hey folks, are there any resources for learning to mess with Balatro's existing UI? I've practiced in Config but I want to be able to add stuff to the existing ui, in particular at the moment I want to add a row above the scoring area and below the blind/shop sign

#

I see there's a replace_ui variable but I haven't looked into it yet

red flower
bold sleet
#

chat, how the heck do I utilize this function?

#

-# I am certainly not understanding the documentation.

left sonnet
# red flower https://github.com/Steamodded/smods/wiki/UI-Guide#creating-a-uibox other than t...

Alright, I'll look into hooking as I'm not familiar, thank you

Would it be a viable plan to copy an existing UI and save it to a variable, delete the original for the rest of the session, add a node under where (haha underwear) I need it, and load mine in for the rest of the session?

I don't know how to do the node-adding to an existing structure but it gives me a goal to work around

left sonnet
# bold sleet chat, how the heck do I utilize this function?
function SMODS.debuff_card(card, debuff, source)
    debuff = debuff or nil
    source = source and tostring(source) or nil
    if debuff == 'reset' then
        sendWarnMessage("SMODS.debuff_card(card, 'reset', source) is deprecated")
        card.ability.debuff_sources = {};
        return
    end
    card.ability.debuff_sources = card.ability.debuff_sources or {}
    card.ability.debuff_sources[source] = debuff
    SMODS.recalc_debuff(card)
end```Here is the source code
#

Looks like you input the card you want to debuff in card, debuff seems to be a true or false as in whether it should be debuffed or not, source is what debuffed the card, probably used for checks

red flower
left sonnet
red flower
left sonnet
#

Oh, brilliant

#

Thank you

bold sleet
left sonnet
#

Check Balatro's source code

red flower
#

it's basically a password, if you want to remove the debuff you need to use it

bold sleet
#

If I want to remove any debuff, then?

#

Really, I just want that.

left sonnet
#

It could be anything you like, yeah

red flower
#

same but you would have 'prevent_debuff' as the second argument

#

you would need the source to remove that prevent_debuff too

bold sleet
red flower
#

yes

#

what i said

bold sleet
#

ah

red flower
#

what's the goal?

#

because if you want to prevent blinds from debuffing the better way is to use the context

bold sleet
#

Played cards get un-debuffed (for the playing hand)

#

That's it.

left sonnet
#

Chitotty

red flower
#

what i said is probably the easiest but you need to remove the prevent_debuff after the hand is played

#

so like

-- before play
SMODS.debuff_card(card, 'prevent_debuff', "source")
-- after
SMODS.debuff_card(card, nil, "source")
bold sleet
#

kk

hidden aspen
#

how to use localize with seals?

#

i want to fetch seal's name

red flower
#

localize { type = 'name_text', set = "Other", key = 'modprefix_[key in lowercase]_seal"}

hidden aspen
#

what about vanilla seals?

red flower
#

same but without the prefix

hidden aspen
#

do i have to convert Blue to blue_seal manually?

red flower
#

yes

hidden aspen
#

okay... 😔

lyric wadi
#

earlier someone mention i can make a vanilla pool by iterating through all loaded jokers and see if it has no mod associated

#

how would i check if a joker has a mod or not, how do i iterate through the jokers, and should i do it that way instead of just going with a hardcoded list

#

since the more mods a player has the worse this approach get

hidden aspen
#

are you iterating through a list once to get vanilla pool? then it wont be resource intensive

red flower
#
SMODS.ObjectType({
    key = "vanilla",
    default = "j_joker",
    cards = {},
})


local SMODS_injectItems_ref = SMODS.injectItems
function SMODS.injectItems()
    SMODS_injectItems_ref()
    for i, v in ipairs(G.P_CENTER_POOLS.Joker) do
        if not v.original_mod or v.original_mod.id == "Balatro" then
             SMODS.ObjectTypes.vanilla:inject_card(v)
        end
    end
end
wintry solar
#

A hard coded list would also work

lyric wadi
#

yeah i just need a pool with the keys of every vanilla joker

#

which i guess isnt a readily available class in smod

red flower
#

taglist when

tidal hemlock
#

#1477838185919807620
if anyone's willing to help program this (and by help i mean be the sole programmer because i cant code for shit lmao)

hidden aspen
#

whats a good way to store global utility functions? I previously just stored them in some files and assigned them to MOD_SINGLETON.UTIL, but i understand that that makes them scattered.
im not sure if there is a header-like thing in lua to store them all in one file? should i look into Lua LSP and somehow autogenerate a file with all MAP.UTIL functions?

gilded blaze
#

that's not how you store a function

red flower
#

usually if you have utility functions you just write them all in one file and load that file first

#

saving them to the mods singleton like you did is usually what most people do

lyric wadi
#

ok to select a random card from the pool, can i just use psuedorandom_element on the pool

#

like not spawning a card from the pool, just grabbing a key from the pool

pastel kernel
#

checking for if sold card is a joker

#

actually wait, what if eggman got the sell value of the joker i sold?

dreamy thunder
pastel kernel
#

so get_current_pool is the door, G.P_CENTER_POOLS is the house?

dreamy thunder
#

can say so

lyric wadi
#

more clarification

#

does owning jokers affect what can be pulled from the "custom" pool

#

it's fine if it does but for my purpose it would be funnier if it didnt

dreamy thunder
#

if you use get_current_pool yes

#

i think

#

also get_current_pool returns a lot of UNAVAILABLE strings so i recommend using SMODS.get_clean_pool with the same args

slim ferry
#

you generally shouldnt use get_clean_pool

#

there is a very good reason thet vanilla uses UNAVAILABLE strings

#

so the pool size doesnt actually change and the outcome only changes if the roll wouldve been something unavailable and it has to reroll

#

with get_clean_pool the pool size varies and a completely unrelated joker being in the pool or not could affect spawns

lyric wadi
#

i understand there are best practices, but for my purpose i really just need something to get a random vanilla key from a not hardcoded list

gilded blaze
#

honestly I can't find a good use case for get_clean_pool

lyric wadi
#

so i believe i will be fine???

slim ferry
#

i mean

#

get_current_pool allows for that

#

but also youre using a custom SMODS.ObjectType for the pool so idk why you would need get_current_pool

#

oh wait grabbing a key

lyric wadi
#

slightly related question, is there a way to grab the atlas x and y value of a joker from its key

#

or maybe centre

red flower
#

from the center it's center.pos

slim ferry
# slim ferry get_current_pool allows for that
local pool = get_current_pool('pool_key')
local selected_key = pseudorandom_element(pool, 'modprefix_seed')
local it = 1
while selected_key == 'UNAVAILABLE' do
    it = it + 1
    selected_key = pseudorandom_element(pool, 'modprefix_seed_resample'..it)
end
``` its just this
red flower
#

from the key its G.P_CENTERS[key].pos

red flower
#

ah wait

slim ferry
#

SMODS.poll_object

#

right

red flower
#

nvm eremel is doing the weight stuff

slim ferry
#

i recall eremel adding a util function for that already

#

and also why was get clean pool ever a thing

red flower
#

dunno

lyric wadi
#

ok one last unrelated question

#

how do you change which loc key a card is using with code again

#

like changing its name and description

red flower
lyric wadi
#

yippee

#

i think

#

i hope it works

#

what to hell

#

i cant even tell what happened

tidal hemlock
#

did you accidentally use a string instead of a number somewhere?

lyric wadi
#

ok this is line 178 from theSuite

#
set_sprites = function(self, card, front)
        G.E_MANAGER:add_event(Event({
            blockable = false,
            func = function()
                if card.ability then card.children.center:set_sprite_pos({x = card.ability.extra.spriteX[card.ability.extra.anchorSuit .. card.ability.extra.followSuit], y = card.ability.extra.spriteY[card.ability.extra.anchorSuit .. card.ability.extra.followSuit]}) end
                return true
            end
        }))
    end

it's the func of this event

#

spriteX and spriteY are key based dictionaries

tidal hemlock
#

idk its something to do with the x = and y =

lyric wadi
#

so it worked fine before, but maybe the order it define things are different?

#

i just copied the code from earlier into this event

#

i even checked card.ability exists

tidal hemlock
#

why cant you just if card.ability then card.children.center:set_sprite_pos( card.ability.extra.spriteX[card.ability.extra.anchorSuit .. card.ability.extra.followSuit], card.ability.extra.spriteY[card.ability.extra.anchorSuit .. card.ability.extra.followSuit]) end

lyric wadi
#

wait you dont need to assign them to x and y resperctively?

pastel kernel
#

how to set joker sell value actually

#

as in starting value

lyric wadi
#

unrelated but for debugplus is there a command to spawn a joker into the shop

tidal hemlock
pastel kernel
#

I think you have to just do add_card but set the area to G.shop.cards?

red flower
#

that won't give it the shop ui

pastel kernel
#
if context.selling_self and card.ability.extra.extra_value == 0 then
            local newegg = SMODS.add_card{ key = "j_busterb_eggman" }
            newegg.sell_cost = 0
            end```
#

wtf

#

ok there

#

so

#

i hope this thing actually gets 0 sell value

tidal hemlock
#

why? i have no clue

lyric wadi
#

because voucher half buy prices, and sell price is directly half of buy price

tidal hemlock
#

ah right

lyric wadi
#

so basically prevents it being /8 into rounding down to selling for 0

pastel kernel
#

herelua if context.selling_self and card.ability.extra.extra_value == 0 then local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_busterb_eggman", "eggman") card.sell_cost = 0 card:add_to_deck() G.jokers:emplace(card) end

rigid solar
#

So I believe quantum enhancement used to have some infinite recursion prevention but it's no longer the case? because as long as the card is highlighted it's pilling up events

red flower
#

is this in latest dev?

rigid solar
#

latest release

red flower
#

i know there are some things fixed in dev

rigid solar
#

hmm ok

#

because i've seen multiple reports of quantum enhancements being broken in different ways (which all make the game very slow in general) since the 1503 release

red flower
#

yeah that is known

rigid solar
#

if it's fixed in dev that's cool, tho we'll have to wait for a release for most people to actually get the fix

red flower
#

still, you should try it out yourself in dev

#

maybe that specifically didn't get fixed

rigid solar
#

sure

lyric wadi
#

fuck i never thought about this

#

if theres no way to force spawn a joker in shop

#

how tf am i gonna test

rigid solar
#

an "easy" way is to get all jokers of the same rarity in your joker lineup, then reroll the shop until it spawns

tidal hemlock
rigid solar
#

there's a reroll shop feature to reroll until a chosen card appears

red flower
pastel kernel
#

how to check if sell value is 0 or at the very least lowest possible

rigid solar
tidal hemlock
rigid solar
#

or just check vanillaremade code

tidal hemlock
#

that too

rigid solar
#

like here you can just check how swashbuckler gets other jokers sell value

#

or temperance

pastel kernel
#

i'm trying to make eggman get to $0 sell value.

#

hmm

lyric wadi
#

rip

#

is my joker borken or is my luck just ass

#

i've done 200 rerolls and it hasnt showed up once for my testing

pastel kernel
#

how do i get this to work properly bruh

lyric wadi
#

ah, i finally got it to show up

sleek valley
#

IVO ROBOTNIK?!?

lyric wadi
#

and of course it didnt work

pastel kernel
#

ok how do you make it so that if the sell value is 0, it actually disappears for good and doesn't clone itselflua if context.selling_self and card.ability.extra.extra_value ~= 0 then local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_busterb_eggman", "eggman") card.sell_cost = 0 card:add_to_deck() G.jokers:emplace(card) end

lyric wadi
#

same question as yestderday i think

#

what's the """""proper""""" way to have a card run something when it appears in shop

exotic hedge
elder rune
exotic hedge
#

Ohhh okay

#

Thanks 🙏

lyric wadi
#

gamblin is a peglin themed mod for this game

pastel kernel
#

if anybody could help me out, tell me```lua
SMODS.Joker {
key = "eggman",
unlocked = false,
atlas = "bb_legendary",
blueprint_compat = true,
pools = { ["bustjokers"] = true },
rarity = 4,
cost = 0,
pos = { x = 0, y = 4 },
soul_pos = { x = 0, y = 5 },
config = { extra = { start = 0, gain = 3 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.start, card.ability.extra.gain } }
end,
add_to_deck = function(self, card, from_debuff)
for k, v in ipairs(G.jokers.cards) do
if v.key == "j_busterb_eggman" then
card.ability.extra_value = 0
end
end
end,
calculate = function(self, card, context)
if context.selling_self then
if to_big(card.ability.extra.extra_value) ~= to_big(0) then
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_busterb_eggman", "eggman")
card.sell_cost = 0
card:add_to_deck()
G.jokers:emplace(card)
end
end
if context.selling_card and context.card.ability.set == "Joker" then
card.ability.extra_value = card.ability.extra_value + card.ability.extra.gain
card:set_cost()
return {
message = localize('k_val_up'),
colour = G.C.MONEY
}
end
end
}

mystic river
#

you also shouldn't have to do to_big anymore, now that amulet is available
(i mean if you want to be backwards compatible with talisman, you can, but people really should be using amulet these days)

pastel kernel
#

This joker specifically

#

It’s 12 AM… I don’t wanna work on the mod tonight… or today idk.

wanton jolt
sleek valley
wild patrol
#

For an ante 8 boss lol

sleek valley
#

i mean sure, i cant deny it fuckin rocks!!
but i'm tryna think balanced here lmao

#

but then again, it is a great punisher
the bigger your hand size, the worse you get it

tidal hemlock
lyric wadi
#

it also hard counters things like Steel Cards or Shoot the Moon/Baron builds

#

which i think is neat

red flower
#

when you only want the selected one by pesudorandom

#

also, you need to remove the card from the _cards list after picking or it might pick the same card more than once

#

also while it probably does nothing you should remove the discard cards from highlighted bit in case it tries to discard a destroyed card and you end up with ghost cards

sleek valley
#

Good idea, thx

gusty compass
#

where would i be able to edit the ui of the hands and discards exactly?

#

or would i have to go around and search via nodes

versed swan
#

How do you force a crash?

slim ferry
#

error("message")

#

i thibk

#

or assert(false, "error message")

versed swan
#

that would do it, thank you

sleek valley
red flower
#
local value, index = pseudorandom_element(...)
if selected then table.remove(_cards, index) end
sleek valley
#

tyy

lyric wadi
#

line 41

#

does this not get the pool

red flower
#

I'm guessing G.playing_cards doesn't exist at the point this is called?

nimble jay
#

can someone tell me what ive done please? Im really knew to modding, so i have no clue

This joker is supposed to give 8 mult then make another version of itself at the end of the round, but it crashes every time i do it. If i use a vanilla joker it works, if i use smods.create_card with a modded joker it works, but smods.add_card with a modded joker just causes it to crash. Whats weirder as well is that it doesnt crash like usual and give a report, it just freezes and doesnt respond.

heres the code:

SMODS.Joker {
    key = "tatoo_you",
    config = { extra = { mult = 8, odds = 2 } },
    loc_vars = function(self, info_queue, card)
        return {
            vars = { card.ability.extra.mult, card.ability.extra.odds, G.GAME.probabilities.normal or 1 }
        }
    end,
    calculate = function(self, card, context)
        if context.joker_main then
            return {
                mult = card.ability.extra.mult
            }
        end
        if context.end_of_round and not (context.individual or context.repetition) then
            SMODS.add_card({ set = 'Joker', area = G.jokers, key = "j_jojo_tatoo_you" })
        end
    end
}

(odds bit it still there cause i plan to make it a 1 in 2 when i get this working)

wind reef
#

Anyone know what function i can hook into for a function to trigger when the first hand is drawn? Trying to do something similar to the idol but only for cards in the first hand

lyric wadi
#

like fuck do you mean attempt to index in to nil

red flower
red flower
lyric wadi
#

😭

red flower
#

what you should do is save the card added with add_card in a variable and add a flag to it like added_card.modprefix_created_by_me = true and if it has that flag then it doesn't add anything

slim ferry
#

-# or use an event

red flower
#

also yeah

nimble jay
nimble jay
red flower
#

an event is probably better because you also need to clear the flag

nimble jay
wind reef
red flower
#

so you want the first card drawn for the blind or the first after it gets added?

wind reef
#

first for the blind

red flower
#

i meant if you want it to do both

wind reef
#

Basically i want it work where a card in the first drawn hand is selected regardless of if the joker is there so that if you get the joker a hand into the round it doesnt check again but knows what card was selected from that first hand drawn

red flower
#

ah i understand

#

use mod calculate

#

SMODS.current_mod.calculate = function(self, context)

wind reef
#

ahh didnt know that was a thing, thought only cards ran calculates. thanks!

mystic river
#

cards, blinds, decks, stakes, modifiers, challenges, and the mod all have a calculate

#

i think the only thing that doesn't is tags (they have apply_to_run instead)

red flower
#

soon(tm)

sleek valley
#

what about adding inject_card to undiscovered sprites?
or just any way to add custom sizes lol

red flower
#

i dont remember there being anything for that

#

idk exactly how undiscovered stuff works since i always make all my cards discovered but i could take a look

lyric wadi
#

how do i make a joker hide modtag but temporarily

sleek valley
red flower
#

i meant i dont remember there being anything in the pipeline to fix that

sleek valley
#

ah, i see

sleek valley
lyric wadi
#

ye

sleek valley
#

hmmmm
i cant think of any way you could tbh

stoic jacinth
#

Before I post it, I know some communities feel strongly about ai assisted dev, so is an ai made qol mod ok? One to update mods and one to sort mods, no ai art used.

mystic river
sleek valley
#

at least you asked respectfully

stoic jacinth
#

Understood I'll refrain 🙂

lyric wadi
#

how do i grab the loc var return of a joker

#

like for example i want to grab the var Popcorn is returning

#

but like to use with my joker

mystic river
#

though I'm not 100% on if that'll work on a vanilla joker, with how thunk defined everything in one big if-then statement

lyric wadi
#

yea :(

#

this is like the second half of the hard part

sleek valley
#

it's worth a shot tbh

lyric wadi
#

first half of the hard part is almost there

sleek valley
#

better to try and fail than to not try at all

mystic river
#

given that it's a known joker, you can probably dig the relevant variable out of the center config

lyric wadi
#

yeah problem is that it's not known

mystic river
#

or the card ability, if you want the decayed version

lyric wadi
#

which one do you think it is

mystic river
#

SMODS.find_card("j_popcorn")[1]

lyric wadi
#

not the second one that's from my mod

mystic river
#

though that wouldn't find cards still in the shop, if you care about that
what are you planning to do with this return value anyway?

lyric wadi
#

just feed it into loc var

mystic river
#

you can also probably invoke the vanilla loc vars function, if you dig it out of the vanilla source

mystic river
lyric wadi
#

to have it not do this

#

really gives it away

mystic river
#

yeah probably just find a way to invoke vanilla loc_vars

lyric wadi
#

rip

mystic river
#

i don't recall what the function is called and I'm at work rn but it's in the vanilla code and searching for j_diet_cola should bring you to it

#

(along with like every other joker related function but yk)

slim ferry
#

Since its vanilla its most likely "Diet Cola" in the loc vars

lyric wadi
#

ok but i would like to also not do 150 checks like vanilla

slim ferry
lyric wadi
#

😭

#

also fun test : can you tell what's wrong (other than the obvious nil)

mystic river
#

that's true
you'd want to pass the center instead of your joker, i think?

lyric wadi
#

ideally if possible

mystic river
#

so instead of Card:whatever vanilla loc vars is called(card, etc) it's like Card.whatever it is(G.P_CENTERS[key], fake card?, etc)
i don't know the parameters the function takes lol

lyric wadi
#

answer : ||real Diet Cola is not full to the brim||

mystic river
#

actually I'm almost sure the vanilla function runs on the card directly without passing the center
argh this is hard to think about without access to vanilla code

lyric wadi
#

if even cryptid threw a concept away then im fucked i think

mystic river
#

i don't think it's impossible to do, i just can't give very specific advice without code access

#

like, have you looked at the vanilla loc vars function?

lyric wadi
#

trying to find where it is

#

like i understand you cant have a code dump on a decent site like github because then that is just piracy but also arg

mystic river
#

too bad balatro isn't structured like doom, where you could release the engine source code but keep the game content proprietary

lyric wadi
#

holy heck crash so bad i dont even get a crash log

#

it just

#

disappear

round lion
lyric wadi
#

bad news : the loc_var part returns a generate_card_ui function

#

cant index into that

mystic river
#

oof

wintry solar
kind palm
#

Prototype of the Bear 5 card

lyric wadi
#

i think i have to hook into the bit that generates the tooltip ui for jokers

#

which is

#

worrying

sleek valley
#

how do i check the number of remaining hands the player has again?

#

i want to check for when this hits 0 and then manually cause a game over

slim ferry
#

G.GAME.current_round.hands_left

#

iirc

plain apex
#

question how do i fix this so that people with amulet can still use the mod since it provides talisman?

wild patrol
#

Update talismen

umbral zodiac
plain apex
#

amulet supposedly provides talisman

umbral zodiac
wild patrol
#

Maybe amulet doesn't have the correct version?

sleek valley
wild patrol
#

Try the official version of talisman see what happens

plain apex
slim ferry
#

Thats definitely higher than 1.7.0

umbral zodiac
#

super weird

plain apex
#

like im told amulet is better talisman and whatever and that it should just work?

slim ferry
#

-# header jank maybe?

plain apex
#

but it doesn't?

umbral zodiac
wild patrol
#

It could be maybe the mod is looking for the official version of tailsman and not amulet

umbral zodiac
#

i have to imagine it's just the fact that youre using legacy headers

umbral zodiac
#

because i have made mods that depend on talisman and amulet works fine for them

slim ferry
#

This is modding dev

#

And thats also jus not how dependencies work

plain apex
umbral zodiac
#

not at all

#

use json files

slim ferry
#

See mod metadata page on steamodded wiki

umbral zodiac
#

there should be a section about it on the

#

yeah

lyric wadi
#

am i hooking correctly

#

im decently sure im not so

slim ferry
#

You are not calling the reference

umbral zodiac
#

instead of local ret = hangedman_imposterous_generate_card_ui_hook (holy long name)

#

you should do local ret = hangedman_imposterous_generate_card_ui_hook(self)

slim ferry
#

And also thats. Not how you create the reference

sleek valley
slim ferry
#

You shouldnt be calling the function when creating it

umbral zodiac
#

^

lyric wadi
#

the goal is for it to overwrite the ui if it's this specific joker

slim ferry
#

Okay

#

The point is though

lyric wadi
#

no i know

slim ferry
#

This just isnt how you hook in general

lyric wadi
#

im just stating my goal to make it easier for you to point me toward doing it correct

umbral zodiac
#

you should
set the original reference to the function, not the results of the function
make sure you call the original function
also should probably not call the original function if it is that special card, since otherwise youre leaving a ton of probably-orphaned ui

#

also don't use card or Card to refer to the card that's calling the function, use self
lua's method calls (:) implicitly define self as a variable which refers to the table calling the function

lyric wadi
#

im basing on the guide on vanillaremade but yeah that was a func with args and this doesnt, so i guess i can see why it doesnt work the same

#

is it this???

mystic river
#

the args aren't what's wrong

umbral zodiac
#

ya basically
say youre hooking some function thats a part of a card, to replace it with no side effects it'd look like this

local ref = Card.func
function Card:func()
  return ref(self)
end
umbral zodiac
mystic river
#

hooking works because functions in lua are literally variables

lyric wadi
mystic river
#

stop calling the function to define your ref!!!

slim ferry
#

You shouldnt call it when creating the reference

lyric wadi
#

what

#

am i stupid

umbral zodiac
#

how many lightbulbs does it take to hook one function

slim ferry
#

no ()

#

For the first one

lyric wadi
#

two brights one and a dim one

umbral zodiac
# lyric wadi am i stupid

"calling" a function is when you () it
calling it means that you don't get a reference to the original function, you get the results of it, which means you can't access the original function itself

lyric wadi
#

oki

#

got it now

#

anything else?

mystic river
#
local ret = function(parameters) -- Calling the function with the parameters and putting the return value in "ret"
local ref = function -- Putting the *actual function* into "ref"
umbral zodiac
# lyric wadi anything else?

i dont actually know if this would work but thats just because this is being called on a card and youre calling it on a center when it's disgusied

#

normally a card is passed into generate_uibox_ability_wtv
but in this case its passing in the center (basically the prototype object)

mystic river
#

yeah i think this might just be a different way to do the thing that turned out not to work before

lyric wadi
#

ag

mystic river
#

though i know fake cards are a thing, you might be able to use those

plain apex
mystic river
#

the collection uses them

umbral zodiac
#

and make sure to remove the legacy header info from the top of your lua file

#

its not necessary iirc but its just useless now

slim ferry
#

Not removing the header can make it load twice iirc?

mystic river
#

smods might have implemented a measure against that at some point but there's no reason to leave the header in

slim ferry
#

Think of the 0.9.8 players /j

umbral zodiac
#

0.9.8 compat is like making sure that your country's due process is still compatible with people who have passports from 1776

mystic river
#

frankly I'm surprised smods itself keeps backwards compatibility for 0.9.8 mods

plain apex
lyric wadi
#

rip of course it doesnt work

#

im krilling my shelf

sleek valley
#

send the code

mystic river
lyric wadi
#

if it's the hook part

#
local hangedman_imposterous_generate_card_ui_hook = Card.generate_UIBox_ability_table
function Card:generate_UIBox_ability_table()
    local target = self
    if self.config.center_key == "j_hangedman_imposterous" and self.ability and self.ability.extra.disguisingAs then
        target = G.P_CENTERS[self.ability.extra.disguisingAs]
    end
    local ret = hangedman_imposterous_generate_card_ui_hook(target)
    return ret
end```
#

the entire thing

#

ignore the backticsk thats discord markdown getting flushed in

mystic river
#

you didn't do the hook wrong
but as ophelia said, the intercepted version calls the function on a center instead of a card, which doesn't seem to work

lyric wadi
#

how do i convert it to card

mystic river
# plain apex
INFO - [G] 2026-03-15 14:30:37 :: ERROR :: Loader :: Found invalid metadata JSON file at C:/Users/EricT/AppData/Roaming/Balatro/Mods/Fortlatro/Fortlatro.json, ignoring: [lovely json "libs/json/json.lua"]:185: expected ']' or ',' at line 16 col 4
lyric wadi
#

or are they just

#

two unrelated objects

mystic river
hardy vessel
#

Is there a way to see if a joker has any sticker? I see how to get specific ones, but I'm not sure about just in general

lyric wadi
#

no

#

i mean pulling the card class from the centre or key

mystic river
mystic river
lyric wadi
#

okay then i have bigger problems

#

so the card object has to remain the imposterous, but i have to somehow feed it the fake key/name

#

hm

plain apex
#

well fortlatro supports amulet now w for the people using that

lyric wadi
#

i dont think this is what i wanted

#

i mean i passed the card into it but uhh

#

it is a funny effect but not what i wanted to do with it

#

if im desperate enough i might keep it

#

woe, obstructions be upon ye

wanton jolt
#

lol

hardy vessel
#

how could you check if a joker can have stickers like eternal or perishable applied or not?

slim ferry
#

card.config.center.sticker_key_compat ~= false

daring fern
hardy vessel
hardy vessel
hardy vessel
#
    use = function(self, card, area, copier)
        local eternal_check = card.ability.eternal or false
        local eternal_compat = SMODS.Stickers['eternal']:should_apply(card, card.config.center, card.area, true) or false
        local joker = G.jokers.highlighted[1]
        G.E_MANAGER:add_event(Event({
            trigger = 'after',
            delay = 0.4,
            func = function()
                for k, v in pairs(SMODS.Stickers) do
                    -- print(v)
                    if v ~= SMODS.Stickers.eternal then
                        v:apply(joker, nil)
                    end
                end
                if eternal_check then
                    SMODS.Stickers.eternal:apply(joker, nil)
                elseif eternal_compat then
                    SMODS.Stickers.eternal:apply(joker, true)
                end
                return true
            end
        }))
    end,
    can_use = function(self, card)
        if #G.jokers.highlighted ~= 1 then
            return false
        end
        local sticker_check = false
        for _, sticker in pairs(SMODS.Stickers) do
            if G.jokers.highlighted[1].ability[sticker.key] then
                sticker_check = true
            end
        end
        if sticker_check then
            return true
        elseif SMODS.Stickers['eternal']:should_apply(card, card.config.center, card.area, true) then
            return true
        else
            return false
        end
        
    end
daring fern
sharp jasper
#
    key = "house_down",
    visible = true,
    mult = 15,
    chips = 150,
    l_mult = 7,
    l_chips = 75,

    loc_txt = {
        name = "House Down",
        description = {
            "Both a Full House and a Down"
        }
    },

    example = {
        { 'S_A', true },
        { 'S_A', true },
        { 'C_A', true, enhancement = 'm_wild' },
        { 'D_K', true },
        { 'D_K', true }
    },

    evaluate = function(parts)
        local down = parts.djvxx_down
        if not next(down) then
            return {}
        end
        if #parts._3 < 1 or #parts._2 < 2 then
            return {}
        end
        return {SMODS.merge_lists(parts._all_pairs, down)}
    end
})```
hardy vessel
rapid stag
#

i.e.

local table1 = { bla, bla1, bla2 }
local table2 = { bla3, bla4, bla5 }

local merged = SMODS.merge_lists{ table1, table2 }
#

so you could get away with turning it into a table call, but if that still causes issues, try returning just the function result as it returns a table and as is, that will be a nested table

#

i have no experience with custom hands though, that's all i notice

jagged gulch
#

Hey I'm pretty new to Lua and wanted to try out something simple to get a understanding of balatro modding (Since I want to make a mod), so I decided the first step would be taking one of the example mods and turning it into something new... can someone explain why even when I dumbed it down to effectively the exact same text as the Deck of 4s from the example mod it crashes the game on start up?

 SMODS.Back{
    name = "Deck of Faces",
    key = "faces",
    pos = {x = 1, y = 3},
    config = {Jack = "4", Queen = "Queen", King = "King"},
    rng = random.math(0,3),
    loc_txt = {
        name ="Deck of Faces",
        text={
            "Start with a Deck",
            "full of {C:attention}random{} Face Cards",
        },
    },
    apply = function(self)
        G.E_MANAGER:add_event(Event({
            func = function()
                for _, card in ipairs(G.playing_cards) do
                    assert(SMODS.change_base(card, nil, self.config.Jack))
                end
                return true
            end
        }))
    end
}```
#

(I'm probably going to be frequenting here a lot tbh since I'm very new and have little experience...)

jagged gulch
jagged gulch
red flower
#

ah it's math.random

wanton jolt
#

honestly i would not do random faces but try to spread them out eveenly

red flower
#

idk what that line is trying to do however

jagged gulch
jagged gulch
#

Get the logic to change the faces through a variable

#

So I can later edit said variable to be based on the value of the cards themselves

#

Rather then

#

Random

red flower
wanton jolt
#

i have a wiki for you

#

that answers most modding questions

jagged gulch
jagged gulch
red flower
#

ah ok

wanton jolt
#

and you can check how checkered deck changes the deck

-- Checkered Deck
SMODS.Back {
    key = "checkered",
    pos = { x = 1, y = 3 },
    unlocked = false,
    apply = function(self, back)
        G.E_MANAGER:add_event(Event({
            func = function()
                for k, v in pairs(G.playing_cards) do
                    if v.base.suit == 'Clubs' then
                        v:change_suit('Spades')
                    end
                    if v.base.suit == 'Diamonds' then
                        v:change_suit('Hearts')
                    end
                end
                return true
            end
        }))
    end,
    locked_loc_vars = function(self, info_queue, back)
        local other_name = localize('k_unknown')
        if G.P_CENTERS['b_black'].unlocked then
            other_name = localize { type = 'name_text', set = 'Back', key = 'b_black' }
        end

        return { vars = { other_name } }
    end,
    check_for_unlock = function(self, args)
        return args.type == 'win_deck' and get_deck_win_stake('b_black') > 1
    end
}
#

but instead of checking for suits you check for ranks

red flower
#

the deck of fours example is fine too

wanton jolt
#

you can check the rank by doing this
v:get_id() == 13 -- Ranks 2-10 are IDs 2-10, Ace is 14.

jagged gulch
# wanton jolt and you can check how checkered deck changes the deck ```lua -- Checkered Deck S...

Would something like this work or is the syntax wrong?```lua
-- Checkered Deck
SMODS.Back {
key = "checkered",
pos = { x = 1, y = 3 },
unlocked = false,
apply = function(self, back)
G.E_MANAGER:add_event(Event({
func = function()
for k, v in pairs(G.playing_cards) do
if v.base.value == ('1', '2', '3') then
v:change_value('Jack') --editted part
end
if v.base.suit == 'Diamonds' then
v:change_suit('Hearts')
end
end
return true
end
}))
end,
locked_loc_vars = function(self, info_queue, back)
local other_name = localize('k_unknown')
if G.P_CENTERS['b_black'].unlocked then
other_name = localize { type = 'name_text', set = 'Back', key = 'b_black' }
end

    return { vars = { other_name } }
end,
check_for_unlock = function(self, args)
    return args.type == 'win_deck' and get_deck_win_stake('b_black') > 1
end

}```

jagged gulch
#

Id not value

#

Oh wait yeah value is set based on id right? I remember seeing that in the "Cards.Lua" code

wanton jolt
#
if v:get_id() == 2 or v:get_id() == 5 or v:get_id() == 8 or v:get_id() == 14 then
  assert(SMODS.change_base(v, nil, 'Jack'))
end
if v:get_id() == 3 or v:get_id() == 6 or v:get_id() == 9 then
  assert(SMODS.change_base(v, nil, 'Queen'))
end
if v:get_id() == 4 or v:get_id() == 7 or v:get_id() == 10 then
  assert(SMODS.change_base(v, nil, 'King'))
end
#

something like this

#

theres probably a more elegant and mathematic way to do this but eh

jagged gulch
#

Ah ok

wanton jolt
#

i commented the change_value thing because i'm unsure how to do it

jagged gulch
#

Let me see the code for Death

#

Or strength

wanton jolt
#

right

red flower
#

the earlier code was correct, you use SMODS.chaneg_base

#

change

wanton jolt
#

oh its smods

#

does it take id or the rank name

red flower
#

name

wanton jolt
#

i changed the above snippet

#

since its in a event function i guess you could put in in assert hold on

jagged gulch
red flower
#

1 doesn't exist, if you want Ace it's 14

wanton jolt
red flower
#

yeah, drawstrps

#

drawsteps

#

look at the example The Soul in vanillaremade

jagged gulch
red flower
jagged gulch
#

I thought it would just default to 2

wanton jolt
#
-- Checkered Deck
SMODS.Back {
    key = "deck_of_faces",
    pos = { x = 1, y = 3 },
    unlocked = true,
    apply = function(self, back)
        G.E_MANAGER:add_event(Event({
            func = function()
                for k, v in pairs(G.playing_cards) do
                    if v:get_id() == 2 or v:get_id() == 5 or v:get_id() == 8 or v:get_id() == 14 then
                      assert(SMODS.change_base(v, nil, 'Jack'))
                    end
                    if v:get_id() == 3 or v:get_id() == 6 or v:get_id() == 9 then
                      assert(SMODS.change_base(v, nil, 'Queen'))
                    end
                    if v:get_id() == 4 or v:get_id() == 7 or v:get_id() == 10 then
                      assert(SMODS.change_base(v, nil, 'King'))
                    end
                end
                return true
            end
        }))
    end,
}
wanton jolt
#

thats one of the ways i thought of

red flower
wanton jolt
#

yea

red flower
wanton jolt
#

like a soul pos with a blank sprite, until its "combined" then soul pos changes to the head sprite

red flower
#

ah yeah i do that for one of my mods

wanton jolt
#

and i guess to merge and separate them i'd use consumables

jagged gulch
red flower
wanton jolt
#

yeah

#

remove them

#

also set unlocked to true

red flower
#

also i recommend installing the release version of smods instead of the latest commit

hardy vessel
#

I'm looking into context.modify_shop_card and I want to use it to change the first card in a shop line up but I'm not sure how to go about it. G.shop_jokers.cards[1] doesn't seem to work

hardy vessel
#

Having specific jokers or Tarots appear at certain shops

red flower
#

do you want it to work like tags where they replace the first card of the set or always the first in the shop?

hardy vessel
#

first card no matter the set (so a joker could replace a planet, for example)

red flower
#

you should probably use create_shop_card instead and return the card you want the first time it's called

wanton jolt
#

fuck

red flower
#

you can check context.starting_shop to set a flag and context.ending_shop to remove it

hardy vessel
dapper sun
#

if i'm using a smods hold keybind, how do i get when it's released?

hardy vessel
prime timber
#

for anyone that uses jokerforge, would you be able to explain the variables to me? i am trying to make a joker that prevents a blind from ending until all hands are played but i cant figure out how to work it

#

the basic thing i want to do is say "when hand is scored, if total score would exceed the blind (i.e. end the blind) & hands remaining are > 1 (so that you can actually still leave the blind once hands are gone), then reset the target blind to be your total score +1"

#

but it seems like the Blind Requirement condition and the Modify Blind Requirement effect are not working properly and not really letting me set the right numbers

wanton jolt
#

export your current joker code

#

i'll do the thing

prime timber
#

for realskies?

wanton jolt
#

yes

prime timber
#

like the .lua file?

wanton jolt
#

yes

prime timber
#

coming right up

wanton jolt
#

i will just make the code work but not clean it up to normal coder standards, you will still have forgeslop

prime timber
#

yeah of course, i want the slop

wanton jolt
#

ew

prime timber
wanton jolt
#

fuck when i set the blind requirement it does it before it finishes scoring despite me putting in context.after

prime timber
#

yeah thats weird

#

just throwing ideas out there, would it maybe be possible to calculate the score before the hand is actually played, and then if the hand is played and before the cards are scored, increase blind to calculated value +1?

#

definitely clunky but idk if that would solve the problem

prime timber
#

yay! success?

wanton jolt
#

wait

prime timber
#

okay tyt! thank you so much again

wanton jolt
#

why u saying ty and thank you

#
SMODS.Joker{ --Walter White
    key = "walterwhite",
    loc_txt = {
        ['name'] = 'Walter White',
        ['text'] = {
            [1] = 'Does not exit a {C:attention}Blind{}',
            [2] = 'until all hands are played'
        },
        ['unlock'] = {
            [1] = 'Unlocked by default.'
        }
    },
    pos = {
        x = 0,
        y = 0
    },
    display_size = {
        w = 71 * 1, 
        h = 95 * 1
    },
    cost = 6,
    rarity = 2,
    blueprint_compat = false,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = true,
    atlas = 'Joker',
    pools = { ["modprefix_mycustom_jokers"] = true },
    
    loc_vars = function(self, info_queue, card)
        
        return {vars = {(G.GAME.chips or 0)}}
    end,
    
    calculate = function(self, card, context)
        if context.after and context.cardarea == G.jokers and not context.blueprint then
                return {
                    func = function()
                        G.E_MANAGER:add_event(Event({
                            func = function()
                                if (SMODS.last_hand_oneshot or G.GAME.chips >= G.GAME.blind.chips ) and G.GAME.current_round.hands_left > 0 then
                                    card_eval_status_text(card, 'extra', nil, nil, nil, {message = "Not Done Yet.", colour = G.C.GREEN})
                                    G.GAME.blind.chips = math.floor(G.GAME.chips + 1)
                                    G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
                                end
                                return true
                            end
                        }))
                    end
                }
        end
    end
}
prime timber
wanton jolt
#

oh

#

yeah minimum hands had to me > 0 because the hands get substracter before context.after is calculated

prime timber
#

oh that makes a lot of sense

#

how do i import this back into jokerforge?

wanton jolt
#

uhhh idk good luck

#

ask jokerforge discord

prime timber
#

will do, thank you for the help

#

@wanton jolt how would you normally add this in outside of jokerforge?

pastel kernel
#

Ok nothing’s working.

wanton jolt
#

well i would just not have the loc_txt in the joker file

#

because i handle loc in a separate file

pastel kernel
#

ok why tf am i not allowed to add or subtract the set value 0?

#

wdym start is a nil value?

idle plaza
pastel kernel
#

i wrote card.ability.start instead of card.ability.extra.start, otherwise it's still not working as intended

#

eggman either ignores the "if sell value is 0" argument or is permanently sold even when the sell value is not 0

idle plaza
#

What's your code for that joker?

pastel kernel
#
SMODS.Joker {
    key = "eggman",
    unlocked = false, 
    atlas = "bb_legendary",
    blueprint_compat = true,
    pools = { ["bustjokers"] = true },
    rarity = 4,
    cost = 1,
    pos = { x = 0, y = 4 },
    soul_pos = { x = 0, y = 5 },
    config = { extra = { start = 0, gain = 3 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.start, card.ability.extra.gain } }
    end,
    add_to_deck = function(self, card, from_debuff)
    for k, v in ipairs(G.jokers.cards) do
        if v.key == "j_busterb_eggman" then
        card.ability.extra_value = 0
        card.ability.extra.start = 0
        end
    end
end,
    calculate = function(self, card, context)
        if context.selling_card and context.card.ability.set == "Joker" then
            card.ability.extra_value = card.ability.extra_value + card.ability.extra.gain
            card.ability.extra.start = card.ability.extra.start + card.ability.extra.gain
            card:set_cost()
            return {
                message = localize('k_val_up'),
                colour = G.C.MONEY
            }
        end
    end,
    remove_from_deck = function(self, card, from_debuff)
        if G.jokers then
            if card.ability.extra.start < 1 then
                return true
            else
                local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_busterb_eggman", "eggman")
                card.sell_cost = 0
                card:add_to_deck()
                G.jokers:emplace(card)
            end
            
        end
    end,
}```
#

i forgot to remove the comment, i stole this from egg

idle plaza
# pastel kernel ```lua SMODS.Joker { key = "eggman", unlocked = false, atlas = "bb_...

I don't think the remove_from_deck function allows you to prevent destruction? I think it's just a "do things in response to being destroyed" type of function.

Try using context.joker_type_destroyed in your calculate instead. This does let you return {no_destroy = true} when you want to prevent the destruction. Just check to make sure context.card == card alongside everything else.

pastel kernel
#

i was thinking of selling_self but idk if this also works

idle plaza
#

No clue. The smods wiki page on calculate functions only mentions joker_type_destroyed having any way to prevent destruction, but it's also not necessarily the most up-to-date thing in the world.

pastel kernel
#

somethingcom save me

pastel kernel
#

wait, context.card == card?

red flower
#

what are you trying to do? i didn't understand your description very well

idle plaza
# pastel kernel wait, context.card == card?

Because joker_type_removed responds to everything gettin destroyed (except playing cards), whereas what you were using before, remove_from_deck was only called for the joker itself being removed.

pastel kernel
#

ok so, dr. eggman, legendary, he always starts at 0 sell value, it increases by 3 each time a joker is sold, and when you sell him, he reverts back to 0 sell value. if you sell him at 0 sell value, he disappears completely.

red flower
#

ah ok, i don't think this is something you can do with only the api

#

you would probably need to hook the sell function

pastel kernel
#

i'll have to change his ability then

idle plaza
#

-# To be fair that looked kinda weak for a legendary anyways

pastel kernel
#

either that or you can suggest a different ability altogether

pastel kernel
#

instead of selling a joker, it's when a joker is triggered

wanton jolt
#

how do i make it so a joker can't be debuffed at all when/if a certain sticker is applied on it

idle plaza
wanton jolt
#

awesome thanks

gilded blaze
#

you can also use SMODS.debuff_card

thorn ingot
#

Hey guys, do you know how I could make one of the tags that appears on ante 2+ appear on ante 1?

I've been trying this, but it doesn't quite work.

        return (G.GAME.round_resets.ante >= 1)
    end,```
idle plaza
thorn ingot
#

Wouldn't that make it not appear on ante 1? that's what I want.

gilded blaze
idle plaza
gilded blaze
#

wait, in_pool takes priority over min_ante iirc

#

why doesn't it work

thorn ingot
#

I don't know been trying it and it just doesn't show up

red flower
#

probably some vanilla jank

thorn ingot
#

I'm trying to change the meteor tag

gilded blaze
#

ok I was wrong then

#

remove min_ante field

thorn ingot
#

okay, I'll rewrite that section.

#

thanks guys.

wanton jolt
#

<@&1133519078540185692>

exotic hedge
#

bam

wanton jolt
#

epic lolhappy win

near coral
#

Is the game hard coded to do Xmult after +mult

wanton jolt
#

uhhh

#

you could try giving mult on after?

thorn ingot
#

Aight, got it working. For posterity:

min_ante = nil, doesn't work. min_ante = 1, does.

wanton jolt
#

or use events?

near coral
#

I'm wanting a rekoj that does +mult after ÷mult (Xmult below X1)

#

But my coder said it's impossible without changing the inherent order for mult calculation

tall wharf
#

oh

#

you can use like

#

SMODS.calculate_effect

near coral
#

Are you talking about the ÷mult or the mult order
The ÷mult is already handled

#

÷1.2 just equates to approximately X0.83333 so I just had it do that

near coral
#

Oh

#

And that's supposed to make an exception to the typical +mult then Xmult logic?

tall wharf
near coral
#

For context, is it that the vanilla process favors +mult over Xmult and the smods one allows complete freedom over the order applied?

wild patrol
#

is there a limit on how many animated jokers you can have

#

I added another one but the spirte sheet is invisible

#

everything is in the correct spot

faint yacht
#

return { xmult = val, extra = { mult = otherval } }

wild patrol
#

nvm I figured it out

#

my dumbass forgot to set the pos to 0

rapid stag
#

oh, thanks for leaving me scrolled up discord, very cool

debuff_card is probably also better for it, yeah

near coral
#

Why is this voucher wide

#

(Rightmost one)

wanton jolt
#

what does the atlas look like

near coral
#

However I didn't code them in, so I know it's a code thing

wanton jolt
#

thats what i asked kinda

#

the atlas code

near coral
#

Oh whoopsie

wanton jolt
near coral
#

The size issue is persistent across both the tier 1 and 2 versions so I'm just sending the tier 1

wanton jolt
#

thats just the voucher code

near coral
#

I'm out of it today istg

wanton jolt
#

also you should change unlcocked to unlocked

near coral
#

They have a habit of misspelling things

#

In fact they accidentally gave 2 rekojes the same name

wanton jolt
#

anyway if you have the atlas for the vouchers

#

the atlas code

near coral
#

I don't know where to access the atlas code

#

I only know about the atlas graphic sheet

wanton jolt
#

uhh wait

#

oh ur github is

#

just the zip file

near coral
#

My github is outdated

#

I can send the test build here if you want

wanton jolt
#

i guess yeah

near coral
wanton jolt
#

yeah voucher px is 61 instead of 69

#

go on main.lua

daring fern
wanton jolt
#

true

#

i looked at the code above like an idiot

near coral
#

So it's 61 px instead of 71 px

wanton jolt
#
SMODS.Atlas({
    key = "Vouchers",
    path = "bzr_vouchers.png",
    px = 71,
    py = 95,
})
#

its 71 instead of 61

near coral
#

Yeah, I meant it as it currently being 61

wanton jolt
#

yeah

#

lol why are the jokers 95.1

near coral
#

I have no idea

#

I didn't even know that until now

#

If you want point out any more errors for me to fix, I can send them the updated lua file

wanton jolt
#

i mean most things that should be 71 * 95 arent

near coral
#

Such as what

wanton jolt
#

like misprint

#

consumables

near coral
#

Ok so bizarro misprint is a special case, it's supposed to have a mini rekoj inside of a display window

wanton jolt
#

wait no consumables just doesnt have the border

near coral
#

?

wanton jolt
#

and its the same for misprint

wanton jolt
near coral
#

The whole grade 10 ordeal has been solved already, at least I hope

#

So the consumables and "bzr_misprint" are supposed to be 71x95?

wanton jolt
#

no its fine

#

because the atlas size is the same as their actual image sizes

#

so there should not be any stretching issues

#

as far as i am aware

#

anyway i need to rly do my totems lol

near coral
#

I want to be on the safe side and have it be the standard measurements

#

All I need to know is if they're meant to be that

wanton jolt
#

for it to be in the standard measurements (idk for misprint and how its coded exactly

#

the consumables should be in a similar grid size than a joker so 71*95

#

while the card itself is 63*93

#

so there should be a left and right margin of 4px and a top and bottom margin of 1px

near coral
#

So while the smods measurement has it be the same grid size as jokers, the atlas sheet can still be the standard 1 px margin on all sides?

wanton jolt
#

well in the case of your consumables

#

the current smods measurement is the same as your actual sheet file

#

both are not standard

#

now you only have one consumable so its not that much of an issue yet

near coral
#

Well 2 really, a tier 1 and a tier 2

wanton jolt
#

i only see morality here

near coral
#

Oh wait I'm thinking of vouchers I'm rupid

#

Yes there's only one consumable

wanton jolt
#

yeah for vouchers you need to add some left and right margin

near coral
#

So instead of 1 px on all sides it's 4 px horizontally and 1 px vertically

#

And this accounts for both parrallel sides?

wanton jolt
#

just overlay your vouchers on this pic tbh

near coral
#

Skul

#

There's a horizontal margin of 6 px on the left and right is that correct?

wanton jolt
#

vouchers are thinner than consumables

#

yeah

near coral
#

And the consumables are 4 px horizontally

near coral
#

So it shouldn't matter, seeing as they're to be stuffed inside a card sleeve

#

Ok I changed the consumable size on both the atlas code and atlass sheet and this is what I got

wanton jolt
#

did u add a margin

near coral
#

Atlas px I made 71x95 as well

#

It matches the canvas size

#

The voucher issue is fixed though

wanton jolt
near coral
#

Whole game, but I saved everything before closing

wanton jolt
#

uhhh

#

weird

near coral
wanton jolt
#

did you also change the 2x? i know that question could be stupid

near coral
#

Oh wait you're right

#

I hadn't

#

Only the 1x

wanton jolt
#

did you do the 2x for the vouchers?

near coral
#

And I have the game with art smoothing on

near coral
wanton jolt
#

wait you have python right

near coral
#

What are you trying to sell me

wanton jolt
#

just a one click resize assets

#

so that you change the 1x

#

click this

near coral
#

I have aseprite I can do it on my own

wanton jolt
#

and it does the 2x automatically

#

oh thats cool

near coral
#

Alright everything is fixed

wanton jolt
#

👍

near coral
tranquil echo
#

why is it evil

    key = 'effect_give',
    primary_colour = G.C.RED,
    secondary_colour = G.C.RED,
    default = 'PLACEHOLDER',
    collection_rows = {4,4},
}

SMODS.Atlas {
    key = "effect_give",
    path = "../../source/assets/1x/PLACEHOLDER.png",
    px = 34,
    py = 34
}

SMODS.Consumable{
    key = 'PLACEHOLDER',
    set = 'effect_give',
    pos = {x = 0, y = 0},
}```
wanton jolt
#

you forgot to localise the name

tranquil echo
#

InuHuh
whats the syntax for that starr

wanton jolt
#

b_modname_key in dictionary i'm sure

tranquil echo
#

what? 😭
sorry im really bad at this i wont understand unelss its handed to me on a silver platter

wanton jolt
#

do you have a localisation lua

tranquil echo
#

OHH LIKE FOR LANGUAGES

#

no

#

okay i understand now

wanton jolt
#

tough

#

i honestly dont know how to do localisation in the same file as the consumable

#

lol

#

but if u end up making a language lua its in

return{
  ...
  misc={
    ...
    dictionary ={
      ...
      k_modname_key = "effect give",
      ...
    },
    ...
  },
}
tranquil echo
#

ouuu okay

#

yeah i was figuring it out tysm

wanton jolt
#

... means there could be something there already

tranquil echo
#

and k_modname_key is k_[MODNAME]_key?

wanton jolt
#

k_[MODNAME]_[KEY]

#

modname being the prefix you set

tranquil echo
#

ah got it okay

wanton jolt
#

in my case felijo

daring fern
tranquil echo
#

what

wanton jolt
#

what

#

on right

#

you have to put _cards at the end

tranquil echo
#

mm okay

#

mmmm no it still hates me

wanton jolt
#

what did you put in the dictionnary

tranquil echo
#

k_embr_effectgive_cards = "Effects",

wanton jolt
#

your key is effect_give not effectgive

tranquil echo
#

"prefix": "embr",
is whats in my json

wanton jolt
#

it should be b_embr_effect_give_cards = "Effects",

#

god i'm tired