#š»ć»modding-dev
1 messages Ā· Page 192 of 1
the stuff in your config gets attached to the actual card ingame
which is why you're able to do card.ability.extra.mult
you don't really need it
oh, so i was useing the actual text to define the mult, which i did not need to do at all
lol
i get it
but it's encouraged so if you want to change it at some point you just change it in one place
oh
I mean the extra stuff, not the text
im sure you explained it really well, im just not getting it lol
Also, stuff in your config are the initial values for the card, so that will be locked to the same value always
if you didn't get it then I'm not explaining it well lol
so for it to work I need a return
This is a bit outdated so
ive been useing this
In the return section of every calculate, whenever it says mult_mod you can just do mult and remove the message
lets see, i think i got it
would removing the message remove the popup that tells me the added mult?
nope
Done spritework, time to figure out how to do enhancement gates and unlock conditions for custom jokers
oh
steamodded automatically handles the message for you
nice
returning mult is automatically handled
those are just outdated examples unfortunately
bummer
so it no longer crashes
but now it does nothing
key = 'Clint',
loc_txt = {
name = 'Clint Eastwood',
text = {
'Gain {C:red}Mult{} equal to the {C:blue}value{}',
"of the next {C:attention}card{} in the deck.",
"{s:0.7}''The future is coming on,",
"{s:0.7}It's coming on, it's coming on''"
}
},
atlas = 'Clint',
pos = {x = 0, y = 0},
effect = "Mult",
cost_mult = 1.0,
config = { extra =
{
mult = 0,
}
},
loc_vars = function(self,info_queue,center)
return {vars = center.ability.extra.mult},
{mult = (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11)}
end,
calculate = function(self,card,context)
if context.joker_main then
return {
card = card,
mult = card.ability.extra.mult,
color = G.C.MULT
}
end
end
}
oh
i see
return {
card = card,
mult = (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11) ,
color = G.C.MULT
}
that might fix it
you only need to specify mult btw
hello, i want to create an effect on a joker for it to randomly destroy a common joker at the end of the round and i am stumped on how to do it. i attempted to create a list and add all of the common jokers you currently have to it, but it keeps crashing the game whenever i include it. i might not understand how to define local variables/lists in lua. can anyone help me?
hehe, animated joker sprite. Objectively I probably could've used the AnimatedSprite for this, but I ended up just using sprite pos on a large atlas texture
I GOT IT TO WORK
THANK YOU
theres proably a lot of code that i dont need
but yay
i've read back some logs and seen someone say "if all else fails, copy the madness code" which might help, but i do not know how to find that lol
card.lua in the game's files, you can find it by extracting the game's exe file with 7zip or similar programs
this seems pretty inefficient, you could instead just try and loop through all currently owned jokers in your deck and check if its a common joker and add it to an array that you can choose from randomly to select which joker to delete
this too ^
just check if the joker's rarity is == 1
this is what i am currently trying to do
i've searched for "madness" but i cannot find the source code
in card.lua?
i found it right here
i would appreciate help on how to do this. soz if i come off as kind of cold, but i am so dialed in rn learning lua and this engine at the same time lol
like, i think i'm looking in the right spot but ctrl F is not getting me to where it talks about it
ok i found it
So the unlock condition works correctly, but the text only displays the values when I hover over it
oh wait I swapped the values too lmao
dont worry you dont come off like that at all
if context.end_of_round then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].config.center.rarity == 1 then -- ? i've never tried this and reading baseball card's code i think this is how it's done
-- destroy, no clue how to destroy the card and im not gonna try and look into it right now since i gotta dip like rn rn
end
end
end
alr, ty, i appreciate the starting point
What's the correct blueprint context for SMODS?
I.E. to stop blueprint from scaling itself when copying the effect of a scaling joker
wrap the scaling part of the joker's calculation with if not context.blueprint then
well then
turns out i've made a joker that makes skipping straight to the boss blind on every ante a valid strategy
is Card.base.value the rank's key?
well, my custom enhancement shattering scaled the wrong joker, this is why we test things
heya! tryna make a Joker that copies the effect of the first Joker acquired that run. I've got the Joker's key, how would I use that to copy the ability?
ty in advance!
I think I may need to create a new context? Because this is probably why it's scaling glass joker
for k, v in ipairs(context.glass_shattered) do
And as far as I know, find_card wouldn't work because I'm assuming the player doesn't still have their first Joker
hm, that actually sounds a bit difficult?
copying jokers rely on the joker it's copying to actually exist and be in the jokers area
I guess you could basically get all the various config values for the first joker's key, save its functions such as calculate, loc_vars, add_to_deck, etc, and then have your copying joker call those references to the copied joker?
That's how I would do it tbh
in theory you could make a hidden cardarea, then make it so your first joker moves to that card area when destroyed
it would be nice if you could just store a reference to the joker, but it breaks when saving/loading
is there a way to check if a player enters a shop?
Just when I finally think I know what I'm doing, this crashes with attempt to index field 'extra' (a number value) when I hover over
extra = {
x_chips = 1,
gain = 0.75
}
},
loc_vars = function(self, info_queue, center)
return {vars = {center.ability.extra.gain, center.ability.extra.x_chips}}
end,```
what would the context be for when a hand is played but before each individual card is scored?
I think I just need to step away and look at something else for a while
I have a joker that creates tags... how do I ensure it doesn't do this, which tries to upgrade a nil poker hand, crashing the game?
hello again, i have made it so that my joker destroys common jokers at the end of the round by using the madness script, but now i am not sure how to make it so it only does this once as using context.end_of_round is causing it to trigger 20 times. would appreciate some tips on how to fix this š
check for context.main_eval too
what does that do?
regardless of if u hav an explanation, it worked perfectly so ty!!
end_of_round is called for cards too so it ensures you're in the main joker evaluation
key = "greedy",
name = "omega_greedy",
config = {
extra = {
Emult = 2,
suit = 'Diamonds'
},
},
pos = { x = 0, y = 0 },
soul_pos = { x = 1, y = 0 },
cost = 50,
rarity = 'b_omega_omegacommon',
unlocked = true,
discovered = true,
blueprint_compat = false,
eternal_compat = true,
perishable_compat = false,
atlas = 'b_omegagreedy',
loc_vars = function(self, info_queue, center)
return {
vars = {
center.ability.extra.Emult
}
}
end,
calculate = function(self, card, context)
if context.cardarea == G.play and context.individual then
if context.other_card:is_suit(card.ability.extra.suit) then
return {
message = '^' .. card.ability.extra.Emult .. ' Mult',
Emult_mod = card.ability.extra.Emult,
colour = G.C.MULT,
card = context.other_card
}, true
end
end
end,
}```
Anyone know why this doesn't work
...why the , true?
joker retrig compat i think???
Im running into issues while trying to make a dollar version of Canio, I know I have to do something with context.remove_playing_cards
but I suck with Lua and I am so lost right now
Idk but with and without both don't work
it's eating me
Oops I slipped. (How do they look, is the yellow a bit too... not balatro yellow? Should I make red and black cards only and not assume everyone uses high contrast?)
Are they the Scarlet and Violet box icons?
Yea, they conveniently fit perfectly into Balatro card sizes
yea it looks nice, but a bit basic
I would've prolly made the box around the characters look a little different. Maybe just inward curving around the edges
It would be pretty easy overall to make the low contrast colors aswell, just fill tool
and of my friend group, half of them use low contrast
Yea, at the moment it's just using the black frame from the base game cards, recoloured. I would say I done a quick and easy job... but uh... I sort of made a whole mix and match your team thing with loads of pokemon.
But yeah, I didn't want to go too far down a hole of making my own fancy backgrounds when I'm aware there needs to be room for enhancements and things. So I tried to keep focus mostly central, so they'd work with whatever mods people use.
yea makes sense
guys i just got this fatal error, i dont know what i should do should I be scared?!?! /j
how do i use SMODS.Back calculate to retrigger cards
wait i got an idea
nope didnt work
ive got it triggering on the cards i want it to, but whenever it does it crashes, saying "attempt to index field 'ability' (a nil value)"
Hey y'all, I'm trying to implement a joker with a rotating rank similar to Mail-in-Rebate, but I'm having trouble with programming the code that specifically chooses the rank. This code is heavily based on the Castle2 code from the SMODS example jokers, and I believe I've made a mistake somewhere converting from suit terms to rank terms. As is, the Joker does nothing, as a valid rank isn't found.
-- WORDSEARCH JOKER SELECTION FUNCTIONALITY
local igo = Game.init_game_object
function Game:init_game_object()
local ret = igo(self)
ret.current_round.wordsearch_card = { rank = '14' }
return ret
end
function SMODS.current_mod.reset_game_globals(run_start)
G.GAME.current_round.wordsearch_card = { rank = '14' }
local valid_wordsearch_cards = {}
for _, v in ipairs(G.playing_cards) do
if not SMODS.has_no_rank(v) then
valid_wordsearch_cards[#valid_wordsearch_cards+1] = v
end
end
if valid_wordsearch_cards[1] then
local wordsearch_card = pseudorandom_element(valid_wordsearch_cards, pseudoseed('wordsearch'))
G.GAME.current_round.wordsearch_card.rank = wordsearch_card.base.rank
end
end```
Anyone?
heat?
(i did not make this art i just took the portraits from disco elysium and put a gradient map on it)
trying out retrigger_joker_check, this does nothing, what am I doint wrong?
Add to enable joker retrigger with your mod.
SMODS.current_mod.optional_features = function()
return { retrigger_joker = true }
end
how do i get certain card values to retrigger with the deck calculate()
check the code for Hack
ive gotten it to detect the values i want but the return{} never does it
done that already
well not hack
but sock and buskin + walkie talkie
the problem i think is those are for jokers while i want it for the deck
the sock and buskin code mentions "card.ability.extra.repetitions" but whenever i do something with that it says something to do with ability being a nil value
have you set repetitions in your config
hey stupid question, but where do I find all of the keys? I'm trying to replace default textures for all images and can't figure out where to look.
nvm i got it
had to change it to self.config.extra.repetitions
i had tried self.extra.repetitions and config.extra.repetitions
thanks!
finishing up a test mod- do i need to make a custom sprite before i can attach a png to the modded atlas, or can i route it to an existing image in the source code?
How do I replace text strings with a mod? I'm re-skinning all the consumable cards. Have figured out the art, but not sure where to find an example of changing strings.
Time to figure out how to set up a custom context for when my custom probability-based enhancement triggers
say, if we're making an edition, where do we put the code for it to do something? does it really just go in config?
Is there a "how to make a mod" tutorial? I wanna try adding something like a second shelf for jokers so that Blueprint is manageable in absurd runs with like 27 jokers
I have been unsuccessful thus far in my attempts at figuring out how to implement a custom context
The reason I (think I) need it:
don't need, just loop through SMODS.find_card(key) at the end of the round and add the value to them
well, even if it wasn't necessary I just figured out how to do it
still looking for pointers on this, the docs aren't clear what exactly is meant to make editions proc... ^^;
How would I add more "collab" things
do you mean like how cryptid does it
haven't played cryptid, but I mean like having an extra selection on the new face cards selections
instead of changing an already existing one
oh you mean friends of jimbo
thanks
chat hi i made another card
now we just need the xmult rankless/suitless card
and an xchip one
and the one that does absolutely nothing
Hey I have never modded anything before, but some of my buddies and I have stupid ideas we want to add to balatro. How would I go about starting? and any tips for a complete beginner?
Do you have other mods installed
I'm not great with the coding aspect
but I'll get you started
no i have 0 mods installed currently
ooh I love the sprite
let me dm
steamodded example mods might help https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua
install steamodded and lovely, and start reading the docs
thank you all for the help!
so glas joker checks for where context.glass_shattered, but I did Ctrl + Shift + F in the Lovely dump files and could not find any instance of it being set anywhere
card.shattered is something that's set by Card:shatter(), fwiw.
If I'm looking for a pattern with lovely patches, how can I tell it which instance of the line if it's been repeated multiple times?
the thing I'm trying to solve is, my custom x_chip version of glass shatters, and when it does it incorrectly triggers Glass Joker
and instead I want it to trigger the effect of my custom joker when it shatters
If I wanted to check for a full house, then compare the ranks of the 2 of a kind and the 3 of a kind, how would i do that
PSA: https://github.com/MathIsFun0/Cryptid/commit/53727c128c23f01f7d26aa44b9c2eb895fbeb0a5
Cryptid-refactor merged to main now
thanks !!!!! i made it : 3
this issue is also exclusive to shattering from natural play. Using Hanged Man to shatter my custom card does not increment Glass Joker. Only when it breaks from being in a hand does Glass Joker scale
patch glass joker to check for card enhancement?
I patched one check, but it looks like I missed a different one so we'll see if that fixes it
sure enough
How do you add cards to your consumeable area from a booster pack? I've tried select_card but it doesn't let me choose anything
YAAAAAAAY
ETA: I believe all interactions with this enhancement and joker are now working properly š«”
Is there a way to change the back sprites of jokers with SMOD functions?
like as in the deck?
The way that custom decks are declared, yes. I want to make a joker similar to e.g. Square Joker that looks different when flipped
bump
Does anyone happen to know if it's possible to do Splash-like functionality?
Your best bet is to add extra context to the pattern honestly
Wdym? Like recreate splash as a modded joker?
Kinda? The idea is Splash with a few extra steps. The main thing Iām after is the full hand scoring regardless of if they fit the hand type
You can look at the code for splash in the balatro source code I guess to get a start on the general idea
I did and I didnāt like what I saw, hence why Iām turning to here to see if anyone has cracked that code a bit better
Show me the code cuz I canāt check for myself since Iām on mobile
I just got in bed so no can do lmao
Oh lmao
But basically itās not handled in a calculate function, itās done during actual hand scoring (which makes sense but kinda tells you why Iām not a fan)
Should I keep or remove the indentation?
I donāt think indentation messes with it, though I usually do just for readability
If there are multiple instances of the pattern, does it replace them all or just one?
I will replace all of them unless you add a ātimesā value to the patch syntax. It will always start from the first instance of the pattern
Additionally, just to be sure, if it is surrounded by other text on the same line then it will still be replaced?
No. If your pattern is looking for one line, it will look for a line that is an exact match (not counting indents). Same goes for code blocks in the sense it looks for an exact match
Is there a way to get around this?
You could use regex but thatās a little more resource intensive
What are you looking to patch specifically? Just to get an idea
I'm looking to patch the tooltip loc_vars of the tarot cards that enhance cards and increase the amount of cards it can enhance.
been thinking of taking a break from my main project, expanding my horizons, and working on something potentially a little easier - balatro modding seems pretty perfect for me!
is there anyone currently making a genshin-themed content mod (beyond that one with element textures on the cards)?
that's what i'm thinking of doing but i don't want to step on anyone's toes if it's already a project
search for it in #1209506514763522108
Even if someone is donāt let that discourage you. Thereās plenty of mods out there with duplicate themes or ideas
ty! i did & got that one result for a texture mod, but i was asking just in case someone here is working on one and hasn't published it yet
hehehe i understand, i just like to try and develop unique things you know? that's more motivating to me xD i think i'll probably go through with it since I haven't found much on it yet and i already have a few ideas~
Speaking a bit beyond my experience, but are you sure that's not something you can access at runtime? It looks like cards like magician use the number as an argument in their localization text
"Enhances {C:attention}#1#{}",
"selected cards to",
"{C:attention}#2#s",
Would just changing c_magician.config.max_highlighted do the trick?
I totally understand and feel that lol
or i could just patch:
self.ability.consumeable.mod_num+(G.GAME.enhance_bonus or 1) >= #G.hand.highlighted
Actually Iāve done something similar with one of my cards. Lemme get you a link to the file I have for it
The Hanged Man section is probs what you should look at
nvm i got it working with regex
So now it goes there, but there's nothing there (no cards)
but still shows the counter has increased?
it's strange
chat why does this joker work
i figured out i could just do this for graveyard so i can arbitrarily check parameters of cards
functions are just variables hee hee hoo hoo
Would it be a bad idea to call the calculate functions on jokers manually with my own context?
Uh
Not really, but SMODS.calculate_context allows you to do that already
Yeah that's a scam
<@&1133519078540185692>

Just call SMODS.calculate_context with your own context
hello mario
Ah, okay, I was trying to find a function like that in the docs but I missed it, thank you ^^
i do this here to rescore all jokers
the added context flag avoids an infinite loop
Honestly there's a chance it's just undocumented
At this point I just look at smods source so I don't know what's in the wiki anymore
fellow ctrl shift f user
honestly I just use grep
Funnily enough, I did find eval_this and, while being a thing I was not looking for, was also yelling at me that it is deprecated
grep users where
š«”
i love that my stupid name for that function stayed btw
Cause it is.
Funny enough it was not indicated correctly.
Thereās a calculate context for this now I just havenāt got round to documenting it yet, maybe today who knows
Surely today wonāt be eaten by new Cryptid update or SMODS beta setup (clueless)
I have no idea how you motivated yourself to do all the lsp stuff, writing docs is dull as hell
speaking of @edgy reef I actually am using those right now and they're proving helpful so ty for that!
how i increase the interest payout
like $2 every $5, but still cap at the same amount of $25
(I haven't coded a Balatro mod before but) perhaps look at how To The Moon works?
Should be as simple as setting G.GAME.interest_amount = 2
indeed it was
i did do this but i think the method used in jokers is different
(i looked at golden specifically)
to the moon is the joker that does exactly that
oh wait
i was thinking of rocket lmao
for future reference where do i find the vanilla jokers that arent in the example doc
in the game executable; 7zip can open it
obligatory ty even if i misremembered the joker name
i have that, do you know the name of the folder/file?
C:\Program Files (x86)\Steam\steamapps\common\Balatro\Balatro.exe
i meant i have that file open
most joker effects are in card.lua
but its worth extracting the whole source so you can refer to it
treat it like documentation for itself, as that is what code is
most joker functionality is realized within the Card.lua file but i'd recommend reading the lovely dump of the file in %appdata%/Balatro/Mods/lovely/dumps/ instead due to how much of the code is changed by SMODS
yeah ive extracted it just couldn't find the file with the code that runs it, i checked main and game but not card
got it now ty
Pls...
how do you make a blind that has effects that occur after a hand scores
hello, I've just started out, can anyone share with me the available guides and docs? I've found the steamodded documentation, but I still cannot figure some things out.
Here.
A repository with examples of some stuff.
If you still don't get how something works, ask about it.
Now my question: Is there a way to have a joker trigger it's effect immediately after being bought/created?
nevermind, got answered elsewere
nevermind2
huh?
thank you, I've come across this already it sadly still didn't answer my questions.
Are there easier ways to test things than just using them ingame?
not really lol
you can use #1228149931257237664 if you don't want to reroll for them etc though
I've also been trying to insert the joker i've made into a deck, but I keep getting crashes when I'm trying to create a card using it's declared key
So let's say that I declare a joker with the key "my_joker", i would need to create the card using
create_card("Joker', G.Jokers, nil, nil, nil, nil, "my_joker") right?
You need your mod's prefix first.
iirc create_card is mainly used for joker effects, the easiest way to give yourself a joker is by using either first round joker or DebugPlus
j_[your_prefix]_[your_joker_key]
oh thank you very much, both of you.
looking for feedback on this graveyard counter ui
-# the (27) at the bottom, if unclear
Whats the standard joker size?
71x95
Thanks
I feel like the graveyard counter would make more sense on the right than on the left? š¤
the deck counter defaults to that position; i figured err on the side of not pissing off people used to vanilla 
ā¤ļø
i tried it first and i didnt like it and i dont consider myself a vanilla purist to any degree so
ah okay
Omg cryptid new calc is live will people finally stop developing on old versions now š¤
ill just have to find a way to make my mod work with that i guess
exactly
people will finally stop complaining about Cryptid crashing their game because they downloaded the wrong version of Talisman
and Steamodded
you guys seem to have way too much faith in people
no now people will just complain that they downloaded thac and talisman together
š
i can't have faith anymore can i
like someone is gonna develop on old-calc just because Jen's is still on old-calc
why does cryptid not work on smods 0.9.8 its the latest release
SO TRUE
š
THERE IS A BIG TEXT SAYING "DON'T DOWNLOAD THIS"
98%
is there cryptid on 0.9.2
literally 3 days ago #āć»modding-general message
šššš
if you didn't read the giant text you deserve to get stung
i don't get the 98% can someone explain
i can't read
sorry got distracted
here's what this looks like, for the merit of its attempt
I like it, idk about you
is it possible to get it underneath?
not with the method i'm using currently
oh underneath might not be bad either
oh but yeah underneath actually isnt that hard one sec
Just ran into this issue:
Which corresponding to this part:
However I did check nil at the very start of the function:
Now I don't know why is this happening.
_c.key is nil, not _c
How come something in this game doesn't have its key?
idk why it happened, only that it happened š¤·āāļø
isn't _c just a card?
And, if there is a card not having a key, how do I identify the card that caused the problem?
I dont think a card object will ever have a key
it's within the center of the object
this is gonna be fun
You mean like _c.center.key instead?
š„²
_c.config.center.key
heya Eremel, I'm trying to use retrigger_joker_check, but Mods that only use Events for their joker and return nothing don't get retriggered
yea im jus gonna create a table and use my create card hook to check when new cards appear
they need to return nil, true
seen PokƩmon
honestly i thought i never needed this again
damn.
I don't think there's any other clean way of knowing if a joker was triggered or not
nvm underneath is a nightmare
hey uh does anyone know any guide for how to make mods? i genuinely cannot find anything, there is only one youtube tutorial that misses a lot of things that need to be addressed
and outside of youtube i am either too blind or have also not found anything
this
thanks you are my saving grace
hello friends
calculate = function(self, card, context)
if G.GAME.current_round.hands_left == 0 then
if context.retrigger_joker_check and not context.retrigger_joker then
return {
message = localize("k_again_ex"),
repetitions = card.ability.extra.repetitions,
card = G.joker.cards,
}
end
end
end
the compounds in my brain are being decomposed (trying to retrigger all jokers)
is there a context for checking when the player enters the shop?
no
I'm trying to make a joker that removes the enhancement from Stone cards, and then adds 50 permanent chips to the card. I've cobbled together this code based on the Vampire and Hiker jokers, but then the game crashes when the Stone card's enhancement is removed. What should I do to fix this?
calculate = function(self, card, context)
if context.cardarea == G.play and #context.full_hand == 1 and not context.blueprint then
if SMODS.has_enhancement(context.other_card, 'm_stone') and not context.other_card.debuff then
card.set_ability(G.P_CENTERS.c_base, nil, true) --Remove enhancement from playing card
context.other_card.ability.perma_bonus = context.other_card.ability.perma_bonus or 0 --idk what this bit does
context.other_card.ability.perma_bonus = context.other_card.ability.perma_bonus + self.ability.extra --add permanent chips to playing card
return {
message = "Chisel!",
colour = G.C.CHIPS,
card = self
}
end
end
end```
Try changing the period to a colon in the set_ability
should be card:set_ability

Okay
the base center is still a center, and a card can't just not have one
I think I might've mistaken it with an another function ^^"
Okay, the change to a colon now stops a crash from that part now. Unfortunately, the part where permanent chips are added causes a crash:
attempt to index field 'extra' (a nil value)
context.other_card.ability.perma_bonus = context.other_card.ability.perma_bonus + card.ability.extra.big_bonus --add permanent chips to playing card```
Is there something fundamentally wrong here that causes the crash?
What does the config table in your joker look like?
heartbreaking
config = { extra = { big_bonus = 50 } }
there will be soon
ty for the info!
@wintry solar sorry for the ping but i honestly still cannot figure out how to make it work with retriggers
what's it supposed to do?
Retrigger the rightmost card per scored ace (including retriggers like chad or seal)
if context.individual and context.cardarea == G.play and context.other_card ~= context.scoring_hand[#context.scoring_hand] and context.other_card:get_id() == 14 then
card.ability.extra.repetitions = card.ability.extra.repetitions + 1
end
if context.repetition and context.cardarea == G.play and context.other_card == context.scoring_hand[#context.scoring_hand] then
return {
repetitions = card.ability.extra.repetitions
}
end
if context.after then
card.ability.extra.repetitions = 0
end```
what was i doing wrong?
you're doing everything in the individual context
Is there a way to prevent the transfer of Negative edition from one playing card to another (via Death, Cryptid, DNA etc.)?
(yes, playing cards)
- prob via lovely patches
- why exactly would u ever need negative edition in the first place
good morning everyone
bestie its fuckin 10:25pm
sounds like morning to me ā¤ļø
Negative playing card is technically a +1 handsize and you can apply it to a card you always wanna keep in hand like steel or gold or blue seal
It's very useful
Or just your most pump up card for the powerful poker hand play
i think that will require a patch, as smell has said, you will have to edit the code of Death, Cryptid, and DNA so that they will remove the Negative edition from the new cards
Like polychrom red seal
So manual? I see
I dont see why you'd want a copy effect to strip certain editions
true
For the same reason you can't copy negative edition on jokers
i mean, jokers are fundamentally different compared to playing cards because they are literal powerhouses, you can just make negative playing cards somewhat rare honestly
What's the point of a spectral card that gives negative to a playing card if after just one use it becomes pointless?
a negative steel card isn't as good as most uncommon jokers when they are negative (i love lucky cat), but if you still want to do it then sure
Sure, negative playing card isn't as strong as a negative Joker but the payment is less smaller
-1 hand
how is it pointless after one use
Just use death, no reason gain more -1 hand
that patch alone would certainly make some strategies in other mods worse btw lol
I genuinely have no idea what you're on about
I'm talking about a spectral card from the mod I'm working on
that's all
honestly, id never pick exchange
I feel -1 hand is an extremely bad downside
mhm
I don't think this should be free either
look at black deck and see how -1 hand made it extremely annoying to play with ā¤ļø
yeah I feel like you're vastly overestimating the power of negative on a playing card
and if you do keep this downside, you should absolutely be able to copy it to other cards
Then there's no point in using this spectral for the rest of the run
either that or you are underestimating how big of a drawback -1 hand is
also super late to this but I'm not sure what could be going wrong - I'd suggest putting for k, v in pairs(card.ability) do print(k) end before the crash as a sanity check to see everything inside of the ability table if you have not fixed it yet
I mean I would never use this spectral anyway
I think you underestimate the power of negative playing card
Especially since it's not the only thing that mod adds
...also to add to this - don't other spectral cards kind of have this "issue" as well in some cases?
i think that the only way for negative playing cards to actually have an impact on your run would be:
- get perkeo
- somehow get exchange inside your consumable slot
and thats IF exchange didnt have that big of a cost
hey yall how can i access the source code for balatro through steam? im trying to read through it to get a better idea of how to woprk with the cards
download 7-zip, then extract balatro.exe
tyty
Hex for sure, ankh is not
IDK what else
that's because i dont think having 3 more playing cards in your hand is gonna make that big of a difference
or maybe about 6, definitely under 10 if you got dem voucher to give bonus hands
Pls don't think about this in a vacuum, there's enough stuff that make negative playing cards worth it
what about deaths with it?
Just saying
like what?
which do?
I'm sure this has been asked a million times but what resources can i look at to begin modding balatro
"Anti-matter Enhancement"
X0.5 Mult
1 in 4 chance to upgrade by X0.5 Mult
(Up to X2 Mult)
"Obsidian Enhancement"
Lose 1$
1 in 4 chance to create a Negative consumable card
Black Seal
Counts in scoring if held in hand
Green Seal
Draw 2 extra cards when scored or discarded
id use this instead of exchange ngl š
That's a -1 Joker slot
black seal is the only card there that works with a negative card
appreciate it
well why would any of the others care about being negative
negative troubadour would net you +1 hand size in exchange for -1 hand, and that hand size will work for every playing card ā¤ļø
ok but its very unlikely you are gonna get one so maybe thats a bad point
with black seal
Also steel, gold and blue seal as I've mentioned before
i thought you need to score cards with gold seals to get the bonus cash
Gold Enhancement
but you already need a handful of those effects to get an increase
oh
Wait actually now that I think about it
^ i find the seals and enhancement overall fail to make the cost worth it
it really is
I still think both are unnecessary
and even without -1 hand, you would still need perkeo to consistently build a negative card deck because of not being able to copy negative
a negative card is +1 hand size, some of the time
and i dont think having to rely on a legendary joker for a spectral card to work is a good idea
Isn't handsize buff one of the most powerful vouchers?
yeah but not when its locked to one playing card
emphasis on "some of the time"
you have to draw the card to make use of the hand size and keep the card in hand
mhm
which if it isnt providing you a benefit for being in your hand, either with it's own effect or making up the hand you want to play, also doesn't really do much
-1 hands played stunts your possible scoring and early econ so much
literally the reason for black deck hate lol
Well, I trust you folks on that but if it turns out to be as broken as I've imagined then I'll just add negative transfer protection
I hope that sounds reasonable
with enough deck fixing the profit from a negative card would be insane
but that requires work
Well, deck fixing enables a lot of broken stuff in general
it really wont, you still need a bunch of Death to make it work beautifully anyways
(i shouldve replied to the specific message, but what i mean is that it will take quite a few rounds and cash to ramp up its potential)
I don't think negative transfer protection is a good idea personally
it blocks playstyles from other mods too, dont forget that
Other editions and seals transfer over
It makes sense for jokers because joker copying is already powerful on its own, but playing cards dont need it
it's also because of the fact that you won't always have the playing card, whereas a joker is a permanent thing you have
oh are we hating on the black deck? It is by far the deck I struggle with the most
pretty much everyone does
where's obligatory all my homies hate pic
I also find plasma to be super hard too. I can't put into words why I struggle with it. I guess it gets super duper hard at the second or third stake
yeah its just inherently harder to play because hand reduction limits you in so many ways but i was mainly talking about hand reductions in general
i usually get jokers which give a lot of chips as they work beautifully in early game for plasma decks lol
stone cards actually become quite viable for early game too
So is everyone who makes mods also pixel artists? I programmed a bunch of cards for a vanilla style mod and am now trying my hand at pixel art and...wow is it hard to make things look good
plasma's weird, you either want to really spec into Xmult or Chips, going inbetween is suboptimal
going into both is worse? Maybe I need to change my approach
Im personally dogshit at art but i need sprites for my mods and i cant use placeholders forever :P, even if its mid ill have to make it
You could also ask friends for help if they want to make stuff with you, or commission someone
I've managed to put out 30 mediocre art pieces in less than a month without any prior experience
Aseprite app was huge "skill" boost for me
It's very good
aseprite works so beautifully when it comes to pixel art
really any image editing software with basic functionality like layers will work
Yeah, but the comfort and speed is better in aseprite imo
That is a perfectly valid take
paint has layers now
š£ļø
i was talking about paint DOT net
Paint2 just dropped
yeh but by that logic, paint should work too ā¤ļø
which is an image editing software separate from MS paint
paint has layers?
yeah
Since Windows 11
oh shit I have never seen this button lol
pros:
layers for mspaint
cons:
having to update to win11
well with this new knowledge yeah it would also work perfectly
for computers in the IT room, id rather them having win 11 so i can mess around with paint even more š„
paint.net is better anywhos
I'm using paint.net on my pc too! I did just get a pencil for my eight year old ipad, I am going to try that.
I think my biggest sin was starting with the 2x resolution cards. That allows for extra detail and when I shrink it down, wow it looks bad. I was reading up on pixel art and the style ideas and it seems liek folks generally start with smaller images and scale up.
i download hoyo games on them 
But the new update also makes the Text box take like 6 seconds to render the first time you reopen the app!
I dont think modded jokers really even need 1x, its only used in the challenge screens
1x sprites are used if you untick one of the settings i forgot which one
if im lucky then we get to study in the room with a computer containing balatro š
Texture smoothing?
that
dayum bro
ah ic
so u can make 1x look ugli and make 2x look good?
i love how much detail I can put in a 2x card but then it doesn't really fit the pixel aesthetic
Also for scaling pixel art, you should generally turn off interpolation
i scaled my jokers from 2x to 1x with interpolation off and they looked fine
I feel like the jokers and packs and tarots I added are very vanilla friendly and folks will like them, if I can spend a week of free time learning lua and adding the jokers, I can take two more weeks to do good hand made art too.
Lua isnt all that hard to understand, as far as programming languages go its pretty similar to human speech, the difficult part is learning all the contexts smods has and what they mean in regards to ingame circumstances
I can't decide if I should make this x0.1 to match the scaling of Vampire or not
i think it should be x0.1
In hindsight I wish I'd tried learning lua 10 years ago, I could have made some fun WoW mods. It's been easy to understand
I also just realized I forgot to include the context for Midas Mask making things gold... time to do that now
the hardest part of modding balatro is actually remembering all the functions, variable names and allat ngl
Would you also count if a steel card is turned to glass, or only when a hologram card becomes lucky, etc?
I also confuse ability, enhancement and ability. End users might too
It's only when an enhancement is placed on a card that already has an enhancement
Enhancements are the ones on playing cards
LIke gold, steel, bonus, mult, glass, stone
much easier to use than vampire if thats the case lol
would turning a lucky card to a lucky card work
yes
"pretty similar to human speech"
SMODS DOT JOKER OPEN BRACKETS KEY EQUALS QUOTE EXAMPLE DASH JOKER QUOTE COMMA LOC DASH TXT EQUALS OPEN BRACKET NAME EQUALS QUOTE EXAMPLE JOKER QUOTE COMMA TEXT EQUALS OPEN BRACKET QUOTE EXAMPLE TEXT QUOTE COMMA QUOTE EXAMPLE TEXT 2 QUOTE CLOSED BRACKETS CLOSED BRACKETS COMMA CONFIG EQUALS etc
ur right about everything else tho
sounds like human speech to me
Would you listen to context.consumable_used? SMODs lets you take ownership so you could do something afterwards
Now if lua took in lambda functions...that would make it pretty easy
lua is like the easiest
then python
put c on the last place bcuz u also have to make it S A F E
My only complaint is please give me my strong typing back
We put respect on declaring variable types in this household š£ļø
š
The duality of man
Yo
Why isn't it null safe? I had to write safety functions for it. I do love the SMODS.Inspect option
Does anyone here have good recommendations for pixel artists they worked with?
mult
Wdym?
return {
mult = 10(or whatever u need)
}
eg. return { mult = card.ability.extra.mult }
^
alr how do i add cards into the deck with a specific rank and suit
elseif (context.other_card:get_id() <= 9) and (context.other_card:get_id() >= 2) then
xmult = context.other_card:get_id()
end
So this line returns 2 - 9 depending on the card, how do i add 0. before?
ex. instead of 9 0.9
divide by 10 š§
By using ... / 10.0
mhm
does your mod have to contain content to be detected by steammodded? i have implemented the .json metadata file but it still hasnt been detected
heres the metadata
"id": "Examplumod",
"name": "Examplumod",
"author": ["biggie"],
"description": "adds genuinly nothing",
"prefix": "xmpl",
"main_file": "main.lua",
"priority": 0,
"badge_colour": "FF230A",
"badge_text_colour": "FFFFFF",
"display_name": "ballers",
"version": "~1.0.0",
"dependencies": [
"Steamodded (>=1.*)"
]
}```
there is nothing in main.lua
--- MOD_NAME: The Nothing Mod
--- MOD_ID: NothingMod
--- MOD_AUTHOR: [Steamo, TheVoid]
--- MOD_DESCRIPTION: This Mod doesn't do anything !
----------------------------------------------
------------MOD CODE -------------------------
----------------------------------------------
------------MOD CODE END----------------------```
this is the old format and should not be used in combination with json metadata
How do i change the joker rairyty
you can / 10 just fine
rarity is defined in the joker by rarity = x
where is is the rarity
afaik 4 is legendary
can i see your mod's file structure?
SMODS.Joker {
rarity = 1
}
3 is rare
2 is uncommon
1 is common
SMODS.Joker=
you mean this?
stupid af
that looks perfectly fine (assuming it's in your mods folder). and nothing is showing up in the mods menu-?
do i add playing cards with smods.create_card()?
The json and lua file should not be inside the assets folder.
imma try and reinstall lovely
?
json file is 0 kb
yep only debug mod
smh
sorry for wasting y'alls time š
its fine
So uh this crashes
error?
whats at line 110
Uhh, how do they work
I assume youād want return {x_mult = ā¦}
you put a key like x_mult and a value
if you want to give xmult, you put x_mult = <value> into a returned table
I want center.ability.extra.Xmult to be xmult more
if you want to change a config value of the card, you do that outside of a table
center.ability.extra.Xmult = center.ability.extra.Xmult + xmult
Thats how you wouldve done it in another lang
cryptid really made a bad example on how jokers are structured huh
no that's fine
done š
you just don't shove it in a table constructor
you can't wrap random statements into a table
either you do card.ability.extra.Xmult = card.ability.extra.Xmult + xmult and change the config value
or you return { Xmult = <value here> } and tell the game to give that xmult
a combination of the two does not work
good so far but you're never giving the xmult, you're just changing around config values
Thue
also line 113 is assigning to a global mult
Yeah
in every possible context
So i should change that to?
you should change that
I don't know the exact effect you have in mind, but you probably want to give the mult in context.joker_main?
So a seven adds 0.7 to the total mult of the joker when scored
Then it multiplies your total hand with this
wait he should return {mult = card.ability.extra.xmult}
to add +0.7 to mult
if u want to multiply then its return {xmult = card.ability.extra.xmult}
at line 113
that will give mult on every possible context
change center to card
Can you show your cards ability section?
Like thias section
It should have a section like this
config = {
odds = 2,
extra = 1.5,
earnedPlusmult = 0,
multGrowthRate = 1
},
Config for a joker is interpretted as ability
Your line 96 has a typo. Locvars isn't taking in card, it's taking in self. So change line 96 to self.ability.blah
does anyone know how to create a playing card?
tell me more? Like add a new card to the deck or hand, or what?
to deck
that's also wrong
So like this?
no
put the line 113 into the context Please
like put it in the if statement
change the center in the loc_vars arguments to card and change self back to card
Also put line 113 into if context.joker_main then ... end
I love watching people give bad advice
Soo next question. How do i check the suit?
alr heres my questions(purpose is to have 1/4 chance of card splitting into 2)
- how do i create a playing card and put it into deck
or(if 1 is hard to answer) - how do i clone a card and THEN edit the cards rank
the quit?
Suit, typo
use create_playing_card()
alr thx
For #2 use copy_card and then SMODS.change_base on it
alr
I'm looking at a modder joker I made and it basically looks like this and works
one way is to do card:is_suit(suit)
so card:is_suit(clubs)?
"Clubs"
"Clubs"
if you just want to know the suit rather than check it is a certain one you can use card.base.suit
it seems like after saving it still isnt appearing, could this be a problem aswell?
in the smods src and in general alot of other files some variables are unknown, but the debugplus mod still loads perfectly fine, just my test mod wont load
yeah this is probably a bad thing
Btw the starting shop context you did doesn't have enough information, like if you did what was intiuitive and wanted to spawn an extra voucher when shop is starting, you'd create a voucher every time the game is loaded too
that sounds like a problem
I think so anyway, I didn't test it, but it looks similar to what we did in paperback
And I had that issue
all this info and more can be found in https://discordapp.com/channels/1116389027176787968/1250386587691388989
but 69x93
thank you!!!!!!!!
np
should be an easy fix
How do you check which cards the player has in hand
G.play perhaps
oh wait
hold on
in hand as in not playing right
its G.hand for the hand cards
Do you need to loop through them?
Or can i like G.hand(1)
G.hand.cards[1] to get the first card
Can you get the total amount of cards?
afaik u can js do
if context.cardarea == G.hand then
it will go through each card in the hand area
OH AND CONTEXT.INDIVIDUAL
so its
if context.individual and context.cardarea = G.hand then
then it will loop through all cards in ur g.hand
What? Why the #?
length operator
oops
lol
#gets the lenght of a table
so my mod still isnt being detected by steammodded, could it be because of this in the metadata? every mod has a specified version but idk if this works either
ill see
so i have to use <=1.*
no the version: "1.0.0"
alright
anything <1.* wont recognize the mod anyways
i confused Everyone
what i meant by My statemtents was "version": "1.0.0"
not "~1.0.0"
for i,v in ipairs(table) do
for i, v in ipairs(G.hand.cards) do
-- i is the index, v is the value
end
for i = 1, #G.hand.cards do
local v = G.hand.cards[i]
-- this is the same thing effectively
end
if you're modifying the table you're traversing, you need a while loop instead
So v would be 7 if the card was a seven?
G.hand.cards[i].base.id would be 7, or G.hand.cards[i]:get_id() (I think thatās the method Iām not at my computer rn)
v would be the corresponding card table
in game the name and description wont show up, did i get misorganized with the {} brackets?
yes you're missing a closing bracket
no, its just not in the screenshot
ah, it's loc_txt not loc_text
ohhh, makes sense, thanks!
also please format your code!
what was formating again, i am rly new to this
ctrl + shift + i if you have the lua extension should do it
or just right click anywhere in the text and press format document
kk, looks a lot better now
oh yeah, its all coming together
now i just gotta make it eternal and not provide the negative mult
(in the description
What if its a jack
What will the base id be
Jack is 11, Queen 12, King 13, Ace 14
This is also the value displayed for them when you hover over Misprint
Thanks
Do you have a variable called mult somewhere else that you forgot to make local?
No, i want it to use the global
Like mult is the multiplier
Oh wait nvm itās throwing the error because you didnāt set a context, so itās calling it when there are no cards in your hand
Wait, how should i set the context?
(Im new to lua, in case you didn't notice)
break that txt pls š
Wdym
The documentation is your friend (until you realize there are some contexts you need that exist but the wiki does not mention)
this
it's too much text in one line
(sorry if this is obvious i'm a complete beginner) the joker resets if a face card is scored, the actual reset part works fine but the "Reset!" message isn't showing up, how do i fix it
this is how u break code in case u didn't know
What languages do you have experience in?
Some, in python and very little in C++
So like this
I would put the context outside of the for loop
Thats smart thanks
yo guys i need help making a mod
i want to make a mod that adds new skins for the face cards
but idk how to add a new tab to scroll to and how to add the cards in the game
just like yk the witcher face cards thing etc
i want to make my own face cards and add them into the game in customize cards area but idk how if someone can help me out that would be amazing
It doesn't work for some reason, no crash
But the stuff wont work
Smods version?
yea
also i got rid of that stray comma at the end of localize but it still doesn't display the message
Uh I'm pretty sure Eremel is asking what version of smods you're running, not if you have it at all
For one, returning inside the for loop will break it and only do anything for the first card in the array
oh sorry LOL 1.0.0
The full versionā¦
you have no idea how little that narrows it down
So like this?
And whats 2
sorry i'm a little stupid
you're almost 2 months out of date
joker calculation was changed fundamentally since then, so it's a huge difference
ah ok thank you
your code should work just fine on the latest version
Still doesn't work š„²
This is probably the context you want to use, and not loop over the cards
what are you trying to do exactly?
context.destroying_card only checks for cards played, right, not cards held in hand?
yep that was the problem thank you
new calc has destroying checks for other areas including cards held in hand
How does the function display thingy look
context.destroying_card is explicitly only played scoring cards, for others use context.destroy_card and context.cardarea == G.hand (or whatever other area)
aaah okay
you're using a variable you never defined
Also that's not how context.individual works
Which?
totalmult
You need to declare
local totalmult = 0 before you use it
Oooh
if context.cardarea == G.play and context.individual and context.other_card:get_id() < 11 then
return { mult = context.other_card:get_id() }
end
this should be closer to what you need if you want to use context.individual
or if you want cards held in hand, you need to evaluate in G.hand. I'm still not sure what you're trying to do exactly though
You mean like this?
Stones?
Stone cards are assigned a negative id iirc
stone cards have a negative id
if context.cardarea == G.hand and context.individual then
local id = context.other_card:get_id()
if id > 0 and id < 11 then
return { mult = id}
end
end
more like this
yeah it's random, I didn't check for these kinds of errors lmao
It doesnt work?
how so?
Oooh, it gives mult for each played card, i want it to give mult for every card in hand
see you never specified that
Every numberd card
change G.play to G.hand
yet I said this
I'm not here to write your code for you
Needs context.main_scoring too
Which we could have told you straight away if you told us what the effect was
You mean like this?
isn't that on playing card eval
Im pretty sure i did
is cryptid refactor branch gone?
it was merged into main
But i want it to add mult for every card in hand, so for a 7 it adds 7
Face cards not included
So no mult for face cards
you can undo that
what you had before that change should be good
Sometimes it play at the end again?
oh right there's some confusion here
ah
oh maybe it is just on playing card eval
try adding not context.end_of_round
I don't think we actually have a positive identifier for that
no I was just thinking that
it can't be context.main_eval either
my initial thought would be to change the end_of_round one
but that is ehhhh
maybe context.score_eval?
What causes this? The layers i added looks like they're also being emplaced.
Full deck or current deck
What's the difference again
Current deck excludes cards already seen in the round
Ooh, full deck
i.e. Blue Joker calculates off of current deck, Cloud 9 calculates off of full deck
Full deck
full deck is in G.playing_cards
Yo, I am AWFUL with lua
anyone got a good source or video that would help me learn it
Can I do like G.playing_cards.Aces
To get number of aced
No
Aces
it's an array of cards
Awe
still need some help with this if anyone has any pointers, editions documentation is a bit unclear how exactly you make editions Function
in calculate
Ah. we were taking the docs too literally in this case, as calculate() isn't mentioned on the SMODS.Edition page atm. ;P
that is very strange
docs have a few oddities - ever since joker calculation is gone as a page i don't think there's a description of the exact order contexts happen in scoring
for whatever reason, editions is pitching a fit about the "extra" in the config line. is this normal?
that can't be the direct issue with it
oh dude
you're referencing card.ability.extra on 148
you're looking for card.edition.extra
oh, that'd do it ;P
i'm also not sure returning repetitions will do anything on context.main_scoring
but that's just a hunch
How do I make a joker that updates its values in real time? (ex. Joker Stencil)
stuff like this should be happening on if context.repetition and context.repetition_only
the calculate page does have them in the exact order they happen?
it does at least proc the "Again!" message, so it's not like it's being entirely ignored. still, gonna try another context at least.
i understand this but i don't think that is made quite clear
i'd suggest looking at red seal
but also, since this is available in shops, you'll have jokers with it, which needs a separate feature and context
anyone that can help?
what do you want to know
just calculate the values you need in the calculate function and loc_vars function
stencil doesn't "update its values" in real time, it just calculates it every time in those functions ^
does anyone know the sticker id of eternity?
'eternal'
it does actually do it in real time because thunk doesn't care about your performance š
stickers are weird
doesn't show up?
What do I write for the orange text, is it just {C:orange}?
it's just a flag on the card ability
Interesting
joker.ability.eternal = true | nil
I assume you're looking for {C:attention}
Yeah that's probably it
yeah but how do I add them to the info_queue?
info_queue[#info_queue+1] = {key='eternal', set='Other'}
that's how vanilla does it, anyway
SMODS does store both custom and vanilla stickers the same way other SMODS objects do, but idk if you can just pass them into info_queue and get the sticker tooltip output.
iirc it doesn't work with SMODS.Stickers.xyz, maybe I should implement that
stickers are so all over the place
I now realized that Iām terrified of any updates horribly breaking any of the modded content Iāve made
vanilla set_perishable cannot even unset perishable
stickers are mega jank
they are
yeah they're really weird
they were even more jank before better calc though
guys i think we should make localization files have proper buffer names
how can i have multiple mesages show up on a card
nah it's fine just stop comparing numbers with tables?
How do you check if a certain mod is installed?

