#💻・modding-dev
1 messages · Page 78 of 1
actually maybe it's a different thing
Okay, I know the discard checking works - it only crashes when i dicard a 3oak or better
but WHAT IS GOING ON WITH LINE 411
it's probably something wrong with localize(text, 'poker_hands')...
Bad hand checking logic btw.
Maybe this will be better
function get_poker_hands_better_than(target_hand, inclusive)
local result = {}
for _, poker_hand in ipairs(G.handlist) do
if (inclusive or poker_hand ~= target_hand) then table.insert(result, poker_hand) end
if poker_hand == target_hand then return result end
end
end
Straight, Flush and Three of a Kind are not all hands better than Three of a Kind
Also you miss Full House
This should be the right channel
does anyone have insight into how to add a joker created with SMODS.Joker to a deck when the run starts? I'm able to load vanilla ones using e.g. 'j_blueprint' and passing that to create_card, but not with SMODS jokers.
i mean i just spawn it in with debugplus
you need to add mod prefix
so j_modprefix_jokerkey
mod prefix is like first 4 letters of your mod name? lowercase
unless you specified mod prefix separately
okay so uh i just put "two pair" in the target hand? or
"Two Pair"
Hmm interesting. I'll have to go digging. Thank you 😄 debugplus also sounds useful
uh
Le'ts modify code a little bit:
function get_poker_hands_better_than(target_hand, inclusive)
local result = {}
for _, poker_hand in ipairs(G.handlist) do
if (inclusive or poker_hand ~= target_hand) then result[poker_hand] = true end
if poker_hand == target_hand then return result end
end
return result
end
calculate = function(self, card, context)
if context.pre_discard and not context.hook then
local poker_hands_to_upgrade = get_poker_hands_better_than("Three of a Kind", true)
local poker_hand = G.FUNCS.get_poker_hand_info(G.hand.highlighted)
if poker_hands_to_upgrade[poker_hand] then
card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
update_hand_text({sound = 'button', volume = 0.7, pitch = 0.8, delay = 0.3}, {handname=localize(poker_hand, 'poker_hands'),chips = G.GAME.hands[poker_hand].chips, mult = G.GAME.hands[poker_hand].mult, level=G.GAME.hands[poker_hand].level})
level_up_hand(context.blueprint_card or self, poker_hand, nil, 1)
update_hand_text({sound = 'button', volume = 0.7, pitch = 1.1, delay = 0}, {mult = 0, chips = 0, handname = '', level = ''})
end
end
end
oh i see
w00t got it working. Thanks again
okay so i can't just put this in, what am i missin
Your result code shoul looks like this:
function get_poker_hands_better_than(target_hand, inclusive)
local result = {}
for _, poker_hand in ipairs(G.handlist) do
if (inclusive or poker_hand ~= target_hand) then result[poker_hand] = true end
if poker_hand == target_hand then return result end
end
return result
end
local trashtrash = SMODS.Joker({
key = "trashtrash",
loc_txt = {
name = "Trash And Trash!",
text = {
"If discarded poker hand is",
"{C:attention}Three of a Kind or better,",
"{C:attenti}level up{} said poker hand",
},
},
rarity = 3,
cost = 8,
atlas = "OSJokers",
eternal_compat = true,
perishable_compat = true,
blueprint_compat = true,
pos = { x = 3, y = 2 },
calculate = function(self, card, context)
if context.pre_discard and not context.hook then
local poker_hands_to_upgrade = get_poker_hands_better_than("Three of a Kind", true)
local poker_hand = G.FUNCS.get_poker_hand_info(G.hand.highlighted)
if poker_hands_to_upgrade[poker_hand] then
card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
update_hand_text({sound = 'button', volume = 0.7, pitch = 0.8, delay = 0.3}, {handname=localize(poker_hand, 'poker_hands'),chips = G.GAME.hands[poker_hand].chips, mult = G.GAME.hands[poker_hand].mult, level=G.GAME.hands[poker_hand].level})
level_up_hand(context.blueprint_card or self, poker_hand, nil, 1)
update_hand_text({sound = 'button', volume = 0.7, pitch = 1.1, delay = 0}, {mult = 0, chips = 0, handname = '', level = ''})
end
end
end
})
didnt like your joker, tried to escape /s
Good luck 
card_eval_status_text needs card rather than self
OH
YEAH I WAS GONNA CHANGE THAT thankies
OKAY NOW IT WORKS WOO
https://youtu.be/dlmDDcRDByc
god i'm gonna get a rude awakening when i try to make the art...
和田たけあき(くらげP)と申します。
はい、さようなら。
■作詞・作曲・編曲 : 和田たけあき(くらげP) https://www.youtube.com/channel/UC7BYDRV-l741zjSUcyLT_cQ
■絵 : チェリ子 http://www.nicovideo.jp/mylist/36367946
公式サイト
http://www.wadatakeaki.net/
Twitter
https://twitter.com/WADATAKEAKI
インストはこちら
https://www.dropbox.com/sh/d01rjhfzcyxu4m8/AAAkeUsTspgkh7Fl0F_fYqNqa?dl=0
(±2,±5、キー変更用ドラムのみ/ドラム抜...
yeah it's infinite burnt joker but antilobotomy
aka "get smeared/shortcut you fuck"
I'm up to 10 jokers implemented now... maybe I should make the art.
Maybe I'll try to implement this.
±0 (common)
If 0 cards left in hand, gain +1 hand size
...this is uncommon isn't it
hmmmmmm
i think you could get away with it being common, but its definitely a very good common
(there should be a mod that adds inbetween ranks, definitely /s)
local plusminus = SMODS.Joker {
key = 'plusminus',
loc_txt = {
name = '±0',
text = {
"If {C:attention}0{} cards held",
"in hand,",
"{C:attention}+1{} hand size",
"{C:inactive}(Currently +#1#)"
}
},
config = { extra = {hand_size = 0} },
cost = 5,
rarity = 1,
atlas = 'OSJokers',
eternal_compat = true,
perishable_compat = true,
blueprint_compat = false,
pos = { x = 4, y = 2 },
loc_vars = function(self, info_queue, card)
return { vars = {card.ability.extra.hand_size} }
end,
add_to_deck = function(self, card, from_debuff)
G.hand:change_size(card.ability.extra.hand_size)
end,
remove_from_deck = function(self, card, from_debuff)
G.hand:change_size(-card.ability.extra.hand_size)
end,
calculate = function(self, card, context)
if #G.hand.cards == 0 and not context.blueprint and not context.individual then
card.ability.extra.hand_size = card.ability.extra.hand_size + 1
return {
message = "UPGRADE!",
}
end
end
}
okay literally nothing went right here XD, can you tell me what i should do
you need to chance the hand size in your calculate function
but also add a better context check
otherwise this will trigger lots
oh yeah of course hm
should i add a context.before
...chance?
change*
by 1
so after card.ability.extra.hand_size = card.ability.extra.hand_size + 1 put G.hand:change_size(1)
and do away with the add to deck right
eh it's fine
but
IT'S WORKING NOW! YATTA
yeah you don't need the add to deck
you need the remove from deck though
keeping add to deck would allow debuffing it to work properly mind
oh
yeah it's fine, it's working now WOOO
11 jokers are now implemented....
GEE MAYBE I SHOULD DO THE ART SO I CAN RELEASE THIS
(I'm so cooked...)
Okay so I have a OS Joker idea:
High Range Test (unc.)
Gains x.25 Mult if score is more than 2500, doubles on every upgrade
What would the Low Range Test be?
idk but if u haven't done matryoshka yet it would be funny if it had something to do with creating smaller copies of itself like an actual matryoshka doll
you should do the vampire that's just the same as vampire

Anyways gn, I'll listen to Vocaloid before sleeping to find Joker ideas
view my descent in #1294698682062475294
you could make it so it just uses vampire's ability name and loc entry straight up
so there's like 0 original code
concepting
i'm trying to make a deck in which you get no rewards from blinds (a la red chip but all of them.) do y'all know where i'm going wrong here?
if you're gonna paste code like this, just paste it as text man
i... sorry...
it's fine, it's just... I can't copy-paste it to my machine to check it
and I definitely don't want to re-type the whole thing
if you use
```lua
[insert code here]
```
you get a nice discord codeblock, with formatting and colours
try it!
SMODS.Back{
name = "Discounted Deck",
key = "discndeck",
atlas = 'whitedeckatl',
pos = {x = 0, y = 0},
loc_txt = {
name ="Discounted Deck",
text={
"Start game with {C:money,T:v_liquidation}Liquidation{}",
"Blinds give {C:attention}no rewards{}",
},
},
config = {vouchers = {'v_clearance_sale','v_liquidation'}},
unlocked = true,
discovered = true,
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.modifiers.no_blind_reward = self.GAME.modifiers.no_blind_reward or {}
G.GAME.modifiers.no_blind_reward.Small = true
G.GAME.modifiers.no_blind_reward.Large = true
G.GAME.modifiers.no_blind_reward.Boss = true
G.GAME.selected_back:apply_to_run()
end
}))
end
}
so, what's going wrong with it? it doesn't apply?
it was crashing but i noticed an error where i accidentally wrote self. instead of g. so we're trying again. i may be dumb
OKAY fixed it, i did some weird phrasing, my bad. thanks for the help anyhow and thanks for teaching me the code block thingamajig ❤️
corrected code:
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.modifiers.no_blind_reward = G.GAME.modifiers.no_blind_reward or {}
G.GAME.modifiers.no_blind_reward.Small = true
G.GAME.modifiers.no_blind_reward.Big = true
G.GAME.modifiers.no_blind_reward.Boss = true
return true
end
}))
end
}
ah, yeah, that'll break it
also nice fix on the event, that was gonna be an infinite loop
though I'm not sure you even need an event here
maybe not, but i'm more putting guardrails to make sure i don't accidentally put something that needs an event where there isn't one. better safe than sorry
events are usually done when you need to time things
the reason the example decks all use events is because they directly modify the deck
and the deck isn't created yet when the Back:apply function is called
which is more of an issue with balatro itself... 

noted, thanks!
quick question: to let blueprint say it is compattable it was: "blueprint_compat = true," right?
i could've swore it was in example jokers somewhere
i'll just try this out
it seems to be working
Welp, I made some of my card art into a mod because I'm struggling to make my game
I'm gonna make a post for it
quick question, what mods have jokers that have Xmoney effects? need to do something similar, and looking at their code seems the best thing to do 😭
like multiplying money full stop or money gain?
multiplying money
i know there's a mod somewhere that has a NEO spamton joker that multiplies the player's money by two
i did see that, i just could not remeber the name 😭
No Laughing Matter?
yas sirrrr
Question. Why G.GAME.blind.name for vanilla blinds is name The Psychic, but for modded it's key bl_twbl_nope?

question: do pattern patches only patch at one instance or every instance?
because the name field serves no practical purpose with the way steamodded is based on keys, yet the base game expects one to exist
so it's not required that mods specify a name field, but it defaults to the key
Understood
after testing i have concluded pattern patches are applied at every instance
is there something wrong this code? for some reason flushes arent working, but any other hands (3oak, pair, two pair, etc) is
they all have the same code, just a different == 'hand name'
that's not how context.poker_hands works
It's a table not a string
i mean it works, just not for flushes 
can you show one that works?
sure
i'll be damned, i realised what was going on
they were working before, no clue what happened 😭
and back here again 😭
try next(context.poker_hands["Three of a Kind"]
is that missing a ) at the end or
yes it is
Okay I have joined, just to ask what is poker_hands a map to?
I have been trying to help Black, but what he is getting told to do makes very little sense to me.
I would like to say I'm experienced enough with Lua, I'm just most used to Factorio's api.
The only documentation I have seen is a link to #1247703015222149120, which is just attrocious and uninformative.
poker_hands contains all the possible poker hands from the cards you play
I kind of already understood that is the purpose, but how?
I understand it's a mapping of the name of the hand to a table of some sort. But what is that table
My first assumption was it was something like table<hand_names,true>, (hand_names being a union of strings) but the fact that you're supposed to use next() means that's clearly wrong
iirc it's something like table[<hand_name>] = <array of cards>
"Array of cards" being the cards from the hand that would form that specific hand.
Okay that's kind of what I thought
But if the hand is not valid, is it an empty array or something?
The idea that there would be an entry at all for an invalid hand sounds completely inane to me, but that's the only reason I can think of for using next()
did you try printing it?
Oh I don't even have the game. I'm a third party trying to understand enough to help my friend when they have issues
this is what I got when playing a two pair
{
Flush House = table: 0x077a37d8 {
},
Full House = table: 0x077a3800 {
},
top = table: 0x07853940 {
},
Flush = table: 0x07264390 {
},
Pair = table: 0x07211880 {
[1] = table: 0x07211858 {
[1] = table: 0x07366760,
[2] = table: 0x0726a0f8,
},
[2] = table: 0x07293028 {
[1] = table: 0x0760f690,
[2] = table: 0x0742c860,
},
},
Four of a Kind = table: 0x0715ac30 {
},
Straight Flush = table: 0x07853918 {
},
Straight = table: 0x078a5988 {
},
Three of a Kind = table: 0x077ccec8 {
},
Flush Five = table: 0x07853940 {
},
Two Pair = table: 0x078a89b0 {
[1] = table: 0x075b8eb8 {
[1] = table: 0x07366760,
[2] = table: 0x0726a0f8,
[3] = table: 0x0760f690,
[4] = table: 0x0742c860,
},
},
Five of a Kind = table: 0x0728d988 {
},
High Card = table: 0x075f6430 {
[1] = table: 0x076186f0 {
[1] = table: 0x07366760,
},
},
}
The functions that check for valid hands to return an empty table.
I believe the innermost tables are the actual cards
Okay. I fundamentally disagree with that structure, but it helps to understand that that's how it works.
One final question, is there luals type annotations that I should've forced Black to show me?
you can go complain to 
about that part
if you're talking about @param and @return comment annotation stuff, there is some (more so in Thunk's code than Steamodded's code), but you might as well assume it doesn't exist
Alright. Coming from Factorio where we've got our api very thoroughly annotated
as well as my own personal choice of enabling the no-unknown warnings, that is plainly unacceptable to me.
I'll continue to help Black from afar, but I don't think I could ever touch it myself
Thanks for answering my questions and correcting my mis-inferences about the api
o/
I don't doubt Factorio has more structured documentation, kinda fits with the game haha
it's also a much more developed modding scene
about a difference of 7 years?
alright chat
how do i change the rank of a card
i can't make sense of how strength does it
Here's how smods redoes strength
i can't read it
They might do other stuff in other files for it
seems to be
assert(SMODS.change_base(_card, nil, new_rank))
where _card is the selected cards and new_rank is the new rank
Oh yeah it is change base you're right iirc
in theory assert(SMODS.change_base(context.other_card, nil, "6") should change the rank to 6
The actual smods.ranks is kinda an internal thing, just a table of ranks it looks like
that was surprisingly easy
this did just work
thanks chat
i'm making a custom challenge and i want to know if this is right?
wait nothing in the base game bans seals or enchantments
also new problem this breaks my mod and i don't know why
🐟
i think i know why
yay! i fixed it
how do i make code that refers to a mod
i want a part of my code to only work with a certain mod mod
if {mod} then code stuffs end
Yooo, hey I've been trying to install the grim mod, but it seems like theres a bug in lovely where it autogenerates the card.lua file, it throws error here, and I assume its because its missing a comma... so is this the right channel to ask? 😓
I'd ask in the #1279275441009459222 thread
Not bug with lovely. Autogenerated file is logs showing lovely injection.
test sprites
the nefarious question mark card
Perfect thank you sorry still new to the community
np, you're good :3
Okay makes sense, I’ll have a look on the threads and see what’s up ty
i worked on sin for like 10 minutes
the background looks so boring 😭
I think they look god *good (though fitting typo)
and as for the plain bg, maybe add some stippling?
I don't think it really needs it though
plus remember these will have spectral shader in the game
im completely guessing here on how to do this (cant even access the source code rn 😭 ), but is this on the right track for having a joker have a chance to times its sell value?
No problem.
🔫
fastest shot in the west
deleted for me
whuh...
would help looking at the spectral cards for references
they mostly have cool effects in the bg relating to the card
Is there a guide/definition/reference available for the context and card parameters used in the calculate function? I'm finding it hard knowing what's available to do with each of them 
discord is bad a being navigated, dw
hm
balatro if it was good
wuddaflip are camel cards....
+1 Hand each hand
and here I am just using nopeus at 8x
all i did today was make 1 (one) joker art lmao
atleast you did 1 (one) joker art

how would one duplicate a selected card in hand? i have this so far but it's not working
SMODS.Back{
name = "Reflective Deck",
key = "rflctdeck",
atlas = 'whitedeckatl',
pos = {x = 0, y = 0},
loc_txt = {
name ="Reflective Deck",
text={
"On hand played,",
"One card in hand is {C:attention}Duplicated{}",
"One card in deck is {C:attention}Destroyed{}"
},
},
config = {discards = -1},
unlocked = true,
discovered = true,
apply = function(self)
evaluate = function (parts, hand)
local cardToDuplicate = parts[math.random(1,#parts)]
local _card = copy_card(cardToDuplicate, nil, nil, G.playing_card)
_card:add_to_deck()
end
}
here's how it looks like in game
that looks awesome!!!
?
Where do I find the code for challenge rules?
you need to create a card first by using create_playing_card, then use that as the first parameter in copy_card
Is there a starting_param value for playable hand size?
so this?
apply = function(self)
local cardToDuplicate = context.full_hand[math.random(1,#context.full_hand)]
local _card = copy_card(cardToDuplicate, nil, nil, G.playing_card)
_card:add_to_deck()
G.hand:emplace(_card)
end
challenges.lua should help
no limit, it should dupe a random card in hand whenever a hand is played
prolly
Nah sorry i'm tryign to create a new hand type but need the playable hand to be larger than 5. just trying to find where i can access this but so far it seems like it's a global value
I want to see the code that makes up the rules themselves
cryptid has something similar, if that helps?
oh, well you'll probably need to go digging in the files then
I thought it would be in card.lua but no 😭
In Game.lua line 2058 begins the modifications of rules absed on challenges. These are set ones though, if you're looking to add or create one i'm not sure that's where
this doesn't throw an error but it also doesn't... work (trying to duplicate one random card in hand when a hand is played and this deck is used)
SMODS.Back{
name = "Reflective Deck",
key = "rflctdeck",
atlas = 'whitedeckatl',
pos = {x = 0, y = 0},
loc_txt = {
name ="Reflective Deck",
text={
"On hand played,",
"One card in hand is {C:attention}Duplicated{}",
"One card in deck is {C:attention}Destroyed{}"
},
},
config = {discards = -1},
unlocked = true,
discovered = true,
apply = function(self)
evaluate = function (parts, hand)
local cardToDuplicate = parts[math.random(1,#parts)]
local _card = copy_card(cardToDuplicate, nil, nil, G.playing_card)
_card:add_to_deck()
_card:emplace()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, _card)
_card.states.visible = nil
G.E_MANAGER:add_event(Event({
func = function()
_card:start_materialize()
return {
message = localize('k_copied_ex'),
colour = G.C.CHIPS,
card = self,
playing_cards_created = {true}
}
end
}))
end
end
}
conflict between mods?
according to my search the file is related to the "Awesome Balatro" mod
that is not correct at all
jimb is jimbos pack
suddenly jimbo's pack's joker atlas doesnt load
sounds like you know the problem then
i know whats causing the problem
i dont know what the problem is
okay wtf
my balatro is not well
Spade cards aint
with what you've done to it, how could it be?
also, what is the spades deck from?
cryptid
somehow i made a duplicate folder with only the lua file
lmfao
ofc it is, lol
whenever I ask what something interesting is from, it's always cryptid
maybe one day they're make the 'balanced' version and i'll want to install it
though there's other mods with suit decks too to be fair
they literally have...
also
you can just disable things that are too overpowered in the config
and use the things that are fun
like the decks
since when?
I know the config exists, but the legendaries are also OP and can't be disabled sperately yet
says math himself
Balanced Cryptid? Before GTA6? ain't no wayyyyyyy. Contribute to jevonnisverycoolman/Cryptid development by creating an account on GitHub.
for a while now
lets be real
@lusty epoch why no advertise?
its a legendary
and im pretty sure they're disableable actually
nowhere near complete yet
Unfinished
well so is every mod, unless it's unfinished as in unplayable
it's called balanced cryptid
its not balanced
thus it's not finished
It unfinished as in i just started like a week ago and half the things are still op
lol fair. I just like... expect WIP threads I guess. They're fun for me
no worries regardless
I mean it’s usuable rn if you want to give it a try
thank you :3
yw :3
Just finished my first Jimbo, a ripoff of Midas Mask but for turning 7s lucky. Would love any feedback on it, improvements and especially on if I'm using the lifecycle/context correctly.
SMODS.Jokers.j_dogmod_lucky7.calculate = function(self, context)
if context.before then
local scoredCards = {} -- store the cards that should be upgraded
for _, scoringCard in ipairs(context.scoring_hand) do
if scoringCard:get_id() == 7 then -- if the card is a seven, save it for later
table.insert(scoredCards, scoringCard)
end
end
if tableLength(scoredCards) > 0 then -- do we have any scoring cards?
G.E_MANAGER:add_event(Event({ -- delay the upgrade a bit?
delay = 0.2, -- what's the unit?
func = function()
for _, toBecomeLucky in ipairs(scoredCards) do
toBecomeLucky:juice_up(0.5, 0.5) -- jiggle. What's the unit?
toBecomeLucky:set_ability(G.P_CENTERS.m_lucky) -- make it lucky
end
return true
end
}))
card_eval_status_text(self, "extra", nil, nil, nil, { -- pops after the hand is removed if in the above event
message = localize("k_dogmod_lucky") -- "Lucky!"
})
end -- end length check
end -- end if context
end -- end calculate
Also anything Lua related as I've never used it before 😐
You’re using 0.9.8?
Balatro Version: 1.0.1g-FULL
Modded Version: 1.0.0~ALPHA-1012b-STEAMODDED
Love2D Version: 11.5.0
Lovely Version: 0.5.0-beta7
But I did use a different mod as a way to get something going. Maybe that is/was using some older stuff? What is it that smells of 0.9.8?
Creating an appending to the table might be redundant. I thought I also had to delay the Joker message popping up in the same event, but apparently that triggers at a different time
Throwing the calculate in like that isn’t how 1.0 is usually coded
Do you know of any good examples to see the 1.0 conventions?
Morefluff seems well made and striaghtforward
it splits its files up though which isn't really a convention, just the author's preference
Lots of big 1.0 mods do that now
From a developing side, it makes it so much easier to navigate through 🤣
very fair, lol
I wish I’d broken galdur into smaller files, it’s such a pain to find anything in there
And that’s not even that big really
Depends, if every file is nicely named its not too hard
Time to make a mod that has the misc, utils and functions files 
pfffft
Thanks for the help. I'll try to make the Jimbos I want then do a whole refactor when I'm more comfortable working with this stuff
how do i , add juice to my joker?
like where do i put it
and does it needs something like self.juice_up or card.juice_up?
When the ability triggers put
card:juice_up()
As one of the events, for example
If context.first_hand then
card.ability.extra = card.ability.extra + 1
card:juice_up()
end
You don't need juice if you are returning a message though
Sorry I missed input, it's
juice_up
Not
juice
that''ll juice twice
?
in the return
Does anyone know how to get the ability of a card? The getter equivalent of set_ability..?
Like, foreach key, card in context.scoring_hand, if card.get_ability === "Glass"
As always as soon as you ask you figure it out
Rubber ducking
Ok another one! Is this an OK way to temporarily nudge the probability of things triggering, like having an "Oops all sixes" for the one played hand?
local oddsBefore = G.GAME.probabilities.normal
local newOdds = G.GAME.probabilities.normal * self.ability.extra.increaseOddsTimes -- 2
G.GAME.probabilities.normal = newOdds
G.GAME.probabilities.normal = oddsBefore
how would i get the challenge id
trying to patch this specifically gives a blank challenge (no rules)
random consumeable idea trigger a selected joker's on sell effect wihtout selling the joker
anyone know why trying to get a random index for smods.ranks isnt working?
i just want a rnadom rank 😭
Why do the colors on the texr look just like my trance theme, lol.
Maybe they're just the normal colors fir debug and I didn't notice before
they're normal for debugplus
me and marie have been trying to make this work for a short while now - the original jokers function is to make it times its sell value but for now, just trying to even make it add to the sell value
but for some reason, it just does not work
set_cost would override any changes you make to it's sell value.
You should be able to do the same thing Egg goes since this reads as just that but multiplied
ohhh
It's prob just an if check issue.
card.ability.extra is set to a number which means that card.ability.extra.odds won't work
Altho that would give you an error not just do nothing
i am getting an error but its for the extra_value = line, not the extra.odds line
Oops! The game crashed:
[SMODS MJOK "MoarJokers.lua"]:739: attempt to perform arithmetic on field 'extra' (a table value)
Additional Context:
Balatro Version: 1.0.1g-FULL
Modded Version: 1.0.0-ALPHA-0710a-STEAMODDED
Love2D Version: 11.5.0
Lovely Version: 0.5.0-beta7
Steamodded Mods:
1: Debug Mode by MathIsFun_ [ID: DebugMode]
2: MOAR Jokers by Mr.SmoothieHuman [ID: MJOK]
Stack Traceback
===============
(3) Lua method 'calculate' at file 'MoarJokers.lua:739' (from mod with id MJOK)
Local variables:
self = table: 0x3abcfac0 {alerted:true, loc_vars:function: 0x3aa61908, _saved_d_u:true, original_key:awesome-egg (more...)}
card = table: 0x3ae42228 {click_offset:table: 0x3af683f0, children:table: 0x3ae2a9b8, ambient_tilt:0.2 (more...)}
context = table: 0x3b00e7d8 {end_of_round:true, game_over:false}
(*temporary) = table: 0x3ab9a548 {bonus:0, h_mult:0, extra:table: 0x3ab9a570, hands_played_at_create:0, mult:0 (more...)}
(*temporary) = number: 0
(*temporary) = table: 0x3ab9a570 {Xmoney:3, odds:3}
(*temporary) = string: "attempt to perform arithmetic on field 'extra' (a table value)"
(4) Lua method 'calculate_joker' at file 'card.lua:2396'
Local variables:
self = table: 0x3ae42228 {click_offset:table: 0x3af683f0, children:table: 0x3ae2a9b8, ambient_tilt:0.2 (more...)}
context = table: 0x3b00e7d8 {end_of_round:true, game_over:false}
obj = table: 0x3abcfac0 {alerted:true, loc_vars:function: 0x3aa61908, _saved_d_u:true, original_key:awesome-egg (more...)}
(5) Lua field 'func' at file 'functions/state_events.lua:103'
Local variables:
game_over = boolean: false
game_won = boolean: false
(for index) = number: 1
(for limit) = number: 3
(for step) = number: 1
i = number: 1
eval = nil
(6) Lua method 'handle' at file 'engine/event.lua:55'
Local variables:
self = table: 0x3b094aa0 {start_timer:true, timer:TOTAL, blockable:true, trigger:after, func:function: 0x3ae20dc8 (more...)}
_results = table: 0x3b0e6058 {blocking:true, pause_skip:false, time_done:true, completed:false}
(7) Lua method 'update' at file 'engine/event.lua:182'
Local variables:
self = table: 0x3af005e0 {queue_last_processed:16.183333333334, queues:table: 0x3af00608, queue_dt:0.016666666666667 (more...)}
dt = number: 0.0291828
forced = nil
(for generator) = C function: next
(for state) = table: 0x3af00608 {unlock:table: 0x3af00630, other:table: 0x3af00aa8, tutorial:table: 0x3af00680 (more...)}
(for control) = number: nan
k = string: "base"
v = table: 0x3af00658 {1:table: 0x3aa2b518, 2:table: 0x3b094aa0, 3:table: 0x3aec2a40}
blocked = boolean: false
i = number: 2
results = table: 0x3b0e6058 {blocking:true, pause_skip:false, time_done:true, completed:false}
(8) Lua upvalue 'gameUpdateRef' at file 'game.lua:2493'
Local variables:
self = table: 0x3a9a2c40 {PALETTE:table: 0x3a9a3990, F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true (more...)}
dt = number: 0.0291828
http_resp = nil
(9) Lua method 'update' at file 'main.lua:480'
Local variables:
self = table: 0x3a9a2c40 {PALETTE:table: 0x3a9a3990, F_GUIDE:false, F_CRASH_REPORTS:false, F_QUIT_BUTTON:true (more...)}
dt = number: 0.0291828
(10) Lua field 'update' at file 'main.lua:133'
Local variables:
dt = number: 0.0291828
(11) Lua function '?' at file 'main.lua:77' (best guess)
(12) global C function 'xpcall'
(13) Love2D function at file 'boot.lua:377' (best guess)
Local variables:
func = Lua function '?' (defined at line 48 of chunk main.lua)
inerror = boolean: true
deferErrhand = Lua function '(Love2D Function)' (defined at line 348 of chunk [love "boot.lua"])
earlyinit = Lua function '(Love2D Function)' (defined at line 355 of chunk [love "boot.lua"])
``` (wont let me send them at .txt, apologies)
How would you interrupt the draw routine for cards to add multiple shaders?
From what I understandyou have to switch between canvases to do it
you should change extra.odds to just odds though
i'm trying to add a custom challenge rule where if you play your most played hand it doesn't score, i have no idea how i'm gonna make it becuase of how rules seem to work.
Maybe I'm wrong, but I think you should always put your config variables inside the extra{} table, unless it's only one variable. So maybe use
extra = { gain = 5, value = 0, odds = 3}
}```
i changed it because, what i was told, extra = is only needed for things that would be changed? but sure, i will try it
Egg's ability.extra is a number, yours is a table
you can't math a table
that.. would make sense, yeah
question because its like 5am, and i can feel my brain melting, why the fuck is it a table?
you only need to do that if the values will be recalculated, but there's no reason not to in almost every situation
because yeah balatro only saves joker values that are within extra which means they save when you close and reopen a run
because you need multiple values and making ability extra a table is the only reliable way to save multiple values
Table basically store values that you want to later access.
it finally clicked in my head what you guys mean, i think i understand now 😭
okay, so, i wanna be absolutely sure, do i need to define extra_value in the joker itself? if so, how? because i presume (from what spa said), you dont put it in config = {extra = {}} because you cant math a table 
I mean I think you do? Look at literally any oker mod, and you'll see how they do it
You just need to get the number from the table to math it, which is just [].[] until you get down to the labeled numerical variable to do math on
could someone point me towards seeing a modded enchantment example? i don't know how to make them
Enhancement you mean?
Ortalab has quite a few
Make sure you're looking in the new demo repo
thank you 
Someone remind to look into why this would be happening later
oh wow this mod has informed me of all the updated info to object making in SMODS
i've made some very old mods (poorly programed) and i've had so much outdated methods.
I think it’s just missing seals out of the ‘normal’ object types
Oh it misses blinds too, those are still on my local environment
oh yeah you need to change the description for the demo repo
it still says dev
I'm trying to in a way replicate the interaction that Midas Mask and Golden Ticket (in that order) have when playing a face card, in that the card becomes gold and then is counted by the ticket. I have a Jimbo that turns certain cards lucky and another that checks if all played cards are lucky and temporarily increases the odds of them triggering.
I've tried to use the same context/lifecycle checks as Midas and Ticket, but when I'm checking the ability of the card in the probability up joker, the ability is reported as being "Default Base" despite a previous joker turning the card lucky. Any ideas as to why these don't interact in the intended way?
-- turn all 7s lucky
lucky7.calculate = function(self, context)
if context.before and context.cardarea == G.jokers then -- TODO: must know more about lifecycle
local scoredCards = {} -- store the cards that should be upgraded
for _, scoringCard in ipairs(context.scoring_hand) do
if scoringCard:get_id() == 7 then -- if the card is a seven, save it for later
table.insert(scoredCards, scoringCard)
end
end
if #scoredCards > 0 then -- do we have any scoring cards?
G.E_MANAGER:add_event(Event({ -- delay the upgrade a bit?
delay = 0.2, -- what's the unit?
func = function()
for _, toBecomeLucky in ipairs(scoredCards) do
toBecomeLucky:juice_up(0.5, 0.5) -- jiggle. What's the unit?
toBecomeLucky:set_ability(G.P_CENTERS.m_lucky) -- make it lucky
end
scoredCards = {}
return true
end
}))
card_eval_status_text(self, "extra", nil, nil, nil, { -- pops after the hand is removed if in the above event
message = localize("k_mmc_lucky") -- "Lucky!"
})
end -- end length check
end -- end if context
end -- end calculate
-- temporarily increase odds of triggering if all cards are lucky
fixed_odds.calculate = function(self, context)
if context.individual and context.cardarea == G.play then
local allAreLucky = true
for _, scoringCard in ipairs(context.scoring_hand) do
print(scoringCard.ability.name)
if scoringCard.ability.name ~= 'Lucky Card' then
allAreLucky = false
end
end
if allAreLucky then
self.ability.extra.triggered = true
card_eval_status_text(self, "extra", nil, nil, nil, {
message = localize("k_mmc_odds_up")
})
for k, v in pairs(G.GAME.probabilities) do -- this is what oops all sixes does
G.GAME.probabilities[k] = v*self.ability.extra.increaseOddsTimes
end
allAreLucky = false
end -- end all are lucky
elseif context.after and self.ability.extra.triggered then -- clean up after trigger to not inflate all probabilities forever
for k, v in pairs(G.GAME.probabilities) do -- reset probabilities
G.GAME.probabilities[k] = v / self.ability.extra.increaseOddsTimes
print(G.GAME.probabilities[k])
end
self.ability.extra.triggered = false -- reset state
end -- end if context
end -- end calculate
I suppose my questions really are, how can we track the state of a card throughout a hand? Why is context.scoring_hand not reflecting the set_ability call that was done in an earlier calucate?
Ooook I figured it out. It has to do with triggering the set_ability in a delayed event. Don't do it is what I've learned
so how would i make a steamodded mod config save
Question. How G.E_MANAGER behave when game in mods loading state?
it doesn't i think
even with a reference this shit is so HARD
I envy those who can draw, it's so cool
that's where you're wrong, i can't draw well
OK drawing better than nothing
Drawing is 2nd most difficult part of any mod after "Idea"
Btw this joker really wants 2 labels "Joker" just like in any other jokers. It fits very well
ok i'll make one on top one on botto-oh wait miku's gonna cover up the bottom text 
but nevertheless yea
~~Is this a known bug? The card gets debuffed as it is played. I haven't touched any boss blinds or changed how Midas works.
Same thing happens with my own Jimbos that do something similar to Midas Mask.
~~ nevermind
https://imgur.com/a/wzZ5zgo
At least I know I don't have to go digging in my own junk.
any help?
I'm not getting the evaluate function to trigger either. Where did that definition come from?
I'm able to get something to trigger on every hand with, trigger_effect, but don't know how to grab the played hand from it.
SMODS.Back{
name = "Reflective Deck",
key = "rflctdeck",
--atlas = '',
pos = {x = 0, y = 0},
loc_txt = {
name ="Reflective Deck",
text={
"On hand played,",
"One card in hand is {C:attention}Duplicated{}",
"One card in deck is {C:attention}Destroyed{}"
},
},
config = {discards = -1},
unlocked = true,
discovered = true,
apply = function(self)
print("hello apply")
return true
end,
trigger_effect = function(self, args)
print("hello trigger")
printObj(args)
printObj(self)
end,
}
Can't see anything about an evaluate function in the Steammodded or OG Backs definitions hmm
Hm, I though maybe the game somehow knew to look for an implicit return of an evaluate function idk. It's not doing anything as far as I can tell anyway.
trigger_effect is at least what e.g. the plasma deck uses to balance chips and mult. Just gotta figure out how to grab the actual hand played. Maybe that's buried in G.GAME somewhere 😐 like G.GAME.last_hand_played
Returning or calling another function in apply doesn't seem to work. But I've been wrong before
i'm glad i know about trigger_effect now LOL
still confused but we're getting somewhere
evaluate is for SMODS.Pokerhand, not for SMODS.Back
yeah, i'm mostly having trouble finding the cards in a hand
You should be able to check G.play.cards in your trigger effect function
SMODS.Pokerhand is for creating an entirely new poker hand, not for finding cards in hand
okay
Here's a way to modify a random card at least
trigger_effect = function(self, args)
print(args.context)
if args.context == 'final_scoring_step' then
ease_dollars(100)
G.E_MANAGER:add_event(Event({
trigger = "before",
delay = 0.2,
func = (function()
local randomCardInDeck = G.playing_cards[math.random(1, #G.playing_cards)]
randomCardInDeck:set_ability(G.P_CENTERS.m_lucky, nil, true)
return true
end)
}))
end
end
Or get some dollars
saving that for later use, thanks :>
Might not need to wrap it in an event
if nothing else i slightly modified it to do the second half of the deck's gimmick, in that it destroys a random card in deck
func = (function()
local randomCardInDeck = G.playing_cards[math.random(1, #G.playing_cards)]
randomCardInDeck:remove()
return true
end)
better to use the games pseudorandom functions other than math.random for seed related reasons
good shouts
out of curiosity, how does one use the pseudorandom functions?
take ```lua
local randomCardInDeck = G.playing_cards[math.random(1, #G.playing_cards)]
pseudorandom element
?
pseudorandom_element(_t, seed)
_t is the table
seed is pseudorandom seed
do i just leave seed blank for the one by default...?
You could do
local randomCardInDeck = pseudorandom_element(G.playing_cards, pseudoseed(self.key))
okay, thanks!!!
A good learning experience this
This turns a random card in the deck lucky and a random card in the played hand lucky. Plays a gong and shows a little blurb.
It does not take into account if the card was scored.
trigger_effect = function(self, args)
if args.context == 'final_scoring_step' then
local randomCardInHand = pseudorandom_element(G.play.cards, pseudoseed(self.key))
local randomCardInDeck = pseudorandom_element(G.playing_cards, pseudoseed(self.key))
randomCardInDeck:set_ability(G.P_CENTERS.m_lucky, nil, true)
randomCardInHand:set_ability(G.P_CENTERS.m_lucky, nil, true)
play_sound('gong', 0.94, 0.3)
play_sound('gong', 0.94*1.5, 0.2)
play_sound('tarot1', 1.5)
attention_text({
scale = 0.8, text = 'Stuff happening!', hold = 2, align = 'cm', offset = {x = 0,y = -2.7},major = G.play
})
end
end,
powerful
is it too busted?
oh no i meant like. muscle power. well done
OH okay thank you :> couldn't have done it w/o y'all's help so
reflected? interesting
i'm worried it's too good
like i imagine it'd be insane at deckfixing
i'd say a decent trade-off would be something like
either hands leveling up slower
or blinds scaling faster
i'll probably do blind scaling but damn that's the second scaling deck in this mod and there's only 5 decks LMAO
okay, x1.5 base size
pretty sure that deck isnt creating the duplicates properly
it's a bit buggy, yeah
it goes from 44 to 43 when it should stay at 44 or at least go back to 44
i'm gonna try just turning a card in deck into the selected card
iirc creating cards in hand doesn't increment the deck count
double check with cryptid if that is the case
wait it creates in hand
the delayed materialize is odd but what I was seeing is not an issue
oh wait is it in hand?
You have to add them to the tables yourself
okay i went with a simpler approach, we just convert a card in deck to the one in hand
ye it's in hand it just looks odd because the card is created and added to hand but materializes way after that
that was also very buggy, which is why i wanted to fix it
i'd occasionally end up with invisible cards
there!
use the webcam to make the deck have a reflective effect
most complicated cryptid exotic joker code
if i wanted to remove a random card from played hand how do i do that?
like destroy or just remove it from played hand?
destroy
ah, i know how to do that
cuz i cannot figure it out for the life of me
is this before the hands are scored or nah
is this after or before cards are scored
if context.cardarea == G.jokers and context.before then
pseudorandom_element(context.full_hand,pseudoseed('random_destroyIDFK')):start_dissolve()
end```
something like this would work right
thats- hella sort lol
G.hand is the hands held, not the played hand btw
.-.
wait
yeah im pretty sure my code is right
hopefully
i think
maybe
if i wanted it to trigger on the last hand i would have to add: and #context.full_hand == 1
nono context.full_hand is the hand played
if you wanted to make it trigger on the last hand you would do
if G.GAME.current_round.hands_left == 0 then
i'm adding a custom sfx into my mod. here's the code:
SMODS.Sound({
vol = 1,
pitch = 1,
key = "reflect",
path = "reflect.ogg"
})
``` however, when i call ```lua
play_sound('reflect', 1, 0.5)
``` it doesn't work. any help? is there something i'm doing wrong here?
woops
why is that inside of context.joker_main
it should be inside context.before
okay theres wayy too many things wrong here
are you sure you have a card.ability.extra.chips
yk what im just gonna rewrite all of this
it's saying it's not in the sounds folder, but it's in assets\sounds\reflect.ogg. i'm so confused
replace your calculate function as this
what im assuming your code is:
before playing hand, destroy a random card and gain Xmult
after playing hand, return Xmult
please format your code better btw
you'd need to prepend your mod prefix to the key when calling play_sound (this is to avoid collisons between mods)
ya thanks <3
i know, just like how i know that i need to actually learn lua 😞
also
rn when card is destroyed it is still gives chips
it does work but when they upgrade it seems to give an error ;-;
send error?
and send the whole joker too
the X isn't capitalized
also gives error when giving mult o-o
where is the uncappalized "x" then?
The thing you're highliting in the pic?
ooh
should be a_xmult
im refactoring my jimbos but im having some trouble with localization. ive structured the project as follows, but can't seem to load the text from the localization file in my jimbo definitions. ive tried to follow the structure of the ortalab-demo project to the best of my ability, but the localization eludes me. the jimmies and their assets load fine, but the name and descriptions are empty. any suggestions?
.
├── assets
├── functions
├── localization
│ └── default.lua
├── main.lua
└── objects
├── jokers
│ ├── lucky_seven.lua
├── jokers_index.lua
-- main.lua
DogMod = SMODS.current_mod
SMODS.load_file('objects/jokers_index.lua')()
-- objects/jokers/lucky_seven.lua
SMODS.Joker({
key = "lucky_seven",
atlas = "jokers",
pos = {x = 0, y = 0},
rarity = 1,
cost = 4,
unlocked = true,
discovered = true,
blueprint_compat = false,
eternal_compat = true,
perishable_compat = true,
config = {extra = {}},
loc_vars = function(self, info_queue, card)
return {vars = {'World!'}} -- localization??
end,
calculate = function(self, context)
...
return {
message = "Lucky!", -- needs localization (misc.labels.dogmod_lucky)
card = self
}
...
end
})
-- localization/default.lua
return {
["misc"] = {
['labels'] = {
dogmod_lucky = 'Lucky!',
}
},
["descriptions"] = {
["Joker"] = {
['j_dogmod_lucky_seven'] = {
["name"] = "Cool Name",
["text"] = {
"Hello #1#",
}
},
},
}
}
SMODS.Joker needs to be between {}, not ({})
Oh
you can also do func"string" which is equivalent to func("string")
you can read more about it at https://www.lua.org/manual/5.1/manual.html#2.5.8
Not really the one who needs the most help rn
Can you send your mod header?
Yees
--- STEAMODDED HEADER
--- MOD_NAME: DogMod
--- MOD_ID: dogmod
--- MOD_AUTHOR: [dog]
--- MOD_DESCRIPTION: Learn by stealing
--- DISPLAY_NAME: DogMod
--- MOD_PREFIX: dogmod
----------------------------------------------
------------MOD CODE -------------------------
oooo
hmm still blank
I can hardcode the labels in the joker constructor but it's just annoying that it doesnt work -_- whos ever gonna use my junk in german anyways
Do you have it available on git and I can take a poke around?
suuure i can in a few minutes. if you dont mind the (temporarily) stolen assets
Nah I don’t mind
true but I couldn't spot the issue in their code 😅
yippee!!!!
there should be tutorials for simple things like this
reposting idea from #⚙・modding-general : vilatro (i.e. letting you play entirely with the keyboard)
rough sketch:
during a blind, you can press 1234567890 to select/deselect the 1st through 10th card in your hand, if you have >10 your hand goes off the screen and can be cycled through with arrow keys
deselect all with q and if you have only one selected you can move it by holding shift and inputting a position or using arrow keys
pressing enter plays, pressing backspace discards
pressing j shifts the focus to the jokers, where it's the same thing but you can only select one at once, and holding s for 1 second (configurable) sells it
same thing with k for consumables, except press enter to use
pressing / opens or closes deck view
in the shop, each buyable item is numbered (p sure you can't go over 10 in the shop in vanilla at least) and you can select one with number keys and buy with enter, buy and use with shift enter
there's more stuff i'd need to go over but yall get what i mean right
i might make this, might not tho bc college
rad, thanks!
you can see it in action here #⚙・modding-general message
saving is slightly more difficult so gl with that one
well
it's not that hard at all
it's just like
nativefs stuff
2 lines worrh
steamodded handled all of the nativefs stuff for me in my config page
smods saves the configs when the window is closed
ok but wdym by that. how would it "save" anything when the config tab is just a function defined by the mod itself that returns a ui
it creates the config file based off of your default.lua, the saving just updates that table
unless there's some random undocumented config place where you can set values that are consistently saved which wouldn't be surprising because nothing in smods is documented
you have to create a file called "default.lua" to utilize smods config files?
I assume creating the table manually in the code will also work
ya ive never seen a mod with a default.lua file so
regardless it seems kinda pointless considering just doing the nativefs stuff is really easy
definitely easier than figuring out random undocumented smods stuff
ill never stop complaining about smods
theres plenty of mods using config files
maybe there are but i have never seen a file named default.lua
yeah iirc just current_mod.config will be saved when the config window is closed
Plus I thought that config.lua in the main file directory was considered the "default config"
it accepts both maybe?
yeah it's config.lua
default.lua is for localization defaults
yeah the documentation could definitely use some more improvements
:o nice! and agreed i stil havent figured it out lol
what if there isn't a return? 🤔
seemed to have figured it out
nvm
it just isn't working
What are you trying to do?
the shake
Can't you just only return that?
At the very end ofc
Of the calculate function
how would i do this? do i just put in a juice in this joker??
like this?
thats
not correct at all
first of all context.joker_main cant be inside context.individual
i believe you dont know how context.joker_main works?
context.joker_main is after every card scores, when most jokers like Joker trigger
its not what makes a joker trigger, its just an event that happens
not really nope
hmm okay
additionally, you cant return twice
returning ends the function, anything afterwards is cancelled
ah okey so it doesn't ends up in a loop or why?
returns are for returning values in a function
for example,
function iDontKnowWhatToNameThis(number)
return number + 1
end
print(iDontKnowWhatToNameThis(3))
-- this will print the number 4, because the function returned the number + 1
so card = card doesn't need to be in the return?
what are you trying to achieve
litterally just letting all my jokers shake on activation
just like the base jokers ;-;
if you want to make a joker shake, just use card:juice_up() or also add card = card to the table
now before i do something stupid, what table, the return?
you're returning a table
ok thanks
problem with this was that card = card wouldn't work cuz i already have card = context.other_card
but i;ll try it with card:juice_up()
Yknow you can redefine variables, right?
i bairly know anything ;-;
instead try
context.other_card:juice_up()
return {
chip_mod = card.ability.extra.chips,
mult_mod = card.ability.extra.mult,
card = card
}```
oh
Idk if card needs to stay context.other_card in this Cass though
To this
De man neither do I. You've already done a lot more actual modding than me
lol
oh something worked
My closest thing to a mod I've made is DeFused which just reuses already made jokers by other people
still smth tho 🤷♂️
I've helped a lot with Pokermon, but only ideas and composing (not even drawing really) art
Yeah, but you're coding NLM which is also something, and well more of an actual original (the coding in know the ideas are nostky modlich) mod
honestly, i do have some idea's i u ever feel like it
now the played card is shaking lol
i am keeping it
its gud
also was making a scolar but with other kind of cards
i do like drawing, and making my idea's but i suck at art 😞
you can use card:juice_up() like we said at first
somehow it's all just not working
what isn't working
the card = card or card:juice_up()
can you send the entire calculate function?
that'll work on every event
i cant get function SMODS.current_mod.process_loc_text() to change text at all
is there more to it than this
He works!
What that supposed to do?
Just wondering
its meant to set stuff in the localisation files
so in the screenshot i sent the default joker should be called test test test test rather than Joker
but idk how to make it work
Ooh cool
oh boy i can't wait to make joker a-
god deciding to strike me with "the sudden urge to play zenless zone zero":
-# hey pass me your id
I JUST STARTED PLAYINGGGGGG
do some of yall ever start modding and are no longer able to play balatro again
all i do now is make modded things 😭
i havent tried to win an actual run in so long
i mean i started modding immediately after c++ so yeah
Me with wuthering waves
well at least i know what my next project will be (retexturing burnt joker because yea)
Same with the one i am playing, my friend at school introduced it to me lol
-# i need to pull for her shit
bump
You could probably just use a localization file for this?
i'd rather do it like this so it can be changed in game
Use loc_vars then
hi! im trying to make a planet card that upgrades the most played hand, but, im not entirely sure on how to achieve that 😭
i, remember seeing there was a mod that had that kind of functionality but i cant seem to find it anymore unfortunately
does anyone know of a way to do that?
the,, closest thing i can think of is manually having a use code for it but otherwise idk jsdhsdjh
Cryptid's white hole does stuff with the most played poker hand
Yeah I think there's also Station from Jen's
you just missed a letter, it's process_loc_text not process_loc_txt
oh my goodness
im sure i couldnt get it to work in times before this tho
ill try it
oh my gosh thank you so much
lmao
completely my fault for using inconsistent naming
hahaha no worries
tbf that's been off my mind since the standard has become using localization files
this function works best for what im making
since im trying to make a mod that lets you rename jokers and collection items from in game and it would be nice to have them change immediately
it's interchangeable, the files are also just loaded and executed as a lua function. I guess it's slightly more convenient in that case
the main advantage of using files is easily being able to support multiple languages
which you might not care too much about
if i could get my mod to write to the default.lua file that would be perfect
is there a nice steamodded way to do that or should i try actual file io stuff
cuz i would love to have it support all languages
sounds like it'd require actual file io, though steamodded does come with a library for that, removing love2d's restrictions. there's also a util method to serialize tables into valid lua format and a json library, whichever one you'd want to use for your language file (both lua and json files are accepted)
it's not a steamodded library per say, it's called nativefs
ty ty
I found easy reproducible silent game crash. Maybe it will help for someone to make try-catcher better, idk
SilentCrashClass = setmetatable(Object:extend(), {
__call = function(table, ...)
local __index_ref = table.__index or rawget
table.__index = function(t, index)
return __index_ref(table, index)
end
local obj = setmetatable({}, table)
obj:init(...)
return obj
end,
})
local test = SilentCrashClass()
print(tostring(test.something))
I'm actually curious on how I could start making mods for balatro 
there are mod examples in steamodded, you can watch code from other mods for learn how do things
Alrighty thank you!
hi! im having this weird problem with the SMODS.create_card function where for some reason, the cards generate in the right area but arent actually added as a consumeable
sdjfhsjdfh i, cant tell what the specific issue is for this one
nvm, fixed it!
forgot to use emplace on the card
these cards so cool
tyyy
ksdfjhdskfjh okay uh
im trying to make a joker that turns all consumables being held into their "rotten" form
but i, cant seem to get this code to fully work-
because im trying to make an exception for when it's already the rotten form
but it doesnt, seem to work?
sdfkjhsdkfjh
like it replaces the card even if it's the same key
Does replacing it with itself change anything?
wdym?
I mean... it sounds kinda cosmetic if it just replaced a rotten consumable with itself
Unless I'm missing smth
It being the bug
Couldn't you use set_ability to change the card without destroying it?
I mean-
the biggest issue is with gift card, destroying it and then creating a new one loses benefits
though i suppose that would be a very minor case
dsfjhsdfkjh
how does the set_ability function work?
if, i may ask
ksdfjhsdfkjh
You call set_ability passing the center of the rotten consumable on the card you want replaced
Something like ```lua
v:set_ability(G.P_CENTERS["c_tma_the_rot"])
ahhh
sjdhsdjhsd
okok, cool!
thank you, so much
ill see if that works
,,sdkfjh
apparently not-
,,,hm
Maybe the key to the rotten consumable is wrong?
well, it worked before
the key in the declaration is like
"tma_the_rot" so i assume it should be "c_tma_the_rot"??? sdjfhksdkjfh
Isn't it your mod prefix?
i,, dont believe i have one-
your mod would automatically make one
oh-
I think it would be insc, it automatically makes one with the first 4 letters of your mod id
,,,really?
it worked before at least-
or i mean, it didnt matter before
but anyways figured it out, it seems like there's a weird difference between "" and '' that i still dont quite get
jsdfkhsdfkjh
idk if smods specifically has one
but usually I think ' ' is for variables and " " is for strings?
,,,oh huh
well weirdly enough just changing that seemed to fix it fsr
Yeah wait what
this just, fixed, the whole replacing issue
i think
,,,okay!! yeah!! it worked!
lua doesn't care, they're both strings
my only problem with this solution is that it,, doesnt have any animation to it 😭
you could have the card juice up?
,,,ooh, maybe
is your dot key broken?
bet
sorry to ask another question
is there a way to apply a sticker to a joker card?
and like, remove them?
SMODS.Stickers[<sticker key>]:apply(card, true) and SMODS.Stickers[<sticker key>]:apply(card) respectively
i cant seem to understand this enhancement API
is it supposed to be treated like a standard joker?
where are the calculations for enhancements done?
im trying to reference the base code but i cant find anything dsjfhksdfjh
I'd say look how ortalab does it
im looking and it doesnt really teach me anything 😭
also im so confused what's the difference between config and ability
because like
they seem, exactly the same in essence???
and other mods im looking at has abilities declared in config i think??
but like
the game doesnt seem to like it when i do that
Are you making sure ability is a table?
Idk of that'll make it work, but I think that's what the error means
I have no clue
most mods im looking at dont create an ability table but use it all the same
So this is how ortalab (the new demo) and to do it. Seems straightforward and very much like a 🃏
It's okay, obviously it isn't working right for you
its,, just that like-
"ability" just seems to be lost on me for some reason
yeahhh,,,
earlier i was trying to do an enhancement similar to ortalab's sand
but like, i, dont see any of the code that reduces the card's xmult
First thing ifmd day that almost certainly went fix your problem, but will remove a variable is to downgrade to the lovely beta 6
Not all that much but enough where it isn't being used by pretty much anybody who plays with a lot of mods
So the actual code for this is seems to be in a lovely patch. Smods.enhancement is incredibly incomplete if this is actually nessacary, but I have a feeling it's more of a choice
I think the lovely patch might just be because of the fancy art effect
It was a choice for timing, you can absolutely change the values in a normal calculate function
Enhancement improvements were meant to be timed with calculation improved but then ejwu evaporated and nobody really knows how the better calc pr works now.
I am pretty sure though that enhancement calculation works to a perfectly acceptable level, and Math fixed edition calculations too
In terms of the config vs ability, when the centers are created, it copies the config table into the ability table, with some caveats in that it’ll only accept certain keywords for value names, hence the use of an extra table which is copied in it’s entirety
after OS comes out i want to make an inverse tsunami
a billion burnt jokers
quick question, what would be a good mod to learn how to make editions? deciding to dip my toes into something non-joker
totally not inspired by ANY character in ANY game especially not a.... haha.....
there's a lot in cryptid and jens almanac, and the new ortalab demo has some too
ty ty
i just realised im an idiot, i meant enhancement (although, i presume those mods also have those)
ortalab has a load of those, yeah
yipee
a
nice
now for auto updating
there should probably be options for both git and no git, right?
do enhancements just not have loc_txt? or am i stupid?
all the ortalab loc_txt's are in the localization file
is there a way to give cards enchancements using the debug tool, or do i gotta go find these through normal gameplay?
with DebugPlus, by pressing W
you can also like
go to collection
find the tarot that makes the card that enhancement
press 3 with your mouse over it
Imagine a mobile port of that
No mobile modding
But im just saying dude, imagine there were mods for the mobile port, thats what i mean
Yeah, but like MiniRebel said don’t talk about mobile modding
🤔 actually I'm not so sure how to do that without git, specifically checking for updates first before anything else
i could save commit hashes somewhere ig, but how do i get them
What are you trying to do?
have i cooked with these new spectrals
There’s a template in the game texture files for all the different card types. You could try using that to unify the art style
This mfer ain't got drugs in his blood, he got blood in his drugs
auto-update mods based on mod index data
guys why is chips nil here
i changed the plasma part to
if (self.name == 'Plasma Deck' or string.match(self.name, 'Test Deck') and args.context == 'final_scoring_step') then
that wouldnt break anything right
hmm only crashes in plasma deck
you need another bracket after your check for your deck
does anyone know where SMODS.Edition.super.register is defined?
i cant find it anywhere
that'll be the center register
oh thanks, i forgot lmao
question, do enhancements use the same sort of structure as a joker for its calculate() function?
like “if context.X and not context.Y then”, “[something else]”, “[actual function]”
cuz im currently lost as fuck with the code i need to add to this to do what i want it do 😭
nvm it turns out G.P_CENTER_POOLS.Edition is a thing
yes
sick, cool
obviously they will only have the ones that are called on cards rather than jokers though
ofc ofc
wanna make sure because im still clueless as fuck, if i want to check the played cards, it'd be something like:
if context.indivdual and context.cardarea == G.play then
return{
--stuff here
}
end
?
if you spell individual correct, sure
😭
i have spelt it correctly in the code, yes
ty though
is this looking all good then?
basically, it doesn't return to anywhere the way it's implemented, so you have to either use SMODS.eval_this or edit the effect table manually
you cna do effect.mult = card.ability.extra.repetitions
ohhh okay, gotcha
i just realised that it shouldnt be mult and it should be repetitions, whoops
but if i do effect.repetitions = , would that all just "work" or would i need to replace it with the .eval_this as well?
that would probably work, yeah
I'm not 100% on how repetitions interact with enhancements
thats fair enough
there we are, now its doing something
(the entire crash log, currently looking at ortalab code though)
can you send your enhancement code
eval this doesn't handle repetitions





