#💻・modding-dev
1 messages · Page 334 of 1
dude that would be awesome
These are the configs, and the two functions, it updates which joker is debuffed as you move the joker around
i genuinely cant find out why it doesnt want to work
but im going to sleep i cbf with this rn
how do you override vanilla values again
nvm
why is there an unexpected symbol at 1511
thanks for nudging me in the right direction! this is what ended up working
-# (though it did make me realize that now i have to handle having more than one of this joker 😅)
but thanks for your help :3
Is there a specific function that handles when the application is put into focus?
looking through the code G.FUNCS.use_card specifically looks for G.consumeables to know if the card is not from the pack
Should I patch that to include my own cardarea?
yeah
bump
ok the code for that 1 line long lol
for using VS Code for Lua is there a way I can set up ---@param to see how everything is returning
--@return
also i don't think those types are correct at all
self is SMODS.Center, card is Card and context is CalcContext
Can you tell me how to add ignore slots consumable?
does anyone know why my game crashes? i've been trying to make this joker and it says there's an unexpected symbol near one of the ifs
SMODS.Joker{ -- Yellow Card implementation
key = 'Yellow Card',
loc_txt = {
name = 'Yellow Card',
text = {
'Earn {C:money}$#1#{} at end of round. ',
'Payout increases by {C:money}$#2#{} every',
'#3# {C:inactive}(#4#){} {C:attention}Booster Pack{} skipped.'
}
},
atlas = 'Jokers',
pos = {x = 2, y = 0},
config = { extra = {
money = 0,
money_gain = 1,
pack_require = 3,
pack_amount = 3
}
},
rarity = 2,
blueprint_compat = false,
loc_vars = function(self,info_queue,card)
return {vars = {card.ability.extra.money, card.ability.extra.money_gain, card.ability.extra.pack_require, card.ability.pack_amount}}
end,
calculate = function(self,card,context)
if context.skipping_booster and not context.blueprint then -- Booster Pack is skipped, decrement the counter
card.ability.extra.pack_amount = card.ability.extra.pack_amount - 1,
if card.ability.extra.pack_amount == 0 then -- the error is on this line
card.ability.extra.pack_amount = card.ability.extra.pack_require
card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_gain
return {
message = 'Upgrade!',
colour = G.C.ATTENTION
}
end
end
end,
calc_dollar_bonus = function(self, card) -- Apparently money isn't in the calculate function. Who knew?
return card.ability.extra.money
end
}
is there a list somewhere so I know the right ones>
nope, you have to look in the lsp files
ok bet
unless you mean for the lsp as a whole in that case just google lua lsp
the comma before card.ability.extra.pack_amount == 0
I mean for like seeing if my jokers return the thing it should
see how its unkown
is it on documentation for lua somewhere?
its not easy to add those to the extra tables sadly as those are variable for every joker
the docs are here https://luals.github.io/
Lua Language Server uses the Language Server Protocol to offer a better Lua development experience for your favourite editors.
clutch!
ik not easy i just wanna know how to do
I'm getting this any time I try to start a run, the only thing I've added is my vouchers, which don't even have redeem code yet
that worked but where it should be showing pack_amount it shows nil
loc_vars says card.ability.pack_amount instead of card.ability.extra.pack_amount
requires should be a table i think
That worked
if i have smods download with work space with it see the input of the src files already present?
or still need to make it
you should get the lsp definitions yes
so Y still doesn't give you mult.
ik VS doesnt know lua but i thought the extension with folder gives it output
SMODS.Joker{
key = 'yankee',
loc_txt = {
name = 'Y',
text = {
"{C:attention}Destroys all played 2's{} gains {C:mult}+#2#{} mult for {C:attention}each destroyed 2{}.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} mult)"
}
},
atlas = "Jokers",
pos = {x = 0, y = 3},
config = { extra = {
mult = 2,
mult_gain = 3
}
},
unlocked = true,
discovered = true,
rarity = 2,
cost = 7,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain,
}
}
end,
calculate = function(self,card,context)
if context.before then
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 2 then
context.scoring_hand[i]:remove()
card.ability.extra.mult = card.ability.extra.mult + 3
card_eval_status_text(context.scoring_hand[i], 'extra', nil, nil, nil, {message = 'Upgrade!'})
end
end
if context.joker_main then
return {
mult = card.ability.extra.mult,
card = card
}
end
end
end
}```
what is wrong with this?
I know it doesn't give you mult but where in the code is it?
hm
because the extra tables are not defined as they vary from joker to joker like i said
gang for making new global variables similar to all the G.GAME stuff how would you recommend doing it
what is the error
the logic error is that Y doesn't give you mult.
I recommend using your mod's prefix so it doesn't cause conflicts but aside from that just put it in G.GAME directly when you need it
It's a logic error not a real error.
unsure then test in game sorry
yeah Y doesn't give you the mult that it stored.
i'm trying to apply an edition to a selected consumable, this doesn't seem to work properly
i'm not sure what's wrong
Does SMODS add a consumeable_rate for each modded consumeable?
if context.joker_main then
return {
mult = card.ability.extra.mult,
card = card
}
end
end
``` I think it is this.
how does one add an enhancement to a playing card?
sorry this is the code
if context.joker_main then
return {
mult = card.ability.extra.mult,
card = card
}
end```
oh it isn't in the calculate function.
That would be the problem
having a hard time finding it in the documentation
Can you tell me how to add ignore slots consumable?
look for set_ability in the game files
oh wait i meant edition
Still doesn't give you mult if I put it in the calculate function.
SMODS.Joker{
key = 'yankee',
loc_txt = {
name = 'Y',
text = {
"{C:attention}Destroys all played 2's{} gains {C:mult}+#2#{} mult for {C:attention}each destroyed 2{}.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} mult)"
}
},
atlas = "Jokers",
pos = {x = 0, y = 3},
config = { extra = {
mult = 2,
mult_gain = 3
}
},
unlocked = true,
discovered = true,
rarity = 2,
cost = 7,
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain,
}
}
end,
calculate = function(self,card,context)
if context.before then
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 2 then
context.scoring_hand[i]:remove()
card.ability.extra.mult = card.ability.extra.mult + 3
card_eval_status_text(context.scoring_hand[i], 'extra', nil, nil, nil, {message = 'Upgrade!'})
end
end
if context.joker_main then
return {
mult = card.ability.extra.mult,
card = card
}
end
end
end
}```
what is causing the logic error?
Where did you get this information?
Just creates planet and tarot cards, but if there is a location, I'd like the number of locations to be ignored
bump
I can send you the code
What's the code?
did you reply to the wrong message?
calculate = function(self, card, context)
if context.before then
G.GAME.consumeable_buffer = #G.consumeables.cards
end
if context.individual and context.cardarea == G.play and context.other_card.seal == 'Blue' and G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
local card_type = 'Planet'
G.E_MANAGER:add_event(Event({
func = (function()
if G.GAME.last_hand_played then
local _planet = 0
for k, v in pairs(G.P_CENTER_POOLS.Planet) do
if v.config.hand_type == G.GAME.last_hand_played then
_planet = v.key
end
end
local card = create_card(card_type,G.consumeables, nil, nil, nil, nil, _planet, 'blusl')
card:add_to_deck()
G.consumeables:emplace(card)
end
return true
end)}))
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
elseif context.individual and context.cardarea == G.play and context.other_card.seal == 'Purple' and G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
G.E_MANAGER:add_event(Event({
func = (function()
local card = create_card('Tarot',G.consumeables, nil, nil, nil, nil, nil, '8ba')
card:add_to_deck()
G.consumeables:emplace(card)
return true
end)}))
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
end
end
Do you even know what question I asked?
I ended up patching in a default value and a check in the create_card_for_shop function
I'd prefer to get an answer to the question of how to ignore the slots of the unmodifiable
I'm just wondering what in my code is causing the logic error in Y.
That's not what you responded "No" to, I asked a question, you gave me an answer, I asked how you got to that answer, and you sent me code for something completely unrelated
i think my problem lies in this section of my code, this seems to be able to apply an edition to a selected playing card, but when i try to modify this code to let me select a consumable instead, it lets me select it, but when used, it doesn't apply the edition
Okay, then I don't know the answer to that question.
Then why did you answer it?
You're looking at highlighted cards in G.hand not G.consumeables, unless that's what you modified to make it work
replacing them with G.consumeables breaks it, making it usable without selecting anything
It looks like there's no references to G.consumeables.highlighted in the base game code so it might not even have functionality for that
it should
i think the problem is that you can only highlight 1 so it's only usable on itself
i think i know how to fix that, let me do some testing
is there a good function to remove or destroys a card after it scores, coming up short using :remove() and :start_dissolve()
code if it helps
if context.other_card.ability.extra.cb_trigger == true then
card.ability.extra.totalChipMult = card.ability.extra.totalChipMult + card.ability.extra.gainChipMult
card.ability.extra.flag = true
local _card = context.other_card
return{
message = 'Crumble',
colour = G.C.FILTER,
G.E_MANAGER:add_event(Event({trigger = 'after', delay = .45,func = function()
_card:start_dissolve()
return true end}))
}
end
yeah don't remove cards using those during scoring. use context.destroy_card and return { remove = true }
this seems to allow me to select playing cards and consumables, edition can apply on playing cards but when i use it on a consumable it does nothing
Your if context.joker_main then is inside your if context.before then statement, move one of the ends to be before the if context.joker_main then line
You need to keep track of your ends in the same way you keep track of closing brackets in tables
Like Kaeda said, you are missing an end
unless you changed it your use function is only iterating through cards highlighted in hand
Your indentation makes it hard to notice
Yes, and then remove the very last end in the code
ok.
alright, it works now for the most part, but i can still highlight playing cards, how do i prevent this?
this blind score is crashing when the blind is selected, what am i doing wrong? i want to make the most played hand not score
nevermind lol
if context.destroy_card and context.cardarea == G.play and context.individual and not context.blueprint then
this will not trigger no matter where i put context.destroy_card
remove context.individual
that conflict does it, well i need it to get context.other_card but i know a workaround, thank you for the help
okay, what am i (still) doing wrong here?
context.destroy_card is the equivalent of context.other_card in that context
also i wasn't telling you to replace your entire logic, you can just use individual for your main effect and destroy_card to destroy
what's hand
this is the blind code, hand seems to always be a table of poker hands ("poker_hands")
thank you very much, did not know destroy_card was that usefull, its now working and i can stop for the night
the crash is happening whenever a card is selected
so i assume the actual variable is going through? but for some reason it's not being treated correctly in the table
bump
yeah
Is there a way to make a certain set of jokers have a much better chance of appearing?
but when a card is selected, it seems to think poker_hands is empty?
How do I make it so that the mult is squared?
a rarity
i think this might be the issue? i have no clue why, though
Oh! ok ^^
Is there a way I can change the rarity values when a deck is selected or a voucher is gained?
is there a way to change a specific card's atlas only if it has a certain edition
like what is code for it.
if you have talisman i believe you can use emult
maybe im too sleepy but i think this is looking for a string instead of a table
i know the docs say it should be a table
this work?
i don't think so, this is the crash
Do you have talisman?
is talisman a mod?
so wait, would i set that as another variable of hand?
Yes.
although I think smods overrides that function so it's weird the error is there
hand = string instead of hand = { string = true }
the override doesn't change that function
oh it isn't in my mods list.
hey why does this patch not do the thing I want it to (legendaries should spawn in shop if the config is enabled)
this let me select a hand without crashing, but isn't debuffing which is annoying. still progress though
?
oh, it works! i just did it wrong
uh
apparently when it's set to "high card" (the default) no hands are allowed to be played lmao. shouldn't be an issue given that this is meant to be a showdown, so eh
No, it’s in steamodded_metadata.lua
oh this line?
hmm
of course it is on the last joker...
Talisman?
What is wrong?
...
I have no idea.
Someone who was playing vanilla is trying to recover the seed for their naninf run. They're posting in modding chat, but I figure active mod coders are more likely to be able to help
Try getting this version of steamodded: https://github.com/Steamodded/smods/archive/refs/heads/main.zip
and now my jokers don't show.
What do you mean?
The mods button is missing!.
Did you Install it right?
I put it in the Mods folder.
Did you replace it or did you delete it and put in the new one?
delete the old
and put the new one in.
hm
uhhhh
What does your mod folder look like?
Did you rename the smods folder?
yeah.
can I see the breadcrumbs on top?
?
ok
Copy smods-main to the root of Mods and delete Steamodded
Or resolve it a different equivalent way
now I have the Talisman error now
talisman is nested too
(@daring fern why the pondering react?)
Keep in mind that unlike smods, Talisman's folder needs to be named exactly Talisman
ok but now Z isn't in my collection.
What was the code for that again?
how do generate money when consumable use
ease_dollars
I got colored text to work with my buff cards [=
Through a really hacky method of making my own color tables and using conditions inside the colours table
what do i put after it
The amount you want to give or remove from the player
Somethingcom is thinking up a storm right now
ok
This is so scuffed ðŸ˜
But hey it works so who am I to judge
Now I just gotta find a unique held in hand color, any suggestions?
Scored is blue, discarded is red, in deck is green
RGB.
vanilla jokers use the standard orange-yellow "attention" color for that, but if you want a new color i'd probably lean towards a light purple (since you aren't scoring or discarding it)
what about magenta?
I'll make it purple, since that's a color already in the game
yo people of modding chat
that someone in question is me
where is the seed of the current run stored in the game files?
basically I scored naninf
I closed out of the game
I reopened the game later to finish the run
hitting continue on the run instantly crashes the game
results in this screen
if someone in here knows how to get the seed of the run would be appreciated thanks
It's in save.jkr
Use this to look in it: https://balatro.shorty.systems/
I do have balatro save editor installed
Actually, I'll make it the same color as the icon, Troubadour red [=
You have to go to Raw and CTRL + F 'seed'
how do u view the save.jkr file in balatrosaveeditor?
You go to %APPDATA%/Balatro select the number according to the profile your on, then drag the save.jkr file to where it says Choose File... or Browse... then go to Raw and CTRL + F 'seed'
im on windows
I went to C: -> users -> me -> AppData -> Roaming -> Balatro -> 1 -> save.jkr
dragged and dropped that there
and got that
that is the right file right?
It should be, so maybe your save is corrupt?
fuuuuuuuuuuuc
does scoring infinity straight up corrupt the entire save file?
I mean I should be able to start a new run pretty sure
No, It shouldn't.
I just haven't yet bc I aint tryna lose the seed of this current one
okay so basically im cooked lol
I don't need the seed it would just be kinda nice to have
thanks tho
but yea dropping profile.jkr in there works
save.jkr is just not working at all
The line you were crashing on was trying to check if you beat the round so maybe it was a problem with infinity?
i mean yea it looks like it
trying to do math or not a number makes computer not happy
It now includes the rarity of the card as if it's a joker
anyone know how the Loyalty cards description works? It changes to "Active!" when the number of cards needed to activate reaches 0. I tried to reuse the Loyalty Cards code, adapting it to my code, but it just says ERROR.
That's because your trying to localize something that doesn't exist.
Is there a way to do it via SMODS?
How do these cards work again?
Like where do they live?
They have their own card area that processes cards after scoring cards but before jokers
Also I made it so that their max is 4, the level 2 voucher gives you 4 slots, and there's a joker that gives you 4 more slots, so you can have 12 total
Ngl as cool as they are I'm not sure, as a whole new mechanic with s new card area, they'd really fit in well in my entire modpack
You can just not take buff cards
Well yeah ofc, though you should probably make a config so they don't clutter he shop in the case. I'm definitely interested in your mod generally
They don't cover any cards in the shop, at least not enough to make the shop hard to use
I could make a setting to always compress them in shops
Like they do when selecting a blind
I meant that if I'm not taking them I may as well not be offered them
Oh
I should probably just do that for all features honestly
Like some mods do, you can pick and choose what's added
Yeah, modularity is always a good thing imo
Can agree
You can just slap SMOD object definitions into if statements right?
Yep!
I just need to figure out an actually good menu for it /=
Yoink the ui code from another mod
I refuse to do so unless it is offered to me
Utilize mod.config_tab!
I already am for my music toggle
I mean... many mods are explicitly gpl 3
Then you can piggy back off of that easy peasy
I mean like, what types of UI elements to use, should I use a card area for jokers?
For the config?
That would be strange if possible
I've seen it done before
fascinating
I have too come to think of it. Though for smth as granular as individual jokers maybe just recommend "banner"
that's what cryptid does, right(?)
you can click on jokers in the collection to change if they're banned
Does it just bundle itself with cg's mod?
Because that's how it works
Afaik
I honestly just leave it to users to comment them out within the code if they want to get rid of 'em 
That looks like a great mod
Yeah, I need to add it to my modpack and make use of it
First off to get rid of the stupid Bunco polyminos
yeah that was the one part of bunco i didnt like tbh
If I put code in the SMODS.current_mod.config_tab function will it only run when the tab is opened?
And yes I can make the bannings apply to people who download my modpack too, with yosbr. Though only if they don't already have a config for banner
Unless it stores the config in the Mods folder instead of the config folder, in which case I could still do that and it would overwrite every time
Might be worth investigating
Is there a way to retrigger without returning?
Maybe SMODS.calculate_context? Not sure if it handles retriggers
Hmm looks like it does not
What are you trying to do that would require that?
Multiple seals?
oh goodness
So... random uh... I guess it's a question. I'd guess you'd call smodded's approach more or less object oriented... what would you call the base game?
It seems to be very random and often inverted as to what polls what from what I'd expect
I think it would be object oriented in base game too, as stuff like cards and blinds do act like objects with their own properties, functions, initializations etc.
Yeah, jokers and enhancements and stuff just get really weird
Lots of branching conditionals
And properties defined in random functions
It definitely could've been handled a bit better lol
Then again, Balatro is a personal project
Yeah I guess it makes sense that modularity is a hallmark of a modding system, but much less so a 1 person indie game
for sure
[manifest]
version = "1.0.0"
dump_lua = true
priority = -1
[[patches]]
[patches.pattern]
target = '''=[SMODS Mossed "mossed.lua"]'''
pattern = """if card.area.config.collection then"""
position = "before"
payload = """
if not card then
return { vars = { card.edition.extra.upgrade, card.edition.extra.sell_up } }
end"""
overwrite = true
match_indent = true
is this how crossmod patches work again (it's not working)
I think Mossed should be lowercase.
Yes, that's because that's the id, the id for mossed is mossed
ah
It begins
what the fuck
Why am I able to make hard things but the second I need to make simple things my brain dies?
you expect yourself to do the easy things so you put pressure on yourself to make them faster
then you do worse work ðŸ«
It is now possible to set the jokers to be disabled by the configs, which makes them greyed in the menu and that's it right now but later it'll actually remove them from pools and stuff
Also nice little particles [=
@shell tangle
Was that the right someone?
I even made it so that if the card is disabled it won't even show up in the collection
Though it requires a restart
What do you mean?
or click on one.
Set Talisman to omeganum
Could you please tell me how to implement e_mult without cryptid mod?
You need Talisman
Okay, what's next, or is he gonna do it for me? 😀
If you have talisman you just return e_mult = number
Thanks. I'll give it a try.
And without additional mods how to realize it
what do i need to do if i want to increase the money cap of The Hermit 🤔
do i take its ownership and use set_ability?
this successfully retriggers adjacent jokers to this edition but just retriggers the scoring card with this edition when trying to do it for cards
SMODS.Edition({
key = "Shockwaved",
loc_txt = {
name = "Shockwaved",
text = {
"{C:green}#1# in 3{} chance to retrigger adjacent cards",
"Idea: BoiRowan",
},
},
discovered = false,
unlocked = true,
shader = 'nitro',
in_shop = true,
weight = 0.5,
extra_cost = 4,
badge_colour = HEX("ea763e"),
apply_to_float = true,
loc_vars = function(self, info_queue, card)
return {
vars = { G.GAME.probabilities.normal }
}
end,
calculate = function(self, card, context)
-- Played card retriggers its adjacent played cards
if context.repetition and context.cardarea == G.play then
-- Find this card's index in the current play area
local idx = nil
for i, v in ipairs(G.play.cards) do
if v == card then idx = i break end
end
if not idx then return end
-- Define adjacent card references (safe bounds)
local left = G.play.cards[idx - 1]
local right = G.play.cards[idx + 1]
local results = {}
-- Attempt to retrigger left card
if left and pseudorandom('shockwaved') < G.GAME.probabilities.normal / 3 then
return {
message = localize('k_again_ex'),
repetitions = 1,
card = card
}
end
-- Attempt to retrigger right card
if right and pseudorandom('shockwaved') < G.GAME.probabilities.normal / 3 then
return {
message = localize('k_again_ex'),
repetitions = 1,
card = card
}
end
return results
end
-- Joker retrigger logic (if used by another Joker)
if context.retrigger_joker_check and not context.retrigger_joker and context.other_card then
local idx = nil
for i, v in ipairs(G.jokers.cards) do
if v == card then idx = i break end
end
if not idx then return end
local left = G.jokers.cards[idx - 1]
local right = G.jokers.cards[idx + 1]
if context.other_card == left or context.other_card == right then
if pseudorandom('shockwaved') < G.GAME.probabilities.normal / 3 then
return {
message = localize('k_again_ex'),
repetitions = 1,
card = card
}
end
end
end
end,
})
You can't retrigger other playing cards from a playing card.
I think.
Unless you have a hidden external joker that retriggers them itself [=
is that a thing i can do without people then just getting it in the shop or whatever?
how do i check whenever the hermit spawns in?
that includes tarot pack, shop, and such
the idea if someones got a better idea for what it should do to playing cards
Technically, what familiar does with maroon seals is it rescores the leftmost card.
hmg
guess no one has the answer
and i havent figured out a way to do it effectively yet, hmmm
Couldn't you patch where hermit checks if its over the limit?
...do i really need to use a patch for that one, but that does sound good
why it doesnt show name and description?
🥀
how you r using the localization file is wrong
how
it should be j_(mod prefix)_(joker key)
You either have to overwrite calculate or you patch it.
this part
likely patching then, since only overwriting calculate wont change the cap shown on the card's description ðŸ˜
What are the other parameters in talisman besides e_mult and what do they mean?
What for
emult, eemult, eeemult and hypermult
emult is ^, eemult is ^^, eeemult is ^^^ and hypermult is any number of arrows.
Thanks, but I take it e_chips is not?
the same ones exist for chips too
Thank you.
so if you wanted My Awesome Joker that gives ^^^4 chips you would return eeechips = 4
echips, eechips, eeechips and hyperchips respectively.
Roger that, thank you very much, I've only started doing this a week ago, I don't understand much yet, but which parameter in Joker is responsible for adding slots for using materials?
i just realized, changing the config of the center itself definitely works, but it wont change already-existing hermits, so maybe not
I just made a patch for an "edition gate" for a Joker. How would I check that the Joker only spawns if there is a playing card with a specific edition in the deck?
decided to just patch in this small line, hopefully wont cause any conflicts
Roger that, thank you very much, I've only started doing this a week ago, I don't understand much yet, but which parameter in Joker is responsible for adding slots for using materials?
You don’t need to know when it is created to change its config
uh
Just change the config
consumeable slots? joker slots?
Then also change existing Hermits
Future hermits should inherit the new value
I think
thats true
Just keep in mind the old config will be reset when the game is loaded
Consumeable
So you’ll need to reup every existing Hermit
there isn't a parameter that i remember, you'll have to use add_to_deck and remove_from_deck
but this raises the issue of me having to go through every cardarea to check for The Hermit and change their value, right?
like this lua add_to_deck = function(self, card, from_debuff) G.consumeables.config.card_limit = G.consumeables.config.card_limit + card.ability.extra end, remove_from_deck = function(self, card, from_debuff) G.consumeables.config.card_limit = G.consumeables.config.card_limit - card.ability.extra end
oh actually, does SMODS.find_card hlp with tit
Well, Shop and Consumables
tarot packs too
It finds them in Consumables
crap
I don’t think you can save inside a pack
That’s what I said
what if that isn't what you said
What if what you said was what I would have said if what I said was what you would have said I would have said if what you said was what I had said
what is this cardarea called again, i forgot
G.pack_cards iirc
The cooking goes crazy
it changes all existing cards too, which is nice
Progress tho
true
What's the difference emult e_mult E_mult emult?
thats likely beacuse the mod's missing something
yeah, but i can't find what it's missing
What's the difference emult, e_mult, E_mult, emult?
why does this crash the game?
does anyone know if consumables can return +mult?
You can't use them during scoring?
i have a suspicion, but i want to see the error it creates to make sure
i already answered
ðŸ˜
^
Try using card not center
whats the code
ive tried to use a calculate function with context.post_joker but it doesnt return anything
this is in loc_vars(), you have to access extra via center because that's whats passed in
No?
nope
even in loc vars, its still called card
but the naming shouldnt matter
oh, derp
Do you want it to give mult when it is held?
my theory is that how they set up config = {extra = ...} is wrong
pretty much yeah
that's what i was about to say, yeah. i want to see their config table
or that the joker existed in the run without the config table
oh right, it might be a load save test
mhm
does testing with a fresh instantiation of the joker still cause the crash?
you should show us how you set up your config if it still does
The consumables trigger in context.joker_main
config = { extra = { values } },
-# i meant the one thats inside your joker's code
it's the same there
did you try starting a new run?
that's how i did config everywhere
this happens in the menu when i hover over the joker
i see
weird, everything looks right
my only theory is that config is set up incorrectly, but since you claim it to be correct then i dunno whats wrong
it works just fine if i use G.P_CENTERS.j_key
but that includes info_queue of the joker i put into that info_queue
wasn't there a fake_card argument you could use for this purpose
i forget what the thing was
that isnt wanting to work...
Where are you putting it?
in a calcaulate function
Show code
In the consumable?
yeah
Does lua handle ^?
yeah i searched and it does
it works in a joker aswell
but just not in a consumeables
My Tom Scott Joker uses ^ too.
local curxmult = card.ability.extra.basexmult ^ toga_calccopiesofself(card.config.center.key)
is better than screenshot, oop.
Is the consumable in the normal area?
You need to patch it in to the joker calculation areas.
That would be why 😂
how do i make this affect jokers with a specific key?
context.other_card.config.center.key == "key"
can i make like a table of jokers and plug it in there somehow?
you can iterate through the list and return if any matches the key
now this... ive only got a main.lua file so having more files is new :/
a reminder that eventually in your balala modding life you eventually have to embrace the lovely patch
NO DONT SCARE ME LALALALA I ONLY NEED A MAIN.LUA FILE LALALALALA
this is one of the cases where there is no practical alternative
How to make Joker pro availability add +2 slots Consumables?
is it hard to use .toml files? or is it just a case of copying code and boom
you can just copy the manifest at the top and the patch i linked you and just replace my area with yours
yeah, .tomls are basically just a bunch of little wrappers that you stick lua in. mini injectors
do i have to call them in my main.lua file?
no
it needs to either be called "lovely.toml" and be in the root folder or be in a "lovely" folder
How to make Joker pro availability add +2 slots Consumables?
you gain 2 slots when obtained?
if yes then
add_to_deck = function(self, card, from_debuff)
G.consumeables.config.card_limit = G.consumeables.config.card_limit + 2
end
and do the opposite in remove_from_deck
so what would i put here? since i noticed your code in general is a little more advanced than mine
What better place in the joker to write this?
you can just do table.insert(t, your_area)
I don't understand what you mean
so if then table.insert(t, domain)?
so like this?
yeah
that seems... to simple...
so what does your code do? since yours contains a if statement
if the mod has conflicts and smods disables it it doesn't disable the lovely patches (contrary to disabling it manually) so I do a check so the game doesn't crash in that case
but it doesnt really matter
also JoyousSpring.field_spell_area is an alias for G.joy_field_spell_area
Here's the code for this by the way, I just yoinked some of the base game collection code and shoved in my own jokers
So you could ban them with banner or disable them on the same page?
The aether_jokers table just separates my jokers by rarity without the j_prefix_ part
I have no idea how this would interact with banner
You set collection = true
If it works with it then it works with it, but won't require it
Disabling a joker just removes it from the spawn pool and collection
isn’t banner the discard joker
Only adds to the inside joke that every QoL mod is named after an object in the game [=
Even Handy is named after the tag
still upset @scarlet thorn won't name better tags diet cola
Oh it’s a mod too
I hadn’t hear of it
seriously such a missed opportunity 😔
I just need better names for my jokers because I sucks at naming things period
is there a way to detect when Xmult scores?
Try looking at Exponentia from Cryptid
Shitty name
i agree with squid
how do i make custom rules for challenges?
Is there a way to prevent playing cards from being destroyed?
i think names should at least attempt to be descriptive in some way shape or form for a mod and naming them after cards doesnt really do that
:P
my cool new mod 8 of Hearts. it adds 2 quintillion jokers and none of them are worth your time
here's a reference
straight from my mod
talisman is a descriptive name because it is cursed and breaks several mods
go wild i guess
would this be correct for a consumable
Do you have a can_use function?
no
You need that.
mm ok
I mean.... most content mods are gonna have "proper nouns" as names regardless and not be "descriptive"
it's one thing if you're talking about qol mods, a complete nother with content mods
but I personally like quirky mod names even then like Malverk and Galdur, for instance
0 descriptiveness, but unique and memorable
And that's it when it comes down to it, I think Diet Cola actually would be a far more memorable name than Better tags or whatever it's called
but if the dev doesn't like it then fair
this is every hand right
are all of them recognizable
highcard, pair, 3oak, 4oak, 5oak, flush 5
two pair, full house, flush house, sflush(?), straight(?), uh
those are probably wrong
i like the idea though
flush straight straight flush
ok so how would i list the chance of the effect happening (the 1 in 3) correctly
what i mean is that i want the 1 to be 2 if you have oops all sixes
#2#
oh
thats how you use loc_vars in text
i don't think there are tags for the hidden hands
for some reason this triggers like everytime
am i ungodily lucky or is this broken???
em
em
you may be lucky
it should be config={extra={odds=3,mult=15}}
i dont see any issue but
yea generally you should put odds in extra but that wouldnt cause an issue
oh shoot
hmhnhmh
💀 i just automatically assumed they were using extra what is wrong with me
1/3 is such high odds that you'll definitely get strings of luck that may seem buggy
make it like
1 in 289-4353490583094583049-5834095809485 0957645t89y5u4 or something
and then maek it 1 in 1
to make sure it works
evil fucked up double tag
Half Tag
starts run with one double tag
Grurple
ok lets see
oh wait
i see the issue
you set the cards base mult
so it will always be 15 mult
and then when you hit that chance itll happen again
oh.
so yea do config.extra.mult
this?
yea
thumbs
what would be the G.P_CENTERS for a custom seal?
G.P_SEALS
it crashes and displays odds as "nil"
Does someone have an example of setting the flavor text for a booster pack? In my store, when I open my custom packs, they say 'error'
card.ability.extra
is it not centers in loc vars?
i can be very mad at myself for not knowing such simple things
no, it's card
self is a center
you use the group key and define it in dictionary
starting hand and discard
what are you working on squid?
plusle and minunle
rougelite
yes
oh, what are you changing?
Thanks Ice! BTW i love your booster packs for Ash blossom. You nailed it!
thanks! They're mostly traced 😛
I wanna make more at some point, so that they don't share art between mega and jumbo
but yugioh designs are complex
BTW how does the linkage work?
I've got a booster like this
SMODS.Booster({
object_type = "Booster",
key = "RarityCollection",
How would I add that in the localiztion file?
- hand size :D
the word that gets put there is based on the group_key!
Did you see the Yugioh one my wife made for my mod? it swaps between kid and grown-up Yugi if you play the right hand to activate the 'heart of the cards'
definitely didn't, but I'd love to seei t
urbl
yeah, that's done by setting localization for the group_key, which you'll wanna define on a booster pack
what colour are legendary jokers
ohhhh I was doing it by the booster key, not the group key!
booster key is for the individual tooltips
the groupkey is for this part of the ui
maybe pink is a good replacement
Thanks Ice!!
what the fuck did you do
Fixed an error!
reloaded a save probably
...okay
oh god wtf
base balatro can already have that bug, haha
did it take you that long to realize ðŸ˜
silly question
i swear ive done it before but ive forgotten
how would i apply size and color to this bottom string
How does other_card work?
Is context.other_card:is_face() correct usage?
{s:0.6,C:color}?
if the context you're on has other_card then yes
that worked
i just had a space inbetween those 2
does this mean stakes applied go in order of lowest to highest or highest to lowest
Does context.cardarea == G.play has it?
Oh
cardarea is another field in multiple contexts, you should look at the main ones here
https://github.com/Steamodded/smods/wiki/Calculate-Functions
Thanks again Ice!
technically there isnt a plural of shiny but thats the best
I have a card who will proc and kill a card to trim your hand, I have been trying to determine how to add an arbitrary texture to a ui pane for a moment so I can render the shinu kanji. A call back to Rune's Spell in Phantasy Star IV where he does this
What is context for played cards?
context.individual and context.cardarea == G.play
is there a way to partially redraw a played hand back to hand?
like say i play 5 cards, but i want a specific card to come back to the hand after being played
Thanks!
where tf is the empress code ðŸ˜
arent they all in use_consumeable
this one, right?
ðŸ˜
it nvm
i think its something like that, the empress is grouped with the other tarot cards that change enhancements
yeah mod_conv
bump
Maybe hook G.FUNCS.draw_from_play_to_discard and send it to hand instead?
How do you make a global function to check if a blind is beaten? i thought you could just create a function in G.FUNCS with e as argument but it doesn't seem to be the case
elaborate
you might want to hook to end_round(), dunno
I want to check whether the player beats a specific boss blind, and i've got the if statements down, not sure how to call it every frame
i'll try
For what reason
why do you need it called every frame
^
just have it return a bool for whatever blind it receives
or a table of all beaten blinds
please dont think of update as your first solution unless it really requires that lol
depending on what you plan on using
i would actually die out of humiliation if N' were to send me that ngl
i just did lol
🥀
i mean it's just advice for future questions
How do i make it so my joker has the bottom part of the tag switching out like cryptid?
man im still so dumb
copy cryptids code because thats always a good idea
🥀
no problems have ever stemmed from copying cryptids code
FAIR
sorry caps
zed
tbf mathisfun knows exactly what hes doing
-# most of the time
so while cryptid's code looks scary as hell, i think its not too bad :p
yea with cryptid
we dont talk about talisman
but most of cryptid is built around most of cryptid so that leads to many a issues
the problem with cryptid is too many cooks
or should i bump up the mult increase to +10
to 6 so that it ends on an even 10
i think +5 is fine
ah
but when you turn them back to other enhancements, it becomes a pretty bad number 🥀
too many cooks and too many of them are new to programming in general
hooking end_round works for what i was doing btw, thanks
though it doesn't seem like i can edit things about it on the fly the same way one would do with cards
How would one prevent a playing card from being destroyed?
I think the best way currently is to give it a property and then hook dissolve and shatter to ignore cards with that property
also give them a nope message obv
Today I learned Crytid has part of the bee movie in its crash log
yea
based
ok, so i want to hook G.FUNCS.draw_from_play_to_discard(). what's the most efficient way to be like "hey, if X joker is not present, just continue on with the original functionality"
what is the little description called, i dont know the name
SMODS.find_card
badge
ah
i really wish that the G.jokers area had like, a parallel table that was just all keys of present jokers in order, so i could go if aforementionedTable['my_joker_key'] then
you can use SMODS.find_card, it tells you if the joker/consumable exists in their area
That’s exactly what find card does for you
...have i mentioned how much i LOVE reinventing the wheel
"how do i do this thing"
"do this"
"man i wish there was a way to do this thing"
ðŸ˜
i may be stupid
oh yeah, something nice to know is that #SMODS.find_card("key") also return how many instances of that card exist, i think
-# i faintly remember someone saying so
i mean i think they're talking about having a look up table but trying to optimize something that has at most 100 iterations in the worst case scenarios doesn't make much sense
yes
:3
yea it returns every instance of it in a table
We could probably repurpose the used_jokers table to do something like that
i mean, i knew find_card() existed, i just for some reason had it in my head that it's not something that should be used with significant frequency
so if you just want to check if the card exists do if SMODS.find_card()[1]
next(SMODS.find_card()) is more efficient iirc
or next
whats next do
not if your just checking for its existence
Just to be sure, this is correct? I mean it looks correct in game but I dont know if i somehow implemented it wrong
so im trying to make a joker that turns any scored cards with seals into my custom seal but its not working...
gives you the next item in a table
you should probably use context.before or something instead
next just looks at whatever thing is next in the table. it can take a second argument, which iirc it expects to be a table index
also
context.other_card
context.other_card
if you have an empty table [1] only looks at one vacant slot as opposed to next() which would need to look at all of them
treated as every rank
well next doesn't care about whether or not the table is indexed or is key based
quantum rank technology is too hard for me
make quantum ranks real
😠HOW
Okay, one last question for now, how do I hide the mod tag. I want it to just be the game its from
i cant just magically make :get_id() == 13 works with a seven of spades ðŸ˜
did you ever do this btw
What's the difference between card.seal and card.ability.seal?
context.other_card smh
Sorry I’ve not had chance yet
in what context? in a take_ownership()? in something you're adding?
god
it's all cool
under the card, it says what mod its from, how can i remove that within the code
order doesn't matter but it still needs to check the full structure to be sure that it would return nil
set_mod_badges is the function that does that iirc
yea
What about making it not be debuffed by suit boss blinds?
so do you think this would work?
cause like i dont understand that
uh
set_mod_badges = function(self, card, badges)
badges[#badges+1] = create_badge('Femtanyl', G.C.WHITE, G.C.BLACK, 1)
end,
like this?
if you had a structure and were asked to return a random value in that array or nothing if it's empty, you would traverse the structure to find some value you can return. to know you can safely assume you can return nothing, you need to traverse the entire structure
however if you're asked to return the element at some certain position in a structure you'll just check whether there's something in that position and you can safely return nothing immediately then
think of it like this, G.play.cards is just a table containing all played cards, from left to right
Stop using context values without context. pls
so when you run for i,v in ipairs(G.play.cards), v refers to a card in played hand
yeah but like wtf does ipairs mean
"please check this table from the first value to the last value"
local hi = {9,5,3,9,5,9,3}
for i,v in ipairs(hi) do
print(v)
end
9
5
3
9
5
9
3
hm, okay so v would be a card?
mhm
meaning i could check it for seals?
yes
ah okay ty!!
ipairs will only do value ranges without breaks. [1] = true, [2] = true, [3] = true, [5] = true will only do the first 3.
yeah, that
What a fun feature!
truly
is there a way to just have it be the text only and no blue part?
set_badges = function(self, card, badges)
badges[#badges+1] = create_badge('Femtanyl', G.C.BLUE, G.C.GREY, 1)
end,
G.C.CLEAR instead of blue?
is clear even one
wow guys, what a useful feature! i truly do love modding balatro, the hit indie title and game of the year nominee!
yes
yes
yeah so, i was about to respond to this
im not sure how i would go about with this one
oh
my first plan was to hook to is_suit(), but that makes jokers which check for suits fucked
thank yall
I think you’d need to override is_suit to add an extra flag to it for when the blind is doing it’s checks
oh, its possible to do that?
-# or alternatively, i could just make wild cards unaffected by debuffs completely, but why do i feel like a joker already has that effect
You can do a lot with a simple hook, including replacing the function outright for the most part, but as it is a "hook", you are to call the original function. Replacing without referencing the original function is an override.
yeah, i know that - i meant the flag part lol
permanent marker, extra credit
technically, it's all enhanced cards, but still
yeah, thats what im afraid of
i dont want to add a feature thats only compatible for vanilla blinds 🥀
You could it set a global flag instead
Oh modded blinds would be a nightmare I’d avoid them completely
i dont like inconsistency..........
like, i will probably have to go with the effect: Can't be debuffed by (most) Boss Blinds
and i think it looks goofy ðŸ˜
You could just do wild cards can’t be debuffed
this might be a dumb question, are you able to put symbols into the joker names
That should be pretty simple
like, [ " ] /?
i was thinking of like a little heart symbol lol
my joker has a star in the name but the balatro font doesn't have that so you need a custom one to see it
oh, i dont think so
damn
-# you will need to add a new font i think
uh, what function is run to debuff a card again
:3
ill probably just skip on the heart, im prob releasing this mod and i dont want to force people to install a font for it
you can't just package it with the mod?
^
yea, but like, im lazy :3c
ðŸ˜
i should change my name to a context too
this is a good one
it's relevant to my struggle
jokes on you
not the localization...................
they call me context.cardarea == G.play
uhh so this doesnt work, it doesnt even print true even with a hand with scored seals in it
New names are fun when you’re still identifiable
true
also what happened to your names?? ðŸ˜
we're becoming balatro
balala
olh
you mean the tooltip?
yea
i guess the balatro was the friends we made along the way ahh
oh or the badge
i think they meant the badge
polychrome above the DDG
yeah, the badge
friends vs balatro?
i havent dealt with seals yet, but i dont think thats how you check if a card has a seal or not
card.seal returns a string of seal name, or nil if no seal is there
ah, i see
and i checked deja vu, it uses set_seal()
Remove the cardarea check
also, you should use context.before instead
wait nvm u r
i thought that was context.individual for some reason ðŸ˜
feafeom ye, remove the cardarea part
is this how i do it
actually, this currently doesnt help to un-debuff currently debuffed cards i think, hm
you can try doing something with context.debuff_card and prevent_debuff
new blind calc context
oh
return debuff = true to debuff and prevent_debuff = true to undebuff
ah icic, but i was mostly concerned about other sources
like jokers which debuff some playing cards
so even if you turn those cards into wild cards, i dont think they wil de-debuff themselves
that context ignores debuffs i think
but it only runs and the beginning of the blind i think so it wouldn't help if a joker does it in the middle
crap
hm
another idea is that when you use The Lovers, it de-debuffs selected cards too
doesnt help if they are turned to Wild Cards through other means though, hmmm, maybe i should hook to set_ability?
i think that makes sense
this is supposed to trigger on stone cards, but instead triggers on enhanced cards if stone is played
you dont need to go through context.scoring_hand again
Also there is SMODS.has_enhancement
if context.cardarea == G.play and context.individual and SMODS.has_enhancement(context.other_card, "m_stone") then
SMODS.has_enhancement still calls SMODS.get_enhancements fwiw.
and in here, just return mult, and you should be good


