#💻・modding-dev
1 messages · Page 84 of 1
skill issue
):
forgot a comma
im so smart guys
forgot another
😭
its 5am its understandable
trust me,,
its fine I know someone whos absolutely nuts with coding for a very specific fangame, and they may forget simple stuff like that
i forgot to put an end on my if statement im actually cooked chat
i'm trying to use lovely to patch code for ending a blind and it just always says it's not found?? even though it's literally copy+pasted from the source
did you patch the right file?
yeah
also check the lovely dump sometbhing else could have replaced it before your patch applied
it's near where talisman is doing stuff
i've tried both the original and what talisman replaced it with, as well as a hack-around using the line below
none work
?!?!?!!
😭
NEVERMIND I MISSED ANOTHER COMMA
ill get all the commas at some point
give me 600 errors maybe ill get them all
nevermind im getting the same error
uifhasiuyfyfsdf
relatable
can you show the whole line
a second pair of eyes goes a long way in situations like these
i just copy-pasted from the dump and it still claims no matches
will it say that if there are multiple matches?
IT WORKS YIPEEE
Im a modding virgin and am learning lua through balatro; how would I go about spawning in a joker or card to test?
you can use DebugPlus to spawn a joker
is there a way to give or take temporary hands/discards
or do I just need to reset them at the end of the round
There's plenty of vanilla jokers that does that
yeah it occured to me after writing that
that burglar is like exactly what I need
i hope this works first try
(it didn't work)
is there a context for after a hand is played
i'm having trouble triggering an effect when there's 1 hand left
do I need to use event manager
context.after isn’t enough?
i've tried a bunch of contexts including that it just
doesn't trigger
and it makes no sense to me cause this should be pretty simple to do
i made sure it's not in any other contexts that would conflict (it isn't)
Can you show the full code?
ive also been trying to do this to no avail
theres some offscreen text for the description
this is it
i do remember seeing a joker before that does it but i couldnt remember for the life of me where id seen it - asked here if anyone knew which mod it had come from but didnt get a correct answer
it was a joker that like carried over discards between blinds and they stack up beyond max but i cant find it for the life of me
There’s no context here
there have been multiple contexts there
none of them have worked
What’s it supposed to do?
on final hand of round if its chips are above 100 (separate effect that is functional builds chips)
give 5 hands, give xmult equal to remaining discards until end of round, lose all discards
i'll probably have to move the xmult return to context.joker_main regardless but none of the other parts are working
so it's kind of like an extra chance at the blind?
yeah
oh and it resets the chips at the end of the round after it triggers
that's the easy part
if context.after and G.GAME.current_round.hands_left == 1 and card.ability.extra.chips >= 100 then
print('test')
card.ability.extra.Xmult = 1 + G.GAME.current_round.discards_left
ease_discard(-G.GAME.current_round.discards_left)
ease_hands_played(card.ability.extra.hands)
end
does this work
the test prints
nothing else works
the hands and discards dont change?
indeed they do not
huh
different problem came up after i triggered the effect
I was hoping I could use a table of strings to get new lines in the joker text
cause the way this secret effect stuff works is that there's a loc var at the end of the joker description which changes from a little bit of splash text hinting at the effect to the actual effect after you trigger it once
but the effect is too long to be put on one line
you can change the key of what description it's using in loc_vars
the entire description
oh how
iirc you return {key = 'key'} in your loc vars return
in the loc tables
what
how are you doing your localization?
am I supposed to be doing localisation
thats how you get any descriptions
i just put it in the loc_txt
loc stands for localization :P
disclaimer i'm fuckin stupid
so you either need to use SMODS.process_loc_txt() or set up a localization file properly then iirc
loc_txt is a localization table I'm p sure
How can I get the width of an UI node before it's created?
what does that do exactly? for fure reference when I do more coding on my mod
it adds stuff to the loc tables
Or, rather, how can I set a node's width to the parent node's width?
smods.process_loc_txt does what exactly
So to add extra stuff to the loc tables it'd be SMODS.process_loc_txt({thing})?
yeah there'll be some uses of it in the smods code you can reference
how does it know which joker to do it in
it doesn't need to, you just need to tell your joker to use that key later on
I can send some examples when I'm back home later
an example would help yeah
Okay uhh, different question.
Any way for an UIBox to be drawn on top of Cards and CardAreas without using .attention_text?
Spoilers for both Lobotomy Corporation and Library of Ruina, but if you don't care about either of those then this is how it looks right now
Iirc instance_type controls the layering
I've tried having "UIBOX" and "ALERT" for the instance_type and neither worked
Does ’TOOLTIP’?
And is it on the root element?
I have no idea how instance type works
TOOLTIP is not an instance type, no
And, it should be on root, I think
local blind_hoverref = Blind.hover
function Blind.hover(self)
...
self.config.h_popup = G.UIDEF.blind_h_popup(self)
self.config.h_popup_config = self:align_h_popup()
self.children.h_popup = UIBox{
definition = self.config.h_popup,
config = {
instance_type = "ALERT",
major = self,
parent = nil,
xy_bond = 'Strong',
r_bond = 'Weak',
wh_bond = 'Weak',
offset = {
x = 0.15,
y = 0.4,
},
type = "cr",
},
}
self.children.h_popup.attention_text = true
self.children.h_popup.states.collide.can = false
self.children.h_popup.states.drag.can = false
...
end
I wonder if it needs to be on the root element inside the definition
G.UIDEF.blind_h_popup does return a root node but I'm unsure
I'm thinking of making it a global instead, similar to G.achievement_notification or G.debug_tools
Then I can simply Lovely patch it into the Game:draw() function
for the purposes of making sure my mod is compatible with other mods that add suits, how do I get a list of all the suits (default {"Spades", "Hearts", "Clubs", "Diamonds"})?
I have a hacky way
but gimme a sec
oh you can just look up the SMODS.Suits table
yeah
Alright thanks
is there a mod/example i can look at for how to turn one hand into another, using a joker?
like shortcut?
uhh, no, more like (this is the actual joker idea): if you play pair, it plays two pair
(or maybe thats done the same way under the hood? idk)
uhhh it's not working. the table seems to be blank or something
ty kindly
np :3
how are you accessing it?
I was looping through ipairs(SMODS.Suits)
it doesn't use integer keys
so then what do I do?
use pairs
so for k,v in pairs(SMODS.Suits) but which one is the suit string k or v?
k is the key and v is the value
I know but how is the SMODS.Suits table structured?
I imagine it’s the key you need
time to find out
idk figure it out
yep it was
all this to get this blind to work properly
cursive nonsense
Ei
lol
anyone know where i can find the editions in the vanilla source?
i wanted to make an edition that didnt apply to jokers but i have no idea how
i was gonna see how negative stops itself from applying to playing cards
you'll have to hook set_edition until I get round to making editions respect in_pool
oh right so would i just set the edition to no edition if it has the custom edition?
thats a lot of the word edition in one sentence
how would you set a card to have no edition is it like you set the edition to nil?
also i have no idea how to like check the edition of each card in the buffoon packs
like i know i can use if context.open_booster and context.card.ability.name == 'Buffoon Pack' and then each name of each buffoon pack (jumbo etc)
but i dont know how to check the edition of cards
im guessing its going to be some sort of for loop to check each card but its the actual function for checking the edition that i dont know
local set_edition = Card.set_edition
function Card:set_edition(edition, immediate, silent)
if edition == 'edition_key' and self.set == 'Joker' then return end
set_edition(self, edition, immediate, silent)
end
this will stop your edition being applied to jokers
would this be under on_apply orr
sorry for so many questions i have literally zero experience with editions 😭
i cant even reference any editions because lshtechs card library is like completely bugged so i cant easily find editions to refer to
this is just top level of your code
oh alright
weight affects how often it applies right? is it higher or lower for more common
higher for more common
is there a max
im guessing not
im guessing editions use weight as a ratio to compare to other editions probabilities
the edition is just never appearing
can you show the edition code?
wait would self.set == 'Playing' be correct or what would the equivalent be for playing cards
you can do self.set ~= 'Joker'
oh yeah
Messy AF, but I can't figure out why this is crashing on played hand (attempt to index field 'blind' [a nil value]
calculate = function(self, context)
if context.individual and not context.blind.boss then
if pseudorandom('curio') < G.GAME.probabilities.normal/self.ability.extra.odds then
G.E_MANAGER:add_event(Event({
func = (function()
G.E_MANAGER:add_event(Event({
func = function()
local card = create_card('The Chariot',G.consumeables,nil, nil, nil, nil, nil)
card:set_edition({negative = true}, true)
card:add_to_deck()
G.consumeables:emplace(card)
local card = create_card('Deja Vu',G.consumeables,nil, nil, nil, nil, nil)
card:set_edition({negative = true}, true)
card:add_to_deck()
G.consumeables:emplace(card)
return true
end}))
card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_plus_tarot'), colour = G.C.PURPLE})
return true
end)}))
end
end
end,
The small/big blind select is from madness so I don't exactly know what's wrong
presuably you have a case where context.indivdual is true but there is no contex.blind
actually I don't think individual and a blind in context ever go together
Interesting I wonder where I even got that...
I also got way ahead of myself considering the card generation doesnt even work, certainly due to my table values
Is there a list with explanations for each context?
Not sure what's going on with things now...
Trying to make a deck start with a joker 'j_leveler'
Everything should be setup correctly, but I keep getting this error when I try to start a run with the deck
line 27 is card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_leveler')
how do i make it so my custom deck gives you a persistent wee joker on start?
A bit confused on this. Do I need to change the key in the joker?
No. Steamodded adds a prefix to your joker to prevent name collisions.
You just need to add the lrefix to the create_card call
I am struggling to get this fixed, I've done every variation I could think and it's still throwing the error.
Do you define a prwfix in your mod header?
yes, sjmp
Then your jokwe should be j_sjmp_leveler
Appreciate the help.
I am very new to modding balatro and don't really know what I am doing tbh
persistent as in?
Please excuse the 0 brain cell moment lol
Is there any documentation on how this would be done?
what does persistent mean
One more oddity, now, when scoring the hand, my joker isn't adding it's chips or mult to the score.
does that clear it up? sorry for the confusion
I sorted it out, forgot _mod in the return.
I won the 50/50 AGAIN so expect more work on original sound
Is context.after not supposed to be after scoring or I do have some deeper misunderstanding? This code is destroying cards before they're scored:
if not context.blueprint and (context.scoring_name=="Straight" or context.scoring_name=="Straight Flush") then
card.ability.extra.trash_list = context.scoring_hand
card.ability.extra.straight = true
end
if context.after and card.ability.extra.straight and not context.blueprint then
for _, card_to_trash in ipairs(card.ability.extra.trash_list) do
if not card_to_trash.removed then
card_to_trash:start_dissolve(nil, nil, 3)
card_to_trash.destroyed = true
end
end
card.ability.extra.trash_list = {}
card.ability.extra.straight = false
end
Maybe try using context.end_of_round instead, careful tho it will trigger context.individual and repetitions so you'll prob have to exclude those
Hey, Trying to make a personal retexture for myself wondering if its possible to retexture the soul?
Ive tried with no luck to change its little... Floating Stone thing?
easiest way to change assets is to unzip the balatro.exe and copy textures from assets, then add them into the same path but in %appdata%/Balatro
how can i check for played stone cards again?
check that either card.ability.effect == 'Stone Card' or card.config.center == G.P_CENTERS.m_stone (either one should return true for a stone card)
is there a way to put a wild card (or enhancements in general) into the hand preview thing? i've been considering making a mod that just adds the spectrum hand + related stuff (planets, basic jokers) so suit mods can just require that instead of reimplementing it every time, and since this mod would ideally not add a new suit of its own the obvious preview hand is heart-diamond-club-spade-wild
-# alternately, did someone already make this mod and i just didn't find it
how does blue joker check how many cards are in your full deck?
#G.deck.cards
oh cool thanks
thanks
yeah this is what stone joker does
ya i know, i looked at that trying to use it
for the counting
but i ended up creating something better for the counting lol
just one more question, how do i like, only retrigger stone cards?
sorry if it sounds stupid
take a look at sock and buckin' in the source code I think
it didn't work, it does work if instead of it being stone, the joker is for face cards
Does anyone know, in the game files, where is the part that ends the game with game over if the player doesn't reach the blind goal?
I think the function is lose_game
end_round is responsible for calling it when you run out of hands
i guess it can also be called naturally when you run out of handsize
Yeah or hit the lose game debug button
makes me wonder whether you still beat the blind if you run out of handsize with mr bones and meet the 25% score req
I know end_round will behage as if you are done playing your hand
end_round bugs the game out somewhat
Just make sure not to call it when your not in the picking cards state or weird stuff happens
If saved= true
how do i find specific ranks in the full deck?
you count them
Like context.after?
Does lose_round not exiat or just buf out?
???
you iterate through the deck and increment a counter
It crashes saying attempt to call global lose_game (a nil value)
It must be named something eksw
Ley me check
Oh it doesn't have a function like win_game, the debug button just does if G.STAGE == G.STAGES.RUN then G.STATE = G.STATES.GAME_OVER; G.STATE_COMPLETE = false end
local ranks = {}
for i, v in pairs(G.deck.cards) do
ranks[v.ability.rank] = (ranks[v.ability.rank] or 0) + 1
end
something along these lines @vague island
it's probably not Card.ability.rank i just bullshitted that you'll have to find what actually stores rank yourself
huh
i can't exactly read the code if you delete it
Should probably use get_id
wait holup
I think that's what it'd called
seems like what they're using
if context.joker_main then
local deck = #G.deck.cards
local decktable = G.deck.cards
for _, v in pairs(G.deck.cards) do
other_card = v
if
v ~= card
and context.other_card:get_id() == 2
or context.other_card:get_id() == 3
or context.other_card:get_id() == 4
or context.other_card:get_id() == 5
then
chip_mod = 35
end
end
if deck then
chip_mod = deck * 3
end
end
end
}
Works with stone cards and some modded shenanigans
i think i see what im doing wrong :P
What are you trying to do exactly?
Yeah, I was trying to use G.GAME.GAME_OVER, but then it doesn't interact with jokers like Mr. Bones
good point
end_round should be correct then
trying to make it so that 2s, 3s, 4s, and 5s in deck give 35 chips
Hold on
That’s just going to always set the chip mod to deck size * 3
other_card = v seems to be redundant
idk bout that either
Maybe try something like this https://github.com/MathIsFun0/Cryptid/blob/main/Items/CodeCards.lua#L302
my brain is soup
well im also making all cards in deck give 3 chips
idk how to do both lol
welcome to the club
Depending on where your thing is running you might be able to get away without checking the hand. I do that there because ending the round in the consumeable use context breaks
boss blind reference
:ooooo
This worked flawlessly
Thank you so much!
Make sure you remove the semicolon variable setting otherwise you'll never lose when cryptid is installed
Will do 🫡 . Max compatibility is the goal
Also not sure but if thus can go off on the last hand it might end up not activating until you start your next blind make sure that can't happen
I'll fiddle around with this a bit, see what's what
Something like this should work
if context.joker_main then
local chip_mod = 0
for _, v in pairs(G.deck.cards) do
if v:get_id() <= 5 then
chip_mod = chip_mod + 35
else
chip_mod = chip_mod + 3
end
end
return {
chip_mod = chip_mod,
card = card,
message = ‘localise the chips here pls’
}
end```
Code might be scuffed, typing in mobile box is hard
looks good to me but im on mobile too so 🔥
<= 5 matches stone cards (which are random low negatives)
its a feature, not a bug
wouldn’t that also get any card below 5? or am i reading the code wrong 😭
thats the point :)
like hack but blue
i thought, by what wilson said, it was only going for stone cards
neat
(spoiler: ||its weezer's blue album||)
is there a context.other_card:is_face() but for enhancements? cuz this ^ it just doesnt work somehow
You can throw a and v.config.center_key ~= ‘m_stone’
quick question, how do i check for the winning hand?
this is supposed to trigger twice on a 3 of 3s, but it doesn't for some reason
it is triggering correctly on both 3s (suit) and 3s (rank)
calculate = function(self, card, context)
if context.cardarea == G.play then
if context.other_card:is_suit('Minty_3s') then
return {
mult = card.ability.extra.s_mult,
card = card
} end
if context.other_card:get_id() == 3 then
return {
mult = card.ability.extra.s_mult,
card = card
} end
end
end```
you can only return from a function once
I think you can dispatch an event
you could keep a vraible and do 2x for if both are ture
Or use SMODS.eval_this()
"Oh Steammodded has a least some comments!" The comments: -- why bother patching when i basically change everything
😭
can anyone here help me with how to make jokers blueprint compatible?
i have zero clue where to even start
Im having a problem that when cards are destroyed by the joker, random spots appear in the hand. Anyone know why?
if context.after then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
for i = 1,#context.scoring_hand do
if pseudorandom('cream') < G.GAME.probabilities.normal / card.ability.extra.odds then
local checkCard = context.scoring_hand[i]
checkCard:shatter()
end
end
return true end }))
return {
message = "Obliterate!",
remove = true
}
end
Do not destroy cards during scoring contexts
what context should i use if i want them to destroy after they are scored
Use context.destroying_card (ex. Sixth Sense)
ah okay
if context.destroying_card then
for i = 1,#context.scoring_hand do --Error
if pseudorandom('cream') < G.GAME.probabilities.normal / card.ability.extra.odds then
local checkCard = context.scoring_hand[i]
checkCard:shatter()
end
end
return {
message = "Obliterate!",
remove = true
}
end
im getting an error on the line with the comment saying it is a nil value
becuase it tried taking the length
i changed it to full hand and it worked
nevermind
i found out they were already compatible
It's happening and I can't figure out why. I've noticed the "Game Over!" screen only shows up after cards are drawn. For some reason, when the blind requirement is met at the end of round, the cards aren't drawn, therefore the code for end_round() only works when cards are drawn in the following blind.
Do you know why is this? I'm at my wit's end
cause your waiting for it to draw the cards before ending the round
Hey, I'm interested in making a mod. How much coding knowledge do I need to start modding?
if you have enough mods to copy code from then you pretty much don't need anything /j
I guess you've got a point there, I could always look at what other mods do to know how to do things. I guess let's start with the... I don't even know if this is basic at all but I think it might be since there's a few mods dedicated to it. How do I add new hands?
There are PLENTY of people you can ask about that. Probably the people in Bunco for their pretty involved Spectrum hands is a good start.
Also the Fibonacci guy and the Blackjack guy.
ask the guy and the guy imo
Alright. Should I DM them or just ask in the mods' forums?
i'd say you should ask on the forums first and if no one answers after a while send a dm or two
Okay.
I'm trying to make a seal that modifies the base scoring of a card, is there any example of tutorial on setting up a seal that changes how the card scores?
Rather, I'm trying to make a card edition like lucky cards, changing the texture of the card, but I can't find any reference anywhere....
I love sitting and writing code for a hour or two without testing it at all
Mood
I love coding with testing every time i change 1 word
Thats why I made watch for DebugPlus
I did develop this feature using it mostly
but now I'm refacoring it into the codebase
and I had to add a bunch of checks
anyways moment of truth
oh I think I accidently depdned on a mod
how do I get the type of card from it's center
oh .set
not sure why eval didn't show thart
hi!
im,, trying to make a custom poker hand that overrides two pair if it's a dead man's hand (two black aces and eights) and while i have most of the pokerhandpart things down, it doesnt seem to be loading properly (and crashes if i open up the hand list)
its, probably a really simple fix, but i cant tell what it is i need to look at djshsdjh
key = 'deadhand',
func = function(hand)
local current_cards = {}
local activated = false
for i = 1, #hand do
table.insert(current_cards, hand[i])
end
if G.jokers ~= nil then
for _, v in ipairs(G.jokers.cards) do
if v.config.center.key == 'j_tma_Gunslinger' then
activated = true
print("hasGunslinger")
else
activated = false
print("noSlinger")
end
end
end
local ace_black = 0
local eight_black = 0
for i = 1, #hand do
if hand[i]:get_id() == 14 and (hand[i]:is_suit("Spades", nil, true) or hand[i]:is_suit("Clubs", nil, true)) then
ace_black = ace_black+1
print("ace", ace_black)
elseif hand[i]:get_id() == 8 and (hand[i]:is_suit("Spades", nil, true) or hand[i]:is_suit("Clubs", nil, true)) then
eight_black = eight_black+1
print("eight", eight_black)
end
end
if eight_black >=1 and ace_black >=2 and activated then
print("has hand!!!")
return {hand}
end
return {}
end
}
SMODS.PokerHand{ -- Dead Man's Hand
key = 'dead',
above_hand = 'Flush Five',
visible = false,
chips = 0802,
mult = 1876,
l_chips = 0,
l_mult = 0,
example = {
{S_8, true},
{C_A, true},
{S_A, true},
{C_8, true},
},
evaluate = function(parts)
return parts.deadhand, parts._all_pairs
end
}
code to go with it
reverse pareidolia:
local is_face_Ref = G.FUNCS.is_face()
function G.FUNCS.is_face()
local id = context.other_card:get_id()
if id == 11 or id == 12 or id == 13 and SMODS.find_card('j_mini_faceblind') then
return false
end
local result = is_face_Ref() -- top = before, bottom = after
return result
end
somehow it just isn't working?
does that mean i cannot hook it?
No you can hook it, you’re just trying to hook a function that doesn’t exist
I can't find any info on setting a custom face texture like lucky cards anywhere. I've looked. Are there any examples or tutorials on making an enhancement that changes the face texture?
would you like to change the texture of the face cards like they have with the collabs?
or spesific texture if for example a facecard is gold?
or perhaps, making your own enhancement?
It would be my own enhancement, but one that only changes the texture of the face card. Like how a lucky card looks like old paper.
like, a texture pack?
a way to change the looks of ingame stuff without messing with the code
Not just a texture pack, The enhancement will be a knockoff-clone of a played card that has a unique scoring function. It will be created by a joker I have already made. I'm not looking to change the games texture packs
alr thanks for making that clear first of all
I've tried looked into cryptid, to figure out how echo cards were done, but I can't find any reference in the source code where the enhancement is declared, nor can I find any reference on the eclipse deck
crypid's code looks just like the base source code
Looking through the games source code is equally fruitless
so true
so i personally find it hard to make sense out of both of them
i prefer looking at things like this: simple joker, has name, some text, but does overall nothing
the most basic and easiest struckture
and then the lovely patch to make it work
sounds like my worst nightmare
don't scare 'em off with lovely now
lovely isn't that bad
it's just so unnecessary in a lot of cases
yes but also the best way to do things in a lot of cases
and it makes reading a mod quite a bit harder
depends
i can't imagine any situation where digging through a patch file would be easier than just reading the code as it appears in a normal file
haven't used it yet my self
would u allow me to dm?
in cases where you need to patch one thing but have to reiplement the entire function cause the patch is in the middle
well yeah but you can't do that without lovely anyways
ain't talking about that
?
Sure.
cough
well its technically never nessicary but it's better in a lot of cases
lovely is sometimes used where it isn't necessary which makes things harder to look at
theres a reason SMODS moved to it
it's necessary unless you fancy overriding functions
which no good mod should do without a very good reason
I'm confused on what your argument is then?
sucks for you I guess
like would you rather read this https://github.com/jamesthejellyfish/JellyMod/blob/main/JellyJokers.lua#L1536-L1553 or https://github.com/WilsontheWolf/JamMod/blob/master/lovely.toml#L70-L78 (I did implement it a bit differently)
idk what you expect me to say I don't want to go through an entirely separate file to find something
i would much rather look at the first one even if that lovely patch takes up less space
7 but they some are farily tightly coupled
like watcher is pretty much a component of console
do while true do repeat until true or false break end if not false and true then end do return end end imo
oh wait
i didn't structure that right
yeah
reminds me of this
yeah
i didn't for awhile either
Yeah I didn't but I tried using contiune and it didn't work so I googled it and they were just like use goto
i actually figured it out by typing in continue and luals corrected it to goto continue with a ::continue:: at the end of the for loop
oh lol
thats actually the second time I've used goto in DebugPlus
yes
i tought i knew how to make it but now i am not that sure
I'm pretty sure we can do all of those in the screenshot
My brain is also melting looking for any information on how to change a playing cards atlas when it is enhanced...or change the texture coordinates
likw what is your goal?
I have a joker that makes (poorly) cloned coppies of played cards. I want to give them a different face texture, like a lucky card/echo from cryptid, that makes them look distinguishable from a normal playing card. The joker is done, it makes cards and adds them to the deck, I have seen how to add enhancements to created cards. I just have no reference to changing a playing cards atlas, or texture coordinates when the enhancement is applied. I would like to avoid a shader, if possible.
you should just be able to provide the atlas and pos to the constructor, like you would in a joker
Hmm, okay. lets give that a shot then.
can someone tell me what i did wrong, i got a loda of help from larswijn (thanks!) but it is still not working like i would want it to?
expected:
reversed pareidolia:
all facecards are numbered cards
gotten:
face cards are numbered cards BUT numbered cards are face cards
your not calling is_faceRef
??
how?
()
local result = is_faceRef()
You should understand the basics of how lua works
nah, been at it without any knowlegde
does that mean i also need the top to be like: local is_faceref() = Card.is_face ?
nvm its a nope
oh-
smth happend
How would I go about setting a cards base chips to half the original value
This is for an enhancement, I know I have to mess with the nominal. somehow.
Im trying to reduce the ante by 1 but this code is doing, well 14 times. anyone know why? Im thinking its the ease ante
if context.end_of_round and G.GAME.blind.boss and not context.blueprint then
local ante_mod = 0
if to_big(G.GAME.chips) >= to_big(G.GAME.blind.chips) * card.ability.extra.scoreRec then
ante_mod = ante_mod - card.ability.extra.ante_reduction
ease_ante(ante_mod)
end
end
Would this result in the cards chip scoring being set to newbase if placed in calculate?
chips = newbase,
message = localize({type = 'variable', key = 'a_chips', vars = {chips}}),
})```
Likely missing some context checks
Try printing the contexts it’s calling on
I think you might also need to add not context.repetition and/or not context.individual as checks
I have a joker that does something at the end of round, the contexts string is lua if context.end_of_round and not (context.individual or context.repetition) then
also a check for blueprint in there
Is there a function that I can use when an enhancement is placed on a card?
Card:set_ability() is what puts enhancements on a card
is there a context for winning hand?
winning hand as in the hand you won at or the poker hand you won with?
Usually you use end_of_round and check if the goal was reached
but if i want a action, ON the winning hand?
What action do you want to do on the winning hand?
i want to- oh? modlitch changed the joker a bit
how do i destroy smth from the full deck?
@nocturne garnet yk how u help me make silly? and how it destroys a card from the played hand (on last hand)
could you please help again? we need to change it a tiny bit to destroy something out of the deck
chat uhm
i suddenly got an idea
for like a cryptid addition
or smth
just a funni joker
that scales off meme jokers
Where do I find the chips scored so far in a hand? The chips part, that is, not the mult. I want to manipulate it with a joker
G.GAME.chips iirc
might be G.GAME.blind.chips or smth lemme check
ok yeah
G.GAME.chips
G.GAME.blind.chips is the score requirement i guess
No G.GAME.chips is already multiplied by the mult
Ooh but maybe I can look what is put into the UI
It's G.GAME.current_round.current_hand.chips
I just need the context after hand chips are added
it's a local variable in the function that calculates the score of a played hand iirc
I'm interested in making a mod. How much coding knowledge do I need?
find enough mods to steal code from /j
im just wanting api documentation on balatro
like how they learned this:
local Calculate_reroll_costRef = calculate_reroll_cost
function calculate_reroll_cost(skip_increment)
Calculate_reroll_costRef(skip_increment)
G.GAME.current_round.reroll_cost = 0
end
but like the Steamodded example mods are really useful to learn the basics
i basically forgot everything from my coding class and i was able to create a joker fairly easily
just be sure not to forget to close your brackets and such
how much do you have?
absolutely none
I mean it depends on what you want to do, but aside from being able to follow instructions, you'll likely need to know:
- Variables
- Conditionals (if/else)
- Boolean Logic
- Loops (for and while)
- Tables/Objects in Lua
- Functions as functions
- Functions as variables
- How to read other people's code so you can understand how the framework works
I learned Lua for the first time while doing this, but I've had a decent bit of prior programming experience. I'm not sure if there are Lua tutorials for people who have never programmed before, but if there are, you should go looking for those. Otherwise, it would probably do you good to look into Python to pick up some basic skills and then apply them to Lua.
where are game actions stored
not sure exactly what you're referring to. Could you give an example?
im wanting to do task automation in balatro that programmatically rerolls in shop until a card is identified. once the card is identified, i want to purchase it and then continue rerolling
i tried it in python using opencv, using image identification. my python code successfully identified reroll in the shop, but having it locate cards i wanted was difficult due to images looking similar on tarot cards
so, i tried using tesseract ocr instead to get the text then get the x,y coord to send a mouse click event
but that also proved painful
apparently G.FUNCS.reroll_shop is a function defined in button_callbacks.lua
It's not enough. You should check can you reroll first
i have reroll set to $0
it can reroll
local Calculate_reroll_costRef = calculate_reroll_cost
function calculate_reroll_cost(skip_increment)
Calculate_reroll_costRef(skip_increment)
G.GAME.current_round.reroll_cost = 0
end
G.FUNCS.can_reroll is also defined in button_callbacks
i found this for setting the reroll to zero. it was shared here on the discord, this works. its cool
yes, i see that now
but this looks like its primarily the math logic behind it (unless im missing something)
i saw someone made a bot using this
Bot.ACTIONPARAMS[Bot.ACTIONS.REROLL_SHOP] = {
num_args = 1,
func = "select_shop_action",
isvalid = function(action)
if G and G.STATE == G.STATES.SHOP and (G.GAME.dollars - G.GAME.bankrupt_at - G.GAME.current_round.reroll_cost >= 0) then
return true
end
return false
end,
}
but im not privy enough with the games internals to understand what this means exactly, the select_shop_action looks like a sql query (???), so many its related to this api snippet?
No it isnt. Most likely it's unique key for bot action or smth
Game doesn't have any actions
gotcha
All actions in game controlled by events
gotcha, so ui action triggers or fires the event
function calculate_reroll_cost(skip_increment)
if G.GAME.current_round.free_rerolls < 0 then G.GAME.current_round.free_rerolls = 0 end
if G.GAME.current_round.free_rerolls > 0 then G.GAME.current_round.reroll_cost = 0; return end
G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase or 0
if not skip_increment then G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase + 1 end
G.GAME.current_round.reroll_cost = (G.GAME.round_resets.temp_reroll_cost or G.GAME.round_resets.reroll_cost) + G.GAME.current_round.reroll_cost_increase
end
ah i see this in the event handler
G.FUNCS.reroll_shop = function(e)
ah, there it is
so, i guess my question now, is it possible to loop an invocation of this function?
or is that not really a thing with steamodded?
Let's assume you want reroll a shop and check jokers for buying.
Your code will look like this:
function iterate_shop()
G.E_MANAGER:add_event(Event({
func = function()
for i, card in ipairs(G.shop_jokers.cards) do
if is_joker_im_looking_for(card) then
G.E_MANAGER:add_event(Event({
func = function()
-- Check for ability to buy card and then buy. Good luck)
return true
end
}))
end
end
G.E_MANAGER:add_event(Event({
func = function()
G.FUNCS.reroll_shop()
G.E_MANAGER:add_event(Event({
func = function()
-- Here, you can call next iteration
return true
end
}))
return true
end
}))
return true
end
}))
end
what the
welcome to balatro
Let me be a bit more specific. I want to make an enhancement that sets the base chips of a card to half the original value. I want it to only score half the chips the card normally would. I'm not sure how to grab the original chip value from inside the calculate tab, and having a way to grab that value when the enhancement is added and set it for later use would be very helpful.
The bulk of the enhancement's code is done. It can be applied to cards, but without the original cards base chips, it isn't going to work
hi i just came back from a trip
i'd assume if you destroy a random card in G.deck.cards (or G.hand.cards if theres no cards in deck) then it'd work
havent done anything in a while so i might be wrong lol
How does one make you start a deck with a joker already in your hand?
I want to make it so where if you select the deck I am making an eternal wee jokers gets put into your hand
thats fine! how was the trip? hope it was good!
lol
It seems I need to make an edition, not a enhancement
Editions have on_apply and on_remove abilities
sigh
What aboutttt, selling a card? 0-0
idfk
if you haven't accomplished this yet i did this exact thing once and while i don't have the code anymore i could probably help out
well, I did it myself, without any balatrobot api stuff
but regardless
how did you accomplish it?
i normally do c++ WINAPI stuff, windows internals stuff
so this is outside my realm of study (i also hate it, im weird and dont like lua syntax, it hurts my brain)
i dont remember exactly, it was pretty much the first thing i did when i started modding
i suppose as a fun little exercise for myself ill write it again from scratch, extensively comment it, and send it here
Well, I managed to get the enhancement to score, but it still scores the base chips of the card, is there any way to disable the base nominal of the card played, or overwrite it?
Would that be something to do in the toml portion?
You can either modify the base chips when the enhancement is added, or hook the function that gets that amount and manipulate it if your enhancement is present
@slow parcel here ya go, you can edit the specific cards you want it to buy in the file, the defaults i put in there to test it are blueprint, brainstorm, and showman
note that you toggle it on and off with 0, its on by default, and it can crash if you try to exit the shop while its running
not working for me
did it work for u?
ya
only reason i can imagine it wouldnt work is if you didnt unzip it or smth
or if steamodded isnt installed or smth
remove freereroll.lua
click the reroll button once
i imagine its still 0
since
yk
freereroll
nah hold on, i did an oopsy, that times its on me
oh
ah now its working
nice
freereroll sets the cost of rerolls to 0 24/7, the method that i used to properly wait until it actually can reroll again is to check whether the reroll cost isnt 0 (as an indicator of whether the game has set the reroll cost yet)
and of course if the reroll cost is always 0 then itll always be waiting for it to not be 0
G.FUNCS.buy_from_shop({ --then buy it
config = {
ref_table = card
}
})
guess buy and use?
not sure on what functions youd use
youd have to differentiate between consumeables and non-consumeables
i have somethign working dw
should work well enough
damn bros cookin
Oops! The game crashed:
card.lua:1591: attempt to index local 'eligible_card' (a nil value)
Additional Context:
Balatro Version: 1.0.1m-FULL
Modded Version: 1.0.0~ALPHA-1031a-STEAMODDED
Love2D Version: 11.5.0
Lovely Version: 0.6.0
Steamodded Mods:
1: Uncap Hermit by Infarctus [ID: Uncap_Hermit]
2: Choose First Shop Joker by infarctus [ID: choose_first_shop_Joker]
3: Shop Reroller by cg [ID: shopreroller]
4: spacereroll by sishui [ID: spacereroll]
Lovely Mods:
Stack Traceback
===============
(3) Lua field 'func' at file 'card.lua:1591'
Local variables:
over = boolean: false
eligible_card = nil
edition = table: 0x12a4c088 {polychrome:true}
(*temporary) = string: "Hex"
(*temporary) = nil
(*temporary) = table: 0x12a4c060 {}
(*temporary) = nil
(*temporary) = nil
(*temporary) = Lua function '?' (defined at line 292 of chunk functions/misc_functions.lua)
(*temporary) = number: 0.0309498
(*temporary) = string: "%.13f"
(*temporary) = number: 0.0309498
(*temporary) = string: "0.0309497880069"
(*temporary) = string: "attempt to index local 'eligible_card' (a nil value)"
(4) Lua method 'handle' at file 'engine/event.lua:55'
Local variables:
self = table: 0x133a3d88 {start_timer:true, timer:TOTAL, blockable:true, trigger:after, func:function: 0x133a3d60 (more...)}
_results = table: 0x128a68f8 {blocking:true, pause_skip:false, time_done:true, completed:false}
(5) Lua method 'update' at file 'engine/event.lua:182'
Local variables:
self = table: 0x12cc5cc0 {queue_last_processed:49.399999999998, queues:table: 0x12cc5ce8, queue_dt:0.016666666666667 (more...)}
dt = number: 0.0166407
forced = nil
(for generator) = C function: next
(for state) = table: 0x12cc5ce8 {unlock:table: 0x12cc5d10, other:table: 0x12cc6188, tutorial:table: 0x12cc5d60 (more...)}
(for control) = number: nan
k = string: "base"
v = table: 0x12cc5d38 {1:table: 0x129dc2d0, 2:table: 0x133a3d88, 3:table: 0x133a4090, 4:table: 0x133a4300 (more...)}
blocked = boolean: false
i = number: 2
results = table: 0x128a68f8 {blocking:true, pause_skip:false, time_done:true, completed:false}
(6) Lua upvalue 'gameUpdateRef' at file 'game.lua:2502'
Local variables:
self = table: 0x126cd5e0 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x1313fb40 (more...)}
dt = number: 0.0166407
http_resp = nil
(7) Lua method 'update' at Steamodded file 'core/ui.lua:81'
Local variables:
self = table: 0x126cd5e0 {F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true, HUD_tags:table: 0x1313fb40 (more...)}
dt = number: 0.0166407
(8) Lua upvalue 'oldupd' at file 'main.lua:965'
Local variables:
dt = number: 0.0166407
(9) Lua field 'update' at file 'shopreroller.lua:81' (from mod with id shopreroller)
(10) Lua function '?' at file 'main.lua:909' (best guess)
(11) global C function 'xpcall'
(12) Love2D function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 880 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(Love2D Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(Love2D Function)' (defined at line 355 of chunk [love "boot.lua"])
oh oops yeah
never seen balatro implode before locally. p cool
thank god its got a copy to clipboard function
1 its working
2 its taking over 9000 rerolls to get the card i wanted
lmfao
but ya, it works flawlessly, this is so sick
tysm @hardy viper
nice
why are you doing this again? 🤔
i wanted to try to use the boot thing and bull thing to get tons of money
and go for inf with it
without cheating too much
and also getting tons of pluto cards
ah okay 😅
i once tried going for inf by doing x mult per card in deck
but once i had like, 250 cards, my game was dying of resource exhaustion
wtf r u me
what are you trying to do
all i did was try to put a function in a table......
table being G.GAME.....
well atleast being inside g.game
unfortunately i kinda suck ass and i probably did something wrong
aww
is there a way to check whenever a card is played instead of scored? trying to make a scaling joker off of 3s but i dont wanna make it too op with hack and stuff like that
ubiquity's evil twin
if you check context.full_hand before the hand scores, it might work
(in context.before obv)
this is not so obv to me im still very new to this stuff
it works yippee
why did i think the negative one was this for a second (warning, spoopy trollge)
why does he have two sets of teeth
idk trollge creators be making that spoopy stuff
thanks to shop reroll, naneinf was easily achieved
v cool
but, the game is laggy as hell. has any experienced this, or seen this?
i'm trying to make a new booster pack, but the cards are showing up squished together, can anyone figure out why?
SMODS.Booster({
key = "workshop",
kind = "Tarot",
no_doe = true,
pos = { x = 1, y = 0 },
config = { extra = 3, choose = 1 },
weight = 0,
draw_hand = true,
-- update_pack = SMODS.Booster.update_pack,
loc_vars = SMODS.Booster.loc_vars,
ease_background_colour = function(self)
ease_background_colour_blind(G.STATES.TAROT_PACK)
end,
create_UIBox = function(self)
-- G.GAME.pack_size = 3
return create_UIBox_arcana_pack()
end,
particles = function(self)
G.booster_pack_sparkles = Particles(1, 1, 0, 0, {
timer = 0.015,
scale = 0.2,
initialize = true,
lifespan = 1,
speed = 1.1,
padding = -1,
attach = G.ROOM_ATTACH,
colours = { G.C.WHITE, lighten(G.C.PURPLE, 0.4), lighten(G.C.PURPLE, 0.2), lighten(G.C.GOLD, 0.2) },
fill = true
})
G.booster_pack_sparkles.fade_alpha = 1
G.booster_pack_sparkles:fade(1, 0)
end,
create_card = function(self, card, i)
if i == 1 then
return create_card("Tarot", G.pack_cards, nil, nil, true, true, "c_death")
elseif i == 2 then
return create_card("Tarot", G.pack_cards, nil, nil, true, true, "c_hanged_man")
else
return create_card("Tarot", G.pack_cards, nil, nil, true, true, "c_hermit")
end
end,
group_key = "k_tarot_pack",
})
I'm using set_ability to apply my enhancement, but the game keeps throwing an error and I'm not sure what is going on
looks cool. I wonder if you could have an alternate version for high contrast cards (would probably require code injection)
send the full line of code setting the enhancement + maybe some context
card.ability.extra.hnum = card.ability.extra.hnum + 1
if card.ability.extra.hnum > 0 then
for i = 1, card.ability.extra.hnum - 1, 1 do
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
local _card = copy_card(context.full_hand[1], nil, nil, G.playing_card)
_card:set_ability('coppied_card')
_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, _card)
G.deck:emplace(_card)
_card:start_materialize()
end```
The rest of the function works fine, creating a copy of the card and adding it to the deck
you're using steamodded to add the enhancement?
what's the code for that look like?
steammodded and there is an accompanying toml
I take it you used the key 'coppied_card'? What's your mod prefix?
sjmp
so the full center key I believe would be 'c_sjmp_coppied_card'
try passing that into set_ability
man just reinvented cookie clicker
It is now throwing a completely different error for config
what's it saying?
this joker was always a cookie clicker reference lol
now it's literally cookie clicker
The enhancement had been placed on a card by another card previously, so I know that functions.
But when I go to add it on it errors
local copy_card = SMODS.Enhancement {
key = 'copied_card',
atlas = 'sprotsAtlas',
loc_txt = {
name = "Coppied card",
label = "Coppied card",
text = {
"Earn half base {C:chips}chips{} when",
"this card is scored"
}
},
unlocked = true,
discovered = true,
pos = { x = 2, y = 0 },
config = {
newbase = 0,
},
replace_base_card = false,
no_suit = false,
no_rank = false,
weight = 0,
overrides_base_rank = false,
any_suit = false,
always_scores = false,
loc_vars = function(self, info_queue, card)
return { vars = { self.config.newbase } }
end,
}```
oh copied_card not coppied_card

I do believe copied is the correct spelling btw
same error, though it was a typo
removing the set_ability call returns it to working order.
peak??
i did fix this thing
actually, theres smth wrong with my reset system
fixed dementia lol
create a negative of which joker?
random one
alright time to try this again
how do I add temporary hands and discards
ease_discard and ease_hands_played aren't working
How are you using them?
in context.after and with two other conditions which are triggering normally
the code gets to the lines in question, but doesn't change hands/discards
ease_discard(-G.GAME.current_round.discards_left, nil, true)
ease_hands_played(card.ability.extra.hands)
it doesn't crash either, they just don't happen
If you throw a 1 in there does it work?
oh hold on i'm getting an atlas crash
do mod atlases need to use the mod prefix now?
No
this crash doesn't make sense to me
didnt happen last time i tried this, so I do think its a steamodded update that changed how something worked
and idk how to fix it
Did you change a path or delete a file by mistake?
i dont think i did
i got busy suddenly
a-
wait
the
the atlas is GONE
how did that happen
is target = "=[SMODS _ \"core/overrides.lua\"]" supposed to be the correct target for patching smods files?
that doesnt work rn iirc
at least, not for the nested smods files
lemme see if i can find that conversation
im interested in looking how to make my own deck for balatro, is there any sort of community guide for looking how to get started in modding
explode
💥
cheers!
okay then uhh can someone assist with making this. Actually Run
seems like something youd hook eval_card for idk
im unsure though i never worked w scoring
i already have an eval_card hook, but mult_mod does not go through that
ok so i've got up to here but i have no idea why it doesn't work now
im trying to make a joker that scales every 3 played (not scored)
tells me theres something wrong with line 69 (nice) but from the little balatro code i understand i dont see why it doesnt work
You don’t need the next in that line
I don't think other_card exists in context.before?
use context.before and iterate over context.scoring_hand, and if it finds a 3, you break and upgrade the mult
question: how do you check for stone cards in a played hand? i wasnt sure if i should check for its ID, or if its something like is_enhancement()
You can check the center key
ok so i replaced some of the code with some from Weebonacci of the Cryptid mod, now there's no error on line 69 but for some reason it doesn't like the } on line 80, which doesnt make sense cause the code doesn't add any {} things
This was cool
balatrostuck is balatroback
we are so backatro
first new joker
dang
i should read homestuck
yesss...
Wow
I have been thinking about getting back into Balatro modding
Does anyone know what "dissolve_mask" is in shaders?
just figured out why none of my lovely patches have been applying... this whole time I've been working in Mods/modname/modname
trying to do some experimentation with the title screen card
is it not possible to replace the initial card in the logo (the Ace of Spades) with an SMODs Joker?
put in the key for one of mine and it crashes every time
the center is there in the table, and i'm using the same logic that the vanilla game uses to load jokers in that position, but for some reason it doesnt wanna work with an SMODS joker
you should check the cryptid code since it replaces the ace with a cryptid spectral card
no, it adds the cryptid spectral next to the ace
im studying that code
oh right yeah, but it still adds glitched and gold seal so it could be helpful anyway
local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, G.TITLE_SCREEN_CARD, G.P_CENTERS.c_base)
elseif type(G.TITLE_SCREEN_CARD) == "string" then
local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, G.P_CARDS.empty, G.P_CENTERS[G.TITLE_SCREEN_CARD])
else
local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, C_A, G.P_CENTERS.c_base)
end```
using this code in a lovely patch, this code doesnt work at all for some reason.
but if i just do ```local replace_card = Card(self.title_top.T.x, self.title_top.T.y, 1.2*G.CARD_W*SC_scale, 1.2*G.CARD_H*SC_scale, G.P_CARDS.empty, G.P_CENTERS[G.TITLE_SCREEN_CARD])``` it works perfectly
the crash says card is nil when it tries to emplace it, somehow
G.TITLE_SCREEN_CARD is currently a string but somehow it comes out unable to set the card
and i'm like 99.99% sure this is the correct syntax for if else so whats the deal here, game
ok I put the if else into a function I put in the mod code and then had the lovely patch code call that and now it works. dunno what the deal with that was but hey got it working now
lmao
Probably @languid mirage knows
But the main shader used in the game is the dissolve shader I think
I don’t know exactly but I think between rendering a card normally or rendering it disappearing is one of the inputs it takes
it's a function that only does card burn effect when card is being dissolved
What is the string to get / change the base nominal of a card?
e.g. when you use a consumable
or dagger eats a joker
you need to have dissolve_mask() run last, since it would have to be on top of your shader
very annoying implementation imo, but yeah
and you have to keep the function because otherwise compiler optimization will yell at you for having unused externs
Ah, okay, thank you
There’s something wrong with how you’re adding that I think
does anyone have a guide to start modding the game
i want to make a mod but idk how
steamodded has good example mods to help you understand the basics of code
if my mod added a joker Prosopagnosia: No cards count as face cards, how would you expect the game to behave when you had it alongside Pareidolia
whichever is left most
honestly do this except if paired with pareidolia give x5 mult or something like that
that might work
Prospagnosia: No cards count as face cards. X5 Mult if played hand contains a face card. and Pareidolia overrides Prosopagnosia
that would probably get some amusing reactions from the seeming self-contradiction before people figure out the trick
that exact idea is alr implemented ngl
Whoops, iirc*
How did i mix those up...
yeah probably, it seems obvious enough
i haven't played whichever mod(s) it's in myself, though :p
idfk why it does that
probably wont do anything much anyways
how do you have a joker specifically add mult to a playing card? this is the code i currently have, its a little rough but it adds chips to stone cards, not mult:
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if context.other_card:get_id() <= 0 then
card.ability.extra.mult = math.min(card.ability.extra.mult + card.ability.extra.mult_gain, card.ability.extra.max)
context.other_card.ability.perma_bonus = (context.other_card.ability.perma_bonus or 0) + card.ability.extra.mult
return {
extra = {message = localize('k_upgrade_ex'), colour = G.C.MULT},
colour = G.C.MULT,
card = card
}
end
if context.joker_main then
return{
message = localize{type = "variable", key = "a_mult", vars = {card.ability.extra.mult}},
colour = G.C.MULT,
}
end
end
end
}
im presuming its something to do with perma_bonus, but i wasnt sure what to try or do about it 😭
(the card).ability.mult = (value)
but it doesnt show up sadly
still works tho
ty
do you know of a way to make it show up? that does work, but it is annoying to not be able to see it 😭
no idea sadly 😭
fair enough
what'd you do
i wish odds text handling was different to allow for that
half all probabilities
lol
also anyone know how to check if a chance thing sucsessfully happend?
nvm, it doesn't matter that it looks weird, might be funny actually,
can i see the config table raisedcateyebrow~2
oh sure!
there
whole joker 😏
honeslty? no clue, wanna say it might be the return missing something, but i wouldnt know what :so
is this how you hook it now????????
like what the fuck is going on with calculate_joker now
Wha? Wth is going on my god
is this the correct way to call a config file?
--Making variable for Config
jojoker_config = SMODS.current_mod.config
--Calling Setting
jojoker_config.part_seven
--config.lua
return {["part_seven"]=true}
it is returning nil
Can you send how you’re applying it? There’ll be an easy fix I think
for i = 1, #G.hand.highlighted do
G.hand.highlighted[i]:set_edition({negative = true},true)
end
Is that the entire use function of your consumables?
is there a way to make a joker always activate last no matter what position it is in?
no, its just the part that sets the edition
What’s the rest?
question - is there a specific context to use for only affecting jokers? im attempting to make a joker that directly effects and boosts other jokers, but i wasn’t sure what to use 😭
(i wanna say its joker_main but, wanted to check)
Is context.cards_destroyed supposed to run after a card is destroyed? because this code doesnt run after the card is destroyed
if context.cards_destroyed then
print("ran")
for i,val in ipairs(context.removed) do
if pseudorandom('crazydiamond') < G.GAME.probabilities.normal / card.ability.extra.odds then
table.insert(card.ability.extra.cardToRestore,val)
end
end
end
Hi, I wanna get one of my cards in a mod, but how much coding knowledge do I need?
(this is sepia joker, it's like the reverse of blackboard, triggering with hearts and diamonds instead)
Do you know how to code and if so in lua?
you can most likely take the code from blackboard and botch it to do the opposite, what you want to do isnt that hard?
or shouldn’t be, at the very least?
but this is balatro modding so fuck knows
no, i mean people have said I can take the code from other jokers and see how they do it
yeah, thats all gkod
as long as you can read your own code, and understand what it does, you are good
do you have access to the source code of balatro?
no, how do I get it?
im pretty sure theres a guide somewhere, but if i remember correctly:
- find the .exe of balatro (should be in steamapps)
- zip it, recommended to use 7zip but you dont have to
- extract that zip
- that should do it?
okay, did it
yall know how i could choose a random joker to retrigger?
thats what im doing and its going pretty good. ask here if you have any questions tho.
okay
i cant tell you exactly since i have no idea, but i presume you’d loop through all the jokers, give your joker a probability and have it pick one? im not sure
cant help you more then that unfortunately 😭
so... i'm trying to set up a localization file for a mod, and it doesn't seem to be loading; even though i've put en-us.lua in a "localization" subfolder of the mod's root folder.
mind telling me what i'm doing wrong?
what does it look like inside?
would anyone here be able to help me with installing mods?
Since I don't know much LUA, in this Cryptid Epic Joker code, hand_chips is global. Is that a LUA thing? A balatro thing?
local sync_catalyst = {
object_type = "Joker",
name = "cry-Sync Catalyst",
key = "sync_catalyst",
pos = { x = 5, y = 2 },
rarity = "cry_epic",
cost = 12,
order = 54,
blueprint_compat = true,
atlas = "atlasepic",
calculate = function(self, card, context)
if context.cardarea == G.jokers and not context.before and not context.after then
local tot = hand_chips + mult
i wanted to offer to help the pokermon team convert their code to be more localization friendly, but already i'm running into problems that i haven't run into on my personal mod
i think i'm using localize right, but i'm getting ERROR and confirming through debug lovely injections that the variables i'm trying to add aren't getting added...
loc_txt = {
name = localize("safari","labels"),
text = localize("safari_desc","labels")
},```
return {
['misc'] = {
['labels'] = {
['safari'] = "Safari",
['safari_desc'] = {
"Can only be obtained",
"through {C:attention}Evolution{}",
"or certain {C:attention}Pokeball Items{}"
}
}
}
}```
i understand that this may not be the way it's "supposed" to be organized, but i'm just trying to get some variable input
i thought i understood how to make a localization file... 😞
bump
now i'm getting this instead...?
it's a balatro thing
i swear, it's gonna take me more time to code my own workaround localization for it than get an answer on how localization file structure works
i would take a look at how cryptid does it
your contents seem fine, make sure it's in Pokermon/localization/en_us.lua or similar
has anyone tried chaniging seals before hand (such as what midas masks does for enhancementes)?
I tried just calling v:set_seal(seals[k], true, true)
but it still has it's old effect
If i set it outside the event it wokrs
but then the sprite changes too soon
Not sure if loc txt supports the localize function like that, I’d suggest structuring your loc file into objects with their keys
did you figure this out? same problem
use = function(self, card, area, copier)
if area then area:remove_from_highlighted(card) end
if pseudorandom('antiparticle') < G.GAME.probabilities.normal*2/card.ability.extra.odds then
for i = 1, #G.hand.highlighted do
G.hand.highlighted[i]:set_edition({negative = true},true)
end
else
for i = 1, #G.hand.highlighted do
G.hand.highlighted[i]:start_dissolve()
end
end
end,```
literally all there is
huh, do you run any other mods that are trying to add negative playing cards?
i want my mod to have a joker named "phase bus" but i don't know what its effect should be
all I've got is "it's a bus, it could be like ride the bus but different" and "it's a cat related injoke and my mod has some cat related stuff in it, maybe it could interact with those somehow"
maybe something like "every 3 consecutive hands without a face card, create a spectral card"?
looks at how much coding knowledge i actually have (not very) that idea might have to go on the back burner for a bit
doesnt sound the hardest, but yeah that will take some code
nope
steamodded just made negative playing cards WEIRD
Does anyone have an answer
I want to create the joker as always negative - is there a field for that? Or what do I call where/when with set_ability? Nothing I find in code works around set_ability or set_edition. Is there a callback function on creation?
add_to_deck = function(self, card, from_debuff)
card:set_edition({negative = true},true)
end,
I think it's step 12, see https://discord.com/channels/1116389027176787968/1247703015222149120
and the context is
remove_playing_cards = true
removed = cards_destroyed
I didn't know that was there, thanks!
Thanks, I can add that as part of the SMODS.Joker {} table?
Yeah just learned about it a few days ago, it's super helpful; though honestly you can also read the evaluate_play function in the source
ya
spectral cards are too rng for this to work amazingly imo
some amazing ones but also some pretty mid ones
true, but i'm not going for "amazing"
i'm going for "exists in the same game as seance without either making the other entirely pointless"
oh okay lmao
is there a specific way to make "X+ extra Y" appear on playing cards? i cannot get it to show up when i add mult to stone cards 😭
Idk if this is the right place or not, but I'm trying to use immolate (seed finder program) to try and find a seed that has blueprint + stuntman + brainstorm after a skip tag + jumbo buffoon pack in the first shop. I've never coded in c++ before, but I have done coding with text before, and I'm looking at both the example filters and the documentation and I'm noticing that the function names seem to be different between the docs and the example codes?
wait have you got the immolate link??
An OpenCL seed searcher for Balatro. Contribute to MathIsFun0/Immolate development by creating an account on GitHub.
You're welcome!
I've made a script that lets me find blueprint + stuntman by modifying the four deadly jokers example, but for this I don't think I can just modify an example
Basically, is the documentation just out of date, or is there something I'm missing
Yeah, I noticed there was a function that wasn't really listen inside the docs inside of the examples
buffoon_pack(jokers, 4, inst, 1);
(jokers is a variable declared earlier)
So then does next_shop_item return joker_data as part of the item that's rolled? Because I've been trying to get the rarity of the first joker in the shop, and it keeps telling me there's no member named joker_data
You have to use next_joker_with_info
I think this would be better in set_ability rather than add_to_deck, using add to deck will make it spawn as standard in the shop
thinking about it, i kinda basically know how to construct this by just copying pieces from existing jokers
after every hand, check if a face card was played (copied from ride the bus)
if so, set a counter (copied from invisible joker) to zero
if not, increase the counter by one
if the counter is now three, create a spectral card (copied from seance) and set the counter to zero
i could probably implement this without much trouble at all
the coding methodology of victor frankenstein, i guess :v
botching is a magical art in balatro, in the way that it sounds piss easy and turns out to be brain surgery when connecting them
The message is: If you code in LUA/Love, remember people can look at your code
im thinking of a joker card that when sold destroys 13 random cards from your deck but gives permanent 2x mult
or something
tips on how to make this more balanced?
this is way too good for thinning your deck without costing any resource, in fact it gives you something for doing so
so is immolate, the spectral is still insanely strong for thinning your deck
making it random just means you can't take it towards the end of a run if you have a card-focused deck
13 destroyed cards is crazy good random or not
so what would you do?
depends what you want it to do
what's the intent of the joker
is its effect trying to reference something or does it have a specific theme to follow
it's meant to remove a bunch of random cards to make hands like straights harder to play
oh also i kind of want to make another spectral which is charmstone
which increases odds for stuff to happen more than oa6 but also has a penalty
how would you check for how many cards have been played in a hand? i wasnt sure where to find a joker that does that, so thought i'd ask here 😭
the length of g.play_cards probably



