#đ»ă»modding-dev
1 messages · Page 121 of 1
ok, let me try to restructure this without using update
Balatro has severe solo dev syndrome
wait actually
that man does not know how to do comments
i recently made deck that starts you on ante 2. im wondering if instead is there a way to skip you to the ante 1 boss shop? so just before ante 2. giving you a single shop before really starting?
when I was making my steel joker fusion I just made it update during context.before and every context that involved adding or removing cards
at all
XD
any gamedev codebase is guaranteed to have some junk in it. if it's good enough to support the complexity of an award-winning game then its a good enough codebase imo
it looks like he has a load of stuff that calculates every frame
it's a great game no questions asked, but solo dev syndrome is very real
better a game that exists than doesn't
what happened to glass joker
most people would never think to care so that's fine
we all would write code like this if we knew no one was gonna review it to get it merged
it checks for destroying cards like 3 different times
i mean
not like it does much right
good to be thorough
oh god you do not know how dense create_card is
I write code like this even knowing people might look at it đ
i feel like the real crime in that situation would be packing create_card instead of Card:init
that function has left me stumped for hours
you screenshotted get_current_pool though?
shoot lol
I write code like this because I want it to compile at all
i am an idiot
everything i was saying about create_card
its actually that one
im sorry
I write code like this because I know that I get to decide what to do with it ultimately
-# I just make it seem like y'all have some power so I'm not overthrown by some different project
but yeah get_current_pool is an evil function birthed from hell itself
idk why you think that it looks fine. Like it's not good but not that kind of atrocity.
That is an atrocity
at least thunk uses sensible variable names
nothing compares to Card:calculate_joker in terms of atrocity
why the hell do all the edition consumables SHARE THE SAME CODE
actually that one is surprisingly ordered
weird crash, need halp
How would I make a joker gain mult based on every copy of that joker (gains 0.5x per activation per copy of that joker)
ye
the edition consumables is easy to understand what it does I just have no idea why it's written that way
you can just use ctrl f to navigate
check luigi from cryptid
not the same but triggers on other joker
might be useful
ehhhhh not really
seems more like something like stone joker
why is one joker's effects in like 4 different places in the code
in which case it would be in update
different parts of the effect
SDM0's has a joker that does this with +3 mult (also copies itself onto other jokers though)
(dev branch iirc)
the only joker that happens to is glass joker
no don't normalise counting effects in update
and oh god i hate glass joker
okay i just looked its fine idk what you mean
theres also 1 comment not 3
i misremembered the function lol it was get_current_pool
plenty have at least 2 in calculate
yall can i get some help please?
and there's other individual effects sprinkled across all the other functions too
the only one that has like 3 is glass joker
whatever
this is the dumbest argument ever
Where in the files would I find Luigi
there is no argument lmao
Ctrl + f isnât helping me
misc_jokers
lets just accept that balatro is held together by duct tape and prayers but if it ain broke, dont fix it
can we just accept that Every played card counts in scoring
and my complete lack of social awareness strikes once again
what do you mean nope
talking to people who have been fixing unbroken things for the past X months
have you literally ever played balatro
I love finding those while scrolling through the source code đ€Ł
if it ain't broke it'll probably break the instant anyone tries to do anything outlandish with it
at least that's how the blind system went
still waiting for the day that local thunk ships the game with the debug menu enabled
could you stop doing code review for 2 seconds to help me with this crash please!?
help i am being owned
someone get me into the icu
im being seperated from my copium
how would getting into the icu help you they just make movies
lets talk about how good better calc is omg you can return chips from any context and it will be happy with it
how to not perform unnecessary commands when exiting a run? (like giving 22 tarots when exiting a run)
Yall im attempting to make a mod, and im really confused on some of this stuff. Some of the example mods i found have a large block of comments at the top that say the mod name and description and stuff. And then others have a json file that says the same things. Is there a reason for this?
intesive care unit in a hospital
the big comment block is old format don't use it
ohhh i thought you said extra fries my bad
2 different ways of expressing the same data
rrrr that reminds me I need to do the json format metadata
anyone got a template file I can grab
on the wiki linked above
there is one in the mod metadata link no?
That has me cracking up more than it should
.
it just feels wrong to use json and i dont know why
i was hoping to be able to download an empty json file with the template in it
i don't know how to just
manifest a json file
do you know how to copy-paste
yeah
what
wdym what
yeah json files are just text
they're not special. they're just text
it's the content of the file that matters
give luchador when there are no luchadors in G.jokers?
yeah how else are you making files
welcome back chicot???
how many times do i have to link this post in order for its existence to be acknowledged
I rewatched te same tutorial 20 times just to get something kind of working so can somebody tell me what if context.other_joker and context.other_joker.ability.set == "Joker" then in the cryptid mod luigi joker does (I know what the if and then are but I'm confused on everything else)
I only know about 10% of what Iâm doing and thereâs maybe 2 YouTube tutorials for this
Is it just checking all the other jokers for if they are jokers?
that sure seems to be what that line does yes
How would I make it be a specific type of joker?
Replace âJokerâ with the name of the joker?
preferably checking its center_key
this does not help
that's its ID and will not break if the user loads a different language
(...unless joker names don't change internally and are just loc'd later, i wouldn't put that past thunk...)
you're using the newest smods which completely rewrites calculation
thats why you're crashing
i have this code so far
local hook3 = Card.calculate_joker
function Card:calculate_joker(context)
if not (G.GAME.blind.name == "bl_pencil_arrow" and (context.repetition or context.retrigger_joker_check)) then
return hook3(self, context)
end
end
local hook4 = Card.calculate_seal
function Card:calculate_seal(context)
if not (G.GAME.blind.name == "bl_pencil_arrow" and context.repetition) then
return hook4(self, context)
end
end
local hook5 = G.FUNCS.evaluate_play
G.FUNCS.evaluate_play = function(e)
local ret = hook5(e)
for k, v in ipairs(G.GAME.blind.debuffs or {}) do
SMODS.debuff_card(v, false, "bl_pencil_arrow")
SMODS.recalc_debuff(v)
end
G.GAME.blind.debuffs = nil
return ret
end
How would I then change the amount of xmult that a joker gives
use config
What would that look like
constellation
this is basically just a simple lua syntax question (since I have no idea how scope works in lua...). I'm looking to define a helper function recalculate_steel_tally within my take_ownership on steel joker, just so I can avoid copy+pasting the same code in two places. What's the right place to put that? I've tried a few so far and just getting various levels of syntax error/nil values
Where is constellation in the files?
card.lua
main scope of file
chat this is just an idea but
when I do that, pairs(G.playing_cards) starts to complain which made me think that was missing some context
what would be cooler? 1 in 4 chance to not consume a discard, or the same but for a hand?
so like when you discard/play a hand, the counter has a chance to just not go down basically
1st one imo
yeah feels a little more interesting
Is there a way to make it cap at a certain probability?
as long as you have enough cards in your deck
probably? maybe you can like
if g.game.probability > 2,
2 in 4 chance
so you just automatically set it to 1 in 2 so its not
kinda just a free win
calculate = function(self,card,context)
if context.other_joker and context.other_joker.ability.set == "BORBJOKER" then
return{
self.ability.x_mult = self.ability.x_mult + self.ability.extra
if context.joker_main then
return {
card = card,
Xmult_mod = card.ability.extra.Xmult,
message = 'X' .. card.ability.extra.Xmult,
colour = G.C.MULT
}
end
end,
I have up to this point but I donât know what to do
mismatched {}
give a luchador card when verdant leaf blind appears
also why are you returning self.ability.x_mult = self.ability.x_mult + self.ability.extra
yeah youre missing a }
take ownership then hook the activate function
The card is supposed to add xmult based on the number of copies of that card there are when triggered
thats not a return value
don't return that, just put it in the function
calculate = function(self,card,context)
if context.other_joker and context.other_joker.ability.set == "BORBJOKER" then
card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.scaling
if context.joker_main then
return {
card = card,
Xmult_mod = card.ability.extra.Xmult,
message = 'X' .. card.ability.extra.Xmult,
colour = G.C.MULT
}
end
end,
start with this
oh also self doesn't have an ability field
use card like in the return
also set is just joker
can i have the whole joker code
I followed a tutorial but it didnât give me the information needed to do what Iâm trying to do
thats not how context.other_joker works
I figured
actually, check out the forbidden one
Per copies of itself but yes
Or copies of another joker I plan to add
But I want to finish the copies of itself first
also a bunch of cryptid's
jokers do something like that
if context.joker_main then
local other_count = #SMODS.find_card('key_of_joker') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
do something like this
turns out the crash is completely unrelated to this
whole joker code please
How do I do the code formatting
To make it look like this
triple backticks (```)
use ```lua at the start and ``` at the end
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: Tax Fraud
--- MOD_DESCRIPTION: I copied a tutorial to get this far and now I'm confused
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#1#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('BORBJOKER') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
if context.joker_main then
return {
card = card,
Xmult_mod = card.ability.extra.Xmult,
message = 'X' .. card.ability.extra.Xmult,
colour = G.C.MULT
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
calc_dollar_bonus = function(self,card)
return 123
end,
}
----------------------------------------------
------------MOD CODE END----------------------
```
yeah if u put lua after the backticks it highlights it
Random lua at the start is not intentional
1 - you need a gain value in your config,
2 - you need to delete the other joker_main stuff
3 - that's not the correct key
wuh oh bettercalc 2 merged
4 - delete the in_pool and calc_dollar_bonus parts
how will this affect the trout population
this broke fucking everything
good luck myst
turns out the crash happens even if i disable strangepencil entirely
it's fucking exams season you can't do this to me
I copied a tutorial that had a joker give money and everything I tried wasnât working so I copied the whole thing of code and am in the process of editing it to be good
does anyone know how to fetch the number of skipped blinds in a run?
Maybe check the throwback joker
'''
--- STEAMODDED HEADER
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: Tax Fraud
--- MOD_DESCRIPTION: I copied a tutorial to get this far and now I'm confused
--- PREFIX: LBR
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#1#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
xmult = 1
card.ability.extra.gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[[#1116390750314307698](/guild/1116389027176787968/channel/1116390750314307698/)_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('LBRBORBJOKER') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
end,
}
------------MOD CODE END----------------------
'''
Weird
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: Tax Fraud
--- MOD_DESCRIPTION: I copied a tutorial to get this far and now I'm confused
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#1#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
xmult = 1
card.ability.extra.gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('LBRBORBJOKER') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
end,
}
----------------------------------------------
------------MOD CODE END----------------------
```
just gain = 0.5
Ah
and Xmult = 1
But other than that it should work?
assuming your smods is up to date, yes
no
the key is still wrong
j_LBR_BORDJOKER
elseif context.skip_blind then
if self.ability.name == 'Throwback' and not context.blueprint then
G.E_MANAGER:add_event(Event({
func = function()
card_eval_status_text(self, 'extra', nil, nil, nil, {
message = localize{type = 'variable', key = 'a_xmult', vars = {self.ability.x_mult}},
colour = G.C.RED,
card = self
})
return true
end}))
end
return
doesnt appear to be a stored value, but just updating the joker. but i need this for an unlock requirement. if my unlock triggers on context.skip_blind. is there some way for it to store that value? cuz i only want to unlock if x blinds have been skipped by run win
also MOD_AUTHOR needs to be in brackets
hey gang can someone help me with this crash
Still not there
do you have latest steammodded?
Yes
other person
I forgot to save
pretty sure? ill check
Ah
if so then thats probably why
commit 2 hours ago broke everything
oh so do i need a earlier version
ill make sure not to git pull XD
It looks like Iâm missing a bracket
yeah
anything before this is hopefully ok
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#1#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#"Info"_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
end,
}
----------------------------------------------
------------MOD CODE END---------------------- ```
@cerulean rose could you please link me to a working version
Oh wait wrong thing
i am having great difficulty finding one
This is the code
me too
ante 39 is broken as always
And this is the crash reason
i read the desc and thought you were reimplementing the entire game
missing comma in config table
Ah
does anyone have a working smod file for the latest cryptid version
I remember a substitute teacher I had going on about how she made a website to show her friends but it crashed because she forgot a single bracket or something like that
Also another crash
i was told someone fucked up the latest smod release. thats why i asked
@wintry solar
why did you ping me
check the message
yes and I have already answered your prior question about a link
i'm getting a bluescreen when launching
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#1#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1,
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
end,
}
----------------------------------------------
------------MOD CODE END---------------------- ``` (same crash reason, unexpected symbol on line 65 near end)
you have an extra end at the end
Oops! The game crashed:
Syntax error: game.lua:2507: duplicate label 'continue'
Additional Context:
Balatro Version: 1.0.1n-FULL (best guess)
Modded Version: 1.0.0~ALPHA-1306b-STEAMODDED
LĂVE Version: 11.5.0
Lovely Version: 0.6.0
Stack Traceback
(3) C function 'function: 0x2003cf38'
(4) global C function 'require'
(5) main chunk of file 'main.lua' at line 1876
(6) global C function 'require'
(7) LĂVE function at file 'boot.lua:323' (best guess)
Local variables:
c = table: 0x2003a5a8 {identity:false, version:11.5, accelerometerjoystick:true, modules:table: 0x2003a5f8 (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"])
is 0.9.8 the bugged version?
I have no doubt Iâll be back but thanks for the help so far
0.9.8 is extremely outdated
then where is the latest version??
you have to download the repo manually
what is a repo dawg
ok where do i find that
here
this?
yes
Nice and thank you :D
ok thanks sorry for the hassle
i accidentally left an extra copy of steammodded lol
np, if you use it please like write my name somewhere
otherwise use it as you please
finally my torture has concluded
I'm not sure I will but it is something to consider. I have two Jokers that provide a benefit and a challenge and I wanted a third to complete a set.
I also have a different Joker that provides a benefit but needs a drawback. I wanted to make the drawback bigger, so I was thinking about introducing a second Boss to each Boss, as it's consistent with other mechanics, but I wasn't sure about it (especially because it might still be too easy)
So making every Blind a Boss sounds like a good alternative to either of those
how do i make an enhancement that has a chance to destroy itself like a glass card does?
hey man the game crashed AGAIN im gonna tweak
when did you last update steamodded
i just wanna play cryptid dude
@wintry swallow by the way are you making any custom objects or only challenges so far
make sure to use the link from above
like a couple days ago
that was when i first installed it
bettercals broken af
only challenges, there will be custom objects but they will be only present in the challenge definition
everything crashes
it updated today
and it's a relevant update
I'm not sure but it could be that your Steamodded is too new lol
more specifically, "random joker of X rarity"
right make sure to use the link above
k
dont update btw
when entering into the challenge, they will not actually spawn as jokers in game but instead they will be replaced
just downloaded the repo is that too new?
what url did u download from
I see, I'd be curious to see if you do create any custom objects đ
Possibly yes, since it's a big, breaking update
yeah thats too new
why specifically me, i'm curious
cripes
The new update might be a bit prone to breaking since a lot changed, but the main feature is facilitating modded Enhancements and Editions, so, like, I don't think using an old version helps you
use this link
cryptid crashes when playing a hand
I liked your vibe
out of curiosity, is there a nice established way to prevent multiple copies of the same joker from stacking
or is it just kinda figure it out case by case
also have you added a hover UI on any of your challenge's texts? IIRC that would make the "scaling" easier to discern. Maybe you could make the Blind description pop up when hovering over the Blind name
I'm gonna say no
what effect do you want?
i have not and it is very hard to do so
i would have to do SO much more bullshit to the text preprocessor to get tooltips working
I've got a joker that does some stuff on add_to_deck and remove_from_deck, but it should really only happen with the first copy of the joker you get
there is already a very large dose of bullshit done to the text preprocessor so i'm saving myself the headache for now
Is it? Decks do it, and I feel like replacing the text with an object that handles both the text and tooltip would work
Can't you copy what decks do?
well it's not a custom object. it's the vanilla challenge select menu
ah
let me check
ha! yeah no
cannot be done
it's making gold cards count as steel and vice versa (blindingly original, I know) which I do by adding an h_x_mult mod to gold cards, which creates the problem of then stacking with multiple copies of the joker
Why doesn't the T control work?
hey man i downloaded from the link you gave, it worked for a sec, but when i finished the round the game crashed
mostly because i'd need to hook in and make it dynamically change
For similar effects I used a "global" variable and the Joker just sets it to true
Fair
I think it's worth considering for later
i should add pregnancy to balatro
I tried this by tracking a count of the joker and updating only when it goes from 0->1 or 1->0, but that seemed to not play nice when returning to main menu
but maybe I'm storing the global variable in the wrong place
If you want I can share my modified Blind tooltip code
hang on im gonna make a #1209506514763522108 shitpost
i think the other guy helping me got tired of the bullshit could someone else help me please
Create a subtable in the init_game_object return dictionary for your mod and store it there
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#1#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1,
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
}
----------------------------------------------
------------MOD CODE END---------------------- ``` It's not crashing but also not working properly. Also, when it says Gain {X:mult,C:white}X#1#{} Mult per activation it's displaying the mult variable and changing mult to gain just makes it white.
As for the not working properly, the score doesnât add
I'll give it a shot, thanks
screenshot your main screen
Ah, also, keep in mind that Card:add_to_deck is called before the card is added and likewise Card:remove_from_deck is called before it's removed
booster packs are unusable other than buying from shop
wrong loc_vars and wrong description
How do I fix it?
the vars are accessed in order with #1#, #2#, etc.
I tried that but realized I didnât save
I canât put what I want to say into words
try a bird call then
But I tried and forgot to save but didnât realize it until now
maybe an ostrich or swallow call
Now it just says xnil
hey could someone help me with this crash
I changed the 1 to a 2 but it says nil instead of 0.5
because you didn't change vars
how to add jokers and consumables to playing deck?
I'm having a Jimbaby and the Jimbaby isâŠ
still doesn't quite work for me. maybe something else in the way I have it set up.
something I notice happening is that when I return to main menu, I see remove_from_deck getting called multiple times and the global var ticks down to 0, but when I continue the run, I don't see add_to_deck getting called that many times, so the effect gets turned off even though I still have multiple copies.
That sounds incorrect because reloading the game should call add_to_deck
noted, i'll look into that
no but you're skill solution
everyone else is skill issue
(it's me I'm skill issue)
I copy some part of the vars function and change the 1 to a 2 and change the xmult to gain but what part do I copy without either a crash or a nil output (or am I going about this completely wrong)
uh, really you only need to expand the dictionary you return in loc_vars to have multiple entries in the vars table
Does anyone know how i can modify the Chip and Mult values with a joker card? I have an idea for something that would flip the value of chips and mult
There should be a vanilla way to swap them
I think thunk didn't use it
so just see if you can find it
swap or something IIRC
So just the info_queue and return lines?
just the return line
there's a lot of things thunk didn't use lol
I mean there's some leftover debug and demo stuff
debug mode is still fully present in the game
There was also like an online championship demo or something which they partially removed
Yes but not accessible to players
just like swapping Chips and Mult
no need for a patch
just need to change a variable
or use DebugPlus
which has extra functionality added on top
A patch sounds like a disproportionately hard way to do it
did you know this is a part of vanilla debug mode
yes
return {vars = {center.ability.extra.mult}}
return {vars = {center.ability.extra.gain}}
end, ``` is this right?
no
you cannot return two values
executing a return stops the rest of your function from executing
So what do I do?
@wintry swallow this is an intervention you don't need to use a patch for everything đ
;P
hey it was the easiest way i thought about doing it
...
i
it's fucking lua
nothing is constant
i could just have set _RELEASE_MODE to false
exactly
fucking hell this is what you meant. oh man

anyways, I'd recommend DebugMode
i have debugplus yes
i use its win ante button a lot
i made my thing before i installed it
I see
show your main menu pls
no they're having an issue with loc_vars
they're also having functionality issues
anyways you want something like vars = {YOURFIRSTVARIABLE, YOURSECONDVARIABLE}
I thought that was someone else
trying to run Cryptid
When the joker activates, it doesnât add to xmult
wild, this is the result of
- spawn 4 copies of the joker
- play a hand
- return to main menu
- continue run
hey is 7bc9acd3164472a39f8f28d058ca97f4104dd4b3 the last steamodded commit before the calculation change that breaks everything?
right; could be new calc
removeFromDeck called 4x, addtodeck not called. still have 4 copies of the joker
actually which Steamodded version do you have
new calc's roll out was very poorly thought out in my opinion, it's starting to hit users of my mod because it breaks vanilla content
i'm on latest as of like 2 days ago
bettercalc 2 fucks with vanilla?
The moment I hovered over my joker it crashed
I'm pretty sure bettercalc doesn't change any vanilla stuff
well i'm getting reports of foil and gold cards not working on my mod which does not touch them at all
so clearly something's up
i'll pulling bettercalc rn, will get back to you
i believe enhancements don't work period in bettercalc
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#2#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1,
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.mult,center.ablity.extra.gain}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER') --note if this is the same as this joker you probably want to subtract 1
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
}
----------------------------------------------
------------MOD CODE END----------------------
```
Crashes when I hover over the joker
ablity
here is a link to the last commit of steamodded before bettercalc was merged: https://github.com/Steamodded/smods/archive/7bc9acd3164472a39f8f28d058ca97f4104dd4b3.zip
Crash on 1. creating a "Joker" (with DebugPlus), 2. adding Foil (with DebugPlus), 3. playing a hand
It does this now
i shjould be turning off mods for this
I swapped the problem
I feel like it would've been better to mention what exactly will break now.
Example: if a single mod does not return two values with eval_card this will happen.
(much like how not returning two values in calculate_joker will break joker retriggers)
Cause enhancements 100% work if I don't have mods that mess with this
The functionality is also still not working
wait when do you even use eval_card
oh fuck right
It doesnât add to xmult and I donât know if it applies xmult
i forgot i hooked to eval_card
waht did you hook eval_card for?
That's the source of the next crash yea
the mess i showed you a few days ago
Although "enhancements not working at all" is likely something else
Iâm going to get the functionality working before I make the text work
oh yeah
yup both Foil (on Jokers) and Gold Cards don't work
It doesnât even apply xmult to the calculation
I think i mightâve accidentally deleted that part maybe
Previously it handles certain aspects of calculation, but iirc now it's everything.
I think
maybe not xdd
foil 100% was working for me
i don't think Mult being given before Chips on Mult Cards is correct
love having to tell end users this
...It doesn't?
I accidentally put mult instead of xmult
showcases:
- Foil/Holo on Jokers not working
- Gold Cards not working
- Mult being given before Chips on Mult Cards
Bruh I'm not on the right commit đ
I'm seeing the same thing with my other modded jokers
bruh
local other_count = #SMODS.find_card('j_LBR_BORBJOKER')
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end ``` is not working for some reason
they're triggering with no change
That explains it
No mods installed, just Steamodded goofed lmfao
oh god did the priority change fuck all the patches
lmao
yes
Not sure how -10 priority means that patches hitting vanilla break but yeah
Screen recording isnât working with my computer so Iâm just going to record with my phone and crop it a bit (and mute the audio)
well if someone has time to fix them right now that would be very appreciated but it is 2:30 and I need to be at work in 5 hours T_T
bettercalc2 moment
does it work fine with the patch priority set back to 0?
I think so
I mean I guess that's the only change since I last worked on it
so it should be okay at 0 for now
Other bugs reported still happen but no instant crash
Well I think othering things might also be whiffing?
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#2#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1,
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult,center.ability.extra.gain}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER')
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
}
----------------------------------------------
------------MOD CODE END----------------------
``` This is the code, how do I fix this?
Xmult_mod
I have to head out for now but I'm curious if anyone else can repro.
- Create a joker, put some printouts in
add_to_deckandremove_from_deck - Start a game, spawn in some copies of your joker, observe the
add_to_deckcalls - Play a hand, then return to main menu. Observe the
remove_from_deckcalls - Continue run, observe lack of
add_to_deckcalls
Do I replace something with that?
instead of xmult in your return
I couldnt seem to find it, theres so much in the files maybe my brain skipped it. maybe is there some way to just get and set the values?
supported effects are mult_mod chip_mod Xmult_mod message etc.
Does the capital matter for this?
capitals always matter for variable names
Ok
try Steamodded wiki
I think itâs just better calc patches whiffing assuming youâre on newest smods version
is there any mods with an example joker similar to drivers license?
I was trying to make a joker similar to that
It might be the whitespace
how do you make jokers look like it would fit in the game well
Some of these patches have 4 spaces inside the loop but vanilla has 2
Oh wait
But they all worked before đ
the source code does decent coverage, depends what cards you're trying to track
Itâs supposed to permanently upgrade xmult
I noticed cards like this or steel joker use "tallys" for the calculations. I get that its looping through all the cards but... I have no clue what
v.config.center ~= G.P_CENTERS.c_base
means. I feel dumb but ive never worked with game dev stuff much or lua
what what
if the playing card is enhanced
Crash and code ``` --- STEAMODDED HEADER
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#2#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1,
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult,center.ability.extra.gain}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER')
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
if context.joker_main then
return {
Xmult_mod = xmult
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
}
------------MOD CODE END----------------------
```
wait I didn't see the rest
is c_base the basic card. so if its not a basic card its enhanced basically?
yeah
A Center is like the prototype/base class for Cards. P_CENTERS is the pool of Centers. c_base is the corresponding base Center for basic playing cards
Am I just missing a comma or is it more than that?
oops you just answered that
thanks, is there a wiki explaining this stuff or is it just stuff you figured out from reading it?
v is the current card in the loop
yeah I got that part, makes sense
Mostly from reading it but the Steamodded wiki does help sometimes
i really cant seem to find an example of this sort of thing. someone please help me here theres gotta be some way to modify the scoring values right?
thats cool, I get the general idea with most stuff but its nice to have the specifics explained. Thanks!
In Joker calculation. Although if you mean a functional example yeah thunk did not implement it in the final game
guess is suck at finding things huh
Same problem as before with it not working, the code now is ```--- STEAMODDED HEADER
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#2#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1,
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult,center.ability.extra.gain}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER')
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
}
end
if context.joker_main then
return {
Xmult_mod = xmult
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
}
------------MOD CODE END----------------------
```
For reference, itâs doing this again
why are you doing context.joker_main again
and repeating the code
just replace xmult for Xmult_mod
I actually think the new calculation guide does a terrible job at demonstrating modded calculations
I did that and thatâs not how I want it to work
the additional code is redundant you're returning nothing to nothing
I want it to be a permanent upgrade that is stronger based on how many copies of that joker there are, what do I do?
count the jokers and multiply
I have it save to the xmult variable and I want Xmult_mod to be the same as xmult after Iâm done with that
I tried putting it in the same return but the game crashed
@zealous glen @wintry solar turns out i forgot to make beating any ante 8 boss not count as winning the run until the last blind so here's the patch with that fix applied
have you read the documentation, it covers how to return values
If this isnt functional, do you know if there is a way to just directly modify chips and mult?
unless you mean it does work but its not in the game
i was thinking of making a joker w/ ability like "Jokers and consumables seen in the shop do not appear again [while this Joker is held]; destroyed when pool is exhausted" , would this be too situational? i feel like it could be really useful either when looking for a specific joker or just when trying to set up a build but maybe it doesn't affect probabilities enough to make a big difference
could also just encourage really boring strategy ... reroll for baron, mime, blueprint, brainstorm every single run
there are around 180 total possible items to appear in the shop (random guess, could be lower or higher) which means at maximum 90 rerolls+rounds to get everything you want
still can't figure this out
i think its neat and worth adding
glass cards getting destroyed is hardcoded into G.FUNCS.evaluate_play, i'm not sure if steamodded has special functionality for this but my guess is that you'd have to hardcode this via lovely
Where is that part
been trying to figure this out, this has to be possible theres no way it isnt
how do i get this unlock text?
the below shows up on preview, but not on the unlock event popup
unlock = {
"Skip {C:attention}6 Blinds{} by {C:attention}Ante 4"
}
this is the code that handles destroying cards ... it only checks for
- whether any jokers want to destroy the card
- whether the card is glass and it succeeds the 1in4 chance
i put 4 pinned jokers and it can't be relocated to other pinned joker location, but the pinned joker insertion method is reverse of code said
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_mista")
card.pinned = true
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_geriolish")
card.pinned = true
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_joker")
card.pinned = true
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_mime")
card.pinned = true
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_mista")
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_geriolish")
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_joker")
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
card = create_card('Joker', G.jokers,nil,nil,nil,nil, "j_mime")
card:add_to_deck()
G.jokers:emplace(card)
card:start_materialize()
the pinned mista is located somewhere on middle, not leftmost
wait shit this is my modded version
in the real thing it says scoring_hand not fake_scoring_hand i think
- some other things
but the general idea is the same -- you'd have to inject custom code into that function to handle your enhancement
fortunately this is only like 3 lines probably
dev made the pinned card immobile, requires some adjustments so all pinned cards (and all non-pinned cards) have own group
how would i make the same joker do a +chips notif, then a +mult notif after
the one during scoring
i experimented with reusing the message function but it overwrote regardless of order
i think you have to use card_eval_status_text and return a message
how would i
use that exactly
the smods tutorial literally said ask someone who knows eval status text for how to use it lmao
full code of this goes over text limit but is there any way i can halve what it gets from the 2 jokers ie joker 1 gives +20 mult so +10 mult joker 2 gives x3 so x1.5 etc?
-- Process the left joker, if it exists
if left_joker and left_joker ~= self then
context.blueprint = (context.blueprint and (context.blueprint + 1)) or 1
context.blueprint_card = context.blueprint_card or card
if context.blueprint > #G.jokers.cards + 1 then
return
end
local left_result, left_trig = left_joker:calculate_joker(context)
if left_result or left_trig then
if not left_result then
left_result = {}
end
left_result.card = context.blueprint_card or card
left_result.colour = G.C.GREEN
left_result.no_callback = true
table.insert(results, left_result)
end
end
-- Process the right joker, if it exists
if right_joker and right_joker ~= self then
context.blueprint = (context.blueprint and (context.blueprint + 1)) or 1
context.blueprint_card = context.blueprint_card or card
if context.blueprint > #G.jokers.cards + 1 then
return
end
local right_result, right_trig = right_joker:calculate_joker(context)
if right_result or right_trig then
if not right_result then
right_result = {}
end
right_result.card = context.blueprint_card or card
right_result.colour = G.C.GREEN
right_result.no_callback = true
table.insert(results, right_result)
end
end
-- Return the combined result
if #results > 0 then
return results[1] -- Return the first result (or adjust as needed)
end
end
}
basically trying to create a half-print
how do i check if a played hand contains a five of a kind?
if context.scoring_name == "Five of a Kind" then
i cant use context in check for unlock, how do i reach that from args?
no idea haven't messed around with unlocks yet
also i specifically want 'contains' so five of a kind and flush five both trigger
aight
Ok so I'm trying to do something quite odd here. I'm confident in the equation but it keeps giving "X(-0)" Mult. Anyone have any ideas on how to get this working?
Wtf why does lua have -0
GREAT question LMAO
Hold on lemme get a screenshot of the trigger cuz it's really funny
apparently 0 * -1 is -0, and -0 + 0 is 0
so I guess if you want to get rid of the - just add 0
ieee 754 my beloved
the general idea is that since floating-point numbers are approximate they represent ranges of possible values rather than single precise numbers, and it can be really useful to distinguish between really small number (positive) and really small number (negative)
In this case the equation is literally multiplying by 0 tho
0 * -1 should not be -0
for all ieee 754 knows you could be multiplying by 1e-10000
we are not in ieee land here we are in omeganum land
I will say this is my first time seeing this in any programming language i've ever used
that's true
the omeganum land in question btw
(... does talisman use omeganum for literally everything, or just scores? i assumed things like ability.extra still used floats)
im not sure tbh
i was under the impression cryptid converted them to bignum format because of scaling and whatnot
Oh god I accidentally sparked math chat 
0*-1 is still -0 in float math terms anyways isn't it
each day since ive joined this server and began modding balatro, Lua seems less like python and more like js
Still need help with this, Iâve looked almost everywhere and canât find anything
i wouldn't consider lua much like js at all
Iâm just glad we donât have to use a Turing machine
Is there a context for when a playing card is drawn to hand? That would make it possible to create "on draw" effects for enhancements
It just crashes
I want to update the xmult variable and then update the Xmult_mod using the xmult variable
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER')
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
Xmult_mod = xmult
}
end```
it just crashes saying that there's a missing }
--- MOD_NAME: Leaf Blower Revolution (but in Balatro)
--- MOD_ID: LBR
--- MOD_AUTHOR: [Tax Fraud]
--- MOD_DESCRIPTION: Mod inspired by Leaf Blower Revolution
--- PREFIX: LBR
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'BORBJOKER',
loc_txt = {
name = 'Borb Joker',
text = {
'Gain {X:mult,C:white}X#2#{} Mult per activation',
'for every other Borb Joker',
'or Borbiana Jonesker', -- Not implemented
'(Currently {X:mult,C:white}X#1#{})'
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {
extra = {
Xmult = 1,
gain = 0.5
}
},
loc_vars = function(self,info_queue,center)
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
return {vars = {center.ability.extra.Xmult,center.ability.extra.gain}}
end,
check_for_unlock = function(self, args)
if args.type == 'derek_loves_you' then
unlock_card(self)
end
unlock_card(self)
end,
calculate = function(self,card,context)
if context.joker_main then
local other_count = #SMODS.find_card('j_LBR_BORBJOKER')
return {
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain)
Xmult_mod = xmult
}
end
end,
in_pool = function(self,wawa,wawa2)
return true
end,
}
----------------------------------------------
------------MOD CODE END----------------------
``` the whole thing
you need a comma at the end of the xmult = line
you're missing a comma
Itâs always the comma
xmult = card.ability.extra.Xmult + (other_count * card.ability.extra.gain), fixed ver
Itâs not crashing but itâs not doing anything either
Got it working!
-- play a hand of 5 7's
check_for_unlock = function(self, args)
if args.type == 'hand' and #args.scoring_hand == 5 then -- or args.handname == 'Five of a Kind' or args.handname == 'Flush Five' then
for _, card in pairs(args.scoring_hand) do
print(card:get_id())
if card:get_id() ~= 7 then
print('non 7 found')
return false
end
end
unlock_card(self)
end
end
should probs remove the prints now đ
This should be working, shouldnât it?
It checks how many copies of itself there are and adds that many x 0.5 to the xmult
It then sets Xmult_mod to that number
Which should multiply mult by a value that goes up every round and goes up faster based on how many copies of itself there are
But itâs not doing that
Does anybody know what the problem is
just remove the xmult thing and put directly the sum into Xmult_mod
Xmult_mod = card.ability.blah blah blah
Thatâs not what I want it to do, that simply multiplies by the amount there are, x0.5, +1
I want it to scale the xmult_mod
So it goes up the more times itâs activated
So that if you only have 1 copy it goes x1, x1.5, etc but 2 copies is x1, x2, etc and so on with more copies
So whenever it's triggered its xmult goes up by the current amount?
Xmult permanently goes up depending on how many copies there are and xmult_mod is just set to Xmult
Okay then, before the return, modify card.ability.extra.Xmult and then put Xmult_mod = card.ability.extra.Xmult in the return
functions/state_events.lua:1089: attempt to concatenate global 'i' (a nil value)
Additional Context:
Balatro Version: 1.0.1n-FULL
Modded Version: 1.0.0~ALPHA-1306b-STEAMODDED
LĂVE Version: 11.5.0
Lovely Version: 0.6.0
Steamodded Mods:
1: Hyperfixation by tomatose [ID: HYPERFIXATION]
Lovely Mods:
1: Saturn-alpha-0.2.1-A
2: DebugPlus
Stack Traceback
===============
(3) Lua field 'evaluate_round' at file 'functions/state_events.lua:1089'
Local variables:
pitch = number: 1.07
dollars = number: 6
(for index) = number: 1
(for limit) = number: 1
(for step) = number: 1
k = number: 1
_card = table: 0x0406c5f8 {click_offset:table: 0x0406c710, zoom:true, children:table: 0x0406e118, ambient_tilt:0.2 (more...)}
ret = number: 1
(*temporary) = Lua function '?' (defined at line 987 of chunk functions/common_events.lua)
(*temporary) = table: 0x03f66eb8 {bonus:true, dollars:1}
(*temporary) = string: "joker"
(*temporary) = nil
(*temporary) = string: "attempt to concatenate global 'i' (a nil value)"
(4) Lua field 'func' at file 'game.lua:3363'
(5) Lua method 'handle' at file 'engine/event.lua:99'
Local variables:
self = table: 0x03773a28 {start_timer:true, timer:TOTAL, blockable:true, trigger:immediate, func:function: 0x03a5e448 (more...)}
_results = table: 0x040fcb60 {blocking:true, pause_skip:false, time_done:false, completed:false}
(6) Lua method 'update' at file 'engine/event.lua:182'
Local variables:
self = table: 0x03793c68 {queue_last_processed:16.15, queues:table: 0x03793c90, queue_dt:0.016666666666667 (more...)}
dt = number: 0.00551203
forced = nil
(for generator) = C function: next
(for state) = table: 0x03793c90 {unlock:table: 0x035a0138, other:table: 0x035a01d8, tutorial:table: 0x035a0188 (more...)}
(for control) = number: nan
k = string: "base"
v = table: 0x035a0160 {1:table: 0x0406c580, 2:table: 0x03773a28, 3:table: 0x0408b718, 4:table: 0x03761f38 (more...)}
blocked = boolean: false
i = number: 2
results = table: 0x040fcb60 {blocking:true, pause_skip:false, time_done:false, completed:false}
(7) Lua upvalue 'gameUpdateRef' at file 'game.lua:2519'
Local variables:
self = table: 0x0357ecd0 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x03da27d0 (more...)}
dt = number: 0.00551203
http_resp = nil
(8) Lua upvalue 'gameUpdateRef' at Steamodded file 'src/ui.lua:81'
Local variables:
self = table: 0x0357ecd0 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x03da27d0 (more...)}
dt = number: 0.00551203
(9) Lua method 'update' at line 22 of chunk '"11585"]'
Local variables:
self = table: 0x0357ecd0 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x03da27d0 (more...)}
dt = number: 0.00551203
(10) Lua field 'update' at file 'main.lua:996'
Local variables:
dt = number: 0.00551203
(11) Lua function '?' at file 'main.lua:935' (best guess)
(12) global C function 'xpcall'
(13) LĂVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 906 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(LĂVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LĂVE Function)' (defined at line 355 of chunk [love "boot.lua"])
can someone tell me what it means by this global 'i'? why is it nil? is this something id have to send the code for?
maybe latest steamodded version broke some of your mods
ill try going back and lyk
yep! that was it thank you
can we get an @ everyone once steamodded is fixed đ
did people figure out a quick reload command yet or is it still just close and reopen the game?
So for my blind, it increases your hand size when you start it, but how do you make it so that it returns back to normal after the blind is defeated?
G.hand:change_size(5)
This line of code is all there is
Still closing and reopening, but there's a hotkey for it, just hold M
oh nice thanks
change the hand size back in the defeat function
or whatever it's called
yeah it's called defeat
Yeah there's function Blind:defeat(silent)
So do I call it like if defeat(true) then?
in your blind add a defeat = function(self)
and there you can disable the effects
I'm taking it from here https://github.com/Steamodded/smods/wiki/SMODS.Blind
store it and manually reset?
Yeah I'm gonna store the current hand size in a local variable, and then increase the hand size after that
Once the blind is defeated, I can use the local variable to reset it back
Like this?
Also what's the function/value to fetch the current hand size?
do you have to put all code in 1 file for it to show as a single mod? cuz i kinda dislike that i have multiple mods 'zeros decks' 'zeros jokers' etc
but i dont rlly want one massive file of everything.
Yeah I haven't split my code yet
i split mine from the start, into the diff categories as said above
i would not be able to stand such a large single file XD
haha yeah
defeat = function(self)
change hand size
end
though my readme list of yet to implement ideas is also 300 XD
main file
you do not have to put everything in a single file
it is a bad habit in general
loc file
loc file is fine tho
mercy gif NFS.load
yea, but then it lists them as seperate mods, so how do i make the multiple files list as 1 mod?
I need to split my Enhancements and Blinds and Jokers
Are there any example code that does this
there are a couple way to load other files
here's in the wiki
if context.joker_main then
return{
chip_mod = card.ability.extra.chips,
mult_mod = card.ability.extra.mult,
message = 'Placeholder!'
}
end
how do i set a color for the message? like that square when it activates
i think the square colour is automatic to the mod type being returned?
add colour = G.C.MULT to the return, that'd be the mult color ofr example
oof
what was the crash reason
let me recreate
What's the value to fetch the current hand size? G.GAME.hands or something
held or played hand?
SMODS.Joker {
key = 'redJoker',
loc_txt = {
name = 'Red Joker',
text = {
"{C:mult}+2{} Mult for each",
"remaining card in {C:attention}hand"
},
unlock = {
"Have {C:attention}10{} or more cards",
"remaining in {C:attention}hand"
}
},
rarity = 1,
atlas = 'ModdedVanilla',
pos = { x = 5, y = 1 },
cost = 2,
calculate = function(self, card, context)
if context.joker_main then
return {
mult_mod = 2*#G.hand.cards,
message = localize { type = 'variable', key = 'a_mult', vars = { 2*#G.hand.cards } }
}
end
end,
unlocked = false,
discovered = false,
-- on play have 10 cards remaining in hand
check_for_unlock = function(self, args)
if args.type == 'hand' and #G.hand.cards > 9 then
unlock_card(self)
end
end
}
Ooh #G.hand.cards then?
yup
this time it didnt crash but the color of the square didnt change either
still chip blue
what colour did you put
is it bc your returning multiple? chip and mult? like if you comment out the mult does it work?
mult
i willtry
i havent had luck when doing chip and mult at same time
that wasnt it
wait wrong
commenting out didnt do it
i tried figuring this out earlier with the example mod but i couldnt figure it out
this should be the current amount of cards the player has in hand
which could be lower than the limit
Try G.hand.config.card_limit
this is how I did it
set_blind = function(self, reset, silent)
ease_hands_played(15)
ease_discard(15)
local original_hand_size = G.hand.config.card_limit
G.hand:change_size(5)
....... up till the end of function
defeat = function(self)
G.hand.config.card_limit = original_hand_size
end
Witness my programming prowess (it crashed)
bad argument #2 to 'max' (number expected, got nil) this error is pointing to cardarea.lua at line 276, which is
self.config.temp_limit = math.max(#self.cards, self.config.card_limit)
Guh what can I do here, I feel like the fix is simple yet I can't pinpoint it
card_limit was set to nil?
That variable is not accessible to other functions
So when you set card_limit to that, the variable doesn't exist, so it's nil
and so G.hand.config.card_limit = original_hand_size set it to nil bc original_hand_size didnt exist
Fuck hold on
can you store the var in config.extra?
A simpler way to do that is to just do G.hand:change_size(-5)
And no need to save the previous value
i completely forgot change_size takes in negatives
Presumably it does, I haven't used it
bro... i thought you were saving cuz you were doing an unknown number of change sizes XD
most change functions do and i dont see why it would be different tbh
even if it doesnt do negative, you can just set it to current - 5 since you know you added 5
Alright sick I got it working
Now a completely different question - how do I destroy specific cards in deck
My Blinds have blind-specific enhancements and consumables so I need to make sure they get taken out and not clog up the deck or consumable slots past the Blind
Never mind I figured it out
defeat = function(self)
G.hand:change_size(-5)
for i = #G.deck.cards, 1, -1 do
if G.deck.cards[i].config.center == G.P_CENTERS.m_fm_diving_bird or
..... or
G.deck.cards[i]:start_dissolve()
end
end
end
is there any way to access 'args' from joker.calculate() ?
the different vars i get between calculate() and check_for_unlock() are frustrating.
i have to use different approaches for the same things depending on which im in
i know how to check if end boss blind with args but not from context :/
Is there a way to get VSCode to auto complete code for making mods?
you can check if context.end_of_round and G.GAME.blind.boss in calculate
i think so anyway...
if you get the lua extension and have the steamodded source in your workspace it will detect something, but it's not that helpful
Ahh thanks
i use sublime text but if i have the balatro source in my project then it lets me view function definitions throughout the codebase which is nice
not quite auto complete but still insanely nice
it is definitely nice to have the game source open
not quite, i since worked it out tho! đ
calculate = function(self, card, context)
if context.blind and context.blind.boss then
G.E_MANAGER:add_event(Event({
func = function()
local card = copy_card(pseudorandom_element(G.jokers.cards, pseudoseed('perkeno')), nil)
card:set_edition('e_negative', true)
card:add_to_deck()
G.jokers:emplace(card)
return true
end
}))
card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil,
{ message = localize('k_duplicated_ex') })
end
end
PerkeNo
doesn't that trigger at the start of a boss
oh, I thought you wanted after it was defeated
context is quite limited
the worst part about making a mod for me rn is lowkey trying to come up with ideas
i can help with that XD >_>
i have 300 lines of pending ideas
i have a bunch of sort of neat ideas for variations on spectral cards but they range from slightly overpowered to completely busted
can i offload some? XD
heres some fun ones
they don't really sound inverted, more like enhanced
yea inverted was just a placeholder name
they have like 3 different names across all my projects lol
in game theyre listed as "antispectral", in the ideas doc theyre "inverted spectral", and the texture name is "distspectral" (distorted spectral)
personally not a fan of making new cards that are very similar or have just changed values of the vanilla one
neither am i really but its a really easy way to get familiar with a bunch of different modding basics at once
like making this one showed me how to add a joker w/ an edition and how to mess with the ante value
maybe 'The Spirit'?
its also one of the more unique of all the ideas, i dont think anything other than the hiero/petroglyph vouchers touches the ante number in any way?
i feel like the +1 ante should work regardless of the current ante
if youre on ante 8 it just cant be used
no, cuz then on 8 you can use this to just win the run
oh I see
or, then you win at ante 9? so you make scores higher but dont just win. if you can do that
so it doesn't work only on ante 8
i thought about making it not work on all big boss blinds but if youre using a consumable card to skip like ante 24's boss i honestly dont care
but i dont want it to like. break win conditions or something
I think that does me for today. commit name = Numerous
oh my god
i think i could do this actually? just by setting G.GAME.win_ante one higher. i may or may not have to overwrite some of the boss spawn code though since i think setting win_ante actually determines the multiple of when final bosses spawn, and not just the first time one spawns
idk if ill do this at all its just an interesting idea
fair
i wonder if anyone else has done something similar with the win_ante before though
Completed!
Decks
Antimatter
Start with 1 Joker slot, Gain 1 per Ante
Unlock: Finish a run with 8+ Jokers
Headstart deck
$25 jumbo buffon pack, start ante 2
Unlock: Skip 8 by Ante 8
Jokers
Red Joker
Gain 2 mult per remaining card in hand
Unlock: Have 10+ cards remain in hand
Dumpster Fire
All discards are destroyed
Unlock: Reduce you deck to 26- cards
One Mans Trash
Gain $1 per remaining discard
Unlock: Finish a run with no unused discards
Noble Joker
Gain 1 mult per 2 face cards in full deck
Unlock: Have 24 face cards in your deck
Prime Time
Prime cards give their rank as mult
Unlock: Play a hand of 5 7's
Perkeo2?
Make a negative copy of a random joker when entering boss
Unlock: None/Legendary
Leaper
+1 mult. this doubles per straight flush played
Unlock: ?
Hey, how do I check to see if a played hand is a High Card to trigger a Joker?
Here's where I need to put the code
this
Thanks
Now, if I want to double the mult each time after it triggers, what do I do?
elaborate
lol, trying to copy my idea XD jk
-- Leaper
SMODS.Joker {
key = 'leaper',
loc_txt = {
name = 'Leaper',
text = {
"{C:mult}Mult gain{} doubles",
"if played hand",
"contains a {C:attention}Straight Flush{}",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)"
}
},
config = { extra = { mult = 1, mult_gain = 2 } },
rarity = 3,
atlas = 'ModdedVanilla',
pos = { x = 1, y = 0 },
cost = 8,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult, card.ability.extra.mult_gain } }
end,
calculate = function(self, card, context)
if context.joker_main then
return {
mult_mod = card.ability.extra.mult,
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
}
end
if context.before and next(context.poker_hands['Straight Flush']) and not context.blueprint then
card.ability.extra.mult = card.ability.extra.mult * card.ability.extra.mult_gain
return {
message = 'Upgraded!',
colour = G.C.MULT,
card = card
}
end
end
-- add an unlock
}
very similar joker of mine for reference
beware that and next(context.poker_hands['Straight Flush']) means 'contains' so high card in this format would trigger on everything. i believe
Gonna bump this. If there happens to be a math guru in chat currently that could assist and sees this please ping me 
Alot of cool things đ€ perkeo 2 is almost the same as Archibald from cryptid
i havent done much cryptid, its a bit too much XD. perkeno is my strongest. most others i make i try to make balanced
Is there a link to forum for this? I'm interested in this frfr
if noone else helps, remind me tomorrow, im decent at math but way too tired rn
uhm please never ask me to cook
So from here, what else do I need to add?
I know I'll need a mult_gain variable, but what else needs to be added?
you need to update the mult_gain there. you also need context.main for the application of the mult
what mult is stored?
the current mult
Heard that
the number in the red box on the side
ahh. thats strong
really strong
does it seem too op
get mult too >100 with repeater on right side, then it scales by that each next turn đ
i think it needs to set its mult from a smaller source, then its really cool. unless this is a cryptid card in which its perfectly fine
This should be correct as I copied it from my Joker that gives x2 Mult with each scored Ace, just given the parameter of requiring a High Card.
meant to reply but i failed
X1.5 mult with extra steps basically đ
if i understand correctly that sounds good
Another full page. That's three! (still need to finish some functionality for some tho)
unpleasant gradient

what it do
I scored hand has exactly 4 cards, it converts the suits of each card to clubs, hearts, diamonds, and spades from left to right
ah
e.g. the 3rd card in the hand would become a diamond
unpleasant indeed
There are a lot of 4-card synergies in this mod. There's another not on that page called 4-Leaf Clover that converts a scored hand of 4 into lucky cards
Omg observer is op af
Hack blueprint this
Holy hell
With talkie walkie
SMODS.eval_this is a lifesaver đ wish i knew this existed before
hiker + retriggers đ„±
@tall wharf
hi
Do you need a coder by any chance
uhhhh
Tacking it to an event that happens as often as the score changing is very strong
i am a comsci student i probably might need some help but i will be the main coder
My mod is my first experience with Lua but Iâve had prior coding experience, so if you have that (and it sounds like you do), you should pick it up pretty fast
Alr np
i've made a small thingamajik in lua before
I dont actually have time I regret asking anyway lol
đ
tbh even without lua experience its easy to pick up balatro modding imo
as long as you have some coding experience
Thatâs what Iâm sayinâ lol
Iâve worked with C#, C++, Java/TypeScript, Java, and Python before and that experience helped a TON with getting into this
i wouldnt say ez
curious for a more general opinion on this - should this be totally random what edition it applies or should it apply one of each across the 3 cards
The only coding experience I have is python from when I was in 7th grade đđ
Well the cool thing with mods is that you can write 3 lines and it will work, unlike a real game where you need to code a shit ton until it works
tru
me looking at the decade of gamemaker studio experience on the table
gotta write less, but gotta read more
Mod coding is cool cause you can code bits by bits and try stuff without breaking too much
Those are really good ngl
broken with any Xmult card tbh
Actually so true
imagine a flush five ace build, scholar on the left of this card, hologram on the right
its over
idk is that really true? i feel like this would be broken with the combo i just listed + dna + blueprint which is a combo ive gotten in runs like 4 or 5 times
feels very hard to balance because you could just put something really cheap that triggers per card on the left side and something really broken on the right
true
this is actually insane i love it! op but awesome
early game, any suit +mult card on left, play flush, with then any Xmult on the right
@tall wharf
Maybe make it last a couple rounds
That would fix it right
And remove from eternal pool of course
sure
X1.11 mult wdym
like
That could work too
it can go either way
could also make it trigger every 2-3 times instead
oooh wait. maybe the amount of times the joker on the left has to trigger goes up by 1 every time it activates? and then you could reset it back to 1 every ante or something
fire
that'd be so cool
workshopping these distorted spectral cards a little more
making mods would be so cool.... but the fact i can't even get one running means i should probably keep any mod ideas in my brain đ
ok well
writing these down to share and keep as record in case i want to turn this into a real thing
i never planned a Minecraft mod
these are just things in my head written down
why is disabling discards so 
i liek
what issues are you running into? also what ideas u got?
can someone please tell me whats wrong with this code 
I'm trying to patch the discard button to be disabled when a specific card is selected. IT doesnt seem to have any effect.
Patch:
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
if G.GAME.current_round.discards_left <= 0 or #G.hand.highlighted <= 0 then
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
e.config.button = nil
'''
position = 'after'
match_indent = true
payload = '''
elseif (function()
if #G.hand.highlighted > 0 then
for i = 1, #G.hand.highlighted do
if G.hand.highlighted[i] and G.hand.highlighted[i].key == 'clowned' then
return true
end
end
end
return false
end)() then
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
e.config.button = nil
'''
Original code:
G.FUNCS.can_discard = function(e)
if G.GAME.current_round.discards_left <= 0 or #G.hand.highlighted <= 0 then
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
e.config.button = nil
else
e.config.colour = G.C.RED
e.config.button = 'discard_cards_from_highlighted'
end
end
is there are mod settings?
thanks for message bomb
Unintentional, sorry 
would this not be better to do through a hook?
potentially, I'm not too familiar with modding yet
I'd just like to do that thing and it doesnt seem to work with the way i patched it and i cant explain why
example mod gui?
how to activate end of round event
if context.end_of_round
What am I doing wrong here?

