#đŸ’»ăƒ»modding-dev

1 messages · Page 54 of 1

tepid crow
#

but regardless, isn't that fixed if I make an obj_buffer in my code?

frosty dock
#

no

#

the main issue is that in the tree of classes that the injection routine passes through, all classes with an obj_table and obj_buffer are considered to be leaves

tepid crow
#

yes makes sense when I look at this function

#

but doesn't Center (a class with obj_table/buffer and thus a leaf) also get extended?

frosty dock
#

yes, but there are no subclasses of Center that need a custom pre-/post-injection step

tepid crow
#

Center is a "leaf" (which is becoming a very vague definition for me now) and thus has it's subclasses only inserted on steamodded start?

#

as opposed to GameObject that isn't a leaf, and thus inserts any subclass at any time, including those after steamodded start?

frosty dock
#

Center is a leaf in the sense that its subclasses are not considered by injectObjects, as subclasses would usually have the same obj_table/obj_buffer inherited from Center

#

so exploring these as additional nodes would mean centers get injected multiple times

tepid crow
#

right, inheritance

#

makes sense so far

frosty dock
#

I think this should work?

tepid crow
frosty dock
frosty dock
#

it would be perfectly reasonable to call SMODS.Center directly and provide these functions yourself because there's nothing inherently different

tepid crow
frosty dock
tepid crow
#

otherwise it would be kinda confusing with inject yes

tepid crow
frosty dock
#

you shouldn't

tepid crow
#

fair 'nuff

muted timber
#

spends like an hour trying to find the problem
realise that i wrote 'voucher = ' instead of 'vouchers ='

#

🙃

tepid crow
#

hey, at least you found it >:D

muted timber
#

who knew that the code had plural

#

never seen something like that ever before

tepid crow
#

though you really should be using steamodded...

muted timber
#

true but i was too lazy to write more stuff

frosty dock
#

I was thinking I might have to push 0805i, but thankfully it's the next day now balatrojoker

frosty dock
#
  • you literally can't distribute anything or get anyone to help you debug
muted timber
#

yeah but it was really more of a one-time thing

limpid flint
#

Tomorrow ?

tepid crow
#

tomorrow

frosty dock
#

recent steamodded is fairly good at not making you worry too much about the specifics of the game's code

wintry solar
tepid crow
#

if "a deck adds a consumable"?

frosty dock
#

can the delay not be changed?

wintry solar
#

it probably can

#

I don't know why it's there tbh

frosty dock
#

pushed tomorrow's fix upstream btw

tepid crow
#

oh I see, that gets rid of the super

maiden phoenix
#

This is sick tho

wintry solar
#

they would do if cryptid wasnt installed

maiden phoenix
#

Damn you Cryptid

wintry solar
#

also selecting some of your decks spits out a LOT of debug messages

maiden phoenix
#

That's weird...

#

What are those debug messages exactly?

wintry solar
#

when I click the alst one I get a whole load of keys

frosty dock
#

oops, that thing I changed reversed the stake order 💀

tepid crow
#

lmao

maiden phoenix
tepid crow
#

when he clicks on it in his deck selector lol

maiden phoenix
tepid crow
#

those are from SMOD itself

frosty dock
#

actually i don't even know what may not work correctly 💀

edgy reef
#

Neither do I.

tepid crow
#

ejwu wrote that so that makes sense

wintry solar
wintry solar
maiden phoenix
#

Oh shit

#

Ok I see the issue...

wintry solar
#

its when apply to run is called

maiden phoenix
#

I have an util function with a debug call in it...

#

Will remove it

wooden nexus
#

Welp, I should start making ranks

tepid crow
#

wait, apply to run gets called... oh right because you need the decksize

#

wow

wintry solar
#

yeah, it's the only way I can find to actually calculate decksize consistently

tepid crow
#

I actually saw SDM's debug message then but discarded it cuz it was in apply lol

tepid crow
wintry solar
#

gah, stake api has so many bugs in

maiden phoenix
#

Pushed the debug message removal

zealous glen
tepid crow
wintry solar
#

what on earth is this for thunk

tepid crow
#

oh I found a fun little piece of thunk code a minute ago

wintry solar
#

"if you win on a stake make sure all the previous stakes have a win saved"

#

WHY

tepid crow
#
            if node.config.vert then local thunk = tx; tx = ty; ty = thunk end

swapping variables by using a temp thunk (don't mind the fact you can a, b = b, a in lua)

mellow sable
wintry solar
tepid crow
frosty dock
#

yeah wtf

#

anyways I still have no idea why the version where the same code runs for every stake works but doing it only once doesn't

#

so i just reverted to that

wintry solar
#

aure do you know who wrote stake api?

frosty dock
#

yes

#

MathIsFun did

vague monolith
#

hey do u guys understand how the fusion mod api works because im trying to make my own addons for a pack and i am so lost 😭

tepid crow
#

just for clarity, which fusion mod? I think there's multiple lol

#

Right, so, quick follow-up on that:

G.P_LOCKED = {}
for k, v in pairs(G.P_CENTERS) do
    if not v.wip and not v.demo then
        ...
        if not v.unlocked and (string.find(k, '^j_') or string.find(k, '^b_') or string.find(k, '^v_')) and meta.unlocked[k] then
            v.unlocked = true
        end
        if not v.unlocked and (string.find(k, '^j_') or string.find(k, '^b_') or string.find(k, '^v_')) then
            G.P_LOCKED[#G.P_LOCKED + 1] = v
        end
        ...
    end
end

these string patterns are kinda preventing my sleeve___rest_of_key from entering P_LOCKED
I could just hook into SMODS.SAVE_UNLOCKS() but that also seems a tad hacky

vague monolith
#

I know they have a api for it, but im not a very great coder and I dont really understand what im doing lol

frosty dock
#

that's just mindlessly copied base game code

tepid crow
frosty dock
#

wdym soon

#

it already is

tepid crow
#

I mean, I'd argue 0.9.8 is the "last stable version" if that makes sense

vague monolith
tepid crow
#

mostly cuz it's the last one in releases tbf

frosty dock
#

I would argue it's less stable than current 1.0

tepid crow
#

fair enough lol

tepid crow
frosty dock
#

0.9.x were pretty much daily releases for a week lmao

vague monolith
tepid crow
tepid crow
vague monolith
tepid crow
#

their API doesn't make creating jokers any easier 😅

mellow sable
#

oh i think i see

#

i kinda left some of the stake stuff the same that probably needs to be overhauled because I assumed that you would still have a linear progression in the stake selection UI

#

this new UI doesn't do that, so it's causing things to break down and the unlock behavior should be completely refactored

limpid flint
#

and I think stakes should (somehow) have a specific order, rather than jumbled everytime

#

Or else it wouldn't be called "progression"

mellow sable
#

Ordering is already handled I think

zealous glen
vague monolith
mellow sable
zealous glen
vague monolith
zealous glen
#

Try Steamodded 1.0

vague monolith
# zealous glen Try Steamodded 1.0

I don’t think I will for now because I’m building these to play on mobile and the mobile version doesn’t properly support that

crisp coral
#

please don't talk about modding on mobile in this server

vague monolith
#

Oh, sorry

limpid flint
#

Luckily I am playing on windows

vague monolith
#

Realll, feel bad for the people who are trying to mod on r2modman lol

wintry solar
#

I’ve sort of cobbled together an unlock system

#

In that it checks for wins on the applied stakes, but I haven’t been able to get the stickers working properly, although that could just be because my test alternate stake path doesn’t have any stickers

mellow sable
mellow sable
wintry solar
#

Tooltips?

#

Oh do you mean unlock tooltips?

mellow sable
#

Or whatever

wintry solar
#

Oh I see

young cloud
#

truly a bugfix of all time

unkempt ridge
young cloud
#

huge

#

if you care how it works i can add some comments

#

but my recommendation is pretend like nothing ever happened 💀

unkempt ridge
#

cheeky having it be checking the previous cards rank instead
thank you so bloody much for real ;-;

young cloud
#

yeah its a bit jank but it works

#

anytime

gilded blaze
#

stronger than wee joker yet is an uncommon

#

💀

unkempt thicket
#

how do you set up consumable booster packs correctly?

dense pagoda
#

getting started on making custom jokers, what is the canvas size for the sprites? aseprite puts it at 71x95px with a 1px transparent border, but i wanted to confirm

crisp coral
#

yup, 71x95 with 1px transparent border

dense pagoda
#

noice. ive never done digital art before but this'll be a fun project

placid frigate
#

ok so i just finshed making my mod for 0.9.8, how to I transfer it over to 1.0.0?

limpid flint
#

Seek Steamodded wiki

placid frigate
#

is it on the GitHub?

limpid flint
unkempt thicket
#

isn't draw_hand what makes the deck draw to hand in booster packs? it doesn't appear to be working did I miss something?

unkempt ridge
glass scaffold
#

What can cause my mod to not be seen?

(it's in the right folder, it has the ---Steamodded header)

glass scaffold
#

Here's all the code

rough furnace
#

What's the logs say?

glass scaffold
#

Duplicate Mod prefix joke used by JokersButArya, JokerDisplay

#

WHAT

#

Welp, I finally got it to work.

#

Doesn't mean that code is working.

vague monolith
#

what id give right now to understand anything im looking at

#

what do you mean error on line 10 i dont even understand what line 10 does

wintry solar
# glass scaffold Doesn't mean that code is working.

You’re missing a comma after your loc_txt. The reason it wasn’t loading is because you didn’t define a mod prefix in your header, and it defaults to the first 4 characters of your name, which Joker Display is already using

glass scaffold
opal spade
#

is there any quick way to check whether a smods object originates from vanilla or a mod?

edgy reef
#

Check if the object’s center has “mod” in it.

#

Although it doesn’t really work with cosmetic mods like Aura.

opal spade
#

i'll check if that'll work for what im doing, and also i dont mind not detecting cosmetic stuff

#

yup it works, thank you

glass scaffold
wintry solar
#

you need loc_vars too, hold on

#
loc_vars = function(self, info_queue, card)
    return {}
end```
glass scaffold
#

Yeah...

wintry solar
#

huh

#

can I see the code again?

glass scaffold
wintry solar
#

loc_txt = ...

#

you can likely remove the loc_vars then

glass scaffold
#

now how to do that fancy text for the mult...

#

Anyone here know how that's done?

frosty dock
#

{X:mult,C:white} X#1# {} Mult

#

(the #1# is for using vars, which you should, but technically you can just put 2 there)

wanton grail
#

couldnt u also look off the other already existng jokers and d work from thrrere

#

as like a example almost

regal wolf
#

@languid mirage what was the mod that only worked with cryptid / modded consumables that stacked them?

frosty dock
#

incantation?

hushed cradle
#

is there a simple way of changing the saved message to say saved by another joker?

glass scaffold
#

Not sure if this helps, but maybe this'll give a hint

hushed cradle
#

all in my code already

#

thanks tho

glass scaffold
#

btw you have anything that checks for when a card of a certain suit is played?

hallow forge
wintry solar
hushed cradle
#

ill go digging

hushed cradle
#

ay thank you

regal wolf
#
                    table.insert(left_text,                  
                    config.saved and 
                    {n=G.UIT.C, config={padding = 0.05, align = 'cm'}, nodes={
                        {n=G.UIT.R, config={align = 'cm'}, nodes={
                            {n=G.UIT.O, config={object = DynaText({string = {' '..localize('ph_mr_bones')..' '}, colours = {G.C.FILTER}, shadow = true, pop_in = 0, scale = 0.5*scale, silent = true})}}
                        }}
                    }
#

just replace localize('ph_mr_bones') with a string

#

although you will have to make a seperate config.x var bc

#

currently config.saved only ever means that you're saved by mrbones

hushed cradle
#

ah right

glass scaffold
hallow forge
#

local variables for the card desciption

glass scaffold
#

Oh

#

The text stuff is already good to go

#

Now I just have to find out how to make it actually work.

glass scaffold
#

So how do I make sure this only counts scored cards that are Hearts?

frosty dock
#

first name the function calculate

glass scaffold
#

Done

frosty dock
#

context.other_card:is_suit('Hearts') should be the check you want

glass scaffold
#

replace context.cardarea or add it as an additional check?

maiden phoenix
#

Iirc theres multiple context.individual, you'll have to add another check

glass scaffold
#

So that code above's not going to work?

#

(also, if you know how to double the mult, pls tell me)

maiden phoenix
glass scaffold
frosty dock
#

yeah you also need the cardarea check

maiden phoenix
#

What does your Joker do?

glass scaffold
maiden phoenix
#

The mult to the left or a specific modular mult?

glass scaffold
#

The mult to the left

maiden phoenix
#

mult = mult * 2 should normally work ig?

#

I forgot if thats the exact var name

frosty dock
#

that doesn't display a message though

maiden phoenix
#

Could always create its own

frosty dock
#

just check some joker that does this

#

bloodstone, photograph, triboulet, whatever

maiden phoenix
#

I just realized the joker is just a boosted bloodstond

glass scaffold
#

WELL UHHH

primal robin
#

This patch is not working. Why? RUN

[[patches]]
[patches.pattern]
target = "functions/UI_definitions.lua"
pattern = '''colour = challenge_unlocked and G.C.RED or G.C.GREY'''
position = "at"
payload = '''colour = G.C.GREEN'''
match_indent = true
overwrite = true
glass scaffold
maiden phoenix
#

Just check bloodstone's code

glass scaffold
#

"Oh dear Neptune..."

glass scaffold
languid mirage
glass scaffold
nocturne garnet
#

i dont know how to make cards have effects using decks

#

but i did the first part

frosty dock
nocturne garnet
frosty dock
#

also you still need the cardarea check back

#

else it tries to trigger on other things as well, e.g. cards held in hand

glass scaffold
glass scaffold
#

wait, what's Lua's AND operator?

nocturne garnet
glass scaffold
nocturne garnet
#

its and

#

if context.other_card:is_suit("Hearts") and context.cardarea == G.play then

frosty dock
#

that's a new one haha

glass scaffold
#

I'm a baby in Lua

frosty dock
#

i don't know of any programming language that uses + for its logical and

glass scaffold
#

I saw it in some code snippet when searching

frosty dock
#

works for javascript maybe

glass scaffold
#

Nope, JS and Java are &&

frosty dock
#

yeah ik

#

but with type coersion technically + can be misused as a logical or

primal robin
#

In JS boolean + number is working fine

frosty dock
glass scaffold
#

I don't think I need that card = self, do I?

frosty dock
#

you named your card argument cards

#

change it to card and do card = card

#

instead of card = self

glass scaffold
#

Bloodstone gets a pass somehow.

wintry solar
#

because bloodstone isnt using the smods api

glass scaffold
#

touche.

frosty dock
languid mirage
glass scaffold
#

All the changes are made, and here we are.

frosty dock
#

you didn't put extra in your config

glass scaffold
#

so is that gonna be a seperate file or just another variable in the code?

primal robin
frosty dock
frosty dock
#

I'm saying js is cursed

primal robin
#

I know, and that's why i like it

primal robin
#

self.config.extra

frosty dock
#

i didn't actually check the code smh

#

you can change card.ability.extra.Xmult to just card.ability.extra in this case

#

but that crash shouldn't be, maybe you didn't save the file?

glass scaffold
#

I've saved all the changes

frosty dock
#

can i see the full joker definition

glass scaffold
#

:O IT'S WORKING FLAWLESSLY

#

Winning code:

frosty dock
#

wait why is it legendary now

glass scaffold
#

As a semi-balancing measure

#

The cost got cranked up too.

frosty dock
#

legendaries always cost $20

#

not like you can buy them anyways

glass scaffold
#

Oh

#

Alright, noted

wintry solar
#

is there enough contrast between beaten, unlocked and locked?

#

or maybe I create a locked sprite

crisp coral
#

locked should be darker imho

hushed cradle
#

is bottom locked?

#

i think the fact that the chips are smiling at me is throwing me off

hallow forge
#

Locked should def be a sprite

wintry solar
#

locked are row 2, 4-8, row 3, 1-2 & 7-8

hushed cradle
#

ah right

#

yeah i think locked could do with a special sprite

crisp coral
#

making locked completely dark could also work

hushed cradle
#

that smiling chip is unsettling

wintry solar
#

someone pls make me a locked sprite

frosty dock
#

I'll try after lunch

hushed cradle
#

ill see what i can do

wintry solar
#

this also works I guess

hushed cradle
#

im now remembering why i dont do pixel art 💀

#

thoughts? 😭

wintry solar
#

It does the job

hushed cradle
#

thanks lol

wintry solar
#

I will plug it in after lunch

hushed cradle
#

in return could you maybe help me w this??

#
calculate = function(self, card, context)
        if context.setting_blind and not card.getting_sliced and not context.blueprint and not card.debuff and not context.control_devil then
            if context.blind.boss then
                G.GAME.blind.chips = G.GAME.blind.chips  * (self.config.decrease / 100)
            else
                G.GAME.blind.chips = G.GAME.blind.chips + (G.GAME.blind.chips * (self.config.increase / 100))
            end
        end
        G.HUD_blind:recalculate()
    end,```
#

that doesnt seem to be recalculating the hud

#

im not really sure how im supposed to

#

i thought for sure thatd work

#

aha

#

mightve figured it out

wintry solar
#

Trying to adjust the required score?

hushed cradle
#

yeah i got it

#
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
G.HUD_blind:get_UIE_by_ID('HUD_blind_count').UIBox:recalculate()
#

oops

#

i think my math is off tho

#

yeah im stupid

#

would it be too broken to have it compatible with

#

because boss blinds pretty small

#

but the other blinds will be so big in comparison

#

i guess you could skip tho

wintry solar
#

Two slots to do that might balance it a little

hushed cradle
#

thats true

wintry solar
#

What does your config look like btw?

hushed cradle
#

its not blueprint compatible

#

my what

wintry solar
#

In your joker

hushed cradle
#

oh right

#
local control_devil = SMODS.Joker{
    key = 'control',
    name = 'Control Devil',
    rarity = 'csm_epic',
    discovered = true,
    pos = {
        x = 0,
        y = 0
    },
    cost = 12,
    config = {
        extra = 1,
    },
    loc_txt = {
        name = 'Control Devil',
        text = {
            'Trigger the effects',
            'of all Jokers {C:attention}worth{}',
            '{C:attention}less{} than this Joker',
        },
    },
    atlas = 'csm_epic_jokers',
    eternal_compat = true,
    perishable_compat = true,
    blueprint_compat = true,

    set_badges = function(self, card, badges)
        badges[#badges+1] = create_badge('Devil', get_badge_colour('devil'), nil, 1.2)
    end,

    calculate = function(self, card, context)
        if card.debuff then return end
        local jokers = {
            message = 'Bang!',
            card = card,
        }
        local ret = false
        for _, joker in pairs(G.jokers.cards) do
            if joker ~= card and joker.sell_cost < card.sell_cost then
                context.control_devil = true
                local joker_ret = Card.calculate_joker(joker, context)
                if joker_ret then
                    ret = true
                    if joker_ret.chips then
                        jokers.chips = (jokers.chips or 0) + joker_ret.chips
                    end
                    if joker_ret.mult then
                        jokers.mult = (jokers.mult or 0) + joker_ret.mult
                    end
                    if joker_ret.x_mult then
                        jokers.x_mult = (jokers.x_mult or 1) * joker_ret.x_mult
                    end
                    if joker_ret.h_mult then
                        jokers.h_mult = (jokers.h_mult or 0) + joker_ret.h_mult
                    end
                    if joker_ret.repetitions then
                        jokers.repetitions = (jokers.repetitions or 0) + joker_ret.repetitions
                    end
                    if joker_ret.Xmult_mod then
                        jokers.Xmult_mod = (jokers.Xmult_mod or 1) * joker_ret.Xmult_mod
                    end
                    if joker_ret.mult_mod then
                        jokers.mult_mod = (jokers.mult_mod or 0) + joker_ret.mult_mod
                    end
                    if joker_ret.chip_mod then
                        jokers.chip_mod = (jokers.chip_mod or 0) + joker_ret.chip_mod
                    end
                end
            end
        end
        return (ret and jokers) or nil
    end,
}```
wintry solar
#

I mean the reduction one

hushed cradle
#

oh

#

mb

#
local fox_devil = SMODS.Joker{
    key = 'fox',
    name = 'Fox Devil',
    rarity = 3,
    discovered = true,
    pos = {
        x = 0,
        y = 0,
    },
    cost = 7,
    config = {
        increase = 50,
        decrease = 25,
    },
    loc_txt = {
        name = 'Fox Devil',
        text = {
            'Small and Big Blinds',
            'are {C:attention}#1#% more{}, Boss',
            'Blinds are {C:attention}#2#% less{}',
        },
    },
    atlas = 'csm_rare_jokers',
    eternal_compat = true,
    perishable_compat = true,
    blueprint_compat = false,

    loc_vars = function(self, info_queue, card)
        return {vars = {card.ability.increase, card.ability.decrease}}
    end,

    set_badges = function(self, card, badges)
        badges[#badges+1] = create_badge('Devil', get_badge_colour('devil'), nil, 1.2)
    end,

    calculate = function(self, card, context)
        if context.setting_blind and not card.getting_sliced and not context.blueprint and not card.debuff and not context.control_devil then
            if context.blind.boss then
                G.GAME.blind.chips = G.GAME.blind.chips  * ((100 - self.config.decrease) / 100)
            else
                G.GAME.blind.chips = G.GAME.blind.chips + (G.GAME.blind.chips * (self.config.increase / 100))
            end
        end
        G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
        G.HUD_blind:get_UIE_by_ID('HUD_blind_count').UIBox:recalculate()
    end,
}```
wintry solar
#

Ah you fixed the math 👍

hushed cradle
#

yeah lol

hallow forge
#

Did someone say math?

hushed cradle
#

it was a bit too broken with my terrible math

#

yeah im terrible at it

#

i think im gonna try make some custom boss blinds too which should be fun

#

never tried it before

#
local chainsaw_devil = SMODS.Joker{
    key = 'chainsaw',
    name = 'Chainsaw Devil',
    rarity = 2,
    discovered = true,
    pos = {
        x = 0,
        y = 0,
    },
    cost = 5,
    config = {
        mult_min = 16,
        mult_max = 36,
        chips_min = 57,
        chips_max = 73,
        chips_chance = 0.6,
        money_min = 1,
        money_max = 3,
        money_chance = 0.4,
        woof_chance = 0.7,
    },
    loc_txt = {
        name = 'Chainsaw Devil',
        text = {
            'Just a friendly {C:attention}Devil{}',
            'trying his best to help',
        },
    },
    atlas = 'csm_uncommon_jokers',
    eternal_compat = true,
    perishable_compat = true,

    set_badges = function(self, card, badges)
        badges[#badges+1] = create_badge('Devil', get_badge_colour('devil'), nil, 1.2)
    end,

    calculate = function(self, card, context)
        if not card.debuff then
            if context.cardarea == G.jokers and not (context.before or context.after) then
                local chips = pseudorandom('pochita') < self.config.chips_chance
                if chips then
                    local temp_chips = pseudorandom('pochita', self.config.chips_min, self.config.chips_max)
                    return {
                        message = localize{type='variable',key='a_chips',vars={temp_chips}},
                        chip_mod = temp_chips,
                    }
                else
                    local temp_mult = pseudorandom('pochita', self.config.mult_min, self.config.mult_max)
                    return {
                        message = localize{type='variable',key='a_mult',vars={temp_mult}},
                        mult_mod = temp_mult,
                    }
                end
            elseif context.after then
                if pseudorandom('pochita') < self.config.woof_chance then
                    return {
                        message = 'Woof!',
                    }
                end
            end
        end
    end,

    calc_dollar_bonus = function(self, card)
        if pseudorandom('pochita') < self.config.money_chance then
            return pseudorandom('pochita', self.config.money_min, self.config.money_max)
        end
    end,
}```
#

is there a way to pass a mult_mod and chip_mult into the joker calc return thingy?

#

id like him to give a random amount of mult and chips

frosty dock
#

uh

wintry solar
#

You can pass both but it won’t do the messages properly

frosty dock
#

well first

hushed cradle
#

id rather he just do one and have the correct message then ig

frosty dock
#

if not card.debuff is unnecessary

hushed cradle
#

really?

#

thank god

frosty dock
#

yeah steamodded checks it for you

hushed cradle
#

awesome

wintry solar
#

You can throw your own messages though

hushed cradle
#

i never had a chance to test it w debuffed jokers

hushed cradle
frosty dock
#

and if context.cardarea == G.jokers and not (context.before or context.after) then can just be if context.joker_main then

hushed cradle
#

cool

#

thank you

frosty dock
#

for two separate messages, i guess you can use SMODS.eval_this, or use your own message for both

hushed cradle
#

i can just called the eval text directly right?

#

i think ill just do that then

#

i didnt know about smods.eval_this

frosty dock
#

just a wrapper for card_eval_status_text

hushed cradle
#

oh right

#

ill see if i can figure it out then

frosty dock
wintry solar
#

That seems wrong

hushed cradle
#

am i able to pass Xmult_mod and mult_mod?

frosty dock
#

I think insert_pool becomes inefficient somehow?

primal robin
#

Badges for blinds when? Lumaflute

frosty dock
#

20k is taking 2-5 seconds it seems

#

bottleneck seems to be recalculating table length

#

t[#t+1] = vs. table.insert sure doesn't seem to make a difference

wintry solar
hushed cradle
#

i might be biased but i think it looks pretty good

frosty dock
#

i like it

wintry solar
#

yeah I think it looks great

languid mirage
#

it works

limpid flint
#

Looks good and works

wintry solar
#

did someone say tooltips?

hallow forge
#

No, but cool

hushed cradle
#

thats hella cool

#

i love how the stake chips like stack

#

when im putting colours into joker descriptions

#

by doing {C:colour}

#

idk how to not make that long sorry

#

can i put in any colour?

#

or is there somewhere i can find all the available colours?

zealous glen
#

The colours are in globals.lua but

#

the colours for {C:colour} are in the loc_colour function in functions/misc_functions.lua

hushed cradle
#

thank you

zealous glen
#

Corollary: you can hook loc_colour to define your own

hushed cradle
#

cool

#

do i even need to hook?

#

can i just add a colour to G.ARGS.LOC_COLOURS?

zealous glen
#

I did it like this

local loc_colour_ref = loc_colour

function loc_colour(_c, default)
    if not G.ARGS.LOC_COLOURS then
        loc_colour_ref(_c, default)
    elseif not G.ARGS.LOC_COLOURS.vic_colours then
        G.ARGS.LOC_COLOURS.vic_colours = true

        local new_colors = {
            vic_HighCard = G.C.VictinsCollection.POKER_HANDS['High Card'],
            vic_Pair = G.C.VictinsCollection.POKER_HANDS['Pair'],
            vic_TwoPair = G.C.VictinsCollection.POKER_HANDS['Two Pair'],
            vic_3OAK = G.C.VictinsCollection.POKER_HANDS['Three of a Kind'],
            vic_Straight = G.C.VictinsCollection.POKER_HANDS['Straight'],
            vic_Flush = G.C.VictinsCollection.POKER_HANDS['Flush'],
            vic_FullHouse = G.C.VictinsCollection.POKER_HANDS['Full House'],
            vic_4OAK = G.C.VictinsCollection.POKER_HANDS['Four of a Kind'],
            vic_StraightFlush = G.C.VictinsCollection.POKER_HANDS['Straight Flush'],
            vic_5OAK = G.C.VictinsCollection.POKER_HANDS['Five of a Kind'],
            vic_FlushHouse = G.C.VictinsCollection.POKER_HANDS['Flush House'],
            vic_5OAFlush = G.C.VictinsCollection.POKER_HANDS['Five of a Flush'],

            vic_stone = G.C.VictinsCollection.ENHANCEMENTS.Stone,
        }

        for k, v in pairs(new_colors) do
        G.ARGS.LOC_COLOURS[k] = v
        end
    end

    return loc_colour_ref(_c, default)
end
zealous glen
#

excep for the animated colours which are in Game:update

hushed cradle
#

cheers

frosty dock
#

how's this for verbose logging

hushed cradle
#

im not sure what that word means

languid mirage
#

what's the point of logging atlas is injected if atlas name is not specified

#

at that point you might just send an end result

frosty dock
#

yeah this is for benchmarking

#

it'll only do it on trace level and if it's specificed

#

just the string formatting from all the individual logs slow everything down when there's lots of items

#

normally it'll just show the end result

#

rn we have nothing that's really slow to inject, if something like that gets added in the future we might want it enabled by default so ppl using it don't think the game froze

remote coral
#

Coffee joker, it has the jitters

lament fjord
#

Scalene jonkler has a noticeable diagonal seam in the middle

remote coral
#

It’s folded

#

Creased

maiden phoenix
#

the freaky juice_up

languid mirage
primal robin
#

God pls don't break all mods in new update eh

languid mirage
#

only 50%

frosty dock
#

it only needs to break one mod for disaster to strike

#

imagine if thunk got rid of the calculation tower tho

edgy reef
#

The game will be saved from all the lovely injections đŸ”„

frosty dock
#

đŸ”„đŸ’€đŸ”„

edgy reef
#

Especially these 3.

#

80-90 patches here from only a couple mods 😭

frosty dock
#

that's a normal amount of patches

zealous glen
#

thunk adds functions so people don’t have to access variables directly

frosty dock
#

aggressive scoping? guh

edgy reef
#

Wait yea I can just pull from Dim's modpack

zealous glen
frosty dock
#

imagine if thunk made the game accessible and I made black hole for nothing

languid mirage
#

he could be working on updates/fixes but instead he'll be spending time to make code look cleaner 😭

crisp coral
#

all that gets added is one comment that says stop posting about my ifelse tower

edgy reef
#

This is making me wonder if Thunk just adds a bunch of comments just to troll Steamodded injections.

languid mirage
#

thunk will obfuscate and inline all the code so it's not an ifelse tower but an endless ifelse line

zealous glen
#

Based aure

languid mirage
#

that's the ultimate way to break lovely patches

zealous glen
#

Thunk puts all of the game’s code in a single file that’s one line long

languid mirage
#

I think when that happens, he will probably go to modding community

zealous glen
#

Go where

languid mirage
#

here

zealous glen
#

Do what

languid mirage
#

well I'd assume communicate with modders about modding support, lol

#

how else would he know what modding support is needed

nocturne garnet
#

why wont this work raaghhh

languid mirage
#

of course he could completely ignore current modding, add his own API and whatever, but then you'll have another community split up

#

between steamodded and "official" modding

nocturne garnet
crisp coral
languid mirage
#

I think with current state of modding, there isn't that much modding support needed anyways, maybe native lovely patching so antivirus doesnt cry

zealous glen
languid mirage
#

sounds about right balatrojoker

mellow sable
#

no way is he gonna patch arbitrary code execution? balatrojoker

nocturne garnet
languid mirage
crisp coral
#

o7

mellow sable
#

With how many lovely patches there are

#

That are pattern patches, too

#

imagine calculation API gets completely refactored so localthunk can retrigger jokers

edgy reef
#

I'm more worried about Talisman than Cryptid tbh.

mellow sable
#

Most of those overrides are pretty internal, I don’t think it’ll suffer as much damage

frosty dock
mellow sable
#

Plus ideally we can figure out how to replace the Lua DLL to remove the weird lua metatable limitations

#

I know someone was working on that but they’re stuck trying to modify assembly to get __eq to work

crisp coral
#

have your own lovely download that also bundles the updated lua dll

frosty dock
#

idk if we would really want a thunk version of lovely

crisp coral
#

or is the problem making the dll itself

mellow sable
#

Yeah

#

Marr-Ales-Fios was working on fixing the LuaJIT source code but the problematic part is in assembly balatrojoker

hushed cradle
#
calculate = function(self, card, context)
        if not (context.blueprint or context.control_devil) then
            if context.cards_destroyed then
                local hearts = 0
                for k, v in ipairs(context.glass_shattered) do
                    if v:is_suit('Hearts') then
                        hearts = hearts + 1
                    end
                end
                if hearts > 0 then
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            G.E_MANAGER:add_event(Event({
                                func = function()
                                    card.ability.x_mult = card.ability.x_mult + hearts*card.ability.extra
                                return true
                                end
                            }))
                            card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.x_mult + hearts*card.ability.extra}}})
                            return true
                        end
                    }))
                end
                return
            elseif context.remove_playing_cards then
                local hearts = 0
                for k, v in ipairs(context.removed) do
                    if v:is_suit('Hearts') then 
                        hearts = hearts + 1
                    end
                end
                if hearts > 0 then
                    card.ability.x_mult = card.ability.x_mult + hearts*card.ability.extra
                    G.E_MANAGER:add_event(Event({
                        func = function()
                            card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.x_mult}}})
                            return true
                        end
                    }))
                end
                return
            elseif context.using_consumeable then
                if context.consumeable.ability.name == 'The Hanged Man' then
                    local hearts = 0
                    for k, v in ipairs(G.hand.highlighted) do
                        if v:is_suit('Hearts') then 
                            hearts = hearts + 1 
                        end
                    end
                    if hearts > 0 then
                        card.ability.x_mult = card.ability.x_mult + card.ability.extra*hearts
                        G.E_MANAGER:add_event(Event({
                            func = function()
                                card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type='variable',key='a_xmult',vars={card.ability.x_mult}}})
                                return true
                            end
                        }))
                    end
                    return
                end
            end
        else
            if context.joker_main then
                return {
                    message = localize{type='variable',key='a_xmult',vars={card.ability.x_mult}},
                    Xmult_mod = card.ability.x_mult
                }
            end
        end
    end,```
#

so i have this calculate function for a joker

#

when you destroy a heart card it increases the x mult by 0.25

#

for some reason its increasing twice for each card destroyed

#

not sure why and would appreciate any help

crisp coral
mellow sable
crisp coral
#

oh wait it doesn't

#

hold on

hushed cradle
#

oh

frosty dock
hushed cradle
#

not thank you then

crisp coral
#

err idk

hushed cradle
#

nws

#

its probably a stupid mistake on my part that ill figure out tomorrow or smth and be like how did i even do that

#

removing the hung man check seems to have worked

#

so i think you were right

#

power now works

zealous glen
hushed cradle
#

just so it doesnt scale twice as fast

#

or the control devil joker doesnt gain x mult

zealous glen
hushed cradle
#

whenever the joker triggers

zealous glen
#

Also, if it just doubles triggers, then it should scale twice as fast

zealous glen
hushed cradle
#

i dont really want it to tho its kinda op already

zealous glen
hushed cradle
#

its whenever a joker triggers, the control devil joker triggers too and does the same thing

hushed cradle
zealous glen
#

So it should trigger that Joker twice

hushed cradle
#

at least i think

zealous glen
#

Don’t create arbitrary exceptions

hushed cradle
#

well that would be what i want it to do

#

but i didnt code it to do that

zealous glen
#

Either rework the effect or let it be

#

Keep in mind it will trigger modded Jokers

hushed cradle
#

ill show the code hold on

#
calculate = function(self, card, context)
        local jokers = {
            message = 'Bang!',
            card = card,
        }
        local ret = false
        for _, joker in pairs(G.jokers.cards) do
            if joker ~= card and joker.sell_cost < card.sell_cost then
                context.control_devil = true
                local joker_ret = Card.calculate_joker(joker, context)
                if joker_ret then
                    ret = true
                    if joker_ret.chips then
                        jokers.chips = (jokers.chips or 0) + joker_ret.chips
                    end
                    if joker_ret.mult then
                        jokers.mult = (jokers.mult or 0) + joker_ret.mult
                    end
                    if joker_ret.x_mult then
                        jokers.x_mult = (jokers.x_mult or 1) * joker_ret.x_mult
                    end
                    if joker_ret.h_mult then
                        jokers.h_mult = (jokers.h_mult or 0) + joker_ret.h_mult
                    end
                    if joker_ret.repetitions then
                        jokers.repetitions = (jokers.repetitions or 0) + joker_ret.repetitions
                    end
                    if joker_ret.dollars then
                        jokers.dollars = (jokers.dollars or 0) + joker_ret.dollars
                    end
                    if joker_ret.Xmult_mod then
                        jokers.Xmult_mod = (jokers.Xmult_mod or 1) * joker_ret.Xmult_mod
                    end
                    if joker_ret.mult_mod then
                        jokers.mult_mod = (jokers.mult_mod or 0) + joker_ret.mult_mod
                    end
                    if joker_ret.chip_mod then
                        jokers.chip_mod = (jokers.chip_mod or 0) + joker_ret.chip_mod
                    end
                end
            end
        end
        return (ret and jokers) or nil
    end,```
#

no this is what ive done

atomic falcon
#

ffs

zealous glen
#

wh

hushed cradle
#

?

crisp coral
#

??

languid mirage
#

????

zealous glen
#

Instead of a custom context, use Blueprint’s

#

And make the original Joker being copied use Blueprint’s context

#

That way it doesn’t scale anything twice

#

Because vanilla Jokers already check for Blueprint before scaling

hushed cradle
#

its not scaling anything twice

zealous glen
#

Doesn’t it?

#

Anyways,

#

I think if you use Blueprint as a reference that’s better because the compatibility isn’t arbitrary. Jokers don’t scale twice as fast because of Blueprint rules

hushed cradle
#

dont think so

atomic falcon
hushed cradle
#

ben?

atomic falcon
#

yes

hushed cradle
#

yeah my wee is still small :(

#

so no double scaling

zealous glen
hushed cradle
#

yeah

#

to clarify that is how i want it

#

same as how blueprint works

crisp coral
#

didn't cryptid have to do a lot of modifications to calculate_joker to have joker retriggers working

zealous glen
#

Skill issue

hushed cradle
#

yeah i looked through cryptid and it gave me a headache

#

my way round it is a bit sketchy

zealous glen
#

Also

zealous glen
#

When you check joker ~= card

#

Instead check the key

crisp coral
#

@atomic falcon can you not interrupt us

zealous glen
#

To avoid issues with multiple Control Devils

atomic falcon
hushed cradle
hushed cradle
hushed cradle
zealous glen
frosty dock
#

gift card:

#

editions:

hushed cradle
#

yeah but its not gonna break

atomic falcon
#

i dont think context.blueprint gotta be used here

hushed cradle
#

its not gonna get super out of hand like infinite loop

zealous glen
#

I’m not saying it has to, but it could

frosty dock
#

yeah it won't infloop

zealous glen
#

I think it’s clever

hushed cradle
#

yeah thats the main thing

hushed cradle
zealous glen
#

I was talking about my own suggestion

atomic falcon
zealous glen
#

Like maybe if you ordered Control Devils and Gift Cards correctly

atomic falcon
#

true fact^

zealous glen
#

But I think you’d like like 3 Gift Cards?

#

Maybe more

atomic falcon
hushed cradle
#

it wont trigger gift card effects

atomic falcon
#

wouldnt you have to gift card before you buy the special joker

crisp coral
#

i don't think that'd infinitely loop but if need be just add a check

atomic falcon
#

or special joker would increase in value at the same rate

hushed cradle
#

i did some testing with gift card

#

had 4 copies with different values

#

it scores loads but its not game breaking

zealous glen
#

4 copies of what

hushed cradle
#

the control devil joker

zealous glen
#

I think something like Control, Gift, Gift, Control, Gift, Gift could infinite loop

hushed cradle
zealous glen
#

I was confused by what you said since you tested it

zealous glen
#

Oops did I ping? :<

atomic falcon
#

deserved

hushed cradle
#

only thing that could cause an infinite loop i think is something like canvas from cryptid

crisp coral
#

didn't ping

hushed cradle
#

but thats funny anyway

crisp coral
#

lmao canvas moment

mellow sable
#

It’s a lot and I want to refactor it and add to Steamodded at some point

crisp coral
#

peak

hushed cradle
#

i looked through cryptid joker retriggering and i couldnt make sense of any of it lol

crisp coral
#

that sounds so fragile lmao

mellow sable
#

My ideas for the refactor were basically:

  • You can pass a callback function to calculate_joker to do things with the result, instead of hardcoding those things it has to do
  • You can return a second value to indicate the joker did a calculation without returning anything
hushed cradle
#

tell me why i cant just do

for k, v in pairs(deez) do
  return v.nuts
end```
#

why isnt it lua

mellow sable
#

lol

unkempt ridge
#

wouldnt that be nuts[v]

mellow sable
#

deez[k] = v

mellow sable
hushed cradle
#

the names are irrelevant, you should be able to return things like that

atomic falcon
#

generator

hushed cradle
zealous glen
atomic falcon
#

you want python geenrtor?

mellow sable
atomic falcon
#

in lau?!

mellow sable
#

can you give an example

hushed cradle
#

yeb

mellow sable
hushed cradle
#

logalthunk

atomic falcon
#
lau
https://www.lua.org/pil/9.3.html
``` This is what you wnat @nkojeo
hushed cradle
#

is?

atomic falcon
#

Ys

hushed cradle
#

a

atomic falcon
#

Start yielding

hushed cradle
#

stress

zealous glen
# mellow sable wdym

Unless you want to affect the middle of calculation, can’t you hook calculate then add something to the end?

hushed cradle
#

what is calc short for

atomic falcon
#

hes new to chat

frosty dock
#

loc alt hunk

unkempt ridge
frosty dock
hushed cradle
#

clac?

zealous glen
mellow sable
#

neither do I balatrojoker

unkempt ridge
#

Coding is all about throwing shit at the wall and seeing what sticks. Whatever does stick then you gotta study it for Scienceâ„ąïž

mellow sable
#

i have to see how I got this to work

zealous glen
#

smods_retrigger idk

frosty dock
#

btw steamodded got another bit of loading perf

hushed cradle
frosty dock
#

doesn't matter much for the amount of objects we're dealing with, but I got it to the point where I can load more centers within a second than Luajit's memory restriction will let me

zealous glen
frosty dock
#

(the issue was the string format calls for trace messages that weren't even firing)

atomic falcon
#
lau
For jker in the hand {
  the_amount_of_money_worth = jokr.get_value()
  if the_amount_of_money_worth > controldevil.price then uhh
    joke.retigger()
  else
    end.it_all
hushed cradle
#

mods please pin

mellow sable
hushed cradle
#

yeah thats kinda what i wanted it to do

#

but im too dumb

zealous glen
#

I think it’s more interesting if it’s cheaper Jokers

unkempt ridge
#

Retrigger all jokers and check if triggered joker has a sell value <= condevil

#

Actually would it just be less than or less than or equal

atomic falcon
zealous glen
hushed cradle
#

gomtry your code is wrong

zealous glen
#

I think that’s more applicable

atomic falcon
#
lau
For each and every fucking jker in the hand {
  the_amount_of_money_worth = jokr.get_value()
  if the_amount_of_money_worth < controldevil.price then uhh
    joke.retigger()
  else
    end.it_all
zealous glen
#

Also that’s how card retriggers work

hushed cradle
#

otherwise infinite loops

mellow sable
hushed cradle
#

i have code for this joker already

mellow sable
#
local cj = Card.calculate_joker
function Card:calculate_joker(context, callback)
    local ret, triggered = cj(self, context)
    --Make every Joker return a value when triggered
    --Check for retrggering jokers
    if (ret or triggered) and not context.retrigger_joker and not context.retrigger_joker_check then
        if type(ret) ~= 'table' then ret = {joker_repetitions = {0}} end
        ret.joker_repetitions = {0}
        for i = 1, #G.jokers.cards do
            local check = G.jokers.cards[i]:calculate_joker{retrigger_joker_check = true, other_card = self}
            if type(check) == 'table' then 
                ret.joker_repetitions[i] = check and check.repetitions and check or 0
            else
                ret.joker_repetitions[i] = 0
            end
            if G.jokers.cards[i] == self and self.edition and self.edition.retriggers then
                local old_repetitions = ret.joker_repetitions[i] ~= 0 and ret.joker_repetitions[i].repetitions or 0
                --[[local check = calculate_blurred(self)
                if check and check.repetitions then
                    check.repetitions = check.repetitions + old_repetitions
                    ret.joker_repetitions[i] = check
                end--]] --figure out something for this later
            end

        end
    end
    if callback and type(callback) == 'function' then callback(ret) end
    return ret
end
#

this is what I have right now

hushed cradle
#

can i have that?

atomic falcon
#

wtf is that

mellow sable
#

it'l be merged with steamodded

hushed cradle
#

are you single?

mellow sable
unkempt ridge
#

đŸ€š

atomic falcon
#

line 9 has syntactical eror

zealous glen
hushed cradle
#
calculate = function(self, card, context)
        local jokers = {
            message = 'Bang!',
            card = card,
        }
        local ret = false
        for _, joker in pairs(G.jokers.cards) do
            if joker ~= card and joker.sell_cost < card.sell_cost then
                context.control_devil = true
                local joker_ret = Card.calculate_joker(joker, context)
                if joker_ret then
                    ret = true
                    if joker_ret.chips then
                        jokers.chips = (jokers.chips or 0) + joker_ret.chips
                    end
                    if joker_ret.mult then
                        jokers.mult = (jokers.mult or 0) + joker_ret.mult
                    end
                    if joker_ret.x_mult then
                        jokers.x_mult = (jokers.x_mult or 1) * joker_ret.x_mult
                    end
                    if joker_ret.h_mult then
                        jokers.h_mult = (jokers.h_mult or 0) + joker_ret.h_mult
                    end
                    if joker_ret.repetitions then
                        jokers.repetitions = (jokers.repetitions or 0) + joker_ret.repetitions
                    end
                    if joker_ret.dollars then
                        jokers.dollars = (jokers.dollars or 0) + joker_ret.dollars
                    end
                    if joker_ret.Xmult_mod then
                        jokers.Xmult_mod = (jokers.Xmult_mod or 1) * joker_ret.Xmult_mod
                    end
                    if joker_ret.mult_mod then
                        jokers.mult_mod = (jokers.mult_mod or 0) + joker_ret.mult_mod
                    end
                    if joker_ret.chip_mod then
                        jokers.chip_mod = (jokers.chip_mod or 0) + joker_ret.chip_mod
                    end
                end
            end
        end
        return (ret and jokers) or nil
    end,```
atomic falcon
#

you must use the for each and every fucking keywords

zealous glen
hushed cradle
#

somone @ thunk my code is genus

mellow sable
#

yes

zealous glen
mellow sable
#

yes

#

this is already possible with canvas/boredom on old API

unkempt ridge
#

Babe wake up new joker troggers just dropped

hushed cradle
#

maybe try implement smth like this?

unkempt ridge
#

Elaborate

mellow sable
#

now here's an example of how bad the old API is

hushed cradle
#

its like a big building, but each floor is a mushroom

mellow sable
#
# ending shop
[[patches]]
[patches.pattern]
target = "functions/button_callbacks.lua"
pattern = "G.jokers.cards[i]:calculate_joker({ending_shop = true})"
position = "at"
payload = '''
local effects = G.jokers.cards[i]:calculate_joker({ending_shop = true})
if effects and effects.joker_repetitions then
    rep_list = effects.joker_repetitions
    for z=1, #rep_list do
        if type(rep_list[z]) == 'table' and rep_list[z].repetitions then
            for r=1, rep_list[z].repetitions do
                card_eval_status_text(rep_list[z].card, 'jokers', nil, nil, nil, rep_list[z])
                if percent then percent = percent+percent_delta end
                G.jokers.cards[i]:calculate_joker({ending_shop = true, retrigger_joker = true})
            end
        end
    end
end
'''
match_indent = true
hushed cradle
#

i remember this

#

i read through all of it earlier

#

i think it caused permanent damage to my brain, its too small

#

usually im pretty good at stealing other peoples code but this was unfathomable

unkempt ridge
mellow sable
#

yes

#

but i had to do this for EVERY CONTEXT

#

and now hopefully I don't

unkempt ridge
#

Simple just do context ~= nil :^)

mellow sable
#

ok so I think this is good, now I have to refactor everything to use callbacks

#
function Card:calculate_joker(context, callback)
    local ret, triggered = cj(self, context)
    --Check for retrggering jokers
    if (ret or triggered) and context and not context.retrigger_joker and not context.retrigger_joker_check then
        if type(ret) ~= 'table' then ret = {joker_repetitions = {0}} end
        ret.joker_repetitions = {0}
        for i = 1, #G.jokers.cards do
            local check = G.jokers.cards[i]:calculate_joker{retrigger_joker_check = true, other_card = self}
            if type(check) == 'table' then 
                ret.joker_repetitions[i] = check and check.repetitions and check or 0
            else
                ret.joker_repetitions[i] = 0
            end
            if G.jokers.cards[i] == self and self.edition and self.edition.retriggers then
                local old_repetitions = ret.joker_repetitions[i] ~= 0 and ret.joker_repetitions[i].repetitions or 0
                local check = self:calculate_joker_retriggers()
                if check and check.repetitions then
                    check.repetitions = check.repetitions + old_repetitions
                    ret.joker_repetitions[i] = check
                end
            end
        end
        --do the retriggers
        context.retrigger_joker = true
        for z = 1, #ret.joker_repetitions do
            if type(ret.joker_repetitions[z]) == 'table' and ret.joker_repetitions[z].repetitions then
                for r = 1, ret.joker_repetitions[z].repetitions do
                card_eval_status_text(rep_list[z].card, 'jokers', nil, nil, nil, rep_list[z])
                if percent then percent = percent+percent_delta end
                self:calculate_joker(context, callback)
                end
            end
        end
    end
    if callback and type(callback) == 'function' then callback(ret) end
    return ret
end
maiden phoenix
mellow sable
#

yeah probably

#

you could probably call calculate_joker directly

#

except the UI might be janky

atomic falcon
# mellow sable yeah probably

To calculate the periodic sequence present in your profile picture, the following equation would be used:
a(n) = 7+5⌊nMOD3/2⌋+10(⌊nMOD3​/1.5⌋ − ⌊nMOD3​/2⌋)

maiden phoenix
hushed cradle
#

ben

vague monolith
#

hey guys do u know how to figure out joker modding because i have been struggling for 3 days to create jokers so

zealous glen
#

yeah

#

Use Steamodded 1.0 and try to mod a single Joker in

#

I had a single Joker mod for 0.9.8

#

Here

vague monolith
#

Oooo okay thank u thank u

#

one more question

#

where is steammodded 1.0

zealous glen
#

GitHub

vague monolith
zealous glen
#

Download

#

1.0 isn’t released yet

vague monolith
#

o h

zealous glen
#

There are installation instructions

#

Follow them

mellow sable
#

i only patched joker_main to use the new callback system so far but it should work decently

#

also separated to its own file so it can be easily merged with Steamodded when I’m done

hushed cradle
#

heaven sent

#

🙏

#

im not by any means good at programming

#

but if you would ever like help with anything id be happy to oblige

#

im helping out w saturn so that proves im not completely stupid

#

i doubt you would ever need proper help but if you gotta do smth thats long and tedious then just drop me a dm

mellow sable
#

tysm

#

if I need to work on overhauling some UI I might have to hit you up

#

Because to me that is still mostly a mystery

zealous glen
#

UIAPI

hushed cradle
#

im gonna be honest i dont fully understand it either, but i somehow manage to make it work lol

#

actually i say that but i understand it a decent bit i think

mellow sable
zealous glen
#

The modding API we need but not the one we want

zealous glen
wintry solar
#

I have no idea how a UI editor would work

hushed cradle
#

does anyone else have a bug where wheel says 11 out of 7 cards are flipped?

#

or 22 with oops

hushed cradle
#

what am i supposed to be looking at??

zealous glen
#

What did you just ask

hushed cradle
#

about wheel

#

i didnt see anything about it in the chat tho lemme look again

zealous glen
#

It’s like the last message

hushed cradle
#

oh right it took me way far back in the chat

hushed cradle
#

is that just a known bug then?

zealous glen
#

I thought it had been fixed

hushed cradle
#

ive no idea

#

redownloaded steamodded yesterday

hushed cradle
mellow sable
#

Look at how something like canvas or boredom is implemented

hushed cradle
#

i am trying

#
calculate = function(self, card, context)
        if context.other_joker then--context.retrigger_joker_check and not context.retrigger_joker then
            print('deez')
            print(tostring(card.sell_cost))
            print(tostring(context.other_joker.ability.name))
            if card ~= context.other_joker and card.sell_cost > context.other_joker.sell_cost then
                return {
                    message = localize('k_again_ex'),
                    repetitions = card.config.extra,
                    card = context.other_joker
                }
            end
        end
    end,```
#

so

#

jokers arent my strong point

hushed cradle
#

i should probably read more thoroughly

#

idek at this point

#

oh card should be card

wintry solar
#

is there a way for sendDebugMessage etc. to auto populate the second variable with the mod prefix?

nocturne garnet
#

how does Cryptid's Misprint and Edition decks affect all cards?

mellow sable
#

I hook all of the functions that create cards

#

if you search for cry_misprintize in the cryptid code you can see where this is being done

#

the biggest use is in create_card but there are more

zealous glen
#

Blind idea:

The Octopus
You have 8 hands
and it has X8 Base size

#

That seems
 too hard đŸ€”

nocturne garnet
#

The Hand:
X1 Base Blind requirement
+3 hands, +1X Base Blind requirement per total number of hands
(applies after jokers)

remote coral
#

Burglar spam vs this for mega violet vessel any day of the week

wintry solar
zealous glen
#

Eremel keeps winning

wintry solar
#

slowly making the game's UI functional step by step

frosty dock
#

fr

wintry solar
#

oh I was thinking too, should the tab colours in mod settings be the same as the badge colour?

frosty dock
#

hm that's a neat detail

wintry solar
#

I first thought the entire button to open that menu, but that might be a little garish

#

but the tabs would look neat

mellow sable
#

i had to learn how to regex patch for retrigger api

#

but it's so satisfying now

frosty dock
#

regex is so powerful when you know how to use it

mellow sable
#

i'm not even close to using its full potential

wintry solar
#

^

mellow sable
#

all I'm doing is basically multiline pattern patches with it

wintry solar
#

there are some patches I look at and am just mind boggled as to how they work

mellow sable
#

and then one or two I have that just check for a variable number of spaces because of janky local thunk syntax

#

i still have so much left to port

#

but this went down from 269 lines to 105

#

and a lot of the later ones should need no patching with how I set the API up

frosty dock
#

btw as effective as regex patches are, they're also inefficient

mellow sable
#

things like this don't need any modifications

zealous glen
#

how so

mellow sable
#

basically the retrigger logic is done within the calculate_joker function fully now

#

before calculate_joker would only run an extra check to count how many times the joker should be retriggered

#

but because the callback function tells it what else to do with those retriggers, it now also calculates the retriggers within calculate_joker

zealous glen
#

Ooh

young cloud
#

anyone aware of a way to add an event to E_MANAGER that triggers on the next round?

#

I made a tarot that modifies hand count, it's only issue is if it's used during a shop or blind selection the hand count resets when a blind is selected

#

was looking into creating an invisible tag, but couldn't find a way to make that work either

frosty dock
#

the way codex does things is it adds a flag and reads that out on round end

zealous glen
#

why don't you set a variable in the Joker and give it a start of round trigger

#

Oh wait you said Tarot

zealous glen
#

There's a Tag with a similar effect

frosty dock
#

i guess an event might work, but the event system is super jank

#

juggle tag might be a good reference?

young cloud
#

yeah, i was trying to make something similar to the +3 hand tag but it would have to be invisible

zealous glen
#

Make it give the Juggle Tag or a new Tag or similar

#

why

#

Make it visible

young cloud
#

the way I have it working rn is it calls ease_discard()

zealous glen
young cloud
#

which works great, but discard and hand counts reset at the beginning of a round

#

was really just looking to see if anyone had another idea, but yeah ill look more into the tag

#

ngl im feeling way too lazy to do that rn lmao

frosty dock
#

I think something like this might work? not sure though since events are scuffed

local rounds = G.GAME.rounds
G.E_MANAGER:add_event(Event({
  blocking = false,
  func = function()
    if --[[condition]] G.GAME.rounds > rounds then
      your_code()
      return true
    end
    -- if the condition isn't met, this is run again next frame
    -- that's inefficient and probably unwanted since a function exists
    -- that fires when the round ends, but it can work
  end
})
zealous glen
#

I mean you could add a new global variable but I think I like the tag more

zealous glen
young cloud
#

ill try implementing it and check back

mellow sable
#

crazy syntax

frosty dock
#

why did you even need that

#

was it meant to match multiple instances with different spacing?

mellow sable
#

future-proofing

#

because the spacing is bad

#

with that, it's my last lovely patch for retrigger api

#

but i have a question

frosty dock
#

i may have an answer

mellow sable
#

some vanilla jokers aren't going to play nicely, should I solve that by taking ownership or with lovely patches

#

i think either is better than what I had before

frosty dock
#

depends on how not nicely they're playing

mellow sable
#

i'd need like 20-30 patches that are basically return nil, true

frosty dock
#

yeah definitely use lovely patches for that

#

could potentially even save space by making them the same patch balatrojoker

wintry solar
#

oh powerful crashomancer, go and break galdur all night whilst I sleep

frosty dock
#

oh i shall sleep as well, it's past 2am over here

wintry solar
#

but you're so efficient at finding crashes

mellow sable
#

i will stay up coding this api

#

(it's well before 2am here don't worry)

#

this will be fun

frosty dock
#

Caino my beloved

mellow sable
#

it's still called that internally đŸ€·â€â™‚ïž

#

WHAT THE HELL DID I JUST DO

#

oh I checked too little in my patch

frosty dock
#

Baltro

stray warren
#

When does set_ability get called? This code doesn't work and mult is always 0 (the default value I set)

stray warren
#

Ok, I guess my question is how can I make the card default to being triple the card's sell value when it's first spawned? I can't access that value in the extra section I don't believe

crisp coral
#

set cost is called after set ability

stray warren
#

Ok, so that won't work. Unless I somehow hook into set_cost for this joker only

shell tangle
#

If I wanted to have an option cycle in mod config, is the opt_callback required in order to save a change, or am I missing something?

young cloud
#

finally got that discard function working

mellow sable
#

almost done with this garbage regex patching hell

#

this is a funny one

young cloud
#

props man

#

anything to do with regex is miserable by nature lmao

#

hold on, the hell is that return statement 💀

mellow sable
#

i learned it today... for this

#

so many patches in card.lua (I added like 30 new ones)

young cloud
#

rip

#

eyyy sweet

mellow sable
#

it's finally done

young cloud
#

once i finish this modpack im down to work on the loader if you need the help

mellow sable
#

now all I have to do is test it out

young cloud
#

nice

mellow sable
#

i don't rly need help rn

#

I'm refactoring retrigger API so I can move it from Cryptid to Steamodded soon

young cloud
#

aight bet

mellow sable
#

anyway I'm just gonna spawn canvas and see what happens

young cloud
#

lol gl đŸ€ž

celest timber
#

is there documentation on how to make a mod or how do i start?

red flower
celest timber
#

tysm

shell tangle
celest timber
#

oh thats awesome

#

time to read!

young cloud
celest timber
#

where do i find this pages? cuz i kept looking on google and couldnt find much

young cloud
#

which pages?

celest timber
#

like the getting started one, or this one u just send

young cloud
#

most of the useful docs I've found have been through this server

#

just search for your topic in the 'modding-dev' channel and someone's probably talked about it

celest timber
#

ok then, tysm!

shell tangle
young cloud
#

oh sweet, thx

golden lake
#

scholar is dead

#

superposition is dead

shell moat
#

How would I use the ante_scaling modifier used for the plasma deck as a modifier in a challenge? I know that it's limited to 1, 2, and 3, but that's fine for my purposes

mellow sable
#

1,2,3 isn’t the plasma one

shell moat
#

Ah okay, I was going off a note in the code for 5 Legendary Challenges

#

Either way, my question still stands - how do I change ante scaling in a challenge, preferably without custom coding it

crisp coral
#

don't think so

#

because I don't remember what opt_callback is

shell tangle
#

Basically just allows you to call a function that's located in G.FUNCS.

#

Here's the current code I have for the option cycle,

create_option_cycle{colour = G.C.SO_2.Diamonds, scale = 1, w = 0, shadow = true, options = {'Test 1', 'Test 2', 'Test 3'}, current_option = config.Option_Cycle, ref_table = config, ref_value = 'Option_Cycle'}

Main thing is just that it'd be a hassle to make a custom G.FUNCS function for every single one, but, changing this as is doesn't seem to save any information.

static juniper
#

This is probably a really dumb question, but I'm just starting out here. In what folder do you have to put a mod in order for it to... work?

#

I see the example mods in the example_mods folder, but where do I put them to actually run them?

shell moat
#

Once you've installed your mod loader of choice, you put lua files (or mod folders) in %Appdata%/Balatro/Mods (you may need to make the mods folder)

static juniper
#

Alright, thanks!

#

Do I have to relaunch the game to load them?

shell moat
#

I'm pretty sure you do, yeah

placid frigate
#

is there a seleton code for adding a joker with steamodded 1.0.0?

static juniper
nocturne garnet
#

honestly easier than what i expected

night pagoda
#

Do you know that every sprite in Balatro has an invisible yet COLORED border, and that's why every sprite has a transparent 1-pixel border around them?

languid mirage
#

I don't think it is the (main) reason for 1 pixel border tbh, border makes more sense for shaders

rain imp
#

The reason is probably the shader that wobbles the cards, since when the pixel gap is absent the sprite of a card starts to peek throgh the closest 4 sprites in the canvas

#

Besides being a common practive in spritesheets lol

languid mirage
#

not true actually

#

cards wobbling is a vertex shader

maiden phoenix
rain imp
# languid mirage not true actually

No it is. See that tiny line on the border of an orange and purple card? That's the overlap I mentioned. Though, sure, it isn't caused by the shader, it enhances its size nonetheless. That's more like a sprite cropping issue though

shell timber
#

it'd probably bleed due to rounding errors etc.

night pagoda
#

not a stray pixel but rather a misplaced one*

rain imp
#

I see a half of a spade broken

night pagoda
#

yup, that's what I was reffering to

rain imp
#

So, gotta fix that

languid mirage
rain imp
#

On the topic of that, what programs do you use for your sprites? Aseprite annoys me greatly

languid mirage
#

but the cards floating effect does not require a pixel border, you're just confusing different things

rain imp
#

I do

languid mirage
hushed cradle
#
local ret = context.other_joker:calculate_joker(context)
                print(tostring(ret))```
#

this is printing nil even tho context.other_joker is def a thing

#
calculate = function(self, card, context)
        if context.other_joker then
            if context.other_joker ~= card and context.other_joker.sell_cost < card.sell_cost then--context.retrigger_joker_check and not context.retrigger_joker and context.other_card ~= self then\
                local ret = context.other_joker:calculate_joker(context)
                print(tostring(ret))
                if ret then
                    ret.message = localize('k_again_ex')
                    ret.card = other_joker
                end
                return ret
            end
        end
    end,```
#

ignore the other joker

#

its because i removed some code that didnt work

#

im just confused why its returning nil when calculating the context of the other joker

#

oh

#

im so stupid

#

i swear i always have these questions and the second i ask about them i realise how dumb i am

shell tangle
#

I don't like UI.

wintry solar
#

UI is life đŸ˜»

mellow sable
#

Graphic design is my passion

crisp coral
#

now everyone must suffer... like i have...

hushed cradle
#
calculate = function(self, card, context)
        if context.retrigger_joker_check and not context.retrigger_joker then
            if context.other_card.sell_cost < card.sell_cost then
                return {
                    message = localize('k_again_ex'),
                    repetitions = self.config.extra,
                    card = card
                }
            else
                return nil, true
            end
        end
    end,```
#

am i doing this wrong?

#

also ui is great

opal spade
red flower
crisp coral
#

TRUE

#

teto miku and the one that didn't appear in mesmerizer

hushed cradle
#

nah len

mellow sable
shell tangle
#

Seriously, though, I just want checkboxes on the left, lablels on the right, under that, cycles with text elements that can show tooltips on highlight. This is the code for this mildly updated blue section, and I have no idea where I'm going wrong.