#💻・modding-dev

1 messages · Page 42 of 1

brisk pond
#

Now only 3 left

zealous glen
#

I think there's an offset parameter which is often set to be negative (moving it up)

river panther
#

I am porting my old 0.9.8 code over to 1.0.0. Anybody have a basic mod that just adds jokers a challenges and a testing deck that I could use for reference

brisk pond
zealous glen
#

Does anyone know where Boss Blind tooltips in the collection are generated?

brisk pond
#

huge thanks to all you people

zealous glen
#

Congrats on the release!

hushed cradle
#

anyone know if theres documentation for adding custom unlock requirements for jokers and vouchers and adding your own hands (secret ones) along with planet cards that only show up once youve played the hand?

frosty dock
#

for unlocks, there's a check_for_unlock function you can put on your objects that gets passed the arguments from the game's check_for_unlock global function, you should read up on that one in the game's source to see how it works - you just need to return true in your method to unlock the card

zealous glen
hushed cradle
#

thank you

zealous glen
frosty dock
#

Poker hand API is still missing docs, you can look at the source code for that one. Use visible = false to make a hand secret

#

for planet cards, the corresponding property is softlock = true

hushed cradle
#

thank you lots

#

one thing im not too keen on in balatro is that when youre going for big scoring runs theres basically 2 builds you can go for

#

or flush house w trib ig

#

so i wanna try and make it so you can build around different hands

zealous glen
#

@frosty dock can I add a new tooltip directly to a Joker's info_queue?

hushed cradle
#

thoughts?

#

i did some maths and its fairly similar to playing 5 cards all with x2

zealous glen
frosty dock
#

that sounds like a use for a generate_ui function

zealous glen
hushed cradle
#

do you think itd be better if it was a hand of three of the same rank?

#

i liked 7 cos of the jackpot thing

#

but any rank would work ig

zealous glen
hushed cradle
#

i just want you to be able to build around more hands in endless

zealous glen
#

The default implementation of this function acts as a wrapper of loc_vars. For advanced UI implementations, define this function directly.

hushed cradle
#

cool

frosty dock
#

generate_ui is passed full_UI_table, which you could insert UI elements into directly - tooltips live in full_UI_table.info

hushed cradle
#

ill get that changed

frosty dock
#

do note that this will happen before anything in info_queue is processed

zealous glen
#

Although I'm asking because I'm adding a Blind tooltip to a Joker

frosty dock
#

each entry into info_queue causes a subordinate call of generate_card_ui, surely you could patch that function to allow passing through a UI element directly if it needs to be in order

zealous glen
#
local info_tip_from_rows_ref = info_tip_from_rows
function info_tip_from_rows(desc_nodes, name)
    if name == "cr_vic_credits" then
        local t = {}
        for k, v in ipairs(desc_nodes) do
          t[#t+1] = {n=G.UIT.R, config={align = "cm"}, nodes=v}
        end
        return {n=G.UIT.R, config={align = "cm", colour = darken(G.C.GREY, 0.15), r = 0.1}, nodes={
          {n=G.UIT.R, config={align = "tm", minh = 0.36, padding = 0.03}, nodes={{n=G.UIT.T, config={text = localize('k_vic_credits'), scale = 0.32, colour = G.C.UI.TEXT_LIGHT}}}},
          {n=G.UIT.R, config={align = "cm", minw = 1.5, minh = 0.4, r = 0.1, padding = 0.05, colour = lighten(G.C.GREY, 0.15), emboss = 0.05}, nodes={{n=G.UIT.R, config={align = "cm", padding = 0.03}, nodes=t}}}
        }}
    else
        return info_tip_from_rows_ref(desc_nodes, name)
    end
end
hushed cradle
#

is this clear enough to understand easily?

#

should i highlight the 'only'

river panther
#

so three of a kind gives over x27 mult?

hushed cradle
#

yeah

#

hmm

river panther
#

oh

hushed cradle
#

wait i think

#

i should

river panther
#

seems broken

hushed cradle
#

make it like idol

#

where its a specific rank maybe?

#

yeah ill make it specific card and suit

#

to balance

river panther
#

Feels very niche

hushed cradle
#

i want to make all hands viable for endless

#

my quick (and probably wrong) maths says that its about on par with 5 cards each x2

river panther
#

Maybe do probability to fit the theme. Something like If played hand is 3 of a kind each card has 1 in 3 chance to give 3 mult

#

sorry X3 mult

hushed cradle
#

ill see

#

i dont want it to be like bloodstone tho

#

where its unreliable

river panther
#

Bloodstone does troll sometimes

hushed cradle
#

i hate bloodstone

#

spades >>

river panther
#

You could do a scaling joker that has probability. Something like X1 mult 1 in 3 chance to increase by x0.5 when a three of a kind is played

#

So you always hit x mult but gotta scale it early

hushed cradle
#

thats not really viable for endless tho

river panther
#

Ohhh I see

hushed cradle
#

i think making it a specific card from your deck, and having it as a rare is fairly balanced

#

and then you can play 3 of a kind for high scores

river panther
#

cook it up

hushed cradle
#

or the new hand i wanna add, flush 3 💀

hushed cradle
#

tryna make it so you can play whatever hand you like and still go big endless

river panther
#

I thought of a nice idea

hushed cradle
#

yea

river panther
#

Pairs retrigger all cards held in hand

#

it could be a common

hushed cradle
#

that would be cool

river panther
#

So its similar to mime but for pairs and stacks with it

hushed cradle
#

damn actually i really like that

#

can i use it?

river panther
#

Could be called like double vision or something

#

yeah go ahead

hushed cradle
#

cheers

#

i think im gonna make a post in the modding bit about this

#

for the pairs retriggering

#

do you think having it only retrigger 2s would work?

#

i dont think you should be able to use it with baron

#

prefer the idea of it being separate

river panther
#

Well the whole idea is its mime again, which is uncommon BUT there is a condition making it only work when a pair is played. I think this alone is good enough to set them apart. If you make it only 2s then you are limiting yourself for it being used only for a wee joker steel deck

#

But its up to you

hushed cradle
#

i reckon youre right

#

just a bit concerned cos there would be no real reason to pick it over baron + mime

#

cos you can hold 1 more card

#

maybe it could trigger card held in hands effects that are on the pair you play

#

like you play 2 steel cards and they each give 1.5

#

then the steel in your hand gives 1.5 too

river panther
#

okay you have 1 less card because your playing a pair BUT you are retrigging all your other cards held in hand. Of course mime is objectively better but your joker would be common making it more likely to show up

#

its essentially a debuffed mime

#

or nerfed i should say

hushed cradle
#

thats true but then youd pivot to high card for endless

#

instead of sticking with pairs

#

maybe have it trigger gold and steel effects on the pair you play

#

but not baron

#

so if i play 2 steel kings

#

i get the steel bonus

river panther
#

alright alright I got ANOTHER idea then scrap the old one

hushed cradle
#

but not the baron bonus

#

hit me w it

river panther
#

So right now you want all hands to be viable yes

hushed cradle
#

yea

river panther
#

The main issue with endless is you end up limited by your handsize

hushed cradle
#

yea

river panther
#

This card may be broken but i think its a sick idea and may code it myself or some variation of it

#

every 9 consecutive pairs played in a row increase handsize by +1 permanately

#

you can adjust the number of consecutive pairs accordingly

hushed cradle
#

that is pretty strong

#

maybe it should increment every time you do it

#

so 9 pairs, 12 pairs, 15 pairs

river panther
#

good idea

hushed cradle
#

i think that wouldnt be too strong

#

just up there with idol and baron mime

river panther
#

What makes it balanced is the fact it needs to be consecutive. Could get screwed with a bad draw or discards not hiting or just player the blind with no discards

#

Or the blind with no consecutive hand types

hushed cradle
#

yeah

#

its def an interesting idea

#

i might try implement both ideas

#

and play around a bit and see what its like

river panther
#

But fuck it make a broken joker. Id rather have a broken joker than an underpowered joker so people would use it

hushed cradle
#

hell yeah

#

endless scales too quick lol

#

so far ive got a joker that retriggers aces and one that gives 9 mult for every square rank card played

#

ace 4 and 9

#

actually im gonna make a post about this in the modding thing

#

cos i feel bad for filling up this chat w stuff

river panther
#

may be a good idea

zealous glen
#

Which is very excessive

hushed cradle
#

its gonna be a specific card like idol

#

otherwise its way too broken

zealous glen
#

Even if it's a specific card it's already broken

#

For comparison

hushed cradle
#

2^5 is x32

#

i think

#

so its on par with flush five idol

#

i think

zealous glen
#

X6 Mult if played hand is High Card containing a scoring Ace of Spades
was too much in thunk's opinion

#

Or maybe it was X13, I forget

zealous glen
#

And The Trio is X3 IIRC

hushed cradle
#

i want it to be as strong as flush five idol so its viable in endless

#

cos you can only play 3 cards the mult needs to be higher to match 5 cards of x2

zealous glen
#

How do I hook functions if the hook is inside a file called with NFS.load?

#

It worked when I called the file directly but apparently what I'm doing right now doesn't

#
for _, hook in ipairs(hook_list) do
    local init, error = NFS.load(SMODS.current_mod.path .. "hooks/" .. hook ..".lua")
    if error then sendErrorMessage("VictinsCollection :: Failed to load "..hook.." with error "..error) else
        local data = init()
        sendDebugMessage("VictinsCollection :: Loaded hook: " .. hook)
    end
end
#

Wait nevermind only a specific hook failed and it threw an error

zealous glen
#

Is this spaghetti code?

local reroll_boss_ref = G.FUNCS.reroll_boss

G.FUNCS.reroll_boss = function(e)
    --[[…]]
    local previous_force_boss = G.FORCE_BOSS
    local changed_force_boss = true
    --[[…]]
    local get_new_boss_ref = get_new_boss

    get_new_boss = function()
        local get_new_boss_val = get_new_boss_ref()
        if changed_force_boss then
            G.FORCE_BOSS = previous_force_boss
        end
        get_new_boss = get_new_boss_ref
        return get_new_boss_val
    end

    local reroll_boss_val = reroll_boss_ref(e)

    return reroll_boss_val
end
frosty dock
#

huh, a one-time hook inside another hook

#

interesting

hushed cradle
#

the {V:1} thing gives me an error

#

i can send a ss of it

#

thats the top bit

#

idk why it doesnt like it

frosty dock
hushed cradle
#

in the localization thing thats what idol does

#

tbh idk what it means

#

i kinda assumed C was for colour

#

but idk why its v

frosty dock
#

that's just not how variables work in this engine

hushed cradle
#

right nvm

#

would you know how to get the colour of a suit from the name

frosty dock
#

G.C.SUITS[suit]

hushed cradle
#

is [suit] a string?

#

also what about high contrast

frosty dock
#

for vanilla suits, it's one of "Hearts", "Diamonds", "Spades", "Clubs"

#

high contrast is accounted for

hushed cradle
#

cool

#

thank you

#

actually carrying my modding

frosty dock
#

the V arg is for color variables, which you have to pass in through loc_vars, while C is for static, predefined coloring

hushed cradle
#

ohh

#

i havent bothered doing anything with loc_vars for any of my jokers

#

is that bad?

frosty dock
#

loc_vars is what you should be using for anything stateful in terms of descriptions instead of inlining it into the description

#

#n# for any number n will be replaced by the variable passed in at index n

zealous glen
zealous glen
#

The forced boss is affecting the next reroll but not the first reroll

#

So it's delayed

frosty dock
# hushed cradle

if that piece of code is where I think it is, I don't see how that would even begin to function with any amount of state involved

zealous glen
#

I thought this would adress it because I thought the issue was that get_new_boss was called inside an event

hushed cradle
#

its in loc_txt

#

lol

#

is that bad

#

💀

#

does that mean it wont update

#

ah

#

i see

frosty dock
#

exactly

hushed cradle
#

you have enlightened me

#

thank you

zealous glen
#

@frosty dock any help with forcing a specific Boss?

#

I actually had an injection that worked, but I figured I should use a hook if a hook works

frosty dock
#

use an injection

#

or use a hook but don't make the hook temporary, but its condition instead

#

even then it won't stack unless the condition is numeric

zealous glen
#

I couldn't find an example of G.FORCE_BOSS being used. I reckon it's an artifact of the demo which was always Verdant Green

frosty dock
#

have you tried if anything breaks if you ignore G.FORCE_BOSS's changed value?

zealous glen
#

No. Since I don't think it's used, I only foresee my own mod or other mods breaking

#

I'd need to clear G.FORCE_BOSS elsewhere, I think that's the only change I'd need to make

#

for self-compatibility

hushed cradle
#

am i doing this wrong?

zealous glen
#

yes

#

card not self

hushed cradle
#

oh yeah

#

will that fix the error tho?

wintry solar
#

What’s line 177/178?

hushed cradle
zealous glen
#

I don't know if 1 = … is Lua syntax

hushed cradle
#

oh

zealous glen
#

You can just list the values without keys

hushed cradle
#

all my knowledge of lua is just reading the game source code and other peoples mods

#

cool

zealous glen
#

or do ```lua
[1]

hushed cradle
#

but doesnt the index start at 0?

wintry solar
#

Not in lua

hushed cradle
#

ofc it doesnt

zealous glen
#

Also not in Lua

hushed cradle
#

right

#

thanks

wintry solar
#

But yeah, just list the values

#

They don’t need keys

hushed cradle
#

cool

#

i wouldve done that if i knew it started at 1

#

probably

brisk pond
zealous glen
#

hmm

frosty dock
#

mfw [tonumber([[[[1]]]])]

zealous glen
#

Ah wait I think I understand the issue

#

When add_to_deck is called, the Joker isn't in the deck yet (?)

#

That's why find_card doesn't find it

hushed cradle
#

does {V: take a hex value?

frosty dock
# hushed cradle

oh also there's another issue with this - color vars are their own thing

hushed cradle
#

damn

#

im tryna figure out the colour thing

frosty dock
#

vars = { ..., colours = { G.C.SUITS[...] } }

#

something like this

hushed cradle
#

oh

frosty dock
#

it needs to be a field inside vars

hushed cradle
#

and then 1 for colour 1

#

?

frosty dock
#

you don't need explicit indices for numeric arrays

hushed cradle
#

i mean in the description

frosty dock
#

yeah

hushed cradle
#

i do {V:1} for first index colour

#

sick

#

thank you

zealous glen
#

I think some colors are variables

#

Like

#

Castle or something

#

there's some Joker that uses Suit colors as variables

hushed cradle
#

if i have a mod that recolours the names of suits

#

do i need to load my mod after?

frosty dock
#

colors are only displayed after injection, so in theory it shouldn't matter

hushed cradle
#

cool

#

i didnt realise how dark the clubs suit is by default

#

so i thought it wasnt working

#

time to see if the card really does change every round or my pc explodes

#

no way

#

its actually different from idol and rebate and whatnot

frosty dock
#

is jackpot_card a global var?

hushed cradle
#

no

frosty dock
#

then where does it come from?

hushed cradle
#

hold on

#

you might die seeing this

river panther
#

After 3 hours finally ported to 1.0.0 for like 400 lines of code. I feel weak

hushed cradle
#

💀

edgy reef
#

WHAT

frosty dock
#

oh so it's just an upvalue??

hushed cradle
#

a what?

frosty dock
#

w/e

#

see for yourself, what happens when you savescum?

hushed cradle
#

how do i do that

#

you mean like exit to menu

sly forge
#

yes

frosty dock
#

yep

hushed cradle
#

its still the same card

sly forge
#

oh, sorry, reload the game

frosty dock
#

what if you close the game and re-enter the run

hushed cradle
#

alright 1 sec

#

ah

#

i see

sly forge
#

(yeah the upvalue would be the same. including across different profiles)

hushed cradle
#

how do i fix this then

#

cos it also doesnt change when you start a run

sly forge
hushed cradle
#

so its always same card first round

frosty dock
#

do what other cards of this kind do, use a field in G.GAME

hushed cradle
#

um

frosty dock
#

as for resetting values, you can define a function SMODS.current_mod.reset_game_globals() that will be called whenever necessary

hushed cradle
#

how do i do the other thing

#

the field in G.GAME

frosty dock
#

G.GAME.xxxx_jackpot_card = whatever with xxxx being some prefix to ensure there's no collision if another mod would happen to have a jackpot_card too

hushed cradle
#

how do i get it to reset and save and stuff tho

zealous glen
#

it just works

hushed cradle
#

or does the game handle that

#

cool

frosty dock
#

just shove that and your code for generating a new random suit and rank into reset_game_globals

#

applied to that field, of course

hushed cradle
#

is reset_game_globals smth i do in my own mod then

#

just make a function

#

sorry ive acc got no clue about this stuff

frosty dock
#
function SMODS.current_mod.reset_game_globals()
  -- code goes in here
end
hushed cradle
#

thank you so much

hushed cradle
#

sorry

#

is there a set_globals thing too

frosty dock
#

there's actually an argument to the function that tells you whether or not it's being called at the start of a run

#

but either way it does get called there

hushed cradle
#

im tryna hover over it in the collection and its telling me im tryna index a nil value

#

so i wondered if i need to set it when the game boots

zealous glen
#

When one card is added to the deck, it's not still in the deck so the check before the reroll doesn't see it

#

Which means it can be overridden by the older one

frosty dock
edgy reef
#

Pretty sure they just have a default value if the global one is nil

hushed cradle
#

oh it does return right at the top

hushed cradle
#

gonna grab some cereal and ponder

zealous glen
#

Sorry, @frosty dock, how am I supposed to use Joker.generate_ui again?

river panther
#

Recently ported over my 0.9.8 jokers to steamodded 1.0.0 and everything shows up fine with description sprites whatever. No crashes whatsover but No matter what my calculate function never triggers EVER. Has anybody ever had this problem?

zealous glen
#

what does your calculate looks like

river panther
#
        if context.joker_main and G.GAME.current_round.hands_played == 0 then
            return {
                message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra}},
                Xmult_mod = card.ability.extra
            }
        end
    end,```
#

Very basic x3 mult on first hand

#

For all my jokers this is just a simple case

zealous glen
#

Arguments are wrong

#

function(self, card, context)

river panther
#

😦

#

Yup they all work perfectly now

#

4 year degree in computer science.... For what?

languid quiver
#

hello mod dev

#

i need help with something i reeeeeally want to implement

brisk pond
#

what do you reeeeeally want to implement?

languid quiver
#

it's a challenge where you start with 1 less discard and have to play pairs

#

or else your hand doesnt score

#

plus, you can play up to 6 cards at a time

#

oh, and i want to implement the hand type "three pair"

#

30 chips x 2 mult base

#

uhhhh

#

hmmmm

#

did u install lovely?

#

the latest version of it?

royal ether
#

also havent seen the mod author around here

proper stratus
#

im not sure

royal ether
#

dw about deleting, just ask again there 👍

proper stratus
#

no its ok dont worry

#

i made it work!

royal ether
#

o nice

languid quiver
#

yay!!

proper stratus
#

i just didnt want to clutter up the chat with unnecessary stuff

#

the problem was a bad version of lovely

#

thank you all so much

royal ether
#

keep it up

hushed cradle
#

can someone help me out rq

#

ive got a joker i added that gives a bonus to a certain card

#

like idol

#

and it changes every round

#

atm i have this

#

which is fine except

#

if i look in the collection before starting a run

#

i cant hover over the joker because it crashes

#

i need to set G.GAME.vanexp_jackpot_card on startup

#

but i dont know how to

#

is there like an SMODS.current_mod.start or smth similar?

royal ether
#

you can create a fallback variable for your loc_vars

#

instead of creating a variable on game startup

hushed cradle
#

this is what it looks like atm

#

oh can i do

#

or

#

like this or that,

royal ether
#

yea you can do if G.GAME.vanexp_jackpot_card then your code

#

yea an or works too

#

up to you

hushed cradle
#

thank you so much

royal ether
#

np

hushed cradle
#

ive been struggling over this for so long lol

royal ether
#

i was struggling over a similar issue in one of my mods too lol

#

didnt think of defaults for like 2 hours

hushed cradle
#

sometimes the solutions are just too simple

royal ether
#

does anyone know off the top of their heads what happens if you have 0 hand size

#

is it even possible to get to 0 hand size or does it floor out at 1

crisp coral
#

0 hand size kills you

royal ether
#

aw dang it

#
    if #G.hand.cards < 1 and #G.deck.cards < 1 and #G.play.cards < 1 then
        end_round()
    end```
i genuinely cant tell, is this what kills you if your hand size is 0?
#

if i set hand size to 0, wouldnt deck still have cards

#

yknow im just gonna test it myself instead of askin

crisp coral
brisk pond
hushed cradle
#

can i get you guys' opinion on the art for some jokers

royal ether
#

oh i found the part that kills you

#

theres a lot of different 'kill you' methods

#

as in two

fallen tendon
hushed cradle
#

yeah hes creepy asf

#

thats the least creepy i could get him tho

royal ether
#

i think he looks cute

hushed cradle
#

its just smth about his eyes

royal ether
#

the makeup around the eyes does kinda not look like make up

hushed cradle
#

hes strange

#

but i like him

royal ether
#

agree

hushed cradle
#

not to be confused with square joker lol

fallen tendon
#

Make cubed joker

royal ether
#

if my lovely pattern hits no matches, it doesnt show in the logs right

fallen tendon
#

Its just jimball but a cube

#

I wonder how jimballs animatuon was made though

mellow sable
#

Pyramid joker

mellow sable
#

Someone put Jimbo on a ball in blender and rotated it then someone else pixelized it

river panther
#

Is their a function I can call on context.other_card to check its enhanced ability

#

cant find one in the source code

brisk pond
#

alternatively, you can open Mods/lovely/dump/targetfile.lua and check yourself if the change happened

solemn coral
river panther
royal ether
brisk pond
royal ether
#

so much of the game kinda just assumes you have cards when you play a hand

#

which makes sense

#

i hope this mod doesnt explode compatibility

hushed cradle
#

why do you get a single chip lol

royal ether
#

i usually just do placeholder values when im still developing

hushed cradle
#

makes sense

#

ive got an unlock for a joker

#

but when you unlock it and exit to menu it crashes cos it cant draw an unlock box

#

i have no idea what any of this means

zealous glen
#

I'm looking at a mod that defines generate_ui (D6 Jokers) but I'm still not sure how to make a tooltip out of it

hushed cradle
#

i tried removing all my mods and reinstalling

#

but its still there

uneven fern
#

INFO - [G] 2024-07-08 22:59:00 :: ERROR :: StackTrace :: Oops! The game crashed
main.lua:4117: assertion failed!
I got this error after updating to the latset version. How can I fix it?

#

Update: It's Codex Arcanum making this error.

nocturne garnet
#

is there a way to check if the current context is one of the contexts in a set array

#

i want to make a randomized joker with a random context, but i want to filter it

wintry solar
#

So you have a list of contexts and you want to see if only one is present? Or if a set one is present?

zealous glen
#

Does Steamodded support using enhancement_gate?

nocturne garnet
zealous glen
wintry solar
zealous glen
#

It could remember if it has been triggered during a run of evaluate_play

wintry solar
#

There’s not many conditional contexts either

nocturne garnet
#

i dont even know how i said it this wrong

mental wind
#

I'm hoping to try and make some simple mods of my own, but I have no idea where to start on figuring out formatting other than just copy pasting other people's code formatting and hoping it works when I edit it. Is that really the best thing for me to do, or are there other resources out there where I could learn how to make balatro mods?

languid mirage
# mental wind I'm hoping to try and make some simple mods of my own, but I have no idea where ...

I mean, that's how I started, so I don't see any shame with that approach. You start by looking at solution, then try to solve it on your own.

Steamodded 1.0.0 docs are not complete yet, but there's some info https://github.com/Steamopollys/Steamodded/wiki
There's also example mods in steamodded that help you understand how API works https://github.com/Steamopollys/Steamodded/tree/main/example_mods/Mods

mental wind
#

Okay, thank you!

languid mirage
#

You're welcome

languid mirage
# mental wind Okay, thank you!

You should definitely unzip Balatro.exe with 7zip and look through source code to see how jokers and such are calculated. There's also a helpful resource for joker calculation contexts https://discord.com/channels/1116389027176787968/1247703015222149120, which might help once you get the hang of the API basics (but I personally found checking calculate_jokers function or just searching 'Joker Name' in source code much better to look for examples)

Also, keep in mind that some modded jokers might use lovely patches, which are injections directly to the game's source code (they're always in .toml files) for features not covered by the API. So just copying lua stuff might not always work. But you don't have to learn that right away

mental wind
#

I tried to make a very simple joker based off the formatting in another mod, but I got an error code saying [string (my code)] attempt to call field 'Joker' (a table value). Any idea what I did wrong here?

frosty dock
mental wind
#

When I go to the releases page, it says the latest release is 0.9.8. How do I get to 1.0?

river panther
mental wind
#

That's what I'm looking at, but it says to download steammodded from the release page, and the page it links to only has 0.9.8 and below

frosty dock
#

you get 1.0 via the source code on the main branch

river panther
#

yeah

#

Have you cloned the steammodded repo in the mods folder?

frosty dock
mental wind
#

I found the source code download in the README on github. Is that the one that's harder to update, or will it be fine?

river panther
#

Thats the direct download. It will be harder to update

#

But it will work

mental wind
#

What is it that makes it harder to update? Is it like the old version where instead of just sitting in the mods folder where you can easily remove it, you need to verify your files on steam to clear it?

river panther
#

You would need to replace the download. Whereas if you use git you just pull in the command line and it updates it

#

No need to manually replace files

mental wind
#

Is the folder that I need to add just the entire unzipped steammodded-main, or is there a folder inside of that I'm supposed to take out?

#

Because the instructions say to use the folder Steamodded-1.x.x, but I don't see any folders with a similar name

tepid crow
#

should look something like this

mental wind
#

okay, so it is the folder that holds all of those. I guess the instructions just assumed it would have a different name than the version I downloaded did, which is why I was confused

tepid crow
#

That's one of the differences when dowloading the zip as opposed to git. I do think you chose the easier option though, to be fair

mental wind
#

Is there still supposed to be a mods tab next to collection like in the old version?

#

Because I just opened the game and it's not there

tepid crow
#

did you download lovely?

mental wind
#

Ah, no, I didn't. I'll do that, and hopefully it should work then

tepid crow
mental wind
#

Yeah, I had read through that before, but then got focused on the steammodded part and just forgot about the injector

#

You just put the injector here, right?

zealous glen
tepid crow
#

In balatro's install folder

zealous glen
#

Put it in the game’s files

tepid crow
#

should be here

mental wind
#

Found it, thanks

#

It seems to be working now, but now when I open the game it also opens a second window with this. (I would show the full window, but the last line shows my steam id, which feels like something I shouldn't publicise)

tepid crow
#

yeah that's normal

#

(and useful when debugging)

mental wind
#

Is it supposed to just stay open the entire time? I tried to close it and it closed balatro itself too

tepid crow
#

yes, it's directly connected with the balatro instance

#

but if you're planning on making mods yourself I'd suggest not doing that, balatro's built-in error screen is not as good as the console's, in my experience

mental wind
#

Okay, thanks

zealous glen
#

I prefer the built-in debug

#

Though you need to run it with Python

tepid crow
#

built-in debug? 👀

zealous glen
#

Yeah in Steamodded’s debug folder

mental wind
#

Now that the test mod I was trying to make works, how do I tell the game how to access an asset?

zealous glen
mental wind
#

k, I saw other mods using atlases, but the ones I was looking at were using sprite sheets, so I thought it might just be for those. I'll try and recreate the ones I've seen and see if that will work

tepid crow
zealous glen
#

idk

#

what’s .pyw

tepid crow
#

I think windows describes it pretty well

Python File (no console)

mental wind
#

I just got the error "Failed to collect file data for Atlas bala_test". Any idea what I did wrong?

#

The image I made is saved as TestingJoker.png inside an assets folder that is in the mod folder

mental wind
#

What does that mean?

#

Where would I add it?

zealous glen
#

You can add one to the header but the automatic one is the first four letters of your mod’s name

#

Your mod’s name begins with “Bala” I presume, hence it tries to find the atlas indexed by bala_test

mental wind
#

oh, so the joker and atlas should both have the key bala_test instead of test?

#

Or only one of them?

zealous glen
#

No

mental wind
#

oh, it automatically adds bala_ to the atlas key, so I need the joker key to be bala_test? Is that it?

zealous glen
#

Actually wait

mental wind
#

Or is it because Bala would be used for what's already in the game, so it breaks something?

zealous glen
#

Put the error message here

zealous glen
mental wind
zealous glen
#

Put the image in 1x and make a double-sized copy to put in 2x

mental wind
#

Is there a simple way to create the double-sized copy?

zealous glen
#

The art program you used to make the original artwork might

tepid crow
#

you'll have to do so manually

mental wind
#

Got it to work, thanks!

#

Do you know if there's a mod that lets you access a console or something similar, because I'd like to be able to find it quickly so I can see if it works in game

hushed cradle
mental wind
#

Luckily I have 2 bulls and over $400, so I have plenty of time to test with it

tepid crow
#

hah, nice

mental wind
#

I am very confused though, on how to make the jokers effects

hushed cradle
#

have you looked through the source code?

#

thats super helpful

mental wind
#

No, how would I do that

hushed cradle
#

if you go to where balatro is installed on steam

#

you can go to local files

#

you make a copy of the exe somewhere

#

then you can extract using winrar or 7zip

#

or similar

mental wind
#

Would it work to just look through a bunch of other mods to see the way they do it, or is it going to be better to look through balatro itself?

hushed cradle
#

i would say def look through balatro itself

#

but some other mods might help

#

but the source code has like very basics and stuff

mental wind
#

I think I'm going to try without it, just because it doesn't display anything, which could make it confusing to see whether it's working with more complex jokers, but if I'm still lost after looking through the game, then maybe I'll try it. Thanks for showing me though!

mental wind
tepid crow
hushed cradle
#

i wouldnt do that

tepid crow
#

but yeah, you probably shouldnt

hushed cradle
#

easier just to make a copy of the exe somewhere

brisk pond
mental wind
#

I'm referring to how, in the video of you showing off the joker that does x10 chips on each played card, that is calculated at the same time that the plus chips from the actual card is, instead of being a seperate trigger after, which makes it harder to tell whether things trigger

brisk pond
#

oh now I updated it, that problem isn't a thing anymore

mental wind
#

I've tried a few times now, but everything has been crashing. How should I format the config and the mult in calculate?

brisk pond
#

config = {extra = {mult = 100}},

#

and then card.ability.extra.mult to get it

mental wind
#

I think I tried that and it didn't work, but I'll try again and see if it does

#

Yeah, it's still giving the same error

mental wind
#

Here's the error I got

tepid crow
mental wind
#

Give me a sec to crash it again so I can grab it from the console instead of the screen

tepid crow
#

I meant your code, not the error

crisp coral
mental wind
#

INFO - [G] 2024-07-08 17:25:38 :: ERROR :: StackTrace :: Oops! The game crashed
[SMODS BalatroTesting1357 "BalatroTesting.lua"]:38: attempt to index field 'extra' (a nil value)
Stack Traceback

(1) Lua local 'handler' at file 'main.lua:1900'
Local variables:
msg = string: "[SMODS BalatroTesting1357 "BalatroTesting.lua"]:38: attempt to index field 'extra' (a nil value)"
(*temporary) = Lua function '?' (defined at line 6476 of chunk main.lua)
(*temporary) = string: "Oops! The game crashed
"
(2) Love2D metamethod at file 'boot.lua:352'
Local variables:
errhand = Lua function '?' (defined at line 1897 of chunk main.lua)
handler = Lua function '?' (defined at line 1897 of chunk main.lua)
(3) Lua method 'calculate' at file 'BalatroTesting.lua:38' (from mod with id BalatroTesting1357)
Local variables:
self = table: 0x22e87658 {alerted:true, _saved_d_u:true, original_key:test, loc_txt:table: 0x22e88190 (more...)}
card = table: 0x23548350 {under_overlay:false, sort_id:593, click_offset:table: 0x22f05200, STATIONARY:false (more...)}
context = table: 0x23149fe8 {poker_hands:table: 0x2371d910, scoring_name:High Card, scoring_hand:table: 0x236e4238 (more...)}
(*temporary) = table: 0x232369f8 {}
(*temporary) = nil
(*temporary) = string: "attempt to index field 'extra' (a nil value)"
(4) Lua method 'calculate_joker' at file 'card.lua:2379'
Local variables:
self = table: 0x23548350 {under_overlay:false, sort_id:593, click_offset:table: 0x22f05200, STATIONARY:false (more...)}
context = table: 0x23149fe8 {poker_hands:table: 0x2371d910, scoring_name:High Card, scoring_hand:table: 0x236e4238 (more...)}
obj = table: 0x22e87658 {alerted:true, _saved_d_u:true, original_key:test, loc_txt:table: 0x22e88190 (more...)}

#

I added that already, and it didn't fix anything

tepid crow
#

the code, not the error

mental wind
#

Ah, my bad

#
    key = 'test',
    loc_txt = {
        name = "Test Joker",                                --name used by the joker
        text = {
            "{C:mult}+100{} mult",             --description text
            "{C:attention}THIS IS A TEST{}"                     --more than 5 lines look odd
        }
    },
    config = {extra = {mult = 100}},
    rarity = 1,                                        
    pos = { x = 0, y = 0 },                         
    atlas = 'test',                                       
    cost = 4,                                        
    unlocked = true,                                 
    discovered = true,                            
    blueprint_compat = true,                    
    eternal_compat = true,                          
    soul_pos = nil,                     

    calculate = function(self, card, context) 
        if context.joker_main then
          return {
            card.ability.extra.mult,
            card = self,
        colour = G.C.MULT,
            message = {"+100"},
                 }
        end
    end
}```
hallow forge
#
SMODS.Joker {
    key = 'test',
    loc_txt = {
        name = "Test Joker",                                --name used by the joker
        text = {
            "{C:mult}+100{} mult",             --description text
            "{C:attention}THIS IS A TEST{}"                     --more than 5 lines look odd
        }
    },
    config = {extra = {mult = 100}},
    rarity = 1,
    pos = { x = 0, y = 0 },
    atlas = 'test',
    cost = 4,
    unlocked = true,
    discovered = true,
    blueprint_compat = true,
    eternal_compat = true,
    soul_pos = nil,

    calculate = function(self, card, context) 
        if context.joker_main then
          return {
            card.ability.extra.mult,
            card = self,
        colour = G.C.MULT,
            message = {"+100"},
                 }
        end
    end
}

please format like this

#

it's easier

mental wind
#

How do I make it format that way?

tepid crow
#

^ using

```lua
code
```

brisk pond
#

oh wait

hallow forge
#

probably not one gets a "j_" appended the other doesn't

brisk pond
#

card.ability.extra.mult without anything before?

mental wind
#

I've also had mult = card.ability.extra.mult, and that didn't work either

#

I think it's probably that line, but I'm not sure what to do to fix it

brisk pond
#

try mult_mod = card.ability.extra.mult

mental wind
#

Also tried that

brisk pond
#

and delete the card = self

mental wind
#

Just tried that, same crash

brisk pond
#

when does the crash happen?

#

while booting up the game?

mental wind
#

Once I play a hand

#

Is there any chance I don't need extra because the joker only uses one variable, because jokers like the default +4 don't have extra in the config

#

I got it to stop crashing again, but now it doesn't do anything

#

It now has config = {mult = 100}, and mult_mod = card.ability.mult,

#

My game didn't crash when I played the hand, but it didn't actually add mult, it just gave the +mult message

tepid crow
#

can you try changing the return to

return {
            mult_mod = card.ability.extra.mult,
            card = card,
        colour = G.C.MULT,
            message = {"+100"},
                 }
#

@mental wind

mental wind
#

I did mult_mod = card.ability.mult, because otherwise my game will crash, but I tried the card = card and it didn't work

tepid crow
# mental wind I did ```mult_mod = card.ability.mult,``` because otherwise my game will crash, ...

It works for me. This is my full code (I removed the atlas cuz I don't have the png, obviously)

SMODS.Joker {
    key = 'test',
    loc_txt = {
        name = "Test Joker",                                --name used by the joker
        text = {
            "{C:mult}+100{} mult",             --description text
            "{C:attention}THIS IS A TEST{}"                     --more than 5 lines look odd
        }
    },
    config = {extra = {mult = 100}},
    rarity = 1,
    pos = { x = 0, y = 0 },
    cost = 4,
    unlocked = true,
    discovered = true,
    blueprint_compat = true,
    eternal_compat = true,
    soul_pos = nil,

    calculate = function(self, card, context) 
        if context.joker_main then
          return {
                  mult_mod = card.ability.extra.mult,
                  card = card,
                  colour = G.C.MULT,
                  message = {"+100"},
                 }
        end
    end
}
brisk pond
#

inside the Joker's calculate i got some functions that create a table in card.EzSc. The problem I'm encountering is that EzSc_calculate_joker is called on the next context that is calculated.
Like when you play a hand, the game does calculate_joker with these contexts:

  1. context.before
  2. context.repetition on first scored card
  3. context.individual on first scored card
  4. context.repetition on second scored card
  5. context.individual on second scored card
  6. etc.
    The problem is that with this code, the EzSc table I got with context.individual on first scored card is being used on the next context, which is context.repetition on second scored card
solid salmon
#

does this look joker enough?

brisk pond
#

this problem only happens when context.individual is involved

brisk pond
mental wind
tepid crow
brisk pond
shell tangle
mental wind
#

Same run, but whenever I reload it does work differently, so I don’t think that matters

shell tangle
#

I think it matters for things like changing scope, since you have mult in .extra now rather than just config, it's probably why it's nil, the run needs to be reset for it to exist, I'd say at least give it a shot, but, yeah, might do absolutely nothing.

solid salmon
#

i hate K

shell timber
#

why are you redrawing the joker text?

solid salmon
#

It's for one of my potions

#

also imma do something with it

brisk pond
#

Is this one the portion that runs the jokers calculate functions?

solid salmon
#

E looks like batman

#

or something in minecraft

brisk pond
solid salmon
#

i wanted to diy

#

and this happened

solid salmon
#

it is now a colorful brick

rough furnace
edgy reef
#

NICE

rough furnace
#

unfortuantly, to do pretty much any kind of fancier text editing stuff, I'll have to write my own text renderer

#

or find a lib I can steal

tepid crow
#

the music really improves it a lot

rough furnace
#

arg parsing

crisp coral
rough furnace
#

Ok I am working on paring steamodded logs, and was thinking, would you rather I just kept the logs as is, but add colour (the first two examples), or to shrink them down a bit as well (the second two examples)?

crisp coral
#

latter looks cleaner

tepid crow
#

looks like you'd lose the logging level?

#

or will you do something like [Level, Logger]?

rough furnace
#

The colour is based off logging level

#

Thinking Blue for info, yellow for warn, red for error/fatal, and haven't decided yet for trace or debug (might keep them both info blue)

tepid crow
#

Ahhhh, I see

#

I'm personally not sure if it's a good idea to make the level that implicit

#

it also kind of depends on whether you want this to be a replacement for the logs or a more of a different view

rough furnace
#

I mean I'm not replacing the logs totally (especially since this view doesn't render always [like when the game is loading or crashes]) and mods can probably screw with it, but it's kind you don't need the logs 90% of the time you use it

#

Oh also if you haven't seen it has a fade effect thing for live log reading (so something like this could make it more glanceable)

edgy reef
#

I'd say not have the time and date show up, it's generally not useful info for live viewing.

tepid crow
#

I like the colors and removal of clutter (especially date lol), I'm just not sure about removing the logging level

#

seems like something someone could easily misunderstand when looking at it for the first time

crisp coral
#

could be like

[ExampleLogger] [W] Example
[ExampleLogger] [I] Example
[ExampleLogger] [D] Example
rough furnace
#

Yeah maybe some variation of that would be good

limpid flint
#

What's ExampleLogger

rough furnace
#

The logger

#

Used to identify what part of the code the log is coming from

crisp coral
#

either that or

[ExampleLogger | W] Example
[ExampleLogger | I] Example
[ExampleLogger | D] Example
limpid flint
#

I think Warn/Info/Fatal is still very useful

#

W/I/D is a bit, confusing

crisp coral
#

[W]arn
[I]nfo
[D]ebug
[F]atal
[E]rror

#

that's fine imho

limpid flint
#

Well my log experience most came from, well, modded Minecraft

#

It has similar log screen

#

Just that it's not covered over the whole game

rough furnace
#

Yeah I prefer single character ones
Which of these do you all think looks best?

[ExampleLogger] [W] Example
[W] [ExampleLogger] Example
[ExampleLogger | W] Example
[W | ExampleLogger] Example
[ExampleLogger :: W] Example
[W :: ExampleLogger] Example
mellow sable
#

W should be at the end I think

rough furnace
#

Yeah I kinda took inspiration from the Minecraft chat box, although Minecraft does have an actual log it uses for development, which this is designed to more closely resemble

crisp coral
#

modded minecraft's logging is the messiest thing i've ever seen actually

#

< only plays modpacks

limpid flint
#

Since ExampleLogger will very if I am understanding it correctly

rough furnace
#

Oh also thoughts on maybe hiding debug level logs by defsult, and an option to turn them on (so mod devs can use them without spamming the console)

rough furnace
limpid flint
shell timber
#

single letter + colour would be nice

mellow sable
#

yeah color makes it easier to tell importance

shell timber
#

*in release build

rough furnace
#

Yeah maybe I leave it on

limpid flint
#

Then I>>D>W>E>F?

tepid crow
rough furnace
#

Though I think I keep debug logs off by default, and then devs can leave these logs for debugging and users can run a command to change the log level

shell timber
#

as for colours i'd go

info: white
debug: blue
warning: yellow
error + fatal: red

but you probably wouldn't see fatal(?)

rough furnace
#

Yeah I figured fatal won't be seen so ill just match error

#

There's also trace but tbh idk when it's supposed to be used

shell timber
#

trace is for a full stack trace so it'd probably be under debug

rough furnace
#

I was kinding thinking info would be blue but maybe it should just be white

shell timber
#

info and debug can be swapped tbh

rough furnace
#

RN its the same blue as the fps display

tepid crow
limpid flint
#

I don't know what to think about info, they are mostly just bunch of numbers

shell timber
#

yellow / red are really the only defined colours

rough furnace
#

Oh also any log that doesnt go through steamodded (or probably an api I'll eventually make) defaults to info

shell timber
#

that's fair enough

limpid flint
#

For developers maybe all of them are important, but for most ppl they might think it's too much. For me I am amongst the latter

rough furnace
#

Oh by a bunch of numbers do you mean the LONG DT messages?

limpid flint
#

I use debug plus mainly for debug panel feature, and a toggle to default the unimportant logs to not appear would be greatly appreciated

limpid flint
rough furnace
#

Yeah I just disabled that in the dev branch

#

It's a built in thing but I don't think anyone uses it

edgy reef
#

It's just a sign of lag, which is noticeable

rough furnace
#

Yeah, it's probably useful if your debugging performance, but not much else

#

Once I build a proper log level system, then I can just demote it to a debug log

tepid crow
#

btw wilson I feel like you'd know, shouldn't inject_class run before inject on a custom Center class?

rough furnace
#

Uhh idk I just make dev tools, not actually make new content

tepid crow
#

oop

#

anyone else?

edgy reef
#

...it does

tepid crow
#

right, that was my assumption too

edgy reef
#

The inject_class function is what handles inject so if you redefine it and have the super/GameObject inject_class go after that's automatically before inject

tepid crow
#

yeah I super

#

this is what I have

SMODS.Sleeve = SMODS.Center:extend {
    class_prefix = "sleeve",
    discovered = false,
    unlocked = true,
    set = "Sleeve",
    atlas = "sleeve_atlas",
    pos = {x = 0, y = 0},  -- within `atlas`
    required_params = {"key", "atlas", "pos"},
    inject_class = function(self)
                   G.P_CENTER_POOLS[self.set] = {}
                   G.P_SLEEVES = {}
                   SMODS.Sleeve.super.inject_class(self)
                   end
}
#

but it errors when I try to create a custom object using the class

#

like this

SMODS.Sleeve{
    key = "none",
    name = "No Sleeve",
    config = {},
    loc_txt = {
        name = "No Sleeve",
        text = {""}
    },
    atlas = "jokers",
    pos = {x=0, y=9}
}
edgy reef
#

What error is it exactly?

tepid crow
#

do you want the full error?

edgy reef
#

yea

tepid crow
crisp coral
#

@rough furnace going to ask this ahead of time, is it okay if we bundle the new logger into Balatro Archipelago (and modify it a tad) to allow communication between games

tepid crow
#

yeah I dont think it's being called

edgy reef
#

If you put a debug message there is it printing anything?

tepid crow
#

no

#

(that's what I did and why I'm assuming it's not running 🙃)

#

do I need to initiate it somehow?

edgy reef
#

Should automatically

#

Maybe try appending inject

tepid crow
#

you mean something like this?

SMODS.Sleeve = SMODS.Center:extend {
    class_prefix = "sleeve",
    discovered = false,
    unlocked = true,
    set = "Sleeve",
    atlas = "sleeve_atlas",
    pos = {x = 0, y = 0},  -- within `atlas`
    required_params = {"key", "atlas", "pos"},
    ‎inject_class = function(self)
                   G.P_CENTER_POOLS[self.set] = {}
                   G.P_SLEEVES = {}
                   sendDebugMessage("G.P_CENTER_POOLS[self.set] = " .. G.P_CENTER_POOLS[self.set], "CardSleeves")
                   SMODS.Sleeve.super.inject_class(self)
                   end,
    inject = function(self)
             SMODS.insert_pool(G.P_CENTER_POOLS[self.set], self)
             G.P_SLEEVES[self.key] = self
             end
}
#

cuz doing that doesn't seem to change the error

#

weirdly, I did try extending GameObject instead of Center, and that didnt have this issue

edgy reef
#

ohhhh

tepid crow
#

does that... explain something?

edgy reef
#

What if you specifically call SMODS.GameObject.inject_class instead of SMODS.Sleeve.super?

#

Lemme try and recreate it rq

tepid crow
#

just to confirm,
SMODS.Sleeve.super.inject_class(self) ->
SMODS.GameObject.inject_class(self)?

#

cuz that doesn't seem to fix it

edgy reef
#

Wait wtf is going on then

tepid crow
#

also, if inject_class isn't running in the first place I doubt changing any of the code in it would help...

edgy reef
#

Wait maybe it is the issue

#

Someone fucked up

#

This doesn't crash the game

#

I don't think this is supposed to be intended behaviour

#

As Steamodded API is set up so functions can be append function from classes by subclasses

tepid crow
#

I'm gonna be honest I don't know what you meant by that last sentence

edgy reef
#

Lemme double check with Steamodded API

tepid crow
#

uhm, I think I found it?

#

I think I had a zero-width space before the function name?

#

HOLY SHIT

#

ohmygod you can see it in my copypastes in the channel too

#

@edgy reef

edgy reef
#

Unfortunately I'm also not getting prints from inject_class

#

Although it is really funny that this is occurring

crisp coral
#

how do you even get a zwsp in there anyway

tepid crow
tepid crow
#

also apparently U+200E is the "left-to-right mark" (aka an indicator of the direction of text when using e.g. both latin and arabic)

tepid crow
mental wind
tepid crow
#

surely not

#

editing in notepad kinda crazy tho

mental wind
#

It's nice, because I just have the .lua file that's already in the mods folder open in notepad, and if I need to try something, all I have to do is close the game, make the edit, hit ctrl+s, then reopen and it's implemented

tepid crow
#

... that's exactly what I do. With a proper editor (since literally 20min ago)

mental wind
#

Ah. Thing is, before that I was using replit, so I had to download all the files as a zip, extract the actual code, drop that into the mods folder replacing the old code, then reopen the game

#

And today is the first day I've started actually working on this, so maybe I will get an actual editor in the future, but at this point notepad hasn't been too annoying to deal with yet, so I may very well end up just sticking with it.

tepid crow
mental wind
#

Yeah, it's what my class used for AP Computer Science A, so that's the only editor I'm familiar with. I know there's also IntelliJ, but I think that's java specific, and it requires a bunch of other setup that I have no idea how to do

tepid crow
#

it's java-ish specific I believe yeah

#

it can also do some other random stuff

shell timber
#

wait

#

what??

#

at least use notepad++

edgy reef
#

VSC is also good. Has some built-in features for GitHub too which is neat (not sure if notepad++ does as well).

shell timber
#

there's also all of the terminal based editors if you want to go down that path

tepid crow
#

I wouldn't

wintry solar
#

Editing in notepad is WILD

tepid crow
#

y'all haven't done word processing code editing yet?

edgy reef
#

HELL NAH

tepid crow
# edgy reef Unfortunately I'm also not getting prints from `inject_class`

Hmm, any solutions or insight for why inject_class isn't working? Right now I've got this horrendous jank, since inject does seem to work for me

local sleeve_class_is_injected = false
SMODS.Sleeve = SMODS.Center:extend {
    ...
    inject_class = function(self)
        if sleeve_class_is_injected == false then
            sleeve_class_is_injected = true
            G.P_CENTER_POOLS[self.set] = {}
            G.P_SLEEVES = {}
            local old_inject = SMODS.Sleeve.inject
            SMODS.Sleeve.inject = function() end
            SMODS.Sleeve.super.inject_class(self)
            SMODS.Sleeve.inject = old_inject
        end
    end,
    inject = function(self)
        if sleeve_class_is_injected == false then self:inject_class() end
        G.P_SLEEVES[self.key] = self
        SMODS.insert_pool(G.P_CENTER_POOLS[self.set], self)
    end
}
solid salmon
#

is this good?

#

(and joker-y?)

tepid crow
solid salmon
#

it's supposed to be simple and thanks

tepid crow
#

Can I not reliably use SMODS.current_mod in function SMODS.current_mod.process_loc_text()? Its contents seems to change to other installed mods'

maiden phoenix
#

You can save it as a variable for later use

tepid crow
#

I guess

#

still seems weirdly inconsistent

maiden phoenix
#

It is

frosty dock
#

it is, maybe we should pass it self?

maiden phoenix
#

Are mods considered objects?

tepid crow
#

if it's done OOP well, everything is an object

frosty dock
maiden phoenix
#

I see

tepid crow
frosty dock
#

SMODS.current_mod is only valid during the load stage, i.e. while each mod file is being executed

tepid crow
#

ah, I see

#

makes sense

royal ether
languid mirage
#

well, creating this was pain in the ass without any seal examples for 1.0.0 😭

zealous glen
#

Is there custom Seal calculation logic for 1.0?

languid mirage
#

hm no I just had a lot of issues with tooltips

#

well I dont know actually about calculation logic

#

I just couldn't find any relevant examples

#

had to debug a lot to figure out why it was broken

#

also had to change calculate a bit to be consistent with other game objects

#

I was creating something for cryptid tho, this seal is just an example I added in steamodded for whoever needs an example

solid salmon
#

i forgot how to make a loop

surreal marsh
#

how to change my card area's position

queen scroll
#

iirc there's just extra parameters in the cardarea's contructor

#

btw that's a lot of slots

surreal marsh
languid mirage
#

first 2 are x and y coords? I'm pretty sure

surreal marsh
#

thanks

queen scroll
#

something from my mod that i remember works

surreal marsh
#

this works but I wonder why X and Y of vanilla areas are 0

languid mirage
#

probably changed somewhere

rough furnace
# crisp coral <@517371142508380170> going to ask this ahead of time, is it okay if we bundle t...

I don't really want people redistributing the console because then it would be incompatible with DebugPlus, as there are two consoles, and things get messy.
Once i get proper command stuff working, I am going to make public api's for adding commands and having full control over logged messages.
If you do get to the point where you need to add commands, and I haven't added the api's yet, then you can distribute the console code, but make sure you follow the license.

languid mirage
#

this is supposed to set x y coords

crisp coral
#

and a command to send messages isn't unheard of either

surreal marsh
#

good position 🤔

zealous glen
# surreal marsh this works but I wonder why X and Y of vanilla areas are 0

I don’t know but I do know that some positions are relative to the cards in them. For example, the View Deck UI is relative to the topmost card in the deck. Recently I had a bug where the play area shifted to the right despite me never directly changing it. I suspect it’s because of its contents being moved in an awkward state

#

Any mods that have implemented Blind behaviour beyond what’s found in the base game? Just curious what’s out there

#

I think Bunco interacted with the Shop

#

As did MystBlinds

#

Though I personally was thinking having the Blind do something when defeated, but Blind:defeat isn’t quite working

crisp coral
#

MystBlinds doesn't interact with anything apart from normal blind functions

zealous glen
crisp coral
#

That was just increasing a base game variable

zealous glen
#

It’s still outside of normal Blind boundaries

#

Even if vanilla supported

crisp coral
#

this is literally the entire thing

#

😭

zealous glen
#

LoboCorp also had multi-phase Blinds IIRC

zealous glen
#

It’s just about the idea

zealous glen
#

The main one destroys the winning hand

#

But it doesn’t seem to be tracking the cards correctly

#

The way I had tried to print it (recursively) led to a stack overflow error ^^’

crisp coral
zealous glen
#

I mean, I hadn’t mentioned it because I didn’t want to go on and on since I was asking

surreal marsh
#

how do I change the display size to 34*34 like tags

zealous glen
royal ether
#

you need a couple lovely patches iirc

#

it gets overwritten back to the card size pretty often

surreal marsh
royal ether
#

pretty sure, yea

#

i remember autumn talking about it a while back

#

while they were working on oddities

#

this too

surreal marsh
#

ok thanks

zealous glen
#

I’m pretty sure I had made it without any patches

royal ether
#

yea you dont need patches, just some hooks

zealous glen
#

But I don’t have access to the code right now

zealous glen
royal ether
#

just some good ol' overwriting values after base game sets them

zealous glen
#

Maybe it was a patch in the draw function

#

But set_ability works because it’s called whenever the object is created

royal ether
#

personally dont like hooking draw unless its like, last ditch effort

#

or update

surreal marsh
royal ether
#

lil' guy

wintry solar
#

Make a 71x95 sprite with it in the middle 🙃

shell tangle
#

Could someone explain the process Smeared Joker goes through? Found the is_suit() function in the source code, but, can't piece together how it works at all.
Wanting to make a joker that makes only hearts count as hearts and clubs.

zealous glen
#

Where’s balatrotalegaming when we need them

royal ether
#

is_suit just compares a card's suit to the suit passed to the function

#

if you have smeared joker (next(find_joker('Smeared Joker)))

#

oops i hit enter

shell tangle
#

Ah, completely makes sense now, I was missing the fact it's self.base.suit compared to just suit. Though, still unsure how it gets spades/clubs.

royal ether
#

yea im honestly kinda confused on how it works with spade and clubs too lmfao

#

this is the first time ive seen is_suit

#

if i had to guess, it probably handles spades and clubs somewhere else

zealous glen
#

I thought it handled Spades and Clubs by exclusion

#

Therefore any non-Hearts, non-Diamonds suit is also Spades and/or Clubs

#

But I don’t know

wintry solar
#

Yes that’s how it works

#

By design though it will handle all custom suits as equivalent

frosty dock
#

I've wanted to fix this for a while but haven't really gotten to it

#

it's not a huge thing but it should be done right and be extensible

shell tangle
#

Code for it is:

if next(find_joker('Smeared Joker')) and (self.base.suit == 'Hearts' or self.base.suit == 'Diamonds') == (suit == 'Hearts' or suit == 'Diamonds') then
  return true
end
return self.base.suit == suit

Wouldn't it just move down to the return base.suit == suit, if it's not Hearts or Diamonds?

wintry solar
#

No

royal ether
#

oh yea it compares the two

#

good point

wintry solar
#

It equates things that aren’t those as false, and checks the suit its checking too

#

So both would be false

#

Therefore it enters the if block

shell tangle
#

Ah, I see, neat.

royal ether
#

my mind kinda skipped over it and thought it was an and

#

i needa sleep

wintry solar
#

As with almost everything I’ve looked at in this game, it has virtually no support for extension

royal ether
#

thats my goat thunk

solid salmon
#

do i need messages for consumables

zealous glen
#

In an extensible way

#

By balatrotalegaming

#

I forget the name of the API

frosty dock
#

BlackboardAPI, I think

zealous glen
#

Yes

frosty dock
#

i remember that

wintry solar
#

You could create a table of tables, where the internal tables contain suits that are to be considered the same, and iterate through it

zealous glen
#

Anyways I think BlackboardAPI was feature complete

#

But when the world needed them the most, the creator vanished

wintry solar
#

You’d just add another table

tepid egret
#

anybody know how i can change the icon for the unlock notifications? what do i set _atlas in create_UIBox_notify_alert to so it looks for the SMODS atlas thingy?

shell tangle
#

Alright, back again - Made a lovely patch, it's being applied correctly in the dumped .lua.
Doesn't crash, which is both good and bad - No crashes means it's not a stupid grammar mistake, but, I have absolutely no idea how to test for things with a lovely.toml, so I have no idea what steps to take to figure this issue out.
If anyone wants to help, or point me in the right direction, here's the joker code, and the .toml.

SMODS.Joker{
  key = 'carousel',
  loc_txt = {
    name = 'Carousel',
    text = {
      "Spades count as Hearts",
      "Hearts count as Clubs",
      "Clubs count as Diamonds",
      "Diamonds count as Spades"
    }
  },
  rarity = 3,
  atlas = 'virtues',
  pos = {x = 4, y = 1},
  cost = 6
}
maiden phoenix
#

Stinky drink

near ivy
#

a REAL invis joker

maiden phoenix
#

Just the emplace function being bad

near ivy
#

oh

willow quiver
#

Does steamodded have any sort of live reloading or do I need to restart the game every time to see new changes?

shell tangle
#

Simply not applying - Doesn't get affected by the suit jokers, or register as a flush.
Best guess is that it's possibly not finding the joker through the same next(find_joker('') that smeared uses, but, I took a look at it, don't know why it'd be an issue, it uses self.ability.name to find the name.

maiden phoenix
wintry solar
#

And it’s definitely applying?

#

The patch, I mean

shell tangle
#

This is from the dumped .lua. It appears a second time, under the else as well for when it's not flush_calc, but, didn't show it just because it'd be even more of basically same text.

wintry solar
#

Perhaps it’s not finding the joker correctly, I don’t remember off the top of my head how to set it up. You could throw a debug message in there to see if you’re getting inside the block or not

shell tangle
#

That was my thought as well, but, I don't know how to send a debug message through a lovely injection, unless the sendDebugMessage() from Steamodded will work?
Edit - It infact does.
I'm also unsure what the alternative way to find the joker would be, maybe I can try salvaging something from the find_joker() code.

frosty dock
#

you should generally use SMODS.find_card instead of find_joker, which takes a key instead of the name

#

but they should work exactly the same way if your joker has a name

shell tangle
#

I've been assuming that lovely injections can't use Steamodded API, is that completely wrong?

zealous glen
#

I don’t see why they couldn’t

#

I have no idea how Lua works, apparently one can use a reference to a function before defining it, unless I misunderstood something

frosty dock
#

lovely injections can't use steamodded if it isn't present, but there's no issue with using it as long as your mod depends on steamodded anyways

frosty dock
humble tartan
#

Is there a way to use a package from luarocks in your mod?

#

Alternatively, if there’s a native way to parse a JSON response body from an HTTP call

#

New to LUA 🙂

frosty dock
#

you can have a package as a file included with your mod and use it by loading it with NFS, or you can use a module patch with lovely and require it using the module name you assigned to it (this is what is done in Steamodded for including NativeFS as well as lua-reload)

shell tangle
#

I now have Carousel working, thanks for all the help and explanations.

humble tartan
surreal marsh
stray warren
#

Why do I keep getting messages that lovely is a trojan? Windows keeps removing the version.dll file from my Balatro directory.

#

I've been downloading it from the official repository on Github

#

And it won't let me redownload it. It deletes it before I even get a chance to look at it

#

Weird. I get the warning when downloading it from the first image, but not from the Assets section in the second image

royal ether
#

because it is functionally a trojan

stray warren
#

You'd think it would be written somewhere on the repo that messages like that might occur and to ignore them

royal ether
#

it wasnt getting flagged until recently

#

also writing that honestly makes it even more sus

river panther
#

Happened to me today

#

Tried to load up balatro and mods were gone. Windows removed the injector

muted pier
#

finally managed to figure it out how to add custom hands

#

by god you have to rewrite a lot

#

and SMOD register adds the prefix, where most poker hands arent even prefixed and just string keys

hushed cradle
#

can you send a picture of your code or smth??

#

ive been tryna figure it out but im so helpless

sly forge
#

hello modding-dev, looks like people are having trouble with poker hands? First get Bunco. I'm open to DM

#

what are peoples' opinion on prefixes in general / prefixes on Poker Hands?

muted pier
#

basically i overwrite a function in Game which is used to determine the information of the poker hand, and also have a rewrite which is used to add your own poker hand evals. I plan to see if i can edit the SMODS.PokerHand to include an eval function, and code it from that

hushed cradle
#

thank you

stray warren
#

Is there a way to access the current context outside of a function that provides the context as a parameter? I guess context isn't a global value?

muted pier
#

you could override the function and set a local to be equal to context?

#
local last_context = nil

local cal_joker = Card.calculate_joker
function Card:calculate_joker(context)
  last_context = context
  return cal_joker(self, context)
end
stray warren
#

Hmm, I didn't think of that. I'll try it, thanks

#

Although, I don't think calculate_joker will be called at the time my function is called, so the context will be incorrect, whatever it is

muted pier
#

when do you plan on getting the context?

stray warren
#

While in a round. I'm not even sure if it's context that I'm looking for. I'm just trying to check if the user has pressed the Play Hand button and is now in the scoring phase

muted pier
#

context will definitely have that

#

i believe it is context.before

stray warren
#

I guess I need to find where calculate_joker's context parameter is passed in, and see where that is stored

#

Oh I see, the calculate_joker function creates the contexts at the function call

rough furnace