#💻・modding-dev
1 messages · Page 380 of 1
no difference except the box is msmaller now
and while I'm at it
how do i add rounding
to the big container
get_user_sprite = function(xpos, ypos)
xpos = xpos or 0
ypos = ypos or 0
return Sprite(0,0,1,1,G.ASSET_ATLAS["reddit_usertags"], {x=xpos, y=ypos})
end
get_user_row = function(user, contributions, xspos, yspos)
return { n = G.UIT.R, config = {}, nodes = {
{ n = G.UIT.O, config = { object = get_user_sprite(xspos, yspos) }},
{ n = G.UIT.R, config = { padding = 0.2, rounding = 1 }, nodes = {
{ n = G.UIT.T, config = { text = user, scale = 0.3, colour = G.C.UI.TEXT_LIGHT} },
{ n = G.UIT.T, config = { text = table.concat(contributions, ", "), scale = 0.2, colour = G.C.UI.TEXT_LIGHT} }
}}
}}
end
SMODS.current_mod.extra_tabs = function()
return {
{
label = 'Credits',
tab_definition_function = function()
return {n = G.UIT.ROOT, config = {
-- config values here, see 'Building a UI' page
}, nodes = {
{ n = G.UIT.C, config = { padding = .3, rounding = 1 }, nodes = {
get_user_row('u/ItsGraphax', {"Mod Developer"}, 0, 0),
get_user_row('u/TSAMarioYTReddit', {"Feelin' Lucky"}, 1, 0)
}
}
}}
end,
},
-- insert more tables with the same structure here
}
end
r = 0.1 or something in the config
whole code
k
they need to be in separate row nodes
btw r, not rounding
w- h- a- t- k imma try
its rounding
no it's r
Always was r
hiya, one more question ^^
what pitch does the game's music play at?
like, in the code
like this?
get_user_row = function(user, contributions, xspos, yspos)
return { n = G.UIT.R, config = { rounding = .1 }, nodes = {
{ n = G.UIT.O, config = { object = get_user_sprite(xspos, yspos) }},
{ n = G.UIT.R, config = { }, nodes = {
{ n = G.UIT.T, config = { text = user, scale = 0.3, colour = G.C.UI.TEXT_LIGHT} }
},
{ n = G.UIT.R, config = { }, nodes = {
{ n = G.UIT.T, config = { text = table.concat(contributions, ", "), scale = 0.2, colour = G.C.UI.TEXT_LIGHT} }
}}
}}}
end
70% speed and pitch I think.
Is in_pool mandatory
Or is it already assumed it won't spawn a second time proceeding purchasing a given joker (without showman)
No, if you don’t set the pitch it’ll do it by default.
oh icicicic! neat!
where did the C node go
i needs to be
C = {
R = {
T
},
R = {
T
}
}
It assumes so in_pool is not mandatory
oh ok
how can i make my joker show up ingame
If you make it properly it already appear like any other joker
i dont know how to make it properly....
Consult the docs
straight up 
looks good excepf ot missing an atlas
Doesn’t need one by default
hm, okay
okay sorryyyyyy one more questionnnnnn
Calling SMODS.Joker will register the Joker thats a function
Also do you have a metadata file
currently, my booster packs allow the player to select a Zodiac card, even if their consumable slots are full
You need one lol
oh 😭
It's easy, just one json
i tried adding can_use to all the Zodiacs, only returning true if there were available slots, but to no avail
okay, and?
is there a fix, or is this an issue with SMODS?
well i mean i made
{
"id": "blu",
"name": "BluMod",
"display_name": "Blu",
"author": [
"TheBlueVolcano"
],
"description": "'born to :3 forced to lock in' - Tsun Szu",
"prefix": "blu",
"main_file": "main.lua",
"priority": 0,
"badge_colour": "#349beb",
"badge_text_colour": "FFFFFF",
"version": "1.0",
"dependencies": [
"Lovely (>=0.7)",
"Balatro (>=1.0.1o)"
]
}
(each of my packs has select_card = "consumeables" on it, btw)
and you see your mod loaded in the mods menu?
Balatro dependency????
copied it from another mod earlier lmao
Bruh lol
well how would you mod balatro if youre missing balatro...
it's not a bad idea
Click on your mod and check if there’s an additions tab
I get what they're going for
okay and you loaded all that but your joker isnt showing up?
well i dont know where to look
In collection
collections
Should be last one
Nope
uhhh

your joker definition isnt in some other file.. right?
Are you actually loading a file with joker?
What does your mod’s file structure look like?
oh
main.lua please
its in Joker.lua
Ah that’ll do it
youre not actually lpading that file
Joker.lua isn’t being loaded
you told the mod loader to load main.lua

We all on the same wavelength lmfao
main.lua isnt loading Joker.lua
Casual: why my css isn't working? Oh bummer, it's not imported
like a function orr
Do assert(SMODS.load_file(‘items/Joker.lua’)) in your main.lua
forgetting to import the module in
...

I forgort an apostrophe
Looks good
oh cause your using the iphone '
Yeah lol
Is Blueprint compat also assumed?
alt f5'ing now
Who cares? Use what you like
No it isn’t
hate to break it
The functionality is but blueprint_compat is false by default
My IDE personally like "
add () at the end of that line
you need to call the file function
Forgot about that whoops
ops

We did it
you did it!!!
Hello World!
I also recommend that you ger DebugPlus mod
How can I disable all vanilla jokers and make it a checkmark in my mod config
i told u : (
oh yeah i forgor sorry probably didnt understand anything at all aswell
oh yeah my fav joker " "
Legendary
Can I exclude blueprint_compat if the desired value is false then?
Yes
Fun
well it's not very straightforward
Time to make a localization file lol
keep in mind blueprint_compat is just for the indicator it doesn't handle the actual compatibility
yep
This one is really easy
yeah especially when half of words in there are called pokemon_something and i have no idea where they come from and where do i need to have them and change them to a different name
they are looking at the value in their config
https://github.com/Steamodded/smods/wiki/Mod-functions#modconfig_tab
okay yeah that’s useful i probably will make some other config options thanks
colour
the wiki lists all vanilla and some SMODS contexts
there's no context for a chance triggering
how do i make the new joker follow the new locale file i made
@red flower hey N' how do I make a Joker that asks how N' is
are you having a stroke
as long as it has the same key (j_modprefix_key) it should use it
Can confirm since I had to add that myself 😭
Actually good page
and by stroke let's just say… 🤤 🧠 🗑️
yea but what is british spelling
colour
aN'yways how are you N'
instead of color
im good hundred line is a good game
oooooooooh i thought that the hex should be british
N'ice
how do I get this to not crash 😭 I'm trying to make a simple DNA+ style effect, but I just can't lmao
ok two questions:
- How do i remove some spacing there
- How do i add a scroll bar
get_user_row = function(user, contributions, xspos, yspos)
return ui_row({ maxh = 0.1 }, {
ui_object(get_user_sprite(xspos, yspos), { padding = .2 }),
ui_column({ padding = .2, r = .2, minw = 7, colour = HEX("2c3269ff") }, {
ui_row({}, {
ui_text(user, 0.3, G.C.UI.TEXT_LIGHT, {})
}),
ui_row({}, {
ui_text(table.concat(contributions, ", "), 0.2, G.C.UI.TEXT_LIGHT, {})
})
})
})
end
what crash
There are no scroll bars in vanilla
wait there aren't?
scroll bars are hard do not recommended
ok how should i do it then
I almost maded one btw
you'd have to ask ui gods if you want a scroll bar
like mr handy himself
there he is right now
🫵

with help from john s mods himself i created the nested table system for returning the effects from my joker separately, but is there a better way of giving the effects like that? since im restructuring it to change one of the values after a certain number of triggers, i want to be able to change that while the effects are applying but idk if thats easily possible with nested return tables
I don't think that's easily possible with or without nested return tables
the effect I want is a simple "if hand contains exactly 2 cards, create a copy of both of them" you know, like 2 dnas taped together, lmao
can't you just change what you're nesting after a certain amount?
i can but i was wondering if there was a better method that would avoid that
but oh well
nope
time to torture my code
so, I guess, how would I make an effect that works like this without the crash?
i dont want to use a global variable from fear of interefence with deuplicate jokers but is there a way to have a card unique variable determine an atlas?
Damn I thought there was Chance trigger jokers
hm?
those make their own custom context but it's not very straightforward
except for lucky because that already has something
this effect crashed = #💻・modding-dev message
how would I make this effect not do that?
you should share the logs
Put card.children.center.atlas = G.ASSET_ATLAS['modprefix_nameofatlas'] in update?
what logs? if you mean the crash, it is in the link, lol, I had already sent it earlier, lol
ahh okay thats alot more simple than what i thought of
oh i didnt see it
are you sure it's related to your code? doesn't seem like it to me
If you had a soul you would also do card.children.floatingsprite.atlas
i do not but thats good to know!!
I mean, the crash happens whenever I use this effect, so, I assume it is?
if not, it's strange this is it's only occurance
anyway, I'm going to my room to cry, as I've just realized my gf broke up with me
uhh try adding G.playing_card + 1 when you copy_card the second card
omg im so sorry
I'm sorry
Wow that's tough :(
wtf I'm sorry

how do i make a card use a custom font i uploaded (i have the Language.lua file and the .ttf in my MOD/assets/fonts dir)
Fonts support added recently (or not)
i would wait for this to be merged
https://github.com/Steamodded/smods/pull/684
Summary
This PR adds a way to define font using Steamodded API (can be used for defining a language or for use with text formatting)
This PR also makes descriptions and name able to contain custom...

how are you
how do i make the joker come pre-unlocked
discovered = true
cost = 1,
config = { extra = { chips = 10, h_size = 0 }, }, unlocked = true, discovered = true,
loc_vars = function(self, info_queue, card)
```?
I think so.
what resolution should i make my atlas
Every card is 71x95, 2x is 142x90
Unless you're me, in which you make it 710 x 950 because you don't wanna lose the details.
also cards have at least a 1 pixel transparent border
literally why
-# Please stay with 71 x 95. It's so much easier.
so usually Jokers use 69x93
they need to see the pores on Jimbo's face
this is a pixel art game
like those Spongebob scenes
I used my VRoid models for the textures, so I didn't want it to be pixelated (like my last version).
4k balatro gaming?
1st off, wow.
2nd off, maybe.
i have this setup currently where it triggers repeatedly, subtracting a dollar each time
every 5 triggers, it increases the price (which does work), but in the same hand it doesnt take the increased price into account, is that a quirk with the way calculations work or am i doing smth wrong
would it be better to just make a copy of the table with the increased price in the loop actually
yes, once you return the value it's fixed
balatro mod devs jamming out to the menu theme:
im losing my mind
i have balatro muted :3
Not the papyrus joker 😭
While i'm restarting game a bunch of times, i just open balatro ost on youtube
Really like shop theme, I'm like really in shop
ok, so how should I set the judgment-like tarot to only create a certain type of joker
how can i change the menu music
and menu bg shader
(im looking through cryptid's implementation and cant find anything)
I don't understand people who play games on mute
except people who have issues with repetitive music
i dont, but i have it muted for development
Playing other music in the background tbh, I do that quite a lot
Flip flopping between game music and my own
create an ObjectType
anyways N' do you know how I could make localization that only loads if you have a setting in your config checked
i usually play with music off and just play whatever if the music gets repetitive
but yeah how ^ ^
no idea no
i did that
this joker might be the hardest one ive done so far
i think i might hate it now
out of spite
This is acutally more advanced one

so i have the context set up
but how would i turn a playing card's number to another (ex: turn all aces into 5s, yadayada)
Would it be possible to make a voucher that doubles the likelyhood of getting wheel of fortune from arcana and shops, and one that gives wheel of fortune the ability to give negative edition?
Looking at Cryptid, it checks if you're on the main menu and a bunch of config stuff
If you want to change background shader, you need override current one
In your case it should be as simple as adding ```lua
select_music_track = function()
return G.STAGE == G.STAGES.MAIN_MENU
end,```
To your SMODS.Sound()
And also syncing if needed
Anyways does anyone know if I can ban the small and big blinds in challenges
Or rather if I can do it in the challenge declaration or if I need to patch some code
first one is hard because tarots don't have weights
second one is just taking_ownership or patching wheel or hooking poll_edition to remove the noneg flag
?
ok, how do I do that then
So first one is potentially potentially possible, just probably not worth the effort?
now how would i point it to the new ogg file i have
path =
-# where...
no wiki page for smods.sound wtf
also, for some reason the tarot I just made is still making the Fool tarot
i mean i rewrote the joker rarity system to accept individual weights so it depends of what you consider worth
SMODS.Sound({
key = "your_song",
path = "your_song.ogg",
select_music_track = function()
return G.STAGE == G.STAGES.MAIN_MENU
end,
})```
Should do the job
peak
I'm just blind
Yeah, probably not worth it for me, thanks for the info though.
8 in 7 wiki pages are drawn face down
bummer
didnt someone say balatro auto-pitches the music down to 70%
can i just pitch my ogg file up to 130% then
to counter it
Just set pitch = 1
That's what I did
I did not realize I could justuse the pitch x)

wait what you can do that
(for those wondering)
Question becomes does it sync now
Ok better question, does it desync over time x)
If length is different then yes, I guess
so put the object type table in the Tarot file, but how should I put that table in the code, in the add card?
where is the cryptid menu shader m.fs?
you put the type key in set
whats the context to retrigger jokers? i have the feature on btw
ohhh the table is a separate key oki
im tring to set up a joker that cheks to see if the hand played has already been played this round, any help on how i can do that?
context.retrigger_joker_check and not context.retrigger_joker and context.other_card ~= card
how are custom challenges coded? i wanna make a basic software that can custom make challenges
this joker does that (ignore the things outside calculate)
https://github.com/nh6574/JoyousSpring/blob/1f60413b8a13267634fa8e9945dfa37358f40c04/src/jokers/99_01Effect.lua#L38
so if were checking for a joker retrigger and not retriggering a joker then we'll retrigger a joker..?
(not that it matters but 1 * 70% * 130% != 1)
oh nice ill take a look
thx
not context.retrigger_joker is to not count if this Joker is being retriggered.
^^ :]
im confused i wanna just recolor the balatro background and speed it up
OHHH
i know cryptid does it
but how can i do it
what do I put as the default in the ObjectType
You need pass variables related to speed and color to shader
"default" is the fallback item of the pool.
whatever you want the player to find if they already have all of them
is there a SMODS.Shader?
Yes
i sent u the code 😦
G.SPLASH_BACK:define_draw_steps({
{
shader = "splash",
send = {
{ name = "time", ref_table = G.TIMERS, ref_value = "REAL_SHADER" },
{ name = "vort_speed", val = 0.4 },
{ name = "colour_1", ref_table = G.C.JOY, ref_value = "EFFECT" },
{ name = "colour_2", ref_table = G.C, ref_value = "BLACK" },
},
},
})
```?
yes
explain this to me like im an idiot
Ok, the TARDIS IS working, but ONLY creating Jimbos
you see how I call it in Game:main_menu? well you need to append your code at the end of that function so the game creates all the graphics first and then you change them
more on hooks: https://forums.kleientertainment.com/forums/topic/129557-tutorial-function-hooking-and-you/
mmhm and where would i add that hook in my code
Anywhere
bruh is this balanced?
no LOL
Like no
bruh
Even for legendary too powerful
cryptid exotic:
what abt 0.05X increase?
and how do i make a hook
0.001X
ok im still confused how do i check if a hand has already been played in the current round?
that seems ass...
idk if 0.001, id say 0.02X
local game_main_menu_ref = Game.main_menu
function Game:main_menu(...)
local result = game_main_menu_ref(self, ...)
-- Your code here
return result
end
Basically it's extending a functions
But for some reason everyone call it hook
Don't like this name personally
Something to keep in mind with Lua is everything is a variable, including functions
If you're JS dev nothing new
So by that logic, you can make function definitions hold different code on the fly
With exception of missing basically any useful function for common actions
this is the code for the tarot and the Object type table, onlt half working
so @red flower im looking at your example, how would i change the menu colors
or anyone else who can help for that matter
I can help with his one. You would change it via this function. In my case, I pre-defined my colors as globals via patch (MXMS_PRIMARY and MXMS_SECONDARY)
This is within a Game.main_menu() hook
change G.C.JOY for G.C and in the ref value put the color you want
if you want a custom color you need to define it somewhere
soo
{ name = "colour_1", ref_table = G.C, ref_value = "#00ff00" },
{ name = "colour_2", ref_table = G.C, ref_value = "#ff0000" },
no
hex values won't do you any good here
wait does it go off decimal
it needs to be a defined color in G.C

(or any other table)
forwarding this since it seems to be a broader issue, people are saying this is a highest priestess crash
you can do G.C.colorname = HEX("FF0000") just before
G.C.colorname = HEX("FF0000")
self.title_top:emplace(newcard)
self.title_top:align_cards()
G.SPLASH_BACK:define_draw_steps({
{
shader = "splash",
send = {
{ name = "time", ref_table = G.TIMERS, ref_value = "REAL_SHADER" },
{ name = "vort_speed", val = 300 },
{ name = "colour_1", ref_table = G.C, ref_value = G.C.colorname },
{ name = "colour_2", ref_table = G.C, ref_value = G.C.colorname },
},
},
})
``` im missing something arent i
ref_value has to be "colorname"
it should be ref_value = 'colorname'
lol
Isnt this thing should be set every frame?
that's why it takes from a ref_table
Are you running your code in the hook?
it's telling you to play my mod
play JoyousSpring

you're probably copying something you shouldn't
for some reason i read this as JoyousSperg lmao
can you screenshot the whole code pls
ctrl+C should copy to clipnote on crash menu
local game_main_menu_ref = Game.main_menu
function Game:main_menu(change_context)
G.C.colorname = HEX("FF0000")
G.SPLASH_BACK:define_draw_steps({
{
shader = "splash",
send = {
{ name = "time", ref_table = G.TIMERS, ref_value = "REAL_SHADER" },
{ name = "vort_speed", val = 300 },
{ name = "colour_1", ref_table = G.C, ref_value = 'colorname' },
{ name = "colour_2", ref_table = G.C, ref_value = 'colorname' },
},
},
})
end
You're not running your main menu ref
i said screenshot because reading code on mobile is a pain
put a game_main_menu_ref(self, change_context) above where you're making your color
SPEEN
soon™️
GAY BOSS BLIND 
you cannot comprehend the true form of jimbo..
This might be Giygas
made me burst out laughing btw I love it
no its FIREBLU from OG Doom
what it do?
it's just a big blind, small number atm because got it on first round
WHAT HOW YOU DO THAT
it's like a wall blind
how would i check if a arcana pack is skipped using a joker
context.skipping_booster
wouldnt that be any booster pack tho,?
oh yeah youd have to check card.config for the set
trying to make a specific numbered card get destroyed but it doesn't happen in my code atm, does anyone have any pointers on what to fix?
anyways, I need help because this is just printing a base Jimbo instead of the ones I want it to
i dont think you need half as much code as that tbh
not quite sure what this means
eyyy
would card = self be what i change?
try modprefix_key for the set
trying to make it to where if a 7 and a 9 are played, a nine gets removed and adds to a stacking mult
context.card is the booster opened
check the config table of context.card for the booster type, if its arcana then do what you want
there should be a mod that combines all title screen colors that you have into one
if context.destroy_card then
local hasSeven = false
local hasNine = false
for i,v in ipairs(context.scoring_hand) do
if v:get_base() == 7 then hasSeven = true
elseif v:get_base() == 9 then hasNine = i end
end
if hasSeven == true and hasNine ~= false then
return {
destroying_card = G.play.cards[hasNine],
remove = true
}
you don't need the destroying_card return it doesn't do anything
i tried okay 😭
you need to check if context.destroy_card is the card you want to destroy
sry if im dumb im rly new to this but i have 0 idea what to actually put in the config area or in the calculate function
when I do this, it crashes with something completely different, but when the keys are the same it just does NOT work
would i just put context.card = arcana in the config area ??
no theres more to it
where can i read the documentation to help with destorying cards?
2 secs
howww 😭
hmmm no idea then lol
are you sure the keys are correct?
look for context.card.config.center.type == 'Arcana'
where would i put context.destory_card == 9?
could it be the quotations??? no way tho
key = 'j_yourmodprefixhere_jokerkey', not set or type
i mean the joker keys
it's a bit more complicated than that, context.destroy_card is a card object not a number
in this case it is set they want to make an objecttype
yeah they key is super wrong lol
no the key should be 'doc1'
so far i'm checking for if it's wanting to destory a card and then doing checks for if a hand contains a 7 and a 9 and then destory 9s and add to mult
ohhhh
don't know if i'm doing it correclty or not
then when creating the key should be 'j_jmbowho_doc1'
does it work?
wha,,
went to change my joker atlas and uhm
so like this?
editing it for now but i'll let you know
i havent written the calc function yet
im confused on where to even start
it might work if after that and you add context.destroy_card == context.scoring_hand[hasNine]
but i havent read the whole code
so change the keys in the jokers themselves or in the table?
what are you trying to do
the jokers, delete the j_modprefix
oki
when creating a joker make it the short key, for example doc1, then when calling on that joker elsewhere use j_yourmodprefix_doc1
planet has its own text styling {C:planet} as does {C:tarot}
oki, tamnk
give me a minute ill just write a calc function for you my head hurts too much
oh ok,
let me share it rn
no i mean that i didnt read the whole screenshot because im playing a game :3
OK, TARDIS works now, gotta fix why it still uses the Fool texture and not the one I made
calculate = function(self,card,context)
if context.skipping_booster then
if context.card.config.center.type == 'Arcana' then
for i = 1, card.ability.extra.cards do
SMODS.add_card({set = 'Planet'})
end
end
end
end
then put cards = 2 in config = {extra = {}}
Wait for the atlas if you're doing one big one instead of indiviual
How do you fetch for pos = { x = 0, y = 0 } for a specific art etc etc
ahhhh that's fairrr
hi!!!
use set_base()
the Tarot sized are X 63 and Y 93, or are they the same size as the jokers?
question, i just want to make sure i'm reading this right because i'm looking at this function definition feeling like i'm going insane, but if i make an SMODS.Edition with the property always_scores = true, this will trigger this condition on calculate, right? 
u can make them any size you want but thats correct for vanilla
0 0 is the card in top left corner 1 0 is the card to the right if that
0 1 is the card below that
okay!!!
yes
btw it to turn a card into a king of hearts for example it would be playing_card:set_base('H_K')
it's just a bunch of nil checks in one line
🧐 So if it's a 5x5 Atlas
witdth of 71 * 5
Height of 95 * 5 innit
Then double it for 2x
yeah, i'm kinda just derping out 
getting crashes atm and it's at the line that checks for a 7 that brings an error
:3
yeah
strange because its printing the fool instead of the TARDIS I made
if i wanted to add 2 planet cards would i just add the add_card thing twice
why... just do this, you dont need to copy all the vanilla stuff lmao
yes
ok cinema
no, the for loop generates 2, or how many card.ability.extra.cards is
Only cause its nice for organization :)
but i'll try that
it might not be efficient but i just have a unique atlas for EVERY sprite i have, its just alot easier for me sicne i hate deciphering pos ={} lmao
the joker no longer causes a crash but it isn't destroying the nine unfortunately
this is my calc for a joker that does something similar, idk just compare them i guess
context.blueprint?
yup for blueprint and brainstorm
so does the context.full_hand[1] indicate to the game that it wats to check if the hand has a ace (aka a 1)
What's it for
no, in my case it deestroys the first card in the fullhand table, being the leftmost card in any hand
blueprint and brainstorm
oh
what would i do if i wanna remove a specfic numbered card
u need to find that card before hand
btw would skipping a celestial pack be if context.card.config.center.type == 'Celestial' then then?
yeah
ok sick
with the if statements i had?
its STILL producing the Fool
hmm okay send the code again
i dont want to scroll up
ok
not context.blueprint is checking if the original joker is trigered?
would this work (i assume not)
anyways
hh where do i put this line
i thought itd go in the config table but that just crashes the game
config = {extra = {cards = 2}}
yeah pretty much i think
so do i change the check for hasSeven and hasNine?
did it
yeah
then in the if change hasNine == true to hasNine ~= nil or wtv the original value is
^
i'll see if this fixes anything
this is how i retrigger jokers to the left and right
I think this only works if you're retriggering another joker
Like the and not retrigger_joker
I want a joker that retriggers itself
It worked!!!
now i gotta make the build up for mult work properly
yum :]
remove the return, remove assert
just do if context... SMODS.change_base
okay!!!
like this??
yeahbut nil wont work for the suit
This didn't work I don't think
then what should i do?? i dont wanna change the suit
check the card suit before hand
local suit = playing_card.base.suit
maybe context.retrigger_joker?
i think its coded so that it cant retrigger itself
I've returned, time to get back on this, lol
uh
show the whole joker code
SMODS.Joker {
key = 'observer',
loc_txt = {
name = 'The Observer',
text = {
"Create 2 random {C:planet}Planet",
"{C:planet}Cards{} every time an {C:tarot}Arcana",
"{C:tarot}Pack{} is skipped"
}
},
config = {extra = { cards = 2 }},
rarity = 1,
atlas = 'kamisjokers',
pos = { x = 0, y = 1 },
soul_pos = { x = 1, y = 1 },
cost = 4,
calculate = function(self,card,context)
if context.skipping_booster then
if context.card.config.center.type == 'Arcana' then
for i = 1, card.ability.extra.cards do
SMODS.add_card({set = 'Planet'})
end
end
end
end
}
oh..
which one was line 540?
this also doesnt change a specific card i just noticed
if context.card.config.center.type == 'Arcana' then
oh yeah
uhm how would i do that if i wanna change all cards of a rank on the played hand
context.card.config.center.type is valid, i tested it
okay for some reason steamodded really doesn't want jokers to retrigger themselves
Is there a way to do it at all
patch smods
why is this custom color muted when added to G.ARGS.LOC_COLOURS? pic 2 is when in LOC_COLOURS, pic 3 is when set with a {V:1} color variable
or multiply it
try removing the {}
not rly sure why its crashing then
wait no i tested with open_booster
still the same
doesnt check for card
weird
yeah, no :< didn't work
how do i fix it,,
guess i'll stick with using {V:1} lol
there ya go
idk why, but its still printing hte fool instead of this tarot
like this?
did you set the joker to that atlas?
yes
wdym?
paste the joker code
i mean in the line local copy_card2 = etc add + 1 before the closing )
yah...
ahh, ok
like this?
yes if that doesn't work i dont know lol
new crash
v:change_base(params go here)
end```
😭
what is this pointing to, anyway?
atlas = 'atlasnamegoeshere' in the joker
no idea lol that's why i didn't know if it was even from your mod
Would there be a way to return +chips and +mult, then return +chips again and xmult if a certain chance is rolled?
OH I FORGOT TO EVEN SET THE ATLAS LAMOO
ok, try context.booster.type
This is what I have, but that does one or the other.
calculate = function(self, card, context)
if context.joker_main then
if pseudorandom('cyan') < (G.GAME.probabilities.normal or 1) / card.ability.extra.odds then
return {
chips = card.ability.extra.mega_chips,
x_mult = card.ability.extra.mega_mult
}
end
return {
chips = card.ability.extra.chips,
mult = card.ability.extra.mult
}
end
end
add an extra field to one of the returns if the chance hits
there it is
like this
return {
mult = 10,
extra = chance_hit and { mult = 20 } or nil
}
uhm
so, I looked in the search, and found one other person who had a similar issue, hmm
#💻・modding-dev message
playing_card was an example
put it in the for loop and do suit = v.base.suit
oh my lmao
SMODS.Joker {
key = 'observer',
loc_txt = {
name = 'The Observer',
text = {
"Create 2 random {C:planet}Planet",
"{C:planet}Cards{} every time an {C:tarot}Arcana",
"{C:tarot}Pack{} is skipped"
}
},
config = {extra = { cards = 2 }},
rarity = 1,
atlas = 'kamisjokers',
pos = { x = 0, y = 1 },
soul_pos = { x = 1, y = 1 },
cost = 4,
calculate = function(self,card,context)
if context.skipping_booster then
if context.booster.type == 'Arcana' then
for i = 1, card.ability.extra.cards do
SMODS.add_card({set = 'Planet'})
end
end
end
end
}
doesnt crash now, but it does nothing
would changing v:change_base to v:SMODS.change_base work
it wouldnt
oh yeah thats it
"expected arguments near '.' "
what line of the code
v:SMODS.change_base
can you add print(context.booster) after skipping_booster and send the log?
SMODS.change_base(v, suit, rank)
what log? like where is it
if you don't want to change the suit it should be nil and the ranks are strings like 'K' and 'Q'
in your mods folder under lovely/logs send the latest
okay but wouldnt using v both times just convert them back into their original ranks
oh sorry it's kind not type lol
cause like there's no errors now but its just... not doing anything
i dont know what the effect is i havent been following the convo
convert all kings into queens and vice versa before hand scored
basically a rank version of midas mask but for specific cards
try
if v:get_id() == 13 then SMODS.change_base(v, nil, 'Queen') end
if v:get_id() == 12 then SMODS.change_base(v, nil, 'King') end
i think i was wrong with the rank key as well
card.facing == "Back"
does anyone have an alternate way of doing this then? lol, maybe it'd be better to, just, work with a fresh slate here, lol
for making a DNA copy which does it for when your hand contains exactly 2 cards, instead of 1
copying each individual played card
i would copy DNA again and then add the stuff for the second card step by step until it crashes
so you know what it is
mhh
well, I don't think it helps that I don't fully understand the base dna code, lol
I'm kinda just copying what seems nessecary lol
you know, I think I may have lost the art of asking stupid questions to gain more knowledge, lol, I'm still a noob a little here, I should be asking basic stuff from time to time
like, what is the purpose of this part? what is it doing?
lmao
btw i somehow broke this joker's description and i have no idea how to fix it
remove the ,C:white
if you meant for it to have the "xmult" appearance, you want the first C replaced by an X
so it'd be {X:mult,C:white}
thanks you!!
like, to continue this, what DOES G.playing_card refer to here? is it all card's in played hand? one specific card? I really want to know the tools at my disposal here better so I can make cooler effects ! :3
what does the "and" mean in that? it takes the playing card and creates an exact copy of it that is one higher and the value is set to both of them? I don't understand, lol, how it's, like, a number var and a table at once?
what does G.playing_card mean in general? is it like how other_card works? where it depends on contexts?
I'm guessing G.playing_card is the amount of playing cards, it's a number
and means that if G.playing_card exists then it adds 1
else it sets it to 1
but I've never seen it other than in DNA
in that case, wouldn't just (G.playing_card + 1) or 1 work?
oh, interesting
no, that would crash when you do nil + 1
oh, lmao, good to know, lol
oooo, just had an idea then, maybe I can reference the code from the cryptid spectral card, maybe that's a safer/simpler one to work with code wise?
maybe?
now to make a whole new enhancement
hehehe, so, I managed to make a dna joker which made 2 copies of one played card, now to make it work on each individually :3
whuh 😭 ok, so, now, opposite issue, lmao
it is making TWO copies of each of the 2 cards
the math is not mathing to me
did you restart the run
it works now btw :3 thankuu
Can someone help me with this joker code? It doesn't add chips after the hand is played, the sound plays when the hand is played, instead of when the cards are destroyed, and it double adds chip_gain to chips (hence the / 2).
config = { extra = { chip_gain = 20, chips = 0, addchips = false } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chip_gain, card.ability.extra.chips, card.ability.extra.addchips } }
end,
calculate = function(self, card, context)
if context.joker_main then
local toDestroy = 0
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() < 9 then
toDestroy = toDestroy + 1
card.ability.extra.chips = card.ability.extra.chips + toDestroy * card.ability.extra.chip_gain / 2
end
end
end
if context.destroy_card and context.cardarea == G.play and not context.blueprint then
if context.destroy_card:get_id() < 9 then
return
{
remove = true,
play_sound('slice1', 0.96 + math.random() * 0.08),
extra = card.ability.extra.addchips and {
chips = card.ability.extra.chip
} or nil
}
end
end
end
how could i increase the mult by 1 per card scored in hand every time a card is triggered
either put sound = in your return table or put an event with the play_sound line, but don't put play_sound in your return table
also you have card.ability.extra.chip without an s
Yeah, I got that, just working through some other stuff.
wait idk why I linked hiker I was thinking of runner
also do you mean permanent increase like runner or do you mean in a single played hand
(here's the runner code)
https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua#L1267
how do i balance this to make it more worth grabbing
does balatro have a list that keeps track of all the vouchers
create TWO planet cards /j
what its going up against btw
when you say "given" does it steal the edition from one and give it to the other or does it copy
steal
I would clarify that
okay but actually i'd get something like that if it allowed that hand to "keep up" with whatever im focusing on in the run
not like "level up least played hand by most played hand level lmao" keep up, but just so it's not completely useless
make it increase the level of every hand except your most played
so like a worse black hole
idk
set the level of your least-played hand equal to the level of your most-played hand
i mean hmm
how do you get these cards? just so i can gauge the rarity of 'em
plain packs
noted
they are semi common (i think idk how exactly the weights are scaled for packs lol)
i see i see 🙂↕️
how much do they cost
compared to a tarot or planet pack
rn they all cost 4 dollars bcus i forgot to set the price
but basic will prob cost 4 dollars
6 and 8 for the jumbo and mega
so they cost the same as an arcana pack but have slightly worse effects?
honestly thinking about it just leveling up the least played hand by 3 like an unfortunate orbital tag
actually maybe 4 5 6 rather than 4 6 8
emperor creates two tarot cards, planet packs at least let you choose which of the hands you want to upgrade
fire idea
so by direct comparison they're objectively not as good as their equivalents
you are comparing apples to tomatoes
but if the apples and tomatoes cost the same amount I'm going to pick the one I know is more useful
tbf edition sounds kind of awesome in the right context
I'm just trying to give balance advice because you asked for feedback
yes, gimme a sec
ok, my bad
G.GAME.used_vouchers looks like { v_antimatter = true, ... }
what variables check for blind required score and hand score
i meant more somthing that tracks voucer keys
loop through that and put the keys in a table
ok now how do i level up hands
G.GAME.blind.chips works for required score
nevermind its level up hand
something like
local vouchers = {}
for k in pairs(G.GAME.used_vouchers) do
vouchers[#vouchers + 1] = k
end
"hand score" isn't a thing but total round score is G.GAME.chips
couple ways to get current hand score i think but i personally just did hand_chips * mult 
No i mean like you have 5 cards, and the first card gives +1, 2nd gives +2, and third gives +3
idk how to say it properly
there should be something in G.P_CENTERS
you increase by 1 mult per card and resets at the end of round
end of round or after hand is finished scoring?
(the method is the same just curious)
after hand finishes scoring
I would increase the mult variable of your joker by 1 in your if statement, and then reset it back to 1 in a separate context check
first card gives +1 and 2nd gives +2, basically the mult adds per card by 1
like this?: card.ability.extra.mult = card.ability.extra.mult + 1
yep
and then in context.after you set card.ability.extra.mult = 1
this is much more balanced lol
hello, if i want to set the player hand to 1, how i need to do that¿
like as in they only have one more hand they can play?
yes, like the needle
here's how I did it
https://github.com/chaseoqueso/Powerful_Balatro/blob/master/jokers/big_bluff.lua
so i bothered to boot up balatro and my run is still there and it seems playing this hands is causing the crash
oh wait I think I also had hooks or something
oh no cause I changed the effect
that's just it
so um
how do you have something happen when the boss blind ability gets set off like matador?
tried to use the vanillaremade repo as reference (in addition to the actual vanilla matador and paperback's calling card) but nothing's going on
code looks like this rn
if context.debuffed_hand or context.joker_main then
if G.GAME.blind.triggered and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_gain
return {
message = 'Upgraded!',
colour = G.C.CHIPS,
card = card
}
end
end```
is only the ease_hands_played(1 - G.GAME.current_round.hands_left) no?
yep, that's the line that does it
yep, it works, ty!
how would i put it on an if statement though
say
(hand chips) > 2 * G.GAME.blind.chips
since i appearntly have a run that consistently crashes playing any hand, what file should i upload so that the devs can properly debug it? i assume it's one of these?
i.e. which file has the "last run that's still going"?
are you trying to do an effect that procs when the score sets on fire?
basically but it'd be nice if i could save it in a local variable before round ends so i can use it in calc_dollar_bonus
hmhm i see, gimme a moment
G.GAME.rare_mod = 2 to double rare chances for example
blah i'll just upload the entire folder of the save, i'm still not really sure what mod is actually causing this issue, the crash says it's paperback but people are saying it's likely Highest Priestess
neato
my guess would be
if context.after then
local handchips = chips * mult
end
end,
calc_dollar_bonus(self,card)
if handchips > 2* G.GAME.blind.chips then
return {
10
}
end
end,```
you can't just return 10
lmao
you can return 10 in calc_dollar_bonus but not in a table
also the local is not going to work between the functions
it would need to go in card.ability.extra
but also that operates under the assumption that the chips earned in a round is always chips * mult
which would be incompatible with specifically my mod lol
i'm trying to have a joker increment its flat mult by 1 per card and gives it per card
i want hand chips not global chips at end of round lol
but i keep getting a large numebr that goes up nonstop until the end of round in the commented out code
btw the chips variable is hand_chips not chips
(mult is mult tho)
changed it
Added it but now the value is going up before scoring and not per card
how balanced is this
i tried other ways to get the hand score but it wasn't cooperating so i just went with this 
Am I misunderstanding the use of sound? this doesn't play anything.
if context.destroy_card and context.cardarea == G.play and not context.blueprint then
if context.destroy_card:get_id() < 9 then
return {
remove = true,
sound = 'slice1'
}
end
end
Nope, looking to play the dagger sound.
line 359 is the start of smods.joker btw which ends perfectly at line 400
line 388 is if context.after then btw
oh wait i think it needs a message
How much more common does it make it
what are you coding on
notepad++ 😭 too lazy to change it to vs studio code lmao
The language is unclear
this is what i did
if context.cardarea == G.jokers and context.final_scoring_step then
if to_big(hand_chips) * to_big(mult) > to_big(G.GAME.blind.chips) and to_big(G.GAME.blind.chips) > to_big(0) then
card.ability.extra.flame = true
end
*...more code here...*```
pls do, it will make it easier to spot syntax errors like that
hello chat, how do i get this code to work?? no matter what the enhancements dont change
the way ive done it looks silly i know but nothings working
local toenhance = SMODS.get_enhancements(G.hand.highlighted[#G.hand.highlighted])
local enhdfhg = toenhance[i][1]
G.hand.highlighted[i]:set_ability(G.P_CENTERS[enhdfhg])
im pretty sure its this
yes but I'm saying hand chips is not always equal to chips*mult
Make Rare jokers +0.1x more common (Cannot exceed +2.5x more common) would be more clear
this is an excerpt the bottom part would be in a for i
i mean... yeah
but lets pretend it is
remove the [i] from enhdfhg = toenhance?
still nothing
hows this
fine
if you print enhdfhg what does it give you
okay wait its not calling the print at all
let me get a bigger excerpt
local toenhance = SMODS.get_enhancements(G.hand.highlighted[#G.hand.highlighted])
...
for i=1, #G.hand.highlighted do
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.1,func = function()
if toenhance then
for i = 1, #toenhance do
local enhdfhg = toenhance[1]
G.hand.highlighted[i]:set_ability(G.P_CENTERS[enhdfhg])
end
else G.hand.highlighted[i]:set_ability(G.P_CENTERS.c_base, nil, true) end
return true end }))
end```
i tried printing enhdfhg after its defined and it doesnt run at all
looking at the code, found absolutely no errors
smods.joker closes just fine, it's an argument that i placed wrong i think
it wants me to close around if
like right here
it has to be like another syntax error that isnt a parenthesis
calculate = function(
oh my god LMAOO
pls get a good editor : )
Now I've got this, but the sound and message play when cards go down after scoring instead of when they're destroyed, how should I fix it?
if context.destroy_card and context.cardarea == G.play and not context.blueprint then
if context.destroy_card:get_id() < 9 then
return {
remove = true,
sound = 'slice1',
message = 'Card was slain by',
colour = G.C.CHIPS
}
end
end
uhh that shouldn't happen probably
haven't messed too much with this kind of thing yet but i think you need G.E_MANAGER:add_event for this
..or not lol
i don't think it's a problem with your code, maybe it's smods
yummers
ok so when i eval SMODS.get_enhancements(G.hand.highlighted[#G.hand.highlighted]) on a steel card it returns Table: m_steel: true but when i do so for its length it returns 0
looks like ill have to find another way
ah ok yeah, it's not an array so # doesn't work
ah thats it then
[1] won't work either
is there a way to get an array of it
you probably need to iterate over it using pairs and count
i mean that would contain the enhancements
yeah this is a pairs problem
wait a second i can steal cryptid code
ah
now that its come up whats the differences between for i, in pairs and in ipairs
try printing highlighted.config.center.key
pairs is for any table but doesn't guarantee order
ipairs is for arrays
highlighted being the card with the enhancement
yeah that works
and objectively that would be the simple and obvious solution
but im trying to be inclusive for multi-enhanced cards
using add_event is better, but it still plays once for each card destroyed, can I add something else to stop that?
if context.destroy_card and context.cardarea == G.play and not context.blueprint then
if context.destroy_card:get_id() < 9 then
return {
remove = true,
G.E_MANAGER:add_event(Event({
func = function()
card:juice_up(0.8, 0.8)
play_sound('slice1', 0.96 + math.random() * 0.08)
return true
end
}))
}
end
end
idk how quantum enhancements work so i cant really help then
save a variable somewhere and change to true once you play the sound once so it doesn't play again?
Im using psuedoshuffle to reshuffle played cards into the deck but the played cards will only change placement when another card is played. Otherwise it's just at the bottom of the deck. Is there anyway I could circumvent this ```lua
if context.final_scoring_step then
G.E_MANAGER:add_event(Event({
func = function()
local hand_count = #G.play.cards
for i = 1, hand_count do -- draw cards from deck
draw_card(G.discard, G.deck, i * 100 / hand_count, 'down', nil, nil, 0.08)
end
pseudoshuffle(G.deck.cards, pseudoseed('recycler'))
return true
end
}))
end
I haven't done this before but you might be able to set the event not to blocking
me neither lol i just know they exist
thanks anyway
How would I do that?
-# (sorry just gonna bump this real quick
)
when i try to trigger plus 1 mult that incremement by 1 per card for each triggered card, i keep having the mult value increase passively before playing a hand, how do i fix this?
the joker desc isn't accurate to what i'm tryna do, i wann have each card add 1 mult to the joker and it carries to each card and resets at the end of round
however when using the joker the joker passively increases the mult to a large amount which is not intended
then resets to 1 like normal
ok i'm dumb it is working fine
idk what was causing issues earlier
but it isn't doing +2 first and instead doing +1 on the first card
ok
lemme try that
that makes it work as intended but it shows +0 mult in the joker description i gotta fix that
It now is working as intended ^^
does G.GAME.blind have a variable that indicates if its a finisher blind? e.g. Crimson heart, violet vessel and if not, is there a mod function in lua?
did you save the file
im going completely insane
i have a savestate set up
everything should be identical
so WHY is it that when this code is run the tables it returns are ONLY SOMETIMES empty and other times correctly have stuff in them
varrrr = k
print(toenhance)
print(k)
print(v)
print(varrrr)
end```
of course once i make a post about it it starts working consistently even though i havent even restarted the game or anything??
yes i had it work BEFORE I updated smods
Yes.
are you sure
Yes
it probably does but idk
modulo is %
Just threw a trash can into space
nah i don't think you did actually
ty !!
Literally here
why is it just the default joker atlas
I've made an enhancement, but it's not showing up on the cards
reasons
easier to hide art
oh.
I think i figured out my problem
it's so funny to me when people include the vanilla sprite sheet in their assets lmao
I don't normally do this btw
ok so i think whether or not this code works depends on how long the game has been open
if its not been a few seconds then center is a nil value or smth
so i guess its resolved
I see the issue
id hope not 😭 i had to scold a doctor who guy earlier for this
I'm doing this for aesthetic reasons, I can't give more information on it other than that
oh aren't we secretive?
Would give away what the mod actually is (and I've been keeping that a secret for almost a month now)
I do
u can use the vanilla atlases without adding them to your assets btw



