#💻・modding-dev
1 messages · Page 508 of 1
you combine the two with and
Use both, context.buying_card is just a boolean
gets the type of the card (i.e joker, tarot, etc.)
context.card is the card that was bought in context.buying_card
How do I get cards in back hand? Like context.scoring_hand and context.full_hand
held in hand?
Yea
G.hand.cards
I think Context.scoring.name is crashing my game
Cause when I click a flipped card it crashes
And also when I turn off talisman it works fine
hi hello, how do i make the shop gain a pack ? ping me pls
Try updating talisman
Had this issue recently
Only for flipped cards as well
That'll be 300 bucks
Soup cans
Mail or email
bump
store as in remember the edition of a joker to apply to a different one?
yes
every few hands this joker switches itself into a different one then switches back
oh, so like there's a pool of editions and you want this joker to cycle between choices?
no I mean it like this if this makes sense
`card:set_edition(edition_key)
theres no crash for this, but why does it not work?
key = 'diamond',
loc_txt = {
name = 'Diamond',
text = {
'Copies ability of {C:attention}Joker{} to the right if played hand contains a {C:diamonds}#1#{} suit'
}
},
atlas = 'diamond',
pos = { x = 0, y = 0 },
rarity = 3,
cost = 9,
unlocked = true,
discovered = true,
blueprint_compat = false,
config = { extra = { suit = 'Diamond' }, },
loc_vars = function(self, info_queue, card)
if card.area and card.area == G.jokers then
local other_joker
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i + 1] end
end
local compatible = other_joker and other_joker ~= card and other_joker.config.center.blueprint_compat
main_end = {
{
n = G.UIT.C,
config = { align = "bm", minh = 0.4 },
nodes = {
{
n = G.UIT.C,
config = { ref_table = card, align = "m", colour = compatible and mix_colours(G.C.GREEN, G.C.JOKER_GREY, 0.8) or mix_colours(G.C.RED, G.C.JOKER_GREY, 0.8), r = 0.05, padding = 0.06 },
nodes = {
{ n = G.UIT.T, config = { text = ' ' .. localize('k_' .. (compatible and 'compatible' or 'incompatible')) .. ' ', colour = G.C.UI.TEXT_LIGHT, scale = 0.32 * 0.8 } },
}
}
}
}
}
return { main_end = main_end }
end
return { vars = { card.ability.extra.suit, 'Diamonds' } }
end,
calculate = function(self, card, context)
local other_joker = nil
if context.individual and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.suit) then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i + 1] end
end
return SMODS.blueprint_effect(card, other_joker, context) end
end
}```
do you want the edition to kind of hop between jokers?
yes
okay, so i'm coming back to the problems i'm having with giving Zodiac cards upgrade arrows
like if you picked up the intial joker in negative it would stay negative when converting to the other
store the edition i think
these are methods on cards, and these should work, as they all deal with cards
that was the idea I just dont know how
keys
this won't, however, as v here is a center
i dont have the full context what does your joker do
i need a way of having cards update their arrows when loaded
because from what im getting you can just idk
and i've got no idea how to do that ^^; suggestions?
store the edition key locally
store it like this:
config = {extra = {edition_stored = "your edition key"}}
at least thats how I'd try to do it
unless theres a better way
card.edition stores it i think
it has an ability but it swaps its ability every 5 hands and in order to do that I had it create a seperate joker with these 2 being different jokers
I just dont know how to grab its edition
OH YOU'RE MAKING A LIY JOKER
yesss
peak
are you creating another card to make the other phase
I've actually fully released my mod I'm just bug fixing
yes
Any reason the sticker badge says error?
bump
ok in that case u can make the created card have the same edition as the initial then
No, just do card:set_ability("j_modprefix_key")
wdym an extra pack slot?
my mods called "battle for jimbo" in the modding thread if you wanna check it out : )
what exactly is not working?
I just dont know how to grab its initial edition though 😭
i'd like to add arrow animations to Zodiacs that are affected by upgrade effects, and the way i've thought of doing this is,
it just wont copy the ability, even if you have a diamond in your played hand
I know how to set a jokers edition I'm not sure how to find and store the edition of an existing joker
the animation should be updated whenever the upgrade effect changes, or the card starts being rendered
Couldn't you just use SMODS.DrawStep?
does anyone know what this is happening to my skin?? the 1x and 2x files have the same colors and nothing seems weird untill i open the game
oh! lemme check that out
Should be joker.edition
big if true
also, i edited the code a bit, let me send the new version
Ok I’ll try that
it still dont work though
key = 'diamond',
loc_txt = {
name = 'Diamond',
text = {
'Copies ability of {C:attention}Joker{} to the right if played hand contains a {C:diamonds}#1#{} suit'
}
},
atlas = 'diamond',
pos = { x = 0, y = 0 },
rarity = 3,
cost = 9,
unlocked = true,
discovered = true,
blueprint_compat = false,
config = { extra = { suit = 'Diamond' }, },
loc_vars = function(self, info_queue, card)
if card.area and card.area == G.jokers then
local other_joker
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i + 1] end
end
local compatible = other_joker and other_joker ~= card and other_joker.config.center.blueprint_compat
main_end = {
{
n = G.UIT.C,
config = { align = "bm", minh = 0.4 },
nodes = {
{
n = G.UIT.C,
config = { ref_table = card, align = "m", colour = compatible and mix_colours(G.C.GREEN, G.C.JOKER_GREY, 0.8) or mix_colours(G.C.RED, G.C.JOKER_GREY, 0.8), r = 0.05, padding = 0.06 },
nodes = {
{ n = G.UIT.T, config = { text = ' ' .. localize('k_' .. (compatible and 'compatible' or 'incompatible')) .. ' ', colour = G.C.UI.TEXT_LIGHT, scale = 0.32 * 0.8 } },
}
}
}
}
}
return { main_end = main_end }
end
return { vars = { localize(card.ability.extra.suit) } }
end,
calculate = function(self, card, context)
local other_joker = nil
if context.individual and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.suit) then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i + 1] end
end
return SMODS.blueprint_effect(card, other_joker, context) end
end
}```
Oh ok
Hi smt 👋
mm, no, i'm doing the animation in a different way
the framework for that works perfectly, the bit i'm struggling with is getting the card to keep its state up to date
card centers have an anim_state and an anim_extra_state, which are the base card and anything on top respectively
and also a bunch of animations that have keys, which the states relate to
so Space Invader has the states crab, squid, octopus
No, I was referring to you just using SMODS.DrawStep to draw the arrows on the cards.
ah that's true, i'll change over to that after
i've set up the Zodiac cards to have working animations — 0, 1, 2, 3 and 4+
how to do custom mod icon hehe
Have an SMODS.Atlas with the key modicon
their states need to be kept up-to-date, and i'm struggling with that ^^;
gimme a minute while i test something though
swag thanks
mm, right, this doesn't seem to be working right now
but anyway
the top method here updates the arrows to whatever they should be, and is attached to Card
like i said earlier, this needs to be called when the number changes, and also when the card is loaded
and i don't know how i'd go about doing that ^^;
oh i see
in your calculate function it should look like this
calculate = function(self, card, context)
local other_joker = nil
local has_diamond = false
if context.before then
for _, playing_card in G.play.cards do
if playing_card:is_suit(card.ability.extra.suit) then
has_diamond = true
break
end
end
end
if has_diamond then
-- blueprint copy effect here
end
end
basically do the suit check by iterating through context.scoring_hand
No, context.cardarea is never G.play in context.before for jokers.
Yes, that would work for playing cards.
No, because this is a joker.
... so then where would be the right context for a joker to check if played hand contains a suit then
context.before without a cardarea works
iterate over the cards in G.play and check for each card's suit
this is fine except for the cardarea and that you're not using ipairs to iterate
ahh i knew i woulda forgotten something, i keep forgetting to do ipairs lmao
screw ittttt let's do this every frameeeeeee i can't be bothereddddd
HAHAHAHAHA OKAY AT LEAST IT WORKS :D
yay >:3
how do i make code only run if a certain mod is active
im pretty sure its SMODS:find_mod("<mod id>")? not entirely sure though since i havent actually seen it much
Oh no april first
how do i make it so a hand is ALWAYS set to a certain one, no matter what i play?
like always a high card or something like that?
like my least played hand
if next(SMODS.find_mod("modid"))
look at the last release notes for smods theres a new context for it
:3
crash says attempt to call a nil value?
at that line specifically?
oh
no you need to do
assert(SMODS.load_file("src/joker.lua"))()
the other lines like it load fine apparently
won't that just make it throw a slightly nicer error
it's not it just gives you a nicer error
the first question is "is there a src/joker.lua in your mod"
for instance it might actually be src/jokers.lua idk
yeah doing the assert for some reason told me the actual reason why it didnt like it
or src/joker.lua might not return anything
i had problems with that before
although then it should be callable and the callable should return nil, right?
yes, that is the assert's entire purpose. to give more details about the error
yeah but normally it would just tell me the issue with the file not tell me everything is wrong
Is there any way to know if other joker has triggered? I want to make a joker that scales each time the joker to his left triggers
context.post_trigger
so if I wanna know when the joker to his left triggers it would be:
if context.other_card[i-1] and context.post_trigger
?
No.
I meant context.other_card == G.jokers.cards[i-1] sorry
i being the index of actual joker
Yes, but it would be if context.post_trigger and context.other_card == G.jokers.cards[i-1] also you have to enable context.post_trigger
how do i hook the main_menu function
local oldmainmenu = Game.main_menu
Game.main_menu = function(change_context)
local g = oldmainmenu(change_context)
return g
end
main menu has a param
does negative priority make things load before others
Yes.
alr
having trouble finding code to reference for making a new consumable visually act like a planet
(i'd like it to move to the center of the screen + clear/move the other UI as needed, juice itself and maybe play a sprite animation, but i'll deal with that later, and then move back into the consumables area)
it is probably in Card:use_consumeable
gotcha
if not there maybe look for G.FUNCS.use_card
probably in state_events.lua or button_callbacks.lua
yea, looks like use_consumeable just handles the hand text for planets
ok
I'll buy you chicken wing later
thx bud I’m hungry
Npnp
turns out that this is the default behavior when using a consumable 🔥 i don't need to do anything special for it
<@&1133519078540185692> another one
that's sad to hear
i would like some help if you can
ok sorry about that i'll elaborate
so I have a joker that is supposed to detect when 3 cards are discarded, delete those cards and instead replace them with a randomly enhanced jack, king, and queen
but in testing it immediately crashed as soon as i discarded the three cards
and i'll send the code for you to check out
yeah please send the code and the crash
I think the problem is that youre trying to return a message for a card that was destroyed
this will also add 3 cards for each card discarded
Missing something here for XMult trigger off of debuffed items?
local curcard = context.other_card or context.other_joker or context.other_consumeable
if curcard and curcard.debuff then return { xmult = card.ability.extra.debuffxmult } end
Yes, debuffed cards don't score.
So how would i fix this?
im writing it down
Ok thanks
this is how i would do it
i didnt test it tho
if context.pre_discard and #context.full_hand == 3 then
card.ability.extra.added = nil
local cards = {}
for _, rank in ipairs({ "J", "Q", "K" }) do
local added_card = SMODS.create_card {
set = "Enhanced",
rank = rank,
area = G.discard,
edition = poll_edition("modprefix_add_card_enhancement", nil, true, true),
seal = SMODS.poll_seal({ guaranteed = true })
}
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
added_card.playing_card = G.playing_card
table.insert(G.playing_cards, added_card)
table.insert(cards, added_card)
G.E_MANAGER:add_event(Event({
func = function()
added_card:start_materialize()
G.play:emplace(added_card)
return true
end
}))
end
card.ability.extra.added = true
return {
message = "Added cards!",
func = function()
G.E_MANAGER:add_event(Event({
func = function()
G.deck.config.card_limit = G.deck.config.card_limit + 3
return true
end
}))
draw_card(G.play, G.deck, 90, 'up')
draw_card(G.play, G.deck, 90, 'up')
draw_card(G.play, G.deck, 90, 'up')
SMODS.calculate_context({ playing_card_added = true, cards = { cards } })
end
}
end
if context.discard and card.ability.extra.added then
return {
remove = true,
message = "Destroyed!",
}
end
Alright thanks, I'll test it a little later and tell you how it works out
Hello, how can I create negative square jokers even though all the joker slots are full?
Remove the joker slots check.
it may be peak
how would i disable a joker from showing up in the shop but still being able to show up from a consumable?
You mean like Judgement could still spawn it?
Sorry, I copied this code from Joker Forge and I don't know where the verifier is.
I think you do in_pool = function(self, args) return args.source ~= 'sho' end
i'll try that ty
the check is the line if #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit then. that checks if you're already at the joker limit, and only does stuff if you're not. remove that line, along with the end associated with it (and fix the indentation for everything inside it), and you should be good
there's more stuff you could do to make the code cleaner afterwards, but it wouldn't really affect the joker's behavior
Thank you very much, really, thank you for your patience.
card1:is_suit(card2.base.suit)
awesome thank you!
I need UI help (again):
I have a stake that adds a timer to the run, however currently that timer is implemented by just printing the number the timer is at every time it updates. How would i instead make it a meter that fills up gradually?
are suit colors linked to their suit? like if i wanted a message color to be card2.base.suit could i put that in the message return?
@manic rune didnt you literally just do this
colour = G.C.SUITS[card2.base.suit]
thanku somecomm
theres progress_bar argument you can put inside G.UIT.R or G.UIT.C
though currently it doesnt have any easing, so you would need to do it yourself
alright so i'm in the .lua file, where should i replace the text?
i barely know how to do basic ui, all of the ui stuff i have was "borrowed" from srockw and i understand none of it
inside the calculate function
for this in particular? nothing other than the aformentioned print()
so i delete everything below here (highlighted) and paste in the code you sent?
unrelated n but any news on that in_pool pr (just asking for checklisting reasons)
oh
yes
well you might want to learn ui basics then :3
you will need to wait for the weekly eremel pr review
got you got you
ok i'll try that and tell you what happens
thankfully all my prs are simple so they usually get accepted or rejected immediately
aaaand the game immediately crashed
if it immediately crashed then it's a syntax error
sighhhhhhhh it's so confusing though...
oh\
its not that hard dont worry
its just wrapping nodes around one another
:3
so this is a syntax error?
i'll just send the file
i prefer a screenshot because im on my phone lol
aight cool
well, we'll see how it goes
oh cool it works
the operations don't work exactly how i intended it but i can work with this
bringing this back up since I still cannot figure out what is going on with the atlas being nil
animation atlas doesn't work with consumables
you'll have to animate it manuallh
you can, just that you gotta make the code yourself
you have to manually animate them in the update function
dt in the update function is supposed to be the time between one frame to the next, correct?
ok so i have a problem
after i discard the three cards, all other discards get destroyed no matter how many cards there are
but the discards before the three-card discard are fine
oops
add this at the beginning of calculate
if context.pre_discard then
card.ability.extra.added = nil
end
you can remove the other line that says = nil
for some reason, the info_queue isnt tracking the discards with yorick?
he is in the table so i am confuzzled
ok so new line after the first one that says calculate, paste in the new chunk, and remove the line that says card.ability.extra.added = nil
yeah
ok
Card:generate_UIBox_ability_table() doesn't return the vars
basically i didnt realize that i was resetting the flag only when you discard 3
can i modify it to do so?
alright thanks for your help so far. i don't really need the "Destroyed!" text, how do I get rid of it?
delete it?
i phrased that weirdly
which lines do i delete to remove the text without it crashing?
the line that says message
im not chatgpt lol you can try things out dont be afraid of crashes
Next I'd like stone cards to be excluded
Have you tried printing what it returns?
the ui box?
No, Card:generate_UIBox_ability_table()
hey so im calling card:explode() on a normal playing card. after that it doesn't actually get removed properly from the deck and can be drawn to hand later completely invisible lmao
is there a function to just...delete a card. straight up. besides start_dissolve because that produces unwanted visual effects
so i want to access this new field that i gave this consumable, how would i do so?
card:remove()
oh remove ok thank you
i was typing out everything i could think to get suggestions from visual studio code of but i didnt guess remove lmao
card.config.center.anim_info
i love coding instead of working on the 6 cards' worth of art i still have to do for my other mod
i like the sound
it's a stock royalty free sound i found lol
so N there are just two more things I want for this joker i'm making
i want stone cards to be excluded
and I want to put the new enhanced face cards in your hand instead of the deck
hope it's not too much of a hassle
change the area to G.hand
oh ty
i think it's the 3 draw_cards at the bottom
ok i'll try that
if im remembering the arguments correctly u should change G.play to G.hand in those
no it's g.deck
ok it worked
mb
ok i know this is getting really picky but i just want the cards to appear in your hand, without the animation of them sliding onto the screen
im going to cry lol
IM SORRYYYYYYY
isnt this emplace
😭
you know what N just go to bed i can do this later
i was going to make a simple version without the animation but because you had it i kept it in..
i missed all of this but why wouldnt you just use the familiar code if you wanna make new face cards in the hand
you can change create_card for add_card and change the area to G.hand
then delete all the animation stuff
idk what the animation stuff is
all the events
ok i tried deleting a few things but the game just keeps crashing
i'll send another screenshot and just tell me what i need to delete
is there a priority when getting most and least played hands?
cause if its tied for some reason full house always gets upgraded
if context.pre_discard and #context.full_hand == 3 then
local cards = {}
for _, rank in ipairs({ "J", "Q", "K" }) do
local added_card = SMODS.add_card {
set = "Enhanced",
rank = rank,
area = G.hand,
edition = poll_edition("modprefix_add_card_enhancement", nil, true, true),
seal = SMODS.poll_seal({ guaranteed = true })
}
table.insert(cards, added_card)
end
card.ability.extra.added = true
SMODS.calculate_context({ playing_card_added = true, cards = { cards } })
return {
message = "Added cards!"
}
end
if context.discard and card.ability.extra.added then
return {
remove = true,
message = "Destroyed!",
}
end
the priority is whatever you program it to be
how do i set the priority?
wait where do i put this?
i think you can figure it out
what do you want it to be
no i cannot :/
im sorry, im not a programmer
then i would recommend you learn some basics
i think you need to get the hand.order but im not sure
calculate
trying to print that causes a card.lua crash at this line (868)
i know it's the print, because commenting it out makes everything work fine
Wa
thank you, that is a lot more helpful
Yes, move the function above it into the print.
it shouldve been common sense since youve been working within that function for like, the whole time
wait so cant i just say print(vars)
yeah that checks out
i'm sorry for being such a headache
but i think i can figure out the rest
actually wait no nvm
no wait yeah cant i
Perhaps.
ill test
@daring fern this means they ARE being stored, then, right?
forgot to ask
ok ok cool
so then why isnt ijiraq tracking them?
i discard a hand, and then hover. i did this until i ran out of discards
Have you tried printing the saved values?
Yes.
Yes.
one moment
INFO - [G] Table:
extra: Table:
discards: 23
xmult: 1
x_chips: 1
hands_played_at_create: 0
mult: 0
h_x_chips: 1
perma_mult: 0
t_mult: 0
h_dollars: 0
set: Joker
perma_p_dollars: 0
extra_value: 0
perma_bonus: 0
p_dollars: 0
perma_x_mult: 0
h_size: 0
bonus: 0
h_mult: 0
perma_h_dollars: 0
yorick_discards: 23
perma_h_x_mult: 0
perma_h_mult: 0
d_size: 0
perma_h_chips: 0
effect:
perma_x_chips: 0
perma_h_x_chips: 0
x_mult: 1
order: 145
h_x_mult: 0
type:
t_chips: 0
name: Yorick
h_chips: 0
Is that the only thing it printed?
well it also printed the 1, 23, 23, 1 thing because i didnt remove it
but otherwise, yes
is that bad?
No, does it change when you discard?
oh let me see
discarded 5 cards then hovered
INFO - [G] Table:
extra: Table:
discards: 23
xmult: 1
x_chips: 1
hands_played_at_create: 0
mult: 0
h_x_chips: 1
perma_mult: 0
order: 145
h_dollars: 0
set: Joker
perma_p_dollars: 0
extra_value: 0
perma_bonus: 0
p_dollars: 0
perma_x_mult: 0
h_size: 0
bonus: 0
h_mult: 0
perma_h_dollars: 0
effect:
perma_h_x_mult: 0
perma_h_mult: 0
d_size: 0
perma_h_chips: 0
yorick_discards: 23
perma_x_chips: 0
perma_h_x_chips: 0
x_mult: 1
t_mult: 0
h_x_mult: 0
type:
t_chips: 0
name: Yorick
h_chips: 0
Does this only happen with Yorick?
hi chat ive returned from my concert
he gave me a pick and gave me an autograph which apparently he doesnt usually do but i pulled my veteran card on him
i dont think so? ive had to create special behaviors for:
- drunkard
- troubadour
- splash
ive also done some for
- the cashout jokers
- mr. bones
but that's because i had custom behavior in mind for them
hi dilly
in the game what actually removes the card? i tried hooking card:remove in order to make certain cards not be able to be removed but it still stayed upon selling
hihi
Hello, could you tell me how to transfer the save data of Balatro from the old iPhone to the new iPhone?
Card:start_dissolve is what is called when selling.
wrong channel methinks
ok well i fixced the rest of it other than this
is there a way to revert the dissolve shader
the joker functions and all its just,,,, not visually there because the dissolve shader already ran and finished
@daring fern is it because i have it like this now?
card.states.visible = true?
its not invisible
the dissolve shader is overlayed on top, which is making it invisible since thats the purpose of the dissolve shader, to make it dissolve and turn invisible before fully removing the card
card:start_materialize()?
that works ty
when you use ipairs on a table that has numbered indices as well as string/other type keys, will it always go through all those numbered keys assuming they're continuous?
Yes.
starting from 1
ok it works fine on things like wee joker, so it's specifically yorick???
hi winter
why your shit so dark
it's behind the debug print from hover
no lmao
Hi dilly!!!
how ar eu winter
ehh, kinda okay
ok yeah it's just yorick
(hi winter!!!!!!!!!!!!!)
i hope you become awesome
would you like some of my mcdonalds to feel better
I promise I have enough coming
huge back
i ahvent eaten yet today and just got back from the concert i deserve this
Biggest back known to modding dev
sicne ur mean maybe i wont sharte with u and will instead break ur mod
im only like 145 pounds...............i cant be that large of a back
And you’re eating THAT much????
fix it felix
ive eaten this much since i was a teenager yea
the ongoing theory is i have a tapeworm
i think its just cause as a kid i only ate sparingly due to no money so i eat as much as i can when i can
sorta a survival type beat
so ive been going back through old jokester code and fixing it up right
why the FUCK is hit the road looking for NINES
"oh no it's not working ill have to figure it out later i guess...."

oh my
why was she counting all the jacks in calculate if they're going to be destroyed anyway
like i get in loc vars, it's for the description
"HTR desc render bug" is the checklist item
a real mystery
jesus
no that's dilly
yea im dilly
new to modding, fumbling my way through getting my first joker set up. It shows up in collections and whatnot, but is there a way that i can force the modded joker to appear in a run play with it?
grab the debugplus mod. then you can go into the collection during a run and press 3 to spawn it
heard, thank you!
any other tips for a new modder? I work as a dev, new to lua, and the steammodded docs are helpful but i feel like im missing some stuff. using another mod as a guide. anything yall wish you knew when you started?
vanillaremade is another great resource, it recreates pretty much all vanilla content as a mod for reference purposes
https://github.com/nh6574/VanillaRemade
Fuuuuuuuck I was gonna send that
im going to kill past jolyne
LOL
there is literally no excuse
do you know why
would you like to guess exactly what is in joker main
the only thing that was done right
was the scoring
just because it's debuffed
does not mean
it's not a ranked card
"oh but that's how the basega-" youre going to destroy them. why are you playing nice
didnt even mention her calling pre_discard instead of checking for the discard cardarea in destroy_card
im tired boss
This isn't working
how can i specifically retrigger steel cards in hand
check vanillaremade for something like sock & then change the face card check to a steel card check?
...sock is only in played hand
i'm talking held in hand
neither vremade's baron nor mime help 
vampire:
nothing useful there either

I feel like mime would be the most useful starting point ngl
if context.repetition and context.cardarea == G.hand and SMODS.has_enhancement(context.other_card, 'm_steel') and not context.end_of_round then maybe
finally.... inner peace....
Lmao
no cause astra
i have this condition, but it won't enter
that indentation is killing my brain cells
that looks fine to me, if your goal is to retrigger all played and held in hand enhanced cards
except theyre trying to only retrigger steel cards in hand
why are you calling G.play then....
i'm not only trying to, it's part of what i'm trying to do
i see i see
if you want the last line to be stylized then you want to manually do so in main_end i think
no but i knew what she was trying to do in this case
so i fixed it
ic
bepis
hi dilly, hi toma
:3
twinning
i cant believe i forgot this part
it's gonna render blank dummy...
We are so eepy
whats the uhhhhhhhhhhh thingy u add to return to make it run another return or smt
i forgor
extra
the condition doesn't enter.
thank
that art is beautiful wtf

the problem is not the condition then
fuck i forgot how to remove the obvious blank line of fakeness
it's whatever you have inside
if you just return { repetitions = 1 } inside the condition it should work
idk if the rest of your code is correct
does anyone remember how to remove the extra line completely instead of returning false or being set blank
extra line in question
i forgot to close the loop
yep, fixed 
the problem was elsewhere 
the joker was loading in the wrong state and i hadn't put it in my thing that forces my jokers with states into the correct state on loading the save
how are you adding the line
this renders fine while i have the joker
obviously since its alternative is a blank space, itll still keep the line
i see
you shouldn't do that, either use main_end or change the localization key for different stuff
im trying to remove that line and i swear it was main_e-
otherwise the line is never gonna go away
ughhhhhhhhhh main end,,,,
i dont have the brain for main end rn ill do it tomorrow
or hell ill do it later and then do all the main end stuff at once
yeah
for now im gonna make sure this joker works and go to SLEEP
loc_vars = function(self, info_queue, card)
local main_end
if G.jokers then
for _, v in ipairs(G.jokers.cards) do
if v.edition and v.edition.negative then
main_end = {}
localize {
type = 'other',
key = 'remove_negative',
nodes = main_end
}
break
end
end
end
return {
main_end = main_end and main_end[1]
}
end,
here's an example of a joker that adds the (Removes Negative from copy) like invisible joker
which has no other variables
saving this for later
yoink

somehow made things worse and now hovering over my joker crashes the game
like hard crash
game closes
whats wrong with this
no
tomorrow
i will figure it out
with sleep
nvm it was quantum enhancemetns
Hello friends! I'm having trouble with a joker making the game crash.
apparently it's trying to insert the object into an empty pool
and i don't know how to fix it
what's your code?
what about your rarity code
idk where the rarity code is, i'm working with jokerforge
well, the rarity on your joker is wrong, it doesn't exist
so that's the empty pool it's referring to
idk how the rarity doesn't exist
well, the rarity specified on your joker doesn't exist
likely got the wrong key
what's your mod prefix?
legendar
set rarity = "legendar_legendpkmn" on your joker
i'm doing it partially with jokerforge and i'm coming here for help and additional assistance
please note i can't actually code (see above) so please be patient with my bullshit
i see
the atlas on the joker is wrong now
by finding where your atlas is defined
it's just in the assets folder in the mod folder
should be a mention to SMODS.Atlas somewhere in your code
what's the key?
key = "CustomJokers",
on your joker set atlas = "CustomJokers" then
ok did that
i'll see if it works
well it's not crashing
but it's using the wrong texture
is the correct texture on the atlas
yes
then you need to modify the pos of your joker
i see
top left of your atlas is x = 0, y = 0
soul_pos is the same but handles the floating sprite on top of the joker
ok to give you a better sense of this i'm gonna send the atlas as a file
the textures i'm looking for are the dark cloudy sky and the red and black bird (yveltal)
but instead i'm getting the first two textures, the galaxy and the white creature (arceus)
since you have only one row, y should always be 0 on the position
the leftmost x is 0
yeah that checks out
what you want is, for the background x = 4, for the pokemon x = 5
oh so the increments are in the textures themselves, not in pixels
correct, your atlas is split in sections of px and py (which you specify in SMODS.Atlas)
i see
alright thank you for your help so far
but i have a couple of other ideas that i want to try out
if you're willing to sit through my lack of experience and general bullshit
if you don't want to that's completely ok
sure, i'll help where i can, i've never used jokerforge tho
thank you so much
alright so there's two slight tweaks that i want to do for another joker i'm working on
for this one, i already have the main ability set up thanks to someone that was helping me earlier
this one detects exactly three cards being discarded, destroys them, and replaces them with three randomly enhanced face cards
my two tweaks are as follows: i want to exclude stone cards from the enhancement options, and I want to make the message "Revived!" appear at the same time as the enhanced face cards
i feel like the first one can be done pretty easily, but i think the second one might be tricky due to the order of operations
for the first one you only need to modify the stuff passed to SMODS.add_card
you want to set set = "Base" and enhancement = SMODS.poll_enhancement({ guaranteed = true, no_replace = true })
no_replace = true will also exclude modded cards that behave like vanilla stone cards, if you only want to remove stone cards it's a bit longer
i'm not seeing "enhancement", i just see set, rank, area, addition, and seal
yeah, you have to add it
oh just paste it in between two of them
and make sure to add a comma at the end
yep made sure of that
as for making the message appear at the same time, maybe putting it in an event will do it
G.E_MANAGER:add_event(Event{
func = function()
for _, rank in ipairs({ "J", "Q", "K" }) do
local added_card = SMODS.add_card {
-- put what you already have here
}
table.insert(cards, added_card)
end
SMODS.calculate_context({ playing_card_added = true, cards = cards })
return true
end
})
card.ability.extra.added = true
actually, that will probably cause more issues
there, i edited it, that should work
ok so where in the .lua file should i paste it
should overwrite this part of the code
note I removed the stuff inside SMODS.add_card cus you modified it for the stone exclusion
I see you guys are having a conversation but uhhh
I just have one question:
why isn’t my mod appearing in the mod list
(can’t send files, on my phone sending this because of… Limitations.)
I have all the things that the .json file has in one of the steamodded examples, and even copy/pasted the tutorial for it that’s on the steamodded wiki, but it’s not appearing
if it's not appearing it's cus something in the json file is wrong
without seeing the file I wouldn't be able to know what's wrong in it
ok so you put in some text that says "-- put what you already have here"
i don't really know what to put there, could you elaborate?
does this work @normal crest
it would be this stuff, would you like me to edit the code to make it clearer
oh that stuff
where you put "version": 1.0.0"", it should be "version": "1.0.0", and you should remove the a at the end of "badge_text_colour": "ff9b69",a
thank you
so the problem was: I’m blind
and can’t type
thanks lol
ok so i put in the lines myself, but now there are a bunch of red brackets below it
that means there are syntax errors, can you send a screenshot?
…so
the mod is now loading but there is an error with my code
it is currently trying to close the atlas on the second line
I do not know why.
this is what the file should look like
you're missing a comma at the end of key = "spr"
same on name = 'cat' below
and maybe more places that i can't see in the pic
alright I'll test it and see how it goes
also it should be text = { not text: { right below the name = 'cat', line
LETS GOOOO IT WORKS
THIS IS PERFECT TYSMMMMMM
ok so next thing
i went into jokerforge and I added a new effect to one of my jokers
and i'm gonna go into the game to test it out
and i'll come back with results
ok
here's the .lua file for arceus
and jokerforge itself says it's not 100% reliable so these kinds of outcomes are expected
so the effect is that this joker wants to destroy another joker (giratina) when the shop is exited
you seem to have a blueprint effect on the joker too? it seems jokerforge didn't do that properly
and made two calculatefunctions, which shouldn't happen
oh right i forgor
the arceus jokerforge makes is unstable
i fiddled with the correct arceus file and put in the new code that does the joker destroying bit
so i'll test it out to see what happens
here's what it gave me
and here's arceus
why does testcat not have the cat sprite
(also im like 99% sure that the coords are correct
also its not giving 1 chip for some reason)
(also omg its so helpful to have it actually colored in because im just editing this in notepad lol)
cause of the y?
i have lost all faith in coders because of that one rhetorical question.
this includes myself.
lol
srsly why tho
do anyone know
in vscode how do i do text coloring specificly for smods cause i saw people with that but i dont know how to do it
theres probably an extension for it
top left of your atlas is x = 0, y = 0
ye
the pictures have 1 pixel of empty space on x and y around them
x and y are not pixels
you know what i mean
yes, and you don't know what i mean
wait no
IT WAS 2 PIXELS
im stupid
the atlas is split in portions of px and py as defined in SMODS.Atlas
x and y refer to said portions
oh so the thing i used to put the images together screwed me
kk
still dont work, its just default joker
i have a pokerhandpart which is four fingered flush but just not needing four fingers and another one thats the same but with straight and i want to make a pokerhand thats both of them but not on the same four like the image but i dont know how to do that
also how do i explain it for the run info
hello hi, i made a custom rarity but th error thingy keeps coming up, how do i fix this ?
maybe localization idk?
Is the image you sent the spritesheet.png file
ye
What does your code look like right now
SMODS.Joker {
key = 'testcat',
loc_txt = {
name = 'testcat',
text = {
"Gives 1 chip. Thats it.",
"{C:inactive,s:0.7}'omg is that inspired by jen walter from hit balatro mod Jen's 'almanac' Almanac, the one that youtubers frequently made videos about and personal favorite of the mod creator???????????'{}",
"{C:inactive,s:0.7}(its not inspired by jen walter from hit balatro mod Jen's 'almanac' Almanac, the one that youtubers frequently made videos about and personal favorite of the mod creator???????????){}"
},
config = { extra = { chips = 1 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult } }
end,
rarity = 1,
atlas = 'spr',
pos = { x = 0, y = 0 },
cost = 0,
calculate = function(self, card, context)
if context.joker_main then
return {
chips_mod = card.ability.extra.chips,
message = localise { type = 'variable', key = 'a_chips', vars = { card.ability.extra.chips } }
}
end
end
}
}
same thing as before for atlas
you have everything inside loc_txt, remove the last } and add }, before config
even then, where am i supposed to put that thing (im new sry)
(you're right)
what do you mean?
Do you have a localization file
those 2 should work read them
ok @normal crest scratch what was happening with arceus we have some debugging to do
a few things are happening with ho-oh
first, it's still giving me stone cards
and it's also destroying cards after the three-card discard
can someone please help me
For the 2nd one, after if context.discard and card.ability.extra.active then line, add card.ability.extra.active = false
But replace active with added
Cus I misread it
For the stone cards, before the line local cards = {} add
local options = {}
for k, v in ipairs(get_current_pool("Enhanced")) do
if v ~= "m_stone" then
table.insert(options, v)
end
end
And then replace the enhancement line with enhancement = SMODS.poll_enhancement({ guaranteed = true, options = options })
alright i'll see how it goes
What do you have so far
nothing really i tried but nothing worked
like i only have the parts and the poker hand skeleton
works, tysm
Can you show what you have
hmm
SMODS.PokerHandPart {
key = "flush4",
func = function(hand)
local ret = {}
local suits = SMODS.Suit.obj_buffer
if #hand > 4 then return ret else
for j = 1, #suits do
local t = {}
local suit = suits[j]
local flush_count = 0
for i=1, #hand do
if hand[i]:is_suit(suit, nil, true) then flush_count = flush_count + 1; t[#t+1] = hand[i] end
end
if flush_count == 4 then
table.insert(ret, t)
return ret
end
end
return {}
end
end
}```
SMODS.PokerHandPart {
key = "straight4",
func = function(hand)
local ret = {}
if #hand < 4 then return ret else
local t = {}
local IDS = {}
for i=1, #hand do
local id = hand[i]:get_id()
if id > 1 and id < 15 then
if IDS[id] then
IDS[id][#IDS[id]+1] = hand[i]
else
IDS[id] = {hand[i]}
end
end
end
local straight_length = 0
local straight = false
local can_skip = next(find_joker('Shortcut'))
local skipped_rank = false
for j = 1, 14 do
if IDS[j == 1 and 14 or j] then
straight_length = straight_length + 1
skipped_rank = false
for k, v in ipairs(IDS[j == 1 and 14 or j]) do
t[#t+1] = v
end
elseif can_skip and not skipped_rank and j ~= 14 then
skipped_rank = true
else
straight_length = 0
skipped_rank = false
if not straight then t = {} end
if straight then break end
end
if straight_length == 4 then straight = true end
end
if not straight then return ret end
table.insert(ret, t)
return ret
end
end
}```
SMODS.PokerHand {
key = "gay_clog",
mult = 10,
chips = 110,
l_mult = 5,
l_chips = 45,
example = {
{ 'S_K', true },
{ 'S_J', true },
{ 'S_T', true },
{ 'S_9', true },
{ 'H_8', true }
},
evaluate = function(parts, hand)
return parts._highest -- Temporary
end
}```
there
@normal crest
well I'm gonna assume the straight part is correct cus it's too much of a hassle to read
yea i just copied the smods straight and flush code and hardcoded four finger to 4
how would i check if it is your last hand and you have no discards remaining
if G.GAME.current_round.hands_left == 0 and G.GAME.current_round.discards_left == 0
ty
not an expert on poker hands but wouldn't your hand evaluate function just be
if not next(parts.modprefix_flush4) or not next(parts.modprefix_straight4) then return {} end
return { SMODS.merge_lists(parts.modprefix_flush4, parts.modprefix_straight4 }
That took so long to type
No, because you're missing a )
no cause that could let it be like ♠️J♠️10♠️9♠️8 instead of it needing to be like ♠️K♠️J♠️10♠️9♥️8 cause there needs to be both parts but not fully overlapping
try adding and #hand >= 5 to the condition is my first thought
Or the opposite
or #hand < 5
oh also what is next(part) in smods i forgot
next is a lua function, just tells you if a table has at least one key/value pair in this scenario
I'm sleeping, ask Somethingcom515 for help
i encountered a problem
works fine(gay clog(yes thats the name of the poker hand)) \/
works fine(flush) \/
works fine(straight flush) \/
but gives gay clog instead of straight \/
why
@daring fern(srockw told me to ask you)
Is that hand below Straight?
what tools are there for testing a mod? i wanted to look into patching overflow and need to put a perkeo and some consumables in the game.
you can download DebugPlus to be able to spawn cards and stuff from collection
DebugPlus
ty!
how do i do something if an ante passes with a joker
if G.GAME.round_resets.ante >= number
yes? i didnt really understand what you meant
or no
I'm referring to the poker hand list.
what would i replace number with
sry if im asking a lot of dumb questions im stupid
but straight flush and flush worked
The ante you want it to activate.
what if i want it to activate every ante
if context.end_of_round and context.main_eval and context.beat_boss
ty
hello?
bru
can you help me
bro
is there a rarity level so you cant get like to make it so that a joker is only attainable using debug or like given in a challage
in_pool = function(self) return false end
'shop_voucher' _booster _jokers' not instantiated befoore load is this a common error that i need to do somthing about?
i get that often and nothing has broken for me
ok thanks
this is normal
basically card stuff gets saved but doesn't get loaded normally as the cardarea for it doesn't exist yet
so the game makes one up on the spot when that happens
its only really an error that matters for modders when messing around with cardareas
with debug plus do i add cards by running some lua code during runtime? is there a breakdown of some basic functions, or should i look through the balatro source code?
hold tab while in a run
ah much easier, ty
key = 'america',
loc_txt = {
name = 'America',
text = {
"Gains {C:mult}+#2#{} Mult every ante.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)",
"{C:inactive, s:0.8}'He's on a journey! (bet you 10 bucks nobody gets this reference)'"
}
},
config = { extra = { mult = 0, mult_gain = 15 } },
rarity = 2,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult, card.ability.extra.mult_gain } }
end,
calculate = function(self, card, context)
if context.joker_main then
return {
mult_mod = card.ability.extra.mult,
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
}
end
if context.end_of_round and context.main_eval and context.beat_boss and not context.blueprint then
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
return {
message = 'Upgraded!',
colour = G.C.MULT,
card = card
}
end
}```
w h y
Get the lua extension if you haven't yet
HOLY indentation
get visual studio code
working in notepad is like taking a driver's test on a bus with a windshield that hasn't been washed in 10 years
you can do it, but it isnt easy
at very least get notepad++
No dont get notepad++
If you’re going to install something why would you choose something that also isn’t good enough
why do my jokers say "Incompatible" with blueprint, but they do work
blueprint_compat = true add this to your joker
ty
i once again ask for help with UI: im starting to understand ui in general, but no matter what i do nothing pops up or it just crashes. Currently it's the former
-# (yes that one line is the only one i have for ui rn)
Gimme ideas for jokers that you want in balatro
put america from america's journey (jk im doing that one)
yeah progress_bar is a table
and you really shouldnt modify G.UIT.ROOT directly imo
.
wait ignore that, im not used to one line ui
this tho
a table containing what? (the extension i have doesn't show all of it's options)
how do i make a joker detect another joker
if next(SMODS.find_card("j_joker")) then ... end
change "j_joker" with whatever key of your joker
ty
thats what he said
yes but vanilla jokers dont have mod prefix
any way to spawn vouchers to test them?
No, it would be j_modprefix_key
Yes
debug mod
hahahahahahahahahaha
Debug plus
I'm gonna cyberbully you for missing a prefix
(Mod)
thanks
rare something's ❌
I hit the blunder
what is ref_table and ref_value here?
No, I've used it about 3 times today.
Glad to be 3rd
o
for example, if you want the code to check G.GAME.hi, then ref_table will be G.GAME, while ref_value is "hi"
the progress bar changes whenever this value changes
what if the value i want to check is just a local variable?
How would I go about adding a new thing that affects chips gain?
You would make it global.
Does anyone know how to get shaderderivatives working?
https://love2d.org/wiki/GraphicsFeature says that they should be enabled as of 11.0 and balatro uses 11.5
return {chips = number}
Gonna phrase this a bit better, I'm not talking about the chips that get multiplied by Mult, im talking about actual scoring.
ease_chips(number)
For example, if I wanted to add something called "iMult", which gets multiplied by Chips * Mult
yeah as smtcom said, u want to make it global
save it into G.GAME if you want it to be reset on starting a new run
key = 'america',
loc_txt = {
name = 'America',
text = {
"Gains {C:mult}+#2#{} Mult every ante.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)",
"{C:inactive, s:0.8}'He's on a journey! (bet you 10 bucks nobody gets this reference)'"
}
},
config = { extra = { mult = 0, mult_gain = 15 } },
rarity = 2,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult, card.ability.extra.mult_gain } }
end,
calculate = function(self, card, context)
if context.joker_main then
return {
mult_mod = card.ability.extra.mult,
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
}
end
if context.end_of_round and context.main_eval and context.beat_boss and not context.blueprint then
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
return {
message = 'Upgraded!',
colour = G.C.MULT,
card = card
},
-- next line is 115
if next(SMODS.find_card("j_tmod_sweden")) then
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
return {
message = 'Teamwork!',
colour = G.C.CHIPS,
card = card
}
end
end
end
}```
what is it talking about
this wouldve been prevented if you didnt use notepad.......
like no kidding, you are making it hard for both YOU and US 😭
As someone who codes using notepad, I'm personally offended by this /j
I have vscode, the only issue is that its the 2017 version because i used to be a ktane modder
whats ktane
im sorry yall im downloading vscode
Keep Talking and Nobody Explodes
I had to search it up to tell If that was a prank or a game lol
here?
Oh fire
I'm gonna have to hook into actual SCORE calculation!
I'M SO SCREWED!!
Have 0 clue how to patch, so hooking it is 😔
you cannot hook this function to do what you want
👁️👄👁️
im not kidding theres like 200 lines above this, youd have a MUCH easier time patching
Oookay time to learn how to patch
y'know whats fun?
whats the name of the vscode extension for this
???
lua extension, preferably by sumneko
-# was it their name
shaders!
sum packer?
Doesnt help that said 3rd thing affecting score only starts appearing after you've bought a certain voucher 😔
love it when a patch breaks
-# it should also in theory make this really easy to modify for you
gotta love breaking ptaches
ok ye it was sumneko
-# im gonna lose it
also eremel do u think ease_progress_bar needs to rise vertically too
im losing my marbles trying to figure this out
sob
still nothing appears
you are creating a ROOT node without setting its parent anywhere
Is it bad that i made a stake thats literally just taxes
(3+ rounds of <10 dollars = game over)
I don't see anything abt that in the wiki...
-# im sorry i need so much help with this
so i put my script into vscode and started trying to fix it
everything has fallen apart
notepad worked better
i have a stake that starts a timer that increments every second, and im trying to make it appear in a bar on screen instead of just printing what number the timer is at
https://github.com/Steamodded/smods/pull/835 here, thanks :3
its just another text editor my guy
where are you using this event?
seems like your code was broken to begin with if that was the case 🤔
you cant break it that badly
my code worked fine until i added synergy with 2 cards
then everything fell apart
then thjats not vscode
fix the indentation and send it over here
im going to restart fully back from when i was using notepad, and remove the synergy mechanic, then re-implement it
if you do the same thing twice it wont give a different result just fyi
there is literally NO circumstance where notepad is better than vsc when you are editing code, unless you hate microsoft or something
-# but in that case, theres a visual studio version thats not associated with microsoft i think?
it might actually
their issue seems to be syntax related
just hold on im fixing it
the modifiers function of a custom stake (i wanted this mechanic to be tied to a stake n it was the only way i could find), im using a modified version of the timer at the bottom of the event manager smods guide
so having an ACTUAL code editor can help prevent this
if you fix the syntax its not really the same thing anymore
at least not the exact same
yes, but in the code I can see you create this event that will create a UI element and then never actually do anything with the event
i mean, true
I have more code that's in it, i just cut it out of the screenshot because, well...
ok so i put some comments and it broke more
how? i have no clue
it says <exp> expected.
on the line that the comment ends
and it errors out when i try to run it in balatro
(just says unexpected symbol near end)
look at the red line in this screenshot
i dont think you can put square brackets there
--[[
]]
this is how you use square brackets
Just make table with functions with all possible outcomes goddamn
oh
its done like that in the example code so i just did it like that
it fixed nothing
no
show another ss
ss of MORE code than that please :3
can you actually mess with the player's frame limit?
oh my god what the fuck is this
Bepis what are you doing with progress bar thing
thats not supposed to be there
i work with what i know and this was the only way i knew how to do it at the time 😭
heyyy it loaded
adapting from balala's progress bar code to make the progress ease instead of immediately jumping to a position
it's just a stake that changes one random thing?
what stake isnt tbf
-# because turned out progress bar already exists in balala
just a side note
message = "k_upg
rade_ex"
then you should do
message = localize("k_upgrade_ex")
yeah that
tangents you should be ashamed of yourself
IM TRYING TO HELP