#💻・modding-dev
1 messages · Page 169 of 1
so like so
yeah, will get to that
does this account for Bonus enhancements and Hiker upgrades?
no
How do you do grey text in card descriptions
ah, okay, what'll need to be adjusted for that
{C:inactive}
forgive me if im dumb as a rock but is there ways to make random rolls not overlap? say like, lucky card chances can overlap in their activation, but i want something to activate x OR activate y
uhhh you could hardcode those specific bonus values, but it's hard to catch all chips sources during main scoring that modded objects may add without hooking scoring calculation to keep track of a scored chips value or something similar
use a single chance roll and use disjoint ranges
or you could use context.other_card:get_chip_bonus() like a reasonable person
local x = pseudorandom('abcdef')
if x < 1/15 then
elseif x < 2/15 then
end
for two 1/15 chances that don't overlap, for example
so swap context.other_card.base.nominal with that?
yup
I mean I was taking it to account for all chips effects in main scoring, which this doesn't
but fair
you mean like odd todd?
if it accounts for base value, Bonus, and Hiker, all I want it to do
cus i think of that as not being part of the chips scored by the card
no, like foil edition
or an enhancement that adds chips in main scoring calculation if you want something more comparable to bonus cards
alatro is weird man

someone should make a 🅱️ joker
small update on that: the crash definitely comes from Saturn, it crashes when i sell a perkeo-affected card or just by starting a blind with one in hand. idk why though, so i just removed saturn sadly. going to sleep now but can maybe investigate tomorrow if someone knows his way around
supported now as select_card = {CardSet = 'area', CardSet = 'area'}, e.g. select_card = {Weapon = 'weapons', Tarot = 'consumeable'}
I figured it out. Saturn sets card.edition as {} if it's nil for some unknown reason
you sure do know your way around lua lol. i might try to learn exactly what happens one day or so
thanks a lot, i'll try fixing that tomorrow
thanks so much anyway
SMODS.Joker {
key = 'ethereal_j',
loc_txt = {
name = 'Ethereal Joker',
text = {
"Each played Planet Card gives",
"a Tarot Card"
}
},
rarity = 1,
atlas = 'vopjs',
pos = {x = 1, y = 0 },
cost = 6,
loc_vars = function(self, info_queue, card)
end,
calculate = function(self, card, context)
if context.using_consumeable then
if context.consumeable.ability.set == 'Planet' then
local card = copy_card(pseudorandom_element('Tarot', G.consumeables, pseudoseed('ethereal_j')), nil)
card:add_to_deck()
G.consumeables:emplace(card)
end
end
end
}
Y'all know what's wrong with this? The game runs fine now until I try to open a planet booster, then crashes saying something about randomseed errors
how would i impliment something like this
steal the code from stencil ?
Isn’t that just stencil?
What the flip
it like slightly different so its ok
holy fuck its you
its YOU
ITS you
In what way?
Despite everything, it's still you.
im just here to figure out if you can make a boss blind manually trigger the debuff sound and visual effect
To me it just looks like stencil but with 1.5X instead of 1X
see, i changed it!
stencils dont count for stencil and only give 1x mult, this isnt excluded from the calculation and is 1.5x
Either way yeah just rip off stencil
so basically it would just be “1.5x mult for every negative joker”
More unique
Then you can adjust the numbers as you see fit
And the rarity cuz that definitely isn’t common lol
i didnt bother to change the rarity on balaui
i use balaui to conceptualize jokers sometimes
Ah makes sense
anyways, two more jokers from me
dont stone cards mostly do that anyway?
well, kinda - they flag as having no suit not any suit
I take it the Casino Night Zone is not recursive?
It would be but the thought experiment is funny
might wanna add "excluding Casino Night Zone" to its description
Enabling rock flushes is actually an interesting concept
what does arranging child notes vertically mean
are children of column node supposed to align as A B C or
A
B
C
where is the splash handling code??
im trying to replicate how it makes all cards score but i dont know Where it does things
whats fun about making balatro mods is making descriptions for jokers and delaying the inevitable
is there a context for when a poker hand gets upgraded? there's a context for consumables being used that I could filter for planet cards only, but that ignores other methods of upgrading hands, i'd imagine (unless it doesn't?)
see how constellation works!
constellation triggers specifically on planet cards, though
Any good/best practices for cross-mod compatibility? If i were wanting to hook into a function for Trance, is it as simple as something like this?
local g_funcs_set_Trance_font = G.FUNCS.set_Trance_font
function G.FUNCS.set_Trance_font(...)
local ret = {g_funcs_set_Trance_font(...)}
SystemClock.reset_clock_ui()
return unpack(ret)
end
Any other checks or compatibility notes required?
wheres the code for jokers typically stored, i can have a look for it
prolly should check whether the function exists
or you'd be calling nil
card.lua and game.lua but i searched for 'Splash' and found nothing??
i assume its where the code that handles which cards get scored and which dont are but i have No iDea where that is
Splash is in... functions/common_events.lua i think?
that function is for setting variables inside the description
ah
its just loc_vars :(
ill check again might have missed it
im not seeing it, or its not referenced by name
now way itsd abbier from mindstorm
i want to make a joker that retriggers all luck based effects
how would i go about coding that?
like in the sense that
when something like a lucky card is played
and it rolls the 1 in 5 and 1 in 15 odds
i want it to make the lucky card roll those odds a second time
or for example a heart card is played and i also have bloodstone
and it rolls that 1 in 2 to give that x1.5 mult
i want it to do it again
aha so this will be a lovely patch
id check oops's code first
this just sets G.GAME.PROBABILTIES.Normal to 2 instead of 1
dam
the way probability in the game works, you call pseudorandom and it spits out a number between 0 and 1
you divide G.GAME.probabilities.normal by your 1 in N chance
then if pseudorandom is in that range, you hit the probability
what you'd probably want to do is hook pseudorandom? im not sure
question does lua not have select statements
select statements?
match
no switch case
if it works it works
itd still be solved with oop tbh
also this in Bunco
multiple actions out of a list
which I'm borrowing code from for my own mod, but I've also changed this
lucky cards on steroids basically
this context occurs after a card has been played, and means removing it from the deck for the rest of the blind, right? it's a bit vague
this context occurs when a card is destroyed
(Canio, etc.)
how would i go about making that patch (im sorry, i only started doing balatro modding like 3 days ago)
the context you're looking for is destroying_cards
also random question, are spectral cards based on anything
nah
like how tarot cars are actual tarot cards
john balatro just made them up i think
im not exactly sure abt the specific patch
i feel like one of these is wrong
yes except it makes sense since that isnt a tarot card
I can only find context.destroy_card, which is for marking cards to be destroyed? the main thing I'm trying to do is have a card that goes back into the deck when played
neither is wrong
i mean neither is estrogen
urgh i like really wanna make a mod but ive got zero ideas
does this just make any card into a queen
no context for that, gotta hook to one of the card play functions
yep
peak
I see, thanks
converts all face cards into queens
money colored box has 2 rows but is in column mode, in the other image container is in column mode but has 3 columns, what am i missing?
any card!
have you also got a testosterone one
testosterone converts any card to a king (including jack bcus thats the third gender)
oh the right one should be 1 column 3 rows...?
pueberty blockers for jack
ah yes, the three genders
there is an error right???
there's some precedent tarot decks with nonstandard major arcana, basically the only choice in this scenario besides inverted cards anyways
@wintry solar
for the transgenderism tarot cards, would the card have the "Transgender" enhancement and have its background become the pride flag
no but we do have spiro
it turns all your cards into gold cards
is hooking not in the documentation?
hooking is part of lovely not steamodded
ahh okay
whats the context i use to run code when a specific hand type is played?
im making yaoi/yuri cards that reset when a straight is played
next(context.poker_hands["type"]) iirc
it's standard lua function hooking. lovely is purely for code injection - you can hook functions using it, but it's not as convenient.
breeze posted the link to an awesome guide/tutorial on lua hooking recently: https://forums.kleientertainment.com/forums/topic/129557-tutorial-function-hooking-and-you/
I have a weird problem. I sent my friend a stripped template folder to give them a quickstart with making their own mod. Neither this nor a changed version of this template show up in their Mods list, but both show up in my Mods list.
Both mods are set up the exact same way in the exact same place (that being, with the rest of our mods). What are we missing?
I see, will look into it
100% refer to the link Larswijin shared
Friend is making a mod, and this is her calculate function rn, what's weird is the game just crashed saying "other_card is nil"
calculate = function (self, card, context)
if context.cardarea == G.play and context.individual then
if pseudorandom('wah_nurture') < G.GAME.probabilities.normal/15 then
G.E_MANAGER:add_event(Event({func = (function() context.other_card:set_seal("Red", nil, true); return true end)}))
return {
message = "EWNIAH",
colour = G.C.GREEN,
card = card
}
end
end
end
by the time the event runs context could have been modified and you can't guarantee it'll be there
you should store the value of context.other_card in a local variable outside the event and use it instead inside the event
Hihi! Im working on a Spanish Suits texture pack but i cant get it to show up in the game its self. I mean- the game starts up and the mod its self shows up in the mods area but the textures just dont show up? Im trying to figure out if its the code of the .lua file or something else
Anybody having the same problem?
edit: this has been solved!
does anyone know why my mod causes the game to randomly crash when executing completely unrelated code?
https://github.com/DigitalDetective47/strange-library
Anyone?
only crashes on #1336473631483760791
Bumping this message because they're still ticked off lol
Waiter, there's Cryptid in my Cryptid
hmm yes the cryptid is made out of cryptid
quite cryptid
I'm not :P
(
())
(^ this is the friend in question)
hi :3
as cryptic as bigfoot hitting the griddy
anyway no the folders are not double nested
are you both using the same version of steammodded?
"min_version": "1.0.0~ALPHA-1030e"
Mine is 1122a
is there a way to separate purchase price from sell price and set them to independent values?
latest version is 1409a
check cube from cryptid
that doesn't mean anything for the problem at hand
it absolutely does
i guess ill look at that
the minimum version is less than either of our versions and it works for my version. i'll tell them to boost the min version for their files but we have a bunch of other mods that are perfectly functional
mod metadata handling might've changed idk
for this section on SMODS.Consumable, would i set the parameters as
soul_rate = 0.005
}```
?
or is soul_rate something else
how would you display an info_queue for a seal? like how you can do info_queue[#info_queue + 1] = G.P_CENTERS.m_enhancement for enhancements
oh its just part of "Other" ok
Steammodded tutorial VS json
how can I prevent a playing card from being debuffed via a seal/enhancement/whatever?
truthy and falsy
truthy and falsy...
sounds liek some cocomelon shit
Where can I access this thing (forgot the term)
to my knowledge everything is truthy except nil and false
im new to booster packs so idk what im actually doing here, the green particles r there at all times + flashing weirdly, and also that "ERROR" on top of Choose 2, how do i fix all of them?
for the particles, make sure to set skip_materialize = true
also kind should be a string value
it acts as a key for booster pack types
nope, that would put it in the same pool as the standard arcana packs
huh, so the kind should be different from them?
yeah
alright, thanks, though i have an additional question now, how would you use "kind"?
when spawning a booster pack
oof, didnt seem to fix it
trying to make a joker that behaves like DNA but for face cards (Played face cards are copied twice to Hand when hand size is 1) having problems where it doesn't wanna copy the card to the deck
Would it be equivalent if I move this to the calculation function instead?
Like, does every possible case of changes in consumeable slot run through calculate_joker?
set that in the table returned from create_card
on a consumable, is this structure correct to give this card a 7.1% chance to spawn?
yeah
perfect ty
oof, got it
Was experimenting with patches but wow, this is new to me. Like, very new.
What's the global variable for the count of how many times a specific hand was played this run?
check supernova 
thanks ;D the particles r gone now, though how do i change this "ERROR" part?
nice! thanks G.GAME.hands[context.scoring_name].played is what i'm looking for
sstill having issues with this one
copied cards is never updated
copied cards is never updated?
:(
idk how that would work with loc_txt
this is referring to me btw
oof, same, i should probably go investigate some mods with booster packs then 💀
how can I detect if a card is changing in some way (i.e. a card is being used to change the seal, enhancement, etc)?
hook Card:set_seal
I have a seal that applies prevent_debuff to a card, but I can't figure out a clean way to remove it once the seal is gone, so it's just never debuffable again
ah
actually, figured out a safer way to do it that doesn't go around applying semi-permanent anti debuffing to cards
how do i make it so that card_eval_status_text trigger immediately instead of it waiting for the round to end?
i am struggling to figure out how it might work like activating per card animation just like how returning a message works
unless im using the event manager wrong
What's your code
trying to make it show the process of chips being changed and then mult
but the events always end at the very end of the scoring animation
you should be able to just return multiple effects and replace the message
return {
chips = whatever,
mult = whatever,
chip_message = "whatever",
mult_message = "whatever",
}
as a random example
chips_message is a thing?
assuming you're using a recent version of steamodded yes
it will replace the default chips message
yeah i had to update my steamodded from the version cryptid uses to the recent one
then that should work
as a replacement for all your code in joker main
actually it's "chip_message" without the s
how about a message per card activated, specifically for a setup like this
also what's the boolean arg for the second value on set_ability for
usually if you want to do a message on each evaluated card you do if context.cardarea == G.play and context.individual where you can replace G.play with any area
and whatever you return there will be evaluated on each card
i'm not sure why you're using pre_joker
this joker is specifically set to wipe the cards clear after the cards have been scored
is it possible to lovely patch steamodded code?
this works exactly like i wanted to except the messages don't display anything, it's a table right?
yep it's a table, i figured it out
i feel like you should use context.after instead
if you want to make a card show a message at any point in time you can always do
SMODS.calculate_effect({ message = "whatever" }, card)
and you can add instant = true to that table if needed
yeah i'll try that, along with another joker to see if it helps

a little, odd
i don't think the numbers look right
can you send the entire calculate function
oh well it's probably because you're modifying them twice here
yeah isn't it adding the numbers again?
when returning effects they are applied automatically to the hand, so you shouldn't need to set hand_chips or mult before
returning chips and mult adds the value to the chips and mult again
i can just set those to 0 when calculating so it returns the exact numbers
mmmmmm what did I do
wait have to tweak it a bit more
i mean sure, that works, but I was more thinking like
local chips = mod_chips(hand_chips * blah blah)
local mult = mod_mult(mult + chips)
return {
chips = chips,
mult = mult,
blah blah
}
what's your metadata file
i mean well it works like that
the issue was that returning chips = chips will just add the new value of chips, to the chips again
same with mult
yeah you'd have to multiply by card.ability.extra.xchip - 1 instead
though. xchips work i think?
Hello, question: Is there a way to get the enhancements, editions and stuff from any given card?
wait, is there a context that ignores card repetitions? i don't want the cards to be constantly check to be wiped
check not context.repetition
card.edition and card.seal, for enhancements you can use SMODS.has_enhancement(card, 'm_wild') as an example to check whether it is a wild card, or SMODS.get_enhancements(card) to get a table with the enhancements it has
I'm trying to make a Joker with the description of:
Gains +1 Mult for each card scored, resets at end of round.
(Currently +0 Mult)
I have it in game and the description is right, but the Mult doesn't increase when I score a card. Is anyone able to help me see what I'm doing wrong?
SMODS.Joker {
key = "my_joker",
loc_txt = {
name = "My Joker",
text = {
"Gains {C:mult}+#2#{} Mult for",
"each card scored,",
"resets at end of round.",
"{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)"
}
},
config = { extra = { mult = 0, mult_gain = 1 } },
cost = 5,
rarity = 1,
blueprint_compat = true,
perishable_compat = true,
eternal_compat = true,
atlas = "MyMod",
pos = { x = 1, y = 0 },
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.mult,
card.ability.extra.mult_gain
}
}
end,
calculate = function(self, card, context)
-- When a card is scored, upgrade joker
if context.main_scoring and context.cardarea == G.play and not context.blueprint then
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_gain
return {
card = card,
colour = G.C.MULT,
message = localize("k_upgrade_ex")
}
end
-- When joker is triggered, add mult
if context.joker_main then
return {
message = localize {
type = "variable",
key = "a_mult",
vars = {
card.ability.extra.mult
}
},
mult_mod = card.ability.extra.mult
}
end
-- At end of round, reset mult
if context.end_of_round and context.cardarea == G.jokers then
card.ability.extra.mult = 0
return {
card = card,
colour = G.C.MULT,
message = localize("k_reset")
}
end
end
}
is that a cookie run mod 😭
it's only part of my mod 
context.main_scoring is not for jokers
you should replace it with context.individual to run on every scored card
I'm applying shaders to seals, and the 'voucher' shader works fine for giving a shiny effect, but isn't nearly as visually strong as what appears on the gold seal?
apparently, looking at the code, the gold seal does just use 'voucher', even though there's a separate 'gold_seal' shader in the files? and attempting to use gold_seal just crashes my game
omg it's working now this is so cool, thank you!! 
np, also your end of round thing is missing a blueprint check
oh true good catch thanks, so that would just be ```lua
if context.end_of_round and context.cardarea == G.jokers and not context.blueprint then
-- (...)
got ya, ty
where can I find it? Or is that my json idk what staff is called just how to code it
nvm its the json
the error says "Skidibi Mod/mod.json"
{
"id": "gambling",
"name": "Gambling",
"version": "1.0.0",
"description": "Adds a 50% chance for a tarot card to either turn all Jokers into Poly or destroy them.",
"author": "Hallowed",
"main": "main.lua"
}
I have 0 idea on metadata files, so don't judge if this is wrong
you only need what says "[required]" next to it
while in the middle of defining a table, can I do something like this if I want two attributes to be the same?
var1 = {
-- definition of big table
},
var2 = var1
}```
doesn't look like it
yeah in the wiki, i noticed the issue but pr'ing to a wiki page felt like so much work
I don't see why you'd need to do that
you really could've been more specific.... at least link the page, in what section it is
meta trash bag 🗣️
I feel very dumb for not knowing my errors
I'm very sorry if this is easy 😭
what's your actual code looking like?
Oh, then nevermind
Is there a way I can just add some random code to make sure its initializing? @normal crest
to what
my main.lua
if your game is crashing that's a sign your code broke smt
yeahh
so your mod is running
I'm looking through API to do it step by step what I want to do, maybe that will help
welp. bodged this with a custom shader that's pretty much just a dupe of voucher but it multiplies a value by 2
nah it's a full separate repo, same amount of effort
is there an always_scores = true but for seals instead of enhancements?
or do I have to make that myself
anyways I still have no clue where the issue is
and I'm not gonna look through the wiki to search for it
lemme find it
https://github.com/Steamodded/smods/wiki/Your-First-Mod#useful-resources "nessicary" in the last sentence
no but you can hook SMODS.always_scores to add it
I am not surprised
shots fired at wilson i suppose
im getting an error idk how to fix 😭
I may be new to this
is that what fire at will means
I see, will try to figure this out then
clearly
without your code we won't be able to help
mbmbmb one sec
try me
and PLEASE judge as I have little idea on what i'm doing
local tarotCard = SMODS.Consumable({
key = "tarot_card_joker_effect",
loc_txt = {
title = "Balance",
description = "50% chance to turn every joker polychrome, 50% chance every joker is destroyed"
},
image = "Tarot.png",
rarity = "common",
unlocked = true,
discovered = true
})
tarotCard.in_pool = function(self, args)
return true, { allow_duplicates = true }
end
local rarityCommon = SMODS.Rarity({
key = "common",
loc_txt = { name = "Common" },
pools = {
["Consumable"] = { rate = 1.0 }
},
badge_colour = {0.5, 0.5, 0.5},
default_weight = 10
})
tarotCard.use = function(self, card, area, copier)
if math.random() < 0.5 then
local jokers = SMODS.GetAllObjectsOfType("SMODS.Joker") or {}
for _, joker in ipairs(jokers) do
joker:set_sprites(card, "polychrome_sprite")
end
else
local jokers = SMODS.GetAllObjectsOfType("SMODS.Joker") or {}
for _, joker in ipairs(jokers) do
joker:remove_from_deck(false)
end
end
end
my guess is you have a consumable with a set that doesn't correspond to any valid pool
Read my mind and figure out my problem
i correct, no set at all
pretty good guess
is it this?
no, you never reach that function
no need to correct yourself, nil is not a set that corresponds to a valid pool
add a 'set' key to your consumable definition
very good assumption
also I have some questions
a lot of what you're doing just isn't how steamodded works
i'd love to see what you used to base your code in
oh yeah I barly know it, i'm trying 😅
e.g. image = "Tarot.png", is not used (or referenced anywhere I know of) to specify the spritesheet of a card
chatgpt?
SMODS.GetAllObjectsOfType just doesn't exist
probably
joker:set_sprites(card, "polychrome_sprite") also isn't how that works in the slightest
it's not how you make a card polychrome, and it's not the right arguments to Card:set_sprites either
very bad idea
I very much assumed that lol, I knew that wouldn't work but was trying to find how it did
I know that now 😅
in fact polychrome doesn't even have a sprite
I just can't find what I need to find on the API, Idk how to look for what I need
yeahhh, I assumed that
start by looking through the docs
Gonna tell people to use nonexisting SMODS function 
also does your tarot really need a rarity? 
seems like it would break a lot of things unless you give all other tarots rarities too
Mod cross compat gonna be hell unless you're somehow able to give them a default rarity
saving this
that was me, you right you right
Kinda why I wondered on allowing handling of “no rarity” as if it was a rarity.
But idk that would work cleanly, and I still have god knows how much more to annotate.
uh
the simplest solution i can think of is this
introduce a default bool to rarities and assume only one rarity for an object type has it
then just use that when there's no rarity
maybe that's a bit backwards and the object types should have a default rarity instead
hm, I'm seeing the function for always_scores in the smods code, but I'm not entirely sure what i'd need to do in the hook in order to make it seal compatible
I looked through a lot of this, I may have missed it but how do I modify jokers? As in making them holo or poly?
I didn't see much in Jokers, Edition, Rank, and others
....
0.5 steps ahead of you
you sent that just as i pasted the link in smh
yeahhhh but its before so I win 

to check if it works, do I litterly just have to to go in the game and pray I see it 😭
Nah just ship it and hope it works
unfortunately
nah we have debug tools for that
They probably meant see in collection
ion think so
a coders best tool is a prayer 🙏
that doesn't confirm if it works, it just confirms if it's there
eyea
SMODS.Joker{
key = 'j_calibri',
loc_txt = {
name = 'Calibri',
text = {
'Played {C:attention}face cards{}',
'are copied {C:attention}twice{} to Hand when hand size is 1',
},
},
atlas = 'Jokers',
rarity = 3,
cost = 3,
unlocked = true,
discovered = true,
blueprint_compat = false,
eternal_compat = true,
perishable_compat = true,
loc_vars = function(self, info_queue, card)
return {}
end,
pos = {x = 1, y = 1},
calculate = function(self, card, context)
if context.after and context.played_cards and #G.hand.cards == 1 then
local copied_cards = {}
for _, v in ipairs(context.played_cards) do
if v:is_face() then
for i = 1, 2 do
local _card = copy_card(v, nil, nil, G.playing_card)
return
G.hand:emplace(_card)
_card.states.visible = true
G.E_MANAGER:add_event(Event({
func = function()
_card:start_materialize()
return true
end
}))
table.insert(copied_cards, _card)
end
end
end
if #copied_cards > 0 then
return {
message = localize('k_copied_ex'),
colour = G.C.CHIPS,
card = self,
playing_cards_created = copied_cards
}
end
end
end
}```
you're right
Speaking of coding I still don't know why it. doesn't wanna copy the cards
that's because your condition always fails
there is no such thing as context.played_cards
when hand size is 1 🔥
im fucking stupid
most useful joker of all time
also G.hand is cards held in hand
I wish discord didn’t format code blocks like shit on mobile
not played cards
Me tooooo
What a pain to read
also what the return doing
i mean this one doesn't have syntax highlighting on pc either
I just kinda. copied the dna joker
I thought i've seen it with syntax highlighting before
At least it doesn’t wrap every line though
you're just returning in the middle of the function-?
It’s two screens long on my phone 😭
```lua
```
have I mentioned that I have 0 knowledge of coding and kinda winging it as I go
I don't know how to set that up, do I just drop the extracted folder into my mods folder?
yep
just make sure it isn't nested
You kinda need to know at least the basics of lua
Or rather programming itself
may I refer to https://www.lua.org/pil/contents.html
fair fair
wanted to make sure because I did that and this happened
sorry guys
Mods/Mods?
would you mind helping me with this? I'm still quite new to balatro modding (and lua, though i've learned a lot the past few days) so while I know what hooking is, I have no idea what i'd actually need to change about the function to make it compatible with seals
That is nesting indeed
Everything is nested wooooo
Maybe you need another nested Mods folder, surely that'll fix it
I'd suggest something like this
local smas = SMODS.always_scores
SMODS.always_scores = function(card)
if card.ability.seal and card.ability.seal.always_scores then return true end
return smas(card)
end
3 more mods folders will fix it
then you could put always_scores = true into a seal's config and this function will mark it as always scoring
the more "hardcoded" way would be to check for your seal directly
I see, thank you very much
this feels like it should be in smods directly
it would be nice if functionality was more universal between seals, enhancements, and editions, but obviously way easier said than done
we're a good step closer to that with better calc
I can see always scoring being a property of all 3
ooh, that's nice to hear
I've realized this would be inconsistent and if i add this always_scores should be on the seal directly and not the config
I'll throw stickers in the mix
True
sometimes I forget about stickers
I wasn’t really sure how should apply worked either when briefly looking at it last night
It has a lot of arguments 😂
i wish lua had clean optional chaining
imagine G.P_CENTERS[card.edition?.key]?.always_scores
won't you get nil in the index there if it has no edition
Idk if that's a problem in lua
it has a 3mb compiler chill
odd
just tell me what i did wrong ATP
local tarotCard = SMODS.Consumable({
key = "tarot_card_joker_effect",
set = 'Tarot',
loc_txt = {
title = "Balance",
description = "50% chance to turn every joker polychrome, 50% chance every joker is destroyed"
},
unlocked = true,
discovered = true
})```
If you need more tell me
I DIDDDDDDDDD
But I forgor
no need to space wall me
so I make my thing
loc_txt = {
name = 'Balance',
text = { '50% chance to turn every joker polychrome, 50% chance every joker is destroyed'}
}
You will have a very long line but yes
even after changing that, didn't work.
I swear if I see that read the docs gif
split the lines in the description as
"line 1",
"line 2",
"line 3"
yeah, but that wouldn't change my issue 😭
Putting what is 5 lines ingame into one line of code just feels extremely wrong
Referring to this
thats it, entire paragraph on one line
you're right, but I didn't want to make that block even longer
it's already more than a full page at normal scale
What's your Entire code
-# not sure who left this outdated info here, that's no longer in use for anything
not much changed, there WILL be errors
local tarotCard = SMODS.Consumable({
key = "tarot_card_joker_effect",
set = 'Tarot',
loc_txt = {
name = 'Balance',
text = {"50% chance joker will turn polychrome", "50% chance every joker is destroyed"}
},
unlocked = true,
discovered = true
})
tarotCard.in_pool = function(self, args)
return true, { allow_duplicates = true }
end
--ignore this I WILL READ THE DOCS
tarotCard.use = function(self, card, area, copier)
local jokers = SMODS.GetAllObjectsOfType("SMODS.Joker") or {}
if #jokers == 0 then
SMODS.DisplayMessage("No jokers available.")
return
end
if math.random() < 0.5 then
for _, joker in ipairs(jokers) do
joker:set_edition("polychrome", true, false)
end
SMODS.DisplayMessage("All jokers are now polychrome!")
else
for _, joker in ipairs(jokers) do
joker:remove_from_deck(false)
end
SMODS.DisplayMessage("All jokers have been destroyed!")
end
end
why are the functions outside the constructor 🤔
Probably using cryptid as a reference 🙃
Oh god really
I said ignore it 
even cryptid doesn't do that 
Pushing aside the horrid chatgpt code, what do I need to manually fix to get it registering properly 😭
oh yeah i was also using chatgpt-
0.9.8 things did
Remove all the useless code for now, only keep the SMODS.Consumable part
what are units in ui size? is it relative?
alr
Does chatgpt even know what balatro is
no, I had to "teach" it (it didn't work)
local tarotCard = SMODS.Consumable({
key = "tarot_card_joker_effect",
set = 'Tarot',
loc_txt = {
name = 'Balance',
text = {"50% chance joker will turn polychrome", "50% chance every joker is destroyed"}
},
unlocked = true,
discovered = true
})
thats all of the code I am using
honestly I've no idea
ima sleep and figure out tomorrow, thank you guys for a bunch of help 
(I have no idea how im going to figure it out)
"hola" (first thing I thought of)
that should be fine
are dependencies required?
No
alr good
{
"id": "gambling",
"name": "Gambling",
"author": ["Hallowed"],
"description": "adds stuff",
"prefix": "hola",
"main_file": "main.lua",
"priority": 0,
"badge_colour": "FF230B",
"badge_text_colour": "FF230A",
"version": "1.0.0",
"dependencies": []
}
this is my json
Idk everything looks fine
did you try changing the key of the consumable to something else
I doubt it'll do anything but I'm out of ideas
also I assume you got rid of the nestsd Mods foldrr right
yeah did that
and changing it didnt help
And I assume you've restarted your game since changing it
yes
wait huh??
I changed set to "spectral", why is it tarot?
have you been saving your changes
yes
maybe i'm editing the wrong main.lua somehow
Are you editing a different file?
probably
for the love of Photochad can you PLEASE change either the banner colour or the text?!
I somehow DUPED the folder then edited the wrong one........
Yayyy
-# no
nowwww how do I change the image?
(only spectral for test)
im going to... read the docs
I need help 
is it "set_sprites(self, card, front)"
wdym? I just want it to be my custom picture
you need to make an atlas
like from fortnite STW?
An atlas from read the docs
ima sleep and do this tomorrow
didn't you already say that like half an hour ago
yeahhhhhh
buts its 3:00am now so the spooky monsters will get me if I don't sleep
Which one looks better?
OK, right side it is.
How hard it'll be to implement these? And just in general how complicated it is to add new seals?
Adding seals is fairly easy
Green seal doesnt look complicated (can peek at hook's code), but black seal does look interesting
They’re both fairly straightforward
Is hook some sort of a mod?
can u link it?
Now it looks like this.
isnt hook just the boss blind?
The hook is a lua technic,
calculate = function(self, card, context)
if context.before and context.cardarea == G.play and #G.hand.cards == 1 then
G.E_MANAGER:add_event(Event({
func = function()
local copied_cards = {}
for _, scoring_hand in ipairs(context.scoring_hand) do
if scoring_hand:is_face() then
for i = 1, 2 do
local _card = copy_card(played_card, nil, nil, G.hand)
G.consumeables:emplace(card)
card:add_to_deck()
return true
end
}))
end
end
end
end
end```
just wonderin, is this any better?
that message was referring to the hook boss blind, i'm fairly sure
though that's the wrong one, for the green seal, you'd wanna take a look at the code for the serpent boss blind I think
true,
Series of train wreck
with draw_from_deck_to_hand
small question about that. did you find where in the code was the problem?? i'm trying to fix it but it's not easy for me
hello again. Is there a way to check if a card is negative?
Search across the entire mod for edition = and you’ll find it
card.edition and card.edition.key == 'e_negative'
do i just replace the self.edition = self.edition or {} by self.edition = self.edition or nil or is that not at all the problem
If Im making a joker that converts to next/previous suit, what would be the correct list to reference if I want to account for custom suits
this one doesnt seem to be correctly ordered
i dont think suits are ordered
this one ain't ordered at all
SMODS.Suit.obj_buffer is what you need, possibly in reverse
It will need to check it’s not nil where you see the something.edition.type
how do i do the set_edition thing for custom editions? All of them work except for the last one
is fg your mod prefix?
nevermind, I am a bit stupid.
the other dev named the edition 'Polished' instead of 'polished'. It is fixed now.
sorry but i think i'm just not used to lua. i do not know what to change i'm very sorry but could you please explain exactly what you did? thanks a lot :(
I haven’t changed it as I don’t use Saturn
in the ui code, is there a heuristic for how long 1 is? is it a multiple of pixels or something?
Which format looks better?
right cuz its 1 line shorter
The break shouldn’t be between the number and the counter
But the left is better imo
Unsure on the need for a reminder of what is odd or even too
how else am i supposed to know what 7 is
Yeah, that being said,
does anyone know how to make a custom info_queue entry?
Yes
Let me grab code example
Oh hang on all my custom tooltips use a custom function
I’m pretty sure if you just do {set = ‘Set’, key = ‘key’} it’ll pull it from the relevant place in your loc table
And how do I do that without making something occupying collection pages?
Are you using a localization file?
Currently no. Am looking for a temporary solution.
I do understand that putting it in localization files is the long term solution though, just haven't bothered to set them up yet.
need to use process_loc_txt then
As in, info_queue[#info_queue+1]={process_loc_txt={}}?
no no, the function
end```Like this?
no
its a function that adds stuff to the loc tables
I dont remember how to use it though becuase loc files are infinitely better
and have been the standard use for months
OK, loc files it is, then.
ok i fixed the saturn thingy, just used the old-calc version of smod
that worked for some reason
Because better-calc is "breaking change" which leads to bugs if not modify mod
this is more of an issue with saturn doing something really weird
Umm...
why is it 22
because Twins
but its an even number 😭
It's meant to be side-by-side with this one.
I personally have no reason to be biased toward either of the twins.
might need a specific_vars arg, I dont remember
love it when things just work first try
-# it was reversed yeah
What is Badge Color?
color of the seal perhaps
its the colour of the badge
the seal itsefl?
would it affect png I use?
hm
the little bubble on the tooltip that tells you the name of the seal
it has nothing to do with your image
understood
How do I simplify this with SMODS utility functions?
I was glaring at this but didn't feel like getting what I want.
baladrone mentioned 🔥
What did you use to create that more dynamic flipping animation? card:flip() doesn't have a shaking animation like that
which timing context should be used for black seal? After?
this mb?
so I came down to this but I have no idea where to look for the function which forces the card to score
Splash Joker?
:juice_up([size scale],[rotation scale])
Oh so they're pairing both flip and juice_up?
You’d need the before context, not the ending ones
I use this utils
cs_utils.flip_cards({target})
cs_utils.unflip_cards({target})
-- Uses game Flip Cards logic
function cs_utils.flip_cards(table, trigger, delay)
for i=1, #table do
local percent = 1.15 - (i-0.999)/(#table-0.998)*0.3
G.E_MANAGER:add_event(Event({trigger = trigger,delay = delay,func = function() table[i]:flip();play_sound('card1', percent);table[i]:juice_up(0.3, 0.3);return true end }))
end
end
-- Uses game Unflip Cards logic
function cs_utils.unflip_cards(table, trigger, delay)
for i=1, #table do
local percent = 0.85 + (i-0.999)/(#table-0.998)*0.3
G.E_MANAGER:add_event(Event({trigger = trigger,delay = delay,func = function() table[i]:flip();play_sound('tarot2', percent, 0.6);table[i]:juice_up(0.3, 0.3);return true end }))
end
end```
like this?
btw I havent found any code related to Splash Joker
wtf
splash doesn't have a calculate function
its just hardcoded into how hand scoring is determined
where should I look then?
in the game's source code, and get ready to do a lovely patch
?
what is lovely patch?
and also I thought I alredy was looking into the source code
the .toml files inject code in specific parts of the game's code (In lovely folder in baladrone if you're still referencing that)
it also does lovely patches
hii i am trying to make a joker similar to mr bones that saves u one time before destroying itself but can't get it to remove itself
Can I add seals without that scary lovely patch?
yeah but if you wanna do anything like splash you're gonna probably need to
depends on functionality of the seal, for the black one im afraid you need to
Also where did you guys learn so much in depth stuff about Balatro modding?
by cross-referencing other mods lol
actually wait it might be possible to do some jank
so SMODS enhancements have an always_scores property
That's sounds like it'd very long and inefficient
you might be able to do something very roundabout to trigger this from a seal
but i doubt it's easy, straightforward, or sane
You just need to do table.insert(scoring_hand, card)
if you're looking for a specific thing it can be helpful
It’s very easy
Yeah for sure
Like where did you get that from 
you're joking
I doubt
I just know how the scoring works
I bet this guy's smart smh
I rewrote the scoring last month so I understand it pretty well
im sorry
The elder has spoken
is thereeeee x_chips?
I just know how to do a lot of stuff because I’ve done a lot of stuff/written a lot of stuff for smods
before balatro?
when the seal code runs wouldnt it be too late to add it to scoring hand?
General programming wise of course, but that doesn’t help for the specifics oh balatro
Not in context.before
It might miss a couple of effects
There’s a more thorough way of doing it but this should work well enough
was curious to try and it indeed works, but if you plan to make it affect the hand played you'd probably need patches
where in balatro's source code can i find the code for "card_eval_status_text" function?
common_events.lua
Is this how you add custom seals?
its just neither seal or its respective spectral card show up
did I miss something?
I didnt touch it
how do I import them?
this is how I did it for my seals at least
-- List all seals files here
local seal_files = {
"lift_seal",
"rank_seal",
}```
```lua
for i = 1, #seal_files do
NFS.load(SMODS.current_mod.path .. "/seals/" .. seal_files[i] .. ".lua")()
end
game crashes now :(
does this patch work? (it adds x_chips)
theres talisman that adds x_chips afaik
wait, so if i have talisman in my mods folder then i can just use that without a patch?
I think so but I havent used it personally
it also uses nebula deck png for some reason
and crashes when I hover over it
steamodded itself has added xchips
no more need for mods to implement it
oh thats neat
o
can you send your code
nice
just have a minimum smods version
no idea why this is happening but it is pretty funny ngl
My assets
you didnt quite import it like I sent earlier
?
in seal_files you need to put the name of the files, and your file is called "blk_seal" not "black"
also youre importing consumables while looping the seal files
.
".." is string concatenation
If I had a nickel for every time someone misinterpreted an automatic import script, I'd have two nickels. Which isn't a lot, but it's weird that it happened twice
like this?
This is a bad import script
the second load should be outside the for loop
how could we improve it
also you should fix that indentation

I took it from cardsauce
Use SMODS.load_file
other than that its fine?
They should be wrapped with assert too
for k, v in pairs(Ortalab.load_table) do
if v then assert(SMODS.load_file('objects/'..k..'.lua'))() end
end
I'm personally also a fan of just auto-loading every lua file in a given directory but I understand if some people don't want that
That’s for a table where keys are either equal to true or false
hmmm how would one do that?
this is what I use
local subdir = "cards"
local cards = NFS.getDirectoryItems(SMODS.current_mod.path .. subdir)
for _, filename in pairs(cards) do
assert(SMODS.load_file(subdir .. "/" .. filename))()
end
what would be the downside
Can’t toggle things
Is everything correct?
fair
Do you understand what a for loop does
this worked for me
for i = 1, #seal_files do
if seal_files[i] then assert(SMODS.load_file('seals/'.. seal_files[i] ..'.lua'))() end
end```
same for this
I dont understand what Im doing wrong :(
If I flip a scoring card, does that prevent it from scoring?
do I just copy this in?
straight up
It should be like this
-- List all seals files here
local seal_files = {
"lift_seal",
"rank_seal",
}```
```lua
for i = 1, #seal_files do
if seal_files[i] then assert(SMODS.load_file('seals/'.. seal_files[i] ..'.lua'))() end
end
now game crashes when I hover over the seal in collection
and this bug returned
do you have a localization file
yes
and did you set the name and desc of the seal correctly
not yet
jokers work without it
you should probably do that
what is the prefix for seals?
in localization file
Go and watch them again
it appends "_seal" at the end of the key (in localization only apparently)
so like I should type blk_seal_seal?
Im currently on a 2 week vacation and it's already ending tomorrow, so I dont think I have any time or motivation left for that
Rare or Uncommon?
rare
whats prefix here?
actually hold on there are so many uncommons that have a x3 conditional 🤔
your mod's prefix
maybe uncommon works better than I thought
Seal localization goes in ["Other"], not ["Seal"]
keeps crashing
Sorry guys for bothering you too much I'm primarily an artist and have nothing to do with coding, just got into it while I had time on vacation

Is there a way to give yourself a specific achievement for steam?
I have completed the requirements of an achievement, and a bug is preventing it from triggering.
SteamAchievementManager on Github
depending on what the achievement is, you probably just need to win another run?
the newest addition to my jimbo collection
nope it's fully bugged
you're a lifesaver 
how so
this is the progress so far
but still crashes the game unfortunately
+adjusted directory
how can i check how many negatives the player is holding
I'm trying to make a Boss Blind that randomly disables 1/4 of the full deck. Anyone have any ideas as to why none of the cards are getting disabled?
Loop through G.jokers and check each edition
also how do the legendary jokers do the two art thing
thanks
The floating heads are referred to as "Souls"
they took their souls? /j
that's what the soul_pos variable in the config is
ohhh
does the soul art have to be below it or is soul_pos where the soul art is
or where it will be on the card
if that makes sense
soul_pos is where it is on the spritesheet
yep
Keep in mind though it must be in the same atlas as the base card since you can't change it for the soul specifically
trying to make a joker that does basically the same thing as the boss blind that discards your cards. I got the cards highlighted to discard but I'm not seeing G.FUNCS.discard_cards_from_highlighted fire up to actually discard them here:
local any_selected = nil
if context.before and not context.blueprint then
G.E_MANAGER:add_event(Event({ func = function()
for i = 1, #G.hand.cards do
if G.hand.cards[i] then
G.hand:add_to_highlighted(G.hand.cards[i], true)
any_selected = true
play_sound('card1', 1)
end
end
if any_selected then
G.FUNCS.discard_cards_from_highlighted(nil, true)
end
return true
end }))
end
ngl, it makes total sense that hologram uses a shader for the hologram effect and the card is just super boringly gray
also... is the card selection limit simply a variable I can change? would be helpful if it is
shouldn't the local any_selected be in the manager
not sure if declaring it anywhere above changes anything
okay it's technically better for it to exist within the event
There’s a dedicated card debuffing function that gets called after set_blind I believe and is undoing all your hard work. You should try using that instead
I saw mention of that on the docs but nothing in the API methods section. How would I define that?
Same as set_blind I believe, just with a different name and parameters list
Unless smods has changed some stuff
alr thank you
What's the best way to iterate and test a mod? Right now I've just been pushing changes to GitHub, downloading the ZIP, then unzipping it into the Mods folder, but that process takes a while and means I have to redownload it for each test.
I just put the github project in my mods folder
^
works like a charm
just have the area you're working in be the mods folder itself, save your code then restart the game and you're golden
I cant imagine how much time you wasted doing that 😱
I only started making a mod as of last night, so thankfully not too much lol
phew
Would I just do like git checkout within the Mods folder?
Tbh I prefer non-console, I'm just not sure how else to do it
oh just move your project into the mods folder
yeah, I have my visual studio project in the mods folder so I just do ctrl + s to save and open the game to test the changes
but it's on GitHub remotely so I don't have it stored locally
ahhhh
you're gonna need git clone
tbh I recommend getting the desktop app https://desktop.github.com/download/
Might consider getting the desktop version in the future, for now though I did git clone and it worked perfectly. Thank you guys
is there a way to detect ending a booster pack, even by "chose the card limit so it automatically closed", not just skipped?
doesn't sound like a context that currently would exist, mostly because in 99% of cases the "on open booster pack" context is sufficient
you could add your own though
bump
I dont remember if I buuilt it into smods or ortalab 🤔
got what I was hoping for another way
ok yeah I have no idea what the param list would be here
Ooohhh you were just looking for a "while in booster pack", that makes more sense. Yeah using G.STATES would work for that
hey does anybody know how to make a joker delete itself (like mr.bones) ? tried this but didn't succeed
card:start_dissolve()
How would i go about coding only face cards? i have one mod i got from nexus to mess around with(the deltarune one thats supposed to only change the face cards of the heart K,Q,J).
This is the code i used to replace ALL player cards, but it (not so surprisingly) doesnt work for a mod that only changes specific cards.
Does anybody have the code that DOES work for that?
you should also do card:remove_from_deck()
if context.before and context.cardarea == G.play and #G.hand.cards == 1 then
for _, scoring_card in ipairs(context.scoring_hand or {}) do
if scoring_card:is_face() then
local success, err = pcall(function()
for i = 1, 2 do
local _card = copy_card(scoring_card, nil, nil, G.hand)
_card:add_to_deck()
G.hand:emplace(_card)
_card.states.visible = true
_card:reset()
G.E_MANAGER:add_event(Event({
func = function()
_card:start_materialize()
return true
end
}))
end
end)
end
end
end```
After having a personal breakdown and asking chatgpt multiple times can anyone pretty please help me with why this doesn't copy the card
that mod from nexus is really really old
maybe stop asking ChatGPT for coding advice
hi aure a question, is there a function that does both remove_from_deck and start_dissolve like SMODS.add_card does both the emplacing and add_to_deck
THANK YOU SO MUCH
not at my PC rn, but does start_dissolve not call remove_from_deck already?
when is this supposed to trigger?
before?
why it seem that it working from now or is it just visual ?
before?
no like
the Deltarune one? i figured as such, it shows on the ingame mods, but it just doesnt replace the actual textures
under what conditions
when there is only 1 face card played, copy said face card 2 times and put it to the deck
oh yeah it does my bad
disregard that
then why are you checking the amount of cards in G.hand?
that's the cards held in hand
not the played cards
np np i understand now no need to remove because desolve calls the method already
what's the played cards again?
thx !!
you've even used it in your code, no?
context.scoring_hand
right, I forgot
you need to stop mindlessly copying things you see and from ChatGPT and actually learn some coding 
honestly I just felt shy asking y'all so much ;-;
there's no need to be
do I check the like.
if the alternative is ChatGPT 💀
that's assuming you don't mind there being extra unscored cards
else check #context.full_hand == 1
ChatGPT + modding is the worst possible combination.
Balatro modders finally find something worse than copying the source code
I'm trying ok
theres nothing wrong with trying, but theres no reason to ever trust what an AI says 
cough google cough

-# i cant tell if thats agreeing or disgareeing with me, im stupid
I think AI is so much worse here knowing chatgpt doesnt know what balatro or smods code looks like
yeah literally
theres just not enough data to scrape to get a """"good"""" response
True
All I've gotten from Googling is popular Balatro mods
I was talking about the AI shit that Google was doing
tbf here you can only peek at the smods docs or other ppls mods
Oh lmao
looking at popular, well written mods is probably the best place to start if you look at them alongside smods documentation
fr fr
and then just asking questions here when you get stuck
What do I write to just get the name and description thing to show? :(
there are plenty of us who know what we're doing and are happy to help
yeah I solved the problem I posted a while ago by just looking around
the little text to appear when hovering over something?