#💻・modding-dev
1 messages · Page 374 of 1
those are basically your edge cases for removal
classic medal
G.playing_cards
thank you 🫡 this would go in the jokers calculate function right
otherwise, loop through G.deck and fix all the glass cards
nope, those are separate from calculate
and comparison with the regular medal
Is there any way to make imgui work w/ balatro mods? Otherwise, is there a basic UI library or smth? Making a personal project, too lazy/not that good at modding to make an actual ui
i might be crazy but where on earth are the variables for things like lucky card odds? they seem to exist according to the localisation but theyre not used ingame and i cant find where theyre defined
probabilities.normal is probably 1/1, so dividing by 5 makes it 1/5 for the +20 mult i'd guess?
not that good at balatro modding but i've looked into a lil, and thats my best guess
nah #5# refers to the 5th variable in config.extra
no i get that
but with everything else they use a variable (like self.ability.extra.odds)
a variable like this seems to exist for lucky cards but i cant find it
which would be defined somewhere mysterious and hidden
they don't exist, they're hardcoded in the localization too
i dont think i follow
they are hardcoded in loc_vars too
oh where is this?
common_events.lua
and since its hard coded, how would i access that as a variable
How could i get the most abundant suit
or like, get the amount of cards in a suit
loop through G.playing_cards and count them
im going to but when i do, would it be like self.loc_vars[5]? (this is my first time patching and messing with vars like this)
sorry if this is a question with an obvious answer
yea, I mostly just dont know where I could place this in my code
SMODS.Blind {
key = "SmearBoss",
loc_txt = {
name = "The Ugly",
text = {
"Debuffs Most Abundant Suit in Deck",
"(#1#)"
}
},
atlas = 'Bosses',
pos = { x = 0, y = 1 },
boss_colour = HEX('9f805e'),
debuff = {
},
boss = {
min = 1,
max = 10,
},
loc_vars = function(self)
return { vars = {} }
end
}
no, when you patch you're rewriting the code
you would add the values to the config yourself and then change loc_vars
you would do it in loc_vars for the description and in calculate/debuff_card? for the effect
oh, so just write the code twice?
yeah
oh
i mean you can make a helper function
ngl, i thought functions were only for jokers
you can add any functions you want to the code
oh wait
i mistook it for events
so, if i want to make it a function, i could give it a name and have it be name = function()
or would i just have it be function()
so to clarify i have to
- add the vars to the config
- make the localisation use those
- do the same for the lucky card calculations
yes
okay thank you very much
im not sure why smods doesn't do that already
wait maybe it does i dont even know how to check
i dont see it in the lovely/dump so it doesn't seem like it
fairly confident theres no unclosed brackets here
you're missing a comma
please get an editor with syntax error highlighting
vscode is scary 💥
vscode is a text editor
💥
yeah actually looking at it, it seems to change code in that part but not that bit specifically
like it literally looks less complicated than notepad++
if i were to make a patch to add these variables, should i make a push/pull request
you could
i feel like they would want the entire logic replaced by take_ownership tho
i have no idea how that would work in this scenario
is this smth that would just be better to suggest or mention in their discord 😭
i think so
I’m not sure if smods should make lucky cards easily accessible or not tbh
i havent tested but it seems hardcoded
if it's not then that's an easier solution to @spice wadi 's problem
got vscode. i might be stupid but it doesnt seem to be highlighting any syntax errors
wait, is debuff{} only called once?
im reading about how take ownership works, and im not sure how helpful it would be as i would still have to rewrite things like the calculate function
id rather do a patch tbh
for the blinds
Trying to make a second button like the sell button, and I have all the code exactly the same as vanilla, its just in a different child. Every instance of "use_button" was edited to have my button aswell with the same functionality
bc ive got a list of what suits should be debuffed but it just isnt debuffing them
plus it isnt crashing so i dont get any info from it
oh right, heres the code
alright got it not crashing
the add_to_deck and remove_from_deck arent doing anything though
this is correct isnt it
no
you don't want to take_ownership
you want to change the value directly in the card
right
wait, i should check, can the boss's debuff = {} debuff more than one suit?
Anyone know if there's a way to get imgui, or an imgui-like library, to work as a mod? Working on a personal project, tried love-imgui but can't get it to render
this goes up 17 times after one round...
would it be possible to check if a card isnt in the deck by doing something like
context.cardarea != G.deck?
add and context.main_eval
you can check card.area ~= G.deck
~ would be the not in that statement?
yes
this might be a stupid question again but why do none of these result in matches even tho i copied the code directly?
hiyas, stumbling my way through making a music mod for my own personal use and am mostly figuring it out butttt
im having trouble figuring out what i would check to see if im in shop for the select_music_track function
at least i assume that is how i would do it
(also sorry to dump a question on top of the other questions)
hmm weird looks fine to me
Hey guys, I'm having some trouble with a copy effect joker. Functionally, it's almost exactly the same as blueprint but it copies both adjacent jokers, except it can't be copied itself (so it doesn't crash from a recursive loop). The copy effect works fine, however the joker is also supposed to get the sell cost of the joker it's copying and subtract that from your money whenever it returns that jokers ability. This works fine for any joker that works during scoring, like any flat mult or chip jokers, retrigger jokers, or on card scoring jokers. However, this does not work on jokers whose abilities function outside of a blind, such as cartomancer, hallucination, even certificate. Does anyone have a suggestion on how I could fix that? lmk if you'd like to see my code and/or a clip showing the issue
Steam Modded heavily rewrites somee evaluations. You should look at the lovely directory to see how the code really looks after other things have finished patching the base code
To be specific, I thought those mods would work by overwriting the directory of the game. Not so! It actually patches the code on startup when the game runs. So the actual running code may not resemble the balatro source directory
"lovely/dump/card.lua" right?
just wanna make sure im looking in the right places
Yes! and I often turn off match_indent. That makes it even harder to get the regex replacement to work
great catch! I didn't notice it either
damn
Has anyone here posted about their mod on Reddit? I was looking for some more folks who might be willing to test it and let me know what they think 🙂
Anyone here know how I could have something like imgui for my mod with Steamodded?
How do you detect the joker key? (just curious)
for draw step?
like a spesific joker?
idk why i made baseball card the giant enemy spider
I am so happy about how this booster looks
Super overkill but this is how I do it to apply shaders to certain decks
Alright but when I can refer to a joker how is this supposed to be? currentBack.effect.center
But yeah good to know
The joker would be like this
SMODS.find_card("j_Fox_IncrementalHermie")
if next(SMODS.find_card("j_Fox_IncrementalHermie")) then
local joker = SMODS.find_card("j_Fox_IncrementalHermie")
ty everyone here who helped me i finally got that stupid patch working and lucky cards are variable controlled now 🤩
SMODS.find_card("key")[1]
Here's what I've at one point had at first or tried to.
I'll try that eventually but yeah.
i was scrolling quickly and for a second i thought the card next to it was freddy
why is my edition sound crashing the game??
no that's bald bull
I tried this but it didn't show the booster shader on the necromancer card.
SMODS.DrawStep {
key = 'joker_shine',
order = 11,
func = function(self)
if self.ability.set == 'Joker' and self:should_draw_base_shader() then
local joker = nil
if next(SMODS.find_card("Necromancer")) then
joker = SMODS.find_card("Necromancer")
end
if joker then
self.children.center:draw_shader('booster', nil, self.ARGS.send_to_shader)
end
end
end,
conditions = { vortex = false, facing = 'front' },
conditions = { vortex = false, facing = 'front' },
}
How could i make it so my boss blind divides mult by a number?
also if it's only for one joker you can use draw
instead of drawstep
how would i apply post shaders to balatro without using reshade anyone know?
before or after scoring?
either works, but after is peferred
you can use calculate with context.final_scoring_step and do mult = mult/number
oh.
oh. and how do I do this to this?
SMODS.Joker{
key = 'necromancer',
loc_txt = {
['en-us'] = {
name = "Necromancer",
text = {
"Create three Ethereal Tags",
"when Blind is selected"
}
}
},
atlas = 'Jokers',
pos = { x = 0, y = 0 },
config = {
extra = {
-- No additional properties required for now
}
},
rarity = 2,
cost = 4,
calculate = function(self, card, context)
-- I don't know
end
}
don't forget legendary
the legendary medals? hm
thanks! now it works!
i wasnt really thinking about adding them but i guess i could add a medal for each legendary that unlocks when you unlock the legendary yo-kai
please add attention text to that
can anyone give me the low-down on how to switch localization entries for a joker
or just a starting point
i dont understand sorry, its a boss blind, how do i add the context part
blinds can have a calculate function like jokers now
of course, when you unlock a legendary yo-kai, you also unlock their medal.
if you return key = ... in loc_vars it should change descriptions, is that what you mean?
eg. unlcoking spoilerina nets you her medal, and it can appear in medal packs from now on
of course, they’re harder to find than regular medals (like, soul card odds maybe)
how can i force a card to act as if its glass with a boss blind
quantum enhancements probably? idk how those work though
quantum... 
That llooks really cool
this could very well be the blind leading the blind though
i would personally destroy the card normally with context.destroy_card but hook SMODS.shatters to make it do the shatter
heh... blind... boss blind
[please laugh]
I guess that depends on if you want the xmult or not
:wheeze:
thank you
you can also do the xmult with calculate
the played cards are G.cards right?
G.playing_cards
i thought that was the entire deck
oh played cards sorry
G.play.cards or that ^
cool, now i gotta find out how to do chances with the seed
using the debug mod is there a way to get planet levels?
spawn in a bunch of planets
(hover in collection and press 3)
is there a way to set the back sprite of a card?
thanks
just to check, am i doing this right?
calculate = function(self, card, context)
if context.check_enhancement then
for i, card in ipairs(G.play.cards) do
if pseudorandom('Flote') < 1/4 then
SMODS.shatters(card)
end
end
end
end,
no i don't think that makes sense
I don't know how check_enhancement works but probably not like that
and SMODS.shatters just checks if a card shatters or not, it doesn't break it
you also don't want to shatter a card manually during calculation
how should i shatter a card then
(but if you have to shatter a card outside of calculation do card:shatter() )
use context.destroy_card and hook SMODS.shatters to return true when the card is played during the blind
OR make it do the quantum enhancement calculation thing maybe, but one or the other
i probably misunderstood fully but ive got this now
calculate = function(self, card, context)
if context.destroy_card then
for i, card in ipairs(G.play.cards) do
if pseudorandom('Flote') < 1/4 then
destroy_card = card + destroy_card
end
end
end
end,
}
closer
no
to destroy a card in destroy_card you need to return { remove = true }
context.cardarea == G.play
you also should remove the G.play.cards loop
oh
so now its this?
calculate = function(self, card, context)
if context.destroy_card and context.cardarea == G.play then
if pseudorandom('Flote') < 1/4 then
return { remove = true}
end
end
end,
}
it works, thanks
is there any easy way to modify the exisiting deck skins? I'm trying to recolor their suits
I am in the middle of adding proper destruction tools for cards
Oh.
what is wrong here
you can just do context.scoring_name instead of get_poker_hand_info
but what's not working exactly
context.scoring_name is what i tried originally but it didnt work
it's supposed to be setting the played poker hand's chips and mult to the chips and mult during scoring right before they're multiplied together
and it's not doing that?
nope
Really confused right now but somehow I've broken the vanilla loc_vars in generate_ui for wheel of fortune and im not really sure how....?
this joker works in the sense that it copies the ability of any joker that is compatible with blueprint, but the sell cost penalty seems to not apply to some jokers seemingly arbitrarily. It works with scaling jokers, scoring jokers, and retriggers seemingly fine, even stuff like baron and mime. However, it for some reason it doesn't work with jokers including burnt joker, beginning of round abilities like certificate, blind select abilities like cartomancer, and other abilities like hallucination. does anyone know what might be going on or how I can fix it? lmk if you'd like to see a clip of other examples, or if you'd like to see the code
just tried this with scoring_name and it worked for me
this is the undiscovered version btw
So SMODS.Center:take_ownership() accepts a key, a table of values to replace, and then an argument for whether it should be silent. I have this contextual table that adds either a change to the loc_text, a change to the atlas/badge, or both. But for some reason doing this breaks the description even though I haven't changed the name of the center which is what vanilla uses to determine the vars for consumeables
if skins or queer then
local build_table = {}
if queer then
build_table.loc_txt = {
['en-us'] = {
name = "The Wheel of Fortune",
text = {
"{C:green}#1# in #2#{} chance to add",
"{C:dark_edition}Foil{}, {C:dark_edition}Holographic{}, or",
"{C:dark_edition}Queer{} edition to",
"a random {C:attention}Joker"
}
}
}
end
if skins then
build_table.atlas = 'fnwk_tarotreskins'
build_table.set_badges = function(self, card, badges)
badges[#badges+1] = FnwkDynamicBadge('jojopolis')
end
end
SMODS.Consumable:take_ownership('c_wheel_of_fortune', build_table, true)
end```
specifically like this?
yes exactly that
why does it not work for me then
What do you mean by it doesn’t work
heres the full joker code
???? Are you not able to use loc_txt and localization files simultaneously???
Or is there something else weird going on that's changing the name of it behind the scenes?
It took me too long to understand the queer joke lol
Lmao yeah. Point being, it is applying the new description, the new art, and the new badge, but it's also seemingly changing something else when I was under the impression that :take_ownership() only changes the fields you actively give it
Aura for example is also changed in its loc_txt and doesn't break?
so if you play a pair and after all the calculations it ends up as 100 * 20 you want the pair's base chips and mult to be 100 and 20, right?
yes
yeah it does that for me
but this code does not modify the hands at all
what could possibly be causing this not to work
Do note that if you then change the level of the hand it will undo that
great
ill worry about that later
i know some mods get around that so i can just look at how they do it
but i still want to get this to work
yeah i just have this idk
Before I go to bed I've actually managed to do this:
What’s your smods version
do you have talisman installed
1.0.0~BETA-0509c-STEAMODDED but it also includes aikoyori's font pr that hasn't been merged yet
yes
Are you actually updating the base mult or the total mult?
G.GAME.hands[hand].l_chips = to_big(G.GAME.hands[hand].l_chips) + to_big(lchips)
G.GAME.hands[hand].l_mult = to_big(G.GAME.hands[hand].l_mult) + to_big(lmult)
G.GAME.hands[hand].mult = math.max(to_big(G.GAME.hands[hand].s_mult) + to_big(G.GAME.hands[hand].l_mult)*(to_big(G.GAME.hands[hand].level) - to_big(1)), to_big(1))
G.GAME.hands[hand].chips = math.max(to_big(G.GAME.hands[hand].s_chips) + to_big(G.GAME.hands[hand].l_chips)*(to_big(G.GAME.hands[hand].level) - to_big(1)), to_big(0))
im trying to update the base mult
s_mult & s_chips, then.
Just remember to also update the "total" mult, counting the levels' l_mult & l_chips with the changed s_mult & s_chips.
so i should do all of this?
You must have something else thats either stopping your joker from triggering or is resetting the hand score
Have you thrown a print in your calculate to make sure it’s happening?
im trying to see if i can use to_big
is this possible?
print function activates
i think
doesnt seem to activate on the final scoring step though
it shows the second i play a hand
unsure if that matters at all
oh hold on
i disabled everything except the necessary mods and it works
seems to be some sort of mod conflict
troubleshooting rn
also you seem to be incorrect
leveling up the hand does not reset it
found the culprit
Did you change it to s_mult?
i didn't
So i've never ever modded balatro before, and i had this idea for a mod
Basically a Joker, that has a 1 in 4 chance to take a dollar from you in exchange for a X5 multiplier
is that possible?
Levelling up should 100% reset it unless something is modifying the level up function
seems possible to me
well luckily for me something does seem to be doing that
probably cryptid if i were to guess
which is a dependency for my mod anyways
what 😭
but yeah the culprit for the code not working seems to be entropy
already brought it up with ruby
once thats fixed it should work just fine
ty for the help yall
not the first time entropy has interfered with my code
its not supposed to look like that......
Is it possible to change the alpha / transparency of a sprite on the fly?
I wanna make this look a little bit more polished
how do i fix this
hi chat i'm working on my first modded joker and am wondering if there's anything blatantly off here, as well as if I can make it so that if the chips value is negative it'll appear as "5 - 3i" instead of "5 + -3i" or something
key = 'euler',
loc_txt = {
name = 'Euler',
text = {
"Increases Mult and Chips",
"based on this value:",
"{C:mult}#1#{} + {C:chips}#2#i{}"
"When you score a:",
"Face Card: Gain i.",
"Ace: Multiply by i",
"Other: Lose i."
}
},
config = { extra = { mult = -1, chips = 1} },
rarity = 2,
atlas = 'ModdedVanilla',
pos = { x = 1, y = 0 },
cost = 6,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult, card.ability.extra.chips } }
end,
calculate = function(self, card, context)
--TODO: Check the scored card.
-- If it's a Face, increase chips by 1.
-- If it's an Ace, multiply chips by negative 1 and swap chips and mult.
-- Otherwise, decrease chips by 1.
-- After checking each scored card, increase mult by mult and chips by chips.
end
}```
also hoping it's a relatively balanced joker, but fine with it being pushed. 🤷.
These sound effects are 👌
You're missing a comma on the third line of your text table
thanks
i'm wondering if the wording feels coherent too, get that it isn't following convention but nothing about this is
Gotta keep track of those commas
I need to know how to make it not just pop out of existence ;~;
i like that it's kind of a jumpscare
But it just stops existing instead of gradually fading out, that's the issue
Benjamin of the deca variety
you might be defining the atlas size wrong
whats the size of each sprite is it 71x71?
yeah all of them are 71x71
hmm
what do you mean byt hat
What are you storing the medals in
they're consumables.
Then yea, im pretty sure the area is whats stretching them
fuck.
set display_size and pixel_size on them
display_size = {x=71, y=71},
pixel_size = {x=71, y=71},```
Did you define it on the consumables themself or the atlas. you need it on the consumables
the consumables
show
mmm
delete display_size and pixel_size?
I guess the only other solution is make the sprites 71x95, but not use the bottom part
Wait why in atlas its px/py instead of x/y ?
Its how vanilla does stickers and seals
oh sorry i missed the other message
try setting the y in display_size to 45
??
i want to see something
nothing happened
look at Square Joker code
yeah that's what i was worried about
and us elovely patches to make it work
that's how i made grim skills smaller than standard
another lovely patch, eh?
The only other way you can do this is make the atlas 71x95 and then use the dispay/pixel size
don't do this
Its legit how vanilla does it fym
it's bad practive and makes the hitbox too large
.
the yo-kai medals are their own objects
seals an stickers go onto cards
different things
"Makes the hitbox too large" Thats what display_size and pixel_size fixes
but half joker does it and that's fine?
of those actually work?
last time i tried that it did nothing
it does
yea it works
Display and pixel size take h and w, not x and y
In that case how should i go about it?
oh yeah
mmmmm
seals and stickers do that because they're specifically meant to be overlaid onto cards of the same size, not the case for completely unique objects of a specific size like blind chips, blinds, tags, etc
still doesn't change jack shit
Then do this
Well firstly you should learn the basics of modding, Steammodded (the mod loader) has a good wiki
Then honestly just look at how the base game does things
You can look at the source code by opening the balatro executable with winrar or similar
Then look for things with chance abilities and abilities that take away money like the rental sticker
Just have blank space at the bottom
Yeah I think the atlas is likely the issue
vanillaRemade > balatro.exe
https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua
yeah if this is a custom consumable type I guess they're always expecting a card-sized object, so the atlas will always take whatever size the sprites are and stretch them out to the size of the card
Are they taller than the sprite? Like if you hover into the blank, does it hover the card
nope
nice
it would be nice if custom consumable types could have default scaling options where you can set how big the consumable type is meant to be
unless it was added recently, I don't think undiscovered sprites let you change their size yet, so a consumable type that is smaller than the average card will still have a fully-sized undiscovered sprite
Didn't know that contained so much, ty
astra did a lot of work
i may be a bit forgetful but i do have to take ownership of a specific modded joker in order to add it to a custom object type, right?
no, you can add it directly to the objecttype
even if the mod that the joker is from isn’t loaded?
yeah you don't use take_ownership for that at all
but I don't know if you can add it to cards directly or if you need to inject it after tho
im guessing you need to inject it after
the wiki doesnt seem to tell people all the functions and stuff where would i find that
if you mean all the vanilla functions then there's no place for that, you need to read the game's code/other mods' code/ ask here
dang,,
lets see if i can
Bump [=
shaders probably
I need help with UI programming, I am making a config page for my mod, but it isn't updating the value with what I input, and is also shifting to the right when I put the value into the text box
edit: The value is being nil for some reasom
do I need to do anything special to get a number value out of it?
would this joker work out
doesn't seem great since it's a net of $2/ante, and that's not including the loss of interest money, so almost certainly wouldn't be an uncommon IMO
maybe making it -4, 5, 10 could be better
but maybe a bit more to be uncommon, as there is the golden joker which is +4/blind (12/ante) and is only a common
could be nice, as scaling is good, but seems very similar to rocket but with a dollar subtraction on small and big blinds
Pierogi Joker
does this potentially put people in debt
anyway how do i have a joker check if the entire played hand is face cards (separately, i also need a joker to check if the entire hand is Hearts)
local faces = true
for k, v in pairs(G.play.cards) do
if not v:is_face() then
faces = false
break
end
end
if faces then
--- do things
end
Better than what I was going to suggest
local hearts = true
for k, v in pairs(G.play.cards) do
if not v:is_suit("Hearts") then
hearts = false
break
end
end
if hearts then
--- do things
end
do these just go into the code of the jokers?
Yes.
how do you get the number of jokers the player has
#G.jokers.cards
ohhh thats what hashtag does
like this?
# originally meant number, so
No, because your calculate function seems to be missing an end.
after the end for the return, right?
Yes.
just fixed that
Can you explain more please
Because that looks like the correct way of making text orange
it's not orange
C:attention
I think using C:attention is what is usually done for orange text
Hey, if I have a copy effect joker, what is a good way to check for when a copied ability is triggered, specifically from the copy effect joker?
hi i use the context.pre_discard to search pairs of cards and then mark the cards, then in a context.discard y destroy the cards but after that the game doesnt update the space of the deck
Put the thing you want in the deepest effect.func?
wym
Because the func is run when the return activates.
sure, but what if it's a joker that doesn't return a table, like burnt joker, or cartomancer, or certificate, hallucination, etc
should this be uncommon?
You can't check then I don't think.
Thank you
The continuation of the card exporter thing strmnn is working on and I'm helping with parts of
is common too unbalanced?
None of the effects feel that strong but they also really vary in terms of usefulness
That probably makes it fine as a common
‘Shader uniform ‘bleached’ does not exist. a common error is to define and not use the variable’
is it because i’m using ‘astropulvis_bleached’ rather than just ‘bleached’?
Either my reading comprehension is...not so great or The Height is bugged
The shader name has to also be an external variable in the shader, which also must be used in the primary shader effect() function
can i provide the shader code
do i need to re-use this entire thing if another joker is also meant to use the same requirement
Yes.
this consumable of mine is egregiously broken, how do i make it so it can specifically target consumables, not be stupidly common (soul_rate seems to not be working?) and make it so it can only appear after ante 8 (in_pool function isnt working)
heres the function for a joker that randomly triggers another joker. i want to make it so that when it triggers itself, you get x1.25 mult. i think whats wrong is that its not detecting that its triggering itself, but i may be wrong. can someon help?
That is the most efficient way.
like.. this is all correct
but
im just
confused
it looks fine, at least
card not self and please use pseudorandom instead of math.random
pseudorandom is the same across seeds.
Wow it looks AWESOME
just name the file bleached.fs and it will work perfectly
its for sure not supposed to do that
okay so what the fuck then
I don't know, it looks freaking dope dude
yeah, the shader really needs its name as a uniform
not having that working made the thing I was doing take forever to fix
lol
laucnh balatro and then run watch shader pathto/bleached.fs, it should work.
why do i have to do that
do i have to do this every time
ok this consumable is so broken i genuinely need to rewrite it from scratch
No, I mean that is how I loaded your shader just fine. It's a cool command you can use within DebugPlus to monitor a file for changes and reapply them in real time. Works great for shaders
im so confused as to why it currently is not loading though
Hey, @midnight coyote can you show me how you're loading the shader? that's probably the error
i put the SMODS.Shader code into a shaders.lua file into modules/init, which is loaded before any content ever is
I have my shaders in Modfolder\assets\shaders
then I load them like this
SMODS.Shader({ key = 'etherOverdrive', path = 'etherOverdrive.fs' })
Be sure your shader file is in the same place, and again that it has an extern that matches the file name. The file you sent me worked fine when I put it in the right spot
maybe its the inital parenthesis im missing
Hey uh
could one of you guys help me out with an SMODS.Suit thing
I made a thread earlier, but got no input
i’m starting to think this game literally just hates me
okay better solution
i’m gonna push this upstream
i’m just. so stumped
wtf
how do i make it so a consumable can be used on other consumables
specifically
able to highlight one consumable in a pack, or in the tray
and use it on it
with the can_use function
You could check if the area of the highlighted is in G.consumeables or G.pack_cards and check if card.ability.consumeable?
can you even select 2 consumables at once?
Not normally I don't think.
how do i use pseudorandom?
i think im using it wrong
this is what i was doing originally but its extremely broken
pseudorandom("seed", min, max)
how do you get the seed
or can you just put any number
You just put a string.
how do i have a joker destroy the played card
thanks you
if context.destroy_card and context.cardarea == G.play then
return {remove = true}
end
how come removing the tag ui element makes the dark background move onto the "or" instead of the skip button??? (the run button is the skip button i just changed the localisation)
chat, let's say i want to use a table like a queue (i.e. like a C# queue). how?
this spectral has been absolutely driving me insane for ages
so would i just add those extra contexts and extra bit in the return to this
so say i want to have a table that only ever has 5 elements. and when a sixth element is added,
element 1 = element 2
element 2 = element 3
element 3 = element 4
element 4 = element 5
element 5 = new sixth element
and it just rotates the elements up every time a new one is added
Insert the new element at the end and remove the first one?
why does git do the identity check after trying to commit?
is it possible to remove at a position? 
table.remove(tableName, 1)?
Yes, that's literally what table.remove does.
ahhh
it's... annoying to have to wait to be told again the commands to set up my identity variables on a new "device"
No, it needs to be outside of any other context checks.
could it be the fact that the folder inside the mod directory in AppData is a symlink to the actual mod folder in my home dir
does anyone know how i could open a booster pack after a blind is defeated automatically? (through a joker)
where should i put it in the code then
because i want it to only destroy the played card when the other contexts (except i guess context.joker_main) are true
You have to do it in context.destroy_card elsewise there will be issues.
won't it just destroy the card every time then?
if nil is good wheres nil2
nil2:
what are you doing that can create nil2
What is the goal?
check how the tags do it
there’s no doubt about it, i’m gonna have to think of ideas for, a whole lotta yo-kai medals
rank things with very bad loc_vars lol
if the conditions for the joker's upgrading (which is in the screenshot) are met then the joker destroys the played card
Check for the same conditions in context.destroy_card and return {remove = true} if true elsewise don't.
some ideas may or may not be original but, whatever.
would the conditions be in the if [code] then part of the statement?
Yes?
Do I at least have the right idea here? Trying to make a blind that disallows any hands of one rank or suit and I get an error "Attempt to index fiel "poker_hand" a nil value (just doing this to get used to blinds first).
debuff_hand = function(self, cards, hand, handname, check)
if next(self.poker_hands['Flush']) and not self.disabled then
return true
end
end
self.poker_hands?
idk what else to do man, I'm just clueless.
I have my own deck skin, and I've made a version of it where hearts / diamonds and spades / clubs have the same colors for smeared joker, how would I go about replacing the atlas or atlas path on the fly to make it update in real time, if that's even possible?
I'm assuming that hand is the highlighted cards so try getting a flush on those.
I've tried taking ownership of my own atlases like the log yelled at me to do, but it just makes the game crash trying to find the current mod
ran tree on my mod dir
could you show how exactly
Me: 
i forget, is it G.P_CENTERS.<JOKER KEY>.unlocked or G.P_CENTERS.<JOKER KEY>.locked? 
unlocked
although i guess if a joker is discovered, it's also not locked 
is there a way to turn the cards face down like in the boss blinds? i remember the game didnt like it when i tried to debuff cards outside of a blind
if #G.consumeables.highlighted + ((G.pack_cards and G.pack_cards.highlighted[1] and G.pack_cards.highlighted[1].ability.consumeable and #G.pack_cards.highlighted) or 0) == 2 then
return true
end
```?
Now I've got this, which at least doesn't crash, but it disables any hand. What should I be checking to only disable those specific hands?
debuff_hand = function(self, cards, hand, handname, check)
if next(hand['High Card']) or next(hand['Pair']) and not self.disabled then
return true
end
end
hi guys, im trying to make my first mod for balatro and the first joker i want to add to the game is bascially diet soda but instead of giving you a double tag when you sell it, it gives you a negative tag when a blind is selected but i have this issue where it just doesnt work lol. any halp woiuld be greatly appreciated. also on a side note im not very experienced in lua
tysm!!!
It's context.setting_blind
I've heard people talk about calculate functions for blinds, but idk if/how to use it here.
You should be checking handname not hand
tysm
Just replacing hand with handname makes a different crash, I'm guessing it should be handname == ' '?
Yes.
Thank you!
how do i make it so i can select a card from a booster pack into the consumable slot
You have to do some patch shenannigans
fuck
yeah lmao
legendary yo-kai and their medals
Is it possible to have odds show up modified by oops on a boss blind?
does anyone know how to get the booster pack to open instead of just sitting in the center of my screen? calculate function:
calculate = function(self,card,context)
if context.end_of_round and G.GAME.blind.boss then
local key = 'p_para_foodpack'
local card = Card(
G.play.T.x + G.play.T.w / 2 - G.CARD_W * 1.27 / 2,
G.play.T.y + G.play.T.h / 2 - G.CARD_H * 1.27 / 2,
G.CARD_W * 1.27,
G.CARD_H * 1.27,
G.P_CARDS.empty,
G.P_CENTERS[key],
{ bypass_discovery_center = true, bypass_discovery_ui = true }
)
card.cost = 0
card:start_materialize()
end
end
I think the wheel does this?
I mean, the text of a boss blind. Not sure what wheel has to do with that.
the boss blind, The Wheel, does this
for the sprites of jokers do they have to be in the same png file or is there a way to have multiple png files?
Ah, in game blind code is kind of annoying to implement, I'll try though.
theres a way to do this but i dont know how
you can do separate, just make multiple atlases
thank you
Very stupid deck idea i had:
Imaginary Deck
Start off with 26 normal cards, [6 Spades, 6 Hearts, 7 Clubs, 7 Diaminds]
and 26 imaginary cards [7 spades, 7 Hearts, 6 Clubs, 6 Diamonds]
And add ichips, and imult.
Thd final chip score calculation is:
(ChipsxMult)x(iChipsxiMult)
Would this somehow be possible
I think you could just do it how you would any other object though with steamodded.
how do i make the booster pack here open
Try looking at Turquoise Tornado
from cryptid
Will do.
I simply cannot get this sound file to work 
How lag inducing would All jokers get duplicated when boss blind is defeated be?
probably not very unless you have cryptid (which is lag-inducing on its own tbh)
This is for overpowered speculo.
Which you would have to have cryptid to use.
almost certainly crash the game within five antes
mostly because balatro doesn't use all your ram? It doesn't seem to know how
probably a love2d abstraction thing
does anyone know how to get the booster pack here to open instead of just sitting in the center of my screen? calculate function:
calculate = function(self,card,context)
if context.end_of_round and G.GAME.blind.boss then
local key = 'p_para_foodpack'
local card = Card(
G.play.T.x + G.play.T.w / 2 - G.CARD_W * 1.27 / 2,
G.play.T.y + G.play.T.h / 2 - G.CARD_H * 1.27 / 2,
G.CARD_W * 1.27,
G.CARD_H * 1.27,
G.P_CARDS.empty,
G.P_CENTERS[key],
{ bypass_discovery_center = true, bypass_discovery_ui = true }
)
card.cost = 0
card:start_materialize()
end
end
Why are you directly creating the card manually instead of using create_card or SMODS.create_card or SMODS.add_card?
Damn, cryptid code is a mess to look through.
i know, right
this was from cryptid's loss tag (when i asked how to create a booster pack in a joker someone said to check how tags do it_
apparently cryptid is just a mess
in my defense I never said check cryptid
true
anyway youre missing this part of the code
true
is there a sprite/animation template for boss blinds?
Soo... properly displaying odds on a blind. Game code is another world, and Cryptid is a mess, is there any decent reference material?
what's the issue?
Why did this happen?:
floating point
numbers are very accurate approximations
3.14 ≈ 4
loc_vars displays blind text properly in the collection, with oops modifying odds. collection_loc_vars displays properly in a run, however, oops doesn't modify that number.
why does this crash
calculate = function(self,card,context)
if context.end_of_round and G.GAME.blind.boss then
SMODS.create_card({set = "Booster", key = "foodpack"})
end
end
I've opened the pack separately so it's not that
You need to do p_modprefix_key I think.
makes sense, doesn't sound like something you can solve without patching stuff
Yeah, kind of figured. Seems like cryptid made a whole function to check for oops, and then modify the text if you have oops. I'm not doing all that, so it'll have to do I guess.
now we're back to packs spawning but not opening
did you do the use_card thing
the what
this
I'm in an interesting situation where I think my loc_vars is causing infinite recursion on the info_queue and I'm not sure how to prevent it
if not card.fake_card
is that a thing
how do you know everything
i just know what i know
theyre the goat
this just freezes the game after a boss blind is defeated
calculate = function(self,card,context)
if context.end_of_round and G.GAME.blind.boss then
SMODS.create_card({set = "Booster", key = "p_para_foodpack"})
G.FUNCS.use_card({ config = { ref_table = card } })
end
end
some of the other stuff in that code might be important
Do ```lua
local booster = SMODS.create_card({set = "Booster", key = "p_para_foodpack"})
G.FUNCS.use_card({ config = { ref_table = booster } })
oh yeah didnt notice that
a number, apparently
these single letter variables are hard to debug
something
i think i solved it
question - if i want to use poll_edition() to apply an edition, do i feed its output into a set_edition() or do i use it as i would set_edition()?
feed
nevermind i didn't
Is there something to check if a card has been retriggered?
if "{X:mult,C:white}X#1#{} Mult" then why does the text appear black
your localization is cursed
That makes things difficult/impossible.
What effect are you looking for?
is there anything wrong with this
I'm trying to make a blind that does -10 chips whenever a card is retriggered.
not that i can see, where is this
its not supposed to do this i think https://drive.google.com/file/d/1C8gaNYqAzPQdqaPaxUNOGxMMnbwnEf2Z/view?usp=drive_link
what's wrong with these lines (it pointed me to what's inside the return)
and context.main_eval?
Put the mult change outside the return.
{"{X:mult,C:white}X#1#{} Mult", "Multiplies by {X:mult,C:white}X#2#{}", "at the end of round"}
does anyone have code that replicates the functionality of the Negative edition? In the same one that VanillaRemade has the jokers and such?
I want to refrence it for an edition's effect I am making
the cash out screen goes over the booster pack when it opens now
astra just made a PR for that, you can check that out
it does show three items instead of three thousand though
changes don't go in returns?
looks fine to me idk
oooh? mind sending a link pls? :3 I am very interested in this
No, they don't?
do you have a space between X:mult, and C:white in your code?
i just merged it to the main vanillaremade :3
ahh, ok, I'll check it out then! :3
ahh it is done through a config 😭 that uhh, is not what I was expecting ashjfbsdjbfs, guess I can't use this for refrence with my "-reroll cost" idea bsdjfbsfj
you can use on_apply and on_remove
ahh, ok, last time I tried it didn't work, but I'll try again, thank you! I shall be back then, soon, lol
wait a sec, my temporary effects I used as placeholders aren't even working? whuh?!
😭 I is so bad at this abfsdhbsjd omg
Is there a way to add a specific Rank card to a suit? i.e. I want to add a 3.5 Rank to only one suit
I messed something up here ;-; lol
is there a way to add two 1D tables together?
like say i have a table of strings and another table of strings and i want to concatenate them
are they both integer indexed lists?
yes!
can i see the code
oh merge_lists will just work, ok
I have another edition too which is basically a copy of this one atm, for testing purposes
loc_vars = function(self, info_queue, card) no?
ahh okey
unintuitive
hmm it's probably card.ability instead of card.config but I've never done editions
(or just hardcode it to 2 if that doesn't work :3)
card.edition.x_mult ahhhhh
that makes sense
why does the same damn shader look so different on 2 types of things?? (look at card sharp vs that 2 of spades there)
maybe that's too early and you need to use an event? idk
question - if i wanted to hook into the functionality used when the reset profile button is hit, what should i be hooking? 
are we doing shenanigans
does anyone know how booster pack tags remove the blind select screen
because of how drawsteps work for playing cards, probably
is there a way to fix it
because this edition is meant for cards
not jokers
as my Discord status for the last week might indicate, I'm really not the person to ask
i see
just be aware that playing cards have their parts drawn in two steps
try turning your card to stone and see if the shader is still gross. If that fixes things, then the second drawstep is probably your root cause
alright
iirc it's because playing cards have a front and a center
while other cards only have a center
checking if something is greater than or equal to is >= right
based on the type of graphical error your shader is probably doing something bad with transparency
awesome
that second drawstep is fucked
i would say you didn't account for the original transparency
how do i do that
in your shader
okay this seems to be a recurring issue
the jokers also don’t have any transparency
somewhere in your shader you're overwriting the alpha to become 1
does anyone know how booster pack tags remove the blind select screen
i see that
when i clamp the alpha down i set the second value to be 1
or the third i mean
second is 0.7
let me grab the code
no
wrong
vec4 effect(vec4 colour, Image texture, vec2 texture_coords, vec2 screen_coords) {
vec2 uv = (((texture_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
vec4 tex = Texel(texture, texture_coords);
vec3 color = tex.rgb;
vec4 final_color = vec4(
contrastMatrix(1.5) *
saturationMatrix(0.5) *
color, clamp(bleached.x,0.7,1.0));
return dissolve_mask(final_color, texture_coords, uv);
}
there
where would i grab the original alpha
tex.a?
behold, ortalab compatability.
yup
i think i fixed it? lemme see
damn right i did
thank yall so much
alright
being gay is sane, noted
new issue, how do i exclude an edition from being able to be pulled from poll_edition
good news
figured that out too
oh
does this mean being straight is insane
yes
how would i apply a random enhancement to a card when its scored?
an idea that popped into my head was to give the ortalab jokers the tribes from yo-kai watch 4 and beyond
but like, fuck that.
that would take a bit too long
bump
how do i look for a card's edition
card.edition
to see the specific edition,
should first check against nil, because if it doesn't have an edition, it'll be nil and you don't want to try indexing edition if it's nil,
but you can check card.edition.type and it'll be any of 'foil', 'holo', 'polychrome' or 'negative'
so long as, again, edition isn't nil. which it will be if there is no edition
G.FUNCS.delete_profile, it seems
okay
@tall wharf , how is The Height meant to work? I encountered it earlier today and needed 400 chips to win, but still lost after scoring 8k + chips total
did you read the blind description? i'm pretty sure the height requires either exact or slightly below the req 
i just realised
score round
type doesn't need the prefix.
but if you want to stay in the habit of using the prefix, do key instead
ah i see, so just bleached?
or astropulvis_bleached?
try the latter
alright
if that doesn't work, i guess just do the key instead
ok basically you're not supposed to score a lot on non final hands
basically
uh
time to make the hand types that play around the lack of suits
why does this read as nil? it's in loc_vars
aH! when I played, the score didn't increase or change at all, not sure if that was expected 🙂
huh
Oh I see!
you're on latest right
am i right in assuming that when it's called, it wipes the profile that is G.focused_profile?
I have no idea, I just searched the codebase for something that seemed correct
oh boy i sure do love figuring out how tf this works
so for greyscale flushes i just need to check for if every card has no suit
how would i apply a random enhancement to a card when its scored?
oooh, i just wrote this myself
I never did figure out all the issues here :< even with them being set to plain numbers instead of config vars it didn't work correctly
right?
you basically want to call :set_ability(SMODS.poll_enhancement({ guaranteed = true }), nil, true) on your target card, at your preferred timing
I uhh, I'm kind of tired honestly :< I haven't been doing too well mentally, lol, and dealing with problem after problem like this is kinda bringing me down :< I might take a break for a bit, anfknsdjkfnjsk tho I'm not sure what I'll do instead, as I don't really have anything to do, honestly
a quick check confirms that i was right
👍
alright, it worked. thanks!
what could be causing this?
i know how complex this code is, hoping theres an easy fix i overlooked or something
ah
that may be it
so if i change that what in the joker do i have to change as well
nothing , probably
just change the args in the func
so all mentions of chips in the function?
ok i still get this crash
unless achips is also a global
idk then
i really am wondering about the version of my mod you're running because I've been moving functions around
whyyy gahh
supposed to be a 1 in 4 chance to destroy the card, and gains x0.25 mult from destroying the card
actually now that i think about it i should probably lower the mult or the chances
but thats a later thing
is hand a table in SMODS.PokerHand?
you have 2 loc_vars and the last one is the one its using
ohh i may be stupid
it happened to me aswell
anyone know?
i think nucleus co-op works but i havent tested it
ive used it for some other games
it might not have it tho
you should do ```
pseudorandom('rage') < G.GAME.probabilities.normal/card.ability.extra.odds
to make it work
ill try
SMODS.PokerHand {
key = "greyscaleflush",
mult = 7,
chips = 50,
l_mult = 3,
l_chips = 15,
example = {
{ 'S_K', true, edtion = "e_astropulvis_bleached" }, -- King of Spades, does not score
{ 'S_9', true, edition = "e_astropulvis_bleached" }, -- 9 of Spades, scores
{ 'D_9', true, enhancement = 'm_stone' }, -- Negative Lucky 9 of Diamonds, scores
{ 'H_6', true, enhancement = 'm_stone' }, -- 6 of Hearts, does not score
{ 'D_3', false, edition = 'e_astropulvis_bleached' } -- Red Seal 3 of Diamonds, does not score
},
evaluate = function(parts, hand)
local suit_increment = 0
for i = 1, #hand do
if SMODS.has_no_suit(hand[i]) then
suit_increment = suit_increment + 1
end
end
if suit_increment == 5 then
return { hand }
else
return {}
end
end
}
why does this not work?
wait
also you dont need Xmult_mod you just need Xmult
np
also what does xmult mod do
ah
.
hm, cryptid expansion material maybe?
entropy?
this is probably so fucked isnt it
ugh
i wish some mod fucking implemented this
or like
custom hands
i mean
because
i am at a loss here
whats the prob?
im trying to make a hand type
with 5 suitless cards
and i have'
no idea how to use evaluate
are the cards suitless due to an enhancement?
theres stone cards, and an edition called 'bleached'
bleached removes suits
ive been trying SMODS.has_no_suit()
how do you make it so that you can buy a card anytime kinda like how negatives work
like no matter how full you are on jokers you can get it
add ur own enhancement there
did thgat
show
i already hooked the function
function SMODS.has_no_suit(card)
if card.edition and card.edition.type == "astropulvis_bleached" then
return true
end
if G.GAME.blind then
if G.GAME.blind.config.blind.key == "bl_astropulvis_the_dip" then
return true
end
end
return smods_has_no_suit_ref(card)
end
and whats the poker hand look like?
cryptid has bulwark which just detects the stone enhancement, maybe your custom hand could just detect if all cards have the edition?
im not checking for the edition though
im checking for the lack of a suit
theres more than one thing that lacks a suit
@scarlet thorn here
just realized
that last card isnt showing as scored in the example
w/e
ill fix it later
i know theres the issue of
ugh
idrk
this is confusing me
im gonna go look at cryptid
where does it define its hands even?
lib/content.lua
bulwark is right at the top
why add_mult become a table for some reasom
I see the problem
thaknk yo
talisman?
omg, but how make it sure the mod is fine with talisman tho
@midnight coyote whats ur localization file
just figured out that its totally loc_file
how do you make a joker destroy a card thats held in your hand
misc = {
achievement_descriptions = {},
achievement_names = {},
blind_states = {},
challenge_names = {},
collabs = {},
dictionary = {
},
high_scores = {},
labels = {
astropulvis_bleached = "Bleached"
},
poker_hand_descriptions = {
['astropulvis_greyscaleflush'] = {
[1] = "5 Suitless cards."
}
},
poker_hands = {
['astropulvis_greyscaleflush'] = "Greyscale Flush"
},
quips = {},
ranks = {},
suits_plural = {},
suits_singular = {},
tutorial = {},
v_dictionary = {},
v_text = {}
}
}
here's the misc table
this should be the part that matters
i looked at bunco for the hands part
idrk what to do
whats that [1]
for
it's a way of creating an array (numeric table) with an element at a specific key, which is not necessary since this is a numeric array
Yea i know. I was mainly asking if it was required to be there.
mmm
Joker concept
Each round, make a negative copy of this joker
+5 chips, +1 mult
make this and uhhh idk man
you got any ideas
interesting
dmd you
i dont think descriptions are allowed to have periods
didnt fix anything
i think you also need commas after the end of each description line like "[text]",
added that too
still not working?
whats the crash say
i changed the key of the hand to see if that was the issue
in loc file and lua file for the def
so thats not it
does switching poker_hands to go first do anything
lemm see
like moving that section to before the descriptions
nope
also the } after the description should have a comma after it

