#💻・modding-dev
1 messages · Page 615 of 1
How would I check what the best possible poker hand is with a group of cards
G.FUNCS.get_poker_hand_info(cards)
i may be stupid
i accidentally put the jokerforge scripts into the main mod so now i gotta recode negative deck
🧠
🗑️
wtf does this mean
is there a way to give a card multiple descriptions
not from what ik
wdym
Like
If i wanted to make multiple descriptions based of context
(Kinda like sleeves alternate description)
I gotta be more specific
So lets say theres a thing called miracle rank
So when its rank is 2 or above it adds xmult to lucky cards
So you want the lucky card description to update when the card has a certain rank?
Kinda like that
In that case you would need to take ownership of lucky cards or hook/patch one of the functions that generates the UI depending on what you want it to look like
for the former you can still use this
K
Ive seen it mentioned before but i forgot to take notes
how do you fix the error message again?
it returns the next value in a table from the index in the second argument, or the initial value if there is no second argument
how does this even work LOL
that's a sick idea but how do you even make that
yea
ah
ive fooled a play tester of mine twice lmao
(and myself)
its insane how gullible discord users are when they a discord notif sound with the correct pitch and speed
budomp
the effect is still place holder bcs idk what itll do
but this isnt really about the discord seal lmao
i want to replace the error text when you hover over any of my seals/consumables
@wintry solar is the calc fix on dev branch? I could check if my stuff works now but I don't have too much time today
how do i change straight/flush requirement?
what do you want to change
like how four fingers changes the cards required to make a straight/flush
do you want to change the amount of cards like four fingers or something else?
exactly like four fingers except 3
like this?
local smods_my_joker_ref = SMODS.my_joker
function SMODS.my_joker(hand_type)
if next(SMODS.find_card('j__my_joker')) then
return 3
end
return smods_my_joker_ref(hand_type)
end
cant you look at four fingers and change what it does to 3?
i could very well be wrong
no, the function is called four_fingers
ah
you would only change the key in find_card and the returned number
local smods_my_joker_ref = SMODS.four_fingers
function SMODS.four_fingers(hand_type)
if next(SMODS.find_card('j__my_joker')) then
return 3
end
return smods_my_joker_ref(hand_type)
end
```?
yeah
what would happen if you made it 1?
would everything just be a straight flush?
(except for flush house and such)
well ive been passively learning lua in my journey of a fun mod for my friends
and i think logically speaking it makes sense
because the way the game looks for a straight and flush is seperate
so im assuming it would see the 1 card as a straight and a flush
Yeah prob
straight logic requires at least 2 adjacent cards
so you would still need 2 for strush
it does make anything a flush tho
how do i make it print out the count
because i know this is probably hurting whoever is reading this code
as much pain
as it is giving me
but i tried somethings and nothing seems to actually print out the count
if you have debugplus print(count) should print to the screen
why not just do count .. " messages" for all of them under 10 lol
also yeah print prints to the debugplus console
piratesoftware
😭
i do NOT wanna have this undertale ahh code
well the issue isnt with the count itself
it "works"
oh did you mean print as in the joker message?
do what eris said
see i tried this but with a +
are you supposed to do with two dots here?
maybe its just because ive been debugging my java project all day where you have to do + on a sys.outprint
yeah in Lua it's ..
bro this dumbass picture is killing me
Got a problem
if context.card_added and context.cardarea == G.jokers then
return {
message = "Ah",
colour = G.C.MULT,
sound = 'R14_ah',
}
end
I just want the message to display one times when the joker is added, but instead, each time a joker is added it redo the message, anyone can help to fix?
if you want a message when your joker is added use the add_to_deck function instead
Let me check
Doesn't work at all
I have try with context.add_to_deck and
context.add_to_deck and context.cardarea == G.jokers
it's not a context
add_to_deck = function(self, card, from_debuff)
if not from_debuff then
SMODS.calculate_effect({
message = "Ah",
colour = G.C.MULT,
sound = 'R14_ah',
}, card)
end
end
Not yet
bump 
I don’t have any resources but can help answer any questions you have in an hour or so once the kids are in bed
i just wanna know how to make a cardarea
i have a vague idea of how to interact with one, but i have no idea how to create one and have it properly display in the run UI
i guess i also need to know how to get calculate to process it during a played hand
huh, i thought all of joyoussprings cardareas were toggled
not in sense of usage, but in the sense of accessing it - like the monster cardarea. you have to hit the toggle to see it
but that's what the hide ui bool is for. okay, thanks 
it used to be like that but the field area is now visible at all times
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play and G.playing_cards then
for _, deck_card in ipairs(G.deck.cards) do
if not (deck_card == context.other_card) and not (deck_card:get_id() == context.other_card:get_id() and deck_card:is_suit(context.other_card.suit)) then
return {
xmult = card.ability.extra.timesmult
}
end
end
end
end
trying to iterate through the full deck and find if there is more than one copy of a specific card with same rank and suit
but im not sure how i'd properly check that with the first if not statement
I know n' says i can make alternate descriptions
But like
Im still confused
How do i apply the contexts for which description i want it to use
wdym alternate descriptions?
Its a bit complicated
But you know how sleeves have descriptions based off whether not you are using the matching deck?
I kinda wanna do something like that
oh okay idk about that? i assume it'd work the same way jokers do with alternate descriptions though
pseudorandom_element(table, seed)
ty
okay im kinda going mental here lol im tryna make a deck that swaps any played cards to a random suit
i have all the syntax done im just going insane at this part
well not syntax but everything else is done
SMODS.change_base(changeSuit, pseudorandom_element(SMODS.Suits)) i think
thats all?
for changing the suit yes
what is that doing
its tryna index it but it says its a nil value
idk it just brings back this
.................why do you have that there if you dont know what the goal of having that is
oh okay
okay yeah
what happened was when porting over the deck or smth i deleted the script for the default edition and enhancement jokerforge packs with it not knowing i needed it to not crash the game immediately
turns out this did not work
show full code
1 sec
whats the key if any that i use for this
its just .key
alr
for getting the key of the suit
also you do need to actually define the card youre changing the suit of somewhere
so this should work
isnt context.played_card or smth a thing
no context.before doesnt run with a card in a context
you need to loop context.scoring_hand
or context.full_hand
@wintry solar for malverk, is there any extra steps to add texture packs for your mod?
okay im sorry im slow is this what i needa do
something like set = 'X' being set = '[prefix]_X?
no its still the same context
as an example
alr
hi everyone , does anybody have an idea of why all the things after my "card.ability" is unknow ?
vscode doesnt know balatro well enough to understand that the config in the definition gets copied into card.ability
okay i see i see
even with all the LSP
uhhhh yeah it depends on what you're trying to make a texture for
yeah but it just crash balatro to with an error
well then send the crash log
and for all of my other joker it show me what is it
because its probably not related to it being unknown in vscode
i think i actually figured it out
im confusing myself more than i am making sense of literally anything im making lol
but um the wiki is no longer on the repo
thats correct but its still the same SMODS.change_base for the suit change
like that
nvm figured it out , it was from an other joker lol
thank you
oh no what a shame!
-# it's never been on the repo shhhh
is there like a prefix for texture packs like tp_ or t_
so do i just get rid of the set_suit part
texpack_
okay no wait how tf did THAT get there???
uncertainly SMODS
SMODS or nil
save me tom cruise
on a side note is there a list of all the sounds i can put in this
/media/Shared/SteamLibrary/steamapps/common/Balatro/Balatro/resources/sounds
❯ ls
ambientFire1.ogg explosion1.ogg music5.ogg
ambientFire2.ogg explosion_buildup1.ogg negative.ogg
ambientFire3.ogg explosion_release1.ogg other1.ogg
ambientOrgan1.ogg foil1.ogg paper1.ogg
button.ogg foil2.ogg polychrome1.ogg
cancel.ogg generic1.ogg slice1.ogg
card1.ogg glass1.ogg splash_buildup.ogg
card3.ogg glass2.ogg tarot1.ogg
cardFan2.ogg glass3.ogg tarot2.ogg
cardSlide1.ogg glass4.ogg timpani.ogg
cardSlide2.ogg glass5.ogg voice10.ogg
chips1.ogg glass6.ogg voice11.ogg
chips2.ogg gold_seal.ogg voice1.ogg
coin1.ogg gong.ogg voice2.ogg
coin2.ogg highlight1.ogg voice3.ogg
coin3.ogg highlight2.ogg voice4.ogg
coin4.ogg holo1.ogg voice5.ogg
coin5.ogg introPad1.ogg voice6.ogg
coin6.ogg magic_crumple2.ogg voice7.ogg
coin7.ogg magic_crumple3.ogg voice8.ogg
crumple1.ogg magic_crumple.ogg voice9.ogg
crumple2.ogg multhit1.ogg whoosh1.ogg
crumple3.ogg multhit2.ogg whoosh2.ogg
crumple4.ogg music1.ogg whoosh_long.ogg
crumple5.ogg music2.ogg whoosh.ogg
crumpleLong1.ogg music3.ogg win.ogg
crumpleLong2.ogg music4.ogg
/media/Shared/SteamLibrary/steamapps/common/Balatro/Balatro/resources/sounds
and here's if you want to add your own sounds: https://github.com/Steamodded/smods/wiki/SMODS.Sound
remove that event outside of the loop
which one do you prefer? (the first is a reference to the original baba texture pack)
the rose colored one looks cool
also still no dice
unless i have to move the func = function() line
maybe i shouldve tested out the texture pack apply before handling the localization 💔
yeah that wouldve worked
woops i forgot i put malverk compat in a seperate lua file
my best guess is that its trying to grab from the base game's decks so i need some way to let malverk know that its my decks
could it be this line thats messing everything up?
idk man
@slim ferry am i right here
figured
set_suit doesnt exist
and changeSuit isnt defined
and differentSuit also isnt defined
@wintry solar i tried a few things messing around with the values, but no dice.
differentSuit is defined just above it
SMODS.change_base already changes the suit
on its own
you dont need another function
so i dont need the changeSuit(differentSuit) or the local differentSuit =
like this?
im so confused bro
it didnt go anywhere
nice one lol
me too dw
that may be why
ykw i probably dont even need that first if statement
nvm i think i do lol
what do i pur to replace that
alright
i dont understand why this isnt working then???
like this should be working fine right
(ignore that massive indent mistake lol)
@willow scroll dev branch has the fix now, should work fine for you
remove the func = function() and one of the ends
what you're doing there is defining a global function called func
idk why this is causing all the cards to be debuffed
i dont think v.seal is every false but aside from that, do you have any enhanced cards when this runs?
yes
when does it run
its for a boss blind
when does it run
you shouldn't be running stuff in calculate without a context check
also for blinds I recommend just using context.debuff_card
didnt change anything sadly
if context.debuff_card and (not context.debuff_card.seal or not next(SMODS.get_enhancements(context.debuff_card))) then
return { debuff = true }
end
sweet ill try that
@red flower help me out here fam
whats making my code not working
i should also include this
let me read it but pls dont tag me for help, if im here and want/can help i will
alr
same thing
- it should be
G.GAME.selected_back.effect.center.key - you are missing the .key when you choose a random suit
- remove the return true
what does it do exactly
thanks man
oh
ok i just copied your logic because i thought it's what you wanted but the problem is that you are checking that the card doesnt have a seal or enhancement
instead of checking if it doesnt have either
you can replace the or for an and
but then wouldnt that only work for cards that have an enhancement and a seal?
no
still nothing
may i see
can i see the entire object
😭
oh god
so i get rid of the key check
yeah
okay now it says my custom sfx doesnt exist except for the fact it does
it needs your mod prefix
I really recommend just setting up a dependency over copying the code or making your own system. Value manip is fidgety with a loooot of edge cases that you need to make systems for to be able to deal with. Copying from Cryptlib or blockbuster would also carry the risk of introducing a near identical system that might overlap in the names of variables, or start behaving weirdly in other ways when both your copy and the original are present. It also means that you're no longer benefitting from the library being maintained. Bugs are now yours to fix, and that's probably harder if the system is new to you
am i putting this in right idk what im doing wrong here
...the modprefix of the mod...
it has to be your mod's prefix, what you have in your .json or header
works great
usually you want to post the entire log
this might be a talisman crash, try updating it or disabling it
you shouldn't use the dev version of smods unless you know what you're doing btw
disabling it didnt work lemme try updating it
nope
actually itd help to re-enable talisman
1 sec
what's your code looking like now
not much different rly
that's not how you use SMODS.Sound
the only thing i can think of is the smods.sound is in the wrong place
yea thought so
i just followed the api
and the thing doesnt show you how to use the smods.sounds thing
atlas = "purp",
loc_txt = {
name = "Material Pack",
description = {
"Choose one of up to 3 {C:attetnion}Material{} cards."
},
group_name = "Material_Pack"
},``` why isnt the description (or name) showing up
oh okay
it does
i recommend reading this
https://github.com/Steamodded/smods/wiki/API-Documentation
can i see the loc_vars if you have them
local cfg = (card and card.ability) or self.config
return {
vars = { cfg.choose, cfg.extra },
key = self.key:sub(1, -3), -- This uses the description key of the booster without the number at the end
}
end,```
remove the key
ok so the name shows up, but not the description
okay so the deck effect works now but it didnt work exactly how i wanted it to, it changed the suits before the scoring, not after the scoring
i tried changing the before to an after, merge the bottom if statement into the top one, etc and it just refuses to happen after?
unless im using context.final_scoring_step wrong
guys how do i make consumables selectable from boosters, like cryptid code cards?
https://medal.tv/games/balatro/clips/lrvvmOelbD-yGAEBQ?invite=cr-MSxhOHQsNDMyNTk1NDk1&v=20 also heres the deck in action
Watch STINGER DECK!!!!!! by genevanougat and millions of other Balatro videos on Medal. Tags: #balatro
2 questions, whats wrong with it and how do i stop the pseudorandom from rounding the xmult
okay so now it happens after but its like once the cards are going offscreen
what context are you using
context.after
try before
alr
im also gonna give it a message when it changes the suits colors
i forgot how the line for custom msgs works lol
what's the code for custom msgs to show up for when the suit changes
guys
uh
i kinda can't get into github
because i forgot to set up the stupid 2 factor authenticator
i have a small question, if i create a new modded rank thats intended to exist for all suits (even other modded ones) and another mod adds a new rank, how does that work then?
i assume a blank card texture or smth?
im talkin like this
I mean… I guess I did have another joker planned besides Ralsei which makes jokers rare and below have 10x values. (Jimbo - Grandiose)
It was just supposed to be for one joker, but I’ll just tell everyone that I am planning to use it for a future joker.
Oh yeah, do I use cryptlib or bbvmapi?
okay is there a way i can make the deck display a message, similarly to gros michel, with a custom message?
chat how do i stop the random from rounding?
all it max mult gain triggers thrice for some reason
pseudorandom with a min and max always returns integers
if you want numbers between 1 and 1.5 do 1 + pseudorandom("seed") * 0.5
decided to try and make custom things, any thoughts?
a bit simplistic but that's not necessarily bad
I assume unique designs are gonna go in each circle, but I also recommend having something more than just a solid color for the background. maybe a light to dark gradient?
i like it
also W etoh player
its mainly meant to be charms from the game called rooms and doors, i didn't really have alot to go off of besides literal circles 😭
ah I see, dunno the reference sorry
in that case definitely spruce up the background
maybe some sort of pattern like a lot of food jokers have
ill probably add more interesting things inside the circles
<@&1133519078540185692>
trying to get this to work but for some reason whenever i hover over the card it keeps crashing? any help?
oh no 😨
...okay were taking a step in the right direction
not only that, your messages indicate at least two steps in the right direction
cant seem to get the text to show up :/
are you using a localization file
yeah
return {
descriptions = {
Charm = {
RnB_chm_none = {
name = "None",
text = {"Does nothing."}
}
}
}
}
are they consumables
What did you use to create them
SMODS.Center:extend
Can you show that part
RnB.Charm = SMODS.Center:extend{
unlocked = true,
discovered = false,
config = {},
set = "Charm",
class_prefix = "chm",
required_params = {"key", "atlas", "pos"},
pre_inject_class = function(self)
G.P_CENTER_POOLS[self.set] = {}
end,
set_card_type_badge = function(self, card, badges)
local display_info = {"Charm"} -- first entry is the type name
if self.badges_info and next(self.badges_info) then
for _, v in pairs(self.badges_info) do
local localized = localize(v)
if localized ~= "ERROR" then
display_info[#display_info+1] = localized
else
display_info[#display_info+1] = v
end
end
end
-- create the badge
badges[#badges+1] = create_badge(display_info, G.C.RED, G.C.WHITE)
end,
generate_ui = function(self, info_queue, card, desc_nodes, specific_vars, full_UI_table)
SMODS.Center.generate_ui(self, info_queue, card, desc_nodes, specific_vars, full_UI_table)
end
}
Try chm_RnB_none
would you know how i'd add a card area for the charm here?
iirc the spacing is defined by the maximum number of cards that can be on the page, even if you don't fill it all the way
so it'll look more natural when you have more charms
crashes when attempting to apply baba is gros
❯ ls -R
.:
assets gimp localization main.lua meta.json src
./assets:
1x 2x
./assets/1x:
back_baba.png back.png
./assets/2x:
back_baba.png back.png
./gimp:
back
./gimp/back:
purple_baba.xcf purple.xcf
./localization:
en-us.lua
./src:
back pre
./src/back:
purple.lua
./src/pre:
atlas.lua malverk.lua
if someone more experienced with malverk wants me to post a zip to debug it uh i can do that too
I'm trying to make a tarot card that has the same functionality as Death, but min_hightlighted doesn't want to cooperate...
key = 'merge',
set = 'Tarot',
atlas = 'tarot',
pos = { x = 0, y = 0 },
unlocked = true,
discovered = true,
cost = 3,
config = { max_highlighted = 2, min_highlighted = 2 },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.max_highlighted } }
end,
use = function(self, card, area, copier)
[ ... ]
end,
}```
The logic in use is purposefully truncated to save space
Am I doing this right?
Unless the logic in use is important to min_highlighted, which if so, I can send the entire block of code
Did you override the can_use function and didn't include it here?
Not for this one
Maybe just try starting a new run
Can set_ability work with custom enhancements?
Trying to make a joker that sets cards to a custom enhancement I made and I’m having trouble
Bump?
Iirc i think so yeah
yes
key should be of the format "m_modprefix_enhancementkey", where modprefix is your mod's prefix and enhancementkey is your enhancement's key
Dope that worked
do you guys know any mods that add card areas which i can look at to reference
paya's terrible additions adds one for dos cards
kkty
When I try to combine things on text like {C:attention, X:red} I only ever get the first thing
Am I formatting it wrong? The examples I can find do it just like that
no space after the comma
Always something silly
I think this is a good way to translate wrath into the game
Wrath In RnD: Health + Stamina are Linked. X0.5 Stamina Actions, X1.5 Health Loss
Wrath In RnB: Balances Chips and Mult, X0.5 Chips, X1.5 Mult
self.rnb_charm_area = CardArea(0, 0, self.CARD_W, self.CARD_H,
{ card_limit = 1, type = 'chm', highlight_limit = 0 })
does the 0, 0 at the start mean the x and y position?>
probably? but you should init it at 0, 0 anyway
here's how PTA sets the position for dos cards, it's done after the fact (still in the start_run hook)
also how would i get a charm in the area for testing?
use the SMODS.add_card function, and in the table of arguments, set area = [your custom cardarea]
huh
ah, fun
do you know why it does that?
no, i haven't messed with custom cardareas myself, sorry
okay 🥹
set the type to joker
does this have any relevance even if its a completely different center type?
yes that's what consumables use too
WHY THE HELL IS THAT SO UNINTUITIVE??
other types have to be defined but in most cases it's unnecessary
G.consumeables
you wouldn't happen to know how to get the thing to actually calculate, right?.
i put this in a toml file but it doesnt seem to work:
# CHARMS!!!
[[patches]]
[patches.pattern]
target = '=[SMODS _ "src/utils.lua"]'
pattern = "-- TARGET: add your own CardAreas for joker evaluation"
position = 'before'
match_indent = true
payload = '''
if RnB and RnB.rnb_charm_area then table.insert(t, RnB.rnb_charm_area) end
'''
calculate = function(self, card, context)
if context.individual then
local other_card = nil
for i,v_card in pairs(G.jokers.cards) do
if v_card == card then
print(i-1)
if i-1 ~= 0 then other_card = G.jokers.cards[i-1] end
end
end
print(other_card)
-- add the thing
if other_card then
Bitterstuff.forcetrigger(other_card, context.individual)
print(other_card.key)
end
end
end
why code not work :(
you should just depend on cryptlib
bnver
im currently going through the agony of installing lua
im not sure if this is even necessary ☹️
you don't need to instal lua for modding
just something like notblock plus or any text program that handle codding in lua works
Vsc 🤤🤤
hey y'all, i'm trying to change the cards in a booster pack when the pack is opened by iterating over G.pack_cards.cards, and i want the change to occur immediately after the cards are created. How can I do this? context.open_booster seems to be called too early, and at that time G.pack_cards is nil
is there a way to stop the max_mult_gain to stop triggering thrice
also is there a way to make pseudo random give decimals
you mean the second condition?
ye
yeah that one is not correct
gimme a sec
it should be context.before or (context.end_of_round and context.main_eval) or context.pre_discard probably
unless you want it to be for each card played or discarded
then yeah that
as for the psuedo random
is the solution simply multiplying it by 100 for it to be an integer then dividing it by 100?
that works
you can also not give it a range and do the thing where you add the min and multiply by the max
what?
like pseudorandom("seed") * (max - min) + min
oh wait
Xmult = pseudorandom("pagerson") * (card.ability.extra.Xmult_max - card.ability.extra.Xmult_min) + card.ability.extra.Xmult_min like this?
yes
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
G.STATE = G.STATES.GAME_OVER; G.STATE_COMPLETE = false
'''
position = "after"
payload = '''
check_for_unlock({type = 'bstuck_soporpie'})
'''
match_indent = true
times = 1```
Does anyone know why this isn't working? My first time trying to do a code injection, so sorry if it's something stupid. This is all I've added so far, unsure if I gotta put something else somewhere else
here? works for me
have you considered checking the food jokers
yeah, so it unlocks on losing
weird. i'll try messing around more, thank you
make sure to have this space in the pattern
oh so 'k_[insert message]_ex'
idk why
oh the dictionary
is it not patching or is it not working
How do I know the difference? /genquestion
Wait, no okay weird thing:
It works if I'm at 0 handsize, but nof if the deck is at 0 cards
Okay the injection is working, I'm likley just injecting in the wrong place. I can probably get it from here, thank you! @red flower N
can someone sauce me the link for dictionary
you can check the line in lovely/dump/<file> to see if it got injected
Why my patch isnt working I just want my enhancement to be use in golden ticket
I would take ownership instead, but the name field in modded stuff doesn't necessarily have the name of the object
oh so its using lovely dump and not the source code
It did got injected, dworry. My only struggle right now is that G.FUNCS.draw_from_deck_to_hand only seems to like. handle killing you if you have 0 handsize, but not if you have 0 cards in deck? and I have not been able to locate where that is. If you have any idea where to check lmk
just extract the game files and look at it yourself
yes
that doesn't have anything to do with what i said if you were replying to that tho
but like if I take ownership I need to rewrite the entire calculate fonction, no?
yeah
how can i make a joker instantly open a booster pack like a tag, say the standard pack for now.
its this iirc
check how the tags do it in vanillaremade, it should be pretty portable
but opening packs is kinda janky if you do it in the wrong place
oh it ends the round which triggers the end of round function. that makes sense, I should have looked there, thanks!
what about in-shop or in a round?
actually just in shop
in a round it breaks a bit, in shop it should be fine?
alr cool
so something like this?
tag:yep('+', G.C.SECONDARY_SET.Spectral, function() -- am i supposed to change `tag:yep`?
local booster = SMODS.create_card { key = 'p_standard_mega_1', area = G.play }
booster.T.x = G.play.T.x + G.play.T.w / 2 - G.CARD_W * 1.27 / 2
booster.T.y = G.play.T.y + G.play.T.h / 2 - G.CARD_H * 1.27 / 2
booster.T.w = G.CARD_W * 1.27
booster.T.h = G.CARD_H * 1.27
booster.cost = 0
G.FUNCS.use_card({ config = { ref_table = booster } })
booster:start_materialize()
G.CONTROLLER.locks[lock] = nil -- what's this do?
return true
end)
@hybrid iris
you should remove the yep function yeah
you want the part inside
try assigning it to G.play?
k
Seems to work, ty
no prob!
I dont understand why it doesnt work again
It all works now, thank you! @red flower
the key is just ticket
also remove the card = self
and replace self.ability.extra for card.ability.extra
I litteraly coppied the lovely dump my bad
yeah but self in the vanilla function and in smods stuff is not the same
oh youre missing a context check
oh yeah right
not relevant to this but talisman messes with the buffer timing? doesnt that affect gameplay?
SMODS.Joker:take_ownership(
"ticket",
{calculate = function(self, card, context)
if context.individual and context.cardarea == G.play and
SMODS.has_enhancement(context.other_card, 'm_gold') or SMODS.has_enhancement(context.other_card, 'm_giga_perfectGold') then
G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra
return {
dollars = card.ability.extra,
func = function()
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.dollar_buffer = 0
return true
end
}))
end
}
end
end},
true)
still crash
(SMODS.has_enhancement(context.other_card, 'm_gold') or SMODS.has_enhancement(context.other_card, 'm_giga_perfectGold')) add parenthesis
omg I forgot everything
hell yeah it work
thx N'
but if another mod is using ownership on this card its going to nuke it, no ?
yes but thats basically unavoidable
i would maybe look into making your card always treated as a gold card instead?
hum how do I do that
in toml ig
no you can hook it you dont need to patch it
is there an example of hook, Im not that advance
i am genuinely confused, idk which shader it is + why the error is happening
I did the hook but like the problem is that now its alway considered as a gold card but sometimes I need it to not
and it doesnt work
Yes, it's SMODS.has_enhancement
No, it's SMODS.has_enhancement
oh the fonction itself my bad
is there a way to have your mod check for updates by like comparing it to the latest github version, or does steamodded handle that already?
maximus has an update prompt so you could look at that
i cant imagine its easy since otherwise more mods would just do that
--#region HOOKS
local enhancement_yapping = SMODS.has_enhancement
function SMODS.has_enhancement(card, key)
if key == 'm_gold' then
return enhancement_yapping(card, 'm_gold') or enhancement_yapping(card, 'm_giga_perfectGold')
end
local ret = enhancement_yapping(card, key)
return ret
end
--#endregion
does the ret is useless in that
oh no its not
how do i check if a card is part of the collection?
card.area.config.collection
depending on where you do that you might need to nil check card.area
thanks ^u^
is there a way to ban an edition from appearing on a specific set of Jokers?
this would look strange on Stencil, Half and Hole in the Joker
No.
calculate = function(self, card, context)
local my_pos = nil
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
my_pos = i
break
end
end
if context.end_of_round and not context.blueprint and context.game_over == false and context.main_eval then
if my_pos then
local sell_minus = G.jokers.cards[my_pos - 1] or nil
local sell_plus = G.jokers.cards[my_pos + 1] or nil
card.ability.extra.dollar = card.ability.extra.dollar + sell_minus.sell_cost or nil + sell_plus.sell_cost or nil
end
end
end,
calc_dollar_bonus = function(self, card)
local result = (card.ability.extra.dollar)
card.ability.extra.dollar = 0
return result
end
My joker is meant to give the sell value of the joker on the right and left of itself as the cashout, it will crash in case of no joker on the left (and presumably on the right too), tried to use 'or nil' for it but will still do, if someone could help me please
oh and just noticed it'll only take the sell value on the left
for a blind how can i take $2 per joker triggered
calculate = function(self, blind, context)
if not blind.disabled then
if context.post_trigger then
return {dollars = -2, message_card = blind.children.animatedSprite}
end
end
end
how can i take x$ per, say gold card, scored?
You mean you want to take $1 for every gold card scored?
calculate = function(self, blind, context)
if not blind.disabled then
if context.post_trigger and next(G.play.cards) then
local count = 0
for k, v in pairs(G.play.cards) do
if SMODS.has_enhancement(v, 'm_gold') then
count = count + 1
end
end
return {dollars = -count, message_card = blind.children.animatedSprite}
end
end
end
ty
Does SMODS.post_prob have a specific internal or API purpose or is it (to my best knowledge) just keeping track of past occurred probabilities?
it's for calculating the context after animations play iirc
how do i make the game just instantly lose
is there a way to download the vr wiki?
git clone https://github.com/nh6574/VanillaRemade.wiki.git
check the vr wiki :3
@umbral spire https://github.com/nh6574/VanillaRemade/wiki#how-do-i-change-the-blinds-requirement-in-the-middle-of-a-blind
nh got all of us covered
like im not sure how to do it. its not the end of the world and just drop that malverk thing
ty homie
how do i make a card thats missing either a rank or a suit
so like a random chance or something like the wild/stone card
like the wild/stone card
any_suit, no_rank, and no_suit
ah
trying to use the https://github.com/Steamodded/smods/discussions/919 SMODS.Scoring_Parameter and SMODS.Scoring_Calculation Example but it appears to be doing nothing
hey folks, need someone with more experience than me
Balatro+ crashes my game if i use 6ixth Sense
what's balatro+
paste in the full crash log in here, stack trace is usually the least useful
(Also probably better in #⚙・modding-general)
ofcourse thank you 1 second
once it's set up you need to actually set the scoring calculation
replace "expo_ecalc" with your own "modprefix_scorecalckey"
(this sets the scoring calculation at the start of the run)
from the SMODS.Scoring_Calculation
ah
that you make
wait whats scorecalckey
i think it would be power in this case or juice in the example code
maybew
idk
im not sure if i need to replace that part or
i have no idea what any of that means, i keep seeing somthing about the LUA file
update yo mods, fool!
not like it matters anymore lost everything lolol
they stole my set_scoring_calculations 😭
I assume calculate functions don't run on cards in your deck, right? I'm having an issue where a playing card destroyed in my deck doesn't activate an on destroy enhancement.
card destroy calculations arent run unless you either use SMODS.destroy_cards or calculate it manually
oh wait like that
yeah
you can enable cards in deck calculating i think though
deck cardarea optional feature should do that
I am using SMODS.destroy_card, but it doesn't seem to activate the calculate function of the enhancement unless it's in hand
yeah so
enable the deck cardarea from these https://github.com/nh6574/VanillaRemade/wiki#what-are-optional-features
should work
i think
Ah, yep, that looks like what I'm looking for
How bad is the hit to use the deck and discard optional areas?
not that bad i think
it does add a bunch of extra calculations but performance shouldnt take much of a noticable hit
where could i learn about and check how button ui works for items like jokers, for instance in the shop slots where jokers can be bought?
found hte issue: the prefix in my json file was rmd and it was using that
i so stupid
update = function(self, card, dt)
if card.ability.extra.active == true then
G.SETTINGS.GAMESPEED = 8
end
end,
remove_from_deck = function(self, card, from_debuff)
card.ability.extra.active = false
G.SETTINGS.GAMESPEED = 4
end,
add_to_deck = function(self, card, from_debuff)
card.ability.extra.active = true
end
i have this function and for the most part it works wonders, but when you lose the game it keeps the game speed up how do i remove that?
any way to add additional config types if that makes sense
like hands, discards, dollars, joker_slot, voucher, and consumables
do you need to do that
well i would make it more compactable for the decks that i plan to add where they add tags
don't repeat yourself yknow
ah i see
probably hook/patch Back:apply_to_run
and remember to respect the fact that decks with an apply should override the default functionality
and if possible my mod could be used as some sort of api kind of deal
looks like this i think
is it possible to slow down the splash vortex?
like the one in the title screen
where all the cards converge
i mean if you can find out where in the files it is
i mean if you can change the cards, background then i presume you can change the speed
thats what i meant
line 1397 in game.lua
@minor magnet
ah
theres here too @minor magnet
yea i think this works
maybe maybe not
wait this just changes the title doesnt it
you'd be changing alot of things 🤷♂️
i dont think you can
it worked
how does lucky_trigger work, like can I hook it ?
it's a flag set when the lucky card triggers
it's cleared out later
yeah but can I make my enhancement trigger the lucky cat when it give you something
yeah just set the flag in the card when it triggers and clear it out after the hand is played
ok
like that ig
Has someone ported the balatro mod manager to linux? 🤔
yeah
it says it's something about the music config
well aparently turning off hotpot fixed it???? idk but im not getting the error anymore\
like- i have no idea what i fucked up
oh wait nevermind its still yhere
i mean
doesn't it not work with wine?
ok so i did the simple way and disabled m config menu, no change at all
Haven’t tried wine, only tried a bunch of proton versions
same thing different names :P
yes and no. it's a fork of wine developed by valve themselves to extend linux support for steam games and the deck
ah yeah fair tbf I dont really know compute stuff all too well
I just like to watch you guys talk about mods
and the art is always really pretty 😍
to put it simply wine is the base windows APIs compatibility layer, proton is a fork from valve for steam, and there's proton-ge which is a community fork of proton that is recommended for some games
but ge is experimental if that makes sense
nah jk jk im lying I know technical stuff
I should know better than to shitpost in modding-dev
you should know worse because its entertaining :clueless:
distinguishing between the two for someone not technically inclined is usually not worth the time, it's better to tell them that if they've tried Proton then they've tried Wine
this channel is a sanctum, respect it
smh my head why must you bring wisdom
i mean fair
but it has worked for some games
and since its not really a steam game it is worth a try
aight guys heres my code and the error i keep getting when tryna set up a new game
im tryna make a deck where base blinds are cut in half but theres no discards at all
do yo magic LOL
btw the ante cutting works perfectly fine its just the discards thats giving me trouble
Start the run with no discards?
If that's the case, set discards in the config to -3.
no like the entire run with no discards
so picking up the wasteful and the one after wont give you the discard
you can do a deck calc function
probably when you select a blind set discards to zero
but also design wise having NO discards sounds like a terrible deck
G.GAME.round_resets.discards, G.GAME.current_round.discards_left should be forced to 0... and probably should hook ease_discards to prevent additions of discards if on the deck.
the blinds are cut in half entirely to compensate
fair enough
so sum like this?
-- This is outside definition of any objects, such as SMODS.Back and what not.
local easediscardref = ease_discard
function ease_discard(mod, instant, silent)
if G.GAME.selected_back.effect.center.key == 'b_modprefix_key' then mod = 0 end
easediscardref(mod, instant, silent)
end
https://forums.kleientertainment.com/forums/topic/129557-tutorial-function-hooking-and-you/
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
ty
UHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
OH wait bc the thing that sets the blinds to half is in the calculate function
yeah no it just doesnt seem to set the discards to 0
unless i messed smth up
i desperatley need help
The hooks are supposed to be outside, like so.
Definition of the object may not be set right.
problem is, I dont knwo where the problem is
i might be able to fix it if its that simple
but locating is gonna be a fucking nightmare
you mean outside of the calc function?
Outside of the SMODS.Back entirely.
ah okay
From what I can see, it's about the localization text... somewhy, a string is passed, where a card should've been?
by string, would you mean like- a custom tooltip/comment?
...is the local easediscardref = ease_discard set right above?
yup
Doesn't have to be exactly a comment, but could be. Check your localization entries.
...or which of the Jokers, decks or w/e is not returning the right thing for loc_vars...
...show the hook fully?
what's jabong_set_music
...why is , there?
cuz i have copryighted stuff
ok can i see the code for that part
i may be dumb bc deleting that fixed it LOL
you want the full config tab code or nah
whatever is fine
return {
{
label = localize("jabong_set_music"),
tab_definition_function = function()
jabong_nodes = {
{
n = G.UIT.R,
config = { align = "cm" },
nodes = {
--{n=G.UIT.O, config={object = DynaText({string = "", colours = {G.C.WHITE}, shadow = true, scale = 0.4})}},
},
},
}
settings = { n = G.UIT.C, config = { align = "tl", padding = 0.05 }, nodes = {} }
settings.nodes[#settings.nodes + 1] = create_toggle({
active_colour = G.C.RED,
label = localize("jabong_mus_getarnd"),
ref_table = jamod_config.jamod,
ref_value = "jimbum_music",
})
config = { n = G.UIT.R, config = { align = "tm", padding = 0 }, nodes = { settings } }
jabong_nodes[#jabong_nodes + 1] = config
return {
n = G.UIT.ROOT,
config = {
emboss = 0.05,
minh = 6,
r = 0.1,
minw = 10,
align = "cm",
padding = 0.2,
colour = G.C.BLACK,
},
nodes = jabong_nodes,
}
end,
},
}
end```
ok imma hop off, ill ask about this tomorrow
breh
try disabling talisman
when hooking Controller.L_cursor_release, how can i check if the thing being deselected is my Joker?
what are you trying to do
the deselected object apears to be very different from my card
even though they should be identical
im making a deck where all blinds are cut in half with the caveat of no discards throughout the entire run
the hook is going to prevent discards being added but it wont start it at 0
if context.setting_blind then ease_discard(-G.GAME.current_round.discards_left) end
-# ...although that would just get nullified by the hook, oops - could change the condition to check if mod is 0 or larger.
is there any way to check if a card in hand has any enhancement?
next(SMODS.get_enhancements(card)) is true if and only if the card has an enhancement
(SMODS.get_enhancements always returns a table, even if it's empty)
<@&1133519078540185692> kill 2
how would i tell if a card is being discarded or not during the discard function
context rather
ok may or may not be dumb but how does one alter the center at which the text rotates for an SMODS.DynaTextEffect?
there's a way to check if a card is highlighted (i don't remember off the top of my head but it's just a true/false value in the card object iirc), and discarded cards are highlighted for the duration of the discard
is there a way to make vouchers appear in other parts of shops that arent the voucher slot?
replying to you because you helped me with this earlier, and i can't crack why this still isn't working
here's the new added calc code (i can't send it all because of character limit, so just use the replied code as ref), and to my understanding everything works perfectly up until the very last for loop. which for some reason doesn't seem to even be firing as the sendDebugMessage("Difference:" .. difference, "CHAK") within it just does not send anything to the console
local difference = 0
sendDebugMessage("Difference:" .. difference, "CHAK")
sendDebugMessage("OG Suits:", "CHAK")
print(og_suits)
sendDebugMessage("New Suits:", "CHAK")
print(new_suits)
for suit_key, og_value in ipairs(og_suits) do -- Compare dictionaries
local new_value = new_suits[suit_key] or 0
difference = math.abs(og_value - new_value) + difference
sendDebugMessage("Difference:" .. difference, "CHAK")
if card.ability.extra.cards_discarded > difference then
for i = 1, card.ability.extra.cards_discarded - difference do
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chips_gain
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
end
return {
colour = G.C.PURPLE,
message = "Upgraded!"
}
end
end
``
got this error now, still will crash if no joker is at the left (and apparently will still not check for the joker at the right either
if context.end_of_round and not context.blueprint and context.game_over == false and context.main_eval then
if my_pos then
local sell_minus = G.jokers.cards[my_pos - 1] or nil
local sell_plus = G.jokers.cards[my_pos + 1] or nil
card.ability.extra.dollar = card.ability.extra.dollar + (sell_minus or {}).sell_cost or 0 + (sell_plus or {}).sell_cost or 0
end
end
end
rewrite the line to be
card.ability.extra.dollar = card.ability.extra.dollar + ((sell_minus or {}).sell_cost or 0) + ((sell_plus or {}).sell_cost or 0)
i'm pretty sure addition has higher priority than the logical boolean operators, so it's not behaving as intended
(i.e. the expression x or y + z or w is equivalent to x or (y + z) or w)
I'm going to give it a shot
the issue i noticed is that it won't ever even care about the right joker, while the left is mendatory to it somehow, maybe cuz sell minus is first
thanks it works now, give properly different money based of left and right jokers of itself
what would a counterfeit sticker look like
that is, a sticker that indicates a counterfeit item
red x

Redd's face from animal crossing
ooh, that's a good one
i actually had an idea to have a "counterfeit/fraud" edition or sticker and have redd and andrew wakefield as jokers related to it 😇🥀
hell yea
something like hack with an image like this
with his stupid oversized coat
it's a fraud and a wan-
automod is big brother i cant finish the sentence
literally 1984
using a cocktail of tylenol and shots 😋 my austim grows stronger
also @frosty rampart did you hear about the major update of new horizons
i did, yea
i don't actually play new horizons but it looks really cool
not testing my deck which gives you a charm tag and getting a soul 😬
i just imagine if my mod goes anywhere purple deck will be the resetting for a beach seed of modded balatro
resetting for a soul card
hi nh
yeah, same problem I pointed out before: og_suits is not an integer indexed table so you need to use pairs
im working on a joker that gives +10 mult for the aces of hearts
this is the line, mostly just copied from the idol:
config = { extra = { s_mult = 10, rank = 'Ace', suit = 'Hearts' }, },
right now its ignoring the rank = ace and giving all hearts +10 mult
how would I fix this to be specifically ace of hearts?
s_mult is only for suits
personally for jokers I don't recommend using the config values, use the calculate function instead
ohhhh ok that makes a lotta sense
is the SMODS support for pseudo-suits/ranks in hand calc and joker calc
pushed yet
what's that
wrong chat woops
wdym pseudo-suits
like wild cards?
Hey guys just joined the discord. I've been wanting to make a balatro mod and was just introduced the the JokerForge website which is really nice for simple stuff getting started, but I was wondering if there is a way to add new consumable types on there? it doesn't seem like so.
how hard would it be to make a new consumable type?
hey gang, how do i make the newly polychrome cards trigger polychrome effects on scoring? :3c
just answered my own question apparently im bad at finding buttons
quick update
config = { extra = { mult = 10 } }, calculate = function(self, card, context) if context.individual and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.suit) and context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then return { mult = card.ability.extra.mult } end end }
i tried this, which is basically just lusty joker and scholar mixed together, unfortuantely that doesnt seem to work either though
You do it outside of an event.
you nailed it, i've got it in an event. i'll give that a try, i hope it still looks right xD
yah as i figured it gets assigned polychrome the moment it's played and throws off the effect "Mwah!" and juice-up effect
it does trigger edition effects on scoring though
for reference
i wonder if there's a way to achieve the desired scoring and visual effects
Code?
if context.before and not context.blueprint then
local convert = 0
for _, k in ipairs(context.scoring_hand) do
if not k:is_suit('Hearts') then
convert = convert + 1 -- thunk please reprogram balatro in C++ so i can use compound operators
G.E_MANAGER:add_event(Event({
func = function()
SMODS.change_base(k, "Hearts")
k:juice_up()
return true
end
}))
end
end
if convert > 0 then
card_eval_status_text(card, 'extra', nil, nil, nil,
{message = 'Love!', colour = G.C.RED})
end
-- Polychrome 8 routine
local kiss = 0
for _, k in ipairs(context.scoring_hand) do
if not k.edition and not k.debuff then
if (k:get_id() == 8) and
SMODS.pseudorandom_probability(card, "merlimbis_poly",
1,
card.ability.extra.odds) then
kiss = kiss + 1
G.E_MANAGER:add_event(Event({
func = function()
k:juice_up()
-- k:set_edition("e_polychrome", true)
return true
end
}))
k:set_edition("e_polychrome", true) -- test this location
end
end
end
if kiss > 0 then
return {message = "Mwah!", colour = G.C.PURPLE}
end
end
Remove the , true
being able to set a card to return as a different rank via a modifier
that does improve things a bit
as in having a joker that makes all Aces count as Kings
for example
and similar with suits
yeah that's calling hooking card:get_id()
and card:is_suit
i understand that. im asking if SMODS added functionality for it.
i dont want to use hooks or patching if i dont have to, which i think is reasonable?
no it isnt
???
a lot of smods functions are designed to be hooked
smods patches in patch targets so you can patch easier
that doesnt mean that hooks and patches arent inherently more unstable than easier and simpler solutions
?
hooks arent unstable
... yes they are
patches are maybe slightly unstable if you have a lot of mods but that's just called Having A Lot Of Mods
and would probably happen regardless based on the non-patch way a mod did something
hooks are unstable if you use them badly
hooks insert code to run locally why would they not be unstable
however my mod is very hook heavy
wtf are you yapping about
and i have rarely had
im not saying 'hooks are bad'
any incompatibilities from hooks alone
i dont think you know what a hook is
im saying 'id rather not use them if there is pre-existing implementation'
i have a 700 line file just for hooks its ok
given ive been coding in C# for almost 5 years im pretty fucking sure i know what a hook is
you codswallop
new insult just dropped
hooks make stacktraces look awful
this is true actually
thats the main reason they kinda suck
googled if hooks were different in c# at all and i got this result
codswallop is an old insult, actually
i would rather have that than patch into a function though because then you cant blame a specific mod
they are unstable because inserting code to run in methods is more risky than running it strictly inside of the card itself if poorly implemented
SMODS needs a built in way of declaring hooks that runs them consecutively and doesnt grow the stack each time
is C# dying 🤔 or losing popularity 👀
old insult just got revived
either through some sort of preprocessed attribute or just a plain function
itll happen at some point surely
that would actually be neat
idk why this is even an argument
im not saying youre wrong but i think you are blowing it a bit out of proportion
its probably a little riskier but its just not really a considerable factor 99% of the time
i'm thinking i'll shift the polychrome 8 routine to after the hand is scored
this guy literally said 'you are being unreasonable for not wanting to use hooks if there are pre-existing options'
don't fuck up your hooks and you should be smiley face
i dont think im bing unreasonable
you are putting words into my mouth
pre-existing built in options is different from anything but hooks
Lmao
also true
i dont want to use hooks or patches
looks inside
patches
... not what i said
i mean this completely uninsultingly but you have to be the only person who ive seen to ever prefer patches over hooks
anyways i think i am being ragebaited and frankly i have things to do so im going to go
i said 'i would prefer to not have to use hooks or patches if there's pre-existing implementation'
bye chat
how is this ragebait
i predict patches will be a lot more popular when better tooling for them drops
lmao
?? but they're just better
I added a new card area, but what's inside of it doesnt save between game openings, any help?
more capable yeah but theyre also more prone to failure because targets can be fucked with by other mods
which is kinda the only reason you would want to avoid them
also its just more complicated to do believe it or not
local olda = a
function a(...)
return olda(...)
end
``` is more memorable for a lot of people
needed to defend myself from this example of silliness
I don't stand for illogical trickery
patches are faster/more sanitary/more capable
hooks are significantly easier to write and (sometimes) debug
some of us have different priorities than others and that's okay, i think the majority of the disagreement here is not over what the strengths/weaknesses of the two but how much we value those and that is completely subjective and should not be in argument
and wacky nonsense
k
i have literally never said any of the things people have started arguing or defending
youre responding like im speaking directly to you which i am not
i dont get why NOBODY has said they like patches over hooks because i think they're better
cg when will lovely sdk drop