#💻・modding-dev
1 messages · Page 655 of 1
for science, try disabling all your files in the loading routine. if this stops the bug, then reenable them one by one til it comes back
SMODS.DrawStep {
key = "elle_pixelated",
order = 69, -- hehe nice :3
func = function(card, layer)
if ellejokers.pixelated_keys[card.config.center_key] then
card.children.center:draw_shader('pixelated', nil, card.ARGS.send_to_shader)
end
end
}```
...
i forgot to make the shader
if it works ingame then you can ignore it 
If it ain't broke, don’t fix 🗣️ 🔥
it's saying you need to check if it returns nil but i dont think it does in practice
i think thats when you try to index a table that could be nil
how do i send a texture in a SMODS.Shader's send_vars
how do you make it so that this looks for odd cards in played hand instead of scoring hand ```lua
if context.full_hand then
for k, v in ipairs(context.full_hand) do
Damn I found very odd issue (or rather it was reported to me)
If start a run on Magic Deck, and it happens too fast (like on very high speeds/without animations), consumable slots cards limit freaks out
Instead of 3 consumable slots you'll end up with only 1
will do
the cost shows up as $1 and idk why
how do i debuff a card in a boss blind without a return?
there's SMODS.recalc_debuff() but how do i make it know that the card should get debuffed by this boss
okay i got it
i created a new consumable , how can i change its shop rate?
is there a way to undiscover and relock jokers 
is it a new type or is it a tarot/planet/spectral?
new type
shop_rate https://github.com/Steamodded/smods/wiki/SMODS.ObjectType#api-documentation-smodsconsumabletype
just found out its ModGlobal.lua doing it, and I think my Game.start_run hook might be the most likely culprit?
still wish I could learn how to change the background color
like the cryptid mod does
could be. comment that out and see if that fixes it
you could take a look at how cryptid does it, but I wouldn't be surprised if its easier to understand how trance does it
i'm not really sure why setting four values would invalidate challenges but
there may be a quirk of the function I'm hooking that I'm not aware of
oh, it's a : function; the arguments should be (self, args)
dammit, you're right
what a silly bug
this issue has been confusing me for almost a full day, thanks for helping
why is the numberslop mod so intricate that it's crucial to use parts of it for many high-quality mods
(talking about cryptid of course)
cause the numberslop mod came up with many interesting ways to number its slop
I don't have a definitive answer, but I think cryptid has a design space that allows for more creative ideas, even though they inevitably get sidelined by big numbers that are easier to use
bump
I've seen how they do it I just couldn't get it to work
hi I just saw this! does .current return an int of the current frame? or does it give a position of the sprite?
Is there a way I can have an effect happen after I destroy a joker?
I have a joker which creates perishable copies of destroyed joekrs
and I used ankh and it got stuck in an infinite loop
so i'm assuming its creating cards and then ankh is deleting them
leading to more creation and so on
yes 🙂
i just found it while looking at the code so its one of those two options
gotcha!
the answer is events but i feel like you should just ban your card from being created too
its eternal
are sticker's calculation functions ran for debuffed cards? it doesnt seem to be the case
they are not
hmm, some way around that? like how vanilla rental works while debuffed
...the Rental goes off before the debuff iirc?
Is there a context immediately after pressing the play hand button (before context.before)? If not, what is the function for that button so I can hook a new context onto it
if you're talking about a card perishing, rental works even on a perma debuffed card
context.press_play?
O perfect, thanks
looking through the code, seems rental is just special cased to work despite debuffs. guess I'll need a hook or patch to replicate
bump
center.unlocked = false; center.discovered = false
tried that, it re-unlocks and/or discovers on next game start
Also you would need to remove it from G.P_LOCKED
ah
You would also need to do G:save_progress()
I'm trying to do some custom UI stuff for a Joker with unlockable abilities, for which I wanna change the localization I pass through to the multiboxes. Still scouting around for how I best approach it, but I'm struggling to find where Smods implements multiboxing. Anyone have a lead I can follow up on to figure the system out?
µayo what is that screenshot
search AUT.multi_box
how did I miss the lovely file named multibox descriptions, damn
doesn't work
I'm trying to make a joker that converts all scored Kings and Jacks into Queens. However, against The Pillar, the card immediately gets debuffed after being converted. Why does this happen?
the status on a card of "played this ante" is set at the very start of hand calculation
and changing the card rank causes debuffs to recalculate for it
is there a way to prevent that?
there probably is but i dont know of a way
Set scored_card.ability.played_this_ante to false or nil?
You would save the card.ability.played_this_ante value in a G.FUNCS.play_cards_from_highlighted hook then change it back to that after changing the rank then do SMODS.recalc_debuff(card).
that makes sense, ill give that a try
hi! just to confirm, if I want to add a message to my localization file, it should be under v_dictionary right?
yes
Easy CodeSnap
Is it possible to pass along specific parameters, like a background colour, in loc_vars, so that they target a specific multibox?
is it like an ocr or is it a vsc plugin
yes, with box_colours
it checks box_colours[i]
Ah, those are separate from background_colour? I assume background_colour is the colour target for the main box and then box_colours is a table that is checked for the other boxes?
Are there other parameters to know for those other boxes? I was checking the localization page for smods, but the details of multibox are still undocumented atm, haha
reading the code i think background overrides all of them
Oooh, okay
i think thats the only one
Well, the main box gets coloured by the background_colour, and the others remain white, if no other arguments are given, is what I've seen so far
ah youre right
I'm trying to figure most of this stuff out by myself out of stubborness, but there might be a moment I break and barrage you with questions about joker ui stuff, haha
feel free
i think you have done better ui than me at this point lol
but i do remember a lot about the code
The process makes sense and I understand why it would work, but I'm not sure how to set up this hook, and how I would read that value back afterwards
It's mostly the figuring out where what gets generated and set up that's a struggle to figure out every time, haha. I'm trying to make a joker with multiboxes, where the layout and content of a specific box changes based on the joker's state, and figuring out which chunk of the ui table gets generated by which function, and what info you need to pass along is quite a challenge, haha
i somewhat recently change my material transfer mechanic to generate multiboxes if you want to take a look at that
Oh, I might, yeah. Do you have a visual example of what those look like as well?
My current attempt is to basically just generate two separate UIs and then remix them into what I need them to be, but there's no way that'll end up being even being close to the best approach 😛
you can also use your own AUT table that you populate as required
Yeah, I keep running into these strange approaches mostly because I find it difficult to figure out where an AUT table is generated and then populated, haha. But I suspect that'll be how I'll set this up in the end
I don't mind the bumping my head into weird approaches as much, right now, because it's mostly just helping me figure out the actual structure of it all
the aut tables are created in generate_card_ui, you can hook it to add your own stuff, then I've used a G.UIDEF.card_h_popup hook to handle my own aut tables with some jank nodes[1].nodes[1].nodes....
utterly confused on what causes this crash
But even before that, there's information that needs to be passed into that, right? I think I mainly just need to mess around with the localize function a bit more just to understand how and where text formatting and colouring, and all that jazz, actually happens, and how to use it properly
this
2 returns???
yeah you'd used localize to generate the correct stuff to add to your AUT table., you can see how I do some stuff for it here https://github.com/EremelMods/Ortalab/blob/d55a60f7490e8cf6fbc15bc3b1cf0a2592fe4d3e/util/functions.lua#L336
thanks jokerforge
Oh, that'll be very helpful to look through, thanks!
local oldgfuncsplaycardsfromhighlighted = G.FUNCS.play_cards_from_highlighted
G.FUNCS.play_cards_from_highlighted = function(e)
for k, v in pairs(G.hand.highlighted) do
v.ability.modprefix_old_played_this_ante = v.ability.played_this_ante
end
return oldgfuncsplaycardsfromhighlighted(e)
end
cursed aut placement here https://github.com/EremelMods/Ortalab/blob/d55a60f7490e8cf6fbc15bc3b1cf0a2592fe4d3e/util/artists.lua#L63
I think I've managed to throw together a functional thing with my approach, just now, but I can't actually properly make it look like what I'd want it to, this way, so I'll have to dig in deeper as well
Worked like a charm, thanks!
is it possible to remove the extra wiggliness and shadow from a card's floating sprite? basically just make it an extra sprite that sits perfectly over the top of the original sprite
yes
No, you should use an SMODS.DrawStep for that.
makes sense yeah
soul sprites use a drawstep that makes them move and shadowed with a shader. So you can just make a drawstep that does the same thing, but without that movement
<@&1133519078540185692>
Will keep messing with it, but it swaps out the text based on what quests it generates for you and how it matches those with the suits, so that's pretty good
hold up who are calling the mods on
joker idea: upside down joker with a name pun based off dinnerbone/grumm and the effect being based of pairs of numbers that vertically work (aces and sevens or sixes and nines)
lazy but its kinda silly
there was a spam bot
mods already addressed it
probably do aces and sevens since there isn't a vanilla related seven joker outside of odd todd for all odd numbers
Dinnerbone
Uncommon
Scored 6s become 9s
9s held in hand become 6s
how is 7 an upsidedown A (or even a 1)
some people had used ones and sevens to invert some messages
3 and E's
Good luck
uh maybe for those digital clock segmented thingys
Nono
It's another
2
5
Two and fives
i might just do something like walkie talkie
someone cooked here 😭😭😭😭😭😭🔥🔥
Someone cooked here Walter White Breaking Bad reaction hollup let him cook waltuh
?
With segmented they inverted yeah
Like 7 segments ones
On electronic clocks
i said you had a good idea
:0?
How do you make it so the description for a boss blind changes to a different description depending on the context?
probably still have a theme of dinnerbone but would do something with 2 and 5
Yayay !
Check cryptid's lavender loop or the clock ?
I hope
i dont think theres a way to do this
at least not an easy one
since blind loc_vars are run pretty rarely during an actual run
^Idiot
That's score requirements
I don't want to make it so the description changes mid-game
you should probably elaborate more on the actual use case
Like the description changes depending on the config setting
thats doabke
return key in loc_vars
yeah
Oooo
Yaya
Pretty easy
Hopeee
:3
thx
hi N
hwllo
im on vacation now so hopefully joyousspring 1.0 soon
if you see me doing more smods prs its because of that
enjoy the time off
high roller 1.0 might be soon too, got a lot of art done recently
still should probably wait for the next smods release tho lol
meta!
eremel!
do you think the canvas sprite text stuff would benefit from having an anchor property that works like UI align to move the anchor point?
probably, seems a bit minor but still helpful
i was thinking for a second maybe it could support both the UI "cm" strings and absolute positioning of the anchor by pixels, but that's probably a bit overkill
well you can use text_transform to move the anchor point manually to wherever you need it, and then text_offset to actually position the anchor
I'm just not sure whether having an easy way to move the anchor point around the canvas would be good to have
at some point i think it just becomes an unnecessary 2nd layer of positioning, but i wouldn't be against something that uses the UI strings
I'm using SMODS.change_base() to change cards during context.before, but want to recalculate the hand type to include the updated cards (I.E. Playing King King Jack Jack converts all cards into Queens, but counts as two pair instead of 4oak) How would I do this?
do it in context.press_play instead
hello modding dev
is there character limits in any places when making mods and if so, what are tehy
like names of items, descriptions, etc.
(this is for jokerforge 2.0)
not in any places i can think of
perfect
the text in names gets really small however but theres not limit
thank you N you are an unspoken hero in the balatro modding scene
you are getting an S when i make a tier list of balatro modders
along with eremel
get this man a true
wh
would smods guys get mad if my joker forge desktop app installed smods for you when it automatically places and updates your mod folder with your jokerforge mod. the license allows it but i dont want to tread on anyones toes
I'm now getting this crash because it doesn't like my use of ipairs now
you need to loop over G.hand.highlighted im pretty sure
or well
get the cards that would score with G.FUNCS.get_poker_hand_info(G.hand.highlighted)
i forget which return is the scoring hand
yea context.scoring_hand doesn't exist in context.press_play
text,disp_text,poker_hands,scoring_hand,non_loc_disp_text
how do i see what a created joker is going to be so i can force-key it to another joker if its in the food pool...
as long as it installs latest release I think that would be okay
will have it auto fetch latest release at the time lol
trying to make it not work if youre using it from the consumable slot since you could in theory accidentally use it on itself and it just would do nothing
i could make it so you have to select at least one other consumables if youre using it from the consumable slot, but i don't know how to raise the selection limit in that slot
you can change -config.max_highlighted
anyway, is the issue that you want to know how to tell if the card is in that area?
so, like... G.consumeables.max_highlighted = 2?
and yes
so that i can make sure you don't use it when its the only card selected
i was just editing it lol .config.max_highlighted yes
card.area == G.consumeables
hoooold on
nope, it was highlighted_limit
sorry
ah
works like a charm :)
ok this is really scuffed, i'll clean it up in a second, but is this the general idea?
been a minute since i did this i'm rusty as hell sorry lol
you shouldnt change the limit in can_use probably
hm
what do u reckon i do then
maybe just change it when the mod loads or something
i think a lot of mods just do that out of convenience, you can also use add_to_deck and remove_from_deck
My issue with this is you have to account for multiple copies of the card
for setting the value?
well it's not like it's adding to the value
Lets say you do this method and have two of this card. Removing one of them from deck will break the other one because highlight limit would be set back to default
I'd say just do a global set to 99
or whatever arbitrary big value
not if you check
so like change the remove one to 99 or
no in that case you would need to do it at the start of the round
you lost me sorry
start_run hook I reckon?
start run blah blah set limit to 2?
Again, probably some arbitrary large number as to not step on the toes of other mods
or technically in theory i could leave it like this and just
check if the limit is one and check if the limit is 2 respectively
but with playing cards in hand which is worse
you will still run into corner cases
hm
mods can do wacky stuff i just wouldnt wory
i guess i'll jsut leave it, kind of sounds like an edge case that i can deal with if someone ends up having issues with it
i think my keyboard is dying
lmao
if youre doing the add to deck thing make sure to check if you have another one of the consumable to avoid the problem astra said
ok i know what you mean i do NOT remember how to do that
if next(SMODS.find_card("c_modprefix_key")) then
Another idea to send N back to the SMODS PR mines with
idk how i would solve it tbh

what i do in my mod is that all object have a function that returns a number and the highlighted limit is the highest one
and it checks in update iirc
The check in add is def moot
moot?
"having little or no practical relevance"
ah
ok Dictionary Boy
ur mom
Moist
Instant Death
ah woops til u cant post tenor links
Thunk decision lmao
lol
vsc
need some ideas for some of these
and i have an idea for "convert one joker into a random joker" and it could either be a brand new spell or maybe it could fit into an existing one without an idea?
I like how you made hormones "spells"
we need an estrogen disambiguation page on the modded wiki
case and point
i should add subtle transgender references in my new mod even though it is very unfitting to be there
true and real
you should add unsubtle transgender references in your new mod because it is extremely fitting to be there
i should add unsubtle references but it still is not extremely fitting
ok but consider: male-presenting dormant joker that realizes she's trans over the course of the upgrade process
LMFAO
ok but fr tho
But what if I'm cis
Impossible in this community I know
yet here I stand 
for _, hand in ipairs(G.GAME.hands) do
...
end
Is immediately expressing a nil value, and I do not understand why I've been at this for like half an hour 😭
whats the crash, where are you using this and whats the goal?
There is no crash, because ipairs just stops as soon as it hits nil value, problem is that the code inside the block isn't being executed. Lemme get the actual block
for _, hand in ipairs(G.GAME.hands) do
G.GAME.hands[hand].original_l_mult = G.GAME.hands[hand].l_mult
G.GAME.hands[hand].original_l_chips = G.GAME.hands[hand].l_chips
end
its not an integer-indexed table
G.GAME.hands[hand] would be wrong here if you use pairs because hand is the value
it would just be hand.original_l_chips etc
the key is the _
is there a way to make sprites that are twice the resolution of normal jokers appear as the same size?
I'm making sprites that are 142x190 instead of 71x95
pixel_size = {w = 142, h = 190}?
interesting
what does this do?
it sets the pixel size to width 142 and height 190 : )
does this work for any numbers? Like if I do pixel_size = {w=3,h=4} would it stretch the sprite to be the exact same size as any other joker?
it would make it 3 pixels wide and 4 tall
ah ok, so this isn't what I'm looking for
I'm looking for a way to make higher res sprites that are visually the same size as normal jokers. Is that possible?
i believe you can do the inverse and set pixel size to normal with a big atlas
interesting
i think what the docs imply is that you don't even need to do rhat
because the default value is already the normal
which i think is true because i remember people making hd jokers without setting that
I might be looking for display size
ok
i believe it will just work if you make the atlas that size you have
neato dorito
display_size and pixel_size are for doing stuff like photograph, half joker, etc. where you explicitly want it to not be a regular card
you can also make it bigger than normal, see morefluff's wide and tall jokers
is there a way to do a message that isnt in a return?
just a message
never mind!
reference rubber ball in entropy, it's very similar
my enhancement crashes the game when trying to view it in the collection. Any ideas why?
oh wow, that's very similar lol
where do you define the Enhancement atlas
oh 🤦 that was it. The atlas key was Enhancement singular, not plural
Is the code for legendary overlays in vanilla remade
You know how how the legendary (and hologram) faces move separately from the background card
That
And in the event it doesn't have soul it shares the same movement?
they're entirely separate sprites, and you indicate the front floating one with soul_pos = { x = #, y = # } just like a regular pos
ah, soul_pos
I forgor what I was gonna say
happens
I'm guessing hover tilt is the idle movement all the cards have
bump - trying to undiscover and relock objects
yes
don't reference hologram, it specifically has some unique stuff for a unique shader and more exaggerated tilting. if you look at any of the legendary jokers, you just need to give it the x and y coordinates of the sprite on the atlas
Sprite I'm looking for the coder to overlay has an offset window for a downsized rekoj to appear in
And while they have done that they don't have separate hover tilts
So it just looks like one card with weird shadows
i mean it looks like it's supposed to be trapped under the glass, i like this better than if it had its own separate hover tilt
is there a way to set the frame an animation is currently on?
how do i edit a vanilla card effect
but im not though
ive triple checked now
this works (i stole it from saturn to test)
if i change voucher to Enhancement, observatory to mult
and then just remove the calculate function and replace it with config.mult = 5
same cras
crash
Try adding another} see what happens
You have anything else in the .lua
Maybe there's another { that isn't closed
Check all { make sure they are closed properly
doing it like this was apparently the fix
no idea why
i literally didnt change anything except defining config like this
If it works it works what I say
Lua itself just isn't built to recognize the format {config.mult = 5} like that. It thinks you're attempting to index a pre-existing table, in this case config, and thinks that kind of statement should only exist outside of a table definition. Doesn't matter if the closing } is five spaces away, or that there isn't already a config table.
whats the best way to edit localization of a vanilla card
just add it to your localization file with the correct key
how would i permantly decrease the amount of joker slots when a joker triggers
G.jokers:change_size(-1) or whatever amount
for checking triggering on other jokers check context.post_trigger
YAY thanks
what exactly are the parameters to the create_card function (not SMODS.create_card)? for example, Cryptid has
return create_card("Code", G.pack_cards, nil, nil, true, true, nil, "cry_program_2")
but I have no idea what each individual parameter should mean if I want to use this function myself
Why would you want to use create_card instead of SMODS.create_card?
function create_card(_type, area, legendary, _rarity, skip_materialize, soulable, forced_key, key_append)
you should just use SMODS.create_card tho
it's a wrapper that has the same (and more) functionality
okay, I see
here's an example of how to use it in boosters
https://github.com/nh6574/VanillaRemade/blob/453a39ee6694ff82bcf0378da37a6c77b702dbfa/src/boosters.lua#L1785
is there a guide or something to get started on modding?
oh missed the modding resources channel ill check it out
This thread is better than anything in the resource channel currently. Only reason it isn’t in there is cuz it was made prior to the channel lol
vremade has a starting guide too..
u hate me..
This is true
Despite using a nice code program to highlight stuff for me, it was only after pasting it into Discord and the formatting broke that I finally saw the duplicated brackets. I never thought I'd be helped by how badly it looks when code gets copy-pasted here. I didn't even have to hit enter to have my issue fixed. I don't actually have anyone to thank, but I'm still thankful for the help.
yeah, I was copying VanillaRemade but it didn't seem to be working, it works now
hey, what is the lose sound file name?
negative.ogg
what are you using, vscode should let you format code
changing a joker's sprite with card:set_sprites seems to reset on save and exit, is there a permanent way?
I am using vscode. For the last hour I could not see the problem here until the formatting broke and I realised there were two sets of brackets
Code?
okay I just re-added those brackets to make the example and oops I used the wrong ones. but it's just for visual ref of the problem that I couldnt tell there were two sets thanks to the formatting
ah ok
in a sticker:
apply = function(self, card, val) card.ability[self.key] = val if card.ability[self.key] then card:set_sprites(G.P_CENTERS["j_cod_redacted"])
You would hook Card:load and run it again if it has the sticker.
that works, thanks
how would i just put a ui element at any given location on the screen? id like to add a progress bar beneath the consumables area
it doesn't explain too much sadly but i would look at examples of ui box in the code
https://github.com/Steamodded/smods/wiki/UI-Guide#creating-a-uibox
god i wish we had some sort of live-updating editor for balatro ui so we could actually see what we're doing without having to restart the game or whatever
i know debug plus has watch but its not the same
ok i still have absolutely no clue how to do what i said
it says how to structure ui
but it does not say anything at all about how to make it show up in game or how to put it where you want it
you should start out by looking at functions/UI_definitions.lua in Balatro source code
you make a uibox and you can anchor it to G.consumeables
that's why i said to look in the code for usages of uibox i think it will be more clear then
you would create it when the run is loaded
i have this one that starts hidden above jokers for example (thats why offset is -5)
going through fixing up some commands
if is_on_cooldown() then return end
if G.STATE ~= G.STATES.SHOP or not G.shop then return end
play_sound('coin1', 1.5, 0.7)
if G.shop_jokers and G.shop_jokers.cards then
for _, card in ipairs(G.shop_jokers.cards) do
card.cost = card.cost + 5
end
end
if G.shop_booster and G.shop_booster.cards then
for _, card in ipairs(G.shop_booster.cards) do
card.cost = card.cost + 5
end
end
if G.shop_vouchers and G.shop_vouchers.cards then
for _, card in ipairs(G.shop_vouchers.cards) do
card.cost = card.cost + 5
end
end
end```
how can I make this effect perma
what is self referring to here
it inscrease but after a reroll or a new round prices return
probably should also hook that then yeah
there's also SMODS.current_mod.custom_card_areas now which might work for you (it just gets called when the run is created its not exclusive for areas)
ah but consumables might not exist there.. so yeah the hook is probably better
what does the 'i' in align = 'cmi' do? i understand cm is center middle but the guide doesnt say anything about an i
if self.alignment.type_list.b then
if self.alignment.type_list.i then
self.role.offset.y = self.alignment.offset.y + self.role.major.T.h - self.T.h
else
self.role.offset.y = self.alignment.offset.y + self.role.major.T.h
end
end
if self.alignment.type_list.r then
if self.alignment.type_list.i then
self.role.offset.x = self.alignment.offset.x + self.role.major.T.w - self.T.w
else
self.role.offset.x = self.alignment.offset.x + self.role.major.T.w
end
end
if self.alignment.type_list.t then
if self.alignment.type_list.i then
self.role.offset.y = self.alignment.offset.y
else
self.role.offset.y = self.alignment.offset.y - self.T.h
end
end
if self.alignment.type_list.l then
if self.alignment.type_list.i then
self.role.offset.x = self.alignment.offset.x
else
self.role.offset.x = self.alignment.offset.x - self.T.w
end
end
in Moveable:align_to_major()...
ah, so it's a Moveable thing
im sure this would be very enlightening if i could make any sense of it lol
man, looking it up in engine/ui.lua was a mistake
i think it means it aligns from the center instead of the corner?
Assuming so.
ok clearly my code is fucked or missing somethnig but i cannot comprehend what
the bar is not showing
did you try after the reference
everything else looks correct to me but G.consumeables doesnt exist before the function runs afaik
good point
ok
so
i may be
a fucking idiot
i am not
loading. this file
let me try again with the file actually fucking loaded this time
is there an smod to create a skip tag lol
if is_on_cooldown() then return end
G.E_MANAGER:add_event(Event({
func = function(self, tag, context)
if context.type == 'shop_final_pass' and G.shop and not G.GAME.shop_free then
G.GAME.shop_free = true
if context.end_of_round and context.game_over == false and context.main_eval and context.beat_boss and G.GAME.shop_free == true then
tag:yep('+', G.C.GREEN, function()
if G.shop_jokers and G.shop_booster then
for _, card in pairs(G.shop_jokers.cards) do
card.ability.couponed = true
card:set_cost()
end
for _, booster in pairs(G.shop_booster.cards) do
booster.ability.couponed = true
booster:set_cost()
end
end
return true
end)
tag.triggered = true
return true
end
end
G.GAME.shop_free = false
end}))
end```
losing my fucking mind trying to get this to work lol
trying setup a command that makes the next shop free
but I might as well just make it simple and create the skip tag instead lol
add_tag({key = 'tag_coupon'})
what
note to self
watch lua does not work very well with ui definitions
i get the feeling i should be clearing out the ui between runs but idk how
it its attached to G.consumables it shoul get destroyed im pretty sure
anyways those grey corners are really bugging me time to figureo ut how to remove those
oh i see why its there
modding my first joker was annoying now time to make more and make it even harder lmao
not working
i've tried with and without tag_
Wait I think I found the issue
yup
somehow I accidentally borke a line of previous code
when scrolling

how do I detect a sticker being viewed in the collection? trying to avoid running SMODS.debuff_card in that case since it crashes the game
why tf is it gray now
if card.area.config.collection
getting that area is a nil value. tried it with self instead of card too
apply = function(self, card, val) card.ability[self.key] = val if card.ability[self.key] and not card.area.config.collection then
Yes, the sticker is applied before it gets emplaced into an area.
It should be modprefix_BANKRUPT when playing it.
oh I forgor....
there we go
also does attention_text support changing the colors text?
You mean the text's colour?
colour?
tried it didn't work unless it doesn't support certain coloiurs
wanted to use the dark_edition color
Yes, it doesn't work for gradients.
ok why tf does it have grey corners i cant figure out what element im meant to be giving no_fill
ive even tried giving the progress bar itself no_fill=true
have you tried colour = G.C.CLEAR
wow ok yeah that fixed it thx
so context.after doesn't run after a discard; is there like, an equivalent thing somewhere?
i want to set a flag during context.pre_discard and then unset it once the discard is done
how would i update the info text on a create_option_cycle?
You’d do that under the options attribute I believe, which taks a table of strings
context.hand_drawn
nope
that's the list of options
info is the description below the button
Ah I see
Created when playing a joker that turns all face into stone as well as Pareidolia
You would probably do that thru a callback function then
i'm trying that but the callback args seem to not do anything when written to
Try setting the text to a global variable and update that thru the callback. I bet it’s getting reset on subsequent calls on the cycler
issue on latest steamodded where v_dictionary entries formatted as {"text"} instead of just "text" crashes when used in a message through localize
Thank ya
still nope
May I see how you’re trying to do it?
I think what’s happening is the values of the cycler are being passed but they’re only references, not the actual info held by the cycler. I’m not sure how but if you could find a way to access the cycler itself in the callback, it’d probably be what you’re looking for
yeah
i tried putting a func callback in the parent but i couldn't figure out the path to the text
Hmm
is it possible for a progress bar's max to also be defined by a ref_table and ref_value? i would have it just be set to like 1 and have the ref value be value/max but i dont see an easy way of doing that either
check the last discard? vanilla does that for something
context.hand_drawn wont work if the discard doesnt draw cards
have you seen that old smods pr that implements a progress bar
i do not concern myself with smods pull requests
if its not in main smods i do not give a care
you could have said no..
this might help what youre doing https://github.com/Steamodded/smods/pull/835
or this one https://github.com/Steamodded/smods/pull/614
We miss you bepis 
so i should patch these in myself and use them as a baseline for a dynamic max
yeah i can prolly do that
i decided to just put my own text below it
you can't even read it with the shader on lol

Fair enough lol
ok i copied over the ease_progress_bar patch into my own toml and now when i set the value of the bar it just. freezes the game for a sec and then sets the value instantly
maybe im not setting the ease correctly? idk rn its just set to 'linear' just to see if that would work
do main_end work with multiple boxes
like does main_end attach itself to the lowest box or the first box
aw
is there a way around that
or am i better off defining custom infoqueues
and if so how do i do that
custom infoqueues is just putting a description in any existing category under an arbitrary key in a localization file
:0
and then do info_queue[#info_queue+1] = { set = <category>, key = <key>, vars = {...} }
i think
if you want the info queue to have ui in it then you would need to make a dummy center
if i were to make mutliple jokers in one mod (for example: Failures just has the custom joker json and main lua file, assets folder) how can i branch out to multiple jokers without breaking it
You would define another joker in the main.lua
is there a way to hide the rarity and mod badge of a joker?
what do you think of this placeholder joker art
set_badges = function(self, card, badges) EMPTY(badges) end
Hi! I made a deckskin steammodded mod for personal use based off the code for the Bocchi the Rock! Deckskin (specifically the hearts one). Decided I wanted to post it on Nexus, so I’m trying to redo the code to match the steammodded template made by Wilsonthewolf. But I’m a little confused about the icon_lc.png and icon_hc.png in both the 1x and 2x folders? Where are these images displayed in game? Do I need to edit my sprites/make new ones? Definitely more of an artist than a modder, so I’m having trouble understanding from the code. I tried to find other mods built off the example but I could only find mods with lc and hc pngs, no icons. This is the first time I’m dipping my toes into modding so sorry if I’m being stupid, ik I did this super backwards and should’ve just used the template from the get-go lol :’D
https://github.com/Steamodded/examples/tree/master/Mods/DeckSkinTemplate
that's for the mod icon in the skin selection menu, it's optional
i think?
ohhh okay!! that makes sense, tysm
Ohhh alright, thank u ! sorry i didnt see that 😭 /gen
hmm looking at the code it seems like it is optional
although the documentation says otherwise
how would i make a dynatext that reads "Media: (G.GAME.hexg_media)/(G.GAME.hexg_max_media)" that can update live?
you would have to make each changing part into its own text and then instead of a string use { ref_table = G.GAME, ref_value = "hexg_media" }
(or have all the text in G.GAME too so it's just one object)
is there a way to have the dynatext get its text from a function so i can just define a function that returns the required text
i dont think so
im pretty sure you can do { ref_table = setmetatable({}, {__index = function() return ... end}), ref_value = "doesnt matter" }
is "Xchips" a valid word?
like Xchips = card.ability.extra.xchips
Because I really thought it would be that easy, but it's not triggering.
No, it's xchips
Since I was using Xmult with the capital and that works I am surprised. But that fixed it! Thank you.
weird
that should also be lowercase
No, Xmult works.
why aren't my blinds animating?
-- Blind atlas
SMODS.Atlas {
key = "blinds",
path = "blinds.png",
atlas_table = "ANIMATION_ATLAS",
px = 34,
py = 34
}
missing frames parameter for atlas
@next timber you can see some progress bar stuff I've done before here https://github.com/Balatro-Potato-Patch/Hot-Potato/blob/9709c9045ab34514af643f5d9d13089d7babd428/Pissdrawer/new_shop.lua#L1432
uses the vanilla implementation
eh ive already added in the patch to make them ease and it works fine, and i dont need much more modification to make the max dynamic
if it works it works
ok yeah like 5 minutes of work just fixed the max issue
lol
if i want an infoqueue to look like the description of a tarot card do i need to put it in the tarot category
and also how do i call custom infoqueue? am i calling the key wrong
Anyone know how to disable the play and discard buttons, plus the ability to manually rearrange cards?
Hook G.FUNCS.can_play and G.FUNCS.can_discard and:```lua
for k, v in pairs(G.hand.cards) do
v.states.drag.can = false
end
media offline jumpscare
oh damn those are some crispy edges
how do you smooth them out like that, my joker is sharper than a philips razor
ah so its not from scratch lol my bad then
debuff effect results in some funky layering
can stickers be rendered on top of the debuff effect?
Hello green joker
How would I go about making an animated joker with an animated floating sprite?
the latest version of smods makes this very simple, you can just make each sprite use an animated atlas
each frame for one animation should be set up as an individual sprite, all in a single row
Ah, very nice!
I should look at making that not require them to be on a single row
image too big i think? how big is PhantaMiscAnims5.png?
does it happen consistently?
every time i see this it just goes away on its own after a restart
yea if the image and timing is changing you probably just have too much other stuff in RAM at the moment
sob???
i might have to disable some things then 😭
this computer apparently isn't built for balatro
well, either that, or it's the new mod i'm making 😭
maybe i'm like, taking up way too much memory
it's possible, though i really don't know how it would be
hmm no, this is now happening without that mod enabled
Dependencies : [Steamodded >=1.0.3, Amulet >1.0.2, >=64GB VRAM]
recommended dependencies when
i'll try reupscaling everything
💔
wait that might be the wrong number
hold on
could be this one
whatevs
yeah not a clue 😭
-# ...integrated graphics?
Oh no.
...yeah, I feel like you are running into the actual VRAM limits. 
Ghost what in the hell did you DO 😭😭😭😭😭
what noooo
Consider rebooting laptop and trying again-
IDK DKJFNGJKFDN
yeah i guess i should reboot then
i haven't done that in like. a while
a month maybe
what are the keys for the enhancements?
hey at least i got my animation thing working!
...you did not at least shut down your laptop for a whole month?!
HDD?
yep
I am sorry. 
😭
disc go spinny
holy 😭
You best be backing up your stuff every now and then...
gah i really should
-# ...and for your own sake, try to get at least a ~256GB SSD or something in the laptop...
at least i use github
-# I know prices are high, but 128GB feels a bit small for current times.
-# fair enough
this does not apply any previous stakes, is something more needed?
applied_stakes = { "gold" },
oh no 😭 it's restarting
applied_stakes = { "stake_gold" },
prefix_config = {
applied_stakes = { mod = false },
above_stake = { mod = false }
},
:3
but i might just be caffeinated and paranoid
:3
At least restart daily... or once a week. 
alright! restarting.
hell yeah
mucho gracias
can you change/remove the texture on the soul layer of a card? set_sprites seems to only change the background layer
Code?
apply = function(self, card, val) card.ability[self.key] = val if card.ability[self.key] then card:set_sprites(G.P_CENTERS["j_cod_redacted"]) elseif not card.ability[self.key] then card:set_sprites(nil) end end,
still has soul layer
what I probably should’ve asked first is how do I make a new card modifier category 💀
wdym
in vanilla, there’s enhancements, seals, and editions. I want to add one more
you can extend SMODS.Center (like enhancements and editions) or SMODS.GameObject (like seals and stickers)
you can also just extend SMODS.Sticker, which is probably easier in the short term but requires you to handle some jank in the collection
(paperback does that with their paperclips)
Where's the code that draws cards when opening a booster?
I can't seem to find where it shuffles the deck for that
extending stickers would also likely break when I make stickers not shit to work with
merci
and it shuffles at end of round iirc
true
i should probably look into overhauling paperclips to not be jank like that
I see
there are plans for a SMODS.CardModifier down the line
good to know
cool beans
I'll probably use center, since it'll be something similar to enhancements
How would I make a tag that makes a spectral card show up in shop since there doesnt seem to be a way to do consumables since store_joker_create is the one thing that exists for creating cards in shop
why are none of these available on smods wiki 😭
theyre outdated and nobody should need to define a center directly
it was replaced by API Documentation iirc
I'm trying to destroy a certain card in my hand using SMODS.destroy_cards() during context.end_of_round, and it destroys the card, but no animation is played and its not obvious that it gets destroyed. Should I Juice the card, or is there a way to add an animation to it?
Code?
Try running a tag apply loop in a global mod calculate under context.modify_shop_card
the idea is that the joker "eats" the lowest card in hand at the end of the round, like how raised fist chooses its target
if you use smods your mod must be gpl3 compatible
ah kay, so the GPL3 licence then
How can I check if a card has a debuff from a specific source? Matador currently triggers on cards debuffed by stuff from my mod and I wanna prevent that
also its against the rules to post it here without a license
is there a function that outputs the numerical value of a card, making a distinction between faces, or will I need to make that myself
oh ^^;;;;;;
okay i'll go back through and licence the others
you can assume they're the same until then
:get_id ?
or the chips
it seems to be random
I played a hand with a 9, 8, 7, 6, and 5 and somehow got 13 as an id
its not
index
previous ID
current ID
2 through 10 is 2-10, J is 11, Q is 12, K is 13, A is 14
code?
if context.modify_scoring_hand and not context.blueprint then
local p_rank = 999999999 --- if your card exceeds this value what are you doing
local good_hand = true
for index, value in ipairs(context.full_hand) do
print("index check")
print(index)
print(p_rank)
print(value:get_id())
if not (p_rank >= value:get_id() or (p_rank ~= 14 and value:get_id() == 14)) then
good_hand = false
break
end
p_rank = value:get_id()
end
card.ability.immutable.do_scoring = good_hand
end
This is what's happening, I think the card does have an animation but it goes away too quick
wait actually this is wrong
the code from the ss has the print checks in the if statement
if the played card is a king then thats correct
it was 9, 8, 7, 6, and 5
there was no king held in hand either, nor 2
lemme do it again with the updated code
add a delay maybe
with delay(secs)
code?
same as above
Will delay scale with game speed? Or can I pull the game speed value and multiply as needed?
only difference between the two times was the print statements being in the if
it does iirc
can i see that one
if context.modify_scoring_hand and not context.blueprint then
local p_rank = 999999999 --- if your card exceeds this value what are you doing
local good_hand = true
for index, value in ipairs(context.full_hand) do
if not (p_rank >= value:get_id() or (p_rank ~= 14 and value:get_id() == 14)) then
print("index check")
print(index)
print(p_rank)
print(value:get_id())
good_hand = false
break
end
p_rank = value:get_id()
end
card.ability.immutable.do_scoring = good_hand
end
can i see the crash log
okay so it actually prints correctly this time
Oops! The game crashed:
main.lua:2313: [SMODS foo "main.lua"]:356: attempt to call method 'get_id' (a nil value)
Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-1224a-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.9.0
Platform: Windows
Steamodded Mods:
1: Foo54 Mod by Foo54 [ID: foo, Version: 1.0.0]
2: Card Sleeves by Larswijn [ID: CardSleeves, Priority: -10, Version: 1.8.0, Uses Lovely]
3: Talisman by MathIsFun_, Mathguy24, jenwalter666, cg, lord.ruby [ID: Talisman, Version: 2.7, Uses Lovely]
4: Vocaloid Deck by nolo33lp [ID: vocaloiddeck]
5: Handy by SleepyG11 [ID: Handy, Version: 1.5.1o, Uses Lovely]
6: Cartomancer by stupxd aka stupid [ID: cartomancer, Priority: 69, Version: 4.17c, Uses Lovely]
Lovely Mods:
Stack Traceback
===============
(3) global C function 'error'
(4) Lua field 'update' at file 'main.lua:2313'
Local variables:
dt = number: 0.0260962
success = boolean: false
msg = string: "[SMODS foo \"main.lua\"]:356: attempt to call method 'get_id' (a nil value)"
(5) Lua function '?' at file 'main.lua:944' (best guess)
(6) global C function 'xpcall'
(7) LÖVE function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 915 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(LÖVE Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(LÖVE Function)' (defined at line 355 of chunk [love "boot.lua"])
why is it so small
no clue
Which line is line 356?
oooooh
nvm it works
errors from a different context
ah found the issue
I forgot to reset my config between hands
oh, then how do I extend smods.center?
You can't put cards in other cards.
you can
but if they exit the run it clears the data
this works fine since it stores at the start of playing the hand and clears after the hand
You still shouldn't put it in card.ability.
You should put it directly in card
Because if something tries to copy_table that card.ability the game will crash without a crash log or it will crash with a stack overflow
If I redefine a vanilla localization entry, do I have to copy the whole thing or just the parts I edit?
You have to copy the whole thing.
merci
@wintry solar may I ask, why CardArea does not call self:handle_card_limit() on init?
Because of this, if you change CardArea's limit via old methods (.config.card_limit =) but before CardArea:update(), slots will break
Specifically, I encountered a bug in scenario where creating G.consumeables and then changing card limit via Crystal Ball given by Magic Deck in a same frame will set consumable slots to 1 instead of 3
Calling self:handle_card_limit() after cardarea is setted up removed this weird behaviour
wondering, what kinds of animation can SMODS do?
none of them
but this doesnt mean that card limit should not work properly on first frame
there is no reason it doesn't call it
I see
are you doing some weird patch stuff to achieve this?
No, accidentally was discovered by one dude, was achieved with very high game speed values when starting a run on Magic Deck
Or, when animation skip was used which basically makes all events non-blocking, i.e. all of them happened instantly
As result, creating G.consumeables and applying voucher happens on same update loop and desync happens
I see
incredibly basic question but how do you make a consumable show a message when it's used
nvm remembered attention_text exists
@red flower and the only way i can think about doing it (injecting some code that'd flag the joker into the function).. wouldn't work until the joker called the function to begin with 😭 which woudlnt work for my purposes
💔 i understand
for clarity, i'm working with a joker that acts as 2 copies of the last sold joker-- this does not work at all for blueprint, assumedly because the initial joker itself calls SMODS.blueprint_effect
weirdly enough it does work with brainstorm which i thought was a blueprint-like
they both work the same way so it's probably an issue with blueprint getting the joker
brainstorm gets a fixed position
would you like to take a look at the calculate cod°?
yeah no problem
calculate = function(self, card, context)
local can_copy = function (c)
return c.label ~= card.label and c.config.center.blueprint_compat
end
if context.check_eternal and not context.blueprint then
local can_shake = false
if G.jokers.highlighted then
local selected_card = G.jokers.highlighted[1]
can_shake = selected_card and can_copy(selected_card)
end
if can_shake then card:juice_up(0.25, 0.25) end
end
if context.selling_card and can_copy(context.card) then
G.GAME.j_o_y_last_sold_joker = context.card
end
if G.GAME.j_o_y_last_sold_joker then
local joker = context.blueprint and context.blueprint_copiers_stack[1] or card
local ret = SMODS.blueprint_effect(joker, G.j_o_y_last_sold_joker, context)
local ret2 = SMODS.blueprint_effect(joker, G.j_o_y_last_sold_joker, context)
if ret then
return SMODS.merge_effects{ ret, ret2 }
end
end
end
the entirety of it is not really necessary but here it is anyway
yeah if a joker is sold it can't find itself in the joker slots to see what it has on its right
this is an issue with any joker that wants to find its position rather than just a bp issue
ahhhhh
that makes sense
is the card thats being sold still in the player's jokers when the context is true
im not sure but im guessing not if that's what happens
it is
i see
i'll see if calling blueprint_effect on the joker in the selling context and storing the result can work
it may cause a problem if say, the blueprint card is positioned to the left of the joker that's doing it but
better than nothing
ty again !!
To do a joker that halves probabilities do you just gotta edit oops' code to double the denominator instead of the numerator or is it not that simple
the result will just be the joker copied by blueprint in context.selling_card
yeah

youre right
it doesnt work 😔
Does anybody have a good starting point for making my own card skins?
like friends of jimbo or for jokers/consumables/others
I'm aiming to make face cards look like some of my favorite MTG cards
How do I check if a consumable has been sold in a remove_from_deck function?
you don't
instead, use context.selling_self in the consumable's calculate function
Where's all the context checks so I can look for selling it and it being destroyed?
documented on the calculate function page
https://github.com/Steamodded/smods/wiki/Calculate-Functions
there's no specific context for the card being destroyed, but you can use context.joker_type_destroyed (it triggers on all non-playing cards, not just jokers) and check if context.card == card
Is there a function to apply a random sticker on a joker?
what do i put in loc_vars again to have the text color change based on a variable
I have a joker that converts all Kings and Jacks into queens, but it doesn't trigger properly with Splash, presumably because it checks for hand type compatibility using G.FUNCS.get_poker_hand_info(). How would I make this compatible without specifically adding a check for if the player has splash?
i dont think thats possible with the way youre doing it
oh wait no it should work fine
is there possibly ANYTHING wrong with this that im too stupid to spot
no, i was confused by a custom function in jokerdisplay
I'm fine with changing the code however much to get it to work as long as I can still do it within context.press_play
yeah the problem is that splash evaluates later
you would need to copy what G.FUNCS.evaluate_play does
i wouldnt write it like that but assuming lastsuit is correct then this seems fine
but also just do an if for the colour lol
im too stupid for this
the reason I'm doing it within context.press_play is so that the poker hand can update after the cards are converted (I.E. Queen Jack Jack turns into Queen Queen Queen and considers it a 3oak. Should I just add a check if the player has splash then?
yeah, i know
you should specifically do the G.FUNCS.evaluate_play thing because other jokers can have splash-like effects
like this
do suitless cards return nil when checking for .base.suit?
no it returns the base suit
is there a way to check where its either only 2 suits instead of all?
two specific ones by doing is_suit
any two you would probably need to check every suit with is_suit
How to I make a .lua file, and is there a template I can edit in an art program?
Disregard I am stupid
Coding in an art program sounds like a concept for someone's coding channel video
is there a way to call the calculate function of a different joker
is it just card:calculate(card, context) or would it be something else
G.P_CENTERS[other_joker_key]:calculate(card, context)
note that it will assume it has all the values and stuff of the other joker
it also probably doesnt work on vanilla jokers
ah
is there a way to do that with vanilla jokers 😭
noootttt reallyyyyy
you probably can but it seems like itd be really annoying to do
how do i get whether an achievement is unlocked
how does smods reptitions work then 😭
What's the prefix for stickers in reference to G.P_CENTERS
stickers aren't centers and do not exist in G.P_CENTERS
SMODS.Stickers is the table you're looking for i think
Thank you
how do you get the value of chips needed to win the blind?
It's certainly progress? Now it just crashes instead of showing nothing lmao
Might as well drop this here too. I ran a print under the conditional and it did print btw. I have a very, very similar method that works perfectly fine on a joker, but for the numerator instead
calculate = function(self, card, context)
local isFaces = true
if context.individual and context.cardarea == G.play and not context.other_card:is_face() then
isFaces = false
end
if context.joker_main and isFaces then
return {
xmult = card.ability.extra.xmult
}
end
end
``` why is this not working?
idk i cant code
sorry for the no help
👍
brilliant
context.individual and context.joker_main are never true at the same time
that's good
it means that your local variable will always be true because there is no context.individual before context.joker_main to set it to false
local?
like
like local thu
bro's a tier 1 ragebaiter
yes, actually
oh
what's the context that's after everything else called?
lmao
for scoring -- context.final_scoring_step is always last
that's the one
what's the effect in mind here?
thank ya kindly
good question lmao. I'm positive this is not the best way of doing it.
but this is what I'm going for
so it's checking if any of the cards are not face cards, and not returning the xmult if 1+ cards are not faces
supposed to be*
then what i think you should do is in context.joker_main simply check if all cards in scoring hand hand (which you can find with context.scoring_hand) are face cards, and then return if that's true
is context.scoring_hand a list?
can I just do context.scoring_hand[1] to get the first card that's getting scored
@umbral zodiac ^ sorry for the ping
bones
try it and see
(but yes)
the wiki says this contains a table of the cards that score but idk if that's a list, or if I have to access it a different way
ah ok
try looking at vanillaremade, hanging chad does this
how do i get a joker's name?
localize({type = 'name_text', key = 'j_modprefix_key', set = 'Joker'})
ty
tho i specifically want a joker card's name, and ik that loc_vars can change the key
nvmd i got it
something like
local vars = {}
if type(joker.config.center.loc_vars) == "function" then
vars = joker.config.center:loc_vars({}, joker)
end
local name = localize({type = 'name_text', key = vars.key or joker.config.center_key, set = vars.set or 'Joker'})
damn
Ah drat, will this need a toml hook?
It didn't work
hold on i made some quick changes that i wanna test
yeah nah
Patch it is then
_ _
your problem is that you're returning true/false?????
why're you doing that
what
G.FUNCS.can_x never returns true/false
They remove the button and change the colour of the UIelement
oh right
Look at what they do in vanilla
they did
It's G.GAME.blind.config.blind.key