#💻・modding-dev
1 messages · Page 683 of 1
currently my colors are working minus the inner text, did I tried a few things and this gets it to not crash the game but no color
whenever i do i just break some shi, i aint trying to lose progress
ight I think this should work
git version control
trial and errors just coding lmao
i've legit spent 6 hours today trying to line up a single UI element
git has been a life saver when I frick things up
its still not lined up 😭
balatro ui my loathed
its not even the UI really
should I just be able to do C:white instead of V:2?
its the moveable element crap
odd, i'm not sure at this point. that seems correct
but yes you should be able to do C:white
if you don't mind, can i take a look at your drawstep and where you define the canvassprite? i know it's for the joker jam so feel free to censor as much as you need
game crashed when i tried,
c white works, how would I go about checking why V:2 wasn't working for future refrence tho?
if you were going for white then the color was just wrong, hex color #000000 is black
oh LOL
now that's the key part of trial and error, the error should help you identify what to fix for the next try
i cannot code
classic game developer completely forgetting which way the hex colors go lmao
technicaly its a bit more complicated cuase its doing stencil shenangains, but I need the stencil to be in the right place first ;-;
sent
take out the prep_draw call
image gets drawn in the top left corner of the screen and is static
it sets things up for balatro UI's auto-scaled stuff, which you don't want for drawing to this canvas
the reason it gets drawn in the top left is you're not actually drawing to the canvas. you need to either call love.graphics.setCanvas to point it to the canvas that's attached to the canvassprite, or just call canvas_object:renderTo for all the rendering functions. whichever's more convenient
ooooooooh
thx
that explains why one of my earlier setups worked but had a weird paralax effect
you want it to be drawn static in the top left of the canvas because that'll be the top left of the card when the canvas is then rendered on the card later lol
okay lemme go boot up balatro and fix this lol
tysm
actaulyl imma do this tmr i should eep
gn
no problem, sleep well
how do you clone a cardarea, ive been struggling to figure it out
is there a way I can make a card "use" a tag?
Like, an example might be: "This jokers consumes Juggle tags to gain +1 hand size" as an example
how do i make the odds on a jokers text go down when an oops is obtained, i.e from 1/2 to 0/2. because i have one effect that should get increased, and the other should decrease accordingly. i feel as though theres a simple way to do this but i just cant think it rn
if context.tag_added and context.tag_added.key == 'tag_juggle' then
return {func = function()
G.E_MANAGER:add_event(Event({
func = function()
context.tag_added:remove()
G.hand:change_size(1)
return true
end
}))
end}
end
how do i add custom badges for cards
For a specific card you would use the set_badges function, for all cards you would patch G.UIDEF.card_h_popup
Thank you! I didnt know about tag:remove
Is there a way I can use the tag-used animation?
I noticed tag:yep does an animation kind of effect, and I might end up using that, but,
I was also wondering if I could apply the animation without removing the tag if I so desired?
stop_use()
G.E_MANAGER:add_event(Event({
delay = 0.4,
trigger = 'after',
func = (function()
attention_text({
text = message,
colour = G.C.WHITE,
scale = 1,
hold = 0.3/G.SETTINGS.GAMESPEED,
cover = tag.HUD_tag,
cover_colour = G.C.GREEN,
align = 'cm',
})
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)
}))
That.. is beautiful, thank you so much
is there a way i can remove the sell button when its in a specific card area
I am trying to create a joker that has a 1/2 to double mult, and 1/2 to half mult. the problem is, is after a player gets oops, they both display as 2 in 2 which is wrong due to the fact that only one of these can trigger and its always double. how do i make it so the half mult goes to 0/2 after obtaining oops?
Reword it as 1 in 2 chance to X2 Mult, otherwise X0.5 Mult?
can neither of the joker effects trigger?
Is there a way to register a value to be saved with the run?
specifically just trying to save a value I have set in "config" in some of my tags, but, just curious in general, if I have any global variables I want to save, like anything I'm keeping track of during the run
Everything serializeable set in G.GAME is saved
is there a way to check how many joker slots a card takes up
im trying to figure out how many slots a highlighted group of jokers are taking up
1+card.ability.extra_slots_used?
thank you!
Ooh awesome ty ty
it doesnt work 😭
Code?
G.FUNCS.worm_can_release_colony = function(e)
local tot_slots_used = 0
for _, joker in ipairs(G.specificcolony and G.specificcolony.highlighted or {}) do
tot_slots_used = tot_slots_used + 1+joker.ability.extra_slots_used
end
local can_use = (G.jokers.config.card_limit >= tot_slots_used + #G.jokers.cards) and (#G.specificcolony.highlighted > 0)
e.config.button = can_use and 'worm_release_colony' or nil
e.config.colour = can_use and G.C.MULT or G.C.UI.BACKGROUND_INACTIVE
end
G.specificcolony is a cardarea
yeah im just a bit stupid holy how didnt i think of this. also epic mod btw
im currently rewording jokers in my mod that im tryna create, so this makes things alot clearer
how do i use info_queue[#1116390750314307698_queue + 1] in the loc_vars to display a string/ credit someone? i want it to show a name in a tooltip and i cant figure it out
It feels like the Booster Packs I've made aren't deciding jokers based on rarity... idk what to do!!@@
What is your code?
SMODS.Booster { key = 'jam_booster_1', loc_txt = { name = 'Jammbo Pack', text = { 'Choose {C:attention}1{} of', '{C:attention}2{} {C:red}Jambatro{} Jokers' }, group_name = 'Jambatro??' }, atlas = 'jam_boosters', pos = { x = 0, y = 0 }, draw_hand = false, cost = 5, discovered = true, weight = 7, pools = { ["Jamboosters"] = true }, config = { extra = 2, choose = 1 }, create_card = function(self, card) return {set = "Jambatro", area = G.pack_cards, skip_materialize = true, soulable = false, key_append = "jammbo"} end, }
And what’s the issue?
It feels like rarity is not accounted for when I open the packs like I always get rares n stuff
What smods version are you currently using?
I am pretty sure things should be working properly but I will investigate
Can you share where you set up your pool?
The joker pool?
Yup
SMODS.ObjectType({ key = "Jambatro", default = "j_jam_greg", cards = {}, inject = function(self) SMODS.ObjectType.inject(self) end, })
Anyone know why this isn't working?
if context.selling_self and card.ability.extra.currounds >= card.ability.extra.maxrounds then
local chosen_joker = pseudorandom_element(G.jokers.cards, 'randomseed13')
Card = chosen_joker
Card:add_sticker('eternal')
end
Do you have any optional features on too?
Who are you replying to
You
Idk what you mean by optional features
Do you do SMODS.current_mod.optional_features anywhere to turn on thins like quantum enhancements
No
Okay I will have a look today and get back to you
Thanks
overriding global Card...?
local chosen_joker = pseudorandom_element(G.jokers.cards, 'randomseed13')
chosen_joker:add_sticker('eternal', true)
Yeah wasnt my go to but I tried putting the local variable there and it wasnt working either so I tried exactly copying the wiki to see
I had false instead of true in the bypass so maybe that was it (when I tried the local variable)
yep, without bypass_check it has to pass a 30% chance roll
the sticker API is still a tad bit wonky tbf
I thought it related to sticker_compat variables on jokers
we're looking to refactor it at some point
Swag as
it also does that
No, without bypass_check it doesn't work ever because should_apply is false for vanilla stickers, and it has to exist for it to add the sticker.
oh right, shop jank
love that
oh while i'm here, is there a quick way to make it avoid jokers with eternals already. Just remembered it should probably do that
what I said is true only for modded stickers
local eligible_jokers = {}
for _, v in ipairs(G.jokers.cards) do
if not SMODS.is_eternal(v, card) then table.insert(eligible_jokers, v) end
end
local chosen_joker = psuedorandom_element(eligible_jokers, 'randomseed13')
if chosen_joker then chosen_joker:add_sticker('eternal', true) end
additionally you might want to add a compat check in the loop
No, because it sets the bypass_roll input to true, so it doesn't check the roll.
yep, without bypass_check it has to pass a 30% chance roll
Yes, it does that without bypass_check being set.
pos = { x = 0, y = 0 },
atlas = "pinned"
}, true)```why doesn't this work 😭
Pinned is stored in card.pinned instead of card.ability.pinned, so it isn't drawn.
how do i get tooltips to display any text i want?? i have no clue how to get it working
like the things that popup next to jokers when you hover over them
like how a sticker with perishable shows what it does next to the joker its on
use an info queue
https://github.com/Steamodded/smods/wiki/Localization#loc_vars
yeah ik, i cant figure out how to add custom text into them
not the text of a joker or tarot, like text that i want, aside from creating a dummy joker
i cannot figure out for the life of me what im doing wrong
some :'s are missing because of copy and paste or .txt files being funky
it just shows as a blank box
ive looked at 3 different mods, and im doing what they are i think, and not getting it to work
the text is not a string
it is, its gone in the copy and paste
i mean this wont go in the description
thats just an arbitrary string in config
the way i understood it i thought that calling the card.ability string would make it appear
how would i get it there
i assume youre trying to add a tooltip with info_queue[#info_queue + 1] = {key = 'Krypton_Deadin5s', set = 'Other', vars = {card.ability.extra.Deadin5s}}
yes
but this creates a tooltip from the key Krypton_Deadin5s from localization files
under the category Other
i think my braincells just created my first thought
if this is the case, holy i was braindamaged
OH MY GOD IM DUMB AS BRICKS
ok i think it got it now
yippeeeeeeeee
oh I forgot to ask, do you have any other mods running?
so I don't have a canvassprite object, only a drawstep
I am 95% sure that your packs have never used rarity and that you pool is just one enormous set. You need to define rarities on your object types, or switch to using new and improved functionality from zeebee (it's a bit buggy, fix coming soon)
how do you check/set if a card has a shadow? (eg. glass playing cards don't have a shadow)
as per the shadow DrawStep, the following (self is a Card instance):
if not self.no_shadow and G.SETTINGS.GRAPHICS.shadows == 'On' and((self.ability.effect ~= 'Glass Card' and not self.greyed and self:should_draw_shadow() ) and ((self.area and self.area ~= G.discard and self.area.config.type ~= 'deck') or not self.area or self.states.drag.is)) then
(yes, glass card is hardcoded)
- if it wasn't obvious, you can hook
Card:should_draw_shadow()to change if shadow should be drawn
is there a variable that gets the boss blind requirement for the ante? I thought about using G.GAME.blind but that obviously only tracks the current blind. This is for a boss blind btw, so if there is a field on SMODS.Blind that has it that would also work for me.
i believe that's Blind.chips
but tbh I'd just use debug plus to eval Blind and read the table myself
I guess I should clarify that I mainly need it to pass through loc_vars for the description, so blind.chips isn't an option here
No
I'm currently trying to make it so that when my custom rarity "Whimsical" is on one of your jokers, the custom rarity "Evil" wont show up, but when you have a whiomsical joker nothing changes
SMODS.Rarity {
key = "evil",
default_weight = 10,
badge_colour = HEX('690404'),
loc_txt = {
name = "Evil"
},
get_weight = function(self, weight, object_type)
return weight
end,
disable_if_empty = true,
pools = {
["Joker"] = function(self,args)
for i, v in ipairs(G.jokers.cards) do
if v:is_rarity("zwp_whimsical") or next(SMODS.find_card("j_zwp_propeller")) then
return false
end
return true
end
end
}
}
the weight is at 10 for testing purposes
and the propeller joker is another joker that I want to have stopping evil ones but isnt whimsical
I still have zero clue whats going on
You got your return true in the for loop so it stops after the first joker
Do pools actually support functions?
given that pools contain mostly water, if you put a function in one, they will most likely short out and sustain water damage 
so thats a no
i actually don't know
dang
Hello Zarcheus.
i mean, it would have to be recieving true somehow
It looks like we both have some questions at the same time.
how can i get the blinds current skip tag and how can i use it to give the player the skip tag?
ive tried 'G.GAME.round_resets.blind_tags[G.GAME.blind:get_type()]' based on something a previous person asked but i cant seem to figure out what this actually returns and how i can use it to give the player the skip tag i want mid blind
Something lazy you can do is put in your joker objects with the evil rarity this function
in_pool = function(self)
if G.jokers and G.jokers.cards and next(G.jokers.cards) then
if next(SMODS.find_card("j_zwp_propeller")) then return false end
for _, joker in ipairs(G.jokers.cards) do
if joker:is_rarity("zwp_whimsical") then
return false
end
end
end
return true
end,
There's prob a better way but I've never messed with pools
that was my backup plan
This Zarcheus character is really pissing me off.
-starman, probably
im now having the issue of the rarity not being disabled once all jokers are out of it
unless im misinterpreting what disable_if_empty does
Noone will hear you scream Zarcheus.
I am not bullying anyone.
Especially Zarcheus985.
LSP says "Disables polling of the rarity if set to true if there are no available objects."
would that mean like, if I put no jokers into the rarity it doesnt show up or if I have all of the jokers in that rarity it wont show up
because I want to have the second one
I think it just means if you're polling from the empty rarity you won't get the default option?
I'm having an issue with quantum enhancments and a Joker I have that gains chips when a card is enhanced. (Quantum enhancements cause the joker to gain chips four times). Is this because of a QE bug or is there a way to prevent the chip gain when a card gains a QE?
calculate = function(self, card, context)
if context.setting_ability and not context.unchanged and G.P_CENTERS[context.new].set == 'Enhanced' then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chips_mod
return {
message = localize('k_upgrade_ex'),
colour = G.C.CHIPS,
}
end
if context.joker_main then
return {
chips = card.ability.extra.chips
}
end
end
ok, for some reason joker is still appearing when I have those cards
or when theyre out of the pool
Try adding and context.check_enhancement == false ?
What's your mod prefix and your rarity's key? add a print in the in_pool func joker loop that goes print(joker.config.center.rarity) to see what is exactly the name of the rarity just to see if it ain't a mismatch
The way quantum enhancements work is by using set_ability to change the enhancement for the other enhancements to calculate
I presume this is a steamodded bug
Since it should account for this
the jokers I made in the custom rarity are getting put out of the pool properly, but it's not removing the rarity from the pool of jokers that can appear, which makes the shop filled with jimbos
i worded my stuff poorly before
seems like whatever issues started in 1501 haven't been fully fixed yet. shame
Maybe disabled_if_empty is bugged? idk sorry
ok, thanks for your help
smods version?
i really hate being insistent but 🥹
i got a newer version of smods but disable_if_empty is still not working
SMODS.Rarity {
key = "evil",
default_weight = 0.15,
badge_colour = HEX('690404'),
loc_txt = {
name = "Evil"
},
get_weight = function(self, weight, object_type)
return weight
end,
disable_if_empty = true,
pools = {
["Joker"] = true
}
}
Do you have debug plus?
Can you run eval get_current_pool("Joker", "INSERT YOUR RSRITY KEY HERE PLS", false, nil)
Okay now this one eval local t = {}; for I=1, 1000 do local r = SMODS.poll_rarity('Joker'); t[r or "none"] = (t[r or "none"] or 0) + 1 end print(t)
hey eremel while you're here, do you have an idea on when a new release with properly working attributes will be released?
really cool feature
They already properly work 😭
the current release is broken in several ways, so there's another one coming your way soon
Today or tomorrow
ok nice thx
It looks like it’s working fine?
literally just got fixed
yeah because i literally just reported it 😛
VIP issue :p
wut
I used my mind powers to control N to implement the fix
we're not always this fast
the message changes depending on whether or njot I have an evil joker
which is another custom rarity
Isn’t that what you said it should do?
work faster!1!1!1!!1! /j yall doing god's work
does the high number mean iots not there?
No the number is how many times that rarity will appear if you picked 1000 jokers
im trying to make it so that when you have all the jokers in a rarity that rarity wont show up any more
ah
how do i make this happen
Sorry it totally flew by I'll give it a look rq
thank you
there are no jokers for it to pull from in zwp_whimsical
This is basically what you have to put
if context.setting_blind then
add_tag(Tag(G.GAME.round_resets.blind_tags[G.GAME.blind:get_type()]))
end
Not sure if this handle the orbital tag issue or not
jimbo
whats the orbital tag issue
but theres disable if empty
i try it out on an orbital tag see what happens
Basically there used to be an issue where if you just straight up add a tag, G.orbital_hand doesn't get set, meaning it's nil meaning it crashes
so wouldnt that make it stop jimbos?
im getting this error regardless of the tag type
lemme try something
Paste a screenshot of your code?
My game crashes because of the atlas I made for the joker heres the code:
SMODS.Atlas { key = 'pomni', path = 'pomni.png', px = 71, py = 95 }
can someone help me fix it?
nvm i know why it happened
???
uhhh
do you have debugplus installed
What's the crash?
Is your file named "jeej_pomni" ?
run this in the console
eval for key, _ in pairs(SMODS.Atlases) do print(key) end
yes
oh wait ib blind thats filedata
yeah whats your file named
and you have both 1x and 2x
Nwm, i fixed i put 1x and 2x folder insde other folder
originally the idea for the joker was to give you a dupe of the skip tag when you skipped so i think since it triggers after it gives you the tag the blind technically doesnt have a tag type anymore so it returns nil and crashes
the idea for the joker was a little boring in the first place so im gonna change it to a different condition

Replace the context check with context.skip_blind?
thats what was causing the error in the first place sorry
Oh oop
Your rarities are set up wrong then
SMODS.Rarity {
key = "whimsical",
default_weight = 0,
badge_colour = HEX('FF1AFF'),
loc_txt = {
name = "Whimsical"
},
get_weight = function(self, weight, object_type)
return weight
end,
disable_if_empty = true,
pools = {
["Joker"] = true
},
}
thats the zwp_whimsical rarity
Maybe save the tag's key (the long line without the Tag()) in your joker's config during context.ending_shop then when you skip call the tag from your joker's config?
Not sure if ending_shop is too early
the weight is not normally 0
but thats not whats breaking things
whats wrong with it
is disable_if_empty a thing?
Wiki and LSP says so
Saw a lovely patch use it too so ig
What about the in pool functions you’re using to control the pool
Ye
SMODS.Joker {
key = "whimsyman",
atlas = "placeholders",
pos = {
x = 0,
y = 0
},
rarity = "zwp_whimsical",
in_pool = function(self, args)
for i, v in ipairs(G.jokers.cards) do
if v:is_rarity("zwp_evil") then
return false
end
end
for _, playing_card in ipairs(G.playing_cards or {}) do
if SMODS.has_enhancement(playing_card, 'm_zwp_whimsical') then
return true
end
end
return false
end,
}
thats the only whimsical joker
An the evil joker?
SMODS.Joker {
key = "evilman",
atlas = "placeholders",
pos = {
x = 0,
y = 0
},
rarity = "zwp_evil",
in_pool = function(self)
if G.jokers and G.jokers.cards and next(G.jokers.cards) then
if next(SMODS.find_card("j_zwp_propeller")) then return false end
for _, joker in ipairs(G.jokers.cards) do
if joker:is_rarity("zwp_whimsical") then
return false
end
end
end
return true
end,
}
What do you get running this code on a fresh run
That looks less fine
and if I buy the evil card it says the same thing as this
Is your mod on GitHub?
Yeah I’ll try take a look this evening
my balatro mod. Contribute to Zarcheus3/ZacsWhimsyPack development by creating an account on GitHub.
end``` i have this so far how do i check if any of the jokers have any stickers on them like eternal or rental or perishable
there's no good way to check for any sticker, especially if you want to take into account other modded stickers
then the link i gave you answers that question
yep, happy modding
one more question i dont know if the link you sent has this but is there a way to remove the stickers
card.sticker_key = nil iirc
its the same way you check if it has the sticker
but you set it to nil instead of checking for true
card.ability.sticker_key = nil
ohh that makes sense
i was checking for it like this though G.jokers.cards[i].ability.rental
hmmm
but i might switch it to the way you sent
G.jokers.cards[i].ability.sticker_key == _____________
card:remove_sticker("sticker_key")
iirc
sorry but what does iirc mean
if i recall correctly
oh ok
difference between this and directly removing the sticker value is that values related to the sticker will not remain
e.g. perishable round counter
oh didn't know that existe
so i can check for perishable then remove perishable by putting card:remove_sticker("perishable")
?
yea
yeah as long as you got the card object
ok
[CARD OBJECT]:remove_sticker("key")
also if you want to reliably remove all modded stickers you can do
for _, sticker in ipairs(SMODS.Sticker.obj_buffer) do
if card.ability[sticker] then card:remove_sticker(sticker) end
end
where card is again a given card object
im not that good at modding but what does in ipairs do
loops over every element of a table
oh ok
every element with a numerical key in order*
theres pairs and ipairs for this, difference being that ipairs only does integer indexes but always does so in order
yeah
ipairs will loop index 1, 2, 3, etc until it runs into a nil, pairs does everything in an arbitrary* order
not actuall arbitrary i think but its based on the order values are stored in memory? which isnt something you really have control over
it's undefined behavior iirc
i did this but with multiple rentals its only removing one each hand played for i = 1, #G.jokers.cards do if context.joker_main then if G.jokers.cards[i].ability.rental then return { G.jokers.cards[i]:remove_sticker("rental"), message = 'Rental', colour = G.C.RED, } end end end
returning immediately ends the current function
also i recommend you put the loop inside of the context check rather than the other way around
ok but how do i not end the function immediantly
store a local value that gets set to true if any rentals are found, then return after the loop if that value is true
if context.joker_main then
local rent = false
if G.jokers.cards[i].ability.rental then
return {
rent = true
message = 'Rental',
colour = G.C.RED,
}
end
end
end``` something like this
no
if context.joker_main then
local rent = false
for _, c in ipairs(G.jokers.cards) do
if c.ability.rental then
rent = true
c:remove_sticker("rental")
end
if rent then
return { message = 'rental', colour = G.C.RED }
end
end
the ipairs loop is essentially the same as the previous one
except c replaces G.jokers.cards[i]
am i able to just remove the return
you can also do that yeah
final question how do i detect when the joker is sold
context.selling_self
you might want to know about https://github.com/Steamodded/smods/wiki/Calculate-Functions
im new to making decks but how do i set the hand size equal to the size of the deck ``` SMODS.Atlas{
key = 'SD',
path = 'Rainbow.png',
px = 71,
py = 95
}
SMODS.Back{
key = 'SD',
atlas = 'SD',
pos = {x = 0, y = 0},
config = {
hands = -3,
discards = -3,
dollars = 0,
hand_size = __
},
apply = function(self, deck)
end
} ``` i have this right now
Do you want the hand size to always be the same as the amount of cards in the deck or only at the start of the run?
the whole run
but i actual just figured it out
i had to use calculate to constantly set the hand size
is there a thing i can call to get the chips scored from the current hand
SMODS.calculate_round_score()
thank you somethingcom515 seals on ever
i am encountering the nil orbital tag issue is there a remedy]
.
how do you change the joker that shows when you boot up the game into another, modded joker (or a pool of jokers maybe?)
you know when jimbo shows up and all the playing cards get sucked into him
i mean that one, not the main menu
ah
there's not a defined way to do that yet, but if you look through the vanilla code you can probably find the right thing to patch
alr
also,,, how do i make my custom packs stop saying "ERROR" ?
is the loc_txt supposed to be like this
that is not how tables are formed
table?
i cant code lol
this is a valid way to make a table actually
its ugly as hell but it is valid
this is not valid syntax
wait nvm i didnt read,
change loc_txt = {Item Pack} to loc_txt = {
itll still say error,
thats how it looked last time
remove group_key
just this part or the whole thing?
the whole line
alr
works now! thx
is there any way to make a boss blind not affect the background
The non-boss blinds in my mod are making the ante go up like boss blinds, how can this be fixed
There isn’t any support for non boss blinds at the moment
Could probably add some spaghetti code by using the ante code subtract 1 instead of adding one when the boss is defeated
If it triggers at the same time shouldn't really be noticeable
That it's adding then subtracting 1
how do i make a jokers shake, like invisible, to signify its ability is ready?
Idr the exact name but look for a juice_until function for reference
k
What
Are you saying every blind makes the ante go up by default but mods just have to work around it?
There are no methods within smods to have custom blinds not as a boss blind
Yes but it's not built into smods
ig he could consume that code to do what he wants tho
Trying to make a UI element similar to the poker hand nodes in the run info, but with a tooltip which uses loc_vars and text styling, but i can't figure out how to do that.
on_demand_tooltip doesnt satisfy my needs but the text im representing doesn't belong to a SMODS.Center and it also needs to use more than 1 color (so text styling akin to a card description) and DynaText doesnt seem to be able to do that
anyone know why this edition doesnt retrigger the joker its on?
For shaders, how would you get the screen width and height
this code works fine if i say if context.retrigger_joker_check and not context.retrigger_joker and context.other_card ~= self then instead of
if context.retrigger_joker_check and not context.retrigger_joker and context.other_card == self then,
but this retriggers all other jokers which is not what i want. anyone know wy?
i want the edition to retrigger JUST the joker its on
if (context.repetition or context.retrigger_joker_check) and context.other_card == card then
return {repetitions = 1}
end
trying to apply foil to selected cards, and this is what I currently got:
for _, card in ipairs(G.hand.highlighted) do
if card and card.set_edition then
card:set_edition("e_foil", true)
end
end
but, it sets the edition for ALL cards at the same time, and the sound stacks together to be really loud
Is there any way for me to either ONLY play the 1 sound, or, delay the applying foil effect per card?
you could change the sound of foil to 0.2
yeah, im bad at coding how could you tell
or use the event manager and add a 0.1 delay
for _, card in ipairs(G.hand.highlighted) do
if card and card.set_edition then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
card:set_edition("e_foil", true)
delay = 0.1
return true
end
}))
end
end
this might work
nice
then again tho the sound is ear candy
maybe just use a delay and event manager
I tried doing the G.E_MANAGER strat and it just reapplies the foil to the same card infinite times without any delay (even though I set delay) and it just blows out your ear lol
I didnt put delay = 0.1 inside the function, I'll try that I suppose
Just delete the true
nah it was my code from earlier
Yeah I noticed that field
yeah deleting the "true" did exactly what it should do, delayed the application to each card
sorry for the dumb questions, I am struggling to find documentation on these functions, I had to find like, obscure website that had the documentation on that function
i feel that, but no question is a dumb question only you before it gets answered. then you become smart :D
thats my thought when i ask something its to not be as dumb
Yup! slowly learning
i feel like i know so much about modding, and then i try something i havent before and get stumped for like 2 hours
Heres what I was workin on. I got on-click effects for my tags in my mod
neat
bump
SMODS.localize_box should be useful to you
ive been trying to figure out how to use it but there's nothing about it in the smods wiki for UI and i havent found examples within smods itself
I have problem with codeing my joker I want it to if there is a 3 in playing hand retrigger it three times and scale the xmult by 1.3 but It dosent work, is there anything I could fix it?
Heres code:
calculate = function (self,card,context) if context.repetiton then if context.cardarea == G.play and context.indvidual and not context.blueprint then if context.other_card:get_id() == 3 then SMODS.scale_card(card, { ref_table = card.ability.extra, ref_value = "XMult", scalar_value = "xmultgain" }) return { message = "Three!", repetitons = 3, Xmult_mod = card.ability.extra.XMult, card =card, } end end end end
you misspelled individual
also I'm not sure that context happens during repetition? but it definitely doesn't happen misspelled so fix that and see what happens
can ease_dollars be used everywhere, across consumables, enhancements, jokers, etc. what is the point of using it over dollars =
you don't have to return inside a calculate to use ease_dollars
so is it just a net positive to use ease dollars
but i think returning dollars=something ends up using ease_dollars in the end anyway
I'm not sure that's necessarily true
we will find out haha
so small update I removed context reptetition and the scaling works but retriggering still dosent work.
yeah you have to do these things separately
Oh, ok.
Returning dollars in calculate gives an automatic message
and properly times it to when the joker animation plays
for anything outside calculate ease_dollars is the only option anyway
how do I that?
Does anyone know how I would add credits to Jokers?
Also displaying side information, eg negative edition
the humble SMODS.calculate_effect:
i guess
Thanks
is there a vscode extension for smods
smods comes with lua lsp definitions, you just need to set it up to look for them or have smods open in your workspace
i dont think it works
do you check if ante is <= 4 like this?
if G.GAME.round_resets.ante <= 4 then
is this a folder with all three or just a workspace
the latter doesn't work
also i recommend setting up the luarc file
workspace? also how do i setup the luarc
what do you mean did you read the link 😭
i did and i was confused what to put in the luarc
do i put this?
{
"Lua.workspace.library": ["path/to/smods", "path/to/lovely/dump"]
}
yes
oh 😭
replace the paths of course
what does this mean
you might need to remove the "Lua." but i don't think so
like
{
"workspace.library": ["path/to/smods", "path/to/lovely/dump"]
}
```?
yeah
also would
%AppData%/Balatro/Mods/smods
work instead of
C:/Users/<user>/AppData/Roaming/Balatro/Mods/smods
in the path
i dont think so
😭
maybe it does idk never tried
where did you add the file
.luarc.json
ah
it works
smods works with %AppData% but lovely/dump doesnt lol
i originally wanted to play hot potato but my texture pack stopped working cause i updated smods so ive spent the past 1-2h trying to fix it
does anyone know where the scoring happens in the game engine? needing it for a patch
it's actually in state_events but this helped a ton, thanks ✌️
How do I use balance?
return balance = true in your calculation table
Thanks
How do you check for money change
do you guys happen to know how to grab the shop queue (as well as set the shop queue)
context.money_altered
and context.from_shop when buying
context.amount is how much its changing
what's your goal
there are some contexts for forcibly creating certain cards in shop or modifying cards that are already created, like the joker and edition tags
i want to make a joker which rewinds the shop queues once sold
checking for when you redeem a specific voucher
how do i make a jokers sprite change based on a condition?
ive seen set_sprite_pos() but idk how that function works i cant find documentation for it
it changes the position of the sprite in the atlas
what are the args for it?
np
Hey guys, can any of you please help me with this problem? Im learning coding right now and i have made a joker card. the code and all works fine, it's just that the card itself is for some reason invisible. Does anyone know why this happens and how to fix it?
https://medal.tv/nl/games/balatro/clips/mrYZmFRyfPF7apOxD?invite=cr-MSx2a1ksMjMyNDg4MTQz&v=15
Bekijk Untitled van sargeant_death en miljoenen andere Balatro video's op Medal. #balatro
Did you set the atlas/pos correctly?
i think? im not sure
im getting help from someone else right now
Does your mod have an asset folder? With 1x and 2x in it with your spritesheet in both?
Yeah i do have it, alongside images linked to it.
Does your pic file name goes [modprefix]_[key] ?
Is the file path + extension correct
Wait no
That cant be the issue nvm
im getting help from someone else rn, and they know what's wrong with it
ty for the help anyway
okay so the mistake was the pos coordinates, which i didn't really know much about. it's fixed now.
#1490007266215198891
would love if i get some programmers on the team, i dont know lua/coding at all
things will be added after other things are added to the mod (the two addeds, thanks english language)
is there an example for atlas?
I'm using this code to replace all blinds with boss blinds, but the ante always increases every time you beat one, even if its the one replacing the small or big blind. How would I fix this?
SMODS.Atlas({
key = "yourkeyhere",
path = "placeholder.png", -- must be assets/1x/placeholder.png as well as the 2x folder
px = 71, -- width for most objects
py = 95, -- height for most objects
})```
-# no indentation since I'm on mobile

SMODS.Atlas({
key = "yourkeyhere",
path = "placeholder.png", -- must be assets/1x/placeholder.png as well as the 2x folder
px = 71, -- width for most objects
py = 95, -- height for most objects
})
look
why is it 0.5X blind size lmao
hey look it's ranran
balancing attempt
if chat is playing for u it's to make up for them playing poorly on purpose
it's a forced ante 1 boss
where chat plays the game for u
does SMODS.current_mod.calculate happen before or after joker calculates
after
sweet, thank you
the retrigger context is going over my head
nvm i just remembered that vremade exists
I have an issue where even when the jokers in my custom rarity aren't in the pool, the rarity is still put into the pool of jokers that can appear, causing the shop to be filled with jimbos, with disable_if_empty not working
ignore the first 2 jokers they work fine
cause they aren't in custom rarities
i remember asking this before, but i forgot the answer
: during context.selling_self, does #G.jokers.cards include or exclude the card being sold
I'm using smods.current_mod.calculate to get retriggers, but the message keeps appearing in the deck rather than the card im retriggering and SMODS.calculate_effect({repetitions = 1}, joker) end doesn't work
how do i make a joker twice as likely to appear in shops and booster packs for every copy of itself owned?
message_card = context.other_card
how do you (without context) check if the game state is in a shop?
if G.STATE == G.STATES.SHOP
awesome ty, you're a legend
how do i make this not lag like hell
bump
You can't, unless you implement your own version of quantum enhancements.
Enable the object_weights optional feature and:
get_weight = function(self, weight)
return weight*(2^#SMODS.find_card(self.key))
end
thank you sooo much bro i could not figure out how get _ weight worked for the life of me
the documentation was vague (at least for me) and no mods had i that i owned
How would I go about 'tutoring' for a card? Like drawing a specific card to hand
can i make a card count as all rarities
Yes, hook Card:is_rarity
ty
does anyone know what the variable the time extern in shaders is?
how to detect if a specific joker has appeared in shop?
how would i just force a card to be scored regardless of when it's happening? i'm trying to make 3s in hand get scored as if they were played whenever a hand is played. code:
if context.individual and context.cardarea == G.hand and context.other_card:get_id() == 3 and not context.end_of_round then
local _context = {
main_scoring = true,
individual = true,
cardarea = G.play,
repetition = context.repetition,
}
return {
pre_func = function()
print("attempting to score 3s in hand")
SMODS.calculate_effect(eval_card(context.other_card, _context))
end,
}
end```
the `pre_func` is working; i can see the `print`. but the `eval_card` doesn't seem to be returning anything that's being calculated
you'd have a hard time with that since stuff may just iterate though G.hand.cards directly
consider drawing them to play and returning them to hand after
i was considering that. maybe in context.before just add them to G.play?
you can achieve this with an SMODS.score_card hook, i dont have it on hand rn but if you dont care about stuff like midas mask triggering it should be fine
i want it to trigger anything and everything that would normally get triggered by playing the card
i think that a legendary joker in paperback does something similar, maybe look for inspiration?
I know that G.GAME will save serializable information to it onto the run
Is there something like that for the whole save-file? Like, if I wanted to keep track of high scores on cards for example?
local oldsmodsscorecard = SMODS.score_card
function SMODS.score_card(card, context)
if not G.scorehand and context.cardarea == G.hand and card:get_id() == 3 and next(SMODS.find_card('j_modprefix_key')) then
G.scorehand = true
context.cardarea = G.play
SMODS.score_card(card, context)
context.cardarea = G.hand
G.scorehand = nil
end
return oldsmodsscorecard(card, context)
end
G.PROFILES[G.SETTINGS.profile]
Then do I just add whatever values I want to that and it gets saved the same way as G.GAME?
like G.PROFILES[G.SETTINGS.profile].someValueToSave = 101?
Yes.
perfect thank you so much
Oh!
Quick question, was trying to set the reroll cost in the shop to $0 (like the D6 tag effect) for my own clickable tag system, but, the vanilla-remake mod I was referencing did not appear to work when I copied what they did over, which is:
tagClickEffects["tag_dishevel_d6"] = function(tag)
if G.STATE ~= G.STATES.SHOP then
return cantUseTagMessage(tag, "Not in shop?")
end
if tryUseCharge(tag, G.C.GREEN, "Rerolls Reset!") then
G.GAME.round_resets.temp_reroll_cost = 0
calculate_reroll_cost(true)
return true
end
return false
end
any ideas?
(you can ignore most of that, just whats inside the "if tryUseCharge()" block)
Mfw someone streaming with no viewers gets that blind
just type the commands urself in chat

Yeah but that's boring
probably add something make it a regular boss if nobody is in chat
but I don't see why you'd play this mod with no viewers lol
minimum is at least 1
for everything to work
The entire mod is based on chat vs streamer interactions lol
how would i make this compatible with oops?
thanking you
second question, why does this voucher not spawn? i keep getting blank vouchers instead (i have every voucher other than hieroglyph)
requires = {'v_modprefix_chaser'}
main.lua
SMODS.Atlas {
key = 'atlas',
path = 'CardsV2.png',
px = 71,
py = 95,
}
SMODS.Atlas {
key = 'icon',
path = 'Icons.png',
px = 18,
py = 18,
}
SMODS.DeckSkin {
key = 'hearts',
suit = 'Hearts',
loc_txt = 'idk',
palettes = {
key = 'hc',
ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', "King", "Ace"},
display_ranks = {"Ace", "King", "Queen", "Jack"},
atlas = 'atlas',
pos_style = 'deck',
suit_icon = {
atlas = 'icon',
}
}
}
SpidersCustomTextures.json
{
"id": "SpidersCustomTextures",
"name": "Spider's Custom Textures",
"author": "TheSpiderNinjas",
"description": "idrk what to put here, the cards are cool i guess.",
"prefix": "sct",
"main_file": "main.lua",
"priority": 1.79769e308
}
why is my mod not appearing
your priority isnt a number
it is and thats not the problem
author is array
yea i changed it to an array
to get deckskin for all ranks would i have to copy this 4 times and change the suits?
SMODS.DeckSkin {
key = "hearts",
suit = "Hearts",
loc_txt = "idk",
palettes = {
{
key = "hc",
ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace",},
display_ranks = {"Ace", "King", "Queen", "Jack"},
atlas = "atlas",
pos_style = "deck",
suit_icon = {
atlas = "icon",
}
}
}
}
yes
-- comment
thx (im stupid)
i mean no other language does this, it's easy to forget 🤷♂️
Np (im stupid too)
doesn't mean you're stupid
yea im too used to fkn python
my game crashes after I tried use my custom poker hand.
show code
`SMODS.PokerHand ({
key = "pkr_youstupid",
chips = 9,
mult = 10,
l_mult = 21,
l_chips = 21,
example = {
{ 'S_A', true }, -- King of Spades, does not score
{ 'D_2', true },
{ 'H_8', false, enhancement = 'm_lucky' }, -- Negative Lucky 9 of Diamonds, scores
{ 'S_5', false },
{ 'D_J', false, seal = 'Red' } -- Red Seal 3 of Diamonds, does not score
},
loc_text = {
name = "You stupid!",
description = {"A hand containing a 2 and a ace"}
},
visible = true,
evaluate = function (parts,hand)
if #hand >= 2 then
local _has2 = false
local _hasAce =false
local eligible_cards = {}
local other_hands = next(parts._flush) or next(parts._straight) or next(parts._all_pairs)
for i,card in ipairs(hand) do
if card:get_id() == 2 and _has2 == false then
_has2 = true
eligible_cards[#eligible_cards+1] = card
elseif card:get_id() == 14 and _hasAce == false then
_hasAce = true
eligible_cards[#eligible_cards+1] = card
end
end
if _has2 and _hasAce and not other_hands then
return {eligible_cards}
end
end
end,
modify_display_text = function (self, cards, scoring_hand)
return pkr_youstupid
end,
})`
three ` instead of one
return "pkr_youstupid"
this
is
three
this is one
and return an empty table in evaluate when the condition fails
rn you're returning nothing when a single card is selected
does print() work, if not is there someone else that will work
print works. it doesn't expand tables unless you have debugplus though
the lovely console. you can also view logs in-game with debugplus
if you print a table, it will display like table: 0xdeadbeef, but with debugplus it displays the contents of the table
Like þe black terminal window þat opens wiþ baltro
yeah
it took me ay WAY too long but the textures work
W
how suit pips are structured on the 9
yea well the normal ones make me want to kill someone (cause autism) its so uneven the normal ones
let's goooo
?
my game crashes when tried to play a sound (that path exists, idk why it carshes with this message).
mod prefix
Game crashed while checking my custom poker hand
im very confused, i have an edition with a chance based effect but it seems to steal the odds of any card that has odds
ok i fixed the description but now its stealing odds without telling me
Can challenges have a custom consumable slot number? if so, how would i program that in?
would smth like { id = 'consumable_slot', value = 4 }, work?
idk if there's anything programmed in already, but those entries mainly serve as lines in the description (with vanilla having some hard coded effects if it sees any it recognizes)
using an apply function will definitely work
yea if challenges don't have something specific you're looking for, the apply function will let you do literally anything to the run
the calculate function can also do things
though in this case it wouldn't work very well
loc_vars = function(self, info_queue, card)
local info_queue_0 = G.P_CENTERS["p_baggutro_blackseal"]
if info_queue_0 then
info_queue[[#1116390750314307698](/guild/1116389027176787968/channel/1116390750314307698/)_queue + 1] = info_queue_0
end
end,
is this the correct way to info que for a consumable?
apply function........
p is not the consumable prefix
seals don't live in G.P_CENTERS, they live in G.P_SEALS
(kinda arbitrary but that's thunk)
though I'm unclear if you can info queue a seal directly like a center; it's a smods function
but consumable info queues are the exact same as any other object
as per the documentation, it's just a function that's run once at the start of the run
the game should save any changes to cardarea sizes
why not, ever heard of Spectral cards that add seals? 
you can info queue seals like that yeah
-- [REDACTED]
SMODS.Challenge {
key = 'redacted',
config = { consumable_slot = 2 },
rules = {
modifiers = {
{ id = 'joker_slots', value = 3 },
}
},
jokers = {
{ id = 'redacted', eternal = true },
},
consumeables = {
{ id = 'c_emperor' },
{ id = 'c_emperor' },
},
apply = function(self, challenge)
G.GAME.starting_params.consumable_slots = G.GAME.starting_params.consumable_slots + self.config.consumable_slot
end,
}```
ive redacted certain info to prevent spoilers (this is NOT for the joker jam)
but would tbis be right
yeah thats exactly what im replicating
uh, why modify joker slots conventionally, but not consumable slots in the same way?
apply doesn't take a "challenge" parameter, just self
this won't break anything today since you don't use it anyway, but it might if you come back in future and think it does something
please scroll up
this works, but the id would be consumable_slots
oe
this is the piece of code that handles modifying starting parameters
loc_vars = function(info_queue)
info_queue[#1116390750314307698_queue + 1] = G.P_SEALS["p_baggutro_blackseal"]
end,
is this right?
because its not working
that I in the length is erroneously capitalized
lua is case sensitive
info_queue is a different variable from Info_queue
discord just does that
try typing #1116390750314307698 without it capitalizing
oh its not capitalised in my code how has it done that
ah, discord
probably use the code markup. impossible to demonstrate but just wrap your code in triple backticks
` <- that guy, probably lives left of 1
#1116390750314307698rmatively
info_queue[#info_queue + 1] = G.P_SEALS["p_baggutro_blackseal"]
end,
#1116390750314307698eaeafef
#in #inf #1116390750314307698
hey so what's with the p_? that's not the prefix for seals. they don't have a prefix. i don't think p is the prefix for anything actually
p is the prefix for booster packs
oh yeah those guys
i removed it but it still doesnt work
you got the function params wrong
oh yeah
self, info queue, card
wrong arguments
game expects loc_vars(self, info_queue, card), not loc_vars(info_queue)
{
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_SEALS["baggutro_blackseal"]
end
}
this was correct earlier, why did you change it.. 🤔

idk i just assumed it wasnt
huh
it wasn't working because of something else, why would you assume it's the arguments
ok so theres a weird bug
it says this
however in game, it gives the intended amount
did you modify consumable slots via apply
yeah
but
i always forget about that column of challenges tbh
this piece of code btw
whats the prefix for enhancements?
m
thanking you
is it possible to forcetrigger a card's enhancement ability?
as long as it handles forcetrigger like how jokers do
assuming this is about the spectrallib forcetrigger feature yeah
as long as the enhancement has compat for it
info_queue[#info_queue + 1] = G.P_CENTRES["m_baggutro_ghostcard"]
end,
how do i chhange this to get it working?
you misspelled P_CENTERS
british english strikes again
yep
Hey, I am trying to make a joker that can manipulate the base value of chips given from a player card, do you know where I can find there that value is stored in a playing card?
sorry?
okay actually maybe I should elaborate a bit
i don't really need to forcetrigger them, but i'm making a joker that makes it so held in hand abilities don't need to be in hand to trigger
Like what hiker does?
Ortalab already does it (Wallet - played cards trigger held-in-hand abilities), you can take a look at its source code
i do not think that is the same thing at all but i think it might help
i am looking at the source code and i have no idea what is goiung on
wallet is quite different from just generally forcetriggering
Sort of what hiker does, but not using perma bonuses, I want to be able to edit the direct chip count it gives
this is not related to what i was doing earlier
calculate = function (self, card, context)
if context.before then
-- undiscard
G.E_MANAGER:add_event(Event({
func = function ()
for _, _card in ipairs(G.discard.cards) do
_card.area:remove_card(_card)
_card:add_to_deck()
_card.from_discard = true
G.hand:emplace(_card)
end
end
}))
end
if context.after then
-- rediscard everything
G.E_MANAGER:add_event(Event({
func = function()
local old_limit = G.hand.config.highlighted_limit
G.hand.config.highlighted_limit= 9999
local any_selected = nil
for _, _card in ipairs(G.hand.cards) do
if _card.from_discard then
G.hand:add_to_highlighted(_card, true)
any_selected = true
play_sound('card1', 1)
_card.from_discard = false
end
end
if any_selected then G.FUNCS.discard_cards_from_highlighted(nil, true) end
G.hand.config.highlighted_limit= old_limit
return true
end
}))
end
I have ZERO idea why this doesn't work
After you play a hand, draw all cards from your discard pile. Discard them again after scoring.
here's what it's supposed to do
it does draw the cards but then the game just softlocks
yeah it just softlocks here
You did not return true in the event
Okay, now it works, but it's not drawing all the cards
And also I'm testing it by discarding a bunch of metal cards and they're just. Not doing anything
Yes, because you're drawing them in an event, so they don't count in scoring.
like i discarded 5 and it drew three
oh really
would it work if i removed the event?
Yes.
okay, this still doesn't fix the issue with the amount of cards it draws
it's like really weird about it
Can I access the current jokers as a list or an array?
G.jokers.cards is a table of the jokers the player owns
How do you make it so Legendary jokers can appear in shop normally?
How do I check if there are curently exactly 5 jokers?
given any table that's indexed with numbers (like G.jokers.cards is), #table will be the number of elements in table
My joker is refusing to work. It's supposed to change art and retrigger a joker when there's exactly 5 jokers but it's doing nothing
if context.retrigger_joker_check and not context.retrigger_joker and not context.other_card == self and #G.jokers.cards == 5 then
if self.ability.extra.left and context.other_card == G.jokers.cards[1] then
card.children.center:set_sprite_pos{x = 8, y = 1}
self.ability.extra.left = false
return {
repetitions = card.ability.extra.retriggers,
message = 'Again!',
card = card
}
elseif context.other_card == G.jokers.cards[5] then
card.children.center:set_sprite_pos{x = 7, y = 1}
self.ability.extra.left = true
return {
repetitions = 1,
message = 'Again!'
}
end
end
end```
well self.ability.extra.left doesn't exist, it should be card.ability.extra.left
thanks
that and and not context.other_card == self is not what you want, it should be and context.other_card ~= card
It's still not working
#G.jokers.cards returns true and not 5 in the console, so how else do I check there's 5 jokers?
ok nevermind
after console testing, it looks like context.retrigger_joker_check isn't returning true for some reason
it's an optional feature
ok why didnt it embed https://github.com/Steamodded/smods/wiki/Calculate-Functions#optional-features
oh well
mhm!
bump, if i may
i'll elaborate a bit. here's my whole joker code
the issue is that for some reason it's not undiscarding every card in G.discard
it's leaving some behind
Why are the values for TCFNA listed as nil?
j_neonmod_tcfna = {
name = 'The Campaign for North Africa: The Desert War 1940-43',
text = {
"Gains {X:mult,C:white} ^#2# {} Mult per {C:enhancement}Enhanced{} card in your full deck",
"if at least half of the cards in your full deck are {C:enhancement}Enhanced{}",
"{C:inactive}(Currently {C:attention}#3#{C:inactive} out of {C:attention}#4# {C:inactive}){}",
"{C:inactive}(Currently {X:mult,C:white} ^#1# {} Mult)",
},
},
you aren't actually returning anything in your loc_vars function
What Meta said, but can I jus tsay. This might be a little busted 😭
It was initially meant to be if they had an edition, enhancement, and seal, but getting that to work would be a nightmare
Not really
Yes really when I don't know what the fuck I'm doing
not really when it's documented ^^^
I used that to make what I have now lol
did you see the part where it checks for edition and seal too
by stitching together shit from cryptid + steel joker
yea the vanillaremade wiki answers a lot of common questions
including "how to check for edition", "how to check for enhancement", and "how to check for seal"
Also please don't cross reference cryptid for the love of Jimbo
That codebase is a mess
At least not as a beginner
Mainly just did that to figure out how to refer to the exponential mult lol
Ah yeah fair
So then would it be like this?
for _, playing_card in ipairs(G.playing_cards) do
if SMODS.has_enhancement(playing_card) and SMODS.has_seal and SMODS.has_edition then
--- words
end
end
updated version
No, it would be if next(SMODS.get_enhancements(playing_card)) and playing_card:get_seal() and playing_card.edition
is G.shop_jokers.cards still populated when context.ending_shop occurs?
bump
okay so now what
talisman moment
replace talisman with amulet
use Amulet instead
there is literally zero reason to use talisman over amulet
thats new
I'm betting it's from old talisman code stuck in a continued run
It actually seems to be from this Joker?
wrap it in to_number(...)
also if your mod doesnt depens on talisman add to_number = to_number or function(x) return x end
where would I put the to_number = to_number or function(x) return x end?
at the top of the file
This is what I have currently, but the description still shows nil for all the values, and it doesn't seem to be triggering properly.
Move the enhanced_count = enhanced_count + 1 out of the return.
It should be emult not Emult
is is_rarity a function in Card or part of card.config.center?
card:is_rarity(...) / card.config.center:is_rarity(...)
It's card:is_rarity
how can i get rarity starting from card.config.center? i assume it's just ..center.rarity
Yes.
Set card.cost = number?
so i found this "mod" on gamebanana that changes the textures for some of the vanilla decks. however, it wasn't really a mod and just included the .png files. what's the easiest way to get these into my game?
Where in the code does the game go through and trigger context.joker_main for each of the jokers? I want to make an effect that adds extra triggers to any joker that meets certain requirements, but this could happen for any joker, so I don't want to take ownership of them all just to edit the code as such, so I figured that either hooking or patching the code that triggers the jokers would let me re-trigger them somehow.
How do you make it to where stickers have a 30% chance of appearing, or is that the default
No, you would enable the retrigger_joker optional feature and do:
if context.retrigger_joker_check and conditions then
return {repetitions = 1}
end
Yes, that's the default.
Oh okay
honestly thank god it always ends up being so easy and i just overcomplicate things a lot
I keep seeing this specific one a lot and I don't know if it was mistakenly made to appear more often or if it's just luck
What can I hook to that is effectively like a global update loop?
doesn't have to be a hook either necessarily
am I able to get data from the specific joker being checked? something like context.other_card?
Yes.
oh yeah i should probably read the wiki
Game:update
i would like to bump yet again
Change the top of the for loop to for k, _card in pairs(SMODS.shallow_copy(G.discard.cards)) do
what does that do?
It makes it so it iterates over every card instead of every card with an odd index.
I see
Is it possible to make a rarity that doesn't create a badge
I don't believe so
...Why
Ok well technically anything is possible but you'd have to do patches or hooks
ty so much!
key = "cosmic",
loc_txt = {
name = "Test Deck",
text = {
"Start with {C:purple}Satellite{},",
"{C:blue}Planet Merchant{}, and {C:blue}Planet Tycoon{}",
"Hands start at level {C:attention}0"
}
},
config = { jokers = { "j_satellite",}, voucher = { "v_planet_merchant", "v_planet_tycoon" } },
atlas = "vegas_jokers",
pos = {x = 0, y = 4},
discovered = true,
unlocked = true,
apply = function(self, back)
local args = { level_up = -1, instant = true }
SMODS.upgrade_poker_hands(args)
end
}```
trying to make a deck and i keep getting a crash. when I comment out the config is doesnt
It should be vouchers not voucher
How would I check for which other Jokers didn't trigger during a given ante?
takes a bit to set up, but it should be like this:
SMODS.current_mod.optional_features = {
post_trigger = true, -- enable post-trigger calculation
}
function SMODS.current_mod:calculate(context)
if context.post_trigger and context.other_card.ability and context.other_card.ability.set == "Joker" then
-- add a triggered flag (unique to your mod)
context.other_card.ability.modprefix_triggered = true
end
if context.ante_change and context.ante_end then
-- remove triggered flags at end of ante
-- code assumes all jokers are in G.jokers (optimal method to cover all possible joker cards omitted for brevity)
for _, v in ipairs(G.jokers.cards) do
v.ability.modprefix_triggered = nil
end
end
end
Thanks
Which function should I hook to affect all draws? I saw context. drawing_cards but I’m worried that it won’t consider when other jokers modifying
what are you trying to do?
no way im doing things
I want to force certain cards to be drawn first
My game crashes at the end of the round when joker suppose to trigger
calc_dollar_bonus should return a number, not a table
why my locale file doesn't work at all?
localization/en_us.lua:
return {
descriptions = {
Tarot = {
c_liroxfunstuff_neon_weapon_purify = {
name = "Purify",
text = {
"Next {C:green}5{} scored jokers give {C.mult}+25{} Mult"
},
}
}
}
}
The key is right (i hope):
object_type = "Consumable",
atlas = "neon_weapon_purify",
key = "neon_weapon_purify",
set = "weapons",
The set:
SMODS.ConsumableType {
key = "weapons",
default = "c_liroxfunstuff_weapon_stick",
primary_colour = HEX("e62314"),
secondary_colour = HEX("e62314"),
collection_rows = { 5, 6 },
shop_rate = 4
}
code
Its en-us, not en_us
But also custom consumable descriptions go in their own category, not Tarot
oh, hm
Uhh like weapons = {}?
Yea
thanks!
game is crashing after I want to check run info (i think i could be coused by new poker hand I added)
then make them not locals?
im taking a table from another mod thats a local
then put the code where that local is? gonna need more context if that doesn't help
i'm doing polterworx crossmod and i need to add to this table (img taken from jen.lua)
i am also trying to do as little pwx modifications as possible
patch jen.lua
I mean it'd be better style to take that from some global table initialized once
like this you'll have to patch where this is
but also get jen to make that not a local lmao
I mean, if he's fine with cross-mod that is
jen said that all crossmod has to be done on the end of the one that wants to do it
ah, patching is the only way then
you can do a simple patch to make it a global
then do the modifications on your end
Attempt 1
is there a redefining of uno_data?
that's an unnecessarily complicated pattern
you just need to patch the very first line
so like this?
wouldnt that still override the old table on each call?
it should be '=[SMODS jen "jen.lua"]'
uno_data = uno_data or {
huh, is it called repeatedly
I'm assuming it's a local table containing init values for adding several game objects related to suit/rank leveling
yes
this
therefore it's called once
then is it not too late to modify it after the function has been called?
In which case you have to patch your modifications into the function
[manifest]
version = "1.0.0"
priority = 0
[[patches]]
[patches.pattern]
target = '=[SMODS jen "Jen.lua"]'
pattern = '''
local uno_data = {
'''
position = 'at'
payload = '''
uno_data = {
'''
match_indent = true
``` this is the thing so far
my brain is not braining
I don't think making it global helps you
what does @gilded blaze have to say tho
making it global doesnt help bruh
to clarify, the table lives entirely inside the given function and has fulfilled its time by the time the function returns. however it only gets creates once the function is called, so there is no way to make use of it outside of the function
its a table that is used ONCE
Yeah
Its used once to loop over to create all the uno cards automatically
to make it a useful global, you'd have to define it before the function
Instead of manually defining 52 consumables
bruh 
😭
it's not like I have access to the mod files
at which point you could modify it on your end BEFORE the function is called
I have absolutely no idea what's behind uno_data

