#💻・modding-dev
1 messages · Page 151 of 1
but I'm trying to use a for loop... shouldn't I? every time I use a for loop somebody tells me I wasn't supposed to do that
I think everything u want to see would be here
how can i check if a joker ina for loop is a certin joker
are you trying to check if there's any joker that's negative? like for the remove negative display on invis joker?
like if G.jokers.cards[i] == (joker) then
I want to check how many, cuz it's supposed to add 5 mult per negative joker
i tried puting key but it crashed
yeah no you do use a for loop for that
no i have a for loop but i need it to not do it for that joker
but every other joker
local negatives = 0
for _,v in ipairs(G.jokers.cards) do
if v.edition and v.edition.key == 'e_negative' then negatives = negatives + 1 end
end
He may be talking to me
i wasn't talking to you
okk... thanks
oh
i'll try that
that was very inconveniant of me
sorry use the updated version, i was just looking at how thunk does it and he got in my head
...wdym?
the thunk way is v.edition.negative as opposed to the v.edition.key == 'e_negative' i said before
which is discouraged in terms of modded
also nvm the way i did worked so i dont need help anymore
how certain of a joker? i.e. any j_joker or a specific card
ok nvm
it was lierly just
if G.jokers.cards == j_(joker key) then
do stuff
end
if you literally mean j_(joker here), that seems wrong
I'd do like if G.jokers.cards[i].config.center.key == 'j_(joker_key)' if that's what you mean
i can do that but what i did worked so
uh can you show me what you did
yeah, was doing that because i was originally just planning on making it a direct injection and tried to make it a mod in a short time while waiting for some more assets in case some dont like the direct injection method, so i winged it a bit too much probably in wait to short of a time
you´re a goddamn saint 🙏
this does not do what you think it does
well i got the results i wanted
this is comparing not G.jokers.cards[i] (probably false) to an undefined global (probably nil)
i was fully ready to just shelf making it a modloader compatible mod for now for time constraint reasons and make a V2 way later
Never heard of "thunk"... I have no idea what ur talking about lmao
(sorry if it's a common english word, not a native.)
shoud I just do if v.edition and v.edition.negative or the other way?
Never heard of "thunk"
The first member in the member list
check the member list in the discord sidebar and look at the uppermost person there
you should do what i first said, i.e. edition.key
yean nvm it broke stuff but i used what you said now thanks
now i need to know how to mute volume with joker
the crazy part is i don't know how many times I've seen someone use not x == y
pls i need help
check how the plant does it?
the plant is literally a blind
let me guess it needs to be not (x == y)
kid named x ~= y:
what a tilde does to a coder
omg
not every keyboard can use them ç--ç
I keep googling it
but not (x == y) works
i forgot that was a thing holy shit
there's a steamodded util function to do this, otherwise it would require patching
SMODS.current_mod.set_debuff = function(card)
if next(SMODS.find_card('j_modprefix_key')) and card:is_face() then return true end
end
where modprefix is your mod's prefix and key is your joker's key as put into SMODS.Joker
okay i'll give it a try i'll tell you
shit ti didnt work
?
how would i have a joker get its location in the jokers array
like G.jokers.hand
or whatever it is
wait im a fucking idiot
local self_pos
for i,v in ipairs(G.jokers.cards) do
if v == card then self_pos = i; break end
end
danke
the dt gets multiplied by the speed factor when passed from Game.update into Card.update
i've asked this kinda before but i never got an answer
theoretically, if another mod adds the same ranks as my mod, is there any way to make it so it only adds one of them
so that should do
like if two mods add an "11" could i make it so theres only one of them
yes, Six Suits does this with poker hands for Bunco and Spectrum Framework
oo
yeah cus i was wanting to add compatibility with unstable
so i guess i do the same thing but rank instead of poker hands
mhm
you'll see there's this thing I do for keeping locals around of what these objects actually are and using the key of that object to ref it elsewhere instead of using my key directly
that's because i don't know what the key will be at runtime
quick question for anyone
why is stuff changing color when i scroll up and down?
okay disregard this it seems closing and opening the thing again fixed it nope, still happening
According to the game, this is the area fucking up my custom Joker.
Does anyone know why this code is crashing when the values get too large?
[[patches]]
[patches.pattern]
target = "functions/misc_functions.lua"
pattern = '''
if min and max then return math.random(min, max)
else return math.random() end
'''
position = "before"
payload = '''
if G.GAME.selected_back.name == "Lucky Deck" then
if min and max then
local value = (math.random(min, max) * 10) or max
print("[Soul] " .. value)
return value
else
local value = (math.random() * 10) or 1
print("[Soul] " .. value)
return value
end
end
'''
match_indent = false
you should probably check out the lovely dump to troubleshoot it
Where are they located?
mods/lovely/dump
Alright
All I can see is that the rarity is reassigned to SMODS.poll_rarity, does that function have any edge cases to make it, under any circumstance, return nil?
that's line 2055?
2053, it defines the rarity variable which, when it returns nil, attempts to get concatenated with a string, which you just can't do
This is 2055
ah
Hypothetically yes, but only if rarity_poll is 1 or higher.
Which under normal circumstances should never happen to begin with.
1 or higher is interesting
Since I was clamping it to exactly 1, which caused the error
lol
of course, using return math.min(value,0.999) fixes it lmao
math.random can only return value between 0 and 0.9 repeating, so 1 is out of bounds.
At least I think
I know some languages work like that
It is 0.9 repeating, but if you provide a bounds it can go further
Yup!
When called without arguments, returns a uniform pseudo-random real number in the range [0,1).
which is right inside the assets folder
would i just set the sound to something like [modprefix]_[filename] like how its done for everything else?
Ye.
does anyone have any idea as to why card:jcbb_add_speech_bubble and card:jcbb_say_stuff dont work when the events are formatted like this?
does anyone know why the message isn't showing? The rest of this is working, but the message just isn't showing
alright i have a problem, i need this code to loop an x amount of times (hence the for loop)
the problem is the returns prevent it from looping
i presume the solution is to replace the returns with add_event()s, but before i do so i want to make sure that i dont have to change anything else to prevent it from breaking
any thoughts?
are you on better calc
if so i believe you can nest returns by doing return = { message = "hello", ..., extra = { message = "world", ... } }
(and recursively thereof)
i am
poggers
and i dont need the events?
i think an important thing to note though is it loops a variable amounts of time
yeah so you'd build the return table in a variable
rather than talk out my ass i'm testing something real quick lmao give me a few
ok
ok so i just reimplemented my old joker tarot with the new system
recursion is fun
nice odds lol
lmao oops i return the ret way too early
pretend the return ret in the for loop is after it
That's not recursion though, is it?
it's not even unperformant
How
ill be honest i still dont know what to do
i still need help as i absolutely have no idea what to do
so you want to have multiple effects
yeah
so make a table that you're going to return
and stuff it with the effects
it'll evaluate like this
ret
ret.extra
ret.extra.extra
ret.extra.extra.extra```
until it runs out of extras
how do i define those extras though
feel free to copy that append_extra function from above
thats one of the big things im confused on
mhm
if ret.extra then return append_extra(ret.extra, append) end
ret.extra = append
return ret
end```
essentially what this does is it looks for the first "empty" extra slot and fills it with the "append" table
which should be the "next" return
and can be structured exactly like the table you would normally return from a joker calculation
[Quick Opinion Seeks]
Are these three effects too much to pack together?
i think making 3card straight flushes not only is extremely powerful but also would require completely reimplementing straight flushes if you dont want the effect to apply to straights and flushes independantly
as-is i believe straight flush is literally just defined as adding a straight and a flush together
hence why it has strange function with four fingers
aint no way it only hit once
(also it worked, thanks so much!)
now the only problem is i kinda wanted each mult update to happen with the lives/blanks
whats the current code
..... huh
also i tried it again, 3 lives hit, and i got 10k instead of 300
funny
here's a weird question - can I send text to the debug console? When working on Pokemon Essentials I can use Console.echo_li(
ummmm
Rad are you on latest smods?
tried replicating it and it seems to work fine here
despite obviously it doesnt work on yours
not latest latest, but ill update rq
at this point its about a week old
still not working
(sorry i would have posted about but ill be real i got sidetracked by funny gun noise)
huh
i updated it and everything
i genuinely dont know why thats happening, sorry
grabbed it straight from this
not to derail from the conversation but seeing a changed suit art hit me like a semi truck
unless its some weird mod incompatibility but yeah idk
:3
it shouldnt be considering the only thing that could vaguely effect this is debug plus
i dont have any other mods besides a music mod and the deck skins
my mod
music
debug
deck skins
lovely
deck skins
smods
maybe eremel or aure would know if you see em around i dont wanna ping anyone 😓
whats the intended effect
because looking at the code this seems correct? ish?
well the main code works, the problem is i want the mult to update as the card triggers, not all right before it
lemme pull up its stats rq
whats that
the issue is that for my joker tarot it's not working that way and idk why the difference
can I do card:calculate( on my own with a custom context? If so, what do I use as the first argument (the one labeled self?
yes but you have the wrong idea about how to go about it
card.calculate(card, foo, bar)
and
card:calculate(foo, bar)
are the same
the : instead of the . implies that the first argument given to the function is always the object it was called on
okay
you dont have like cryptid enabled or something do ya? cus i heard it adds some weird fixes or something
any examples of consumable cards? looking for somewhere to base off of but i don't think there's anything in the example mods repo
actually this is a dumb question nvm lol
a) whoa trif jumpscare good to see you
b) it should be in the dumped card.lua file
leif jumpscare wtf LMAO also thank you 🙏
hows it going
shit its been a long while
good LOL
So I changed it to retriggers.
And before any of you asking, it's the 2nd, 3rd, and 4th scored card, including the case with Four Fingers.
glad to hear :) i essentially largely stopped coding after like last year lol so i'm getting back in the groove by learning to mod this peak of a game
g o o d
also i might reword the latter effects to just be like, "Upgrade Straight Flush when you use a Neptune, Jupiter, or Saturn planet card"
Nep is +3 lv. SF and Jup&Sat are +1 lv. SF
oh i cant read
space joker says "upgrade level of" burnt joker says "upgrade the level of the" ugh
inconsistent ass terminology
Are there any guides to start with modding like how to make a simple joker?
Thank you so much
Is context.consumeable.ability.key == 'c_neptune' the correct expression?
So context.consumeable.config.center.key ?
ye
I want to disable certain jokers/planet cards/consumables / anything on a certain stakes, how do I go about that?
Is uncommon OK with this effect?
Reference:
Which do you want to know about, debuff mechanic or blind detection?
So I basically want to almost emulate a challenge on certain stakes. I'm looking through the source code and I think I need to do
if _ch.restrictions then
if _ch.restrictions.banned_cards then
for k, v in ipairs(_ch.restrictions.banned_cards) do
G.GAME.banned_keys[v.id] = true
if v.ids then
for kk, vv in ipairs(v.ids) do
G.GAME.banned_keys[vv] = true
end
end
end
end
if _ch.restrictions.banned_tags then
for k, v in ipairs(_ch.restrictions.banned_tags) do
G.GAME.banned_keys[v.id] = true
end
end
if _ch.restrictions.banned_other then
for k, v in ipairs(_ch.restrictions.banned_other) do
G.GAME.banned_keys[v.id] = true
end
end
end
I need to somehow trigger this code when I start a game on a specific stake
IE I want to remove soul cards from gold stake for example <- this is just an example
I guess you want to remove certain cards from the pool?
you can take_ownership and add an in_pool function that checks if you're on that stake or not
Please elaborate, my first time looking at balatro source code and the lua language was like a couple hours ago, looking to learn as much as I can. I'm like 80% of the way there, here's what I have
# At the beginning of the game we disable all Cryptid elements unless G.GAME.modifiers.cry_ingame_enabled is set by Stake
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = '''if self.GAME.stake >= 2 then'''
position = "before"
payload = '''
if not G.GAME.modifiers.cry_ingame_enabled then
if not G.GAME.banned_keys then
G.GAME.banned_keys = {}
end
-- Loop through and add all Cryptid items to banned_keys
end
'''
match_indent = true
where does new calc handle retriggers? state_events.lua doesnt contain the word repetition at all after smods modifies it, and thats where its normally done in vanilla, so i dont know where it passes the repetitions = true context
hi i don't have any modding experience and i was wondering how difficult it would be to extract the game's sound effects
i know a few of them are unlicensed sourced online but balatro has some post processing on it and it doesn't sound the same
you can actually just open the game's executable with 7zip and extract everything
oh really?
yeah its that easy lol
that's a lot simpiler than i thought
looks like the game does some speed manipulation on a few of the sounds but that can be easily fixed
I'm trying to add a badge to a joker when the user hovers over it, but this doesn't seem to be working. It won't even print the debug message on hover
local generate_UIBox_ability_table_ref = Card.generate_UIBox_ability_table
function Card:generate_UIBox_ability_table()
local generate_UIBox_ability_table_val = generate_UIBox_ability_table_ref(self)
sendDebugMessage("Generated UI!")
if generate_UIBox_ability_table_val == nil then
return
end
if self.ability.set == 'Joker' and (self.area == G.I.CARDAREA[7] or self.area == G.pack_cards) then
SMODS.Joker:take_ownership('joker',
{
set_badges = function(self, card, badges)
badges[#badges + 1] = create_badge("$" .. card.sell_cost, G.C.RED, G.C.BLACK, 1.2)
end
}, true)
end
return generate_UIBox_ability_table_val
end
how can i set all sound volume to 0 useing the code
how do I check a cards enhancement? to give something when a card with a specific enhancement is scored for example
nvm, it is actually sending the debug message, it's just that DebugPlus isn't showing it since i had it disabled. But the badge still isn't showing up
Finally got the config up and running!!!!! 😄 The only hang-up still is that for the tooltips colors to take effect, every time i open the game, i have to disable and re-enable High Contrast Cards in the Customize Deck tab and start a new run for those to change to their matching colors. Any way i could force the game to reload/check that option from my mod's end?
base game uses G.FUNCs.refresh_contrast_mode when enabling that button, so i figured it may be something along those lines but im stumped
this is currently how im modifying it to change those tool tip colors for suits
Is there a better way to get a random spectral key than local _spectral = G.P_CENTER_POOLS.Spectral[pseudorandom('ina',1,#G.P_CENTER_POOLS.Spectral)] ?
theres pseudorandom_element
anyone know how
shit
Fuck
i need somoen to save me from my suffering
No im fucking done
this is all i needed
G.SETTINGS.SOUND.volume = 0
lol maybe a silly question, but why not just turn down your game volume?
because rthe joker mutes the game for its effect then tursn it back on
ahh makes sense!
how do I do this?
is there a way to have textures larger than 71 x 95 fit for a Joker?
I want clearer pictures for mine
says that it cannot find init.lua..... its in the same directory so idk
Is there a way to give a random joker ability to a generated card?
Like when it's created it gets a random joker effect
Just j_oops
danke
for some reason this is giving mult and not Xmult
Why is Balatro throwing this error?
Patched the bug!
context.cardarea == G.play added on 209
New issue: It's triggering twice. How do fix
https://cdn.discordapp.com/attachments/1153815324643299458/1332615070148071486/Balatro_2025-01-25_01-36-14.mp4?ex=6795e5ff&is=6794947f&hm=2a5dbbac07035eed13a2ba3d904450c3e0cf3696ab1bea0063dd705961e21b63&
i just want to share this bc its really funny to me
50/50 chance that you really dont want to get boosted to 100%? just kill the sixes!
Love the shotgun effect lmao
Now do it with 100 jokers

And the one joker that triggers the on to the right
With a blueprint to copy it
the best part imo is if you cheat you also dont get to actually fire the shotgun
this stemmed from the fact that the dice still worked post mortem for that round
cant have a free X243 mult now can we?
you could also simply not check G.GAME.probabilities.normal
yeah but this is funnier
blueprint cant copy oops im like 90% sure
actually no
it works off of oops' key
so no it wont trigger a blueprint even if it was compatible
though the shotty itself is compatible with blueprint
go wild 
i might recommend not saying "retrigger" if you arent actually implementing it as joker retriggers
it might make how it would interact with actual joker retriggers unclear
even just like "triggers again"
mkay
just specifically not the word "retrigger"
ill change that in the morning
Anyone know how to patch this issue?
context.individual and not context.repetition and not context.end_of_round and context.cardarea == G.play
Split or throw on one seperate line?
thats all the base checks to score when a played card is scored
youll also want to throw on whatever you want context.other_card to match, which in this case looks like an Ace check
I want to check for Aces scored, but it's counting twice.
so where do I throwand not context.repetition
.
Alright, that worked.
Oh what a sad if statement
I was really confused as to why this was failing in the very specific case where the 2 was to the left of the King and the player had Splash, was coming really close to asking wtf. Right before posting, realized it's probably because Splash pushes full_hand into scoring_hand, and thus I can't just check scoring_hand[1]:card_id() == 13
How do I make a Joker play music when it's acquired
Look at 'SMODS.Sound' and 'play_sound' iirc
What's up with this part? (Sourced from: Music Albums mod)
uhh
is that a fusion
kinda
what do you mean kinda
you wrote the last line as though it is a fusion using fusionjokers
okay, fair
the effect has nothing to do with shoot the moon or wee joker's effects outside including a queen and a 2
and would be absolutely terrible if you actually fused those two jokers into it
I hope it's not a fusion and you just wrote the last line for the funny or smthn
but like, my mod is written so that if you have fusionjokers installed, you can get my jokers via fusion, but they're also in the main pool
okay well then this is indeed a horrible fusion
wee joker gives +chips and shoot the moon gives +mult, both of those fusing into Xmult makes zero sense and can easily kill your run if you scaled wee joker to any degree
it actively gets rid of 2s from the deck which ruins the wee joker hack synergy and requires you to play 2s that turn into queens which ruins any of shoot the moon's synergies
fusions should retain at least some semblance of the effects of the jokers they're fused from
hey uh, so, I would like to make my own deck of cards textures, is there a way to make it without changing the original ones? just add another one? Thanks :) (Btw I don't know how to code, although I can follow a tutorial if there's any d:)
awesome, THANKS! :3
calm down it's just a joker 😭
Joker of Hearts
mfw i play joker of A♥Joker
anyway what i was trying to fix is that this consumable creates a negative copy of 3 random cards in the deck which works but the copies do not appear in the deck preview and also say INFO - [G] [DebugPlus] Error: Trying to dup card without an area if i attempt to copy them with debug
use = function(self, card, area, copier)
if config.sfx ~= false then
play_sound("fn_decoy")
end
-- Add an event to execute after a delay
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.1,
func = function()
local all_cards = G.deck.cards -- Get all cards in the deck
if not all_cards or #all_cards == 0 then
return false -- Exit if the deck is empty
end
-- Shuffle the deck to randomize card selection
math.randomseed(os.time()) -- Ensure random seed is set
for i = #all_cards, 2, -1 do
local j = math.random(1, i)
all_cards[i], all_cards[j] = all_cards[j], all_cards[i]
end
-- Select the first `card.ability.extra.copies` random cards
local selected_cards = {}
for i = 1, math.min(#all_cards, card.ability.extra.copies) do
selected_cards[#selected_cards + 1] = all_cards[i]
end
-- Create negative copies of the selected cards
for _, selected_card in ipairs(selected_cards) do
local new_card = copy_card(selected_card)
new_card:set_edition({negative = true}, true)
new_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
G.hand:emplace(new_card)
playing_card_joker_effects({new_card})
end
return true
end
}))
end,
}
Uhm what
i did it?
why did i never realize this before
you can just put a card's center in the info_queue and the loc_vars shit will be done automatically 😭
wait no
nvm
That’s a recent change
how do i set my mod's prefix ?
Do you use a header or a metadata file?
--- PREFIX: your_prefix
nice, ty !
is there a function to flip cards back facing forward
during those binds that flip ur cards
What happens when you flip a card
Just makes it hard to know what card it is
also add_to_deck is what u use when a card is added to the joker slots right?
No, I'm asking what happens when you flip a card
nothing?
Wait I think I misunderstood your question
The function is a method: Card:flip
alright
guys, how do i create a texture pack for balatro?
thinking of adding swords of revealing light to yugioh mod
what for
and using the flip function to disable that bind
speaking of bind disabling what's the function to do that?
for jokers
G.GAME.blind:disable()?
I recommend Malverk
it doesn't make Texture Packs
but it's a Texture Pack manager
How many Jokers
idk, from one to all of them
i want to make a texture pack for my favorite streamer
hmmm,
It's just that if it's a few, it's easier to do them in one way but if it's all it's easier to do in another
But for a reference of a Malverk texture mod I recommend Legendere
is this some kind of mod loader?
Legendere: #1251615229721186457 message
No, it's a mod
But if you install texture mods made for Malverk it allows you to manage them
like the Minecraft texture pack manager
oh i understand, something like CIT/optifine
IIRC no
just the built-in manager
Because you can have multiple texture packs active at once
But only the topmost applies in case of conflict
It's more visible when there's an update that adds new blocks, so the texture pack you're using doesn't have textures for it
oh okay
But maybe another one does, and is on the bottom, so it only applies those textures
Legendere only applies textures to the Legendary Jokers, so you could have other textures on the other Jokers
With a "normal" texture mod it wouldn't work because they're usually replacing the vanilla textures
you'd need to manually edit different textures into a single file
if G.GAME.blind and ((not G.GAME.blind.disabled) and (G.GAME.blind:get_type() == 'Boss')) then
card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('ph_boss_disabled')})
G.GAME.blind:disable()
end
end
function jinzo_removed(self, card, from_debuff)
if G.GAME.blind then G.E_MANAGER:add_event(Event({ func = function() G.GAME.blind:set_blind(nil, true, nil); return true end }))
end
end```
would this work for a add_to_deck and remove_from_deck function?
Don’t set the blind
how would it be done then? I can't find much on blind disable in the vanilla game
You can’t un-disable the Blind in vanilla
I’m not sure there’s a generic way to do it
how would you make a uhh blind debuff carads with a certain enhancment
hello! i need help with something
so i am making a joker that is supposed to trigger 5 text boxes in succession, and the best way to do so i was told was to make events unnested from eachother, however there is an issue with this
something about card: effects breaks and ceases to work while unnested, and only the card: effects in the final called event works
the card: effects are still called correctly however, the only thing that doesnt work is their function (add_speech_bubble and say_stuff dont work until the last called event)
i was wondering if anyone here would be able to help me figure out why this happens?
Oh I think the disabling part is right
thoughts on these abilities?
Astra (Uncommon):
0 in 3 chance to give +50 Mult, held Tarot cards increase the odds
(Guaranteed if you have Lily)
Lily (Uncommon):
0 in 3 chance to give X2 Mult, held Planet cards increase the odds
(Guaranteed if you have Astra)```
If what Mr.Smods suggested did not work I do not know who can help you
It didn't work unfortunately
I think 0 in 3 is kinda low
I was going to keep talking
Do you also have it on calculate?
well ya, if you have 2 Tarots you have a 2 in 3
98%
No
with Crystal Ball you can guarantee it
oh yeh mb
you forgot the last half of the card 😭
I thought that was for calculating multis?
👍
It should work like Chicot
lmao
but i do think 2 in 3 chance for 50 mult is quite weak
well if u have both of them u will get +50 and x2 garanteed
how often do you get oa6 + bloodstone
Nothing gets past my bow
Where does the game check if a voucher is redeemed before serving it in the shop? (Tier 2 and 3)
what about 3.14159265358979323846264338327950288419716939937510?
?
this is an entirely different issue
Didn't John smods help you?
i discovered why this isnt working thanks to john smods
just call him aure 😭
i like to call him Mr smods
cool tho !
is that his name?
yeah
noted
mr smods
yeeeeeeeeah
G.playing_cards for every card or #G.deck.cards for only in deck
and thats a list of cards?
oh yeah lua
What do I use for add_to_deck?
gern geschehen
i dont speak german i just swear in it
ultimately the issue wasnt something that aure had thought about
its something weird that i cant seem to diagnose the cause of
I speak just a little
my native language is portuguese tho
update = function(self, card, dt)
for k, v in pairs(G.playing_cards) do
if v.config.center == G.P_CENTERS.m_sbc_ice or v.config.center == G.P_CENTERS.m_sbc_fire then
self:debuff_card(v)
end
end
end
trying shit but its just like not 😭
help, the thing is not doing the thing.
i might be a little stupid but where is the erratic deck gen code
trying to use brainstorm auto reroll to filter by amount of suit
Nothing?
looks like your code is working perfectly
^
Tried with G.UIT.R and I get the same result.
Ah
Can anyone help me out?
if not saveTable then
if true then
print("test")
print(G)
print(G.GAME)
print(G.GAME.banned_keys)
print(self)
print(self.GAME)
print(self.GAME.banned_keys)
end
if false then
if self.GAME.stake >= 2 then
self.GAME.modifiers.no_blind_reward = self.GAME.modifiers.no_blind_reward or {}
self.GAME.modifiers.no_blind_reward.Small = true
end
if self.GAME.stake >= 3 then self.GAME.modifiers.scaling = 2 end
if self.GAME.stake >= 4 then self.GAME.modifiers.enable_eternals_in_shop = true end
if self.GAME.stake >= 5 then self.GAME.starting_params.discards = self.GAME.starting_params.discards - 1 end
if self.GAME.stake >= 6 then self.GAME.modifiers.scaling = 3 end
if self.GAME.stake >= 7 then self.GAME.modifiers.enable_perishables_in_shop = true end
if self.GAME.stake >= 8 then self.GAME.modifiers.enable_rentals_in_shop = true end
end SMODS.setup_stake(self.GAME.stake)
self.GAME.selected_back:apply_to_run()
Does anyone know why printing G or self print nil here? Clearly the object should be defined? This is in game.lua. Literally just injected this small if statement. The statement "test" prints out normally and works
G is probably undefined but self is
self also returns nil
new jim
is there any way with the SMODS.Joker to make a legendary with 2 textures (one for bg, and one for the floating joker)
or does that behavior have to be manually implemented
function Game:start_run(args)
args = args or {}
local saveTable = args.savetext or nil
G.SAVED_GAME = nil
...
if not saveTable then
if true then
print("test")
print(G)
print(G.GAME)
print(G.GAME.banned_keys)
print(self)
print(self.GAME)
print(self.GAME.banned_keys)
end
if false then
if self.GAME.stake >= 2 then
self.GAME.modifiers.no_blind_reward = self.GAME.modifiers.no_blind_reward or {}
self.GAME.modifiers.no_blind_reward.Small = true
end
if self.GAME.stake >= 3 then self.GAME.modifiers.scaling = 2 end
if self.GAME.stake >= 4 then self.GAME.modifiers.enable_eternals_in_shop = true end
if self.GAME.stake >= 5 then self.GAME.starting_params.discards = self.GAME.starting_params.discards - 1 end
if self.GAME.stake >= 6 then self.GAME.modifiers.scaling = 3 end
if self.GAME.stake >= 7 then self.GAME.modifiers.enable_perishables_in_shop = true end
if self.GAME.stake >= 8 then self.GAME.modifiers.enable_rentals_in_shop = true end
end SMODS.setup_stake(self.GAME.stake)
Here's the full code snippet it's in Game:start_run
I literally cannot move forward at all if I can't even manipulate the game object, any help would be appreciated
if im understanding what your asking, the background would be set as the normal joker and for the floating part it would be soul pos
is this from vanilla code or the lovely dump
lovely dump
I injected
if true then
print("test")
print(G)
print(G.GAME)
print(G.GAME.banned_keys)
print(self)
print(self.GAME)
print(self.GAME.banned_keys)
end
Here's my injection
[manifest]
version = "1.0.0"
dump_lua = true
priority = -1
# At the beginning of the game we disable all Cryptid elements unless G.GAME.modifiers.cry_ingame_enabled is set by Stake
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = '''if self.GAME.stake >= 2 then'''
position = "before"
payload = '''
if true then
print("test")
print(G)
print(G.GAME)
print(G.GAME.banned_keys)
print(self)
print(self.GAME)
print(self.GAME.banned_keys)
end
'''
match_indent = true
Well, a new game not continuing an existing game, right?
yes a new game
Alright
The problem is that "test" is printing every time, but G is not nor is self
Does it not print an adress?
No it prints nil
😭
if Cryptid.enabled["Progression Locks"] and not G.GAME.modifiers.cry_ingame_enabled then
print("test")
print(Cryptid)
print(Cryptid.enabled)
print(Cryptid.enabled["Progression Locks"])
print(G)
print(G.GAME)
print(G.GAME.banned_keys)
print(self)
print(self.GAME)
print(self.GAME.banned_keys)
local tt = "test"
print(tt)
end
Alright I'm officially losing my mind. How the f can Cryptid.enabled["Progression Locks"] be nil if it literally HAD to be true to enter the if statement in the first place
Am I missing something here? Why can't I reference any variables outside the scope of the if statement? Is there some LUA garbage magic I don't know?
Im trying to make a joker that opens the shop after skipping but when the skip is a booster it doesnt show anything.
if context.skip_blind then
G.E_MANAGER:add_event(Event({
trigger = "after",
func = function()
G.STATE = G.STATES.SHOP
G.blind_select:remove()
G.blind_prompt_box:remove()
G.blind_select = nil
delay(0.2)
G.STATE_COMPLETE = false
return true
end,
}))
end
code
I figured it out, some ass decided to override the print function in LUA. Print only works for numbers and strings. I ran print(true) and it returned nil LMFAO
my magnum opus
me with my Level 1e206 high card
real shit
Nevermind, i think i fixed it
now make him pregnat
Is this the right channel to ask for help with making a mod?
yea
i would be so happy if that were true
So I'm working on making a mod that replaces the card designs of the entire deck, but when I load the mod in-game there seems to be a tiny grey-ish outline around the cards. This doesn't occur on any of the mods I've downloaded online, and it's certainly not there in the textures. Is there any way to get rid of it? (I hope you can see the outline in the image, it's especially noticeable when you zoom in on the face cards or aces)
did you try enlarging the sprite by a few pixels? maybe that will get rid of the outline.
which mod 🤔
The full sprite itself or the indivi bits? Because I used a different mod's sprites as base for sizes
Use this: #💻・modding-dev message (but don't forget to backup the sprites just in case)
@frosty dock im having a weird problem where my code doesnt update the mult at the same time as the messages
the problem is i copied this guy's code (the picture in the replies) and his code works like intended, so i really dont know what i did different
https://cdn.discordapp.com/attachments/1233186615086813277/1332537787185893447/Balatro_2025-01-24_20-28-53.mp4?ex=679646c5&is=6794f545&hm=d003393b6105f5a59ce1f4d10cd67fa4b237cd6651b85361a91f119b134f793a&
WHAAAAAA WHERE CAN I GET THE CHANGED CARDS
buddies of scrubby in the modding forum channel
THANKS
This will only affect the Balatro mod folder in Appdata, right? I have another Balatro/Mods folder in a different location with my backups Looking at the code the answer appears to be yes, luckily
Shouldn't it not have the "50/50"
in the text I mean
nope its 'uneffected' by sixes
this is just a wild guess but do you have both the 1x and 2x versions of the sprites?
and by that i mean it calls you a cheater and shoots the joker before you can use it
I see
i havent messed around w/ importing sprites so this might not have anything to do with it
Confusing template then
personally i think its fine
Is you change Xmult_mod to just xmult what happens?
trying it
Looking at the code of the file Firch linked it appears I was wrong about how 1x vs 2x worked, yeah. I was under the impression that I had to manually make both textures, but it appears that this may not have been the light action 😅
no change
They're there in the files, but they're not simply the 1x files doubled in size. I completely remade the textures since they can look way nicer with the higher amount of pixels. Especially the face cards
(like, the 50/50 already tells you its different from normal chances, and also i dont want this joker to become a 3^number of jokers joker if theres a dice)
I was expecting it to just add the value together
suggestion for the ability:
1 in 2 chance to give X3 Mult, else gives X0.5 Mult
Retriggers for each Joker left of this one (Currently # retriggers)```
current example and i think that the xmult thing just made it not work
no <3
Oh there’s some wonkiness in how extr tables are calculated, will have to patch smods when I’m free in a bit
wait
What smods version are you on?
Yeah I thought that might happen now
newest as of yesterday
Though I would have thought the messages would alternate
like 12 hours ago
This is extra tables being wonky though, don’t worry
ok
I’ll fix it soon, just don’t want to do it on mobile
as a final aside i think its backwards compared to how i built the table
mhm
It’s not going through the keys in the table in the correct order, so it’ll mistime it all
i say that bc i have this piece of code that i want to happen last, but whenever it does trigger it happens first
why if I put 2 Xmult it gives X2 mult but if I put 1.25 Xmult it gives 1.25 mult instead?
but it relies on all the buckshot firing first
because it checks for if they were all blanks or all lives
this isn't what you're asking about, but if you don't want this to work with oops then i think you should replace G.GAME.probabilities.normal with just 1
no its funnier this way
just fucking shoots it instead
i mean aren't there other (modded) jokers that mess with probability?
Is there really no way to get the upscaled versions to look different from the lower scale ones without getting the outline? The 1x version is lower detailed than my custom 2x and the 1x jut can't reach the same level of detail :/
ok
Not just Jokers, technically.
i would assume the game's graphics are built assuming everything's the usual resolution / style ...
so it'd make sense if trying to use 2x graphics that weren't just upscaled versions of the 1x ones would result in errors
I know, I'm just hoping anyone does know a way around it
hmm
maybe ill just use math.random, to be safe
whats its t2 do?
Can you send code?
Actually, that's it for that. The one to the right of it is unrelated. I'll probably change the white part to black later.
actually maybe i cant send it via text
sick
here's the thing in a txt folder
@wintry solar
cus i couldnt send it in discord directly
Can you send code?
I figured it out
You can it’s just that Firch didn’t code it
Also I’m not sure why you’re having this issue
I’ve hardly noticed it
It seems to be whenever the 2x version isnt the same as the 1x version made twice as big
I'll run some more tests in a bit then
never got an answer for this one...
look at the game source tbh
i did and got nothing conclusive
blueprint and brainstorm are both two very specific contexts and i dont know how to recreate that
They literally just call the calculate function of the joker they are copying
i tried that already
and it isnt working
is there anything that would kind of be like the steammodded vanilla joker lua file but for blueprint and copying jokers
I mean there's not a lot of changes required to smods-ize vanilla blueprint
yeah but i really cant figure it out myself to be honest here
how would i check if a voucher's been redeemed?
is it just this
if G.GAME.used_vouchers["v_voucher"] == true
== true
true
no, blueprint works in every context
can someone please just walk me through this, i have no idea what im doing
like if i wanted to recreate blueprint to a tee
I made an edit on 2x of one single card and the entire deck got an outline. But then I made that exact same edit on the 1x version, expecting it to fix the outline, and it didn't. Running the Python script again removed the outline again. I repeated the experiment and made absolutely sure that my edit and the output of the upscaler were the exact same, yet once again I got the outline on my version. The plot thickens...
It’s something to do with colour values of transparent pixels iirc
am i correct in guessing that if i want to increase the card selection limit of consumables by a fixed value i'd want to use lovely?
Yes, what the script does is it creates a fully-transparent outline of neighboring pixels
base game consumables use max_highlighted as a config value so i know i'd be going after this
just want to make sure i have the right idea
Let me try another test then
help?
Hey yall, I want to make a TAS for a theoretical “fastest naneinf” but am unsure on how I would do that. Is there a way to essentially doctor a balatro game to be able to guarantee outcomes?
The odds of this seed is beyond the amount of possible seeds balatro can generate. Is it theoretically possible? Yes. Will it happen? HELL NO.
like in minecraft seeded TAS’s, they modify the game to guarantee perfect luck. I would need something like that
or create it i guess
at the risk of repeating myself, i Have looked at the source code. i cannot figure it out
I promise you it's not that difficult
I have done it!
this is brainstorm's code without the UI stuff (message on correct joker etc) or setting the blueprint contexts
local other_joker = G.jokers.cards[1]
if other_joker and other_joker ~= self then
local other_joker_ret = other_joker:calculate_joker(context)
if other_joker_ret then
return other_joker_ret
end
end
I hope it's okay that I made a tiny modification in your script (changing the scaling factor so it just cleans my faulty images instead)
thank you so much
where on the balatro files can I find the loc_txt of jokers?
localization/LANGUAGE_HERE.lua
sorry, back again. how would i go about adding the little "Incompatible" stamp at the bottom of a joker's description
ok
You need to create it manually
It’s like a column with text inside
how would i go about doing that
I have an example at home but you can also see how vanilla does it
It’s similar to xMult text IIRC
But with curved borders
I have looked at the source code and i dont understand it
if im asking a question here it means ive looked through the source and couldnt figure it out
Some people don’t
People don’t even read the install instructions for SMODS
But you likely need to append to main_end
formatting stuff may also be in the uh
localization files
thats where i found how to properly display planet card colors
info_queue is the little side bubbles
that describe foil, holographic, negative, etc etc
loc_vars is used to set that and also return variables that you can then display in loc_txt
ya
im still confused on how id go about doing it :P
ive never done ui code in loc_vars function though so im entirely clueless
and ive already looked into how its done but balatro ui code is so esoteric to me
okay so basically
loc_vars = function(self, info_queue, center)
--loc_vars shit
return {
vars = {your variable shit},
main_end = ui code shit
}
end,```
ohh
Finally released my first Jonker :D
how would i use this for giving money at the end of a boss blind?
i presume i cant just use context.blind.boss right?
ive never used this calc before
well the problem is it doesnt take context in its args
what i think ill do instead is set it in normal calculate and turn it off after the boss blind
how does one add a variable to G.GAME? like how you can access G.GAME.probabilities.normal, or discount_percent, etc etc
i assume with lovely but i havent been able to figure out how
if i were to immediately guess
a patch with lovely
yea same i just cant figure out how
find where G.GAME is in the files and patch there
(do you know how to patch or is that not the problem?)
i do not know how to patch is the problem
i know where G.GAME is
just never used lovely before
ok
if you plan on making just one patch, create the file lovely.toml in your mod, on the same level that main.lua is
(i.e. on this level)
mhm
if you plan on making multiple patches, replace that with the lovely folder, and place .toml files in there instead
this also has the benefit of allowing the toml files to be different names
yea i saw this structure in cryptid
ye
next up, to make a simple patch
(lemme open up my patch)
first up set this up at the top
priority is just in what order it gets patched compared to other things
it can be negative and the lower it is the earlier its patched
im not new to programming
ok
you dont have to go this simple
sorry
i get it
i just needed to when i first did like a week ago
how could I check the rarity of a sold joker?
after that set up patches and patches pattern, which i believe is the kind of patch you need
it finds a string of text and then replaces it?
it finds a line of code and either
replaces it, inserts your code above it, or inserts below it
depending on what position is equal to
ok got it
so id just want to find some existing property of G.GAME and add my own line below it
this will also help
i was looking at the website but it wasnt making sense
is there a way to make a joker "non movable"?
pinned?
idk
i just want to make it so the player cannot change it's place
you can add a pinned sticker to it so it's always on the left
thats a default game thing
used only for the ceremonial dagger challenge i think?
it doesnt even have a graphic, its only used for that challenge
nop
not what i want... I know that it will be ""movable"" if somebody moves the jokers arround it, but i wanted to make it impossible for the player to move THAT joker
but thanks
can anybody help? im totally stumped on this
we are trying everything but nothing seems to make it work
does anyone know where I could find documentation on how to access specific values like hand size, total chips, etc.
there aren't any docs on that, you'll need to look in the game code
unfortunate but fair enough
having the weirdest issue where other_joker (in this case it's Smiley Face) is giving a return on the first played face card but not for any subsequent ones
if context.hand_card and context.hand_card:get_id() == 7 then
local other_joker_ret = other_joker:calculate_joker(context)
if other_joker_ret then
print("return!")
other_joker_ret.card = context.hand_card
return other_joker_ret
else
print("no return")
end
end
end```
from what i can tell context is identical in each case other than other_card which obviously should be changing
@ionic verge fixed on latest now
cool, thanks!
there's no context.hand_card
is a mod able communicate data over to a python file
like, able to send a 1d list of the players hand to the python script
its a custom context passed into this, used because i needed to keep track of more than 2 cards at once
again, it works perfectly on the first played face card, but then doesnt on the second
hmmmmm
oh yeah the mult messages
how hard would it to be to replace all of these with add_events()s?
you can swithc back to Xmult_mod or add remove_default_message
cus at this point it might be cleaner
nah this is the best way
events would make it more complicated
I simply added the "cards_2" line in here to add the custom high contrast cards
and now it's crashing on launch
wait
nvm, im dumb!
That feeling when you realize you’ve been using “loc_text” instead of “loc_txt” for weeks.
I have had such a dumb
how would i get these messages to play after the lives/blanks?
i literally just asked for support only to realize that my 8BitDeck_op2.png was titled 8BitDeck_opt2 .png
there was a damn space

the big thing is i need this code to happen after the shells, bc this relies on the shells played to trigger
(i.e. if they were all blanks or all lives)
After the scoring is done or..?
well im currently using recursive returns
using the return{ stuff, extra = { stuff, extra = { etc }}}
yea, i dont think thats it pal
add them to your extra tables last
i think it plays the most inner extra = {} first, but when i put the stuff that needed to play last in the most outer extra = {} it still didnt work
oh
they should play in order now
Haha! Highfive! Same problem XD
yep it worked! thanks so much
eremel did you see the sins i committed against extra returns
.
its very clever
what are we doing here? pygame and screenreading?
nah I think its reasonbly clean
oh ok apparently i can just scrawl whatever cave runes i want
okay yeah this might be a bit much
does anyone know the variable that I should add to when I want to give a certain amount of chips to the player?
dumb ahh question here, how can i make sure a joker is ALWAYS negative? not only in shop, but in collection too
im trying to get a screenshot from the game and try to turn it into a list in python
one sec
overall, i want to at least get a neural network to play "the best hand" it can
set_ability = function(self, card, initial, delay_sprites) card:set_edition('e_negative', true, true) end,
i have this on hand because i needed this exact same thing as well
dont put this in calculate, for the record
it goes on the outermost layer like cost = '' does
it got one card and then crashed
yeah, thought so
danke!
I suggest using something better than screenshotting ngl
whatre you doing? im curious
i really want to get a nerual network to learn to play balatro
cool art
still gotta remake that first one and draw the legendary in the middle... only 5 more to complete the page tho so it's coming along nicely i think
chat why did i decide this was a good idea to try and code
too deep in the sunk cost to stop now
i thought it was gonna be the hardest part
it was not
well i didnt think it was gonna be at first
and then it was
and then it wasnt
is it not just local con2 = context con2.blueprint = true for i, v in pairs(handcards) do if v:get_id() == 7 then leftjoker:calculate_joker(con2) end end
no because of all the possible contexts a joker could trigger under
well this would work if you want the joker itself (hudson in this case) to trigger the copied effect
im trying to make the 7s trigger the effect
it would probably be a lot easier to do it that way though and maybe i should pivot lol
hello! i'm trying to code an effect on a joker where it applies steel to specific cards played
is there any examples of mods out there i could reference for an effect like that
well that sounds like a very similar effect to midas mask from vanilla
you could probably reference that
card.lua and then you can just ctrl+f for "midas mask"
managed to get a joker working the first time i loaded the code
that felt great
*besides a term i had to change, but shush
woah you go big guy
badabadabadaba, true?
POSE FOR THE FANS!
genuinely though awesome joker - like the reference to the tall tappers in the bottom right of the card
hii is this where i would ask for help with modding something?
trying to set up a custom color for test and it's crashing bc of alpha not being defined i think? but idk how that could be true
well hm i guess it's possible that there's no colors defined at all?
still though
where is card.lua(?)
you can extract the game's exe using 7zip; card.lua will be right in there
nope. more confused now
what language are mods coded in?
lua
why
because that's what the game was made in
WHYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
roblox ass language
idk I'm not localthunk
c# >
I agree but that's not stopping me
same lol
i love c# but i also have only ever actually made games in love2d so i feel at home here
lua is so weird like i cant believe
return not bool and 4 or 6
is actual correct syntax and returns 4
if it helps, doing this does make it work?
wtf
which like. i guess i would have been more distressed if it didn't work
so is it just me or does Xchips not exist in the steamodded util.lua
or am i like just super blind
Xchips isn't provided by smods
I don't think it exists
why is it not provided
it's never been provided
that makes sense as to why MTJ doesnt have Xchips then
isn't there a way to inverse chips and mult? if u do that and then apply the Xmult... It may work
you can either do it manually within your calculate function, implement it yourself, or add talisman as a dependency
but whichever you choose, outside of plasma deck and niche ordering, it's effectively the same as xmult
Has anyone done a joker that increases the chances of other jokers being found?
I dont know lua and i dont know how to make that happen
so i can make some jank code to implement Xchips?!?
Cryptid does that
You can
what language are u using that doesn't have short circuiting
hello! i think i have figured out the issue im having, i think my card:add_speech_bubble functions are blocking eachother in the unnested set of events i have... but i am unsure as to how to make them only not block eachother
ok youre right, testing it this works in other languages i just never thought to use it because it feels so unintuitive lol
also worth noting that in like ruby the syntax is practically the exact same
bool = false
return (not bool and 4 or 6)```
Guessing no?
it's very useful and efficient, very common in Lua because it's also readable and understandable
oh wait i screwed that up hang on
much better
you can't even tell it's ruby and not lua how lovely
clearly they're just the same language
other than the fact it complains main.rb: warning: argument of top-level return is ignored
whenever I check vanilla for how to code something it gives me an error message, since in Smods card.ability.extra is used instead of self.ability.extra
some jokers' code can be found in card.lua on the balatro files, but some can't, where's the code for those jokers?
what joker are you referring to
juggler for example
juggler uses the var h_size, if you search for h_size in card.lua you should find a related code
vanilla joker, +1 hand size
Neato jonkler
would anybody know how to make the events stop clashing with eachother?
i can show the code if needed
want to make a card trigger on 3s and only 3s
how do I make it do that using other_card?
i don't know how the context is written for determining whether a cards value matches or not
or some other method
yep
😨
?
a joker?
context.individual and not context.repetition and not context.end_of_round and context.other_card.get_id(context.other_card) == 3
should probably use :get_id()?
should probably
probably should
<card>:get_id() == 3 to see if a card is a three
so for a joker that could be e.g. context.other_card:get_id() == 3
well
(i asked for repetitions so you didn't fully code the thing for me, i can show the code though)
I'm trying to mod in a Challenge and while looking at other modded challenges I've if sdm_config.sdm_jokers then what does it mean?
can anyone help me with this? i dunno how to download a downgraded version of steammodded
could Hiker's effect be modified to permanently give Mult to cards? if so how, I want to make a Joker with an effect like that
yes you would need to change the the chips to mult
Look for the old-calc version of Steamodded
well I'm looking at Hiker's actual code
what is context.blueprint???
only for the colour and message is Chips actually mentioned
