ive been trying to figure out how to get these to stop saying "ERROR" for a bit now and im at kind of a loss at this point, ive tried putting label stuff in my localization file based off of how i see it in the vanillaremade code but that doesnt seem to be working either, im guessing im missing something here ?
#💻・modding-dev
1 messages · Page 677 of 1
why not context.create_shop_card?
also there's no Card:in_pool
SMODS.add_to_pool is basically that
i see 
mod prefixes arent automatically added to object or consumable types so make sure you actually have the correct full key
ah i should add that to the docs
thing is though that in for example the tarot code the key does end up being a bit different with the capitalization, and fixing the capitalization on mine doesnt really change anything anyways so
yeah
and putting the 'e_' with the editions doesnt change anything
okay but what key did you put in the ConsumableType definition
i see
you are actually returning the localization, right?
oh okay
also make sure misc is not nested
also youre missing the label
i am ?
so... how do i use card_eval_status_text if it exists?
for this, unless you make the badges manually
don't, use SMODS.calculate_effect({message = "message"}, card)
oh, thx :)
so i guess it would be better do everything in context.create_shop_card and return a shop_create_flags table if the card that's going to be created was in the previous roll? but in that case... i'm not sure how to structure that. the docs say that the table that comes out will be passed into create_card, but i'm not sure how what a "make any other card that respects current conditions (voucher redeems, joker effects, etc.) that isn't this one" table would look like, given that create_card doesn't support any kind of blacklisting
so i think i would have to mess with the pools dynamically
maybe remove_from_pool on all created cards, keep track of removed items and readd them every reroll? 
i actually do not know what a badge is in this context
😭 sorry
the thing below the description
that has the rarity/mod name/consumable type etc
wouldn't that still lead to the collection's consumable page still being called error
the thing that says challenge here ?
so it adds the value before it adds the card and i can tell because the upgrade message
bc that works now that i un-nested the misc localization thing
(the card type is called "challenge")
does your collection page still say error
i think in this case just hooking add_to_pool and doing what you said would work, i just didnt finish reading the entire thing lol
you would hook it and check if card_was_in_the_previous_roll and args and args.source == "sho"
(obviously card_was_in_the_previous_roll is something you have to flag somewhere else)
this actually kinda makes me want to develop a more generic banning system that looks at a G.GAME.banned_cards table, which would work similarly to how debuff_card does with like sources and stuff to allow for people to more easily develop something like a challenge where every joker you encounter only appears once, and develop it into something that could eventually be PR'd as an smods feature
that would be cool
speaking of PRs, i need to test my unlock text one at some point 
One of my Boss Blinds, on Ante 1, gave me something that shouldn't be appearing before Ante 4.
set_blind = function(self, blind, context)
if not G.GAME.blind.disabled then
G.GAME.blind:set_blind(G.P_BLINDS[get_new_boss()])
end
end
Here's the in_pool() function of the offending Blind:
in_pool = function(self, args)
--[[
self.config.extra.suits_to_seek = {'Hearts', 'Diamonds'}
--]]
for _, suit_to_seek in pairs(self.config.extra.suits_to_seek) do
for __, playing_card in pairs(G.playing_cards or {}) do
if playing_card:is_suit(suit_to_seek) then
return true
end
end
end
return false
end
Does this override the boss.min consideration?
yes
For implementing advanced restrictions on when a Blind may appear in a run. This puts
boss.minandboss.maxrestrictions out of effect.
manually, by comparing G.GAME.round_resets.ante
why does in_pool override the min btw
I dunno, it probably doesn't need to
idr if it was a deliberate choice or just how the code ligned up
the branch I have for object weights changes that and also makes max actually work 🙃
that's good
Branch? You one of the people behind Steamodded?
both of us are >_<
I also settled on having it function as an optional feature so that I didn't need to spend any more time trying to get it to match vanilla spawnings, thoughts on that?
how long until i get into the top 3
the order is based on commits
only another 270 commits to go N!
tbf I've done a bunch of stuff early spread to more than one commit on main
oh speaking of commits i forgot to bump the version yesterday
I suppose that's acceptable. I'd be good for untouched pools to preserve vanilla spawnings but I don't view it as strictly required
Could you enable it per blind, like with no_collection?
The feature mentioned includes weighted pools, which must be active (or not) for a full pool (e.g. of blinds or jokers), so that doesn't make much sense in this case
why does context.setting_ability not have a before and after of the other card's ability table
So, I'm trying to make a blind that sets your money to $0 when the most common suit in your deck is played, but I don't know where to actually put the logic for it so that it updates the most common suit at the appropriate times.
before the effect of setting the money should do
that's the folder with all the code
no that would be a nightmare and very much not recommended
well then
im looking at that lol
so rather than cram everything inside the main
put them in seperate files inside another folder
you don't need this when you are just starting but if the mod has a couple of objects i would recommend it
This mod will have a lot yes
also it doesn't need to be a src folder, thats just a naming convention i like
what does src mean
source
I prefer that over other namings then
cause ik my brain lol
but the main.lua will be for what then? setting up the mod and that's it?
like instructions for the game essentially
to tell it what to do with all the code lol
kinda yeah, the main.lua is treated the same as every other file so you can do stuff there too but i prefer keeping it for loading files
yeah it's nicer
okay so i assume there is instructions for how to do all that then?
well ig i need to figure out how to make this first jokers description happen in game now lol
yes, what i linked
: )
alright
i shall begin the digging
cracking open a ice cold monster while i do it lol
the main vanillaremade repository is also an example
oh ya im using that to understand how everything needs to be framed
so for now if i plan to make a new rarity would it be best to make the rarity 4 for legendary as the joker is a variant of a legendary
just til i get it working
ugh i need to snag someone into a vc to help me break this down in a way i can understand it lmfao
is this a yes or no?
\localization\en-us is what it's listing
okay so the game crashes now so im obv doing something
this line is cited but i swear that's right
what does the crash say
here
yes
comma
my bad g
well now another crash
i have the sprite and for now just using the code from the vanilla remade just so i can at the very least get it into the game
i added the assert into the main
I feel like this is a case of me forgetting to switch sum out
WAIT
I don't have a utils.lua
will just removing that bit from the code fix this?
like i said i just want to see it in game bare minimum
oh wait
there's no mention of that in the code
did you make an smods.atlas
like the sprites?

like
it can be in any file as long as it loads first
i usually put it in the same file as the jokers
thank you for not getting annoyed btw
i ask too many damn questions but it's how i learn
so i can put it in the main and be fine?
as long as the atlas comes first, yea
so put it at the top
pretty much ye
key is the name of the file replacing spaces with _ correct?
sorry i can read everything six times but until i ask questions in my own way i don't grasp stuff lol
ADHD am I right?
no, key is whatever you want, but you have to use that same key whenever you're defining the atlas for a joker
path is the exact name of the file, even if it has spaces
so if for example the key i placed in the joker lua says warpedperkeo
then i have to use that
not quite
going by the crash, your joker has atlas = "Warped_Legendary_Jokers" in it. so the key when you create the atlas should be key = "Warped_Legendary_Jokers"
oooooo
okay so i had it backwards lol
and path is the name of the file
actually i can change the key to whatever as long as its the same right?
alright we're shortening that for sure
like dis?
I did change it on the others
hmmm i hope that's alright cause now it's something else
Oh and should i nuke that config file so it doesn't display all that garbo at the bottom
this is my entire main, jokers and en-us lua files so far
im lost
wait
the key
the key isnt warp anymore is it
how would i go about debuffing a hand (akin to the psychic) as a stake
AAAA
change the prefix?
main?
second image yeah
do you have any json file already
yeah you should remove the header then
i had no idea that would mess with the code
i though comments were harmless lol
I think I'm lost
I removed the commented header (The one in green)
Is that what you meant?
(Also thank you Aiko for helping a dum dum)
im kinda taking this in stages lol
tomorrow i learn how to do the effect so it's not just joker lol
but rn i just wanna see him in game 😭
Hmm
A joker with a custom calculate is causing a crash when losing a run if it's in the joker area
It's a "calculate on table extra" crash which is weird
How do I make custom music play during the payout screen after beating a blind? I know how to make music just don't know how to check for that
G.STATE == G.STATES.ROUND_EVAL
you should post the crash
Zokers is there to be able to grab jokers to test, but I can confirm it's not causing the issue - it occurs regardless
The code itself for the joker is this - it's effectively just VanillaRemade's implementation of Popcorn, with some extra to change the sprite on activation
it won't help the crash but you can use debugplus to spawn jokers at will instead, zokers is pretty outdated afaik
Oh! I wasn't aware that was part of its utilities, I'll check it out, thanks! might save me some other issues down the line
it's trying to run the original code as well, which doesn't use extra as a table
the easiest want to fix it is to give it another name like name = "modprefix_popcorn"
This is taking ownership of the original, I thought that was supposed to overwrite it
it overwrites its SMODS.Joker.calculate function but vanilla jokers don't have those and are hardcoded
Oh, I see. I had a similar issue with a different joker, where I had to have extra as a value, and use a different variable to store mine - I tried to do that here by renaming it to extran for the table, but yeah that hasn't worked either
because there you are overwriting its config table lol
for reference, I did a similar thing with credit_card, and that one works without a crash - If I do the same here, with extra = 0 in front, and renaming extran.extra to something else, it seems to still face the same issue
(I think there's a high chance I'm just not understanding something yet)
like i said, the easiest way is to give them another name
there's vanilla code that runs the vanilla behavior of jokers regardless of what the joker's calculate function is, but it checks for the joker's name (different from key). if you change the name of the joker when you take ownership, it will stop running the vanilla behavior
OH
i had a similar issue with my 8ball take ownership. at the very end of your calculate function, outside of any condition, do return nil, true. this ensures your calculate function always runs and prevents original code from running
yeah
Ohhh, I get it now, I hadn't realized that was one of the uses for the name field, thank you!
@frosty rampart?
That would trigger post trigger effects on every context.
as N said, it's a bit of a hack, and i prefer changing the name field because making your joker always count as triggering means it can mess with some other mods (e.g. Ready To Fly in Paperback)
so yea what Somethingcom said
oh 
the proper way is to return nil, true but just in the vanilla context
but the name is better honestly
...i should probably change that 
so name field is...
i will port vanillaremade to smods
what even is the name field
name = "something"
it's not loc_txt.name, surely
no
oh literally a name property
i was gonna ask if that changes the discovered state if you'd already discovered it beforehand, but it has that same key, so it should be fine
yea literally a name in the table, same as atlas or whatever
I did it
this jonkler goes nuts in endless
...hm.
when hooking this, how do i get to the object's key from prototype_obj? i'm aware that this is typically self, but i'm like... is it self.key? 
wait, yes it is, i'm stupid. i literally just did this with my weird create_mod_badges madness which also receives self as obj
...oh. that's actually much simpler than i thought.
i think i'll write the PR now, actually. as i flesh this idea out, it actually sounds kinda stupid. i'll hold onto it for now, but
If you make it to endless
remind me how i do queue.stack() and queue.pop() in lua again 
Is there a way to hide all vanilla content without taking ownership or something like that?
Like, jokers, consumables, boss blinds, skip tags, everything
You can hook SMODS.add_to_pool and remove anything that isn't from a mod
Would that hide from collection?
no
Is there a way to do that?
not an easy way off the top of my head
Basically; im just making a vanilla rebalance mid, but take_ownership is causing bugs for stuff
So i was thinking i could just, remake it all, but hude the base game stuff
for k, v in pairs({G.P_CENTERS, G.P_BLINDS, G.P_TAGS, G.P_SEALS}) do
for kk, vv in pairs(v) do
if not vv.original_mod then
SMODS[vv.consumeable and 'Consumable' or vv.set]:take_ownership(vv.key, {
in_pool = function() return false end,
no_collection = true
}, true)
end
end
end
Sorry, where exactly would i put this?
Would this be in my main .lua i assume?
And if so, where in that?
anywhere you want, as long as the code runs
(i.e. not inside a joker definition or anything)
yea
Okay cool
Then i should be able to just use something like vanilla remade as a base for ut then right?
Oh and apologies if these sound like dumb questions
no worries lol, we all start somewhere
yea you should be able to use vanillaremade from there
You mean that it was still running the old code?
Its so funny to me that i can be making some weird stuff like draft deck in my mod, but cant just figure out something basic
Correct
In some cases (mostly boss blinds and a few others)
It ran both
Add name = 'Name (Mod Name)'
bump
To the code you gave you mean?
Cause that i havent tested yet
No, to your take_ownership calls.
Ahhh
Noted
Okay, i will try that as well
Which should i try first.
?
Probably just the adding mod name right
Yes.
Cool
Then ill try what you gave
And if neither works well or i need help ill be back
Sometime tomorrow though, i am done for today, it's almost 11:30
It becomes quite annoying being able to figure out the complicated stuff easily but not the easy stuff period lol
Again, thank y'all for the help :)
Real quick, how would I localize a consumable type? I.e. localize("spectral") -> "Spectral"
I guess this would count as a center
localize('k_lowercaseconsumabletypekey')
thanks!
is there a way for a joker calculation to return a chips or mult value without it generating the ui notification?
chip_mod and mult_mod
cool, will that still update the hand score ui and just not give the lil popup?
Yes.
perfection. thanks <3
im having an issue when setting a playing card's enhancement from m_stone to other enhancements where the card's front (rank and suit) doesn't appear. is there some kind of update front function i should run?
Hey chat, is there a simple way to just turn a card into another, rank, suit, enhancement, etc included?
i have code for that. are you copying it from another card?
Yes.
one moment
Just make a playing card become another playing card.
fully copying all aspects or just select aspects?
Probably everything.
Though if you have code for either of the situations, that might come in handy later on.
the full card is just what the death tarot does. but i also have the others. ill drop you a code snippet
k
I might have totally forgotten death is a card that exists.
k ty
oh, im using get_rank_suffix there which looks like this:
function get_rank_suffix(_id)
local _rank = 'A'
if _id < 10 then _rank = tostring(_id)
elseif _id == 10 then _rank = 'T'
elseif _id == 11 then _rank = 'J'
elseif _id == 12 then _rank = 'Q'
elseif _id == 13 then _rank = 'K'
elseif _id == 14 then _rank = 'A'
end
return _rank
end```
No, you should be doing:
for k, v in pairs(SMODS.Ranks) do
if v.id == _id then return v.card_key end
end
i'm using this string.sub(_source.base.suit, 1, 1) to get the suit. is there an SMODS method i should be using instead?
for k, v in pairs(SMODS.Suits) do
if v.key == _source.base.suit then return v.card_key end
end
understood
attempt to index field 'T' (a nil value) ante
where is the code that generates this entire text block? i need to make it not still show the base card's chip value
is there away to debug a custom boss blind?
instead of just hoping it randomly shows up
Yes, with DebugPlus, if you hover over a boss blind in the collection, and press 3, it will be set as the boss blind for the current ante.
👍
stone card shouldn't have a base card chip value, is this a custom enhancement?
im changing stone with take ownership
yeah normally it shouldn't have base chip
ive managed to get it to not display the nominal. im currently trying to get it to correctly reset its front when converted from stone to another enhancement
for some reason, using set_ability to apply a new enhancement after my custom m_stone leaves the card without a visible front (though it functions normally). so i'm hooking set_ability to reset the front if the card goes from m_stone to anything else
i think its due to a smods bug i've heard
would seem so
it's also not corrently resetting card.ability.bonus so im doing that in the same hook
okay, i believe i have it fixed now. seems to function as intended
okay
in that video being referenced, it looks like delay_sprite is set to true so the card fronts are being removed before the center is updated visually. but yeah, the stone cards have some stuff going on that i cant find the code for in the vanilla code. like i'm not sure where it's setting the card's nominal to 0 or back to normal when the vanilla The Tower is used
What is the easiest way to destroy a random card in the deck that I can put in a joker calculate function
something like SMODS.destroy(pseudorandom_element(G.playing_cards)). will look for that in the wiki quick
local other_card = pseudorandom_element(G.playing_cards, 'seed')
SMODS.destroy_cards(other_card)
yeah that
How do i make a consumable open a set booster on use? even if already inside a booster
you are a beautiful person
carefully. it breaks. once you finish the second booster the original one gets soft locked on screen so you'll have to dig deep to fix that
If a booster is open do you want to delay the booster to open when the current one is closed or do you want to open the booster and return to the other one after it's closed?
i would open the booster and return to the other one (unless it is too fucky)
this is a smods bug, though it's already fixed in dev
hover and press 2
unsure, sorry
have you tried discovered = true,
unlocked = true,
discovered = true,
eval G.P_BLINDS['bl_modprefix_key'].unlocked = false
bump
Yes, you would have to do a lot of work to save the other booster pack's state to return to it after closing the booster pack.
and for the other way?
it's a bit odd, but i do it by just making a tag that triggers after the first booster closes
oh true i could make a tag
You could do that, or you could set a global variable and hook G.FUNCS.end_consumeable and open it there.
that's smart
the tag would be more versatile, as i could just use it too
is there a way to have a function run near boot but not TOO early (as in, all mod objects have loaded and G exists)
thank you all
Hook Game:main_menu
thank you
logo is sweet
the twitch purple background is a nice touch
now that I did

took me forever to figure it out
looked at how the cardsauce mod did it
still don't know how exactly cardsauce did it but I got the general idea
hey all, looking for a bit of help getting this joker ready. The effect of the joker is that it duplicates any tags earnt through skipping a blind. Ive tried a couple implementations and none of them have worked. My current one which has gotten me furthest is this:
if context.skip_blind then
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag(G.GAME.round_resets.blind_tags["Small"]))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end)
}))
return nil, true -- This is for Joker retrigger purposes
end
end```
which works as you'd expect. when a tag is earnt from skipping, whatever the tag on the Small blind is duplicated. but when i try and replace "Small" with G.GAME.blind to make it sense what blind you're currently on, it doesnt work (i imagine G.GAME.blind is a numeral value or something other than the "Small/Big" that G.GAME.round_resets.blind.tags wants). Any ideas on a fix or an alternate method to get the same effect?
G.GAME.blind_on_deck
just tested, blind_on_deck is already the one you're hovering over, so when you skip a small blind you get the big blind tag, and when you skip big blind the game crashes
Do local blind_on_deck = G.GAME.blind_on_deck outside of the event and use that.
if context.skip_blind then
local blind_on_deck = G.GAME.blind_on_deck
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag(G.GAME.round_resets.blind_tags[blind_on_deck]))
play_sound('generic1', 0.9 + math.random() * 0.1, 0.8)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end)
}))
return nil, true -- This is for Joker retrigger purposes
end
end```
this? its having the same issue
Try instead doing add_tag({key = G.GAME.tags[#G.GAME.tags].key})
ohhh its working perfectly 🙏 tysm
I have 2 different music tracks that are supposed to be sync'd, but when I go from one to the other it starts from... well the start
anyone knows what could the issue be? 🤔
oh i needed to put my mod's key before the name in sync, duuh
You need your mod prefix on the sound keys.
How can I change the text of a UI element?
im trying to change the .config.text of the element when its grabbed from get_UIE_by_ID but its not working
yeah that doesn't work, there's probably a way but i had a hard time doing this when i made jokerdisplay
the easiest is just to patch the element to use ref_table
thx
is there a way I can change the color or no?
cuase I need some way I can differentiate between safe and unchecked cells
changing config.colour should work for it
critique my new legendary
a new ouro to the pile
new and unique concept ofc
Is there a way I could disable the movement on a button?
What's it do?
im going insane
lmaooo
ok i stole some code from sealsoneverything to make a joker that makes all editioned cards count as negative.. i can tell it is registering the cards as being quantum negative. but its not actually doing anything with them. the eval is spitting out an empty table
and i dont know why
they just count as negative in terms of scoring
ugh
thats what quantum does
as far as i'm aware
if you want to give cards the negative perk in extra you could probably just increase the joker slot by 1 or reduce its size to 0
what
this is meant to be working on playing cards i should mention
oh lol
ok im certain theres at least 1 or 2 mods with jokers that make certain playing cards act as negatives. does anyone know of any so i can go and raid their code
it's this```lua
local function count_mod()
seen = {}
for _, c in ipairs(G.playing_cards) do
local ed = c.edition and c.edition.key
local seal = c:get_seal()
local enh = (SMODS.get_enhancements(c))
if ed then seen[ed] = true end
if seal then seen[seal] = true end
for key in pairs(enh) do seen[key] = true end
end
local mods = 0
for _, mod in pairs(seen) do
if mod then mods = mods + 1 end
end
return mods
end
Idk how to fix this
ipairs(G.playing_cards or {})
G.playing_cards doesn't exist if you're not in a run
with my fix, if G.playing_cards is nil, it'll pick the empty table instead and just skip over the for loop
Thank you
bump
does emult follow the convention of "just keep it there and let SMODS do the rest" or do i have to manually make it calculate
if your mod depends on amulet or spectrallib, you can treat it just like xmult. if it's standalone, you'll have to implement it yourself
i'm using both
then yes, emult should work fine without any extra work on your end
i'm trying to make an enhancement that, when played 3 times in the same ante, it self destructs.
actually i think i'll change that to "destroyed when discarded"
can i set multiple different enhancements as an enhancement_gate?
OR logic operator preferably
nvm
is there a tutorial for making face card mods?
bump
could you elaborate? 
there's some documentation on how to do it, but it's not exactly a tutorial that'll hold your hand through the whole process https://github.com/Steamodded/smods/wiki/SMODS.DeckSkin
oh, i figured they might be referring to things that do stuff with Card:is_face()
i'm trying to modify the royal face cards with my own artwork for a project, but i'm not experienced with coding
that link on deckskins is what you're looking for, then
ooo
i always thought attaching conditions is gonna be way too difficult but as long as it isnt something very complex,
appearently its not that hard.
why is it a rare?
Made the immortal joker baby trapped in concrete
no reason
its supposed to imitiate older version of bloodstone
bump
LOLL WHAT HAPPENED
OHHH
oopsies
thank you mods for not banning me 🥺
do any of you guys use BMM (mod manager)? doesnt seem to work so im assuming i just need to go back to the regular mod strat (when my account is unhacked)
bump
how do i make it so that after it stole enhancements, it removes them during scoring and replaces them with bloodmarked after scoring```lua
--stole some stuff from ascensio
calculate = function(self, card, context)
if (context.before and not context.blueprint) or context.forcetrigger then
local scalar = 0
for _, card in ipairs(context.scoring_hand) do
if next(SMODS.get_enhancements(card)) and not card.debuff and not card.vampired then
scalar = scalar + 1
card.vampired = true
card:set_ability("c_base", nil, true)
G.E_MANAGER:add_event(Event({
func = function()
card:juice_up()
card.vampired = nil
return true
end,
}))
end
end
SMODS.scale_card(card, {
ref_table = card.ability.extra,
ref_value = "eemult",
scalar_value = "gain",
scalar_table = { gain = scalar * card.ability.extra.eemult_gain },
})
end
if context.joker_main or context.forcetrigger then
return { eemult = card.ability.extra.eemult }
end
end,```
what is bloodmarked
is it an enhancement, an edition, a seal, a sticker, what
where should i hook if i wanna mess with rarity badge
is there a smods function i can use or do i just have to dive into source code
for every card or for a specific one?
just specific one
set_card_type_badge https://github.com/Steamodded/smods/wiki/SMODS.Joker
there's also badge_colour, badge_text_colour if you just want to change the colors
bump
oh cool, is there a reference or key for the vanilla badges i can pass into it or do i just have to redefine them
check G.UIDEF.card_h_popup
oh, table.remove returns the value removed?
yes iirc
set_card_type_badge = function(self, card, badges)
G.E_MANAGER:add_event(Event({
blockable = false,
func = function()
if not card.ability then
elseif card.ability and card.ability.extra.disguisingAs then
badges[#badges+1] = create_badge(({localize('k_common'), localize('k_uncommon'), localize('k_rare'), localize('k_legendary')})[G.P_CENTERS[card.ability.extra.disguisingAs].rarity], G.C.RARITY[card.ability.extra.disguisingAs].rarity)
elseif card.ability and card.ability.extra.failure then
badges[#badges+1] = create_badge('IMPOSTEROUS', HEX('FF00FF'))
end
return true
end
}))
end
``` does this look somewhat correct
you shouldnt use an event, the card will have an ability table when this function runs
ok sorgy
i've been burth too many times by this
wait so does this not run in collection
they have an ability table in the collection
:0
an event will just make it not show up
how do i make code that adds a RANDOM joker to your deck>
yes it is random
alr thx
one question
HOW THE HELL DOES ANY ONE OF YOU UNDERSTAND THIS WITHOUT GOOGLE
I CANT FIND ANYTHING THAT FALLS UNDER THIS AND RELY ON SMARTER PEOPLE THAN ME ON A DISCORD SERVER
That's exactly why I'm making a video guide right now lmao
have you checked the link i sent
thank you
heck
set_card_type_badge = function(self, card, badges)
G.E_MANAGER:add_event(Event({
blockable = false,
func = function()
if not card.ability then
elseif card.ability and card.ability.extra.failure then
badges[#badges+1] = create_badge('IMPOSTEROUS', HEX('FF00FF'))
elseif card.ability and card.ability.extra.disguisingAs then
badges[#badges+1] = create_badge(({localize('k_common'), localize('k_uncommon'), localize('k_rare'), localize('k_legendary')})[G.P_CENTERS[card.ability.extra.disguisingAs].rarity], G.C.RARITY[card.ability.extra.disguisingAs].rarity)
end
return true
end
}))
end
677 is the one that does the rarity badge, i cant tell which one is returning nil
you shouldn't use an event
as for the actual crash, the line where the rarity badges are created is messed up in terms of brackets
you are missing a comma after they key
also you should have a context check in that calculate function
or it will add a million jokers
smods 1502e is crazy work lol
ohhh like how
https://github.com/nh6574/VanillaRemade/wiki#whats-a-context
in this case if context.ante_change and context.ante_end then should work i think
OH
ikr..
also whats the thing so that only one of said card can be in your deck
SMODS.add_card does that by default, it only spawns multiple if showman is present
no its more like uhhh lemme give you an example
if i have one "Kindness luigi" card, the shop shouldnt be able to sell me another
whats that

cuz like i saw a copy of my card show up in shop even after i bought it
have you not played basegame
Balatro Wiki
Showman is an Uncommon Effect Joker that removes the restriction on Jokers, Planet Cards, Tarot Cards and Spectral Cards from appearing when already in the player's possession. This can lead to multiple copies of the same card appearing in Booster Packs or the Shop, or allow card generators such as Riff-Raff (When [[Blind|{{hl|orange|Blind}}]] ...
ah thats a debugplus bug most likely
granted i did hack it in but still
i have i just use certain jokers
oh yeah if you hack in it, the clone clause breaks
Nah that's a fair worry lol
i've seen this convo so many times, there should just be a billboard of faqs with this being one of them
fr
really what should happen is debugplus should fix it
does this theoretically work?
i think it might be a base debig bug that debugplus didn't touch
yes
you can return { message = "STOLEN!" } instead of using calculate_effect
^
Was just about to say that
ah wait
oh yea but does it like change anything? just wanting to know
just makes it easier
nope
rarity = 3 will work but it's not the way to use rarities there because it doesn't follow the standard 1,2,3,4
use rarity = "Rare"
alright
using returns is a lot more preferrable tbh
also returns makes it so other cards can detect if it triggers
I had a feeling that was the case I just wasn't 100% sure on it
random question: whats the code for the credit card
w8 thats really useful
please use VanillaRemade as a reference it is fantastic
as if the three links we've posted to it already weren't enough of an indicator
i am only posting links to it because it fills my ego
well i mean atleast youre helping
but like what if i want my card to have a 40 percent chance of giving a common joker (cuz some common jokers like raised fist are really good) and a 60 percent chance of gettin a rare
I believe rarity is observed when making a random joker
i know how math.random works i played roblox
its forced to be rare rn
I mean if you remove the rarity flag
true..
rarity = pseudorandom("unique seed") > 0.4 and "Rare" or "Common"
don't use math.random for gameplay because it doesn't take the seed into account, but pseudorandom works similarly
weighted pools are about to be a smods thing sooo
get excited for an smods update soon
thats a boolean tho i dont think thats working
its fine i already have my function
what's a boolean
if your roll is over 0.4 fill true condition and get rare, otherwise get common
ohhhhhh
no I didnt mean what boolean means lmao
i meant to ask what you thought was a boolean there
ohhhh
akso yeah it outputs a number not a bool
like adding 3 = 3 is a boolean so adding extra things like > 0.4 and rare or common fits the boolean
no
looks so goofy in the code i love it
3 = 3 is a condition
number > number is a boolean but then that expression it gets evaluated into a string
not a variable
a and b or c gives b when a is true or c if it's false
Technically it's just a syntax error since you'd be trying to assign '3' as if it were a varaible.
oh
yes
i put my weights in the same pools i use to build my cards
and then i call the pool to do weighted pick
soemwhere else
yay
yeah the spawn card hits a vanilla code pass that calls add_joker. I could probably change it but I can't be bothered
I actually don't know why it even happens (I never looked into it)
CAN THIS WORK or do i need to write tarot a different way
try it and see
Is this still happening for you? If so, dos it happen if DebugPlus is the only mod (it doesn't need steamodded)? What is your lovely and DebugPlus version?
No but smods does https://github.com/Steamodded/smods/wiki/Text-Styling
ohhh thx
👌
I'm modifying superposition to give a planet card as well, but creating the different messages in sync with the consumeables being made is annoying. Putting them in the return of the calculate function makes the messages appear at the same time, and when I try to do them separately like this, they don't even play. what do I do
ok, can i use {C:purple}? like whats the color option
ohhh like color codes like c:#00ff00
u have to define it solewhere
no
it has to be either passed as a loc variable or defined globally
ohhhh
Use SMODS.calculate_effect({message = whatever, colour = whatever}, card) since returning a table in an event's function won't do anything
The only relavent return in an event's func is return true to prevent it from looping infinitely
for example you could in your joker loc vars
return
{
vars= { colours = {HEX('222222')}}
}
*code might not ne exact im on phone
and in your loc description you would use B or V for background or text color respect.
like {B:1,C:white}Hello{}
two options here. you can return multiple consecutive effects by putting one table inside the other as an extra key. Or if you care about this specific delay you can use a func return
return { func = function()
SMODS.calculate_effect({ ... }, card)
delay(0.5)
SMODS.calculate_effect({ ... }, card)
end }
or define it globally as told in the vanillaremade wiki
aure cat smod cat
no i fixed it by unchecking only show commands
yes
cool
very yes. much cool
yes
ok I did this and it didn't work so I'm assuming I did something wrong
it should be SMODS.calculate_effect, not SMODS.calculate_context
whoopsie
okay, to clarify, you mean add it like this correct?
No, you need a ,
but in the right spot?
Yes.
but thank you!
how do i add an edition to the playing card pool? is it "Default", "Enhanced" or "Playing Card"?
what do you mean
like a random edition when you create the card?
i'm editing Waxed, and i'd like it to only appear on playing cards
ah, i dont even know if editions have an option for that
paperback does some kinda weird stuff to lock dichrome to jokers only, it piggybacks off the argument in poll_edition that removes negative from the pool and assumes that only jokers would ever want natural negatives
to make it playing cards only you can probably do the inverse of that, hook poll_edition and just remove waxed from the pool for the duration of the function call if the edition pool allows for negatives (since only jokers want that, and consumables don't poll for edition at all)
but that might have some weird edge cases with crossmod of course
here's how dichrome does it, you'd just check if not _no_neg instead
How good is Joker Forge? I'm building a mod, and although I do know a good amount of Lua code I am trying to do the bulk of the mode in Joker Forge then edit or add stuff afterwards that I can't do there.
jokerforge is fine for simpler projects, but you are going to be much better off coding from scratch than editing jokerforge output
i know im missing a comma but i dont know where
I have always (strangely) felt like a better coder when editing preexisting files or projects, sometimes that empty code area makes me not know where to start
not a comma this time, you're missing an end for the if statement in your calculate function
after 'sound everytime a card is played'?
yep see that
OH MY GOD HOW CAN I NOT NOTICE THIS
no that line doesn't need a comma, but it can have one without any issues and jokerforge probably adds it there because it's easier not to have to account for a final line when generating the localization
how do i set up the sound tho im trying to set up glenn quagmire sound but it doesnt exist or i dont know how to make it exist
I don't know if it is added by Joker Forge but it's something I normally do writing Lua anyway
do you have a SMODS.Sound object yet?
https://github.com/Steamodded/smods/wiki/SMODS.Sound
GitHub
A Balatro Modding Framework. Contribute to Steamodded/smods development by creating an account on GitHub.
I didn't know code worked without it, and I have known the language for half a decade ;-;
yes i do
ok well the key is glennn with 3 Ns, so that's part of the issue, but also what's your mod's prefix? it needs to be play_sound("modprefix_soundkey") because it's just a function call, so it doesn't know what mod the sound is from automatically
oh like EpicerMod_glennn
wait so if Cryptid is installed I could call cry_music_jimball.ogg to get Funkytown to play
ye
post your mod's json file, it needs to specifically be the mod's prefix and not the key
but how do i install cryptid
Don't worry about it, I was wondering if I could call assets from other mods in my mod.
ok so it would be play_sound("epicerMod_glennn") then
(capitalization matters, and your prefix has a lowercase e at the start)
ok that one's strange, because from the screenshot you should have the atlas already
definitely
oh do you actually have glenquagmire.png in both the 1x and 2x folders in your assets folder?
with specifically that filename
no its in a seperate folder titled sounds i think that could be a problem but yahimod does the same thing and doesnt specify where the file is and it works
yea thats a cardname
is there a recommended development studio for this? I could get away with Notepad++ but if there's something better I'd like to hear it, all of my Lua experience is in Roblox from when I used to mass produce low quality slop games with my friends a few years back during covid (literally had nothing else to do) so if I seem like a noob I kinda am to this side of Lua
no the sound is fine, we're talking about the sprite now
visual studio code
a lot of people like vscode, notepad++ is perfectly fine, just use whatever's comfortable
oh fuck i gave it two ns cuz thats how its spelt,
ok yea make it match in the atlas
mb
i thought i wrote it as glenquagmire and not glennquagmire
cant use ogg lols
do i have to use wavs?
ogg should be fine
it crashed
post the crash then
ok this is just an issue with the audio file, not with it being an ogg in general
run it through some converter to convert it to wav and then back to ogg and it should be fine lol
(or you can just leave it as .wav, that should be supported too)
So I think I might code from scratch, I want my mod to be massive and unbalanced which I can't really do with Joker Forge easily, I made a tetration joker with it which just did XMult equal to current mult twice successively but I think it could be easier coding from scratch
to add, fre:ac is a good conversion tool
i transitioned it to wav
true
if you know your way around the command line and have ffmpeg, you can even convert it from ogg directly back to ogg
some things still double trigger twt
I added fucking CSS to Balatro
ok so just grab it, convert it to wav and then ogg
ye
i dislike this and dont know why
im going to try that other method you had now
Put sound = 'modprefix_soundkey' in the return instead of using play_sound
ohhh ok
thx
Where is the best place to figure out where to start my mod? I don't need Lua tutorials (good amount of experience) but I have so far only edited Joker Forge projects
I have a name for my mod already, "Eris" and the description will be "An out-of-this-world, horrifically imbalanced Balatro mod"
thx
fine, i will switch from notepad++
notepad++ != notepad
it's workable if that's what you're into, whereas notepad... isn't
this is impressive but also deeply unsettling
What exactly? Performance? Maybe
agreed...
I optimized it as I can, shouldnt be that bad
that didnt work
it doesnt play
I dunno, that's not what I thought about. Moreso on a level of "why would you do that"
I was implementing different format for balala UI first, which is looks like this
Code?
As a part of it, I implemented classes, and during discussion was some mentions that classes may be part of smods
if performance winds up being an issue, I could see this being an optional feature
well, a soft-optional feature would do as it's tied to a class
shouldnt be a big deal, I implemented various things to minimize performance issues
Specifically, caching
Put the message in the return
But again, is niche thing worth performance? Not sure tbf
I like this for how compact and readable it is
no the message works, the audio doesnt
Yes, the message needs to be in the return
if it's used? sure. what I mean by soft-optional feature is that it can just be bypassed entirely if no selectors were registered
but why
if i put it in return the message goes on the card played and not the joker
In this way yes that's true
i dont want that
because a sound return can't exist by itself
message_card = card
OHHHH
But I think there's no place for this in SMODS
the reason is because the sound in a return only replaces the sound a message makes so you need a message as well
putting all the code made quagmire useless
that's not necessarily true. it could be of real value if it integrates smods UI things like localize_box
is this like right?
you still need the message
its message_card tho right?
Also what's that message_card
this can be done if try hard enough, but not sure yet. Modders hate UI in general and I don't think this one will help, maybe even opposite, even more things to memorize
i think if it adds some more predefined classes it would be very neat, and other devs could contribute more templates to it
Especially when it's optional thing, you can do UI as usual too, just like everyone else
especially if it has a lot of templates, I can see this being liked by at least some modders
I see some places for elements which applying localized text for sure
whats the code for context if blinds selected?
context.setting_blind
oh ok
so hands is the thing of how many cards you hold, and hand is how many cards/ rounds you play
so how do i write them
I was developing something similar too, but I really like this
what do you mean
Or developed*, I already made it https://github.com/Oinite12/balatro-modding-modules/wiki/JTML
like how would they be written in the code
maybe try reading this https://github.com/Steamodded/smods/wiki/G
as like how do change hand size and how many hands
hand size: G.hand:change_size(number)
how many hands to play:
https://github.com/nh6574/VanillaRemade/blob/1abd606dc26c46f0c7b281995f40fb25b1d54b4f/src/vouchers.lua#L368
so if the hand is one, then it will only have one card in hand
if the size of G.hand is 1 then yes
so how much to only have like 4 cards
G.hand:change_size(-G.hand.config.card_limit+4)
ohh ok
also on the topic of context.setting_blind can this be used as a boolean of sorts
that's basically a boolean
ohhh ok thx
I prefer ternary logic though: true, false or nil
the blind is being set
the blind is not being set
the blind is maybe being set
ohhhhhhh, also can i theoretically change joker slots to just 2
yes, it's the same code but G.jokers instead of G.hand
ohhh okie
how do I pull the rarity of a joker card object?
for context G.E_MANAGER:add_event(Event({ func = function() G.GAME.joker_buffer = 0 card:juice_up(0.8, 0.8) sliced_card:start_dissolve({ HEX("57ecab") }, nil, 1.6) play_sound('slice1', 0.96 + math.random() * 0.08) SMODS.add_card { set = 'Joker', rarity = --sliced_card's rarity goes here } return true end }))
but is it g.jokerslots? i thought i saw that exist
no, G.jokers:change_size() to change it G.jokers.config.card_limit to get the current one
G.jokers:change_size(2)?
rarity = "Common" ?
or do you mean something else
I mean taking the value of the rarity from the removed joker
ah
sliced_card.config.center.rarity
I see the vision but a bit too far from initial balala system, also requiring n be exactly first and children be exaclty second arguments is weird
Yes, but you would have to do ({'Common', 'Uncommon', 'Rare', 'Legendary'})[sliced_card.config.center.rarity] or sliced_card.config.center.rarity
cool that works
even though ive been pretty much going to see how long i could go without help, it seems that every new atlas isnt working now
Yeah I'm aware it's very distant from UIBoxDef, I'd say that design choice is intentional because I don't really like how UIBoxDef lumps behavioral attributes with visual attributes
As for the second point, mainly did that so I don't have to use keys which I find to be noisy in code - but I could always revise the module to include keys for those two (though it's not within my interests atm)
did you make an SMODS.Atlas
yes
OH NVM
know i need to know the color for yellow
oh w8 its gol
uhh since context.setting_blind can be a nil it crashed the game
where is turns out that's not a thing G.GAME.legendary_mod in this list 

Before I code too much towards my mod just for it to have conflicts with another, would prefix "eris" be taken already? (If so I can just think of another)
Are you making Atlases for each individual card??
it wont with the code you posted earlier
probably something else is crashing
i wouldn't worry about it personally unless it's one of the big mods
yea
how would i implement a joker effect that increases the rates of hidden legendary consumables (i.e. the soul and anything else with soul_rate) while you have it?
You can def get away with doing this but you’ll end up with a ton of tech debt
I do worry since "eris" of course is borrowed from the Flush Five planet Eris and I know mods named after Balatro cards are common (Talisman, Cryptid, Incantation)
wait until my pr for it gets merged : )
or look at the code for it and change the same places
ohhh, like what
idk show the crash log and the current code
that one is in limbo until eremel finishes the weighting stuff
ah i see
you forgot to put a number on G.jokers:change_size
w8 wut
oh i did lol
Can anyone say why these hover-tooltips don't show? Here's the localization data:
ch_c_LAPSEMS_den_of_shadows = {"All Boss Blinds are {C:attention,T:bl_lapsems_mask}The Mask{} or {C:attention,T:bl_lapsems_final_cloak}Chromatic Cloak{}"},
so how do i get the discards and change it
Y'wanna know how many Discards you got left? That's stored in G.GAME.current_round.discards_left.
ohhhh, could i use that to have only one discard right?
Yeah, if you run ease_discard(-(G.GAME.current_round.discards_left - 1)).
Sets 'em to 1. Now, anyone got any pointers for what I messaged a minute ago?
ohhh
ok so know i need it so the player can only play one hand..
So, is this just a souped-up version of The Needle?
its a shrimpo card but yea same thing
What is that, a shrimpo card?
so its a joker card based off dandys world character shrimpo
i just wanted to make a goofy challenge card
Anyone?
I don't believe Blinds have hover tooltips
the website ive been shown talking about colors says it exists
Yes, that's what I was going off of!
is it like this
There's no way to include G.P_BLINDS in that selection?
is it possible to restart balatro? i keep adding things to my mod and i wanna test it out but i have to restart it every time
None that I know of
alt + F5
oh dang fr?
Okay so I'm trying to write a Joker where one rank is considered the other rank (it's random per ante) and i can't figure out how to even start the code (I'm HELLA rusty)
probably hook Card:get_id
note that hooking card:get_id means the card's rank is effectively replaced (so e.g. "aces count as 2s" means that aces won't trigger scholar anymore)
if you want a card to simultaneously count as multiple ranks, like smeared joker or wild cards behave with suits, you'll have to wait for the infamous quantum ranks PR in smods to get merged (it will probably not get merged any time soon)
is it possible to make a boss blind always appear as the final ante 8 boss for a certain deck?
me when i use card.base.value:
put UI code into SMODS.current_mod.config_tab
How?
well the way i did it was i had a separate lua file where i defined my config tab UI code and then assert(SMODS.load_file())'d that into that var
that's bad practice because that also bypasses rankless enhancements like stone
which is why i also check SMODS.has_no_rank()
well it depends why and how its used
is there any particular reason why you need to use card.base.value instead of card:get_id()
my reason is that i'm stupid 
-# who has docs on Card:get_id()
it returns the id of the card : )
2-10 for 2-10, 11 for jack, 12 for queen, 13 for king, 14 for ace, a random negative value for stone
i think modded ranks get assigned an id
you can get modded rank IDs by checking SMODS.Ranks.modprefix_rankkey.id, and all rankless cards get a random negative value
i think for some reason i had it in my head that :get_id() was bad practice and you were supposed to use .base.value 
i don't know how this happened
there are a couple non-mechanic-related circumstances where i need .base.value though, so
Now that I've got a config page available, how do I access its values?
SMODS.current_mod.config.myValue
although it's generally safer to have a global mod table you can access that is populated by SMODS.find_mod([your mod id])[1]
yeah, that value in runtime is volatile because it iterates through all mods
to find it via debugplus, you could try
SMODS.find_mod([your mod id]).config.myValue
Is it supposed to return a table?
SMODS.find_mod returns a table of all the mods that have or provide the ID
next(SMODS.find_mod("...")) is the first mod in that table, which is what you're looking for
right, forgot about that part
although actually you shouldn't need find_mod at all
just SMODS.Mods.Lapsems should get you the same table lol
Same with next(SMODS.find_mod('Lapsems')).config.
SMODS.Mods.Lapsems.config.disable_vanilla_boss_blinds worked, though.
how do you change the background color of a boss blind?
I can change the ui and title color
but not the background
Of a Boss Blind, it's boss_colour = HEX("FF5555"), say, if you want a light red!
or is that a lovely patch thing
tried that the color stays the same
talking about the swirl in the background
That should be the same as boss_colour. I'm as stumped as you are.
Yes, if you wanted to do that it would be select(2, next(SMODS.find_mod('Lapsems'))).config
I change itt o the ox but only the ui changed not the swirl
Ohhhh, it's negated for Showdown Blinds. I tried the same.
so just not possible through smod?
I'm sure it's possible somehow, but that solution is not known to you or me.
probably needs to be done through lovely patch then
i'm pretty sure there's stuff on changing vortex colour code
is that only for the main menu
I had to do it through lovely patch
unless it was recently added
smod wiki says it's supposed to affect the background colour
but only affects the ui
yeah it's disabled if it's a showdown boss
is that intentional?
does this work to do what i want, or am i stupid? in testing, it's never done the xmult more than once, even with a bunch of oops all 6s
yes, all showdown blinds have the same generic "final boss" background
huh never noticed until now
I wonder if I could do a dumb work around
I was gonna make it the final boss of the twitch deck anyways
is there away to set a boss to be the ante 8 boss of a deck?
thoughts on the artwork?? (dont mind the elephant in the room)
It looks good to me
Art is subjective anyways lol
As long as it fits your theme should be good
nice way of saying its ass
what if the joker were like a library card
oh LMAO i was so confused. I know what a library card is i just didnt understand what you meant 😭
thank you for the reference image
Oh hey you're alive again lol
bump
That is a scary amount of extras
Why aren't you using a for loop and SMODS.merge_effects?
the idea was to, instead of combining the xmult, have it do the xmult juice each time.
it's 1 in 3 chance for x1.5 mult, then 1 in 4, 1 in 5 and 1 in 6. so the intent is if they all procced, it goes x1.5, x1.5, x1.5, x1.5.
...would merge_effects do that, or would it just do 1 lot of x5 mult?
Yes, it would do what you want.
merge_effects creates a return table, right?
Yes.
wow, it works! 
Did you design those face cards? I've got some ideas of my own for such, but my pixel art skills are not what I'd like for them to be.
i didn't - they were drawn by the former other developer and lead for this mod, who seemingly disappeared off the internet altogether back in november 
hell yeah n you the goat
How would I check if the blind is beaten in one hand?
if context.end_of_round and context.main_eval and G.GAME.current_round.hands_played == 1
is there a hand scoring context that a joker can access that would occur just before an individual card is calculated? i would want each individual card to score until the last, then have this joker affect that last scoring card, and then that affected card gets scored
i guess i could use context.individual of the card right before it as a really hacky way to accomplish this
No, but you could use SMODS.calculate_effect outside of a func and it would look as if you did.
i dont think there is
sorry, how would i do that?
SMODS.calculate_effect(effect, card)
where do i put it though, sorry. do you have an example of that being used for something?
In context.individual
oh, are you saying like, just don't put it in an event so it bypasses the event manager?
i feel so dense right now, im really sorry im not understanding
No, things in returns happen when they should, but if you use SMODS.calculate_effect outside of a func in a return it doesn't.
does SMODS.scale_card accept operation = "/"?
No, you would have to use a function.
is this what you mean?
-- TODO: new joker that makes rocks count as wild, playing a flush causes the last scored card to become a rock
SMODS.Joker { key = "painted", -- object key (mod prefix will be added automatically)
atlas = 'balatro-revalanced-jokers',
pos = { x = 0, y = 0 },
rarity = 2,
blueprint_compat = false,
cost = 5,
calculate = function(self, card, context)
-- m_stone are also m_wild, can quantum enhancements do this part?
if context.individual and context.cardarea == G.play and next(context.poker_hands['Flush']) and
context.other_card == context.scoring_hand[#context.scoring_hand] and not context.blueprint then
SMODS.calculate_effect({
context.other_card:set_ability(G.P_CENTERS['m_stone'])
}, card)
end
end,
}
If what you want to do doesn't require a return then you don't need the SMODS.calculate_effect
oh, i just put the code directly into the calculate and it will work?
lawl, that's easier

