#💻・modding-dev
1 messages · Page 186 of 1
Idk though, never looked very far into balatro's coordinate system
But T is almost certainly what you need
From memory, though I haven’t done much with it for a while, it’s based off the card width and height
so i know the rules say no debugging allowed
is there a modding discord where i can get help?
that's mainly for the balatro source code itself, and probably other mods (without the creator's consent)
code for your own mod i think is fair game
--- MOD_NAME: Nomads Super Cool Amazing Balatro Mod
--- MOD_ID: NSCABM
--- MOD_AUTHOR: [Nomad_00]
--- MOD_DESCRIPTION:
--- PREFIX: nscabm
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas({
key = "Jokers",
path = "Bullseye_joker.png",
px = 71,
py = 95
})
SMODS.Joker({
key = "Joker2",
loc_txt = {
name = "Bullseye",
text = {
"If round score is exactly the amount needed,",
"Creates 2 random {C;(blue)}spectral{} cards"
}
}
})
------------MOD CODE END ------------------------- ```
perfect thank you
so im just trying to test to see if i can get my card to show in the joker list
but it throws up an error
i have smod sloader and lovely installed as well as the multiplayer mod
i have experience with code before but not lua, so newish territory, any help would be greatly appreciated
send the error log pls
Two things here
you don't have an atlas set so it'll show up as jimbo
and your loc_txt is formatted incorrectly
you have {C;(blue)} but need {C:blue}
I did fix a lot of it
One sec I'm in bed rn
Let me find what I have so far
--- STEAMODDED HEADER
--- MOD_NAME: Nomads Super Cool Amazing Balatro Mod
--- MOD_ID: NSCABM
--- MOD_AUTHOR: [Nomad_00]
--- MOD_DESCRIPTION:
--- PREFIX: nscabm
----------------------------------------------
------------MOD
local achievement_atlas = {
object_type = "Atlas",
key = "bullseye",
path = "bullseye_joker.png",
px = 71,
py = 95,
}
SMODS.Joker({
key = "bullseye",
loc_txt = {
name = "Bullseye",
text = {
"If round score is exactly the amount needed,",
"Creates 2 random {C:(blue)}spectral{} cards"
} },
atlas = "Jokers",
pos = {x = 0, y = 0}
})
------------MOD CODE END -------------------------```
And here is the new error code
So now boots into the game
But when I go to the joker list, it crashes when I load it.
Your atlas key doesn’t match
I just noticed lol
But the code i executed did have matching atlas
There i changed it
you still have C:(blue)
You also aren’t creating an atlas in this code
Darn
I was getting help from someone else and they told me to do it this way
It should be the smods.Atlas
Which i had right the first time?
Yes
for some reason the joker doesnt wiggle when the card scores, what's the reason?
because the affected card is other_card
remove card = context.other_card
If I want a consumable that does something different depending on whether we're currently in a round, what should I check? I know .shop is an option, but I'm not sure if that's also counting the blind selection screen
G.GAME.blind.in_blind
Is there a way to add a delay to sound q?
ah, i knew it'd be something that easy, haha. Thanks!
delay is async and only applies to events queued after it's run
I suggest you just put your play_sound call in a delayed event
what settings should I use for such event?
like that?
oh ig delay should be abover it
Does anyone know if it would be possible to somehow modify the rank of a card to make it succeed at checks that compare it's ID to different IDs?
I want to make a joker that makes all face cards count as other face cards but it doesn't seem like there's much of a way to handle IDs like that
does this have anything to do with using mult and not mult_mod or nah
does anyone know how to give exactly one of something after the boss blind is defeated (ex. anaglyph gives one double tag)
Add juice_card = card
it's all about the juice 🗣️
🧃
JOOS
So I want my joker to give a Pop up notification before cards start scoring but for some reason it happens at the very end. What should I change here?
What context are you using?
well that's why, joker_main happens after the cards score
use context.before instead
chat what do we think of this
<@&1133519078540185692>
Not if you didn't take the Uncommon Robux Tag when you skipped the blind
seems interesting
hmm, I'm trying to find the right spot to inject some code to allow a tag to retrigger playing cards, but I'm not entirely sure where that'd be best done. A lot of the calculate functions and proper contexts are dynamically set up, so it's a bit of a struggle to parse everything
So here's a small thing idk how to change, I want my Joker to start dissolve when it reaches $0 but it starts doing that only after it goes negative in $
< 0 means 'smaller than 0'. Not equal to or smaller than 0
if its equal to 0 it doesnt dissolve
still
even with <= 0
whats the issue then?
wdym?
it doesnt dissolve at 0$
any idea on how to shorten this description?
SMODS.Joker {
key = 'coffee_break',
atlas = 'Jokers',
pos = { x = 3, y = 2 },
rarity = 1,
cost = 5,
unlocked = true,
discovered = true,
blueprint_compat = false,
eternal_compat = false,
perishable_compat = true,
config =
{ extra = {
money = 5,
coffee_rounds = 0,
target = 2,
money_loss = 1
}
},
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.target, card.ability.extra.coffee_rounds, card.ability.extra.money, card.ability.extra.money_loss } }
end,
calculate = function(self, card, context)
if context.after then
if card.ability.extra.money - card.ability.extra.money_loss <= 0 then
G.E_MANAGER:add_event(Event({
func = function()
card:start_dissolve({G.C.GOLD})
return true
end
}))
return {
message = localize('k_hnds_coffee'),
colour = G.C.CHIPS
}
else
for _, played_card in pairs(context.full_hand) do
card.ability.extra.money = card.ability.extra.money - card.ability.extra.money_loss
SMODS.calculate_effect({
message = '-$1',
colour = G.C.RED,
message_card = card,
}, played_card)
end
end
end
if context.end_of_round and context.main_eval then
card.ability.extra.coffee_rounds = card.ability.extra.coffee_rounds + 1
if card.ability.extra.coffee_rounds == card.ability.extra.target then
card.ability.extra.active = true
local eval = function() return card.ability.extra.active end
juice_card_until(card, eval, true)
end
return {
message = card.ability.extra.active and localize('k_active_ex') or
card.ability.extra.coffee_rounds .. '/' .. card.ability.extra.target,
colour = G.C.FILTER
}
end
if context.selling_self and card.ability.extra.active then
return {
dollars = card.ability.extra.money
}
end
end,
add_to_deck = function(self, card, from_debuff)
--card:set_cost()
end
}
pls with syntax highlighting
How do I do that in discord?
put lua after the triple tick
you do your reduction and dissolving in the same if statement so they can never both happen
that's cool as hell i didn't know that was a thing
separate event?
I'd probably reduce in before and destroy in after
I'd say write "resets after scoring" but people might be confused if it's joker scoring or hand scoring
Not that it changes a lot mechanic-wise
I'd just say 'reset each hand'
okk
Trying to understand the code in the dump, and apparently I'd just hit delete on half a line and was trying to parse nonsense 😢
worked like a charm, thanks! :D
Heya folks, making a kinda silly card idea, and needing a bit of help.
Currently, the "Repeated!" popup happens on the playing cards, but I would like it to happen on the Joker itself like Seltzer does. Probably just have the wrong context, but I'm a little unsure what to do, any help is appreciated!
calculate = function(self, card, context)
card.ability.extra.repetitions = #G.jokers.cards
if context.repetition and context.cardarea == G.play then
if context.other_card:get_id() ~= 0 then
return {
message = "Repeated!",
repetitions = card.ability.extra.repetitions,
card = context.other_card
}
end
end
end
remove the card = line and add message_card = card
Ooo hey how did you manage to make the card effects apply after scoring, the timing for my mod is way out of wack
whats the current code for your effect?
It's uh very long
It now crashes on scoring .-.
gotta love modding weeee
A lot of queued events
Cheers
me rn
dont develop on 6 week old builds 🙃
You’re right, downloaden 0.9.8 right now
can someone tell me roughly how i would do this?
i wanted to make it so discarded cards have a chance to be instantly played?
i know bunco has something similar, but it is on an enhancement while mine would be cards in general
real af
Huh, actually it seems the crash was caused by Talisman being activated, as even after updating it was still crashing. Turning off Talisman fixed it (forgor I had it on in the first place lol)
talisman code is lowkey funky lol
Yeah it definetly seems to be lmao
anyways, works like a charm now, thanks
guess it was just Talisman doing funky shenanagins lol
My brain is mush but managed to get retrigger tags working!
heck yeah
if i understand the intended effect correctly, you can hook G.FUNCS.discard_cards_from_highlighted to execute G.FUNCS.play_cards_from_highlighted. although you'll need to patch the play function to not take away a hand if done by this effect
bcos thats how hook (the boss) does its discards - it uses the player's discard button but w/o taking away a discard
oh god that sounds so funky but i guess if it works
that's really funny tbh
although on second thought that might conflict with that exact boss ironically, so you'd need to add an edge case to where if there are already cards in the play area then instead of pressing play it just emplaces the discarded cards into the play area
but you could just make it so that effect never procs on hook's discards, but wheres the fun in that
Do tags always disappear upon giving a return value?
nevermind, I was being mindless and testing code by spawning in an entirely different object
How do I make a gain money function again?
from a calculate function?
I think?
return { dollars = amount }
oh, is dollars a function?
is anyone here familiar with nuclear fusion
i need help with a joker meltdown
ohhhhhhhh wait
i think i get it
context.individual and context.cardarea == G.play doesn't do the same thing as it used to
how do I make that trigger once in new calc instead of a thousand million times
no that check should work fine
.
are you sure that's what you have?
yeah i'm sure that's what i have
can i see the code
SMODS.Joker {
key = "magical_waterfall",
name = "Magical Waterfall",
atlas = "Tsunami",
rarity = "fusion",
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = false,
pos = { x = 2, y = 2 },
cost = 16,
config = { extra = { base_mult = 10, increase = 1, decrease = 0.25 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.base_mult, card.ability.extra.increase, card.ability.extra.decrease * 100, card.ability.extra.base_mult / (G.GAME.unused_discards or 1) } }
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if card_is_splashed(context.other_card) == true then
card.ability.extra.base_mult = card.ability.extra.base_mult + card.ability.extra.increase
card_eval_status_text(card, 'extra', nil, nil, nil,
{ message = localize('k_upgrade_ex'), colour = G.C.MULT })
end
end
if context.joker_main then
if G.GAME.unused_discards < 4 then
local tempmult = card.ability.extra.base_mult * (card.ability.extra.decrease * G.GAME.unused_discards)
return {
mult_mod = tempmult,
card = card
}
end
else
return {
message = localize('k_nope_ex'),
card = card
}
end
end
}
really
Also use mult instead of mult_mod
just to check before I do a stupid:
If I want to add a bit of randomness to a joker, does balatro/steamodded have it's own random function or should I just use math.random
math.random is probably fine
you should use pseudorandom('your_seed_here')
that ensures that your randomness is consistent with game seeds
gotcha
cause i'm trying to make a thing that would adjust the rank of a card by either adding or removing a specific amount (so a 10 could become a Joker or a 9, etc etc)
and I was wanting it to be a bit random
a joker?
JACK
lmao

they are in my head
you've become a jonkler
joker deck when
Oops all jokers
no
what are you trying to do?
Check out https://forums.kleientertainment.com/forums/topic/129557-tutorial-function-hooking-and-you/ for a good tutorial on wtf hooking is
basically, i want to make it so that at end of round, a function will be run which go through some stuff in your deck and change some of the stuff in their card.ability
but currently, it only works when i have the jokers with that function in their calculation, so i want to make it so that it runs without the need of a joker
lovely, thanks :D
I wouldn't recommend hooking calc_context to do that
hmm, how else would i do that then?
if you want it to go through all your deck probably somewhere between the round ending and the reward screen I would think
Would someone be able to explain the pseudorandom probabilities to me? I'd like to make a tarot that on use has a 1/4 chance to do one thing, and a 1/8 to do another. Taking a look at some jokers and effects that have probability I'm just confused. What exactly does the ('space') part do here? Do I have to create some sort of custom seed that has a 1/8 probability?
return {
card = self,
level_up = true,
message = localize('k_level_up_ex')
}
end```
The seed just ensures that the randomization stays consistent. So that two runs on the same seed will have their jokers do the same things too
thats very specific, no clue where im supposed to find that 😭
Also so that space joker's randomness doesnt impact say wheel of fortune
Okay, so I can just put whatever in there and it won't matter? As long as it always calls the same thing?
but i will try my best, thanks 🧙♂️
Just make it unique between objects so their randomness isn't tied to each other. But it can be any string
As long as it doesnt overlap with (and would influence) anything else, yeah
Hmmm okay that makes things a bit less confusing lol. And where does it actually get the probability value from? How would I format that in SMODS?
Smods has an end of Round function, doesn't it? I'd check but I'm not at my pc
Do you know when reset_game_globals runs? That might be good timing?
hmmmmmm, i will check both of those, thanks once again :D
oh hey, its probably this one
function end_round() it's this one that you probably want
"the probability value"? idk what you mean by that
i suppose that works too, thank
I mean like how do I actually tell it to do a 1/4 chance or a 1/8 chance
I'm very new to modding 😅
Speaking of hooks, I've added some additional tag contexts so tags can upgrade playing cards and retrigger them. The retrigger works entirely fine, but the upgrade hook is a bit clunky. It hooks onto score_card, but ideally I'd have the tag give it's bonus chips basically in the same loop as jokers do, so that it works on retriggers too. But eval_cards creates its dict locally, so it's not really possible to hook it, I think. Do I just have to bite the bullet and inject in SMODS or am I missing an obvious solution?
If it’s tied to an effect in cards you can use the Steamodded options to make effects in the deck and discard pile work
Or add a new CardArea to the calculation step with auxiliary Jokers
The pseudorandom function creates a number between 0 and 1. Luckily, probabilities are also written as numbers between 0 and 1, as 1/4 is 0.25. so you compare the result of pseudorandom with ( 1 / 4 ) and if it's smaller
Ice already mentioned some good stuff. If you want code examples, I suggest checking out some mods that have jokers with randomness instead of base game jokers
...wait, what do i call to hook to this?
Hmmmm hmmm okay sounds easy enough frantically writing everything down
It just looks a bit more confusing, because the code doesn't tell you the numbers right there, it stores them somewhere else. The 1 is replaced by G.GAME.probabilities.normal, and the 4 or 8 are stored on the joker in the config.extra, which is called with ability.extra
i dont think this is correct lol
Yeah, that's how I've been learning so far. Scouring the discord for a mod that does the same thing and then "copying" that. Just that the function itself confused me lol
oops, all 6s affects G.GAME.probabilities.normal btw, thats why you can see the odds go from 1/4 to 2/4
Okay, gotcha
Thanks for your help guys, really appreciate it
Everyone here is so helpful and nice
Did you look at the article I sent?
I felt an inherent kindred connection between Ice and Penguins, honestly
i did, but the functions they hooked to have this part
They indeed did
You can ignore that stuff before the : or . then
But you have a () in your function "reference"
Making it no longer a reference, but a call (and thus saving the result)
other than that it looks good though
ohhh, i see, i just noticed that, thanks yall 💀🙏
uhhh
oh wait, im missing something
Okay I might be an idiot but I was trying to make a joker effect cards at the end of the scoring and it wasn't firing at all, so I did a good ol print text and got this. This seems... odd, unless I am missing something?
the second one just, doesn't seem to fire?
there isn't anything in G.play at the after step
how can i mod this as a skin for lucky cat
i just need to do a quick sanity check
did context.destroying_card get changed in new calc
easiest way without mods would be to open Balatro.exe as zip file (e.g. using 7z), then go to assets, find the Jokers.png, edit it in paint and put it back in
that's bad practice graagh
do it with malverk the texture pack manager
i might be getting the name wrong
🐧
...it's a bit confused but it has the right spirit
The card does actually change and score as it should, the graphic just changes weirdly while the cards are still scoring so it does... that lmfao
It's doing it's best
this is because the card changes after the hand has been calculated
but before the scoring animation plays
yeah I guess that's two different things so it causes a bit of funkyness
if you put the rank changes in an event and enable blockable = true it should wait until after the scoring animation
to change the ranks
can someone tell me why the hell its still trying to attempting to REACH A FRICKING NIL VALUE
Works, but the cards whisk away before the new value can be seen, need some way to delay the clearing of the hand for just a second or two or something.
i know its cuz of the soul_pos but even changing the pos of the card isnt moving it around the sheet
im just not sure why theyre showing multiple cards when the card size is the 71x95
this kind of thing is getting me crazy
its probably a comma
Hi! I'm currentely trying to translate Balatro and can't seem to be able to find the "Choose your next Blind" text anywhere in the en-us.lua file. Does anyone know how to change it?
in misc, dictionary, as
ph_choose_blind_1="Choose your",
ph_choose_blind_2="next Blind",
Thank you!
how do i do this on mac...
you need 7zip
Can you show the code of one of the cards that’s supposed to have the soul/floating head?
yes yes sorry am in online class rn ill send in a little
and i dk the rest
I think you have to rename the executable
to end with .zip
or something
try also adding blocking = true so it can block the event of the cards being put back in the deck
maybe
lemmie try
search for extract files option
and click on Balatro Idk\
might work
i feel pain
wow that actually worked, combining that with adding in the message leaves just enough time on 4x to see it, coolio thanks!
what line does it error on
what the actual fuck do you want me to do with that
i'll run you through it
SMODS paperback is the mod name
:144 is the line it crashes on
attempt to call a nil value is the error
paperback.lua is the file it's in
⭐
so go to paperback.lua, check line 144
omg i want to eat an onion and cry
you're doing fine as long as you don't let it happen a second time
yeah that's coding for ya
Also yeah this looks good now
Also funny as heck it all shifted to tens for the recording lmao
this doesnt really help me as line 144 is the line where the jokers are called so if they crash the error comes from there
what's the line say
the actual error was a missing n in then
oh yeah sometimes it just
doesn't tell you the exact line but tells you when it starts causing problems
what editor are you using
the error was in another file
notepad ++
big recommend vscode with the lua plugin
dont wanna setup vscode because it doesnt work
you can usually look further down the crash log and figure out when your code is being called btw
oh alright then
print out enabled_jokers[i] 🔥
mood as fuck

writing a joker for 3 hours: 😄
drawing a jonkler: 🥀
Especially When u Draw mid and cant do nothin but Have whatever
Yeah actually doing the art is my kryptonite for any mod for any game cause I have like no art skill lmfao
same
this shit so annoying
bro i wanted to draw a king dice once
and then I died from the end results
I NEED TO RESKIN MY LUCKY CAT WITH MY BEAUTY AND I CANT FIGURE OUT HOW TO DO IT
ios?
do u have steammolded
no
then download lovely and steammodded then U could use this https://canary.discord.com/channels/1116389027176787968/1300851004186820690
any sound effects i could use to make this more satisfying?
so like this?
i dont see the mods file even after pressing shift -> command -> .
are you at /Users/$USER/Library/Application Support/Balatro/Mods?
i dont see the mods folder
if the Mods folder doesn't exist you should be able to just create it
oh ok
someone tell me how to actually check if played card is a certain rank
mm can i see the full code?
get_id() returns a number, not a string
you need to check for 8 not '8'
yeah i got that thanks
Lol
its ok
What is the issue here exactly?
thats exactly what im asking
I assume the joker doesn't do anything at all?
try putting context.other_card in a variable
like
local _card = context.other_card
then run the functions
ok ill try
what da fack
also I know you're using paperback as the base, but you should remove that set_ability function
that will cause issues
ive been removing peices of code and putting them back in bc i don't what crashes
what step are u on
4
that specific piece of code will cause crashes if you haven't modified the reset_find_jimbo function
good to know
did u try sh run_lovely_macos.sh
yes
also are you an M-series cpu or Intel based cpu
M-series
u downloaded lovely-aarch64-apple-darwin.tar.gz right?
yes
here?
nono
also since you're using paperback as a reference, i recommend looking at Jestrica, that one gets upgraded by 8s as well
lovely is, after all a DLL injector
before "if contex.other_card:get_id == 8 then" you put "local _card = context.other_card"
then
why so many redundant if checks for each rank
you replace context.other_card in the checks with _card
cant u js do if context.other_card:get_id() == 10 or context.other_card:get_id() == 4 then
bcuz it seems to me that ur doing the same G.Event
ye also that
nope one is substracting
ah i see
HUH?????
What exactly is the problem?
did it leave any log files
no
check mods folder
crashes and i cant do anything with the logs
what's in the smods-main folder
whats in the log
if you're crashing send the crash logs
Anyone know how I could go about selecting a random joker without an edition, and then applying negative to it? Tried copying the code from Wheel of Fortune but it's not working. No errors, but even with guaranteed chance it never triggers.
self.eligible_editionless_jokers = EMPTY(self.eligible_editionless_jokers)
for k, v in pairs(G.jokers.cards) do
if v.ability.set == 'Joker' and (not v.edition) then
table.insert(self.eligible_editionless_jokers, v)
end
end
local temp_pool = (self.eligible_editionless_jokers) or {}
local over = false
local eligible_card = pseudorandom_element(temp_pool, pseudoseed('wheel_of_fortune'))
local edition = nil
edition = {negative = true}
eligible_card:set_edition(edition, true)
used_tarot:juice_up(0.3, 0.5)
return true end }))```
alr fuck it try from the start uhhh restore the original balatro files and delete the stuff in mods folder
this explains why i cant
It crashes on launch right?
u can js go to steam and check the files completability?(im not native and i dont use english steam)
yes
use this
that will restore them to normal
idk what this means
You have other jokers that work?
4 others and im basing myself on paperback
just pick a pseudorandom joker from G.jokers.cards and then apply the negative
set_edition does the work for you
imma just reinstall balatro
alr
Can you send your main lua file?
you can make a list where you add jokers with no edition
There’s a utility function for that iirc
i can assure that isnt the problem
but ok
it says line 144 where it loads jokers
make sure you put your joker_peaks file in Mods/your mod/joker/joker_peaks.lua
And can you send the full crash?
IT WORKED @broken cliff
could you send what's on line 144
i know im a beginner, but i really feel like the error is coming from the joker peaks.lua file
that was the easy part
The error is saying it couldn't find the joker/joker_peaks.lua file
lucky cat replacement here i come
So make sure it's in the right folder
thats for you
Your file is in the wrong place
okay yeah it can't find the file
its there don't worry
It’s not
getting this when I copy that code
if it's there then the name is wrong
syntax error, what's your code
@vocal verge alr now install malverk
wait you didn't have to copy all of it just the set_edition
i was just sending an example use lol
Oh... I'm kinda dense with mod stuff lol
np
do i just drop malverk into the mods folder
Well but then how does it pick a joker to apply negative to
yh ig
then see if balatro launches
Did you rename a previous file? For example the find_jimbo one
Or did you create a new file
created a new one
how
Oh there’s an extra bracket in your loc vars return
AAAAAAAAAAAAAAHHHHHHHHHH
EVERY SINGLE TIME
What a remarkably unhelpful file loading system
your code would probably be more like
- create an empty table for the joker pool
- check all the jokers in G.jokers.cards, add the ones with no edition to the empty table
- if there's at least one editionless joker then choose a random joker from that table
- do this to make it negative
i felt that
download the zip file
Yeah it's from an old version of Paperback
thats not on my side
It is absolutely on your side for using it
Okay, I'll try and figure that out. Thanks!
Either way, this is why editing in a program that colours your syntax is useful
i d wanna try difficult stuff rn
sigma
yes you should get an actual IDE instead of what I'm assuming is notepad++
ik ik but nothing works and i dont have the patience to do so
alr now the hard part
making a texture pack
i already have the texture
do you have 1x and 2x
what
you are in for a ride
You need a 71x95 version and a 142x190 version
ik that don't worry
LOL
heres some of my favorite jokers ive been making, just thought id share 
fire
this is what i meant
u would need to do 71x95 version and a 142x190 version js like eremel said
ok so i need a 142x190 version of my cat
take this fella and scale it up to double
that's your 2x
and fix your current one
it's 69x93 rn
i love memory card and alloyed
i recommand pixel scaler
Missing the 1 pixel paddingg
ikr
wait i'll share some of mine too
@vocal verge heres how ur texture pack folder should look
1x - 71x95 version
2x - 142x190 version
localization - will discuss later
licence - ignore
main.lua - settings for what card ur replacing
BTW u dont have to name it AURE_SPECTRAL exactly
but its important that 1x and 2x folders have the same png names
heres all my jokers, the last 4 are unfinished
what the dog doin
some notable ones
canine: triggers when a king is next to a 9, havent ironed out what that would do exactly tho
the joker text in the minesweeper one is a nice detail but it's very hard to read
legendaries
oops all sixes and critical roll gonna make heads roll
hell yeah
ik, it was worse before
might tweak it yet again
if all 5 cards trigger its gonna be
x1024 mult
(4* 4 * 4* 4*4)
god bless america
oh actually, i wanted to ask, did you get that gender equality card working? i happen to be doing somthing similar
the funniest part is you can also lowroll into no mult at all
reduce the saturation prbbly
cant get this to work :P
i got it treating queens as kings, not the opposite tho
might suggest u to look at how cryptid's maximize card does it
ill have a lookie
kity
hell nah that's incredibly incomprehensible trust me
searching through this chat has been handy
alr do u have THE folder
the cat is cute
my cat :)
oh, i love this joker too, just havent gotten it to work quite yet
function Card:get_id()
local ret = Getid_old(self)
if ret == 12 and next(find_joker("j_garb_equality")) then ret = 13 end
return ret
end```
no
ewww loc jokers
this is how i did it
aight
now what do i do to replace lucky cat
let me Get u the main.lua file
ohhhhh, i was searching the joker by name instead of id lol
this one really depends on your language doesn't it
j_lucky_cat is the lucky cat key
--- MOD_NAME: casey cat
--- MOD_ID: casey_lucky_cat
--- PREFIX: casey_large
--- MOD_AUTHOR: [cat.bread]
--- MOD_DESCRIPTION: Replaces the texture of the lucky cat.
--- VERSION: 1.0.0
--- DEPENDENCIES: [malverk]
AltTexture{ -- Lucky Cat
key = 'casey', -- alt_tex key
set = 'Jokers', -- set to act upon
path = 'casey_large.png', -- path of sprites
keys = { -- keys of objects to change
'j_lucky_cat'
},
localization = { -- keys of objects with new localizations
'j_lucky_cat'
}
}
TexturePack{ -- Aure
key = 'casey', -- texpack key
textures = { -- keys of AltTextures in this TexturePack
'casey_large_casey'
}
}```
this is the main.lua
YEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEESSSSSSSSSSSSSSSSSSSSSSSSS
you should do the lcoalisation within that file tbh
change this ```
localization = { -- keys of objects with new localizations
'j_lucky_cat'
}
to
localization = { -- keys of objects with new localizations
'j_lucky_cat' = {
name = "Casey"
}
}
yeah
i was about to write a 3 page doctorate localization.txt file
Maybe put this on the texturepack object
loc_txt = {
name = "Casey",
text = {"Change Lucky Cat"}
}```
this is the png i have and I am wondering how i would get the image in the 3rd row 2nd spot to appear as the card
like that would the pos be for the sheet?
x = 1, y = 2
okay cool cool
top left is 0, 0
okay so the image just didnt change. what the heck 😐
did u save
yes
question, how should i go about checking when cards have their rank changed to a specific rank? is there a function i can hook into
ohh you need a 2x version
Card.change_base probably, but I think it works weirdly
you need a 2x sprite
okay maybe i made it too big cuz now there is not image lol
should i change the size from 100% to 200%?
brain is on 5% rn
this file has wrong proportions
it's a 73x97 atlas
i know i had the 1x version in the 2x section
you added an extra pixel
hmmm
to each
umm
what's your code?
oh i forgot to change default-lua
whats the image of your cat called?
this is true
ive told them each card has to be 71x95 and they still made it wrong 💀
casey_small
casey_large
@vocal verge i goofged up
casey_small for 1x, casey_large for 2x
u goofed up
oh are they both supposed to have the same name
they should be the same name
sigma
Anyone know how to get the public version of Saturn to work properly?
rename them casey_large
does it error out
Yea downloaded the public version from github and its not starting up properly
error screenshot?
then rename the casey_large.png in main.lua to casey.png
yeah
just change the stuff thats about aura to lucky cat
if you want to change the name that is
can u show me the mods folder
it looks like you might've installed lovely incorrectly
why the fuck is this shit still crashing
error message?
@broken cliff
saturn doesn't need smods and actually causes a crash when you use smods
this is when i tried pressing "textures"
oh wtf
show me the folder
my bad
happens
Coming off this post, anyone able to assist? I think I got the table set up so it grabs all jokers without an edition and puts them in the table. Just not sure how to then grab a random joker from that table
Or maybe I'm completely off
for i=1, #G.jokers.cards do
if i.edition = nil then
table.insert(eligible_editionless_jokers_rtarot)
end
end
if eligible_editionless_jokers_rtarot ~= nil then
end```
pseudorandom_element
does your saturn file have multiple files in it?
your condition is not correct, it should be not G.jokers.cards[i].edition
Gotcha, thanks!
as for your other check, it will never be nil
you can use this function#
function SMODS.Edition:get_edition_cards(card_area, edition)
local cards = {}
for _, v in ipairs(card_area.cards) do
if (not v.edition and edition) or (v.edition and not edition) then
table.insert(cards, v)
end
end
return cards
end
ah i didn't know about this one!
Okay, so scrap all that I have and use that?
it's buried in a jank place
@languid snow
SMODS.Edition:get_edition_cards(G.jokers, true) should give you all the cards without an edition
within the jokers area
I still haven't figured out how to get the proper screen coordinates of a sprite. The Sprite:draw_self() function sets love.graphics.scale and then essentially just draws the rect of the sprite at 0,0, seemingly
Yes @neat plover
ptsd
p sure headers are deprecated
this might be some prefix jank
change your prefix to casey_cat
and then the line near the end to 'casey_cat_casey'
thats in the default.lua file you had
return {
descriptions = {
alt_texture = {
alt_tex_aure_spec_aure = {
name = 'Casey',
}
},
texture_packs = {
texpack_aure_spec_aure = {
name = 'Casey',
text = {
'Replaces the {C:attention}Lucky{} cat',
'with casey'
}
}
}
}
}
need to change the texpack and alttex keys
what do i change it to
return {
descriptions = {
alt_texture = {
alt_tex_casey_cat_casey = {
name = 'Casey',
}
},
texture_packs = {
texpack_casey_cat_casey = {
name = 'Casey',
text = {
'Replaces the {C:attention}Lucky{} cat',
'with casey'
}
}
}
}
}
still crashing
error?
So like this? (Sorry I keep bothering about it)
local cards = {}
for _, v in ipairs(G.jokers.cards) do
if (not v.edition and edition) or (v.edition and not edition) then
table.insert(cards, v)
end
end
return cards
local picked_card = pseudorandom_element(cards, pseudoseed('editionless_rtarot'))
picked_card:set_edition('e_negative', true)
end```
current code is
main.lua:
--- MOD_NAME: Casey
--- MOD_ID: casey_cat
--- PREFIX: casey
--- MOD_AUTHOR: [cat.bread]
--- MOD_DESCRIPTION: Replaces Lucky Cat with my cat, Casey.
--- VERSION: 1.0.0
--- DEPENDENCIES: [malverk]
AltTexture{ -- Lucky Cat
key = 'casey', -- alt_tex key
set = 'Joker', -- set to act upon
path = 'casey.png', -- path of sprites
keys = { -- keys of objects to change
'j_lucky_cat'
},
localization = { -- keys of objects with new localizations
'j_lucky_cat'
}
}
TexturePack{ -- Aure
key = 'casey', -- texpack key
textures = { -- keys of AltTextures in this TexturePack
'casey_cat_casey'
}
}```
default.lua:
return {
descriptions = {
alt_texture = {
alt_tex_casey_cat_casey = {
name = 'Casey',
}
},
texture_packs = {
texpack_casey_cat_casey = {
name = 'Casey',
text = {
'Replaces the {C:attention}Lucky{} cat',
'with casey'
}
}
}
}
}```
can i make it so that stickers apply shaders to Jokers?
no literally just the single line snippet I sent
(in main.lua)
prefix to casey_cat and nothing else needs to change
So... like this?
function SMODS.Edition:get_edition_cards(G.jokers, true)
return cards
end
local picked_card = pseudorandom_element(cards, pseudoseed('editionless_rtarot'))
picked_card:set_edition('e_negative', true)```
IT WORKED
gg
HELL YEAH
@iron socket this one
local cards = SMODS.Edition:get_edition_cards(G.jokers, true)
oh he isn't renamed 😦
So the full thing with picking one of them to set as negative would be like this right?
local picked_card = pseudorandom_element(cards, pseudoseed('editionless_rtarot'))
picked_card:set_edition('e_negative', true)```
Edit: Okay, hopefully that works...
another hour of debugging incoming
yeah
Nothing's scarier than encountering a game breaking bug and not being able to reproduce it 😢
thats called Gaslighted by John Balatro
Please someone help me lol. I know the version works with some of the new features in Saturn, but I cannot get it to work for me😂
Aaaand nothing happened... also I can't copy the tarot card with the fool for some reason, even though I just cloned the code I used to make all of my other tarot cards
how exactly do I allow legendary joker to appear in shop ? G.GAME[("Legendary"):lower() .. '_mod'] = 50 doing this doesn't seem to work, and I think I've got the right key so I don't know, do I need to change the pool for the legendary ?
what do you mean no matches, it's literally in the dump file???
you have ot match the full line
when you forget to return true in an event:
up
--- MOD_NAME: Casey
--- MOD_ID: casey_cat
--- PREFIX: casey_cat
--- MOD_AUTHOR: [cat.bread]
--- MOD_DESCRIPTION: Replaces Lucky Cat with my cat, Casey.
--- VERSION: 1.0.0
--- DEPENDENCIES: [malverk]
AltTexture{ -- Lucky Cat
key = 'casey', -- alt_tex key
set = 'Joker', -- set to act upon
path = 'casey.png', -- path of sprites
keys = { -- keys of objects to change
'j_lucky_cat'
},
localization = { -- keys of objects with new localizations
'j_lucky_cat' = {
name = "Casey"
}
}
}
TexturePack{ -- Aure
key = 'casey', -- texpack key
textures = { -- keys of AltTextures in this TexturePack
'casey_cat_casey'
}
}```
Either remove the quotes or wrap them in square brackets
i see
Lua no likey keys formatted as strings
still crashing
Is there a way to conditionally apply a different sprite to a card for an enhancement, based on its suit? Specifically so I don't have to define four different enhancements under the hood for this one enhancement
Show changes
there may also be a better way to implement my idea entirely
--- MOD_NAME: Casey
--- MOD_ID: casey_cat
--- PREFIX: casey_cat
--- MOD_AUTHOR: [cat.bread]
--- MOD_DESCRIPTION: Replaces Lucky Cat with my cat, Casey.
--- VERSION: 1.0.0
--- DEPENDENCIES: [malverk]
AltTexture{ -- Lucky Cat
key = 'casey', -- alt_tex key
set = 'Joker', -- set to act upon
path = 'casey.png', -- path of sprites
keys = { -- keys of objects to change
'j_lucky_cat'
},
localization = { -- keys of objects with new localizations
'j_lucky_cat' = {
name = [Casey]
}
}
}
TexturePack{ -- Aure
key = 'casey', -- texpack key
textures = { -- keys of AltTextures in this TexturePack
'casey_cat_casey'
}
}```
table index is nil
What are you changing
it should be like this
localization = { -- keys of objects with new localizations
j_lucky_cat = {
name = "Casey"
}
}```
❤️
Cute
i.e., define more than one atlas position for a single enhancement?
quick question
how do i get this to appear with jokers?
(before you ask, T: tag doesn't work with jokers)
info_queue[#info_queue+1] = G.P_CENTERS.m_lucky
Okay yeah, once again asking for help with something.
I have a little screen overlay texture that I'm drawing in screenspace because it's independent of the actual game behaviors, but I want to do a little animation transition where it pops out of the joker to fill the screen
This is the code I'm using to determine the screen position to draw it. Work well enough!
local scale = screen_res.y * 0.75 / width
local in_x_pos = screen_res.x / 2 - width * scale / 2
local in_y_pos = screen_res.y / 2 - height * scale / 2```
However, I *also* need to get the screenspace position of the joker, rather than its local/scaled transform position, in order to lerp between the little window and the final screen size
```local center = card.children.center
local start_pos = {
x = center.T.x,
y = center.T.y,
}```
Does anyone know how to transform the base x and y position of a joker to screenspace? Because for example, center.T gives the position of the joker in the image as (4.75, 0), so attempting to do the transition starts at the top left of the screen b/c it's really close to 0, 0 in terms of screen pixels
at least i know my hook works
so that goes with my loc_vars?
oh yeah it does
the doc does it with Perkeo and Negative
how can i check if a round is active at the moment? i keep getting this error due to a custom context i'm trying to add when a card's base is changed
does this only happen when out of a round, or out of a game entirely?
happens as soon as the game loads so i assume when out of the game in general
i mean idk what the exact code is but you can have a return like (if hand and hand) or 0
I had a similar issue for a joker that counted the # of jokers and it looked like (if G.jokers and #G.jokers) or 0
So Diet Cola uses add_tag(Tag('tag_double')), is there a way to use that to create a random tag?
i'm guessing there's an SMODS.Tags and then you can use pseudorandomelement on it
help why do the cards i return here have no get_id function
pseudorandom_element(get_current_pool('Tag'), pseudoseed('SEED_KEY_HERE'))
@maiden phoenix fixed the level up thing btw
Yooo let's go
this can return "UNAVAILABLE" tho
I'm going to bump this
or that's what I understood from the poll functions
ah, yeah how can I prevent that result?
i think im bad at doing hooks :( has anyone hooked into the set_base func before and if so can i have some help
this is my entire block Azzy
alright so this should be good?
what context would you say a glass card shatters during?
question; how do we make a consumable that targets a playing card?
because they're not actual card instances
yup i just figured that out
now how do i fetch the actual instances
is it just self
what information do you want in your context
the previous rank and suit, and the new rank and suit?
yep
before calling the reference you should store in a local variable rank and suit
from self:get_id() and self.base.suit
then, after calling the reference you can store the new ones doing the same thing
crashes as soon as it has to make the tag
selectedTag is a tag's key
you should do add_tag(Tag(selectedTag))
Also you will have problems if it creates an orbital tag
Because orbital tags don't have a hand attached to them when they're created for some reason
you can assign a blind to the tag iirc which will handle it
Tag(selectedTag, 'Small') iirc
that might be something I've done locally though
I think that'd have problems if a mod modifies blinds no?
I remember looking at the code and reaching that conclusion
was a while back tho
holy shit it finally works tysm
only if they directly modify the table it pulls it's hands from
:3
this joker also spawns from another one that gets mult from how many jacks you have
no way... estrogen joker
so i kinda wanted to have a dynamic where when that joker goes banana (extinct) then strengths become extremely valuable
Do modded blinds have a different "type"? like what's called here
so this basically
jokers based on ocs my beloved
ong
no
unless they're extra blinds in the sense of not the standard gameplay of 3 per ante
either way, the table should always have a Small value
card.ability.extra_value is the card's sell value, right? for some reason it's always returning as 0 here
Hmm, to me it looks like the orbital choices are created when the UI for the blind is created, so if the first ante didn't have any "Small" blinds it'd still make an invalid orbital tag
no, it is additional sell value on top of the base sell value of half the cost, e.g. gift card value
ok so this joker's ability is to destroy certain cards scored
what's the way of doing that?
use context.individual and loop through context.scoring_hand
you can't get an orbital tag in the first ante
they're just not in the pool at all?
card.ability.sell_cost is already halved, right
Oh you're right, but still, if there was never a Small blind in your run, that way of creating an orbital tag would still crash
sell cost includes extra value
i'm already looping through context.scoring hand
where do i put the context.individual
ah okay
extra_value just exists because it's possible to modify it
outermost if statment like
if context.individual then
-- loop through the context scoring hand
end
modifying sell cost directly would be incorrect as the next set_cost call will just override it
good to know, thanks
hmmm I guess so
extra_value can be negative to reduce price further, right?
the context.joker_main is there to make it trigger after every card's been scored just to look cool ig
though i should probably do it how other cards do it (Immolate, Familiar, etc.)
use context.destroying_card
don't do it in any other context
you will end up with ghost cards
that's when cards are being destroyed
not destroying cards
or maybe i'm misinterpreting what you're saying
you want to destroy cards right?
yea
i want it to destroy after each card is scored
hence why it's all in context.joker_main
use destroying_card
what happens?
just no wiggle
i mean all you'd need to do is mark them as destroyed/shattered and this wouldn't happen
I suppose so, though it's still better to use the destroying step to do it
For some reason when one of my jokers destroys cards, when i come back to the save file the cards come back and I'm back at 52
did it save?
it does save like the jokers i got previously so i don't think it's that
How are you destroying the cards
what's your smods version?
do jokers need destroying context too, or can they be destroyed whenever without making ghosts?
jokers are fine to destroy
if context.destroy_card and context.cardarea == G.hand and not context.blueprint then
for i=1, #context.full_hand do
local rand_cond = pseudorandom('camera') < (G.GAME.probabilities.normal / card.ability.extra.odds)
if rand_cond then
return {
x_mult = card.ability.extra.Xmult,
card = G.hand.cards[i],
}
end
end
end
you're not returning remove = true
the latest of both is 1418a and lovely 0.7.1 so you should update
you should not be developing on old calc
still doesn't make it so that the deck saves
maybe it's specifcally an issue with the deck mod i have
ye ok
Oh wait you don't need to loop through full_hand
destroy_card is called once for every card
is there a context for when a joker is sold?
my intention with this joker is for it to have a chance to destroy glass cards in the player's hand and have them give x_mult
and context.card would be the card itself then?
that's what I'm getting from the wiki yeah
the card being sold, yes
nice ty
do you only want to destroy one card at max
all cards held in hand would have a chance, not just one
also context.full_hand is not cards held in hand
that's the full played hand
either way, you don't need to loop through cards in destroy_card, it is called once for every card
and the card being checked to destroy is context.destroy_card
how do you check the current hand size? i've only found G.hand:change_size(num) to change it
New Joker:
Yurika Harako
If first discard of round has at least 2 ranks and 2 suits, give them random Enhancements
Do you want to know how many cards in hand or handsize
what are we missing here? trying to make a consumable that can only be used on 1 playing card at a time.
You didn't end the function
you have a syntax error somewhere
you really should use an IDE that can tell you about syntax errors
2 different ones or just... Existing?
so Erosion checks G.GAME.starting_deck_size, is there like a G.GAME.starting_hand_size? Since Painted deck increases starting hand size
yeah, 100% set up the condition wrong. it's presently just
end,```
cards held in hand should just be #G.hand.cards no?
yep
thats what i thought
what do you reckon
if you don't return anything by default it returns nil, which is a falsy alue
Well yeah but there is quite a significant difference
yeah i am aware
are there any guides available for creating custom jokers and modding in general?
what do i put in can_use to detect "yep, you're selecting 1 playing card"? we're using some stuff from cryptid as a basis and it's missing can_use altogether
I'm expecting different but the text basically implies "not stone cards"
return #G.hand.highlighted == 1
is what i do
I think the text implies different, as you expect
Five Spades cards only have one suit among them
so don't discard a flush or a Xoak?
The text implies "not stone"
well, good news and bad news.
good news: the use works!
bad news: after making the tarot "pop~" sound, IMMEDIATE crash. likely because of the "add a seal" syntax we're unsure of.
How so?
High Card is neither Flush nor XOAK
Because the sentence doesnt really make sense in normal balatro
it's technically 1oak
1 of a kind
meant to reply to the message above
lol
Mythical 1 of a kind pokerhand
1 of a kind, yet somehow not your highest card
is there a template for a full-rank suit replacement image for Smods? I tried to just use the default sprites from the game, and then edited it, and I get this in-game
One of a kind would be a fun hand if it meant like, the card's rank and suit is unique in your entire deck
Not in name
Let me rephrase: I think you could reasonably argue a hand of Q, Q, Stone contains 2 ranks
How doesn't it?
personally I think restricting it the other way is more interesting
I think you could, but I think most people wouldn't
'sides the counterargument is just set theory
My first thought was 2 different ranks and 2 different suits
Sure, but it made me reread the effect to make sure I understood it
and I think the vanilla rules text for Flush and Straight and XOAK implies the same interpretation that this Joker implies

