#đŸ’»ăƒ»modding-dev

1 messages · Page 47 of 1

hushed cradle
#

hmm

frosty dock
#

I am not, it was just an educated guess

#

I saw it was getting that UIE by ID for pasting seeds, so I thought it might be relevant

#

I could be wrong though

hushed cradle
#

i mean youve def got a better idea than me

#

ill look through the source code and hope i find smth

#

ah

#

i think you may be right

#

but theres more ids used in the text input

#

like prompt and position

#

so ill change those too and see what happens

#

i think im just gonna patch the create_text_input to take its own id prefix or smth

#

and append that to each id

#

because every letter node has an id

gilded narwhal
#

Okay so here's the function I want to have

#

Is there any errors you can spot

frosty dock
#

looks alright to me

gilded narwhal
#

Hmm

#

Maybe there's something in the code that prevents you from modifying the base mid-run

frosty dock
gilded narwhal
#

It doesn't show when I start the blind either

frosty dock
#

get_blind_amount is definitely being called on set_blind

#

not so sure what's up with that, how are you changing the function?

gilded narwhal
#

As in the lovely patch?

frosty dock
#

sorry dumb question, i should have just scrolled up

#

i forgor

gilded narwhal
#

Well I did add another line

frosty dock
#

have you checked the lovely dump?

gilded narwhal
#

I have not

#

How do you check that?

frosty dock
#

open Mods/lovely/dump/functions/misc_functions.lua and search for the function you're modifying

#

you'll see it as it's actually being run

#

then you can debug from there

#

possible the change isn't taking effect due to setting ante_multiplier to 1 somewhere unintended?

gilded narwhal
#

Idea

#

Maybe as I'm selecting blind, ante multiplier gets set to 1 again

frosty dock
#

yeah that's what I mean

#

check what places these ante_multiplier = 1 patches are hitting

gilded narwhal
#

Okay so actually I just changed ante_multiplier to 0.5 manually and it still does nothing

frosty dock
#

wdym manually?

gilded narwhal
#

Like I changed G.GAME.ante_multiplier = 1.0 to G.GAME.ante_multiplier = 0.5 in the files

#

I'm gonna see how betmma does it

frosty dock
#

wait so you're setting it to 0.5 at the start of get_blind_amount or no?

frosty dock
#

can you screencap and send the dump of that function?

gilded narwhal
frosty dock
#

and that doesn't work??

#

what mods are you running?

gilded narwhal
#

Cryptid, Talisman, and twewy

#

ALso debugplus

#

Okay so good news

#

It works fine when

frosty dock
#

cryptid does also change get_blind_amount

gilded narwhal
#

I removed all the mods

frosty dock
#

so that's probably why

gilded narwhal
#

Cryptid incompatibility :(

frosty dock
#

i think for what you're trying to accomplish, a hook would be cleaner than lovely patches

#
local gba = get_blind_amount
function get_blind_amount(ante)
  return gba(ante)*G.GAME.ante_multiplier
end
gilded narwhal
#

That's it?

frosty dock
#

you're just trying to multiply the return value by some number

gilded narwhal
#

Man I made that way too complicated

frosty dock
#

and even for that, I think G.GAME.starting_params.ante_scaling already takes that role?

gilded narwhal
#

In my defense tho I did not know how to hook

frosty dock
gilded narwhal
#

See now could I do that but only for one ante

#

Because all of what I'm doing is to make it so one ante is smaller

#

Lemme try something first tho

gilded narwhal
wintry solar
#

In your local mod file

gilded narwhal
#

Ty

gilded narwhal
#

So good news

zealous glen
#

I have a Joker that increases the Blind amount at the start of a Blind

#

Both because I didn’t want to figure out how to update the UI, but also because it reduces the motivation to sell it mid-round

gilded narwhal
#

idk why I expected this to work

frosty dock
#

good one

#

you might wanna iterate G.jokers.cards

gilded narwhal
#

I'm just trying random stuff

#

Like it works for all antes but I just want it to work for only one ante

wintry solar
#

having an issue where my configs aren't getting loaded back in on a restart of the game, have I missed something obvious?

frosty dock
#

that may or may not be my fault, let me check

wintry solar
#

I'm using local mod = SMODS.current_mod and then referencing mod.config

frosty dock
#

are you modifying mod.config outside of settings?

#

actually nvm it's my fault

wintry solar
#

no

#

ah I see the mistake too now

frosty dock
#

fixed

wintry solar
#

👍

gilded narwhal
#

Hey guys is there a thing like context.changing_ante or something

hallow forge
#

more tabs

hushed cradle
#

i cant figure out the multiple text input boxes for the life of me

#

if anyone happens to look at it at any point and figure smth out please tell me

lament fjord
#

What's the path to the lua shared library for the mac release of Balatro?

frosty dock
#

or the save folder

lament fjord
#

yeah, in relation to the balatro executable or whatever

#

(I don't have experience with mac systems)

frosty dock
#

wait so do you want to know where the executable is or where something inside that executable is?

lament fjord
#

I'm looking for the path to the interpreter

#

The thing that corresponds to what lua51.dll is in the windows release

frosty dock
#

I'm not sure I can help then, I don't have a mac system or even executable at hand

languid mirage
hushed cradle
#

thats such a good idea

languid mirage
#

It's workaround but it should be easier than figuring out the correct way of doing it, especially if you don't plan on adding something more complex

hushed cradle
#

this was my idea of a solution lmao

#

not aligned yet ofc

#

but yours is so much better

#

thank you

willow quiver
#

any info on how wildcarding works in lovely patch patterns? I want to patch every line that starts w a given substring

solemn coral
#

I believe it will patch all lines that match your pattern

willow quiver
#

right, but the readme has a wildcardish example: pattern = "(?<indent>[\t ]*)if (?<cond>_context.type == 'eval' then)" and Im not quite sure how to make sense of it

tepid crow
#

that's regex

willow quiver
#

oh

tepid crow
willow quiver
#

i know regex, but the engines i've used it in don't really look quite like this...

#

like <indent>

#

or question mark being used by itself

tepid crow
#

(?<name>) is a regex named capture group

willow quiver
#

oh, that is new to me. TIL

#

I guess i got tripped up. the readme mentioned that pattern could use * and ? as non-regex wildacrds i think

tepid crow
#

that's patches.pattern vs patches.regex I believe

oblique gust
crisp coral
#

are there any workarounds for cards with context.destroying_card trigger making other cards with that context not trigger

#

for example, Sixth Sense and Nameless Fetus [If the first hand of round has only 1 card, destroy it, ...]. if i play a singular 6, Sixth Sense would proc first and mark the 6 as destroyed, so Nameless Fetus cannot proc its effect

shell tangle
#

Maybe try using a context.before somehow?

crisp coral
#

destroying cards in any context other than context.destroying_card creates a ghost card

#

and if i modify the code itself then multiple copies of Sixth Sense would work which is non-vanilla behavior

shell tangle
#

Something like, add a check in context.before, then trigger destruction in context.destroying_card if possible, and then activate the ability if the check passed? Does feel like it'd be a very makeshift work-around, though.

crisp coral
#

oh hm

willow quiver
#

so you want 2 destroyers to proc if theyre diff jokers, but only proc one if they're the same?

crisp coral
#

as long as vanilla cards aren't touched i'm fine with it

#

so i'll try the context.before thing

wary dirge
#

How do i change the number of initial hands a deck gives?

#

Or make a deck start with +1 hand

night pagoda
#

Does SMODS.Seal not have update field?

wintry solar
#

Update field?

#

What would that do?

night pagoda
#

run every tick? like Jokers?

wintry solar
#

oh I missed that form jokers

night pagoda
#

was a bit confused when wanted to use it but it had no output of any kind

wintry solar
#

I guess not, seals aren't really centers in terms of the game

night pagoda
#

still would be handy

wintry solar
#
# Card:update()
[[patches]]
[patches.pattern]
target = "card.lua"
pattern = 'if G.STAGE == G.STAGES.RUN then'
position = 'before'
match_indent = true
payload = '''
local obj = G.P_SEALS[self.seal] or {}
if obj.update and type(obj.update) == 'function' then
    obj:update(self, dt)
end'''
#

throw this in a .toml for now

#

I'll set it patched into SMODS with some other seal logic later on

night pagoda
#

đŸ«Ą

#

thanks!

frosty dock
#

cleaner additions tab anyone?

maiden phoenix
#

Neat

frosty dock
#

right side looks a bit empty on this one, but I don't think I'll auto-balance

maiden phoenix
#

Is this part of the recent config addition or something different?

frosty dock
#

yeah it's part of it

#

i just refined it to remove empty tabs instead of greying them out

maiden phoenix
#

Couldnt it be done automatically on SMODS object creation?

frosty dock
#

wdym

maiden phoenix
#

If I call say "SMODS.Joker" it adds it to the thing in the pic above

frosty dock
#

you mean like saving separate object lists for each mod?

maiden phoenix
#

Instead of manually inputting it in a config file

frosty dock
#

oh it isn't via config

#

it's just there

maiden phoenix
frosty dock
maiden phoenix
#

Thats very cool then

frosty dock
#

also hides the consumables box and full columns when they'd be empty

#

there's still red deck bug which I have to look into, I'll still push up what I have

wintry solar
#

Oooo nice

#

Is there a planned solution to the main collection with custom consumables types?

frosty dock
#

yeah but I'm not sure of specifics yet

#

might do that next

crisp coral
#

i don't need to request again right......

frosty dock
#

request what, the booster dupe bug?

crisp coral
#

removing consumable types from collection

frosty dock
#

oh I thought you were referring to something else

#

yeah I'm on it

crisp coral
#

yay

frosty dock
#

thoughts on localizing mod names / descriptions?

lament fjord
#

I finally figured out why I can't get require("string.buffer") to work: It's because Balatro uses luajit 2.0 and not 2.1

frosty dock
#

doesn't quite seem right how everything else is localizable now but mod names and descriptions aren't

lament fjord
#

Localthunk pls

maiden phoenix
frosty dock
#

I surely can't cut support for the current header components for backcompat reasons

#

but there's also 3 different ways to do other loc text, so whatever

#

it could also act as a way to allow actual text formatting

brisk pond
#

me patiently waiting for "Balatro'UI for dummies - A modder's guide" to drop from someone

wintry solar
#

it's in progress

lament fjord
#

Can I formally ask Localthunk to bump the underlying luajit to 2.1

languid mirage
#

tho Idk what version was used before that might've caused performance issues

#

actually nvm

#

says that it was 2.0.5

#

yea Idk why it's not 2.1

#

¯_(ツ)_/¯

zealous glen
#

I’m getting some idea of how other tooltips can work

lament fjord
#

Luajit does rolling releases, so today's 2.1 might have solved the problems of the 2.1 tried in 1.0.1e

#

Do we know what kind of conditions contributed to that problem?

hushed cradle
#

would anyone know how to get the box on the right to be drawn on top?

#

its hidden under the other joker atm

languid mirage
#

the tooltip would need to be drawn after the other joker

#

I think that's how it works? I remember someone mentioning that

#

people just add tooltips below the main one

#

to fix that

hushed cradle
#

right

#

it looks like i can change the draw layer manually after creating the ui box

#

so im gonna try that

#

no idea what i have to change it to but ill trial and error

lament fjord
#

Mad science idea: Lug in a later version of LuaJIT and then load some modules in from it

Will this bork anything horribly?

frosty dock
#

guys

crisp coral
frosty dock
#

adding pages to this was more annoying than I thought, given I don't really know much about object nodes

royal ether
# hushed cradle right

the way balatro does rendering priorities is G.I.[whatever], so try moving it up through the tables in G.I until it renders on top

#

you can find the priority it renders stuff in Game:draw()

#

top to bottom its G.I.POPUP, G.I.ALERT, G.I.UIBOX, G.I.CARD, G.I.CARDAREA, G.I.UIBOX (again for some reason idk), G.I.MOVEABLE, G.I.NODE

#

maybe your uibox isnt being drawn in the 2nd uibox render so thats probably why its being put under cards?

#

idk

hushed cradle
#

thank you

#

can i table.insert at a specific point?

#

i dont use much lua

royal ether
#

yea you just table.insert(table, pos, value)

hushed cradle
#

cool

#

cheers

lament fjord
#

Hmm... What if lovely_injector also exported a lua module allowing lua code to do its own patch applications

royal ether
#

basically it groups objects into the G.I tables and thats how it chooses what to render over what

#

i.e G.I.CARD is rendered over G.I.CARDAREA

#

if you look in Game:draw() it makes more sense

lament fjord
#

Okay, I think I have something I want to put down now because I don't want to forget it:

Keep around a (compiled) regex for determining if the ends of a span are word boundaries. If they are, apply whitespace padding to the ends of the patch if needed so it doesn't unintentionally merge into existing tokens

river panther
#

Trying to make a joker that swaps mult and chips not sure how to go about this though

shell tangle
#

Find where chips and mult are stored in G.GAME, store one value, let's say mult, current mult = current chips, then current chips = stored mult.

languid mirage
#

in Lua you can just
a, b = b, a

shell tangle
#

Or that. Neat.

wintry solar
#

There’s also a swap return that does it for you iirc

hushed cradle
#
local save_ref = Card.save
function Card:save()
    local ref_return = save_ref(self)
    ref_return.st_counter = self.st_counter
    return ref_return
end

local load_ref = Card.load
function Card:load(cardTable, other_card)
    self.st_counter = cardTable.st_counter
    load_ref(self, cardTable, other_card)
end
#

adding this to my code gives me the error at the top

#

i have no idea what the problem is

zealous glen
#

does replacing the hooks with function Card.functionname(self, args) work?

hushed cradle
#

ill try

#

no

hushed cradle
#

fixed my problem

#

basically part of the save table is text_drawable

#

which is a userdata value

#

but i think its only made when you create ui for smth

#

so i basically removed the ui to save it, then created ui for it again when its loaded

austere schooner
#

maybe a stupid question but
context.before is the context of before playing a hand and context.after is after, right

#

or do i need different contexts for that

brisk pond
#

before is when Space Joker levels up your hand, after is when Ice Cream loses 5 Chips

austere schooner
#

okay so i need the context for "after a hand is played and scored" I think

#

context.after_hand?

#

...is there just a big list of contexts anywhere

frosty dock
austere schooner
#

excellent

weak depot
#

this look good?

unkempt thicket
#

how would you check if a card does not have a modification (enhancement, edition, and seal)?

lusty epoch
#

Enhancement is something like if context.other_card.ability.effect == base
Edition i think do something like if not context.other_card.edition

#

Dunno about seal though

wooden nexus
#

I mean the deck idea is good but good grief

mellow sable
unkempt thicket
mellow sable
#

doesn't work on my 1 in 1e100 joker

#

😭

maiden phoenix
#

Is it me or the banana badge looks too bright on a debuffed cards compared to other ones

crisp coral
#

yea they didn't get hit with the debuff shader

mellow sable
#

The modded stickers are being rendered after the debuff shader

maiden phoenix
#

I have a dilema right now. I have a Joker that can be activated once per ante with an extra variable thats true/false when it can be activated and is blueprint compatible, thing is I dont know. Thing is I dont know how to prevent the blueprint card from activating the joker when its inactive since the extra variable doesn't exist in the blueprint card

frosty dock
#

though setting it to false after use might prevent blueprint from activating the ability

maiden phoenix
frosty dock
#

blueprint is in context.blueprint_card

maiden phoenix
#

Its trying to, I get an error saying "ability" doesnt exists

frosty dock
#

blueprint surely has ability

#

are you sure you're not using the center instead of the card?

maiden phoenix
#

This is what I have so far roughly:

if context.ending_shop
  if card.ability.extra.do_stuff then
      --- do stuff
      if not context.blueprint then
        card.ability.extra.do_stuff = false
      end
  end
  if context.end_of_round and boss and not context.blueprint then
    card.ability.extra.do_stuff = true
  end
end
#

in the calculate function (self,card,context) of SMODS.Joker

#

Oh wth I have no idea how but I fixed it uhm

wintry solar
#

@frosty dock is it possible for this to still display the base consumables and then have a modded consumables option at the bottom?

frosty dock
wintry solar
#

I just need to get used to the big orange button 😆

frosty dock
#

meanwhile I'm not so sure about the Other button

oblique gust
#

i love the big orange button it looks cute

crisp coral
#

lobcorp configs?

#

feat. reused houserules code

#

consistency with the mod ui height now

wintry solar
#

👀

edgy reef
#

I’m adding a stickers tab to it so D6 Sides won’t be lonely.

crisp coral
#

contracts might use that

fallen tendon
#

imm trying to add multiple use buttons to a consumable

#

how can i make them all do sommething diferent

#

just like sending a value into the use function

wintry solar
#

"you can only have one text input" they say

fallen tendon
#

im sorry you can put text input on a card??????

brisk pond
fallen tendon
#

i need a method of choosing a rank from 1-ace for a card

#

and i dont think making 14 use buttons is a good idea

#

so figuring out those text inputs could be a good idea

#

oh god every time i forget how unreadable the ui code is it comes back to haunt me

brisk pond
#

or with one that does +1

fallen tendon
#

i can definitely figure this out... definitely

#

also what the hell are even nodes lol

brisk pond
#

I just had this conversation

wintry solar
#

Please note that my guide in there is far from complete

brisk pond
#

pls send the code

fallen tendon
#

please spare me

#

this code is actually so painful

zealous glen
#

No one will be spared from UI

wintry solar
#

UI code isn't too bad as long as you don't use auto format on it

#

then it looks like shit

#

from this to this

#

đŸ€ź

fallen tendon
#

that looks better

#

also i am ANGRY

#

it refuses to give me a text box

wintry solar
mellow sable
#

Maybe you could show a pop-up menu when pressing the use button?

fallen tendon
zealous glen
fallen tendon
#

but like, how do you even make one

#

how do you initialize ui elements from within use_consumable

zealous glen
fallen tendon
zealous glen
#

Or selecting from hand

fallen tendon
#

the text inputs just refuse to work

wintry solar
#

ugh no the right one is awful for tracking the nesting of nodes

zealous glen
#

I think reworking mechanics for UI reasons can be interesting

wintry solar
#

what's your code alex?

zealous glen
#

You can tell by the number of tabs

#

And sublime allows you to close specific nodes

mellow sable
#

Also the UI in Cryptid is already pretty weird

zealous glen
#

Well, Lua tables

mellow sable
#

Like controller doesn’t work half the time

zealous glen
#

But you know what I mean

fallen tendon
#

this is the current state of the function im operating in

#

this is only for using it from packs

#

using it when its in slots is a whole nother ballpark

#

the second part of it is for code cards in general

#

they all work

zealous glen
#

Anyways, @wintry solar , do you know if the right formatting could be automated?

#

It would be so helpful

fallen tendon
#

im trying to add just a simple text input above the card

zealous glen
#

I have an adapted print function to see UI nodes that almost does that

wintry solar
#

I have a VSCode extension that'll format it that way, yeah

zealous glen
#

But I meant inside Sublime

#

Oh maybe I should use VSCode

#

What’s the extension

edgy reef
#

Y’all autoformat UI nodes?

wintry solar
#

Alex, can I see where you try to add the text input?

zealous glen
#

Unless I missed it

wintry solar
#

I don't remember if it does or not

zealous glen
#

@fallen tendon try printing the UI elements

fallen tendon
#

im thinking of just hooking in a new popup menu into the use function

#

i genuinely think it might be easier to just make a new ui box lol

wintry solar
#

what happens when you remove all those empty rows too?

zealous glen
wintry solar
#

just right click and press format document

#

or Shift+Alt+F

zealous glen
#

Oh I think there was a syntax error, that’s why it didn’t do anything

fallen tendon
#

so uhhh, slight problem

#

how do i call the create_UIBox functions properly?

wintry solar
#

Did it work now, Victin?

fallen tendon
#

yay it crashed meaning its finally doing something

#

im getting thhis message

#
    use = function(self, card, area, copier)
        self.HUD = UIBox{
            definition = create_UIBox_variable(),
            config = {align=('cc'), offset = {x=0,y=0},major = G.ROOM_ATTACH}
        }
    end
}

function create_UIBox_variable()
    G.E_MANAGER:add_event(Event({
        blockable = false,
        func = function()
          G.REFRESH_ALERTS = true
        return true
        end
      }))
    local t = create_UIBox_generic_options({contents = {
        UIBox_button({button = 'Done', label = {Done}, minw = 5, focus_args = {snap_to = true}})
    }})
end
#

seems that the issue is that something is missing a parent

rough furnace
#

Yeah my formatter makes some code worse

zealous glen
zealous glen
#

Is the return wrapped in curly braces?

wintry solar
#

I don't think you have a return at all

#

I think create_UIBox_variable needs to have return t

rough furnace
fallen tendon
#

oh god what did i do

wintry solar
#

I just format my code by hand (:

rough furnace
#

I mean my IDE is smart enough to do indenying 90℅ of the time so it's not a big deal

wintry solar
#

yeah

zealous glen
rough furnace
#

I mostly use it when moving code around or particularly nasty code

fallen tendon
#

YESSSSSSS

#

NOW I JUST NEED IT TO BE AN ACTUAL POPUP AND NOW WHATEVER THE HELL THIS IS

rough furnace
zealous glen
fallen tendon
#

i just have vsync off and i have a pretty good laptop

zealous glen
wintry solar
fallen tendon
#

something like that

#

im doing some testing rn

rough furnace
#

Sorry I got a new phone not used to the keyboard fully yet

#

%

zealous glen
rough furnace
#

Idk

#

Care of

zealous glen
#

That’s what I found too

wintry solar
#

what a bizarrely niche symbol to put on a keyboard

#

@fallen tendon you could try throwing a text_input in there now

fallen tendon
#

ik

#

the probles is i cant get it to not be nearly the entire screen'

rough furnace
#

I mean it is in the sort of niche page of keys.

fallen tendon
#

or get the butttons to display

wintry solar
#

Ooo I have this one ‰

#

I don't think you want to use create_UIBox_generic_options

fallen tendon
#

oooh im sorta getting there

zealous glen
zealous glen
#

Betmma had activatable objects too

fallen tendon
#

No im making an actual popup

#

managed to get it to exist

#

it just needs to be not there

wintry solar
#

try putting instance_type = "POPUP" in your config

#

note: I haven't tested how this works properly

fallen tendon
wintry solar
#

I think it'll bring it to the front

zealous glen
wintry solar
#

yeah I saw that

#

I just haven't had chance to try it out

fallen tendon
#

its in a slightly better spot

#

but the popup thing did not work

#

oh that was because i accidentally put instacne

#

so, how do i define a function to be executed by a button

wintry solar
#

button = "function_name"

#

and the fucntion needs to be in G.FUNCS

fallen tendon
#

oh ok

fallen tendon
#

mission failed successfully

#

i have no clue whats going on here

wintry solar
#

code pls

fallen tendon
wintry solar
#

and how do you want it to look?

fallen tendon
#

i want it to be either in a column or a row

#

just a positioning where the text field isnt outside of the window

wintry solar
#

wrap each in a {n=G.UIT.C, nodes = {*INSERT HERE*}}

fallen tendon
#

also weird thing, the button doesnt appear until you click the text box

wintry solar
#

that is strange

#

I've found base text_inputs very strange tbh

frosty dock
#

they are

wintry solar
#

I just need to convert my changes into a lovely patch though and then at least you can ahve more than one

fallen tendon
#

oh also how do you close a window

wintry solar
#

put 'exit_overlay_menu' as the function of a button somewhere

#

or press escape

#

or call G.FUNCS.exit_overlay_menu() somewhere

fallen tendon
wintry solar
#

I built my own button

fallen tendon
#

hhhhh so now when i press the apply button the card switches rank, but it doesnt exit the menu

#
G.FUNCS.variable_apply = function()
    if G.ENTERED_RANK == "1" or G.ENTERED_RANK == "2" or G.ENTERED_RANK == "3" or G.ENTERED_RANK == "4" or G.ENTERED_RANK == "5" or G.ENTERED_RANK == "6" or G.ENTERED_RANK == "7" or G.ENTERED_RANK == "8" or G.ENTERED_RANK == "9" or G.ENTERED_RANK == "10" or G.ENTERED_RANK == "J" or G.ENTERED_RANK == "Q" or G.ENTERED_RANK == "K" or G.ENTERED_RANK == "A" then
        G.FUNCS.exit_overlay_menu()
        G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function()
            play_sound('tarot1')
            return true end }))
        for i=1, #G.hand.highlighted do
            local percent = 1.15 - (i-0.999)/(#G.hand.highlighted-0.998)*0.3
            G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.15,func = function() G.hand.highlighted[i]:flip();play_sound('card1', percent);G.hand.highlighted[i]:juice_up(0.3, 0.3);return true end }))
        end
        delay(0.2)
        for i=1, #G.hand.highlighted do
            G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.1,func = function()
                local card = G.hand.highlighted[i]
                local suit_prefix = string.sub(card.base.suit, 1, 1)..'_'
                local rank_suffix = G.ENTERED_RANK
                if rank_suffix == 10 then rank_suffix = 'T'
                end
                card:set_base(G.P_CARDS[suit_prefix..rank_suffix])
                return true end }))
        end  
        for i=1, #G.hand.highlighted do
            local percent = 0.85 + (i-0.999)/(#G.hand.highlighted-0.998)*0.3
            G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.15,func = function() G.hand.highlighted[i]:flip();play_sound('tarot2', percent, 0.6);G.hand.highlighted[i]:juice_up(0.3, 0.3);return true end }))
        end
        G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2,func = function() G.hand:unhighlight_all(); return true end }))
        delay(0.5)
    end
end
frosty dock
#

call G.FUNCS.exit_overlay_menu() at the end

fallen tendon
#

ok

#

can i still do it in the if statement?

#

cuz i dont want to completely waste the consumable if you type in an invalid string

frosty dock
#

yeah it just won't exit if you do that

#

maybe add an alert or something that it's invalid

fallen tendon
#

ok

#

actually what if i put in a premature return

#

the function is still at the top scope

#

actually uhhhh changing it still did nothing

#

or not, i didnt save it lol

#

ok it still doesnt work

#

fun

brisk pond
#

of course I have no idea what is going on

fallen tendon
#

YES

#

IT WORKS

brisk pond
brisk pond
#

video of demonstration and code. now.

#

please đŸ„ș

wintry solar
brisk pond
#

this is the code for that row

wintry solar
#

what's your entire code for the config tab?

brisk pond
wintry solar
#

what button are you pressing in your clip?

brisk pond
fallen tendon
#

it uses the rank suffixes

wintry solar
fallen tendon
#

so it goes 2-9, T, J, Q, K, A

wintry solar
fallen tendon
wintry solar
#

alex pls

brisk pond
fallen tendon
#

it lets you type more than one character

wintry solar
#

I was talking to Cerlo 😆

fallen tendon
#

oh ok

brisk pond
#

đŸ€Ł

wintry solar
#

I know how to type a J

#

it's cool though

#

how did you end up making it close?

#

oh

#

you just remove the node?

fallen tendon
#

turns out removing the overlay doesnt work if it isnt an overlay

frosty dock
#

fun

fallen tendon
#

and if it was an overlay it still doesnt work because the game is frozen

brisk pond
# brisk pond

maybe it's something wrong for ref_table and ref_value

wintry solar
#

this dynamic text scaling is pretty neat

brisk pond
#

the problem is if I click "Backspace" the text continues to shrink

brisk pond
wintry solar
#

ah figured it out

#

change your maxh and maxw in the root node to minh and minw

night pagoda
#

I'm trying to inject into misc_functions.lua, but it doesn't work 90% of the time, what am I doing wrong???

wintry solar
#

needs full line

night pagoda
#

oof

#

still nothing

wintry solar
#

does SMODS hit this before you do?

night pagoda
#

don't think so, double checked

#

will try remove space

#

now it works

#

💀

brisk pond
#

but just when I do one text input

#

when I do two, the first isn't loaded

wintry solar
#

yeah

#

only I can do two

#

🙃

frosty dock
#

yeah multiple text inputs on vanilla create_text_input doesn't work

brisk pond
wintry solar
#

aure would you prefer overriding them or injecting to fix it?

brisk pond
#

please, teach me the Way

frosty dock
#

it's fine to override if that's cleaner

wintry solar
#

nah it's not too bad

#

just plonking some different id values in there

frosty dock
#

yeah that should be alright to inject

fallen tendon
brisk pond
#

?

fallen tendon
brisk pond
#

because you can input any number

languid mirage
frosty dock
#

I might add a config option for the lowered precision

languid mirage
#

that's fine

#

I mostly added it for money

#

because I cba changing the scale_number function

wintry solar
#

huh

#

text_inputs turn a 0 into a o and need to do shift+0 to get 0

frosty dock
#

probs it's fine to leave since the extra precision is usually negligible

#

idk

languid mirage
#

because in font 0 == o

#

so thunk just decided to auto convert it (mostly for seeds I think)

#

didnt know about shift+0 tho

frosty dock
#

huh that's weird

languid mirage
frosty dock
#

I'll have to agree

zealous glen
wintry solar
#

okay, let me see what other lovely patches I have that should be making their way into SMODS

zealous glen
#

I need to work on some to make some contributions still v_v

frosty dock
#

work on any of the open issues is appreciated

zealous glen
#

I was thinking of new features :<

frosty dock
#

ofc that's also welcome

zealous glen
#

Like bonus mult for cards and bonus chips and mult for jokers

#

Among other things

#

I wanted to add a new object to allow easily adding new calculable CardAreas but the Object type confuses me

frosty dock
#

object type?

wintry solar
#

I have a patch that allows turning the floating question mark off for undiscovered sprites, throw it in atlas.toml?

frosty dock
#

sure

#

could make it a setting on UndiscoveredSprites whether the question mark should be there or not

wintry solar
#

yeah it is

#

just needs a patch for where it's drawn to check the value

fallen tendon
#

Then you can input any number from 1-100

#

And if you have 100 retriggers then what are you doing with your life

wintry solar
#

or just wait for the PR and use inputs!

brisk pond
wintry solar
#

just checking it still works

zealous glen
frosty dock
#

ah

zealous glen
#

Maybe it’s GameObject

#

I forget

frosty dock
#

yeah the SMODS type is GameObject

#

which extends off Object itself

wintry solar
#

the PR is there 🎉

zealous glen
frosty dock
#

the same way Steamodded object types do, branching off whatever works best (probably GameObject or Center most of the time)

frosty dock
wintry solar
#

man I wish git had a better way to collaborate on the wiki

frosty dock
#

it's possible to set it up as a separate repo apparently

wintry solar
#

also all the smods tabs are now blue

#

🙃

frosty dock
#

too much red on that page tbh

zealous glen
#

I can gauge how to define required keywords from the existing GameObjects

#

I think

#

But I’m not sure I understand how one would go about defining a new extension of GameObject correctly

languid mirage
#

you can look at how other gameobjects are specified đŸ€”

#

well, it depends I guess

#

because there's inject and all that

frosty dock
#

you pretty much have required keywords, default values, obj_table (holds objects indexed by key), obj_buffer (holds object keys in order) and whatever functions need to be extended

languid mirage
#

and dont forget inject function that is used to handle all new gameobjects

brisk pond
languid mirage
#

also that comment is kinda outdated

#

because it's not just centers

compact idol
#

decided to look at cryptid for starting out with balatro mod dev and it turns out that was the exact wrong move lmao, didn't realize steamodded had a function for adding jokers so I set mine up like cryptid's and then couldn't figure out how to inject them

languid mirage
#

cryptid does the same, but because it does it in batches, it's not the best entry example, yeah

#

in case you didn't see this yet

wintry solar
tepid crow
#

cryptid is probably a bit too complicated for a "starting look" lol

compact idol
#

also doesn't help that I've never used lua before

frosty dock
#

yeah cryptid's wrapper isn't the easiest to wrap your head around for what's actually happening

wintry solar
languid mirage
#

I never used lua before either balatrojoker

wintry solar
#

id = blabla

languid mirage
#

wasn't the hardest thing to learn with so much source code examples

frosty dock
#

same here

compact idol
#

yeah it seems pretty intuitive to start with

tepid crow
#

I've used lua once before, in a minecraft mod that had robots >:)

brisk pond
#

the 0 to o?

wintry solar
#

that's just how the game handles keyboard inputs

#

do shift+0

zealous glen
zealous glen
#

Like the list of PokerHands

#

I think every GameObject has a list of all its instances actually

#

Which makes me think the type GameObject should do it instead of it being user-made

frosty dock
#

yeah SMODS.PokerHands and similar tables are just shortcuts for convenience

#

SMODS.PokerHand.obj_table is identical

#

so yeah it kinda does that

zealous glen
#

Okay that makes more sense

#

Any style guidelines?

edgy reef
#

We should probably clean up the lovely patches for style purposes.

frosty dock
#

inject shouldn't have side effects that stack when reapplied, but prototypes are generally kinda inconsistent rn and we might do something about it

zealous glen
#

The main object I want to add is a helper object to extend calculation

#

Such that users could register a type and a CardArea to have SMODS automatically iterate over instances in the CardArea and call calculate

edgy reef
#

I think better_calc has stuff relating to that but I haven’t looked at the code too much.

#

Speaking of CardArea, something to ease handling of it would be nice.

#

I don’t think we need API for it as CardArea already has the functions and properties you’d want, but there’s loads of hardcoded parts that need to be messed with to make custom ones.

#

And said hardcoding fixes could screw with other mods that also try to fix it for their CardArea.

frosty dock
#

yeah that's fine

#

break 'em

brisk pond
#

it says that current_mod is a nil value

wintry solar
#

yes

#

you have to save it in top scope

brisk pond
#

?

wintry solar
#

just delete that function you've added

#

the update_config one

brisk pond
#

the code is now using current_mod.config.MaxRedSeals and it is still nil

#

I tried config.MaxRedSeals but it is still nil

frosty dock
#

you should save a local reference to config at top scope in your mod

wintry solar
#

oh, they're not in your main file

#

is that the reason?

#

local values in a file that's loaded in?

brisk pond
#

ok now it doesn't crash

#

still, when I change the value in the config menu, it doesn't update the variable

tepid crow
#

does it work when you don't seperate the files?

frosty dock
#

as long as you change the value in <mod>.config, steamodded will save to file when exiting the mods menu

#

(not to config.lua though, that stays unchanged and acts as a default)

brisk pond
#

where do I add that line of code?

#

I have to get the input from the input box

wintry solar
#

I think if you put everything in one file it'll be fine

brisk pond
#

I tried merging the main file and config_tab.lua

wintry solar
#

let's see what you have now then

brisk pond
wintry solar
#

well yeah, you're fixing the values as soon as you load the config

brisk pond
#

that's what the function was for

#

updating the config values

wintry solar
#

just put the tonumber(config.RedSealsPerCard) wherever you need it in your code

brisk pond
wintry solar
#

well then you changed something you shouldn't have done

brisk pond
#

found the problem

brisk pond
#

if I keep them, the game has problems

wintry solar
#

you need the top one...

#

that's how you access your config

brisk pond
#

i'm trying a solution

wintry solar
#

but I've given you the solution?

brisk pond
#

your solution doesn't work

#

when I access config, it crashes

#

sending you the file and the crash report

#

line 109 is this one if card.ability.SRSreps > tonumber(config.MaxRedSeals) and tonumber(config.MaxRedSeals) >= 0 then

shell tangle
#

Don't think it'd be it, but what happens if you delete the .jkr that has the configs saved and try again?

brisk pond
#

from where?

shell tangle
#

Where your profiles are located in appdata, there's a new folder besides 1, 2, 3, and Mods called config.

wintry solar
#

What are the values in the config file?

brisk pond
#

but when i start the game they are 5 and 5

wintry solar
#

No not that one

brisk pond
#

as per the last time I updated those

wintry solar
#

The one someone just mentioned

brisk pond
#
return {
    ["SRS_MaxRedSeals"] = 15,
    ["disable_collapse"] = false,
    ["RedSealsPerCard"] = "5",
    ["MaxRedSeals"] = "6",
    ["RedSealsForCard"] = 10,
    ["hide_empty"] = false,
    ["hide_by_default"] = false,
    ["default_rows"] = {
        ["SRS_RedSealsForCard"] = 1,
        ["SRS_MaxRedSeals"] = -1,
        ["modifiers"] = true,
    },
    ["enabled"] = true,
    ["SRS_RedSealsForCard"] = 10,
    ["small_rows"] = {
        ["reminder"] = false,
        ["extra"] = false,
        ["modifiers"] = true,
    },
    ["reload"] = false,
}```
#

wait a sec

#

no I got nothing

wintry solar
#

Try deleting it

brisk pond
#

I'll delete this and retry

wintry solar
#

I don’t think that’s the problem but this config is all wrong anyway

#

Can you delete the bit where it checks it’s above 0?

brisk pond
#

it works until I put a 0

#

like 10, 20

wintry solar
#

Every other number works?

brisk pond
#

yeah

shell tangle
#

Nice lucky guess, I suppose.

brisk pond
#

maybe it's the fact that 0 = O

#

and tonumber() has problems

wintry solar
#

How are you typing zero?

brisk pond
#

Shift + Zero

wintry solar
#

Oh

frosty dock
#

just use string.gsub and replace the O with 0

wintry solar
#

Shift + zero must be capital

#

Why does it swap 0 for o?

mellow sable
#

looks same in font

frosty dock
#

seeds

mellow sable
#

what's funny is neither of them can appear in natural seeds

brisk pond
#

so instead of tonumber(config.RedSealsPerCard) i do tonumber(string.gsub(config.RedSealsPerCard),"O",0)?

mellow sable
#

but in seeded runs it matters

frosty dock
#

these brackets are off

#

but yeah

#

actually no

#

these can also be numbers

#

what

#

just do the number parsing on the input

wintry solar
#

That is the input

frosty dock
#

maybe I'm confused because it's on the input

#

I'd still be worried for types

brisk pond
frosty dock
#

like I said, your brackets are wrong

brisk pond
#

card.ability.SRSreps = tonumber(string.gsub(config.RedSealsPerCard,"O","0"))

#

I read that

frosty dock
#

oh i see

#

card.ability.SRSreps = tonumber((string.gsub(config.RedSealsPerCard,"O","0")))

wintry solar
#

I’d throw an :upper on there too

frosty dock
#

the extra parentheses should cast it to one return value

brisk pond
#

the solution is: just add some more parentheses lol

frosty dock
#

yeah that's stupid

#

I didn't know about that behavior before reading it in lua docs somewhat randomly

wintry solar
#

Why does the extended_corpus contain 0 and ) if it changes them before it ever reaches that point anyway

frosty dock
#

idk

#

thunk moment

wintry solar
#

Maybe there needs to be a number_input instead, this workaround is quite unintuitive

#

I don’t think many people will link their zeros being converted to Os

#

In fact it could just be an argument on the text input to skip over that exchange

brisk pond
#

I totally think it so too

brisk pond
tepid crow
#

can lovely not handle random {s?

#

(lovely regex, specifically)

rough furnace
#

are you escaping them

crisp coral
#

i think Archipelago fixed the text input to input the player slot and whatnot

#

(Archipelago as in, the mod BalatroAP)

frosty dock
tepid crow
#

I know, but from some quick testing, I don't need to escape it in js, python or perl

#

oh wow, it's rust specific actually

#

and php, js, python, go, C# dont care

#

neat

wintry solar
crisp coral
#

yea it has 3 or 4 idr

#

address/port, slot name, password

wintry solar
#

Yeah I see it now

#

It does what I was planning for 0 slightly differently but it is functionally the same

frosty dock
tepid crow
#

Haha, I might've exaggerated that because of my annoyance with my regex testing.
Most languages seem to consider the { (and }) as normal text when it's not valid/not matching?
I tested my regex using both using python and js, and both compiled and matched without issue

#

Seems like at least java and rust don't do that, and error out when not valid and not escaped

brisk pond
#

I wanted them to be aligned vertically

#

but the gold text and the black row are aligned horizontally

wintry solar
#

You need to put the text inside its own row

brisk pond
#

I tried and it ended very badly

#

maybe the text is too long

#

no that isn't the problem

wintry solar
#

What did you change it to?

brisk pond
wintry solar
#

Hold G and press A and see which node is stretching the display

brisk pond
#

it's done

#

it now works

crisp coral
primal mirage
#

Hi, is there a good "getting started" for modding Balatro?

tepid crow
#

also, nice to see bojack

primal mirage
#

Seems like a decent doc, @tepid crow thank you!

compact idol
#

how does #num# in the loc_txt of the modded jokers actually work? I can tell it's referencing the config array by index, but I can't tell why it works through an extra layer of array or why it isn't working for me

#

it just says +ERROR in the specified boxes ingame for me

mellow sable
#

scary UI box

unkempt thicket
#

how do you check if you have a certain joker?

mellow sable
#

i use next(find_joker()) but there's definitely something more elegant

crisp coral
#

that's the way thunk does it so

#

shrug

mellow sable
#

i think steamodded added something better i just forgot what that was

edgy reef
#

SMODS.find_card

crisp coral
#

SMODS.

#

yea

#

that just takes keys instead of names

rough furnace
#

Here's the one's I got planned rn

#

if anyone things of some other good ones, let me know

mellow sable
#

one to spawn a card by id?

#

like spawn blueprint or something?

rough furnace
#

i can add it to a list to see

#

not sure how difficult it would be

#

actually, I do want you to be able to bind to keys and having a spawn blueprint key would be handy

languid mirage
#

if you do rank then maybe also do suit

#

free rerolls can be achieved with infinite money so I dont think that's necessary

#

spawn tag

#

probably is a good command

#

because I dont think debug mod has hotkey for that

#

set probability

#

set hand size?

#

generate & open pack

crisp coral
#

christ i fucking hate this sound manager thread thing

night pagoda
#

I'm going insane - can't find the cause why balatro just can't find the card:juice_up function now

#

it is literally right here (screenshot from the dumps)

crisp coral
#

i have manage to crash stacktraceplus

#

jesus christ

languid mirage
night pagoda
languid mirage
#

well you can add a debug function that can dump you what's in the card

#

I mean

#

shouldn't that already be displayed in stacktrace

#

I dont know

night pagoda
#

yeah, will tinker around

#

thanks for the ideas tho

languid mirage
#

you can go up in stack trace and probably see where this card_eval_status_text call is from

#

might also be helpful

night pagoda
#

found the issue! all good

crisp coral
#

i'm trying to make a new sound manager that runs parallel with the ingame/cryptid sound manager but i have no idea how to debug it

#

it... probably works? because when i load the sounds as smods objects then both the normal music and my music play at once

#

this sucks so much

#

i wonder if a sound manager rewrite is plausible... it's impossible to get a list of sounds via smods tho

#

im going insane

frosty dock
#

huh

crisp coral
#

hey aure can you rewrite the sound manager đŸ„°

frosty dock
#

uh what do you need out of it exactly?

crisp coral
#

playing background music, because Cryptid completely overrides it

crisp coral
#

i think i'm dumb

#

i could've sworn it broke tf

crisp coral
#

this is offcentered and 😭

frosty dock
#

ugh

rough furnace
rough furnace
crisp coral
#

load an invalid file with nfs

rough furnace
#

I mean the crawh handler doesn't seem to have crashed

#

Or does it crasg right after that?

crisp coral
#

eh it doesn't matter anymore

languid mirage
mellow sable
crisp coral
#

not gonna bother with that anymore

#

opinions?

frosty dock
mellow sable
#

I use it for synced, easing music like with the Program Packs

rough furnace
mellow sable
#

SMODS Music library always starts from the beginning of the track and doesn’t fade in

frosty dock
#

hm i should be able to add that

mellow sable
#

Would be good to allow for both

rough furnace
mellow sable
#

Yeah then I can remove all the sound_manager.lua jankiness

frosty dock
#

can you point me to the relevant code for syncing in cryptid?

mellow sable
#

literally just sound_manager.lua

#

Which is the vanilla sound manager but slightly modified to load from Cryptid’s files

#

It also automatically pitches down which theoretically you shouldn’t need to do except for the vanilla music

crisp coral
#

oh yeah the default smods music stuff doesn't pitch down the music when game over'd

wintry solar
crisp coral
#

that one is especially annoying because my stuff are bosses

frosty dock
#

alright I think the current sound API just bypasses too much of the sound manager, I need to integrate it better

crisp coral
#

đŸ„€

wintry solar
#

that is a lot of spacers

rough furnace
#

Maybe make it red so its very glanceable?

wintry solar
#

oh good shout

zealous glen
#

Also I don’t particularly like the floating, dark “disabled” text

wintry solar
#

the entire object

zealous glen
#

The Green Balloons?

#

Or, more accurately, the Bunch of Green Balloons?

wintry solar
#

so they won't spawn

#

in theory

zealous glen
#

As an user, I’d like to know what the items do before enabling them

#

If I enable then change my mind I’d have to go back to the config

wintry solar
#

hmmm yeah

#

I'll find a way to display the text still

crisp coral
#

oh in theory now that we have configs i can move my abnormality unlocks to that

#

saving configs on demand is SMODS:save_mod_config(SMODS.current_mod) right

wintry solar
#

SMODS.save_mod_config(mod_reference)

#

current_mod will be nil

crisp coral
#

what is mod_reference

#

SMODS.Mods.LobotomyCorp?

restive osprey
#

is there a tutorial on balatro modding? I'm a beginner coder that loves making joker ideas so to see them in the game would be wonderful

#

also it will help me in my comp sci career

crisp coral
wintry solar
#

wherever you've saved SMODS.current_mod locally

restive osprey
crisp coral
#

and of course, extract the game executable for the source code and look at other people's codes

crisp coral
#

oh hm. is it actually SMODS.save_mod_config instead of SMODS:save_mod_config

wintry solar
#

yeah it's a dot

crisp coral
#

it isss

#

fuck

wintry solar
#

also where do you save SMODS.current_mod originally

crisp coral
#

screw you SMODS.save_all_config

shell tangle
restive osprey
shell tangle
#

Absolutely no need, it's meant to go into the Steamodded example mods eventually.

wintry solar
#

oh seals have so much missing functionality D:

restive osprey
#

it's in VERY early development since I came up with the idea today and we're making ideas for jokers

#

i have 2 mod ideas which i could mash into one
one is a mod where it makes a bunch of jokers based on the blinds in the game (including 5 new legendaries from a new the soul like spectral card that are based on the final boss blinds)
and another is a mod that adds an upgrade spectral card, which makes upgraded versions of all the jokers (best idea but most work)

#

that along with a bunch of other unique jokers
I'm thinking i name upgraded chicot "cheat code" for the funny

mellow sable
#

Second one sounds cool too

restive osprey
#

some funny ideas I've come up with
the legendary boss joker for cerulean bell is called ring for service, and it activates diamond cards again and makes a bell noise when it does. Its upgraded version is a meme soundboard that plays random meme sound effects on every repeat it does on a diamond card
the hack actually has 2 upgrades, hack'd the system, where he got famous off plagiarism and didn't get caught, and laughing stock, where the card art is just the hack reading a callout post about him on his computer

zealous glen
#

@wintry solar I'm trying out VSCode for Lua. How can I make the globals defined by the game, and thus not my mod, not show up as errors to the Lua extension? (Besides manually marking each of them)

wintry solar
#

I believe if you add the folder of the game code to your workspace it'll automatically find them

zealous glen
#

Can I do it without adding the folder to my mod's folder?

wintry solar
#

yes

#

File>Add Folder to Workspace

zealous glen
#

It's still throwing some errors

#

Including the game itself

wintry solar
#

what sort of things are being called as errors?

wintry solar
#

huh

crisp coral
#

add the balatro source or lovely dump into the workspace

wintry solar
#

did you add ALL of the source?

night pagoda
#

I have both added yet it still does that

#

I just ignore it

crisp coral
#

it doesnt do that for me so shrug

zealous glen
#

I had already done so

wintry solar
#

tried a restart?

crisp coral
#

for love you might need the love2d support extension

zealous glen
#

The Lua extension said it supported love but I can try

#

what is it

wintry solar
#

I don't have a love extension

crisp coral
#

oh idk then

#

i guess you only need love2d installed?

wintry solar
#

any ideas on how to disable used consumables moving to the middle of the screen?

restive osprey
# restive osprey some funny ideas I've come up with the legendary boss joker for cerulean bell is...

problems with this
I'm not skilled enough in coding, but i want coding experience
I'm not skilled enough in art for making over 150 new joker designs, but i like making art so that's ok if i can at the very least find a mentor to clean up my art
BIG PROBLEM: I have next to no dedication to a single thing for more than a week at most, especially if it bores me

Solution
I become the ideas maker (along with my friend in the server), overall manager, and a helper in all the different things we need, and hope a people like my ideas enough to work with my incompetent ass
or i just learn a bunch of time saving loopholes for all this stuff

fallen tendon
#

but its probably now what you are looking for

restive osprey
#

that being said, I want to post the google doc with the ideas somewhere. where do i do it?

#

oh wait modding forum

#

I'm a dumbass

wintry solar
zealous glen
#

what the localthunk doin'

crisp coral
#

lmao?

zealous glen
#

I wonder if the reason AnimatedSprite doesn't work for Cards by default is because of thunk's spagetthi code

wintry solar
#

It wouldn’t surprise me

zealous glen
frosty dock
mellow sable
#

And because doing it manually works I’ve kinda rolled with it (literally)

zealous glen
mellow sable
#

For Aura it wouldn’t make sense because it needs a lot of customizability. And then Jimball is Jimball

languid mirage
zealous glen
zealous glen
#

Yes but what’s the spaghetti

crisp coral
#

all of it

languid mirage
#

everyone writes shit code so balatrojoker

zealous glen
zealous glen
languid mirage
#

at least death will be quick balatrojoker