#💻・modding-dev
1 messages · Page 104 of 1
no savescum
No Oopstone
good enough, especially around all the other suggestions
what am I supposed to do when I have 2 of each suit looking for a flush 🥺
??? and Profit! could be at the end. 😆
what does this error mean? Oops! The game crashed:
Syntax error: engine/controller.lua:1511: 'end' expected (to close 'function' at line 1004) near '<eof>'
Additional Context:
Balatro Version: 1.0.1n-FULL (best guess)
Modded Version: 1.0.0~ALPHA-1221b-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.6.0
Stack Traceback
(3) C function 'function: 0x1f05cf38'
(4) global C function 'require'
(5) main chunk of file 'main.lua' at line 1867
(6) global C function 'require'
(7) LÖVE function at file 'boot.lua:323' (best guess)
Local variables:
c = table: 0x1f05a5a8 {identity:false, version:11.5, accelerometerjoystick:true, modules:table: 0x1f05a5f8 (more...)}
openedconsole = boolean: false
confok = boolean: true
conferr = nil
(8) global C function 'xpcall'
(9) LÖVE function at file 'boot.lua:362' (best guess)
Local variables:
result = boolean: true
(10) global C function 'xpcall'
(11) LÖVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])
inerror = boolean: true
deferErrhand = Lua function '(LÖVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])
What do you think of these suit colors? (Im making a modified deck skin with the normal skins i use, but with clubs being more distinct. Ik I could use high contrast, but that ruins the art, so this is a best-of-both-worlds solution)
anything else
looks cool
Gold Stake Only?
Maybe "R.No m"
no jolly
NO JOLLYNESS
what does the joker do?
What is the base card called in the game (The basic white card)? I want to take ownership and replace its atlas with a different one.
this?
Yeah. what is it called in the game's files? I want to take ownership of it.
oh I have no idea of the file name lol, sorry
no Xchips?
hrm, maybe make it look more like a metal plate? add bolts on all 4 corners or something
what would I need to change about the highlighted code in order for this to actually rank up cards
there's no way to directly rank up a card x times, you'll have to repeat ranking it up once x times over
that and i need to code in the creation of the ace of hearts
ah ok that makes sense
we're so seeding this one
where one rank up looks like this under smods conditions
(rather, one rank up of all selected cards in hand, i.e., strength)
should i make that a util function maybe?
never said i was making balanced stuff so go ahead lol
I just need to know what to change g.hand.highlighted to as this is instead a Joker, of course
because idk if g.hand.cards was correct
but ty this helps otherwise
not sure exactly what you're trying to do, but wouldn't you just want to rank up the other_card?
ah right
i might not get your joker effect
what its ment to do is upgrade any played 2-5 (which may not be useful now that im thinking about it but ill make it anyways)
Fixed the art and i'm working on that start of round effect
yeah then you just do it on the other_card
alright
G.hand.cards are the cards held in hand / unplayed
oops yeah thats what I thought but I tried just in case
If I wanted a Joker to half all probabilities in the game, would I need a context if-statement do would I just put it directly in the calculate function?
you'd use add_to_deck / remove_from_deck functions for that to change G.GAME.probabilities.normal
no calculate function needed
Like hook into that or are those params a Joker has?
real
Can you set the sell price of a Joker seperate from its cost?
yes, vanilla jokers literally do this
(egg, gift card)
I mean the base sell price, not having a joker change other sell prices. Is there something like that like cost?
you can set sell_cost manually but it'll be overwritten by set_cost
so you probably want to use the same mechanic that these jokers do with ability.extra_value
just set it in set_ability
So I have this calculate function that looks for dark suits in scoring_hand, and light suits in the hand, and destroys them. Everything gets destroyed as expected, but for some reason after the round is over, the total cards in deck count is higher than the supposed max number of cards in deck at that time (ex. it will say 49/43 in the bottom right)
Here's the video of it happening
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I can't figure out what is going on to make that happen
i think you created a ghost card somewhere
That would make sense, because gaps appear in your hand if you continue the run
I think it has something to do with when I'm dealing with the scoring_hand part of the code, because if I comment that whole section out, I don't have any issues
Okay I'm stupid, Idk how SMODS.create_card works for this
funny banana
only findable after cavendish is deatroyed
I could make it legendary. Imagine getting this out of a soul card
im 99% sure i’d spend it all within one shop, rerolling for blueprint
If I play a flush of clubs or spades with 52 cards in the deck, they all get destroyed and at the end of the round the card counter in the bottom right displays 50/47
So I somehow created 3 ghost cards in that process
you need to assign the card to a variable
and then emplace that
MurphyCardA is a table, not a card object
how do i assign the table to a card?
local _card = SMODS.create_card(MurphyCardA)
ah
I got this properly ranking up cards, only issue is that it increases the rank of all 5-2 ranked cards before scoring, it causes weird visual things like a 4 card giving 3 chips
and then replace MurphyCardA at the emplace and materialize funcs with _card
changed card to _card because card is alr used in the calculate function params
Okay we're getting closer
how do i set the card that spawns to always be the Ace of Hearts tho?
use SMODS.change_base() before you empalce it
oh
for yours, can't you just make it in context.after?
oh there actually is a change to ace of hearts on the wiki, cool
ill see if that works
I'll have to change other code in order for me to be able to do that
I kinda don't like making this Joker im ngl
its effect probably isnt even good
Where in the code does Sixth Sense handle destroying cards in the scoring_hand? I'm checking in card.lua and I can't find it
Did you look at card:start_dissolve()?
trying to make my first mod and im having issues with it
what's the problem?
Yeah, was hoping it would say something about the scoring_hand cardarea, but it doesn't
code?
right here
Do you have the atlas in both the 1x and 2x folders?
do you mean where it actually destroys them rather than flagging them?
I have GrassyMod.png in both assets -> 1x and assets -> 2x
Yeah, basically trying to replicate what it does when destroying cards in the scoring_hand
without creating these weird ghost cards
it's in state_events
Ah, ok. Thanks
O: finally fixed the Malverk switch profiles/reloading atlases crash 🎉
When I call start_dissolve() on a card in G.play.cards do I need to do table.remove(G.play.cards, current_card), or is that done inside that function? Cause when I reload the game, those ghost cards appear back as they were before they were destroyed
Is there a way to have colour override mult_mod's color when returning in calculate?
return {
card = card,
mult_mod = mult,
message = '^' .. card.ability.extra.ExpMult,
colour = G.C.DARK_EDITION,
}
Ok, so when it is all glass cards and they all shatter with shatter(), no ghost cards are created. If it is all regular cards and start_dissolve() is called on them, for some reason ghost cards are created. Anybody have any clue why this might be happening? I'm about to lose my mind trying to figure it out lol
welp, trying to figure it out
Hello, I've gotten into modding and I've got something going with my jokers but...
I don't know how to play custom sounds. I know the code requires the play_sound() function and an SMODS.Sound thing, but apparently I need to add the mod Prefix... but I'm very clueless as to what it means to add the prefix?
Help appreciated, thanks!
Figured it out
Image was named HeavyMetal.png.png 
what is your mod prefix? (either in the mod metadata or smods header)
Does it make a difference or can I use just whatever prefix?
If it's the ladder, currently the prefix is shok
you can set the prefix to whatever, i would recommend keeping it to 3-4 characters
for playing the sound the format is <mod prefix>_<sound name>
Okay thank you so much for the help!
What is the edition param for returning in a Joker's calculate function?
Does anyone know what the if statement would look like to check if card played is steel?
if context.other_card.ability.name == "Steel Card"
sorry, let me correct that
Forgot to add ability before name
awesome thanks!
for anyone who wants to try making their own standard decks, here's my aseprite file with all the blank deck backs. posted these in fan art too but theyre reskins for a holiday mod im a part of 😄 #🎨・fan-art message
o nice! im sadly going to need to do entirely original deck backs due to: hubris
its pretty fun i cant wait to see what you come up with !
I'm trying to use the event manager to make it go and change editions of scored cards one by one, but it's ignoring the event delay only for changing the edition, changing all cards at once, then it scores, and then it shows the status text.
I'm in context.before, so no idea why it's adding it after scoring and not before scoring either.
Any ideas or insights?
is there like a wiki where some of the basics for modding are laid out?
https://github.com/Steamopollys/Steamodded/wiki/API-Documentation
https://github.com/Steamopollys/Steamodded/tree/main/example_mods/Mods
ah sweet, i blazed right past that stuff when i was grabbing steamodded, ty!
if anyone is interested I just spent a couple hours making a balatro color palette filter you can apply to images through Krita using its 'Palettize' filter
It isnt perfect but it is nice if your goal is just to import an image and make it work purely off of colors ripped from existing Jokers, here's a couple examples:
how do i add new jokers into the game
there was also a tutorial video that walks you through simple steps
idk where it is though
you can probably find it by searching in #1209506514763522108
oh yeah I have no idea whats up here
== not =
because languages are ✨ inconsistent ✨
I can't think of a language that uses '=' for equality. The vast majority of them use '=='
pascal and sql off the top of my head
but some use === or is which doesn't help
what do you call the joker that you have on the table
now to find a way to actually implement the ability
Ayo thats cool af
Are a bunch of mods just waiting on updates right now? The only one I can really seem to get working is Cryptid
this description would be better written something like this
When blind is selected, this joker gains X0.1 mult and destroys 1 other random joker
Cannot be sold or destroyed unless captured by a Sealing Card
If this Joker does not destroy another Joker when blind is selected, the run ends
the last line changing makes it not possible to circumvent and neuter this joker's effect by simply having 1 eternal joker, which can't be destroyed
are you on an arranged modpack or just picking mods by yourself
either way would need to see which mods you have to know whats going on
but no, most mods should do something
can you screenshot your mods folder
Most of them load at least to the title screen, but I can't get much further without crashing
I tried a few mods (individually, with any required API or other mods) from this list that were run with Steamodded
https://github.com/jie65535/awesome-balatro?tab=readme-ov-file#awesome-balatro
And again, Cryptid works completely fine with no issue, at least so far
okay well without crashing is a bit more complex
there are some very unstable mods
Therein lies the problem, Cryptid is the only one that hasn't crashed😅
hey look, bunco
This list hasn't been maintained for an unfortunately long while, and contains a lot of 0.9.8 mods.
yeah most of your crashes are likely caused by 0.9.8 mods
Ah, that'd probably do it. Know of any lists like that with more updated mods?
This is the other index I know of, but it hasn't been maintained as much recently. Still a lot more updated than that though. And, yeah, there's dimserene.
https://docs.google.com/spreadsheets/d/1aoJrrC7Y-dkvJwBu_U6amelYnoCrZgWqpoGRAfHN1ys/edit?gid=1869836281#gid=1869836281
thanks!
thanks
what's the color for gray for the currently +X mult line
C:inactive
how do i select a random joker in the joker area to be destroyed
Alright, new question from this idiot (me):
How would I make a joker that triggers every X-cards played?
Best I can give you is this function,
This line, to be specific.
(clueless)
how do i spawn my joker in a test game using debug mod i wanna try it
hover over it in the collection and press 3
see loyalty card
see madness
Every other reference is for the language translation.
search for Loyalty Card
not j_loyalty
the calculate functions always refer to the name in vanilla, not the key
ok
The joker, I think.
Is this what I am looking for?
Probably in card.lua
Madnesser
yeah except for the part that it end the run if theres no destructable joker
in the congif.extra add something like count = 0 and mult_activate = 7
and in the context.individual first check if the id is 7, then increase count by 1
if count == 7 then do the x2 logic
maybe it can work
of your joker yes
when you increase the count, make sure you aren't in context.blueprint or it will increase twice
how do i make a joker end the run
Now I need to figure out how to make a reverse counter.
Which is just subtract active (7) - count (int between 0 and 7)
idk how to do that in here.
why do you need a reverse counter
just +1
For the remaining thing.
count 0, 7 remaining
count 1, 6 remaining
and so on.
For the how many remaining 7s you have to play for it to trigger.
mult_activate - count
But where?
I don't know how to store variables inside jokers and stuff.
(yes, I am stupid)
the joker isnt removing other jokers when a blind starts what am i doing wrong
return {
vars = {
center.ability.extra.s_mult,
center.ability.extra.suit,
}
}
end```
loc_vars is the place for showing data in the joker description
in loc_txt then you can reference them by using #1#, #2# etc like
``` text = {
"Played cards with",
"{C:hearts}#2#{} suit give",
"{C:mult}+#1#{} Mult when scored",
}```
depends if thats what you wanted to know
Checking...
But where and how do I declare variables for a specific joker?
i.e. Any counter, really
And where do I do these funky operations?
can you send your joker code
SMODS.Joker {
key = 'battleworn_insomniac',
loc_txt = {
name = 'Battleworn Insomniac',
text = {
"{X:mult,C:white}x#1#{} every {C:attention}7th{} played 7",
"{C:inactive}#3# remaining{}"
}
},
config = { extra = { Xmult = 2.0 , count = 0 , active = 7 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.Xmult , card.ability.extra.count , card.ability.extra.active} }
end,
}
Yes, I am stupid af.
what are you trying to do?
this is how I would do it
extra = {
Xmult = 2.0,
Xmult_activation = 7
rank = 7
count = 0
}
},```
``` text = {
"{X:mult,C:white}x#1#{} every {C:attention}#2#th{} played #3#",
"{C:inactive}#4# remaining{}"
}```
```return {
vars = {
center.ability.extra.Xmult,
center.ability.extra.Xmult_activation,
center.ability.extra.rank,
center.ability.extra.Xmult_activation - center.ability.extra.count ,
}
}```
so you technically could change which rank triggers it easily etc
in loc_vars you use center instead of card
and also your loc_vars has 3 items instead of 4
huh?
nevermind your function is different
My function does not function
its missing the 4th value in loc_vars
wdym name it
In your loc vars return, each value corresponds to the #1# parts of your description
almost there, I know what I am missing, I think.
th and the substraction
idk
lesgoo
does the joker gain the x2 mult or does the 7th played 7 get a x2 mult when scored?
Let me ask the guy who came up with the idea.
I think the joker gives x2 mult
Not the card played.
Guess I have to learn how to inplement my own Xchips
Now it is time to add the logic to it.
Then the description can be changed into
x2 mult every 7th played
card with rank 7
(X remaining)
good luck 👍🏽
"shouldn't be too hard"
-# Last famous words
-# Doesn't even know where to start
although that joker is kinda pointless
original score 30 x 100
60x100 is the same as 30x200
What is
context.individual
context.cardarea
G.play
Like, what do they refer to?
i stoopid and you know the drill
Trying to gather as much information as I can so I don't have to ask later.
.
ah
that in combination with the cardarea being G.play (the area for played cards) makes this trigger each time a card scores
So under that context I should increase the counter thing, right?
yes
if you play more than one seven does the count increase by 1 or per played 7
Per played 7
then yes
Yes, you are heavely encouraged to play 7s.
if context.other_card:get_id() = 7 then
I suggest you also give the mult on the card instead of the joker and use the same context
it also works on retrigger so you could end up in a situation where 7s are scored more than 7 times in one hand
I'd rather give it with the joker, since it is the joker the one firing the x2 mult
the joker would be giving it to the card
the vanilla-like effect is giving it to the card instead of in the main scoring phase imo
ah
it's still the joker giving it, but it triggers on the card scored
Then I guess I'll do it your way.
I am fine with it.
So, what do I need for the conditional?
the other option is to do everything based solely on the hand, in which case you're not counting retriggers
context.individual and...
getting error at juice_up
(*temporary) = string: "attempt to call method 'juice_up' (a nil value)"
context.individual and context.cardarea == G.play
Also check for not context.bluepring when changing the counter
you can just copy this and replace 10 with 7 and remove the 4
anywhere vanilla calculate uses self, you should use card
in Steamodded calculate, card is the actual card while self is just the prototype/center
ah ok
which you can otherwise access as card.config.center, so it's mostly out of OOP conventions
so this?
LETS GO IT WORKED
I swear I am trying.
ok now for the run ending function
you should do a specific if encapsulating the code that increases the count inside that if
yeah, except you might want to move the blueprint check in as a separate if statement
unless blueprint cannot copy the x2 mult (your decision)
is there a function that allows a joker to end a run
debugplus has a button that makes you insta lose
I am fine blueprint blueprinting my stuff.
dis good?
if context.other_card:get.id() == 10 and not context.blueprint
i cant find the function in the debugplus mod
as in the code
i can use it ingame
actually these two ifs probably shoould be separatae
you sent this picture 
isnt there a recent tutorial vid
what's the pool for blinds?
weird, me neither
G.P_BLINDS
jelp
you should increase the count without the eval there
then later, if the increased count is 7 it does the x2 mult, otherwise it displays the upgrade
Wouldn't I get like 2 messages or something then?
G.FUNCS.DT_lose_game = function() if G.STAGE == G.STAGES.RUN then G.STATE = G.STATES.GAME_OVER; G.STATE_COMPLETE = false end end
x2 mult is in the if, upgrade is in the else
these are confusing, context.individual is different from the rest
I believe it's x_mult = 2 here
but might be XMult, can't check rn
That applies it to the jonkler, tho.
I believe.
no
yeah its x_mult
how do i remove specific blinds from the game
you kindly ask them to piss off
:3
will be updating that thing soon
is this the end game function?
yeah i knew that mod but i don't want to only disable them i want them to get the hell out of my sight
wym get them out of your sight?
like, not in the collection?
that's what debugplus uses for it at least
take ownership, set in_pool to a function that always returns false and set no_collection = true
I guess i'll just remove them from code (it's easier for me)
oh, didnt know "no_collection" was a thing
that's because I just added it a few days ago
might add that as a config
imagine using in_pool 
true queen
how do i make a joker eternal without the eternal sticker
like unable to be destroyed or sold
card.ability.eternal = true?
that will add the sticker

damn
eh i'll have to put up with the eternal sticker i guess
how do i make a joker appear in a shop with debugplus
you can only directly spawn it into your joker slots
the preorder mod lets you add jokers in the shop
I don't know why, but when the counter thing reaches zero nothing happens, help.
(Sort of, if I uncomment --card.ability.extra.count = 0 it does reset.)
try adding "and context.joker_main" to this idk
dis?
yeah
Check
then in return add card = card,
wat

here's my dingaling
why doesnt it spawn the correct Joker?
it spawned a random joker instead
j_ - joker
jgl_ - your custom prefix
battleworn_insomniac - card name thing
not certain
where is the jgl coming from
My mod prefix
i mean where do you get the prefix
The json you bundle up with your mod
Or if you are using the old thing the prefix field
im using lovely theres no json
At the start of your mod file.
You should have the mod name, author and stuff.
There should be a prefix field.
you're using lovely to make jokers?
ok good it worked
This is still not working. I suspect it is because this isn't the joker phase but rather the playing card triggering phase thing. How do I make so it gives the x2 Mult it should?
Someone should host a best balatro mod of the year award thing
Why is this triggering my jokers twice?
That’ll trigger many times
calculate_joker is like always called with scoring_hand set
Then you want to use context.before and check that the played hand is only 1 card
so true
#G.play.cards i think
Testing 2
Context full hand would work too
dis?
yes brah 💯
me am now confused
wait, that sh*t is a table™️ or something?
# count the table brah
#count_the_table
got ya
🥶
ah yes 240k ante 1 small blind
Very possible.
cryptid
Cryptid gameset UI be like
is there a mod that can put jokers into playing deck
like converting a joker into a playing card type
hi i need help!! (please)
this joker is supposed to gain mult for every played diamond card and then destroy those cards. The gaining mult part seems to be working (though it doesn't seem like the upgrade message is working) but idk what type of warcrimes my attempt at destroying cards is committing because it is NOT working
calculate = function(self,card,context)
local destroyed_cards = {}
if not context.blueprint then
if context.individual and context.cardarea == G.play then
-- Is played card diamond?
if context.other_card:is_suit('Diamonds', nil, true) then
-- If so, add mult and add card to the destroy queue
card.ability.extra.CurMult = card.ability.extra.CurMult + card.ability.extra.CardMod
destroyed_cards[#destroyed_cards+1] = context.other_card
return {
message = 'Upgrade!',
colour = G.C.FILTER,
card = card
}
end
end
end
if context.joker_main then
-- Delete all cards in the queue
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
play_sound('tarot1')
for i=#destroyed_cards, 1, -1 do
local ncard = destroyed_cards[i]
if ncard.ability.name == 'Glass Card' then
ncard:shatter()
else
ncard:start_dissolve(nil, i == #destroyed_cards)
end
end
return true
end
}))
return {
card = card,
mult = card.ability.extra.CurMult,
message = '+' .. card.ability.extra.CurMult .. ' Mult',
colour = G.C.MULT
}
end
end
also sorry for the giant message lmao
hi k
use context.destroying_card to destroy cards, for example
if context.destroying_card and not context.blueprint and not context.destroying_card.ability.eternal then
return true
end
also you'll need to do your check in that context, your destroyed_cards table will be set to empty everytime the calculate runs
oh ok
so i should just check if the card is a diamond in this context and return true if it is?
(you don't even need destroyed_cards using this)
yea
i'm guessing i should put it inside this if statement?
no, outside
alr
doesn't seem to be working
sorry it took like 10 minutes to test i couldn't find the card in the shop lmaop
this is what i have
oops wait
shit am i stupid
the not before the eternal thing just deleted itself at some point
ok let me try now
oh no i have it insalled dw
i just set my money to 50k and reroll until i find it like a normal person
you can do that??
collection > jokers > hover over the card and (ctrl+)3
oh
thank you!!!
i have wasted probably hours of my life looking for cards in the shop i'm not even joking 😭
still doesn't seem to be destroying the cards though
actually let me try rebooting the game completely
just in case
ok then rebooting the game fixed it
thanks for helping!!
currently writing a mod to force enable Steamworks API integration when running balatro on Linux
[S_API] SteamAPI_Init(): Loaded '/home/cappy/.local/share/Steam/linux64/steamclient.so' OK.
Couldn't connect to steam...
Please ensure that the following conditions are met:
* Do you have Steam turned on?
* If not running from steam, do you have a correct steam_appid.txt file?
* Is the application running under the same user context as steam?
* Is a license for the App ID present in your active steam account?
* Is your App ID correctly set up, i.e. not in ``Release State: Unavailable`` and not missing default packages?
skull
I got it to load luasteam but it can't connect to steam when using lovely
wtf
nvm it loads fine when Steamodded isnt loaded
so I guess it's a Steamodded bug
currently looking at what steamodded modifies so i can see where it fucks up
if i wanted a joker to gain something when cards are discarded, would it be context.pre_discard or context.discard?
So, is there a way to give Xmult to cards via a joker
i.e. aside from the normal scoring, a card also gives x2 multi
oh yeah, shit
forgot that got added
lemme
i have a joker that gives mult, you should be able to just replace it with xmult
balatro modding expirence
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
context.other_card.ability.mult = context.other_card.ability.mult or 0
context.other_card.ability.mult = context.other_card.ability.mult + card.ability.extra.mult_gain
return {
extra = {message = localize('k_upgrade_ex'), colour = G.C.MULT},
colour = G.C.MULT,
card = card
}
end
end
``` this is what i have, its essenitally just hikers code but for mult
i presume it'd be context.other_card.ability.Xmult or xmult
I'll check.
im not sure if smods has been updated to handle jokers giving cards extra values, but if not i have the code that makes that work too
What does the thing inside the return do?
it makes the joker give the "Upgrade!" message, makes sure its colour is set to mult, and does the jiggle thing
is there a way to prevent a joker from being sold right at the start of the game
if you want it to be entirely unsellable, you can give it the eternal sticker
if you want it to be temporary, I'm less sure about that
yeah but when the round start but before selecting a blind the eternal sticker isnt applied yet
so you can just
sell the joker
since the sticker only applies AFTER you go into a blind
huh
why does the sticker wait til selecting a blind? it doesn't in vanilla challenges
"Start with a deck" 🔥
my first try would be putting set eternal after add to deck
(it would be weird for that to make a difference at all, but weird in the way i expect programming to be weird sometimes, so worth trying)
my second try would be to look at the vanilla code to see what it does for its challenges that center around an eternal card
arent i a great programmer
certified css moment
hmm i should change it to challengs instead of deck
Bumping this, and @wintry solar, if you wouldn't mind, I'd appreciate if you took a look, since this feels like something that falls under your wheelhouse.
I know, my pixel art level is not the best, but i'm trying
I'm using the jimbos as a base obviously (because everyone's a jimbo at the end of the day)
why does my text input UI hide most other UI unless you're typing in it?
i need help i updated steamodded to the most recent version and my mod just stopped working
the mod is detected, but the card that i added aren't there
And there, after some cleaning up and changing pixel movements
Roffle:
1 in 5 chance to create a Negative copy of 1 random consumable card in your possession at the end of the shop
This Joker gains X0.25 Mult for each card sold, halved when Boss Blind is defeated
It's Campfire + Chance at Perkeo
well damn
I think this alone is causing a crash and I'm not sure why
everything else works well its just this
You somehow picked line the least useful part of the crash log
Send the entire crash
I'll send the rest of this code aswell incase theres something there that may need to be fixed
for reference I kinda just want this card to display how many rounds it has left when creating a card
its supposed to be destroyed after 10 or so rounds
this must be a weird case where nobody knows what the issue is
so I guess this means I have no idea how to get this joker to display a message when blind is selected
it might be smth stupid lol
show code
the
Uhhh I’ve started looking at something similar to this but with enhancements. It’s to do with when values are updated, once I’ve sorted my stuff out I’ll let you know and you can refer to it
Text inputs are funky
😭
yeah text inputs are cursed
idk would need a copy of your functions/common_events.lua around line 2224
from the lovely dump
I think thats the base game's files
yes but it's patched by lovely so it's different on your machine than mine unless we have the exact same patches
oh huh
when checking the lua file I have extracted before, its this interestingly enough
which doesnt seem related to what I'm doing
did you grab the rightfile?
its functions/common_events.lua yeah
from your lovely dumps?
oh wait no this is extracted from the exe
oops
ah so its this
is it actually an issue with my consumeables creation thing instead hand on I mightve mispelled smth
YEAH
its 'Consumeables' not 'Consumeable'
sorry to bother ya then
Alright, no idea how this is meant to work.
what do you mean raisedcateyebrow~2
need someone to help me on how to create a joker with an eternal seal attached BEFORE the blind start
or should i just make it a challenges instead
How do I make it work?
It just shows the upgrade text.
And that's about it.
it doesnt change the cards value?
No.
Curious... can't you set a specific variable on the created Joker during creation and in the update part of the Joker itself, check if the variable had been set and, if so, apply Eternal to itself? (i.e. set card.ability.extra.deckcreate = true and check for that within update of Joker itself.)
'sides, it looks like the upgrade would be permanent, while I want it to be just this one round.
/hand
i understand half of the thing you said
oh, i have no idea how to do that 😭 i presume you could do something like:
if context.after then
[iterate over deck] then
context.other_card.ability.mult == 0
end
end
but thats just a guess
I am thinking it could set a variable to true then add a context.joker_main and that variable and if it is true, trigger the x2 thing
Like, once the counter reaches 7, do that.
I don't know.
if you want to make the values appear on cards, copy the code in #1315304310707327017
sure
the counter on the joker?
wdym by update
So, before you emplace the created Joker, set card.ability.extra.deckcreate = true. Go to where you define the Joker and
update = function(self, card)
if card.ability.extra.deckcreate and card.ability.extra.deckcreate == true and not card.ability.eternal then
card:set_eternal(true)
card.ability.eternal = true
card.ability.extra.deckcreate = false
end
end
do i need to add deckcreate into var
Not necessarily.
oh yeah, quick question, if a joker spawns as eternal, can it still destroy itself or would i need to find another way to make it unsellable/undestroyable?
woky af
idk if it will work.
But I need to carry a variable for the joker to trigger.
yeah no its still sellable
(as in, if its own calculate has a way to destroy the joker, will it work or will its eternal-ness stop it?)
It can be destroyed, yeah. My Karting Joker self-destructs even if Eternal.
oh thank god 😭
Not so eternal, huh?
-# your missing an end
looks fine? but no idea 😭
the eternal seal only apply after i choose a blind
if i get the joker card before choosing the blind no seal apply
Did you set the update function in the Joker definition? That runs every single frame.
It imploded because of a typo lol
Though, I guess card.ability.extra.deckcreate = false could also be card.ability.extra.deckcreate = nil so that it's not defined anymore for other stuff to mess with it.
thanks for the help
now to make another card that can capture jokers
oh there's the pokemon mod that is similar
I did it! It works!
(stoopid OBS, but you get it, right?)
Is not even mine, lol.
I asked suggestions for jokers related to Rhythm Doctor and A Dance of Fire and Ice and I got that.
still, i like it
is there a more direct way to level up a hand multiple times or am I gonna have to do level_up = true multiple times
huh, this is odd
My tag freezes when it tries to load the pack
but not a usual crash
like actually freezes
oh it's not a me issue
its' happening with any modded tag it seems
does context.glass_shattered even work in this sort of context
wait do I also have to do some sort of card destroyed context aswell
yeah idk what to do here
maybe I got it
ok no
please someone help me with this 😭
i dont understand why create_text_input does this
How would you deduct money when a joker is sold? Do you set the sell cost to a negative number?
okay so apparently it just hides everything that comes after it
that may work yeah
if not, make the sell value zero and remove money with an ability instead
i forgot about those names oops
Setting it to a negative kinda words, but you can sell it even when the player doesnt have enough money ($1 with a $-4 sell value leads to $-3).
Is there a way to prevent a joker from being sold until certain conditions are met?
this is human nature at its finest
Why the fuck is cryptid the only card to use this color
It doesn't even fit in the pallete
ism stg
getting this error at the end of the round, when using this joker
no idea why its throwing an error 😭
im gettin somewhere
you didnt change the names?
I don't really consider this an issue, I like this, but I realized the glitched enhancement also changes values that are not even displayed on the card
I wonder if I could make it where the amount of retriggers is displayed when given the glitched enhancement
piss yellow
When selling a Joker, is there a way to remove the sell animation on the dollars UI? I only want it to show the animation for ease_dollars in this case.
remove_from_deck = function(self, card, from_debuff)
-- Pay off debt
ease_dollars(-card.ability.extra.owed)
G.GAME.bankrupt_at = G.GAME.bankrupt_at + card.ability.extra.debt
end,
update = function(self, card, dt)
-- Check if the player can afford the interest
if (G.GAME.dollars - card.ability.extra.owed) >= 0 then
-- Joker can be sold
card.ability.eternal = false
else
-- Joker cannot be sold
card.ability.eternal = true
end
end,
Any suggestions on how to render these cards properly?
seeing the atlas may help
You're looking at it
SMODS.Atlas {
key = 'disenhancement_confused',
px = 87,
py = 118,
path = 'vic_confused.png'
}
cuz first off that sprite is larger than the typical card so the issue may be related to that
Yes I know it is related to that
ok sorry I thought id be able to help but idk what the issue is here myself
I knew the alignment was based on the top of the atlas
You’d have to adjust the size of the card itself afaik
I remember there being no cropping when I did some taller cards, but the alignment worked because the card was tall but the top was properly aligned
Oh it’s cropped too
Do you know how to both change the size of the card and change the alignment
Look at wee joker in set ability
The documentation for SMODS.Enhancement doesn't say that's an option
They should have a set ability function afaik
I'll try it
Do you know where I set the offset?
I believe that's an option but I don't know where
Actually maybe it would be in set_ability too
It would yeah
Looking at a wide Joker I have, I needed set_ability, set_sprites, and load
oh yeah I need some help here
I'm just trying to make the context when a card breaks, this card is supposed to level up the played hand when a glass card is broken
it causes a crash related to ipairs
I decided to take some code from Glass Joker
Hi chat
might change the color of Cryptid (the mod) to this now lmao
btw shouldn't we move SMODS.Enhancement docs into SMODS.Center?
We could do yeah
Either that or separate out the center docs
I’m not sure people who are new would know to look there
(im people who are new)
heres the crash
Hello, good people. 2 quick questions:
- Is there a way to fix the +- problem in the joker description?
- What is the context.XXX for defeating a boss blind?
it may help to see the joker's code
yeah it's a little crowded in there ngl
you're not checking for context
at least if context.glass_shattered, maybe also and next(context.glass_shatered)
also the context for beating a blind is context.end_of_round = true but I forget what it is for specifically the boss blind, check campfire's code in the lovely dump
or rocket
Alright.
@zealous glen didnt u try to work on #1272112266246094902
imma be honest, when people tell me look at the other joker's code half of the battle is figuring out what joker to look as an example
I would like a keybind for multiline comments in Lua that doesn't suck
wait do I even need to use the ipairs junk
no I just used the specific artwork as permitted
maybe not
Idk how the context works
Ah alr cause I'm making the mod rn just so u know
ok natsuki
Could be this what I am looking for?
so G.GAME.blind.boss?
thunk uses a giant tower of conditions
so you need "every" condition on top
sometimes you can reduce
but as mentioned you need to check you're defeating a Blind
that seems to have not worked at all
Cool mod! the offset click position in the video is messing with me
@wintry solar set_ability and set_sprites didn't quite work
errrr...
i dont know what you did but you definitely set the ability to some eldritch abominable enhancement
idk
I need it to trigger once after the boos blind is defeated.
I looked for campfire code.
if G.Game.blind.boss and context.end_of_blind then
or whatever the end of blind context was
as we said before
does anyone have any idea how I'm supposed to make a joker trigger when a glass card is shattered, I've tried everything (including looking at glass joker's code) and nothing works
It triggers like 8 times for some reason.
oh weird
if context.end_of_round and not context.repetition and not context.individual
Yeah, just looked it up, but thanks you.
I mean what are you doing compred to Glass Joker
something along the lines of this
well there shouldn't've been an extra end there but yeah
this is what happens
You're still not checking if the context exists
Does -2 joker slots seem right for the pros of this card? Originally, i had it as -3.
seems fine when you compare this to Cryptid's Wormhole Deck
seems fine when you compare this to Cryptid
problem:
its cryptid
@mellow sable do you know how to manipulate Enhancement sprite sizes and offsets?
I haven't messed with it
I suspect I'll need a hook or injection to apply the offset, and anoter to fix the size issue. The size issue might be better as a Steamodded change
I remember doing something like this via having the atlas size differ from the default.
Because what I have in mind is to have all playing card centers set their own size
But that code is so old idk if it still works
I mean I have an oversized Joker
I have some code knocking around somewhere that offset the seal sprite, that might help?
I tried both context.destroyed and context.remove_playing_card, the first does nothing and the latter causes a crash
Maybe!
Note that the drawing for this might not work for enhancements specifically (since this is drawn on top I believe?) but the idea might work
flowey I already know how to configure the Atlas
also we worked on that together
I had that code open already
the one behind the 2 of diamonds looks correct
that's the result of applying the Enhancement twice
so it's twice as big
logarithmically
can I see what code you've got so far?
ok if I move the code from set_sprites into set_ability it doesn't crop
althought I can see that it also scales the rank and suit
if self.ability.floating_away then
self.ability.floating_away = self.ability.floating_away - 0.075
G.shared_seals[self.seal]:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod, self.T.w*-0.38 + 0.3*math.cos(self.ability.floating_away), self.ability.floating_away + self.T.h*-0.65)
else
if SMODS.Seals[self.seal] and SMODS.Seals[self.seal].balloon then
G.shared_seals[self.seal]:draw_shader('dissolve', nil, nil, nil, self.children.center, nil, nil, self.T.w*-0.38, self.T.h*-0.65)
else
G.shared_seals[self.seal]:draw_shader('dissolve', nil, nil, nil, self.children.center)
end
end
looks like my offset and movement was patched into Card:draw
Yes I was thinking I'd need to patch it.
though I think there are smods hooks into card:draw now
by the way, what do you think of modifying SMODS.Enhancement so that by default it sets its sprite size back to normal?
if you leave the size alone and just alter the drawing it wouldn't need that
Enhancements behave as centers so yeah they should have access to it
altho idk if there comes a problem if the center is drawn then redrawn with offset.
what do you mean?
changing the draw method when your enhancement is in effect wouldn't need you to change the size of the card itself
you just scale up the drawing of the center of the card
The scale of the drawing is correct
It just needs to avoid cropping and be offset
if you know how to do it without changing the size
I could do that
this is what I currently got, no crash but it doesnt print
-2 slots? ^1.33 sounds right.
IIRC Glass Joker just looks at how many glass cards were destroyed. I'm not sure v.shatered exists
ah
if I could just detect when a card is destroyed during play I might be fine at this point
Thoughts?
thats so different
I took anaglyph's notion of incentivizing skipping and then worked with that
Should the debt amount be higher or is 40 good? Im trying to make it like a better Credit Card, but with its downsides too.
where would one, such as me, aka i, find a list of all the events in balatro?
wait i think i mean contexts
like the code used for:
when a pack is opened
when a consumable is used
when a blind is selected
all of those
isnt that list also on Steamodded's wiki
there was a link for that in there anyways
oh yeah this is great stuff
ty mx. cryptid
to be able to detect if a destroyed card is a glass card, would I do if cards_destroyed.enhancement == 'Glass'
it's written out differently on the wiki
if you're new the wiki is definitely better
if you just need a quick reference my original list is fine
do you have a link to the wiki ?
ty!!
Do you @wintry solar ?
like I said, I think you can do it by patching the draw function
this doesnt seem to be leveling up the hand, is there anything I'm missing?
Hey so if I want to rework a joker or blind for a specific deck, I pretty much have to use lovely for that right?
For a joker there's a take_ownership function, but for blind I think you need lovely yea
or at least function pilling
I was prolly gonna use lovely either way but neat !
i quickly made a little test mod thats adds 1 joker, but its not appearing and im not sure why
i have the 1x and 2x folders in assets, and the main.lua file in the folder for the mod itself
this still doesnt work
take_ownership also works for blinds
--[[
multi
line
comment
]]
so you can just type -- at the beginning, then select the block and type [[
Neat
pov:
--[=====[
comment here
--]=====]
I asked for a keybind 😅 I know I can comment manually
the existing keybind doesn't do what I want it to do IMO
the block comment keybind doesn't comment the entire line, and I feel like the line-by-line keybind isn't what I should be using for multiline comments
lol
uhhhh idk, i haven't used a keybind for this, i was satisfied to learn that i didn't need to comment every individual line
in most text editors and programming languages CTRL + / comments
I'm away from my computer rn but where is the existing keybind anyway? i might look into this later
so for example in Python it adds # to the beginning of every line
I might just change CTRL + ; into CTRL + /
i should ask, is there a thing i actually need to do first before my mod appears in the game?
i kinda just put the code for a test joker and the mod isnt appearing in the mods menu
pretty sure you dont need the ending --
unless that was a typo
you don't need it, but i like to include it anyways
basically you can just uncomment the top delimiter to uncomment the full block
This one's a little different because they got an avatar
how do I get the name of the currently scoring hand
apparently context.scoring_name doesnt work
where?
context.scoring_name works in contexts that provide it
ok idk how to do it actually, anyways im tryna make the current hand level up after a glass card breaks
kid named context.glass_shattered:
I remember that not working
Kid named kid:
guess I'll try this again but anyways yeah I get a crash when using context.scoring_name here, changing it to be like 'High Card' worked though
yeah scoring_name doesn't exist in glass_shattered I'm pretty sure
oh so do I have to do some kind of last played hand context then?
I dont remember what that is though
hey so does the take_ownership function only modify the variables like rarity and stuff or can it also completely rework the logic as well
it can take any functions that steamodded APIs support and usually it'll bypass the base game's logic too if it's a vanilla object
Gotcha
does anyone know why my mod just straight up doesnt exist? I made a little test mod that adds a joker that does literally nothing and it doesnt show up in collection or mods, is there something else i need to do first?
And I can just plug that into the back.apply of a deck to make it apply for only that deck?
i can send an example if need be
youre missing [modname].json
theres more info about that in steammodded's wiki page
okay yeah i do remember there needing to be a file like this when modding minecraft so that makes sense
is there any place it needs to go in particular? or just in the folder
wait nvm it says that lawl
thanks again
also also !! is there a way to automatically unlock the custom joker just so i can quickly see what it does?
like some mod or line of code that helps with that
orrrr actually theres the unlock all thing lol nvm
I got it working, but for future reference, it doesnt seem like that works for if statements
what do you mean
it did not work for me whatsoever, I even tried it while including context.remove_playing_cards
does anyone know what this is actually referring to? https://github.com/Steamopollys/Steamodded/issues/104
from what i can tell, you just call ease_dollars and put a message either thru return value or eval_this
Is there a way to distinguish what type of pack you're skipping in the code? Because I want to have it to where it has more rewards when skipping a mega pack than just a normal one
Can't remember when this was initially proposed, still can't remember now.
Maybe it's about dollar_buffer?
how would I be able to detect the ability of a card that was just destroyed had
wait I could just detect is the scoring hand has a glass card
wait I think I got it
i dont
oh I realized theres some very clear problems here
context.remove_playing_cards is after a discard
am i being silly
ok whats weird is that context.cards_destroyed doesnt work, what
hm, trying to add it to eval_this and having a bit of an issue, in context.individual eval_this will fire before any other effects returned from the context will, so the effect happens before the chips from the playing cards themselves
Got an idea
What is instead of calling eval_this inside the context, what about returning a callback function that has eval_this, then calls it when effects are checked (like if effects[ii].eval_this).
Should work for context.individual since it's logic is handled that way
i dunno, eval_this just doesn't seem to be built with context.individual in mind
just confirmed it does the same for other evals, the message pops up before the card itself
i don't think there's a reasonable way to delay it
So it's more of a eval_this limitation, hmm
so passing eval_this thru the return might be the only option there
individual context is already different enough, so why not throw that in, idk

hm so that's why the game never uses card_eval_status_text and actually supports multiple effects in one return for individual
then again that means there's not much of a need to ever use eval_this under those conditions
I'd say we keep it without individual in mind and just keep the boilerplate around for individual
we can't patch it into evaluate_play because that breaks vanilla jokers
(in which case it's inconsistent to get rid of it at all, so keep it?)
anything against not caring about two lines of boilerplate code?
No not really
while I'm closing issues, I should bring up this https://github.com/Steamopollys/Steamodded/issues/14
i think it's completely unnecessary
i wouldn't mind some way to make more profiles
Auto-backup of player saves in case of corruption is nice, but idk if that's even a risk anymore.
but that doesn't need to be part of steamodded, and not in some way that syncs to vanilla saves
Plus it's practically unfeasible to separate vanilla from steamodded.
I defined these custom colors, but how do I make them able to be used in loc_txt within the curly braces? (like {C:dark_suit})
G.C.DARK_SUIT = HEX('324975')
G.C.LIGHT_SUIT = HEX('f05250')
we're stable enough where that doesn't happen usually, you can mess a run up badly enough for the save to be unrecoverable though, which doesn't affect profile data
patch loc_colour function to include them
Ah, that's a separate thing. Makes sense
(is that significant enough to warrant some SMODS.LocColour api? i don't think so)
It's really easy to make a hook into loc_colour too.
Balatro's art style is surprisingly easy to replicate.
(Though I'm not sure why my numbers aren't appearing in the blue box for chips)
why does this not work? I'm like 99% sure it has to do with the context because it works with other contexts just not skipping_booster
iirc you don't even need to patch loc_colour
throwing G.ARGS.LOC_COLOURS['Zodiac'] = HEX("a84040") for example in works
as long as you call loc_colour at some point
Ok, so is having the {C:x} in the loc_text calling loc_colour?
So if I do the above and put {C:zodiac} that will color that portion in the zodiac color as defined?
yeah you just need to do loc_colour('red') or something before you try and assign any of them
btw for future reference sorry for asking so many questions
That's what this channel is for. No need to apologize for it
Should be G.joker.cards
Make sure you are including the mod prefix when you pass the key into jokers_contains. that may be your issue
no, just prefix_exodia_left_arm I think
Also I think the prefix gets cut off after 4 characters, so try both
if context.end_of_round and not context.repetition and context.game_over == false and not context.blueprint then
if card.ability.extra.chance == 1 then
card.ability.extra.chance = G.GAME.probabilities.normal + card.ability.extra.odds_gain
end
else
card.ability.extra.chance = card.ability.extra.chance + G.GAME.probabilities.normal + card.ability.extra.odds_gain
end
doing the thing above caused the error below
basically i want it to go from 1 in chance to 2 in chance
then go from 2 to 3 and start considering probability
You put an end in front of the else, try removing that end