#💻・modding-dev

1 messages · Page 697 of 1

slim ferry
#

The expantanum/omeganum library repos have links to the entire series

#

idk if this is related but uhh

#

Okay

brisk dune
#

It's made by a different person

#

I found this in the googology discord

#

Which I just found out exists

#

Anyways I expect this in amulet in 3 seconds thanks /j

brisk dune
slim ferry
#

No

atomic edge
#

when is this coming out? or is this already out?

vale zinc
#

Also, is there any timeframe for support for custom Small/Big Blinds?

narrow prawn
#

is there a way to make it so when you use a consumable, it isnt used up

red flower
red flower
red flower
#

it's in the docs

dapper sun
primal robin
#

card.container.T.x + card.T.x

#

also depends on what kind of position you need

frosty dock
#

ah whoops that's what I get for relying on my memory

gusty compass
#

what could be potentially causing this error within the hook?

-- card_removed, fires when a card is removed for any reason
local remove_card_ref = CardArea.remove_card
function CardArea:remove_card(card, discarded_only)
    remove_card_ref(self, card, discarded_only)

    SMODS.calculate_context({
        card_removed = true,
        other_card = card,
        cardarea = card.area
    })
end```
mystic river
#

you didn't return the original return
idk whether that function normally returns something but it's good practice even when it doesn't

hidden notch
#

This has probably been asked a million times but I can't find anything via Discord search;
How do I update the "Choose your next Blind" UI?

wintry solar
#

What are your goals?

gusty compass
#

yea that was it

hidden notch
wintry solar
#

It’s something like create_blind_select from memory

hidden notch
#

I'll check for it, thanks lewxen_sparkle

analog slate
#

so i have my music working.. now i just need to make sure it only plays if i have a certain card.. lemme try smth first

#

hmmmmm yea no im gonna need some help

red flower
#

something like this

analog slate
#

i got the music working for the music playing on blind but i want the music to play if like you have a certain card

#

i do have smods.find_card

red flower
#

can i see the code

analog slate
#

i think it should be after

#

but idk

red flower
#

you need the next()

#

because find_card always returns a table so it's always truthy

analog slate
#

ohhhhh

#

and a # before it transitions it into a number :)

red flower
#

yeah you can also do #... > 0 if you want it would be the same as next()

analog slate
#

yea i remember now.. i didnt even need the if variable if the thing was true anyway

red flower
# analog slate

ah a better check than string.len(G.GAME.bind.name) > 0 is G.GAME.blind.in_blind

analog slate
#

so like how do i check how much cards with a certain pool exist

#

like i can convert to number but like whats the SMODS.find_card version

red flower
#

you would need to loop through G.jokers.cards and check each one

analog slate
#

FAH

#

i just need like +25 mult for every card under a pool

rapid stag
#

bump

hidden notch
analog slate
#

also where am i missing my comma

hidden notch
#

If you want all the Animations, just search for the select Blind code glaceonwink
-> G.FUNCS.select_blind = function(e)
-# And remove all the "selecting blind stuff" ig x3

analog slate
frosty dock
analog slate
frosty dock
#

what's the crash and what's around this lines it points to

analog slate
#

nvm i removed it

rapid stag
#

remind me what causes this again

game.lua:2832: bad argument #1 to 'push' (boolean, number, string, love type, or table expected)

Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-1620a-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.9.0
Platform: Windows
Steamodded Mods:
    1: CirnoTV & Friends by DaemonTsun, NopeTooFast [ID: CTVaF, Priority: 999, Version: 1.003.126, Uses Lovely]
    2: Malverk by Eremel [ID: malverk, Priority: -999999, Version: 1.1.3a, Uses Lovely]
Lovely Mods:

Stack Traceback
===============
(3) method C function 'push'
(4) Lua upvalue 'gameUpdateRef' at file 'game.lua:2832'
Local variables:
 self = table: 0x03bb3dd8  {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:false, HUD_tags:table: 0x04d4b220, F_ENGLISH_ONLY:false, viewed_stake:1, HUD:table: 0x18d31c78 (more...)}
 dt = number: 0.0166613
(5) Lua method 'update' at Steamodded file 'src/ui.lua:456' 
Local variables:
 self = table: 0x03bb3dd8  {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:false, HUD_tags:table: 0x04d4b220, F_ENGLISH_ONLY:false, viewed_stake:1, HUD:table: 0x18d31c78 (more...)}
 dt = number: 0.0166613
(6) Lua field 'update' at file 'main.lua:1024'
Local variables:
 dt = number: 0.0166613
(7) Lua function '?' at file 'main.lua:962' (best guess)
(8) global C function 'xpcall'
(9) LÖVE function at file 'boot.lua:377' (best guess)
Local variables:
 func = Lua function '?' (defined at line 933 of chunk main.lua)
 inerror = boolean: true
 deferErrhand = Lua function '(LÖVE Function)' (defined at line 348 of chunk [love "boot.lua"])
 earlyinit = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])```
red flower
#

trying to save a function

rapid stag
#

my culprit is here, but i'm not sure where

#

wait what

#

this crash is occurring when winning (on ante 8 beaten), though

red flower
#

you're probably saving a function to the profile

#

and functions can't be serialized

#

i dont see it there tho

#

oh i see what it could be

#

you're using a table as a table key

#

selected_back_key is a table despite the name

rapid stag
#

ah. G.GAME.selected_back_key.key

#

thank you thunk

silent sail
#

how does one mark a consumable as being unable to be perkeod

red flower
#

take ownership or patch perkeo's effect

silent sail
#

i see

dapper sun
#

anyone know why the card scaling is being retriggered despite being in a not context.joker_retrigger check?

#

before anyone suggests it, this isn't blueprint retriggering

latent perch
dapper sun
#

oh ty

latent perch
#

np! balatrojoker

viscid talon
#

My booster packs arent showing their description and idk why

frosty dock
#

pretty sure there's supposed to go in descriptions.Booster

#

but for Other it would be in descriptions too, and not misc

viscid talon
#

o

#

hmm

silent sail
slim ferry
#

descriptions.Booster doesnt exist

silent sail
frosty dock
vale zinc
frosty dock
vale zinc
noble rapids
#

is there a way to find out what cards held in hand will trigger a held in hand effect, and what cards wont, like a context or something?

vale zinc
brittle yacht
#
SMODS.Atlas {
    key = 'hector',
    path = 'hector.png',
    px = 71,
    py = 95
}

SMODS.Sound {
    key = 'bell',
    path = 'bell.ogg',
}

SMODS.Joker {
    key = 'hector',
    loc_txt = {
        name = "Jimbo Salamanca",
        text = {
            "Plays a {C:gold}bell sound{} every {C:attention}click{}",
            "If {C:attention}CPS{} is {C:attention}10+{}, {C:red}explode{}",
            "{C:inactive}({}{C:red}Explode:{} {C:inactive}destroy self and adjacent {}{C:attention}Jokers,{} {C:red}ignore{} {C:enhanced}Eternal{}{C:inactive}){}"
        }
    },
    atlas = 'hector',
    pos = { x = 0, y = 0 },
    rarity = 2,
    cost = 4,
    blueprint_compat = false,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = true,

    calculate = function(self, card, context)
        if context.sink_press then
            G.E_MANAGER:add_event(Event({
                func = function()
                    print('skbidi toielt')
                    play_sound('sink_bell')
                    return true
                end
            }))
        end
    end
}

return {
    init = function()
        local lcpref = Controller.L_cursor_press
        function Controller:L_cursor_press(x, y)
            lcpref(self, x, y)
            if G and G.jokers and G.jokers.cards and not G.SETTINGS.paused then
                SMODS.calculate_context({ sink_press = true })
            end
        end
    end,
}```
heres joker lua
any other file u needed to see?
red flower
#

do you run this init function somewhere

#

seems like a badly copied thing from cryptid to me

daring fern
noble rapids
#

how would i do that?

daring fern
# noble rapids how would i do that?
local oldevalcard = eval_card
function eval_card(card, context)
    if not card then return end
    local g, post = oldevalcard(card, context)
    if not card:can_calculate(context.ignore_debuff, context.remove_playing_cards or context.joker_type_destroyed) then return g, post end
    if context.main_scoring and context.cardarea == G.hand and next(g) then
        card.modprefix_trigger_held_in_hand_effect = true
    else
        card.modprefix_trigger_held_in_hand_effect = nil
    end
    return g, post
end
brittle yacht
red flower
#

you only need this part

#

remove the things wrapping it

brittle yacht
#

thank you very much twin

slate turtle
red flower
#

wrong arguments

silent sail
#

SMODS.Joker:take_ownership("perkeo", {
    calculate = function(self, card, context)

        
        if context.ending_shop then

            local pool = {}

            for _, c in ipairs(G.consumeables.cards) do
                if c.set ~= "astrological" then
                    pool[#pool + 1] = c
                end
            end

            if #pool > 0 then
                local chosen = pseudorandom_element(pool, pseudoseed("perkeo"))

                local copy = copy_card(chosen)
                copy:set_edition("e_negative")
                copy:add_to_deck()

                G.consumeables:emplace(copy)
            end

            return true 
        end

        return nil
    end
})

something about this isnt working, its not ignoring the set

daring fern
#

Also it should be return nil, true instead of return true

daring fern
silent sail
#

oh my god im so blind

#

thank you

slate turtle
#
return{
                    card.ability.extra.payphonemult == card.ability.extra.payphonemult - card.ability.extra.payphonemult_minus
                }```
#

why is it not subtracting cuh

faint yacht
#

...why are you return-ing that?

slate turtle
#

just card.ability.extra.payphonemult == card.ability.extra.payphonemult - card.ability.extra.payphonemult_cost

slate turtle
daring fern
faint yacht
#
if condition then
  value = value - subtractvalue
end
slate turtle
#

thanks guys

#

question

#

how do yall make those messages that appear below jokers

#

for instance

#

when a round is over

#

a joker displays a "(amount of mult left) Mult"

#

how can you do that

daring fern
primal robin
red flower
#

amazing

primal robin
#

time for even more testing

#

damn, most of info queue is full custom huh

#

makes sense

#

Fortunately I made some sort of api to deal with this

#

after I made vanilla work properly of course xd

red flower
#

dont worry im literally getting rid of those info queues as i type this

dapper sun
granite apex
#

Is there a setAbility equivalent for seals? I had working enhancements but I had to convert my code to seals for art/balance purposes and I can't get the right functions going

daring fern
daring fern
granite apex
#

and if setAbility does work with seals then I'm unsure as to why its never being called regardless of me putting seals onto stuff, it also crashes my Calculate functions

SMODS.Seal({
    key = 'cup_seal',
    atlas = 'Enhancers',
    pos = { x = 2, y = 0 },
    badge_colour = G.C.GREEN,
    config = { extra = { chips = 5, rank = 'Rank', rankInt = 0 } },
    loc_vars = function(self, info_queue, card)
        return { vars = { self.config.extra.chips, self.config.extra.rank, self.config.extra.chips * countRanks(card) }, key = self.key }
    end,
    set_ability = function(self, card, initial, delay_sprites)
        setRank(self, card)
    end,
    calculate = function(self, card, context)
        if context.main_scoring and context.cardarea == G.hand then
            local count = countRanks(self, card)
            return { chips = card.ability.extra.chips * count }
        end
    end,
    draw = function(self, card, layer)
        draw(card, layer)
    end
})
daring fern
dapper sun
granite apex
#

damn so there's something for enhancements but not for seals

#

I'm a little worried that it wont work the way I do it but I'll try 😭

white zinc
#

i've prob asked this before, but if i have an integer value from 2-14, what's the easiest way to turn that integer into a corresponding rank string?

daring fern
vale zinc
# white zinc ty!

Better you should put that in a function call so you don't have to constantly rewrite the code.

primal robin
#

goddamnit this stickers

#

they creating problems once again

white zinc
#

is there a reason that it's saying my function is unused?

daring fern
white zinc
#

should i just move the function above that code then?

dapper sun
#

how do i SMODS.create_card a modded card?

#

like,, any mod

daring fern
# dapper sun like,, any mod
local jokers = {}
for k, v in pairs(get_current_pool('Joker')) do
    if G.P_CENTERS[v] then
        if G.P_CENTERS[v].set == 'Joker' and G.P_CENTERS[v].original_mod then
            table.insert(jokers, G.P_CENTERS[v].key)
        end
    end
end
local key = pseudorandom_element(jokers, 'seed')
SMODS.create_card({set = 'Joker', key = key})
dapper sun
#

does this account for joker weights

#

and rarities

daring fern
forest cobalt
#

how do you add custom sounds

dapper sun
forest cobalt
#

yea

#

my mod has modname/assets/gun.ogg

#

atlas looks like this SMODS.Sound({ key = "gun", path = "gun.ogg" })

dapper sun
forest cobalt
#

oh yeah thats what i meant

dapper sun
#

what's the problem then

forest cobalt
#

it crashes

#

hang on one sec

fading rivet
forest cobalt
daring fern
# forest cobalt

Are you adding the mod prefix to the key when you are using it?

dapper sun
#

send the code

forest cobalt
#

its supposed to be assets/sounds/thingamabob.ogg right

fading rivet
dapper sun
#

play_sound('modprefix_soundkey')

fading rivet
forest cobalt
dapper sun
forest cobalt
#

says it dont exist

fading rivet
forest cobalt
#

goddamn it

forest cobalt
forest cobalt
dapper sun
fading rivet
#

add the mod prefix like all 3 of us have said

dapper sun
#

you didn't add the prefix

forest cobalt
#

ok

#

yall fw angry birds

#

welp it crashed again

#

SMODS.Sound({ key = "add_sus", path = "sounds/sus.ogg" }) SMODS.Sound({ key = "add_gun", path = "sounds/gun.ogg" })

dapper sun
#

remove the sounds/

forest cobalt
#

sorry if i am being frustrating i am amateur at the lua language

#

@dapper sun thank you it worked

dapper sun
#

yw

forest cobalt
dapper sun
daring fern
dapper sun
#

also why aren't we just checking for the center having a mod entry

#

i'm not wanting all mods equally i just want modded jokers

#

okay i cut the code down to this

local jokers = {}
for k, v in pairs(get_current_pool('Joker')) do
    if G.P_CENTERS[v] then
        if G.P_CENTERS[v].set == 'Joker' and G.P_CENTERS[v].mod then
            table.insert(jokers, G.P_CENTERS[v].key)
        end
    end
end
local key = pseudorandom_element(jokers, 'elle_becca_shop_modded_j')```and now it only crashed when i rerolled (this is for a custom shop)
#

okay i tried on a new run

#

it seems to just happen a lot of the time

daring fern
#

I also edited the code to fix it.

dapper sun
#

ty

#

i assume original_mod is so it doesn't get affected by take_ownership?

dapper sun
#
local mod_txt = 'elle_rebecca_modifier_'..G.GAME.elle_popup_shops.rebecca.modifier
local modifier = ellejokers.rebecca_modifiers[G.GAME.elle_popup_shops.rebecca.modifier]

local modifier_lines = {}
localize({set='Other', key=mod_txt, type='descriptions', vars=modifier.loc_vars and modifier:loc_vars() or nil, nodes = modifier_lines,default_col=G.C.UI.TEXT_LIGHT})```for some reason this makes the game freeze up and overflow crash
#

(no crash screen given)

shell timber
dapper sun
#

oh that's so much easier

#

how do i use that

#

my mod enables weights so i can just use that

shell timber
#

like you just pass filter = function(pool) [do stuff] return pool, in the table passed to add_card

daring fern
# dapper sun my mod enables weights so i can just use that
SMODS.create_card({set = 'Joker', attributes = {}, filter = function(pool)
    local new_pool = {}
    for k, v in pairs(pool) do
        if v.type == 'Joker' and G.P_CENTERS[v.key].original_mod then
            table.insert(new_pool, v)
        end
    end
    return new_pool
end})
shell timber
#

okay yeah it does check for the attributes table for some reasoni just checked

dapper sun
#

ty

shell timber
#

try setting attributes to { "Joker" }

#

yeah alr that works

#

its evil but it works

dapper sun
#

nope

#

still crashed

shell timber
#

odd

dapper sun
#

ill push so you can look

shell timber
#
SMODS.add_card {
    set = "Joker",
    attributes = { "Joker" },
    filter = function ( pool )
        local new_pool = {}
        for k, v in pairs(pool) do
            if G.P_CENTERS[v.key].original_mod then
                table.insert(new_pool, v)
            end
        end
        return new_pool
    end,
}
#

this works for me

#

oh you need set = joker and attributes = joker

dapper sun
#

i added both of those

shell timber
#

okay ill take a look

daring fern
dapper sun
#

oh

#

i forgot the return

shell timber
#

is whats on github what you have rn

#

apart from the return

#

you need set = "Joker" and attributes = {"Joker"}

dapper sun
dapper sun
#

i'm setting the attrubutes to joker here

shell timber
#

you need both

#

its stupid

dapper sun
#

and i'm setting the set here

shell timber
#

oh hm

#

okay unrelated but your title screen animation is cool

dapper sun
#

tyy

shell timber
#

okay it works for me wtf ? ???

dapper sun
#

weird

daring fern
dapper sun
#

what smods ver

shell timber
#

ohhh you have no commons

dapper sun
#

oh

shell timber
#

except jess pin

dapper sun
#

rly?? 😭

#

THAT'S my problem??

shell timber
#

yeah lol

dapper sun
#

😭

#

okay,,

#

onto uhhh

shell timber
#

you're looping over modifier_lines and adding to it

dapper sun
#

oh 😭

near coral
#

How can this be fixed to fit the description of "all cards debuffed if a card is sold, used, or destroyed"

daring fern
# near coral How can this be fixed to fit the description of "all cards debuffed if a card is...
calculate = function(self, blind, context)
    if context.selling_card or context.using_consumeable or context.joker_type_destroyed then
        for k, v in pairs(G.playing_cards) do
            SMODS.debuff_card(v, true, self.key)
        end
    end
end,
disable = function(self)
    for k, v in pairs(G.playing_cards) do
        SMODS.debuff_card(v, false, self.key)
    end
end,
defeat = function(self)
    for k, v in pairs(G.playing_cards) do
        SMODS.debuff_card(v, false, self.key)
    end
end,
near coral
#

o oke

faint urchin
#

is it possible to spawn in cards that have in_pool as false with add_card?

#

if not is there a workaround to take ownership before and after adding the card because i tried that and it just popped up a bunch of messages about tracking the jokers

faint urchin
# daring fern Yes.

is there a flag that i have to set for that because currently it's not spawning in any cards that aren't in the pool so im wondering if that is the issue or if there's a different issue

daring fern
faint urchin
#

getting this error

#

wait nvm it works now, thanks

dapper sun
teal grotto
#

is it possible to make a rank use different sprites if it has a certain enhancement?

daring fern
teal grotto
#

thanks

cunning radish
#

does this actually change the condition of any specific achievement or any achievements at all?

local unlockconditionref = SMODS.Achievement.unlock_condition;
function SMODS.Achievement:unlock_condition(args)
  if args.type = "siuwa"
  return true
  end
end;
slim ferry
#

you are hooking the default unlock condition, this will only affect achievements without a condition (none of them)

cunning radish
#

how do I that to each achievement? or a specific set of achievement without repeating it for each achievement

slim ferry
#
whatever = SMODS.Achievement:extend{
  unlock_condition = function(self, args)
    --...
  end
}

then use the defined whatever instead of SMODS.Achievement for said set of achievements

#

I also recommend putting said whatever in a table for your mod or prefixing it with your mod prefix

silent sail
#

is there a way to have a joker apply showman like effects for a single consumable type

red flower
vapid cave
fading rivet
vapid cave
#

gave me error without them

#

for some reason

#

something like "missing symbol } at line 56"

fading rivet
#

replace the last 2 } with ,

#

and go learn lua syntsx

#

syntax

wintry solar
vapid cave
#

notepad

wintry solar
#

You should not do that

rapid stag
#

ok hold on,
notepad notepad or notepad++

vapid cave
#

notepad notepad

rapid stag
#

important distinction

primal robin
#

ew

wintry solar
#

I’d recommend using something that will show you bracket pairs

rapid stag
#

ok yeah don't use notepad notepad

calm marten
#

sometimes whatever idea my friend suggest to me, i cant find a way to implement it as a joker
like one time he said "make a joker that gains mult every second" and i just cant figure out a way to implement that.

primal robin
#

eremel am I allowed to ask questions about generate_card_ui shit to you?

#

Because I have one

wintry solar
#

Sure

vapid cave
primal robin
# wintry solar Sure

Here's a deal.

I'm generating card's description just like LocalThunk intented:

    local new_card = copy_card(card, nil, 1, nil, nil)
    main_card_area:emplace(new_card)
    new_card.ability_UIBox_table = new_card:generate_UIBox_ability_table()
    local popup = G.UIDEF.card_h_popup(new_card)
    new_card.no_ui = true

Then I'm using result and render it. It works for most cards just fine, but I have problem when it's about stickers. Specifically, their display in collection.
For some reason, UI and info_queue I'm gettings does not match what I expect to get. I expect get thing on right, but I got what on bottom

#

And since stickers is insane junk I'm not sure what to do

red flower
primal robin
#

If you need mod where I'm doing things I can add it to git

#

pinned "sticker" works just fine btw

wintry solar
#

Sounds like the input is wrong

primal robin
#

hm, maybe I'm indeed doing it not properly somehow, because if I call card:hover() info_queue is correct

slate turtle
#

question

#

how can i make a joker play a noise

red flower
slate turtle
#

it's prob out there somewhere in the smods wiki

primal robin
#

card uses sticker's info_queue to build own description Trolge

#

that's crazy

#

I might say that's insane actually

#

and how I'm supposed to deal with it

vapid cave
#

managed to get it to work on visual studio, now for some reason its telling me i need a bracket inside the display ranks string???

red flower
#

maybe searching here

red flower
#

it thinks you need one to close the table before King because of the missing comma

gilded blaze
#

also I don't recommend VS

red flower
#

oh is this regular visual studio

gilded blaze
#

yea

#

the highlighting is too familiar to not realize

primal robin
gilded blaze
#

Visual Studio isn't built for anything outside C++/C# and other Microsoft-related programming languages
sure, you can do code in it, but it takes way more work to debug since there's no linting at all for lua

slate turtle
#

question what's the sound effect for when you get money

red flower
#

coin1

#

let me see if i can compile a list and put it in the wiki

silk latch
#

How do I get ease_background_colour_blind() to actually use the colors correctly rather than just making it black?

silk latch
red flower
red flower
#

im saying to go read ease_background_colour_blind

#

that will also tell you what you need to do

silk latch
#

Which is defined where?

red flower
hidden notch
#

Is there a list of Tag-Contexts?

red flower
#

not that i know but they are all used by the vanilla tags

hidden notch
#

Alrighty ^w^

silk latch
red flower
silk latch
cunning radish
red flower
red flower
#

what eris said is just to make it easier to make your own without having to repeat the condition

cunning radish
#

I think I want to

red flower
#

what's the goal

cunning radish
#

I want to change conditions of achievements to something really easy like args.type = "siuwa" and then unlock them by something like check_for_unlock(type = "siuwa")

red flower
#
for k, v in pairs(G.ACHIEVEMENTS) do
  unlock_achievement(k)
end
cunning radish
#

this will direct unlock it without ever messing with any objects yes?

red flower
#

yes

cunning radish
#

(also thanks to eris but I don't want to ping)

cunning radish
primal robin
#

I'm definitely cooking

brittle yacht
#
    key = 'hector',
    loc_txt = {
        name = "Jimbo Salamanca",
        text = {
            "Plays a {C:gold}bell sound{} every {C:attention}click{}",
            "If player clicks 44 times, {C:red}explode{}",
            "{C:inactive}({}{C:red}Explode:{} {C:inactive}destroy self and adjacent {}{C:attention}Jokers,{} {C:red}ignore{} {C:enhanced}Eternal{}{C:inactive}){}",
            "{C:inactive}(Currently {}{C:attention}#2#{}{C:inactive} clicks left){}"
        }
    },
    atlas = 'hector',
    pos = { x = 0, y = 0 },
    rarity = 2,
    cost = 4,
    blueprint_compat = false,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = true,
    config = { extra = { bellclicks = 0, }, { bellclicksleft = 44, } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.bellclicks }, { card.ability.extra.bellclicksleft } }
    end,

    calculate = function(self, card, context)
        if context.add_to_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) == 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 44
        end
        if context.remove_from_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) == 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 44
        end
        if context.sink_press then
            if to_big((card.ability.extra.bellclicks or 0)) == to_big(43) then
                return {
                    message = "bemusement"
                }
            else
                card.ability.extra.bellclicks = (card.ability.extra.bellclicks) + 1
                card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) - 1
                    G.E_MANAGER:add_event(Event({
                    func = function()
                        print('skbidi toielt')
                        play_sound('sink_bell')
                        return true
                    end
                    }))
                return {
                    message = "Ding!"
                }
            end
        end
    end
}```
#

sorry for wall of code

primal robin
#

damn, my showcase was interrupted immediately

#

config = { extra = { bellclicks = 0, bellclicksleft = 44, } },

brittle yacht
#

?

#

oh wait

#

u right

#

im so smart

brittle yacht
#
        if context.add_to_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) == 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 44
        end
        if context.remove_from_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) == 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 44
        end
        if context.sink_press then
            if to_big((card.ability.extra.bellclicks or 0)) == to_big(43) then
                card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 0
                for i = 1, #G.jokers.cards do
                if G.jokers.cards[i] == card then
                    if i > 1 then
                        local left = G.jokers.cards[i - 1]
                        left:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                    end
                    if i < #G.jokers.cards then
                        local right =  G.jokers.cards[i + 1]
                        right:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                    end
                    self:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                end
                
            end
            else
                card.ability.extra.bellclicks = (card.ability.extra.bellclicks) + 1
                card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) - 1
                    G.E_MANAGER:add_event(Event({
                    func = function()
                        print('skbidi toielt')
                        play_sound('sink_bell')
                        return true
                    end
                    }))
                return {
                    message = "Ding!"
                }
            end
        end
    end```
#

theres an error in here when i reach bellclicks == 43

cunning radish
red flower
cunning radish
#

It should be

red flower
#

the only different is that now you're calling unlock_achievement with 2 arguments, but it doesnt use the second one

mystic river
brittle yacht
mystic river
#

well what it does is change them to booleans indicating whether they were at their base value at that time

#

if you want to assign, you just do variable = value

#

variable == value is a comparison, it's asking whether they're already equal

wintry solar
silk latch
#

How do I get the speed of the mouse cursor?

mystic river
#

also i think i deliberately made that less precise than it could be, you may want to remove that part

fading rivet
silk latch
#

since when does joker poker have distance units

fading rivet
#

always

silk latch
#

what's the balala-unit to hammerunit conversion rate

mystic river
#

that's what neko there is measuring in, yeah

fading rivet
#

UI uses it heavily

#

oh G.CURSOR is a thing that's cool

#

im assuming that's in balala units then

silk latch
#

How would I get the position from like a second or two ago?

fading rivet
#

wait a second

#

woah its a second aho

#

ago

silk latch
#

but wouldn't the update function override it before the next second

silk latch
#

does update run 60 times per second?

mystic river
#

every frame, yeah
lag may reduce this below the intended 60hz

amber turret
#

uh how to make a joker multiply mult by 10?

keen totem
#

how large is a balala unit in pixels?

mystic river
amber turret
#

oh thx

silk latch
#
    update = function(self, card, dt)
        local positions_x = {}
        local positions_y = {}
        local speeds = {}
        local piss = 0
        local mouse_vel = {}
        local timer = (timer or 0)
        local oldtimer = timer
        timer = (timer or 0) + dt
        local mousepos = {}
        mousepos.x, mousepos.y = math.floor(G.CURSOR.T.x), math.floor(G.CURSOR.T.y)
        local oldpos = {}
        table.insert(positions_x, {mousepos.x})
        table.insert(positions_y, {mousepos.y})
        if #positions_x >= 60 then
            oldpos.x = positions_x[1]
            table.remove(positions_x, 1)
        end
        if #positions_y >= 60 then
            oldpos.y = positions_y[1]
            table.remove(positions_y, 1)
        end
        local speed = 0
        speed = sqrt(((mousepos.x-oldpos.x)/(#positions_x + 1))^2 + ((mousepos.y-oldpos.y)/(#positions_y + 1))^2)
    end,

I'm probably doing this way wrong

mystic river
#

local variables won't persist between updates

#

so timer is always going to be 0

amber turret
mystic river
#

you can't do an if check inside a return, you have to do it outside

red flower
#

also G.GAME.blind.chips is the number, if you need the text it's G.GAME.blind.chip_text iirc

amber turret
#

oh

red flower
#

but its probably better to check for the number breakpoint for the e formatting

mystic river
#

broadly, you can't do things in general inside a return

amber turret
#

hm

#

but then how would i do it?

mystic river
#

instead of return if... then value do if... then return value

amber turret
mystic river
#

that should work

red flower
#

youre missing an end

silk latch
# mystic river so `timer` is always going to be 0

so this?

config = { extra = { timer = 0, positions_x = {}, positions_y = {}, speeds = {}, speed = 0, mult = 0, mult_mod = 1 } },
    update = function(self, card, dt)
        local piss = 0
        local mouse_vel = {}
        card.ability.extra.timer = (card.ability.extra.timer or 0) + dt
        local mousepos = {}
        mousepos.x, mousepos.y = math.floor(G.CURSOR.T.x), math.floor(G.CURSOR.T.y)
        local oldpos = {}
        table.insert(card.ability.extra.positions_x, {mousepos.x})
        table.insert(card.ability.extra.positions_y, {mousepos.y})
        if #card.ability.extra.positions_x >= 60 then
            oldpos.x = card.ability.extra.positions_x[1]
            table.remove(card.ability.extra.positions_x, 1)
        end
        if #card.ability.extra.positions_y >= 60 then
            oldpos.y = card.ability.extra.positions_y[1]
            table.remove(card.ability.extra.positions_y, 1)
        end
        card.ability.extra.speed = sqrt(((mousepos.x-oldpos.x)/(#card.ability.extra.positions_x + 1))^2 + ((mousepos.y-oldpos.y)/(#card.ability.extra.positions_y + 1))^2)
    end,
mystic river
#

well, unless there's some syntax error like that :v

mystic river
amber turret
#

cheated in a lot of jokers to make testing the one i added easier, and i ended up getting another one of them avalible in the shop without showman, is this norma;?

primal robin
silk latch
# mystic river i don't see anything wrong with that on a quick skim put in some debug prints a...

tweaked it a bit to

config = { extra = { timer = 0, positions_x = {}, positions_y = {}, speeds = {}, speed = 0, mult = 0, mult_mod = 1 } },
update = function(self, card, dt)
    local piss = 0
    local mouse_vel = {}
    card.ability.extra.timer = (card.ability.extra.timer or 0) + dt
    local mousepos = {}
    mousepos.x, mousepos.y = math.floor(G.CURSOR.T.x), math.floor(G.CURSOR.T.y)
    local oldpos = {}
    table.insert(card.ability.extra.positions_x, { mousepos.x })
    table.insert(card.ability.extra.positions_y, { mousepos.y })
    oldpos.x = card.ability.extra.positions_x[1]
    if #card.ability.extra.positions_x >= 30 then
      table.remove(card.ability.extra.positions_x, 1)
    end
    oldpos.y = card.ability.extra.positions_y[1]
    if #card.ability.extra.positions_y >= 30 then
     table.remove(card.ability.extra.positions_y, 1)
    end
    --[[    if #card.ability.extra.positions_x >= 61 then
        oldpos.x = card.ability.extra.positions_x[1]
        table.remove(card.ability.extra.positions_x, 1)
    end
    if #card.ability.extra.positions_y >= 61 then
        oldpos.y = card.ability.extra.positions_y[1]
        table.remove(card.ability.extra.positions_y, 1)
    end]]
    card.ability.extra.speed = sqrt(((mousepos.x - oldpos.x) / ((#card.ability.extra.positions_x or 60) - 1)) ^ 2 +
    ((mousepos.y - oldpos.y) / ((#card.ability.extra.positions_y or 60) - 1)) ^ 2)
    table.insert(card.ability.extra.speeds, { card.ability.extra.speed })
    if #card.ability.extra.speeds >= 61 then
      table.remove(card.ability.extra.speeds, 1)
    end
    print("pos_X = " .. math.floor(G.CURSOR.T.x) .. ", pos_Y = " .. math.floor(G.CURSOR.T.y))
    print("v_X = " ..
      math.floor((mousepos.x - oldpos.x) / ((#card.ability.extra.positions_x or 60) - 1) * 100) / 100 ..
      ", v_Y = " .. math.floor((mousepos.y - oldpos.y) / ((#card.ability.extra.positions_y or 60) - 1) * 100) / 100)
    print("speed = " .. math.floor(card.ability.extra.speed))
end,
#

(goes to the card.ability.extra.speed = sqrt line)

#

added an or 0 to that line

#

still crashes damn it

mystic river
#
    mousepos.x, mousepos.y = math.floor(G.CURSOR.T.x), math.floor(G.CURSOR.T.y)
    local oldpos = {}
    table.insert(card.ability.extra.positions_x, { mousepos.x })
    table.insert(card.ability.extra.positions_y, { mousepos.y })
--...
    if #card.ability.extra.positions_x >= 30 then
      table.remove(card.ability.extra.positions_x, 1)
    end
    oldpos.y = card.ability.extra.positions_y[1]
    if #card.ability.extra.positions_y >= 30 then
     table.remove(card.ability.extra.positions_y, 1)
    end

why are you appending the current position to the end of this table and then checking the table's length?

silk latch
#

So the table doesn't become infinite in length?

mystic river
#

why do you need a table of the last n positions? you only need two points and a time to calculate velocity

silk latch
mystic river
#

you seem to be tracking 30 points
do you need that many?

silk latch
#

I'm trying to track the average speed over the last half a second and keep it up-to-date?

mystic river
#

i see
card.ability.extra.speed = sqrt(((mousepos.x - oldpos.x) / ((#card.ability.extra.positions_x or 60) - 1)) ^ 2 + is this the line that crashes?

silk latch
#

yes, even after coating all the positions in ([...] or 0)s because now I'm getting hit with the

mystic river
#

well yeah, table or 0 results in table, because tables are truthy

#

or doesn't check contextual validity, just truthiness

#

put print(mousepos.x, oldpos.x) above that line

silk latch
#

So I need to set another value to = #card.ability.extra.positions_x?

mystic river
#

those are supposed to be numbers, but the crash indicates that one or both of them is a table, so let's find out which one

silk latch
mystic river
#

i imagine you have debugplus active, you can press / to bring up the log
it should be right before the crash

#

(logs are also stored in /mods/lovely/logs)

silk latch
mystic river
#

looks like it's oldpos.x that's a table

#
    table.insert(card.ability.extra.positions_x, { mousepos.x })
    table.insert(card.ability.extra.positions_y, { mousepos.y })
    oldpos.x = card.ability.extra.positions_x[1]

oh, i see what's happening
you're putting a table containing the number into oldpos, when you want to be putting just the number

silk latch
#

so I just lather that shit in tonumber()?

mystic river
#

no

#

delete the brackets

#

number instead of { number }

silk latch
#

Oh right from before I seperated the tables

#

Okay that is a much smaller scale than I imagined

#

(with my mouse in the bottom-right corner)

mystic river
#

that might not be accurate
iirc dt doesn't get passed to cards in the collection

#

or something like that, i forget the details, but i couldn't make neko do things in the collection, its timer never updated

silk latch
fading rivet
primal robin
#

@red flower since glossary development is happening in both sides looks like, what kind of tools you may want to have out of the box?
I already have some API to filter info_queue and add own things in it, but I can prepare smth more advanced if needed

#

I seen you're working on terminology, I can setup some sort of parser which will convert text to actual entries

red flower
primal robin
#

I want it make more like api

#

Right now I have API to make custom sections in which you can insert any stuff you need

#

And then, you setup filters to define when to display, what and where

#

Basically all this terms page you have, already can be made pretty easily

#

it's like 1 section and 1 filter

#

seals suck tho

red flower
#

yeah i can probably use my stuff to set up compat in the future

primal robin
#

I'm planning to add pokermon compat by myself

#

as proof of concept kinda

#

then polish more ui bla bla bla

red flower
primal robin
#

yea this one like ideal to work with

#

Also I'll include PPU credits

#

Would be nice to see card creator's cards from credits in this page

#

And that's kind of idea Doc mentioned

#

He wanted page where I can visually see credits for a card

#

I need implement pages tho

#

I'll let you know when I will have something decent to show

#

(happen probably after pokermon shenanigans)

#

man maybe I should stop creating small lib mods or smth which I will not support afterwards ⚗️

#

I have smth like 4-5 of them

#

also I'll do it for hotpot, especially because it has shit ton of stickers

#

and wacky jonklers which, for example, adds info_queue for all jokers you seen in a run

#

perfect mod to test stuff actually

#
  • has credits
#

Does stocking stuffer uses PPU for credits?

red flower
#

im pretty sure

primal robin
#

good, easier for me

#

you what also would be very cool? PPU have function which creates a card from member

#

Because if I want make a card with all funny things other teams did as shaders, sounds, click interactions, woule be nice to keep all of that

#

but I guess that's big ask

gusty compass
#

what would i have to do in order to get formatting reminiscent to joker desc formatting via DynaText

#

since apparently it doesnt seem to react to {f:}

red flower
#

whats the goal

#

you can use font = in dynatext

gusty compass
fading rivet
red flower
#

font = SMODS.Fonts.modprefix_key should work

gusty compass
#

alright

#

cus im going off of the assumption that dynatext works with the formatting system

#

so yea

fading rivet
#

yeah we need to add dynatext to the wiki its got some smods exclusive features ;-;

gusty compass
#

yea...

silk latch
fading rivet
#

namely shader support and conditionals

gusty compass
#

alright...

fading rivet
red flower
#

the formatting system makes dynatext but dynatext doesn't support it out of the gate

gusty compass
#

could be up for debate

red flower
#

?

gusty compass
#

some function that natively supports the formatting system, but its a personal take

#

unless it already exists and im just uninformed

red flower
#

i dont undestand what youre saying, there are functions that do

#

the easiest way to get formatted ui is to SMODS.localize_box(loc_parse_string("my formatted {C:attention}string"))

#

there is an example in the SMODS.localize_box docs iirc

gusty compass
#

also i was gonna ask does that work with object nodes

red flower
#

that function returns ui nodes, you can create a UIBox with them but it's easier to just plug the ui directly

gusty compass
#

alright, ill see what i can do with that

#

thanks

primal robin
#

Issue says that incorrect font was passed

#

Also if you think about it, joker names are all Dynatext and supports formatting

#

So maybe, there's some magic to make it work, or imitate it

gusty compass
#

yea i have no clue what im doing

primal robin
#
local loc_text = SMODS.localize_box(loc_parse_string("{C:attention}My{} formatted line"), {
  default_col = G.C.UI.TEXT_LIGHT,
  vars = {}
})
local line = { n = G.UIT.R, nodes = loc_text }
gusty compass
#

alr

red flower
gilded hamlet
#

hey i made a custom deck skin and it was working but then randomly stopped working and i have no clue why

#

:(

clever lily
#

how do i freeze the game for a specific period of time with a joker

red flower
#

that will still allow the player to press buttons and stuff tho but the game wont advance

clever lily
#

that works

#

thanks <3

vital jewel
#

Lua newbie here
So basically I'm trying to code 2 new suits for a mod I'm making, they mostly work as they load in correctly and get detected by jokers but, for some reason, instead of displaying their name id thingy correctly it gets replaced by "ERROR", I'm really stuck as everything else works and everything should be defined

versed swan
#

Set up localization for your suit

#

I think there should be details on SMODS.Suit documentation

#

(Can't check rn, afk)

vital jewel
#

How do I do that tho

versed swan
#

Like I said; There should be details for that on SMODS.Suit documentation on the Steamodded wiki

vital jewel
#

Oh ok thanks

#

Didn't know there was a wiki

#

I was going with the github links

slate turtle
#

uh question

#

is there a way to add jokers from other mods into a pool from my mod

red flower
#

im not sure if the other mod has to load first

white zinc
#

what context should i use if i want to modify a scored card of a hand that just beat a blind? context.end_of_round is too late and context.after runs each hand played

brittle yacht
#
    key = 'hector',
    loc_txt = {
        name = "Jimbo Salamanca",
        text = {
            "Plays a {C:gold}bell sound{} every {C:attention}click{}",
            "If player clicks 44 times, {C:red}explode{}",
            "{C:inactive}({}{C:red}Explode:{} {C:inactive}destroy self and adjacent {}{C:attention}Jokers,{} {C:red}ignore{} {C:enhanced}Eternal{}{C:inactive}){}",
            "{C:inactive}(Currently {}{C:attention}#2#{}{C:inactive} clicks left){}"
        }
    },
    atlas = 'hector',
    pos = { x = 0, y = 0 },
    rarity = 2,
    cost = 4,
    blueprint_compat = false,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = true,
    config = { extra = { bellclicks = 0, bellclicksleft = 44, } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.bellclicks, card.ability.extra.bellclicksleft } }
    end,

    calculate = function(self, card, context)
        if context.add_to_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) = 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) = 44
        end
        if context.remove_from_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) = 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) = 44
        end
        if context.sink_press then
            if to_big((card.ability.extra.bellclicks or 0)) == to_big(43) then
                card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) = 0
                for i = 1, #G.jokers.cards do
                if G.jokers.cards[i] == card then
                    if i > 1 then
                        local left = G.jokers.cards[i - 1]
                        left:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                    end
                    if i < #G.jokers.cards then
                        local right =  G.jokers.cards[i + 1]
                        right:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                    end
                    self:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                end
                
            end
            else
                card.ability.extra.bellclicks = (card.ability.extra.bellclicks) + 1
                card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) - 1
                    G.E_MANAGER:add_event(Event({
                    func = function()
                        print('skbidi toielt')
                        play_sound('sink_bell')
                        return true
                    end
                    }))
                return {
                    message = "Ding!"
                }
            end
        end
    end
}```
#

sorry for wall of code

#

nvm im an idiot

#
    key = 'hector',
    loc_txt = {
        name = "Jimbo Salamanca",
        text = {
            "Plays a {C:gold}bell sound{} every {C:attention}click{}",
            "If player clicks 44 times, {C:red}explode{}",
            "{C:inactive}({}{C:red}Explode:{} {C:inactive}destroy self and adjacent {}{C:attention}Jokers,{} {C:red}ignore{} {C:enhanced}Eternal{}{C:inactive}){}",
            "{C:inactive}(Currently {}{C:attention}#2#{}{C:inactive} clicks left){}"
        }
    },
    atlas = 'hector',
    pos = { x = 0, y = 0 },
    rarity = 2,
    cost = 4,
    blueprint_compat = false,
    eternal_compat = true,
    perishable_compat = true,
    unlocked = true,
    discovered = true,
    config = { extra = { bellclicks = 0, bellclicksleft = 44, } },
    loc_vars = function(self, info_queue, card)
        return { vars = { card.ability.extra.bellclicks, card.ability.extra.bellclicksleft } }
    end,

    calculate = function(self, card, context)
        if context.add_to_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) == 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 44
        end
        if context.remove_from_deck then
            card.ability.extra.bellclicks = (card.ability.extra.bellclicks) == 0
            card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 44
        end
        if context.sink_press then
            if to_big((card.ability.extra.bellclicks or 0)) == to_big(43) then
                card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) == 0
                for i = 1, #G.jokers.cards do
                if G.jokers.cards[i] == card then
                    if i > 1 then
                        local left = G.jokers.cards[i - 1]
                        left:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                    end
                    if i < #G.jokers.cards then
                        local right =  G.jokers.cards[i + 1]
                        right:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                    end
                    self:start_dissolve({ HEX("57ecab") }, nil, 1.6)
                end
                
            end
            else
                card.ability.extra.bellclicks = (card.ability.extra.bellclicks) + 1
                card.ability.extra.bellclicksleft = (card.ability.extra.bellclicksleft) - 1
                    G.E_MANAGER:add_event(Event({
                    func = function()
                        print('skbidi toielt')
                        play_sound('sink_bell')
                        return true
                    end
                    }))
                return {
                    message = "Ding!"
                }
            end
        end
    end
}```
nvm again i have a different issue now
white zinc
silent sail
red flower
#

it's for text that you can hover over like deck descriptions or mod descriptions

#

same with {T:}

silent sail
#

ahhhh

daring fern
primal robin
#

Darn, I guess something is broken with stencil

noble rapids
#

is there a way to make a joker animate once? like its usually one sprite, but when i say enter a blind, it goes through a couple sprites, then ends back on its normal sprite?

red flower
#

with that you can animate manually

noble rapids
#

but if the joker goes through multiple sprites, the game just changes it to the last sprite, so it doesnt look like anything happens

faint yacht
#

Events.

wanton jolt
#

Ok so i'm making Misprint Consumables, and want them to appear both in their respective normal sets (like hidden = true, soul_set = "Set") and in their own respective misprint Vouchers

#

right now i can only have one or the other

#

Do i have to take ownership or patch the booster packs?

brittle yacht
#

MB

brittle yacht
noble rapids
# faint yacht Events.

like i just go through the sprites in an event? or i make each sprite change an event?

red flower
#

make each change an event with delays yeah

primal robin
#

Okay, something in hotpot breaks stencil

#

this... sucks

#

at the same time understandable, this kind of technology was not invented during hotpot

#

I was worried that something in smods fucked up stencil completely

noble rapids
#

if i do this, the base card sprite changes, but the soul sprite does not, why is that?

glossy dagger
knotty solstice
keen totem
#

how do you do something when either a joker first appears or the run gets reloaded

#

i need to set which sprite a joker uses in the altas dynamically, but if you reload it currently just resets to the base one set as the pos when you reload

frosty rampart
#

set_sprites function in the joker definition

#

it'll run every time the joker is generated or loaded into the game

keen totem
#

thank you

frosty rampart
#

but it runs pretty early in the process of (re)creating the joker, so if you need access to variables in card.ability.whatever, you'll need to put all the relevant code in an event, because at the time of running set_sprites, the ability table isn't even set up yet

keen totem
#

also, i want to change the sprite at the exact same time as returning a message

#

how would i do that

#

im not too good with the timings of events

frosty rampart
#

in a calculate return table, you can do this, and i think it'll give you the exact timing you want

return {
  ...
  func = function()
    -- run any code you want in this function, and it will
    -- be timed to happen when the joker visually triggers
  end
}
#

you shouldn't even need an event for it

keen totem
#

alr

#
function setSprite()
    local c = card.ability.extra
    local pos = math.ceil(9*(c.payout/c.resetValue))
    card.children.center:set_sprite_pos({x = pos, y = 0})
end
if reset then
    SMODS.calculate_effect({message=localize("k_reset"),colour = G.C.FILTER,func = setSprite()}, card)
else
    SMODS.calculate_effect({message=localize("k_upgrade_ex"),colour = G.C.FILTER, func = setSprite()}, card)
end
#

so i could do something like this

frosty rampart
#

yep that should work great (as long as that function is defined within the calculate function)

radiant bronze
#
SMODS.PokerHand{
    key = "flushsix",
    chips = 120,
    mult = 15,
    level = 1,
    l_chips = 30,
    l_mult = 3,
    loc_txt = {
            name = "Flush Six",
            description = {
                "Six cards of the same rank and suit"
            }
        },
    visible = true,
    order = 100,

    example = {
        { 'S_A', true },
        { 'S_A', true },
        { 'S_A', true },
        { 'S_A', true },
        { 'S_A', true },
        { 'S_A', true }
    },

    evaluate = function(self, parts, hand)

        if parts._flush and #hand == 6 then

            local first_rank = hand[0] and hand[0].rank
            local same_rank = true

            for i = 0, #hand - 1 do
                if hand[i].rank ~= first_rank then
                    same_rank = false
                    break
                end
            end

            if same_rank then
                return hand
            end
        end
        return {}
    end,
}
#

my poker hand is not poker handing

frosty rampart
#

lua is 1-indexed, not 0-indexed

radiant bronze
#

whoops

white zinc
# white zinc what context should i use if i want to modify a scored card of a hand that just ...
            local possible_cards = {}
            for _, scoring_card in ipairs(context.scoring_hand) do
                if scoring_card.edition == nil then
                   table.insert(possible_cards, scoring_card)
                end
            end
            if possible_cards ~= nil then
                local chosen_card = pseudorandom_element(possible_cards, 'bgn_cardczar')
                local random_edition = SMODS.poll_edition { key = "modprefix_seed", guaranteed = true, no_negative = true }
                if chosen_card ~= nil then
                    chosen_card:set_edition(random_edition)
                end
            end
        end```

this is what i have right now. is there a better context to use? i want the player to see the card change edition
faint yacht
#

Try if context.after and SMODS.calculate_round_score() + G.GAME.chips > G.GAME.blind.chips?

white zinc
#

that works, but it visually puts the edition on the card before the cards even score. lemme try wrapping this in an event and see if that helps

#

yep, that works

#

thanks for the help!

white zinc
#

i don't understand how this could be returning a nil value when that line of code should only run if the value isn't nil

white zinc
#

🤦‍♂️

#

oops

#

thanks lol

final jewel
#

```pseudorandom_element(SMODS.Ranks, pseudoseed('giga_idk'))````is it the right way to get a random rank

#

cause it return the whole table right now

slim ferry
#

it returns the rank object table, you should get the key from that

near coral
final jewel
#

context.other_card:get_rank() and is there something like that

near coral
final jewel
#

cause like im using get_id but the table return Jack and not 11

daring fern
final jewel
#

oh yeah and I just convert for the loc_vars

tall wharf
#

if you need then i can include some extra properties on the center i extended

primal robin
#

I found workaround so not really

cursive sentinel
#

Is there a way to have context.buying_self working for when the joker is generated

#

For now, it only applies when bought from the shop, not when picked in a booster pack, or created by a tarot or joker

daring fern
cursive sentinel
#

Oh right, thanks !

cursive sentinel
#

wondering, is there a way to specifically lower jokers price?

daring fern
cursive sentinel
#

in which script can I see it?

#

I didn't seem to find it in the game files

daring fern
cursive sentinel
#

thanks a lot

#

mhh doesnt seem to appear there either

daring fern
cursive sentinel
#

smods-1.0.0-beta-1503a

daring fern
cursive sentinel
#

updated to smods-1.0.0-beta-1620a, still doesn't seem to find it

cursive sentinel
#

wdym code?

#

i dont have code for what im looking to do yet, im just trying to understand where'd the hook be

daring fern
cursive sentinel
#

yes

calm marten
#

how would i create a playing card with specific suit and random rank?

#

the code a friend of mine gave me doesnt seem to work as intended

daring fern
amber turret
#

trying to make a combination of even steven and misprint, whats wrong with this code causing it to crash?

calculate = function(self, card, context)
  if context.joker_main then
    local temp_Mult = pseudorandom('misprint', self.ability.extra.min, self.ability.extra.max)
    context.other_card:get_id() <= 10 and context.other_card:get_id() >= 0 and context.other_card:get_id()%2 == 0 then
      return {
        mult = temp_Mult,
        card = self
      }
    end
end
red flower
#

you're missing an if?

amber turret
#

oh

#

also, do you know how to make the description have the weird random description that misprint has?

red flower
#

are you looking at the vanilla code for reference?

amber turret
#

yeah

red flower
#

it has misprint too

amber turret
#

oh, thanks!

daring fern
amber turret
daring fern
# amber turret

No, you're supposed to replace your entire calculate function with that.

amber turret
#

oh

#

what do i do then?

slate turtle
#

question

#

how can i make a boss blind that disables a specific joker

#

wait let me check boss blinds rq

amber turret
#

I'd look in the Yahimod for the blind that disables all Yahimod jokers to see how it does that.

slate turtle
#

ig i'm using crimson heart as my template

#

how do i make it disable a joker in a specific position tho

amber turret
slim ferry
#

does SMODS.add_card now also take a filter argument just like SMODS.poll_object?

daring fern
amber turret
#

thx! now i have 3 jokers for my mod.

#

uh

#

tried the misprinted steven joker out and the game crashed when i played a hand

hard kayak
#

You need to define config

amber turret
#

so, in the function but or somewhere else?

hard kayak
#

Did you forget to define min and max as extra

amber turret
#

oh

hard kayak
#

It should be inside the SMODS.Joker but not in the calculate

slim ferry
amber turret
#

actually

hard kayak
#

So it would be like config = { extra = { min = 0, max = 22}}

amber turret
#

oh

daring fern
hard kayak
#

If there are more lines past config, append a comma at the end of that line

#

Keep in mind that you will need to make a new copy of that joker because config variables aren't updated on existing cards

slim ferry
hard kayak
#

how exactly is pool defined

daring fern
hard kayak
#

Yeah

slim ferry
#

right

hard kayak
#

You never created a pool

#

That's what I was asking about where is the pool defined?

slim ferry
#

well the pool is created but the issue is not returning it

slim ferry
red flower
#

if attribute is empty it might get nothing im not sure

slim ferry
#

fuckkk

red flower
#

you can just do poll_object separately

slim ferry
#

i suppose that is true

red flower
#

new smods function usage found : )

#

i could probably do this directly with add_card but whos checking

primal robin
#

SMODS.emplace when

red flower
#

that SMODS.add_to_deck

primal robin
#

there's difference between emplacing and adding to deck

red flower
#

it does both

slim ferry
#

why does this say im not using a pool source

#

oh wait

#

nvm

#

okay well

#

the pool is still just the default joker

#

even without the empty attributes

keen totem
#

W floating point error

keen totem
#

why does this happen when this Joker is undiscovered

#

it has multiple sprites, and its the only one that has multiple sprites, and its the only one that has this half-Jimbo half-Undiscovered sprite

#

so i assume its caused by having multiple sprites in some way

tidal hemlock
#

does smods allow stickers on playing cards by default

#

like eternal

slim ferry
#

if you manually set eternal to the cards yes

#

though they dont work

#

idk if perishable or rental work but nothing in vanilla checks for eternal on playing cards so that wont work

frosty rampart
#

has spectrallib integrated the stickers on playing cards patches yet idk
perishable and rental both need a bit of work to stop it from triggering twice if it's on a playing card, but otherwise they're pretty much fine

slim ferry
#

it has the eternal patches

#

the others idk

white zinc
#

i'm looking at the context.stay_flipped right now. is it possible to detect whether a played card is currently flipped or unflipped?

#

actually i think i may have found it

sturdy compass
#

If so, you need to check if a card is discovered before running your custom draw code

brittle yacht
#
        art = { "sinkhole" },
        code = { "sinkhole" },
        idea = { "sinkhole, rocket, Jerry J. Jerry XXIII" }
    },```
crashed when i hovered over my joker i tested it on
amber turret
#

does anyone know how to get fs files?

dapper sun
#

what for?

amber turret
#

joker editions and stuff

dapper sun
#

all of vanilla's files can be gotten by opening the .exe like a .zip

#

including the shaders

amber turret
#

yeah but i mean for custom joker editions

dapper sun
#

yea

#

i'd recommend copying and modifying a simple shader like resources/shaders/negative.fs

#

you only need to modify the effect function

white zinc
#
            if context.card:has_attribute(food) then
                card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_gain
            end
        end```

how does the :has_attribute thing work? i thought i did it right here but my joker isn't working
frosty rampart
#

the argument needs to be a string, so "food" with the quote marks

#

it doesn't crash because lua assumes any uninitialized variable is just nil

white zinc
#

ah gotcha

silk latch
keen totem
#

how would i check if a joker is discovered

sturdy compass
#

card.config.center.discovered iirc

slim ferry
#

or card.bypass_discovery_center

#

check for either

white zinc
#

tried to get this joker to work in 2 different ways, but neither of them have proved successful. checking to see if a card is face down has proved harder than expected and i'm not sure if i'm over complicating things here :/

frosty rampart
#

I can't see the code rn (on mobile) but can't you just check if card.facing == "back"

silk latch
#

white zinc
#

that's what i did, but i think that when i'm checking them, they already switch to being face up

keen totem
slim ferry
#

why does this draw on front sprites of the card on the loading screen instead of like anything i want it to draw on

frosty rampart
slim ferry
#

the loading screen card shouldnt even have an area defined

frosty rampart
slim ferry
#

okay but

white zinc
slim ferry
#

its a drawstep

#

oh wait actually

#

nvm you right

frosty rampart
#

happy to help, both of you

slim ferry
#

though it didnt work to begin with even when i was nil checking that

frosty rampart
#

not sure what exactly the issue would be for getting it to work in the intended situation, would need to see more info about that cardarea I think

slim ferry
#

evaling this is true

#

this is the area definition

frosty rampart
#

hrm
not too sure, sorry. I'm kinda handicapped at the moment by being on phone anyway

white zinc
# white zinc G.hand.highlighted was the context i was looking for! thanks!
        if context.press_play then
            for _, card in ipairs(G.hand.highlighted) do
                if card.edition == nil and card.facing == "back" then
                   table.insert(possible_cards, card)
                end
            end
        end
        if context.before and context.cardarea == G.play then
            for _, card in ipairs(context.scoring_hand) do
                for _, flipped_card in pairs(possible_cards) do
                    if flipped_card == card then
                        local random_edition = SMODS.poll_edition { key = "bgn_memory", guaranteed = true, no_negative = true }
                        G.E_MANAGER:add_event(Event({
                            func = function()
                                if chosen_card ~= nil then
                                    chosen_card:set_edition(random_edition)
                                    chosen_card:juice_up()
                                end
                            return true 
                            end,
                        }))
                    end
                end
            end
        end```

i've got this so far, but i'm still not getting any action unfortunately
silk latch
frosty rampart
white zinc
#

ahh

#

would i need to make that table a loc_var then?

silk latch
#

And that's before the concern of it possibly not even scoring for some reason and how the

   loc_vars = function(self, info_queue, card)
        local chips = card.ability.extra.mult * card.ability.extra.max_speed
        local fastness = math.floor(card.ability.extra.max_speed * 100) / 100
        if not fastness or not chips then
            return { vars = { "Recalibrating...", "Recalibrating..." } }
        else
            return { vars = { chips, fastness } }
        end
    end,

just doesn't fucking work at adding the Recalibrating text

frosty rampart
# white zinc would i need to make that table a loc_var then?

not quite, just put it somewhere like card.ability.extra or even just a local table outside the joker itself so you don't overwrite it at the start of the calculate function
(and then clear it out before you add all the cards in context.press_play)

fervent rampart
#

Is there a way to make just the first playing card get counted as a face card?
I tried

if context.before and #context.full_hand then
            local first_card = context.full_hand[1]
            first_card.is_face()
        end

But this causes an "attempt to index local 'self' [a nil value]" when I play a card. (I couldn't find any information about is_face on the vanilla remade of smods wikis, so if there is any please link me)

slim ferry
#

this is not how you make a card count as a face card, check the implementation of pareidolia on vanillaremade

#

currently this is only running a face check on a card without passing an actual card object

rigid solar
#

you'd have to hook Card:is_face() to do your effect

fervent rampart
#

Already checked Paredolia's code. And I think I have hooked Card:is_face() already.

rigid solar
#

then that's it

slim ferry
#

you should run your checks in the hook

fervent rampart
#

...But I guess what that means is I should be adding the code into the hook?

rigid solar
#

yes that's the point of hooking

slim ferry
#

you should check if the self == G.play.cards[1]

#

and if G.play exists, of course

fervent rampart
#

Thank you.

brittle yacht
#

how do i make the badges with the text that cycles through different entires

dapper sun
#

does anyone know why the hologram shader isn't working?

wintry solar
#

Needs to be slightly transparent iirc

dapper sun
#

oh damn

#

ty

silk latch
#

How would I check the type of the most recently opened booster pack as a G value?

slim ferry
#

what matters most is the check for actually applying the badge

cerulean ridge
#

Im having isses with colection order, i have each joker in its own file in a folder. "Order" seems to be getting ignored and the fallback is alphabetical, any work around?

slim ferry
#

what are you using to load your jokers in order?

proper swan
#

did i type it in right?

cerulean ridge
#

SMODS.NFS.getDirectoryItems

proper swan
#

above is the tutorial video

slim ferry
# cerulean ridge SMODS.NFS.getDirectoryItems

are you doing anything to get a specific order with the file structure/loading system? by default this gets the file names listed in alphabetical order so that will also be the order the files are loaded in

cerulean ridge
#

Oh, i have order = x on each file. Thats all though. I assumed that load order and collection order would be independent.

slim ferry
#

the order value on jokers doesnt actually mean anything by default, im assuming youre looking at cryptid which gives that value functionality elsewhere

cerulean ridge
#

Im looking at source code for this, but i also notice that they are all listed in the collection order here too so i can see how it could be redundant

slim ferry
#

load order and collection order are tied to each other as the order value is overridden to be whatever the next order value in the collection would be at injection

slim ferry
cerulean ridge
#

Is it tricky to tie in my own order with the loading function?

slim ferry
#

shouldnt be all that hard

tidal hemlock
#

failing to understand why this doesnt load

#

only sending the zip because i dont know the culprit file

silk latch
#

How do I get specifically the type of item typically spawned by a booster pack, given the booster's key? (Given how some have different kind names compared to their consumables' types)

cerulean ridge
slim ferry
#

i gave you a link already with my solution

tidal hemlock
#

is this the correct file format for a mod or am i missing something

slim ferry
#

this is correct

#

what is in your json file

tidal hemlock
#

desc is leftovers from vremade

slim ferry
#

version is not a valid version string

#

it should be in the format <major>.<minor>.<patch><revision>

#

major, minor and patch should be numbers

#

e.g. 0.5.0b

#

and a revision starting with a ~ indicates a beta

frosty bone
silk latch
#

How do I make an info_queue without using another item?

brittle yacht
white zinc
#

if i reference SMODS.last_hand in a calculate function, is it going to return info about the CURRENT HAND or the PREVIOUS HAND?

brittle yacht
slim ferry
#

you shouldnt need to edit anything besides where the list of strings are created

#

but this is already pretty much the minimum for this i think

brittle yacht
#

oh ight

#

thanks gng

tidal hemlock
#

custom suit wants to render as hearts and idk why

silk latch
#

because my current alternative is making a not-in-pool Joker that still runs the risk of being found by another mod or something

slim ferry
#

you can do info_queue[#info_queue+1] = { key = X, set = Y, vars = { --[[text variables if needed]] } } to add a tooltip for the entry in decriptions[set][key]

tidal hemlock
brittle yacht
# slim ferry but this is already pretty much the minimum for this i think

so i put this into my joker

        { key = "credits_code", vars = {"sinkhole"} },
        { key = "credits_art", vars = {"sinkhole" }},
        { key = "credits_idea", vars = {"sinkhole + rocket + Jerry J. Jerry" }},
    },```
and i put this in my hooks.lua
```local smcmb = SMODS.create_mod_badges
function SMODS.create_mod_badges(obj, badges)
    smcmb(obj, badges)
    if not SMODS.config.no_mod_badges and obj and type(obj.inv_badge_info) == "table" then
        local function calc_scale_fac(text)
            local size = 0.9
            local font = G.LANG.font
            local max_text_width = 2 - 2 * 0.05 - 4 * 0.03 * size - 2 * 0.03
            local calced_text_width = 0
            -- Math reproduced from DynaText:update_text
            for _, c in utf8.chars(text) do
                local tx = font.FONT:getWidth(c) * (0.33 * size) * G.TILESCALE * font.FONTSCALE
                    + 2.7 * 1 * G.TILESCALE * font.FONTSCALE
                calced_text_width = calced_text_width + tx / (G.TILESIZE * G.TILESCALE)
            end
            local scale_fac = calced_text_width > max_text_width and max_text_width / calced_text_width or 1
            return scale_fac
        end
        if next(obj.inv_badge_info) then
            local scale_fac = {}
            local min_scale_fac = 1
            local strings = { INV.display_name }
            for _, v in ipairs(obj.inv_badge_info) do
                if v.key and v.vars then
                    local str = localize({ type = "variable", key = v.key, vars = v.vars })
                    strings[#strings + 1] = (type(str) == "table" and str[1]) or str
                end
            end
            for i = 1, #strings do
                scale_fac[i] = calc_scale_fac(strings[i])
                min_scale_fac = math.min(min_scale_fac, scale_fac[i])
            end
            local ct = {}
            for i = 1, #strings do
                ct[i] = {
                    string = strings[i],
                }
            end
            local inv_badge = {
                n = G.UIT.R,
                config = { align = "cm" },
                nodes = {
                    {
                        n = G.UIT.R,
                        config = {
                            align = "cm",
                            colour = INV.badge_colour,
                            r = 0.1,
                            minw = 2 / min_scale_fac,
                            minh = 0.36,
                            emboss = 0.05,
                            padding = 0.03 * 0.9,
                        },
                        nodes = {
                            { n = G.UIT.B, config = { h = 0.1, w = 0.03 } },
                            {
                                n = G.UIT.O,
                                config = {
                                    object = DynaText({
                                        string = ct or "ERROR",
                                        colours = { G.C.WHITE },
                                        silent = true,
                                        float = true,
                                        shadow = true,
                                        offset_y = -0.03,
                                        spacing = 1,
                                        scale = 0.33 * 0.9,
                                    }),
                                },
                            },
                            { n = G.UIT.B, config = { h = 0.1, w = 0.03 } },
                        },
                    },
                },
            }
            for i = 1, #badges do
                if badges[i].nodes[1].config.colour == INV.badge_colour then
                    badges[i].nodes[1].nodes[2].config.object:remove()
                    badges[i] = inv_badge
                    break
                end
            end
        end
    end
end```
but im not seeing any changes and its not crashing
#

HOLY wall of code

slim ferry
#

is INV a reference to your mod object's table? (as in, you did INV = SMODS.current_mod somewhere)

brittle yacht
#

i think so

#

i might have deleted it lemme check

#

i did delte it

#

when did

#

whatever

slim ferry
#

that probably means it is defined but not as your mod object then if it isnt crashing

brittle yacht
#

so what and where would i put

slim ferry
#

where is the INV table actually defined

#

and as what is it defined

brittle yacht
#

hold on

brittle yacht
slim ferry
#

ah

brittle yacht
#

if i even have a table i didnt know

slim ferry
#

well you can just put INV = SMODS.current_mod at the top of your main file then

brittle yacht
#

i did that much

slim ferry
#

or anything else instead of INV, whatever you want the table to be called

silk latch
brittle yacht
slim ferry
#

i recommend using Other

silk latch
#

And does the item key append the mod key?

slim ferry
#

no it grabs the entry with that key

#

as the tooltip

#

from the given set

slim ferry
brittle yacht
#

mmk

brittle yacht
#

when i hovered over the joker

slim ferry
#

i see

brittle yacht
#

am i missing something in my loc_vars?

slim ferry
#

loc_vars shouldnt matter here

brittle yacht
#

ight nvm

slim ferry
#

did you put a print right after the if badges[i].nodes[1].config.colour == INV.badge_colour then check

#

since thats pretty much what matters

brittle yacht
#

yup

#

that printed once

slim ferry
#

okay uh

#

theres probably something im missing but im not seeing it

brittle yacht
#

hold on

#

im gonna try it on a different joker

#

nope didnt work on the other one

dawn knoll
#

How do I get a joker to re-trigger a scored card with a specific enhancement

daring fern
brittle yacht
slim ferry
#

no

brittle yacht
#

darn

dawn knoll
#

Also I added it to where the joker gives 30 chips before the re-trigger

naive coral
#

I am trying to make a joker that makes stone cards score additional plus mult equal to their chip value, and this is what i have so far. unfortunately, all stone cards score the chip value of the first stone card as mult. how can i make it so the stone cards score their chip value as mult, rather than the first played stone? (i have a tarot that scales stone cards chips, so +50 mult when scored stone doesnt work)

slim ferry
#

dont do a for loop

brittle yacht
#

it says error

#

i added 3 badges to it

slim ferry
#

just return{ mult = context.other_card:get_chip_bonus() }

slim ferry
brittle yacht
#

but why did it only work when i put the badges in manually 😭

slim ferry
#

idfk

brittle yacht
#

it might be because i have a set badges function now

#

idk gng

slim ferry
#

idk either 😭

keen totem
#

how would i get a bonus and mult in an enhancement to add to the "+X extra chips" or "+X mult" text on a card

#

like how bonus card does

slim ferry
#

the bonus value gets added by default, mult cards display their mult via the description

keen totem
#

the bonus value doesn't show on my card

slim ferry
#

oh

keen totem
#

the +15 Chips is from the desc

slim ferry
#

what is the description for your enhancement?

brittle yacht
keen totem
#

i assume that removing the +15 Chips text wouldn't just add +15 extra Chips to the desc

slim ferry
slim ferry
keen totem
#

thats the thing tho

#

stuff like Hiker adds to the +X extra chips text

slim ferry
#

huh

naive coral
#

how can i make a card NOT move up and down when i click on it

keen totem
#

yes

#
SMODS.Enhancement{
    key = "Disease",
    atlas = "Disease",
    pos = {x = 0, y = 0},
    config = { bonus = 15,
        mult = 2,
        extra = {}
    },
    loc_vars = function(self,info_queue,card)
        return {vars = {card.ability.bonus,
        card.ability.mult
    }}
    end,
    calculate = function(self,card,context)
        
    end
}
#

this is the full thing

daring fern
tidal hemlock
#

how you do define colors (such as G.C.[...])

daring fern
naive coral
tidal hemlock
# daring fern `HEX('HEX')`
    key = 'Vortexes',
    card_key = 'V',
  lc_atlas = 'CelestSuits',
  lc_colour = HEX('788383'),
  hc_atlas = 'CelestSuitsHC',
  hc_colour = HEX('C3ACCE'),
    pos = { y = 0 },
    ui_pos = { x = 0, y = 0 },
    keep_base_colours = true,
}```
would this be correct
brittle yacht
#

how do i change the joker that shows up on the menu

#

like cryptid

viscid talon
#

i have a strange issue and i dont rly know how to fix it

#

so i have a stake which increases the ante requirements to ante 10

daring fern
viscid talon
#

however, it looks like it resets the scaling effects from purple/gold stake

#

so like, ante 2 has you complete a 800 chip small blind rather than 1000 chip small blind for instance

brittle yacht
frosty rampart
brittle yacht
#

nvm

daring fern
# brittle yacht nvm
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "SC = Card(G.ROOM.T.w/2 - SC_scale*G.CARD_W/2, 10. + G.ROOM.T.h/2 - SC_scale*G.CARD_H/2, SC_scale*G.CARD_W, SC_scale*G.CARD_H, G.P_CARDS.empty, G.P_CENTERS['j_joker'])"
position = "at"
payload = "SC = Card(G.ROOM.T.w/2 - SC_scale*G.CARD_W/2, 10. + G.ROOM.T.h/2 - SC_scale*G.CARD_H/2, SC_scale*G.CARD_W, SC_scale*G.CARD_H, G.P_CARDS.empty, G.P_CENTERS['j_modprefix_key'])"
match_indent = true
frosty rampart
#

no, menu_cards can handle it by returning remove_original = true

brittle yacht
brittle yacht
daring fern
brittle yacht
frosty bone
#

Oops! The game crashed:
[SMODS _ "src/utils.lua"]:242: Attempted to insert object "j_houserules_hoteljoker" into an empty pool.

what do i do?

brittle yacht
#

and where

frosty rampart
brittle yacht
#

oh ighr

#

*ight

red flower
frosty bone
red flower
#

rarity = 2

#

not "2"

viscid talon
#

was this made with jokerforge

#

yeah it was, i can tell