#đ»ă»modding-dev
1 messages · Page 553 of 1
which delay, the delay of the event or a delay()
i tried both and neither worked for me
the best way for me is actually "string1".."string2"
it just does it
two dots?
concatenation is .. yes
Whats the card area for deck skins?
tho if you want a space in between, that's "string1".." ".."string2"
say i want to make this
"string1" would be the number gain
"string2" is " more people joined in"
that string1 is a number that doesn't remain constant
would i need an if else for every different hand type?
so for example
i play a pair it says "4 people joined in"
if i play a 3oak, it says "8 people joined in" and so on
i can just hardcode every single hand type lmfao
but i'm trying to explore different options
in config?
yeah, and you can just concatenate that variable into that string
it can be a local, it depends on what your logic is
so, chip_gain for example?
and change that chip_gain after each hand is played to then display on the string
you can do card.ability.extra.chip_gain.. "text"
Grrr
i'll try that
yeah you need to check youre in a run then
How :3
add G.GAME.blind and at the beginning of your returns
wait does the mod name imply it changes the music to an epic theme song every time it's predicted that you're completely destroying the blind in one hand?
oh
you should implement that idea then too lol
@narrow merlin i like your pronouns lmfao
I am relatively gay, as you can see from them :3
same
source: my gf
Whatâs going on in my modding dev
Grrr
if context.before and (context.scoring_name == "Pair") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 4
card.ability.extra.chip_gain = card.ability.extra.chip_gain == 4
return{
message = localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
ignore the message part, i'm sorting the code still lol
sound prolly doesnt exist ingame i thinks
yeah i think the path is probably wrong
calculate = function(self, card, context)
if context.before and (context.scoring_name == "Pair") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 4
card.ability.extra.chip_gain = card.ability.extra.chip_gain == 4
return{
message = localize("card.ability.extra.chip_gain".." ".."pride_upgrade"),
colour = G.C.BLUE,
}
end
if context.joker_main then
return {
chips = card.ability.extra.chips
}
end
end
in the game, (it didn't crash) but it said ERROR lmfao, fuck you jimbo
is it in assets/sounds/music1.ogg
So I need to put them in a sounds folder too?
yes
and make sure it's sounds, not sound. hehe
I said sounds?
message = card.ability.extra.chip_gain .. localize("pride_upgrade"), assuming pride_upgrade is in your localization file
it's a small mistake but it's one that's gone unnoticed for the longest time when i was initially implementing sound to experiment with stuff
It is
I can show you my localization file, just to make sure
Ahhh, i see what i did wrong
Oops, sorry for the double reply
tis fine
I copied it off dusk
the keys are the exact same
I understand now
Localize() is for strings, extra numbers need to be added outside yeah?
Cause they're not strings
tho idk if that's important in this context
Message= will convert everything inside into a string, yeah?
current_round singular
no, but concatenating a number turns it into a string
Tyy
also no, localize is to fetch from the localization keys
In the localization file
yes
En-us
yeah
Wait, so i can make several different loc files for different languages?
And they automatically pull from the right one?
yeah thats what theyre for haha
Time to ask Russian gf to translate everything
And use my Portuguese side of things to translate to Portuguese
anything not translated will be taken from english by default as well
That's really cool
Hence why it's not a good idea to write the "upgrade" texts in the joker code
yeah
it's also handy dandy for localizing variables like +15 mult
:3
heck, i even made my own localized variable called +#1# Odds and it's just easy as throwing in an extra line into a certain area im forgetting the name of atm
Can't wait to see blahaj say "ŃжалĐș :3" instead of "Splash :3"
Beats the plant
Fast music starts playing
"...is that... Phase 2 plant?!"
Tbh boss blind phases would be funni
weird
play entropy..
Idk wym bud
entropy has a boss with phases
play lobotomy corporation
the mod
You play it
what does your joker config look like
what about = 0
=0 sets it to 0
config = { extra = { chips = 0, chip_gain = 0}, },
Okay, it's midnight, modding balatro was so yesterday, gn y'all
if context.before and (context.scoring_name == "Pair") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 4
card.ability.extra.chip_gain = card.ability.extra.chip_gain == 4
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
if context.joker_main then
return {
chips = card.ability.extra.chips
}
end
end```
OOPS
i saw
lmfao
==4 lmfao
fuck is this
== instead of + is certainly something
exactly
lmfao
but the issue is
that number isn't constant
i want to set it to 4, not add 4
=4
yeah
or just make it 4 to begin with in the config since you arent changing it anywhere else
it's giving me an error i think

this will change depending on the hand played
oh i see
see, why's it red D:
you could just like make a table in the config of hand types and their respective chip gains
can i see the whole line
im guessing you have two = that line
how do i do that? i have never done that
you can make any number of tables in your config
just card.ability.extra.chip_gain = 4
you cant assign twice in one line
if context.before and (context.scoring_name == "Pair") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 4
card.ability.extra.chip_gain = card.ability.extra.chip_gain = 4
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
this is the whole thing
Misterprint and Mxprint when?
Itâs just card.ability.extra.chip_gain=4,
yup, that's what i did
how could I make it so a sticker is applied to a random joker at the end of each round? I guess I can put it under context.end_of_round and not context.repetition and not context.individual alongside pseudorandom but that's as much as I'd know. Not sure how I can apply a sticker just like that
card.ability.extra.chip_gain = card.ability.extra.chip_gain = 4 bad
card.ability.extra.chip_gain = 4 good
the one on the top is using for math?
say chips = chips + 4
yes
what is applying the sticker
the deck itself
it works, nice
thank you!
you can probably do pseudorandom_element(SMODS.Stickers,"seed") to get a random one
or SMODS.Sticker.obj_buffer
one of the two
Thinking of later making Misterprint (random chips) and Mxprint (Random x mult)
I mostly wanted it to apply a specific one to one of the jokers, which it would choose with pseudorandom
ohh
you can use pseudorandom element on G.joker.cards then and then do joker:add_sticker("key", true)
alright
thank you !
@red flower is this good idea?
im bad at ideas
im only good at code
type shit
call me Sanji, with how good i'm cooking
Speaking of stickers what's the way to check if a sticker is compatible with a joker (ignoring stake difficulties)?
Is there any quantum rank support rn?
wouldn't it be eternal_compat = true, for example?
Does the wiki page for SMODS.Sticker say anything
My Textures have this weird Black Outline and I can't figure out ... why xwx!?
Aseprite?
Nope
No.
I'm using the Raw brutality of Paint
Does your image editing software support saving non-black transparent pixels?
Aww man. I'll try making some for the time being then
.. Hmm, I see x'3
The main issue for SMODS is Straight calculation
If you used Aseprite Iâd know an easy fix
Yes, but there is a pull request to SMODS that does that.
I remember long discussions about the topic, but not necessarily a move towards implementing it
I know people have implemented stuff
But there was still pushback against merging
I didnât see much progress but I havenât looked at it in a while
Whatâs the current status?
the current PR is supposedly finished but i didnt see people testing it
what are the hand names?
"Three of a kind" or Three of a Kind" đ
like, how specific do i have to be
Three of a Kind
Pair
Three of a Kind
Four of a Kind
Five of a Kind
Two Pair
Full House
Flush House
Flush Five
Straight
Straight Flush
?
thank you
Thanks you and ? Arenât valid hands
u arent a valid hand
There is a mention of SMODS.Sticker:should_apply() but I couldn't get it to work
What did you try
How would I read that for a given joker
SMODS.Sticker:should_add(SMODS.Stickers['eternal'], card, card.children.center, card.area, true) or smth like that
It kept returning nil
I think I tried both true and false for the bypass
chat, stupid question but
Or atleast this was my test attempt
Youâre doing it wrong
Damnit
Class.method denotes that the method is available to instances of Class
if context.joker_main then
return {
chips = card.ability.extra.chips,
xchips = card.ability.extra.max_level
}
end
can i have two context.joker_main?
either triggering one or the other
So you want to do instance.method
Yes
With pseudorandom
Or math.random if you donât care about seeds
But when I did it for local sticker = SMODS.Stickers['eternal']; sticker:should_apply() it would complain and say that should apply is a boolean
not if you return, you either need to combine the returns or use SMODS.calculate_effect
The terminology might be slightly incorrect, but the point is that instances of the class define their own version of the method
They want to either trigger xchips or chips
no
That seems correct
What
Why wouldnât it be a boolean?
Thatâs literally what you said lmao
Anyhow gtg I'll ask again later
i probably didn't explain correctly
As in there was no function should apply
thats not what they were asking tho
You want +chips then xchips ?
xchips only triggers if a condition has been met
I think maybe you misinterpreted the output
hence why i asked if i could have two joker main
Itâs hard to tell without seeing the error
Oh do the vanilla ones operate differently so the Class allows the entry to be a Boolean?
There it is tysm â€ïž
probably
If so thatâs kind of an odd implementation
what do you need it for btw
can i do something like
if context.joker_main and (insert check if a variable equals something) then
yes
Depending on the check I recommend just splitting the conditional
i dont
more identation makes it more illegible
yes
What if you have 1 condition but 10,000,000,000 repetitions
then those many conditions should be put in a helper function
true

I mean they still need to exist somewhere
Why do you have that many conditions to begin with
The conditions being inside the helper function or in the original are still taking space somewhere
You need to check if a number is even or odd

but then you wouldnt have nested conditions
You would inside the helper function
not if you do it correctly
and besides if all the conditions need to be true you can group them into multiple helper funcs
if it is really that bad
but if you need more than 5-6 conditions either your card is a tad bit too specific or there's a better way to do it
if card.ability.extra.chips >= 250 then
return {
card.ability.extra.max_level == 1
}
end
i want it to check if the chips you're getting is 250 or more. if so, the extra xchips buff activates
I disagree, sometimes you need to check things exist
you would either 1) have the conditions directly in the return, 2) have multiple helpers and/or 3) make the conditions return early
That can be easily two or three checks depending on how many nested tables youâre dealing with
max_level is either a yes or a no
(table.field or {}).value my beloved
I mean YMMV if thatâs more legible or not
i dont understand the return here
should it be = 1?
no
I think it doesnât make sense for what youâre trying to do
this whole == and = confuses me D,:
what should it do
Iâd be something like xChips = value
its not a case of = or ==
The equivalent of poll_sticker
you gain chips everytime you gepplay certain hands
Because poll sticker doesn't exist
Equality test and assignment
pr it to smods when ur done :3
You can read = as âgetsâ or âis assignedâ
if the total chips surpass 250, then it turns max_level from 0 to 1 and you get an extra xchips
-- final joker calculations
if context.joker_main and card.ability.extra.max_level == 0 then
return {
chips = card.ability.extra.chips,
}
end
if context.joker_main and card.ability.extra.max_level == 1 then
return {
chips = card.ability.extra.chips,
xchips = 1.15
}
end
hence why i have these
wait thats actually a pretty cool usage of lua's or operator lmao
yes
This makes a bit more sense
Do you want the max level to be set without the bonus being granted?
I agree but I think itâs less legible to the average user
i agree
Maybe but I think card:add_sticker would need fixing first for that
Oh also
why
whats wrong with it
Another reason I split conditions is to define variables
It can't apply vanilla stickers without the override
Because I might need those variables after the conditional anyways
oh yeah
in that case yes
calculate = function(self, card, context)
--hands played
if context.before and (context.scoring_name == "Pair") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 4
card.ability.extra.chip_gain = 4
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
if context.before and (context.scoring_name == "Three of a Kind") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 7
card.ability.extra.chip_gain = 7
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
if context.before and (context.scoring_name == "Four of a Kind") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 10
card.ability.extra.chip_gain = 10
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
if context.before and (context.scoring_name == "Five of a Kind") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 15
card.ability.extra.chip_gain = 15
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
```
card.ability.extra.chips = card.ability.extra.chips + 8
card.ability.extra.chip_gain = 8
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
if context.before and (context.scoring_name == "Full House") and not context.blueprint then
card.ability.extra.chips = card.ability.extra.chips + 20
card.ability.extra.chip_gain = 20
return{
message = card.ability.extra.chip_gain .. localize("pride_upgrade"),
colour = G.C.BLUE,
}
end
-- check if
if card.ability.extra.chips >= 250 then
card.ability.extra.max_level = 1
end
-- final joker calculations
if context.joker_main and card.ability.extra.max_level == 0 then
return {
chips = card.ability.extra.chips,
}
end
if context.joker_main and card.ability.extra.max_level == 1 then
return {
chips = card.ability.extra.chips,
xchips = 1.15
}
end
end
this is the whole thing lmfao
what a fucking mess
seems more organized than my desk tho
this is a good case for nested conditions haha
Alright, hit me up, what's the easy fix? x3
but does it look good? xD
Aseprite can export in 200% size, which introduces the same issue. The fix is to manually scale the canvas 200% and export in 100%
I hopoe it's tasty :3
damn, adhd brain was too much for N D:
I should make lunch too @_@
have a good lunch!
Huh.. That's a weird one but aigh't, I'll try that x3
Casual coding while at work
Why in gods name does that work!? 
THANK YOU! 
exporting at 200% shouldnt have that issue, i always just export and transparency works just fine
i have the debug mod. is there any way to add cards to hand?
you cant add cards but you can cycle suits/ranks/enhancement/seal/edition of hovered cards with hotkeys
I mean every other Balatro modder Iâve seen encountered this issue
thats very strange
I donât think you can add specific cards from your deck but you can have infinite discards and I think you can copy cards too
Ay but now the Issue goes the opposite way.. The white is bleeding into the Texture owo'
how?
What do you mean
CTRL+C
What visual settings do you have in Balatro?
This isnât an issue with the export
Itâs an issue with how Balatro renders the art
?
Well, thereâs a minor issue with the export, but it doesnât matter 99% of the time
you literally said exporting introduces the same issue
Left is my Texture, Right is Vanilla
There's a very slight white-bleed
In this case it wouldn't be that bad but with lighter colors it gets really bad x'3
The blurry grey aura happens inside Balatro
But it happens because of an âissueâ when Aseprite exports at 200% scale
Iâm not sure I can see it
and what is that "issue"?
Black transparent pixels
Aseprite doesnât save the color of transparent pixels, or it sets their color to black when exporting at higher size
oh so #00000000 causes bleed but #FFFFFF00 doesnt
Hi, just wanted clarification of rule 3 "Do not debug source code" #đă»modding-rules message . Does that mean it's against the rules to look at the source code with a decompoiler tool. I understand part of the reason is to not pirate the game, but I'm curious how else you would get understanding of the code in order to make a mod
Iâm not sure
i mean the first time i did 2x assets i tried to increase canvas size but that doesnt give me the option to not use some upscaling algortihm
Unzip
youre allowed to look into the source code
just not distribute/discuss edits of it
Well I recommend copying the EXE then unzipping the copy
extracting with 7zip leaves the original
In Aseprite it does
i use aseprite thouggh
I think itâs nearest neighbor the one without* interpolation
I mean some algorithm is needed to fill in empty pixels
Nearest neighbor is the one that does what you want
Itâs not weird
chat, it all works perfectly
âUpscale without interpolationâ is just nearest neighbor
thank you so much
why don't you use a tool to upscale it? i do and it works just fine
Aseprite can do it
https://lospec.com/pixel-art-scaler
change it to 200% and done
Just try it next time
Youâll see
calculate = function(self, card, context)
local pool = {}
for _, joker in ipairs(G.jokers.cards) do
if joker ~= card then
table.insert(pool, joker)
end
end
if context.end_of_round and not context.repetition and not context.individual then
if #pool > 0 then
local selected_joker = pseudorandom_element(pool, card.key)
if selected_joker then
selected_joker:add_sticker("tdec_Eroding", true)
end
end
end
end
I'm definitely messing something up majorly but I have no clue what exactly
How does an enhancement even check if the score is on fire?
The only thing working here is the Xchips
is the entirety of a blind's config stored in .config.blind?
destroy_card and after dont happen at the same time
I guess that means, that streaming on twitch is out of the question :(
it means don't send code to local to fix bugs
You can extract the files and look at them but editing the source code is prohibited
wdym editing
Editing the src and compiling it back
i mean it's not allowed to share that obviously but you can do it for personal use
Yeah
hhh how would I check if a card has a specific sticker? Forgor
card.ability.[sticker_key]
ty
So, and how do i that correctly?
I wanted to make an enhancement, which adds X2 Chips (that first part is fine), but that gets destroyed when the hand is on fire.
It is similar to the Glass Card's Code right?
why doesn't this work
.txt is error given
The key in the SMODS.add_card needs a class prefix, also the SMODS.add_card needs to be in the event.
oh hell yeah
should probably be in #âă»modding-general though
oops, you're right
i dont understand
could you explain in simpler terms
let me post it there
Hey all! Brand new to modding Balatro and still getting to grips with SMODS and Lua in general. Wondering if any of you know what Iâm doing wrong here.
Iâm creating a joker that has a certain amount of Xmult according to the level difference between the highest ranked poker hand and the second highest (starts at 1x, has 0.5 extra for each level). Struggling to get the code to work.
Hereâs the function for finding the level difference (ai assisted - maybe there's something wrong here?)
Probably an obvious blunder
except if its pinned, then its card.pinned
Justice for pinned
is there any easy way to take a UIElement out of the ui temporarily?
You're trying to execute the find_level_difference as an extension (idk the proper word) of the Card class, But you didn't define that. SMODS.Joker doesn't know what to do with the definition
Instead just define the function outside the SMODS.Joker and inside calculate call it with find_level_difference(self)
also self isnt even used lol
That is also true lol
self:find_level_difference would only work if you explicitly defined Card:find_level_difference = function(self) [...] end
But that would make it a general function for all cards to just have, when I don't think it needs to
No, self would be the center.
I just created a booster pack but for some reason it doesn't show up in balatro.
is there something I'm missing?
Keys can't have spaces.
aight
huh, it still doesn't appear
wait, don't tell me I have to update my steammodded again
are you loading the file
ok so for now I just updated my steammodded but still the booster pack doesn't show up
why did you ping me to not answer my question
This might sound weird but is there a way to make it so you straight up just can't see shops within a run(by finishing a blind, at least)? I don't know if there's anything of that sort but it's kinda what I want my next deck to revolve around.
yeah that was what i didn't do, my bad if I reply pinged you
i think you can patch the part that switches states to switch to blind selection immediately
I'm pretty bad when it comes to patches but i'll try to do it, thank you a lot
how can I make it that the booster pack creates jokers that are only from my mod?
make an objecttype with jokers from your mod
alright
hmm. for whatever reason, my food jokers started borking out in a weird way. the xmult/xchip ones do get eaten, but they "ERROR" instead of properly displaying "Eaten!", meanwhile the emult/echip ones... Just don't do a dang thing. what, exactly, are we missing here?
if context.joker_main then --score Xmult
return {
xmult = card.ability.extra.Xmult
}
end
if context.end_of_round and context.cardarea == G.jokers and not context.blueprint then --is it the end of the round? NOM
card.ability.extra.Xmult = card.ability.extra.Xmult - card.ability.extra.decay
if card.ability.extra.Xmult <= 1 then
card:start_dissolve()
play_sound('tarot1')
return { instant = true , message = localize('k_eaten') }
end
end
end```
is there a way for a lovelypatch to just straight up replace a pattern instead of adding to it
What's the localization entry for booster packs? i can't find it anywhere in the docs
let's say you type G.play
what does the G. mean?
It's k_eaten_ex
position = at instead of after or before
okay now my comrade joker is balanced
It means that G.play is a variable of G
but why G?
game
i see
russian girlfriend said "i like how it says that everything is free"
naninf runs be like
ah, that makes sense. still unsure why the Emult/Echips version just... fails to eat the food though once it hits 1
if context.joker_main then --score Emult
return {
emult = card.ability.extra.Emult
-- message = "TEST",
}
end
if context.end_of_round and context.cardarea == G.jokers and not context.blueprint then --is it the end of the round? NOM
card.ability.extra.Emult = card.ability.extra.Emult - card.ability.extra.decay
if card.ability.extra.Emult <= 1 then
card:start_dissolve()
play_sound('tarot1')
return { instant = true , message = localize('k_eaten_ex') }
end
end
end```
I made it fair tho so if you sell the joker it removes the penalty
crustulum:
i want to try to make a deck
Guess I'm nobody
SMODS.Back is for decks
fair enough
i only ever made jokers, so i'll need to research a bit more, yes
unless you like it why would you want to play balatro thats just reroll simulator
Thereâs nothing such as SMODS.Deck LOL
its Back!!!
Kind of simple
bump
Check other modsâs localization file
to access the atlas of said back, is it the same way?
this is how i organize my art
im pretty sure atlas functionality is completely identical for everything
How to make card get back in hand after scoring?
except ig that blinds ignore y position because theyre animated
Spritesheet is more efficient
not with me
No idea
the entirely atlas system is definitely built around having larger spritesheets over singular images
71x95
for deck back?
so 140 x 190 for 2x
Only blind icon and mod icon is 34x34
142
oh, i need to design the mod icon too
For mod icon you just need to make an atlas and name the key âmodiconâ
Smods loads it for you
Px and py =34
how do you make something happen everytime a joker triggers/a card scores. More specifically, call the play_sound() function.
when putting it before the return of a if context.individual, it just does it once
I think you can return sounds to play now
yeah but it's like an sfx that's longer and over it
If youâre playing sounds inside calculate
- there is another function that goes with it
Calculation happens before animation
i'll try something before asking for help
but it should be SMODS.Atlas and then SMODS.Back right?
So the sounds must be playing all at once at the start because youâre just calling the function that plays a sound
Instead of integrating it with the event system
then how do i implement a sound and a G.[variable] change in the event system
What variable change are you trying to do
becahse there is G.[imaganame] = x (where X is the number of frames the image stays on screen) as well as the play_sound
its a custom, newly made one
i can DM you the code but its kinda complicated since it also handles GIF displays
I would rather you describe what youâre trying to do
okay so i have a joker that does +10 mult for each stone card scored
i want it so that everytime a stone card scores/the joker activates, the image displays and the sound plays
i may change the joker's effect but it'll still be on scored cards
Well, the sound should play at the correct time if you return the sound youâre trying to play
I donât know off the top of my head but I think SMODS has a key for it
well it only plays the sound/displays the image once but it still waits for it to be the first stone card scored
iirc the key is directly sound
I mean that matches what you want no?
but i kind of want to keep the original mult sound too... I also belive that it won't solve hte image dispay problem
I think I know how to keep the original sound
{mult, extra = {sound}}
Something like this should work
no, each time a stone card scores, even if there is 5 of them, it will only activate once
That sounds like a coding error to me
Do you get the Mult five times?
lemme show u
yes
making me doubt
gonna retry
if context.individual and context.cardarea == G.play then
if SMODS.has_enhancement(context.other_card, "m_stone") and not context.other_card.debuffed then
G.ltg = 60
play_sound("tao_vineboom")
return {
mult = card.ability.extra.mult, -- Give +10 mult for each stone card scored
card = other_card,
message = "Pierrin' my shi'"
}
end
end
end,
Well, you arenât returning the sound
yes cuz im was using the play_sound function since the sound would replace the original sound
wait imma first see if the joker actually gives +10 fopr each stone cards
yep
only 1 img
1 sound
but all mults
like that ?
Deck names are weird
yup yup
Someone recently had this issue
SMODS.Atlas({
key = "purplish",
path = "d_purplish.png",
px = 71,
py = 95,
})
SMODS.Back {
key = "purplish1",
pos = { x = 0, y = 0 },
config = { discards = 1 },
loc_vars = function(self, info_queue, back)
return { vars = { self.config.discards } }
end,
}
okay so, sounds plays five time but the image is still once but not sync
I explained why above
yep but how do i display the image then ?
Starting from here
Specify atlas=âatlaskeyâ in deck
Hold on
alr
And name=ânameâ
Try something like this to see if you can have both sounds
didn't i do that? i'm not understanding
In SMODS.back
You need a localization file
Or well
I think you can define localization in the object itself, usually
Loc_txt
I prefer having a single localization file
no custom sound sound at all
well, i haven't set the localization stuff yet
i want to fix the atlas first
then i'll add the entry in the localization file
Atlas=âatlaskeyâ
Weird. Sounds like a bug. What if you do
{sound, extra = {mult}}
Add this to your SMODS.Back
Not like this
Have just the sound outside, and the rest inside
You forgot the message but yes
yeah deleted it cuz i realized it did +10 mult then the lessage
and doesnt matter for now
no custom sound
i'm sorry, but where do i add this?
my bad
in SMODS.Back?
Try adding a message next to the sound
{sound, message, extra = {âŠ}}
okok thanks
đđi literally said it twice to add it to SMODS.Back
Like literally here đ
SMODS.Back {
atlas="purplish",
key = "purplish1",
pos = { x = 0, y = 0 },
config = { discards = 1 },
loc_vars = function(self, info_queue, back)
return { vars = { self.config.discards } }
end,
}
i'm a lil slow sometimes, i'm sorry :,)
now how in the hell do you display the image knowing that its displayed by G.ltg = 60
like this?
I have two suggestions
But first
Should work
I need to know how does the image work
Just give me an idea of what the variable is doing
The answer is about the same
But if you want it to look a specific way Iâll know better what to suggest
whats not working? Im trying to make it so a hand with three of a specific rank increases a percent that the joker reduces blind size by
i gotta fix the text first lol
then fix the config, but so far so good, thank you!
Nice art
oh, thank you ^^
perkeo
me too
it's pissing both me and my ocd off
What if there are no valid cards
dms sent btw
kw i can rework this to suit it probably works better
I canât read the TXT file on mobile
tech you can if you download em
no, you were the first
care to send the joker's effect?
Hello good people, does anyone happen to know how to unrestrict the characters one can add to a text input?
i can't find the consumable tooltip list, is there any?
I think itâs hardcoded
i made the soul tool tip work, but for wheel didn't work
Hello, how can I print/log things to help find what crashes my game on startup ?
Can i see ?
b_jgbt_purplish1={
name={"Purplish Deck"},
text={
"Starts with both a {C:spectral,T:c_soul}Soul{}",
"card and a{C:tarot,T:v_wheel_of_fortune} Wheel of Fortune{}",
"but gives {C:attention}#1# joker{} slots",
},
}
Suggestion for a description more in line with the way Local makes 'em:
Start with a Soul and
a Wheel of Fortune
-2 Joker slots
I have seen people disable the restrictions.
I want to know where those are made.
i think bepis knows
@manic rune, then.
bro, of fucking course i got chicot from the soul
error(âmessageâ)
Or print
@stray swan So I think thereâs two (or three) ways to achieve what you want
Iâm not sure the extent to which theyâre different
But itâs all about Event timing
The easiest one to try first is to return func and have the function set the variable value
If you want balala to immediately crash, error, otherwise use print or sendDebugMessage("message","logger")
"The Soul" tbh
I think in theory itâs supposed to execute function during animation, but Iâve seen it act weirdly
but why isn't the wheel's tooltip working ;-;
here
V_ ?
Are you sure
wheel of fortune voucher real
Also check for Uppercases
thats so cool i didn't know you could do that
See if the timing works
can't test it rn, will tell u when its done
after some reworking, hows this
should it be c_wheel_of_fortune?
why wont this work?
Presumably because there are no valid cards
I love checking nils
How to get all unlocked hands as table?
oh wait think i missed something lmao
By that you mean avoiding secret hands right
thank you
Np man
maybe
Yes or no
yes
Take a look at Moody from my mod
i read "mil fs"...
There we go
It handles that internally
So you should be able to find out how to retrieve a table
brain autocorrected it lmfao
âat least threeâ or âat least 3â is how Iâd write it
Would you play my game if it was like balatro but with a lot of glitches
I might remove âat leastâ actually
I was wondering how you managed to do that...
I understand now

Yeah I think if we write in a localthunk way it would be "if hand contains 3 scoring Club cards", with 3 in yellow
So, i just use G.GAME.hands but this doesnt works(
SMODS.smart_level_up_hand(card, pseudorandom_element(G.GAME.hands, "othala"), nil, -1)
Did you look at Moody?
Idk the new SMODS function but it might expect something specific
I just wanted to know why G.GAME.hands is not working
Like names
G.GAME.hands is not integer indexed
G.GAME.hands use names or keys?
Well recycling half joker's writing it would be "if hand contains 3 or more Club cards"
Yeah Iâll fix that
Not showing Negative Numbers here is nice and all, but I kinda depended on the Number actually going Negative đ
is it possible to increase the negative chance?
keys but the names of the pokerhands in english are the same
Which is why I donât suggest vanilla wording :P
So, whats problem here
.
pseudorandom_element only works on arrays
I kinda like keeping vanilla wording but I wouldn't want to force my opinion on anyone lmao
G.GAME.hands is not array?
no
no
G.handlist would work
check to do list
i ain't going to lie, i figured this would cause a crash đ
time to make half joker viable
it works, thanks a lot
Unfinished mime art
4.5x by doing nothing is lovely
hell yeah
wait, chat
how do i increase negative rate on the shop? i want that to be a feature of my deck, since it only has 3 joker slots
can i start off of this?
Vanilla is inconsistent
ok im back, does it need a return ?
You can make basically everything a 0.5 value
Except for Ante
Ante only wants full numbers owo'
i don't really care about vanilla wording as long at it seems clear enough and there isn't a way to reword it to be smaller (and still clear)
me omw to buy an 8 ball with 0.4453 joker slots left
I think clarity and conciseness are the most important, followed by accuracy
I had written more about this but I think it was in the localthunk channel
i think you'd love the way i word my jokers
@zealous glen
I prefer flavorful wording occasionally
ow my eyes
way too many words
Also yeah it violates conciseness
I wish the localthunk channel existed because I liked how I had written it
I had found three words starting with C
Clarity, conciseness, and
Ah, consistency IIRC
I think later I added two non-C words
Something like flavor and accuracy maybe
But I think clarity and conciseness are the most important
Consistency is important to create clarity, but
It can also create wording templates that are difficult to parse, thus reducing clarity
but but... how do i make it so that nat negatives in the shop have extra chance...?
Naturally you can opt to prioritize consistency over clarity
or is it even possible?
I donât know
I recall reading something in the recent SMODS release
But idk if itâs relevant
cryptid does it so check that out ig
I think it was about per-item weights
let me see
I mean I can imagine how Iâd try to do it
Which is by manipulating the weight parameter of the Edition
But idk if thatâs the recommended way of doing it
i think you could make the chance of getting a negative when an edition rolls at all higher, but the rate of any edition rolling is a fixed value afaik
i was looking at the tarot merchant to see if i understand how to implement it on my deck (or get an idea from it)
defeating a boss blind gives a negative tag
would that be possible? since yknow, anaglyph deck
yes
Yes
plagiariasm at its finest
if context.round_eval and G.GAME.last_blind and G.GAME.last_blind.boss then
G.E_MANAGER:add_event(Event({
func = function()
add_tag(Tag('tag_negative'))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end
}))
end
end
all i did was change tag_double to tag_negative
context.round_eval is when you are receiving the money from the boss blind and the last two G.GAME are to specify if you are in the boss blind?
anyone know what's causing this crash on my spectral card?
can_use = function(self, card) -- line 17
local has_ethereal = 0
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].ability.chak_ethereal then
has_ethereal = 1
end
end
return G.jokers and #G.jokers.cards > 0 and has_ethereal = 1
end,
use = function(self, card, area, copier)
local chosen_joker = pseudorandom_element(G.jokers.cards.ability.chak_ethereal, 'realize_choice')
local deletable_joker = pseudorandom_element(G.jokers.cards not chosen_joker, 'realize_choice')
local _first_dissolve = nil
CHAK_UTIL.use_consumable_animatio(deletable_joker, nil, function()
SMODS.destroy_cards(deletable_joker)
return true
end
)
CHAK_UTIL.use_consumable_animatio(chosen_joker, nil, function()
chosen_joker:remove_sticker('chak_ethereal')
return true
end
)
end
G.jokers.cards.ability.chak_ethereal is the sticker ability table, idk why youre doing pseudorandom_element on that
well i want it to pick a random ethereal joker
but the part that's crashing it is the can_use
i mean the crash says that its coming from utilities/misc_functions.lua at line 8
could you show that file too?
you specified the path wrong i think
hmm
if i get rid of the can_use it loads
config = {joker_slot = -2, consumables = { 'c_soul' , 'c_wheel_of_fortune' }, chance = 0 },
how do i check what number does chance has? card.ability.extra.chance is only for jokers, no?
wdym
usually cards use odds
you can have any values on any card
bruh, the way i convey words is just so fucking weird
return G.jokers and #G.jokers.cards > 0 and has_ethereal = 1
this looks weird lol
dunno if you can do the variable setting like that
ohhh yeah it should be has_ethereal == 1
fuuuck
so, when making a joker, in the config, if you want to use any variable, you need to use card.ability.extra.variable_name, correct?
i always forget the other =
i mean if you put the variable in extra yeah
the entire card config field is copied to card.ability
is it the same with decks?
yes
thank you, all i needed
it should be the same with all centers
Code should yell at you for trying to set a variable in a statement, lol. Do you have any kind of warning suppression on?
i don't have that on because the lua vscode extension doesn't know anything about smods and other misc utils i make myself and i don't care to set it all up lol
Personally, i just have my workspace to be my Mods folder, it usually makes everything work
yeah i do that too
even then it would still scream at you
it never screams at me
because you cant set variables in a return
if you have syntax error suppression then you will get nothing
which is usually why I'd avoid doing that
I was wondering how you'd set up definitions for Balatro functions and SMODS functions
That'd be super handy
thats normal
thats ugly
grinds my gears...
i mean, i have some suppression on for when i hook functions, but thats single line
Ive finally coded all 24 spectral rune cards
poop_butt.lua nice
i mean, if you suppress everything, you might as well use np++ or something
i like the vscode ui
still, seems like a bad idea
it's worked thus far
I think I also get mine looking like that
Even though I tried to add Balatro and SMODS so VSCode would know their functions
I have Balatro in the same workspace and it still tells me the Balatro functions donât exist
i have balatro, smods, and lovely all in the same workspace
apparently all their functions are heresy of the divine lua gods and thusly have no god given right to work
calculate = function(self, back, context)
if context.setting_blind then
G.E_MANAGER:add_event(Event({
func = function()
card.ability.extra.chance = math.random(0,1)
message = localize("Rolling...")
end
}))
is this gibberish?
according to the lua extension yes
I mean my vscodium looks like this, i don't have suppression turned on at all, except for some single-line suppression for hooked functions
youre one of the luck ones
i think you need an end at the end of your calculation function?
or did you mean something else
there is, yes
i'm tryna make a 1 in 2 chance of giving a negative tag upon beating a boss blind
Youâre not cooking
Donât use math.random
calculate = function(self, back, context)
if context.setting_blind then
G.E_MANAGER:add_event(Event({
func = function()
card.ability.extra.chance = math.random(0,1)
message = localize("Rolling...")
end
}))
end
if context.round_eval and G.GAME.last_blind and G.GAME.last_blind.boss and card.ability.extra.chance == 1 then
G.E_MANAGER:add_event(Event({
func = function()
add_tag(Tag('tag_negative'))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end
}))
end
end,
since i don't know how to do the whole chance part, i'm doing it in other ways, also trying to figure stuff out on my own
uhhhhh oh uh you dont have card defined
Use pseudorandom
i figured
how do i do that?
oh, yeah also dont use math.random lol
gotcha
Check vanilla remade wiki
Because math.random is always random
can i look at wheel of fortune chance stuff? for the whole 1 in 2?
But pseudorandom takes a seed which has always the same outcome
Yes
Take a look at the previous releaseâs release page
It discusses the new probability functionality
yeah, card here is undefined, the calculate function doesn't have a card. Did you mean back? Maybe just take another look.
(SMODS.pseudorandom_probability(x, y, z, w))
something like this?
ignore the xywz
i got it off of wheel's
pseudorandom_probability is for probability effects that can be detected/modified by other cards
got it. oops affects it?
interesting
what does each slot do tho?
the x, y, z and the w
SMODS.pseudorandom_probability(card, 'vremade_wheel_of_fortune', 1, card.ability.extra.odds)
originally copied it like this
i understand the 1 and extra.odds
what i don't get is card and vremade
if you have it in vscode, you can hover over the function to see what it does
first is the source object, then the identifier/seed, then the numerator and denominator
actually, this is outdated, i should put in a pull request to have it updated for latest smods
because here the 1 wont be updated by oops
this is a deck that has 1 in 2 chances give you a negative tag on beating a boss blind
okay, well then definitely replace all mentions of card with back, as you aren't making a joker or anything
got it
tbh i'd look at a mod that has some kind of random functionality (thats updated) to get a better look at it
its not updated
shit
If you want, you can take a peek at mine, since i have one thats properly done
please do show
but following the logic
(SMODS.pseudorandom_probability(back, b_jgbt_purplish1, 1, 2))
this would technically work?
purplish1 is the key of said deck
the key does not matter, the second argument is just a seed, which is a string. so make sure its a string
"test" got it
And then after, technically yes, however it would break with an Oops or anything that messes with probability
if you just want the numerator to be 1 under most circumstances, you can replace it with G.GAME.probabilities.normal
i don't want it to be affected by oops
and then for the denominator, you'll want to use a variable, defined like config = { extra = { odds = 2 } }
why wouldn't you?
guaranteed neg tag on beating a boss blind on a -2 joker deck
i want it to be a miserable deck /hj
inconsistency be damned i guess
so it's not card.ability, it's back.ability.extra?
yes, since card isn't passed, back is.
guyts
whats that thing aclled
when you look at aj joker
and it says like
create a tarot card
and then displays the tarot card
how do i do that
shit
info_queue
try spelling things correctly đ
info_queue in loc_vars, you should look at vanillaremade for examples of it
i play balatro, i cannot read :(
The guy above you

mmm yummy bananan
is there anywhere you cant use a gradient in place of a colour? or can it actually be used everywhere where a colour is expected
tryitandsee
good point
it's still crashing, on line 18 still
unless you post the full code, line 18 is meaningless
oh true
0/10 helpful
average modding dev interaction
if context.round_eval and G.GAME.last_blind and G.GAME.last_blind.boss and (SMODS.pseudorandom_probability(back, "test", 1, back.ability.extra.chance)) then
is that fucking "test"
idunno why i felt like saying this but after a few weeks of modding the game I wanted to thank everyone here for helping people all the time u guys are awesome
can you post the crash log? when is this crashing?
i feel the same way
if it wasn't for this chat, i would've never gotten any of the stuff i did done xD
same pretty much
4
edit: typed 4 on accident
the
the full crash log
please just post the lovely log
its in Mods\lovely\log\ and its the latest one
yeah
sorry for being slow lmfao, i was not understanding
and then can you post the full deck code?
ofc
key = "purplish",
path = "d_purplish.png",
px = 71,
py = 95,
})
SMODS.Back {
atlas="purplish",
key = "purplish1",
pos = { x = 0, y = 0 },
config = {joker_slot = -2, consumables = { 'c_soul' , 'c_wheel_of_fortune' }, chance = 2 },
loc_vars = function(self, info_queue, back)
return { vars = { self.config.joker_slot } }
end,
calculate = function(self, back, context)
if context.round_eval and G.GAME.last_blind and G.GAME.last_blind.boss and (SMODS.pseudorandom_probability(back, "test", 1, back.ability.extra.chance)) then
G.E_MANAGER:add_event(Event({
func = function()
add_tag(Tag('tag_negative'))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end
}))
end
end,
}```
uhhh because you need to put extra stuff in extra
like i said earlier
config = { extra = { odds = 2}}
ooohhh
config = extra { {joker_slot = -2, consumables = { 'c_soul' , 'c_wheel_of_fortune' }, chance = 2 }},
this?
obviously i didn't add a =
okay so my mod crashes on one pc but works on another what on earth is happening its specifically a consumable that triggers the crash i have the crash log if that helps
config = {joker_slot = -2, consumables = { 'c_soul' , 'c_wheel_of_fortune' }, extra = {chance = 2 } },
the crashlog
the variables should be added with an extra then?
thats how it works with everything else
can you post the actual crashlog? Found at Mods\lovely\log\, and the latest log
oh yh hold up
what about the "test" as pseudorandom_probability? do i leave it like "test" lol
its a seed. it doesn't matter
its like putting orange in your minecraft seed when you generate it
changing it to purplish_deck then
idk what is going on with it, or what a new pc is doing wrong
same crash...
do you need galdur and talisman for your mod to work?
no i just use them
turn them off
talisman may be required soon tho with how its looking but okay
if your mod doesnt work with galdur then theres a problem with your mod lol
i dont even remember what galdur does
yeah these are the things i normally use
galdur's bate
just reinstalled everything on a new pc tho
thanks
yeah that didnt work
whats the new crash log?
also, can i see your probability code example?