#💻・modding-dev
1 messages · Page 471 of 1
You also swapped your k and c
Also, that looks like a fun function of that joker. Nice work
oop
thanks
NP, happens to the best of us
IPA name is pretty cool
SMODS.draw_cards(number)
is this not the right way to make a function
done
Can jokers have animation? This seems to work, but when I uncomment the atlas_table and frames lines, the game crashes when the joker is displayed, saying it tried to access atlas that was nil.
SMODS.Atlas({
key = "roulette",
path = "j_roulette.png",
-- atlas_table = 'ANIMATION_ATLAS',
-- frames = 2,
px = 71,
py = 95
})
no, you cant put that in the middle of a table
not this way
you need to update the sprite position manually
where i have to put it
ok
Thanks - I'll go dig how to get a delay set up so I can go back and forth between the two images to simulate "spinning"
Use Aura or have a look at how I pull it off with one of mine.
SMODS.draw_cards(#G.deck)
well it should be .cards i think
i for got
wait no im correct
its G.hand.cards
#⚙・modding-general message
Putting both of these together with a double bump
Thanks! I was trying to do something similar in the calculate function - with the idea being that when the hand is about to be calculated the roulette wheel spins and a card value is chosen. It doesn't seem to work, but I'll look at the update function you're using
calculate = function(self, card, context)
if card.debuff then return nil end
if context.before then
logger = adc_get_logger()
logger.log( "::CARD::" )
logger.log( card )
for i=0,100 do
logger.log(i%2)
card.children.center:set_sprite_pos({ x = i%2, y = 0 })
-- if love.timer then
-- love.timer.sleep(0.1)
-- end
end
end
end,
looks hard
i need to do something like that for my mod next but still havent looked into it
Seems like someone forgot the ,
yes i find out that after seeing error screen for more then 10 times
are there any jokers that can only spawn with a certain sticker so i can have a look at how they do it. i can see small cube in cryptid but are there any others
wait nvm i got it
not fully happy with the art, it's a bit too empty, but it'll work for now :v
how can i make a card as large as a booster pack?
you can seemingly make them smaller by just making the image smaller, so maybe simply making a larger image works??
well, I accidentally put in a 90x71 image instead of 95x71
and it just was smaller
so, in the directory Atlas reads the images from
ya it'd be smaller if the image was smaller
but this is the same size as the base game spritesheet
oop the Lucky 7 corners are wrong :v
how do i mod? im new
i love how this shop is completely modded dfkjgndfjkg
Welcome to the Balatro Modding 101 tutorial.
In this beginner-friendly guide, I'll walk you through the steps to get started with modding in Balatro. Whether you're looking to install mods created by others or dive into making your very first mod, I've got you covered!
Links!:
https://github.com/Steamodded/smods - Steamodded
https://github.com...
buffoon pack and standard pack >:(
a thanks
also if someone else knows a better first guide but this is what I used
in the description, what colour are ranks usually?
C:attention I think
i love how this shop is COMPLETELY modded
oh
they all have their own colour it seem
C:spades and the such
I figured it wouldn't be too bad but I can't figure out like 50% of it
Also i have no idea how cardareas work
is this all a mod you're making?
most of it is!
there's a charm from Bakery and an Arts and Crafts pack from ArtBox
but otherwise, all me :3
that's decent going!!
dw about how much content your mod may have
overall, it's the quality of the content that really matters :D
fairfair!
with jokers that I could see existing in vanilla
what's the minecraft axe do?
the prefix for booster packs are p_ correct?
i recognize those zodiac colors
thats not a normal rainbow
Copper Grate cards do not oxidise, and this Joker deoxidises them when they are played and scored
also what mod is that
I see I see
hi quick question, looked at clearance/liquidation code and wondered if there was a way to change G.GAME.discount_percent by selling a joker w/o it being "reset" by said vouchers? i can see how to do it if the joker's owned, but not sure if there's a way with a sold joker
MY STUPID JOKER FINALLY WORKS (it adds 5 mult for every 2 played)
you could always patch clearance/liquidation
how can i set the mouse damping of my consumable?
thought of it, but risky for mod compat no?
i think i may do that in the end though
it only breaks compat if another mod patches that exact line and makes a different change
if anyone here is familiar with pools could i make a seperate blind pool that has a chance to override the regular boss blind pool at the start of an ante, and if you skip the blind another one from the pool appears? exactly like the showdown pool that appears on the final ante
question: how do i change the "nil" to its actual mult value
do you have a loc_vars function
no, never thought of that
hm, i can't find the blind spawning code in the lovely dumps
hehe sorry to promote! but you may be interested in my BFDI mod: https://discord.com/channels/1116389027176787968/1337836888181968927
holy crap beefy die balatro real
oh THANKS balatro. i was looking for POOL but it's just P.BLINDS
thunk cannot spell for shit
it's whatever, i found the function i was looking for
gulp
this is going to take a lot of reverse engineering
what are you trying to do?
create a new boss blind pool that sometimes spawns in place of the standard boss blind pool
i want a seperate pool, so that if you reroll it generates another in the pool and not a standard boss blind
oh you can probably just swap eligible_bosses at the end then
get_new_blind also handles the logic for bosses_used though
balatro modding is super fun yo
yeah
i wouldnt put stuff in that function tho is what i mean
i would copy it and just swap the table at the end
a hook would work
yeah it was that thank you N'
i have only made this 3 fellas for now, i'm very proud of myself
where would be the best place to start for making a balatro mod?
ive not got much experience with lua and developing game mods as a whole.
is there any decent tutorials that walk me through the full process or do i just need to wing it lmao
i believe the smod wiki itself is a very good tutorial
probably the best resources we have rn https://discord.com/channels/1116389027176787968/1349064230825103441
alright, ill give it a look thanks
this too
if i do the swap right here, i can run my own in_pool checks on the shattered blinds and the bosses_used functionality is handled by the rest of the function, right?
yeah
wee joker
glorified wee joker indeed (im nerfing the added mult to 1)
was doing a run to test my jokers then this bastard appeared on the shop
very good to see how it behaves with my jokers tbh
how would i change jokers that appear in the shop
yay
can a patch overwrite code stuff?
it can but it doesn't have to
i assume by "code stuff" you mean balatro source code
yeah
looking to have a joker effect to either double or halve all prices when sold
i can see how to do it when joker is owned
but when sold, the way i originally thought to do it would make it go nil if player buys a voucher after
if context.selling_self ?
cuz it's just G.GAME.discount_percent = extra
not the issue
the problem isn't how to do it
it's about how price reduction is done
Making progress, ignore moons and stars from six_suits, i'm using that mod as placeholder for debugging
Do you think staves is okay? Since club is already taken
ive added voice to my simple bot mod (LLM use qwen3-32b, voice with local docker travisvn/openai-edge-tts). (Long final pause due to API limit for free tier). Does anyone have experience in Balatro bot dev? ive a few questions.
are those italian cards?
Yup
could i add a line to self.cost = math.max(1, math.floor((self.base_cost + self.extra_cost + 0.5)*(100-G.GAME.discount_percent)/100)) before the /100 that would be basically a * VALUE, with Value being 1 at first, but being modifiable by my jokers?
like, inserting a global in card.lua that doesn't exist yet? Sorry if the answer seems obvious
tyler the creator reference??
cool, piacentine are my favorite ones
Yeah piacentine are nice, they keep that retro look
nlg it's a bit strange to see 8 9 and 10 for those cards. due to the fact that they do not have number is not so easy maybe to play straights
They are placeholder ^^ they'll have different ranks
Like knight instead of queen
ahah, I see...
can you actually check the price of the jokers in shop?
yeah, loop through G.shop_jokers and check card.cost
thanks
Moderate Joker
I might add some brown though
common, 4 dollars, +1 joker slot
whats the context for exiting a shop again
isn't that just a better golden jonkler
oh i see
where's Game:init() in?
so it's just like a blank slate for stuff like wheel procs or sell value scaling
pretty interesting
ending_shop iirc
got it
tried this, doesnt work
because its not setting_shop
entering_shop?
starting
everything else is okay right
there's a part in the docs for that
Brb
idk what uncosted is but sure
in your suit make an in_pool function
If you never want it to generate, return always false
I found the culprit, it's how it's implemented in six suits, which i referenced
SMODS.Stickers.prefix_key:apply(card, false) should work, there probably is a better way that I don't remember tho
whats the context for detecting if cards were destroyed
How would I prevent a card with a certain sticker from being destroyed?
Or more in general. How would I prevent a card from being destroyed?
which type of card
but in general this is hard to do because effects just hardcheck for eternal right now
you can hook Card:remove / start_dissolve / shatter maybe
there's a new context to prevent destruction of jokers tho
am bored. lmk if you want me to work on your mod
does anyonr know wh the souinds arent working?
How would I make it so my Joker displays a list of variables in loc_vars?
Move the sound out of play_sound
Also it's context.cardarea
Also you need your mod prefix.
so yip_error?
Yes.
Are these icons recognizable as sword, coin/gold, club, cup? (as mini deck info icons)
yeah
Just as a half bump to get one thing done at a time
How do I make it so you can highlight things in the cardarea
why isnt this working btw
there's a highlight_limit argument in the cardarea init
With context, yes. Will the player have context for them when they first see them? If so, coin could be misconstrued as many things.
If not, rather.
Yeah i Will color them, and should be there
maybe put a small notch in the middle of the coin like a Mario coin
other than that they look good
Yup, with colors should be there, i was Just asking for the overall shape
yeah the shape is coiny
With colors, should be fine. Even in silhouette, you could do a bit of a glint in the dark bit to show it's something shiny and valuable.
Card:apply_sticker doesn't exist.
in the calc_function in JokerDisplay definition do i have to calculate hand_chips by myself (to display the effects of a joker relaying on that while having the hand selected and not played yet)
What does exist, then, cuz ive tried multiple methods
hi guys ummm im working on a joker and i need it to find cards with the glass enhancement how do i check for glass
thanks
SMODS.Stickers["modprefix_key"]:apply(card, true)
Why did this even happen if my code is commented out?
Is this lua jank or something
Tried that, it doesn't work still
It was crashing at first so I commented out all of the code just to go in and test jokers normally
And it does this
Oh wait I have 78 cards, it just added the two suits
Oops
I have it set to 5 but it doesn't let me do anything with it
i think it also depends on the cardarea type
The correct way. I'm pretty sure it has to do with the if statements, because its not crashing. It's just not doing anything
O
I didnt quite get that part when i saw it
How do u make it do playing cards
Coin should be done
Yes, context.main_scoring isn't called on jokers.
G.hand is type = 'hand'
Thanks 
Comment means comment, as in you could write whatever and code doesnt run/compile
I realized my mistake
Didn't realize that with extra suits it creates two pages for the deck
Yeah, same mistake i made before xd
Question though, if I create new suits how do I stop them from appearing in normal decks immediately
I'd like for them to only be available through tarot cards / a deck that specifically starts you with them
in_pool arg. as false
Thx
Bump
how would i go about making a joker not appear in the shop or through any cards (riff raff, judgement, etc)
in_pool = function(self) return false end?
would that go at the top around config and atlas
It would go anywhere in the joker definition.
How would I make a dynamic description that shows a list of values if said values are above 0? e.g. mult/chips
can you elaborate
I have a Joker that gets bonuses. If it has a mult bonus, it shows a +X mult thing. Otherwise, it shows nothing. same goes for chips/xmult
you have 3 options:
- use vars and variable colours in your text to add/remove that text
- use main_end and ui nodes
- switch descriptions using
key
what's the goal? a texture pack or some effect?
So if I did #1##2##3# and did newlines (via the 1. method) that would work?
Good schmorning chat
no, newlines don't work
it's actually the reason why i told you about options 2 and 3 lol
i'm making a joker that destroys the cards to left and right of it, but the game crashes if they aren't both there
use Malverk then
Is this frowned upon as a method
would i just have to make two separate if blocks for the joker to the right and the joker to the left?
yeah probably
I'm not sure if I did it right
self.hold_area = CardArea(
15.5,
3.75,
self.CARD_W * 1.95,
self.CARD_H * 0.95,
{
card_limit = ALLOY.hold_limit,
type = 'hand',
highlight_limit = 5
}
)
self.hold_area.states.visible = true
ALLOY.hold_area = G.hold_area
doesnt seem to be letting me highlight anything
do you guys know if there is a built in context that holds last played hand ? i am trying to make a joker that triggers if curently played hand is different then previous. if there isn't a builtin i will make my own variable but it may cause a little problem
Downscaled the sword it's a bit ugly, but i am satisfied
G.GAME.last_hand_played
G.GAME.last_hand_played = context.scoring_name can i use it like that ?
hey guys, this is my code and im getting this error:
I believe so
okay. Thank you ❤️
okay the second error (the suit) is fixed now
but the first one (the rank) is still broken
The build of SMODS you're executing that on doesn't have the probability stuff updated.
sooo lets sayyy how would i fix it
Easiest is to grab the latest commit instead.
it looks right, i have no idea
o
oh wait i got it working
this is the second time where the solution was just "do ???"
save code
open balatro
test
it doesn't work
close balatro
open balatro
test
it works now
???
Now I just need to make it vertical instead of horizontal
time to steal aiko's solitaire code
don't get me wrong it doesn't look bad like this but like
it would fit so well above the deck
o
Where may this code be perhaps :3
sorry but i need to bump again
@tall wharf
theres a lua file thats solitaire.lua im pretty sure
o
module > custom_minigmaes
thanks 
oh right unrelated but I forgot I was gonna ask you something about a different thing
uhh
how do you get the number of cards in a specific hand
how do i make a card immune to debuffs?
in add_to_deck use SMODS.debuff_card(card, "prevent_debuff", "source")
elaborate?
local function get_all_hands(ignore_hand_limit)
ignore_hand_limit = ignore_hand_limit or false
no_hand_size_limit = evaluate_poker_hand(G.hand.cards)[G.GAME.last_hand_played]
hand_limit_accounted = {}
if ignore_hand_limit then return no_hand_size_limit end
if no_hand_size_limit then
for _, hand in ipairs(no_hand_size_limit) do
if #hand <= G.hand.config.highlighted_limit then -- Apparently #hand doesn't work and just returns zero? Replace with something equivalent
hand_limit_accounted[#hand_limit_accounted + 1] = hand
end
end
end
return hand_limit_accounted
end
i completely forgot i just kinda left it and gave up on it
they're temporary cards so i never add them to the deck
should i be doing that regardless
oh sorry is this a playing card
oh then on_apply
if i can make temporaries self-destruct regardless of debuff status that would probably be better
hmmm #hand should work there i think but no_hand_size_limit is always true if G.GAME.last_hand_played is valid, you need to check for next(no_hand_size_limit)
o
the check was mainly there just in case G.GAME.last_hand_played wasn't valid
so like if it's the first hand
tho if I do like
print(#hand)
it just always returns 0
weird
bump
seems like i can't use G.GAME.last_hand_played ~= context.scoring_name because they will be same the time i am checking this equation.
any idea ?
config = {extra = {chips = 0, chip_mod = 10, suit = 'Hearts' }},
loc_vars = function(self,info_queue,card)
return {vars = {card.ability.extra.chips}}
end,
calculate = function(self,card,context)
if context.joker_main and context.individual and context.cardarea == G.play and context.other_card:is_suit(card.ability.extra.suit) then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod
return{
chips = card.ability.extra.chips
}
end
end,
still new to modding so I cant rlly tell but what's wrong with this code?
depends on what you're using it for
if context.before and context.main_eval then local reset = true if G.GAME.last_hand_played == context.scoring_name then reset = false card.ability.extra.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_gain end
i use it like this
what you can do is "if context.after then, card.ability.extra.previous_hand = G.GAME.last_hand_played"
which will log it after the first hand you play with the joker
and for the card.ability.extra."blank" <-- anything can go here
bump
i think there is a way to do it globally but i'm not sure how it works
thank you
The colors of the non face cards are the low contrast version, how would I have it be the High Contrast ones?
local suits = {
Clubs = SMODS.Atlas {
key = "collab_dr_clubs",
path = "collab_DR_clubs.png",
px = 71,
py = 95,
}
}
for suit, atlas in pairs(suits) do
SMODS.DeckSkin {
key = atlas.key,
suit = suit,
loc_txt = "Deltarune",
palettes = {
{
key = "hc",
ranks = {'Jack', 'Queen', "King"},
display_ranks = {"King", "Queen", "Jack"},
atlas = atlas.key,
pos_style = 'collab'
}
}
}
end
First spectral card
It works :3
Hello, I have a question regarding SMODS.Pokerhand. I want to make a new hand consisting of 5 face cards that are flush. Here is what I have
key = 'Family',
visible = false,
above_hand = 'Flush',
chips = 20,
mult = 5,
l_chips = 10,
l_mult = 2,
example = {
{ 'S_K', true },
{ 'S_Q', true },
{ 'S_Q', true },
{ 'S_K', true },
{ 'S_J', true },
},
loc_txt = {
['en-us'] = {
name = 'Family',
description = {
'5 face cards with',
'all cards sharing the same suit.'
}
}
},
evaluate = function(parts, hand)
if not next(parts._flush) then return end
modify_display_text = function(self, cards, scoring_hand)
local fam = true
for j = 1, #scoring_hand do
local rank = SMODS.Ranks[scoring_hand[j].base.value]
fam = fam and (rank.key == 'Ace' or rank.key == '10' or rank.face)
end
if fam then
fam then return {parts.flush} end
end
}```
Am I missing like a pokerhandpart or something, how would go about making unique from a normal flush?
why is my joker not displaying the variables in loc_txt? did i miss setting something up?
should be return { vars = { variables here } } instead of just return { variables here }
thank you!
np
Bump just in case
how do i make a calculate function on a card (edition in this case) always execute even the card is debuffed
can someone come up with a rough draft for a joker that just adds a random card to your hand with the mult enhancement, kinda like certificate but just mult cards
i cant seem to figure it out and i gtg to work it would help me tons !
I'm starting to think my Balatro copy is cursed
This is the third time in the past day that the solution to the problem I was having is just "try again and it magically works"
Nvm it broke again
Oh
Oh i see the problem nvm
hey, is there any function or method that is called when a hand is played? and also one when its scored?
if context.press_play in the calculate() function for the first one
there's multiple contexts that trigger during hand scoring, what are you trying to do?
wheres the function that shows how many jokers you have in your slots?
G.jokers.config.card_limit
yeah but whats the code that displays that?
oh ok, ty
Trying to figure out joker retriggers... how do I make it so that a Joker that retriggers other cards doesn't respond if the card it's attempting to retrigger doesn't do anything?
just this is enough
ty very much
np
How do I check the ID of a sold joker?
You mean the key?
Yeah
i think you need to store the id of the joker when its sold then retrieve it later
card.config.center.key?
Did i made something wrong? When i select deck in the description suits are not colored
return {
["misc"] = {
["suits_plural"] = {
["BBB_Swords"] = "Swords",
["BBB_Cups"] = "Cups",
["BBB_Coins"] = "Coins",
["BBB_Staves"] = "Staves",
},
["suits_singular"] = {
["BBB_Swords"] = "Sword",
["BBB_Cups"] = "Cup",
["BBB_Coins"] = "Coin",
["BBB_Staves"] = "Stave",
},
},
["descriptions"] = {
["Back"] = {
["b_BBB_scopa"] = {
["name"] = "Scopa Deck",
["text"] = {
"Start the run with",
"{C:BBB_Cups,E:1,S:1.1}Cups{},{C:BBB_Swords,E:1,S:1.1} Swords{}",
"{C:BBB_Coins,E:1,S:1.1}Coins{} and {C:BBB_Staves,E:1,S:1.1}Staves{} suits.",
},
},
},
},
}
--i'm pasting only cups
local cups_suit = SMODS.Suit {
key = 'Cups',
card_key = 'COP',
hc_atlas = 'hc_cards',
lc_atlas = 'lc_cards',
hc_ui_atlas = 'hc_ui',
lc_ui_atlas = 'lc_ui',
pos = { y = 0 },
ui_pos = { x = 3, y = 0 },
hc_colour = HEX('C00000'), -- red
lc_colour = HEX('C00000'),
in_pool = allow_suits
somewhere in CardArea:draw()
It finally works properly 
Wait, isn't context.selling_self a thing?
Can i have only the play last hand code? Haha
When I'm done with the rest of the mod I'll send it ur way :3
Ty <3
Yes.
How do I like make new variables saved with the run?
Put it in G.GAME
how can i make a joker that gains +1 chips every second? it's probably not that hard but idek where to start
I currently have it that way, but every time I load the run and try to use the variables it crashes
Do I have to store jokers differently?
Are you trying to store cards in G.GAME?
Yes
Any suggestions or like things I should look at instead then?
Because storing cards in the save is vital to what I'm attempting to accomplish
What is the goal?
I am making a deck - TLAZ - which stores 2 different joker hands that swaps each blind, if that makes sense
In terms of the code, I'm basically just copying the jokers to an object and pulling from another, and swapping between the two
^5
gang i cant code for shit what am i doing wrong here (did not crash)
Maybe your for loops being weird
I don't know much about lua but the way you set it up seems odd
Nevermind
bill cipher save us
NOTHING is happening. like literally nothing. it should sell all consumables in the consumable area and add the sell value of those consumables to this joker's xmult, but it doesnt
well first of all, its not sell_value its sell_cost
That might be the issue
.. does that fix it?
great! now it does something! it crashes!
You can't score on context.setting_blind.
that makes sense
Your context.setting_blind section should end in message = 'X'..card.ability.extra.Xmult, not xmult =
I gave in and used C:red, attention, blue and green because i don't wanna get another migraine
why doesnt this work?
Tomorrow i'm doing custom ranks, and if i don't take too much, even custom hands like settebello (single 7 of coins instead of high card, etc.)
When i'm done i'll make custom art instead of placeholders
I want this joker to add eternal to the joker on the right when it's sold, I'm guessing G.jokers.cards[i] == self doesn't work, so what else can I use?
calculate = function(self, card, context)
if G.jokers and not context.blueprint then
for i = 1, #G.jokers.cards do
if context.selling_self and G.jokers.cards[i] == self then
G.jokers.cards[i+1]:set_eternal(true)
end
end
end
end
But custom art right now is very low on priority
THANK YOU.
Autra i can feel you, capitalization Is my enemy too
G.jokers.cards[i] == card
Don't put () at the end of the local cfbs = ... line, that calls the function and stores its return value, instead of storing the function itself.
Also move the context.selling_self check out of the for loop.
like this?
No, local cfbs = G.FUNCS.check_for_buy_space
like this?
Yes, but please move the (card) back to where it was before.
So like, any work arounds to saving cards into the save?
How would I go about disabling a blind that uses the debuff_hand function?
hey
this is my code, the test 1, 2 and 3 are working (play is pressed too), but the test 4 dont work
the ideia is a joker that choose another joker to copy its effect each hand played. Half of the time it copies the leftmost joker, the other half, the rightmost joker
calculate = function(self, card, context)
local targetJoker = nil
local availablePos = {}
if context.press_play then
print('play is pressed')
if G.jokers.cards[1] and G.jokers.cards[1] then
table.insert(availablePos, 1)
print('test 1')
end
if G.jokers.cards[#G.jokers.cards] and G.jokers.cards[#G.jokers.cards] then
table.insert(availablePos, #G.jokers.cards)
print('test 2')
end
if #availablePos > 0 then
local chosen_position = pseudorandom_element(availablePos, pseudoseed('losted_doodle'))
targetJoker = G.jokers.cards[chosen_position]
print('test 3')
-- if targetJoker == card then
-- targetJoker = nil
-- end
end
local ret = SMODS.blueprint_effect(card, targetJoker, context)
if ret then
print('test 4')
ret.colour = G.C.PURPLE
end
return ret
end
return nil
end
anyone can help me ?
what's the context for the end of a round?
context.end_of_round
thank you
Hello !
I am having trouble with a feature to dynamically change the hand size,joker size,...
The hand size is linked to a variable in the G.
But if I have a joker that increase this variable on a end_of_round, then all the increase will be made one round later.
It looks like it is :
Check for the value then increase it. But if both joker trigger in end_of_round, how can I choose which one to trigger first ?
SMODS.Joker {
key = 'X',
loc_txt = {
name = 'X',
text = {
"Gains +#1# jslots",
}
},
config = {
extra = {
slots = 1,
},
immutable = {
max_slots = 50,
},
},
rarity = 2,
atlas = 'Jokers',
pos = { x = 0, y = 0 },
cost = 5,
loc_vars = function(self, info_queue, center)
return { vars = { self.config.extra.slots } }
end,
add_to_deck = function(self, card, from_debuff)
local extra = math.min(card.ability.extra.slots * G.GAME.pharahos_scarabs, card.ability.immutable.max_slots)
G.jokers.config.card_limit = lenient_bignum(G.jokers.config.card_limit + to_big(extra))
end,
remove_from_deck = function(self, card, from_debuff)
local extra = math.min(card.ability.extra.slots * G.GAME.pharahos_scarabs, card.ability.immutable.max_slots)
G.jokers.config.card_limit = lenient_bignum(G.jokers.config.card_limit - to_big(extra))
end,
calculate = function(self, card, context)
if (context.end_of_round and not context.individual and not context.repetition and not context.blueprint) or context.forcetrigger then
local extra = math.min(card.ability.extra.slots * G.GAME.pharahos_scarabs, card.ability.immutable.max_slots)
G.jokers.config.card_limit = lenient_bignum(G.jokers.config.card_limit + extra)
end
end
accidentally did a stack overflow crash-
^6
Isn't wee joker just a regular sprite size
But a lot of transparent pixels on the sides
I'd like this joker to destroy the 2 and give an ethereal tag if the scoring hand contains one queen and one two, anyone know why it isn't working?
calculate = function(self, card, context)
if context.before then
local queens = 0
local twos = 0
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 2 then twos = twos + 1 end
if context.scoring_hand[i]:get_id() == 12 then queens = queens + 1 end
end
if twos > 0 and twos < 2 and queens > 0 and queens < 2 then
card.ability.extra.created_tag = true
end
end
if context.destroy_card and not context.blueprint then
if card.ability.extra.created_tag == true then
card.ability.extra.created_tag = false
if context.destroy_card:get_id() == 2 then
return
{
func = function()
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag('tag_ethereal'))
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)
}))
end,
remove = true
}
end
end
end
end
How do I change the text on a button
no, it's regular jimbo sized down
That is what i have for my joker but is still acts as a full joker so the sell button is just floating instead of being next to the actual joker, you use pixel size to change it but idk what to multiply 71 and 95 with
just put the size you want directly
Hmmm ok
bump
it works thanks, i just had to move sprite right after
convert to mp4
ye
mp4, joker creation is a bit funny
i know im missing the emplace, but when i put it into my code, the game crashes
Code?
Try just using SMODS.add_card({key = "j_joker"})
@daring fern can you help me ?
context.end_of_round and context.main_eval
here
idk how to resolve
thank you!
for patching into this func, what would i do as my local variable that stores the original
e.g. hookTo = ...
local oldcardareaupdate = CardArea.update?
ahh i was using : instead of .
you're only ever passing the other jokers the context of pressing play - this context doesn't do anything on almost any joker
the create joker works, but when i try to replace it to create my placeholder rose, nothing is made
how to resolve this ?
Code?
Remove the if context.press_play check.
first one is placeholder seed, second is the rose
but that way it will keep copying a joker and then changing it, all while the hand is still being played
before the screen shots, i also tried placing the key into the quotes for the add card
what your engine ?
Is there a central context for the deck being modified? There's a central unlock condition but that doesn't get sent to unlocked items, so I can't leverage that here
can i make a sprite for an edition then just try to match it with the card in shaders or smth?
The key would be j_modprefix_rose
visual studio code
you could hook the check for unlock function mayhaps
ok
bump
can i have more context
like is it a button you made or an existing one
A button I made
I wanted to change the text on the button depending on what the player is doing
so like
changes while the menu is open?
Essentially yea
G.FUNCS.can_hold = function(e)
if 0 < #G.hand.highlighted and #G.hand.highlighted == #ALLOY.hold_area.highlighted then
e.config.colour = G.C.GOLD
e.config.button = "toggle_hold"
e.config.text = "Swap"
elseif 0 < #G.hand.highlighted and #G.hand.highlighted <= ALLOY.hold_limit - (G.GAME.cards_in_held_area or 0) and #ALLOY.hold_area.highlighted <= 0 then
e.config.colour = G.C.GOLD
e.config.button = "toggle_hold"
e.config.text = "Hold"
else
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
e.config.button = nil
e.config.text = "Hold"
end
end
this but replacing e.config.text with whatever I would be using here
would you need to change it then recalculate the menu its in
I'm not sure
Currently the colour changes just fine
can i see the button code
like where you define it
local hold_button = {n=G.UIT.C, config={id = 'hold_button',align = "tm", padding = 0.3, r = 0.1, minw = 2.5, minh = button_height, hover = true, colour = G.C.GOLD, button = "toggle_hold", one_press = false, shadow = true, func = 'can_hold'}, nodes={
{n=G.UIT.R, config={align = "cm", padding = 0}, nodes={
{n=G.UIT.T, config={text = "Hold", scale = text_scale, colour = G.C.UI.TEXT_LIGHT, focus_args = {button = 'z', orientation = 'bm'}, func = 'set_button_pip'}}
}}
}}
i feel like this is an issue with how youve set the variable
like the text is nested in a different element
instead of text = "Hold" change it to ref_table = G.GAME, ref_value = "your_variable" and put the text in G.GAME.your_variable
or any other table
thank u :>
Is there a way to use Smods.add_card to create a joker only with a specific prefix? e.g creating jokers only from my mod or smthn like that
it does work tho there's something weird
It's off center for some reason
i think
centered from the sides, a little too high
-# from my glance at least
maybe add align to the text node? idk
tru

huh
I don't even use the sound manager
what's the code for the must have room conditional?
if #area.cards + G.GAME.area_buffer < area.config.card_limit
hi something, how are you doing today
i fixed it by muting the draw_card function i used
apparently it uses sound
<@&1133519078540185692>
Task Manager, kill him
causes a crash
You replace area with the card area.
And G.GAME.area_buffer with the buffer.
Where can I find a template Lovely mod without anything else? I want to make a very simple Lovely mod but the example mod I've found includes a lot more stuff that I don't need, and I don't know how to remove what I don't need without breaking the mod.
what kind of mod are you trying to do
I want to add a custom deck to Cryptid by modifying their deck.lua. I have a good idea of what the modifications will look like.
Modifying the file via Lovely seems like the most relaible option.
a new deck?
Yes.
just add it as a deck within your own mod
But it depends on Cryptid's lib.
then make your mod depend on cryptid
I... don't know how to do that.
Does that just give me access to the Cryptid libraries, or do I need to load those myself?
it'll mean your mod only loads if the cryptid librares are also loaded
every mod has access to anything other mods make global
Okay so I don't need to load anything from Cryptid; I'll just have their globals.
Trying to make a joker that randomly changes the enhancement of a card when its played, but it kinda crashed. any help?
calculate = function(self, card, context)
if context.before and context.main_eval and not context.blueprint then
local enhanced = {}
for _, scored_card in ipairs(context.scoring_hand) do
if next(SMODS.get_enhancements(scored_card)) and not scored_card.debuff then
enhanced[#enhanced + 1] = scored_card
local eligible_card = pseudorandom_element('magic_elephant')
local edition = poll_edition('magic_elephant', nil, true, true,
{ 'm_mult', 'm_bonus', 'm_wild', 'm_glass', 'm_steel',
'm_stone', 'm_gold', 'm_lucky', 'm_fnaf_glitch', 'm_fnaf_pizza' })
scored_card:set_ability(edition, nil, true)
end
end
end
end,
what's the kinda crash log
is .modded_objects still something you can use? this is just a reappropriated version of one of SDM's functions, but it crashes saying it got a nil value where a table was expected

in my main file i have it set to PhilsMod = Smods.current_mod
oh pseudorandom_element is missing the table
@maiden phoenix
@daring fern can you help me ?
local eligible_card = pseudorandom_element(true, 'magic_elephant')?
Don't use that it's old
I do it differently nowdays, check a more recent version of the mod in the pools.lua
no, it has to be a table, not a boolean
i dont know what youre trying to pick there tho
good question
just trying to make randomly select a enchantement without having to manualy code the random selection
those also aren't editions
so using poll_edition is probably going to crash
you're looking for SMODS.poll_enhancement
what does it mean when it crashes because of something called "juice_up"
oh yeah
usually your card no longer exists when it's trying to juice_up
how does that work
or it simply doesn't exist
you used self instead of card
it is there until it is triggered
probably
let me see
used self and card
calculate = function(self, card, context) for example
wherever there is self there is also card
am i allowed to post my code here
yes
if card.debuff then return nil end samplejimbos detected
also what is the resource you're copying this from?
yeah using samplejimbos as a base
dont
I recommend checking the SMODS docs and VanillaRemade
i tried ripping the base game up but i couldn't figure out how
(I really wish VanillaRemade showed up when I google for it)
samplejimbos is badly written, I wouldn't recommend using it as a base at all
what is happening?? i keep getting this crash on almost every joker in my mod
bump
at least they updated it from 0.9.8
No way N you made VanillaRemade for Minecraft too? That's so cool
did you do SMODS.Joker = {... anywhere?
no, it's all just SMODS.Joker {
i have no idea what's happening like
it's not just this it's every joker
i ask because thats a common mistake i see
yea
and that would break all the other jokers
ddg does actually
i hate to break it to you but i think you committed a cardinal smods sin and you have to perform the ritual to eremel now now
all works now by the way, thanks guys
Damn DDG based
you should definitely double check this
yeah i don't know what's happening 😭
i mean like i'll look
umm
oh my god
you little
thanks
alright i did that and the game doesnt crash anymore but its only pulling the default joker i put in
in addition i also added set the .modded_jokers thing to {} in the main file before any of the files are asserted
after doing your SMODS.Joker tables you added them to the modded_jokers table?
trying to make the "must have room" conditional, crashes anytime a joker is attempted to be made.
whats the code
i get the feeling its the long line at 56
#G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit
so it's the .GAME. on cards and limit?
can i gift one of you coding guys a steam game to make me a single joker cause i cant 💀
a lot more than that
no but what is it
-# im honestly in the same boat as you right now, im lucky people are responding to my queries
oh ok i just saw eremels message from earlier because i couldnt figure it out with the identation lol
you're only calling blueprint_effect in context.press_play so it will only work on jokers that do stuff there
you should use press play to save the index of the left or right card but then call blueprint_effect outside of a context
still crashes after i replaced it
did you put the #
@red flower Query for you. I'm having trouble setting up this card to work with joker retriggers. Due to the way set_ability and its delayed sprites work, I can't figure out a decent setup so that the cards turned gold by this code wait to visually change at the same time that the message plays. Instead, if it's retriggered, all cards turned gold do so at the same time on the first message, and then nothing appears to happen on the second message even if the retrigger turned cards gold that were missed on the first iteration
local gold = 0
for i, v in ipairs(context.scoring_hand) do
if v.config.center.key ~= 'm_gold' and v:is_suit(G.GAME and G.GAME.wigsaw_suit or "Hearts")
and SMODS.pseudorandom_probability(card, pseudoseed('csau_goldexperience'), 1, card.ability.extra.prob) then
gold = gold + 1
v:set_ability(G.P_CENTERS.m_gold, nil, true)
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
return true
end
}))
end
end
if gold > 0 then
local flare_card = context.blueprint_card or card
return {
func = function()
G.FUNCS.flare_stand_aura(flare_card, 0.50)
end,
extra = {
message = localize('k_gold_exp'),
colour = G.C.MONEY,
card = flare_card,
blocking = true,
}
}
end
end```
I could just package set_ability in the event, but that means the cards don't have their updated values for the remainder of scoring
So if some other card wants to do smth with scoring gold cards, I'd prefer to have those chain off each other rather than it skipping this hand
oh ok
visual example of this
oh i hadnt done that thanks it works now
Honestly never worked with retriggers so no idea, sadly
Maybe having everything in func?
the problem is the conditional i guess
The colors of the non face cards are the low contrast version, how would I have it be the High Contrast ones?
local suits = {
Clubs = SMODS.Atlas {
key = "collab_dr_clubs",
path = "collab_DR_clubs.png",
px = 71,
py = 95,
}
}
for suit, atlas in pairs(suits) do
SMODS.DeckSkin {
key = atlas.key,
suit = suit,
loc_txt = "Deltarune",
palettes = {
{
key = "hc",
ranks = {'Jack', 'Queen', "King"},
display_ranks = {"King", "Queen", "Jack"},
atlas = atlas.key,
pos_style = 'collab'
}
}
}
end
Ugh yeah again the issue is packaging it func puts it in an event preventing the new enhancement from being visible further in the scoring order
Hnmmm
func doesnt put things in events
it just runs after all the scoring stuff so you can have an event that runs after it, but doesnt do it automatically
Hmm I see. But I think that might result in the same issue. I need a delay after the return block message
The main thing is just blocking the delayed sprite application to the second set of set abilities
hey, whats up with my identation?
My guess about the func thing is that maybe (i really dont know how retriggers work) the main part of calculate runs practically after it first triggered but anything returned runs after the again message, so it would put the set_ability delay event after the again message and the other stuff
looks bad on discord
oh ok
bad | good
idk where the "end" of context.press_play, bruh
?
what
what do you mean
i don't know where the "end" of the function context.press_play is
it's not a function it's a statement but there's a line
bruh
oh, real, ty
im dumb bruh
Im jeong dae from squid game
not the flavor, the effect
oh yeah if you have he gives $100 each round but he has a chance of getting impaled by a metal pole
Yes its a joke joker\
Am i stupid thats his effect 😭
The card gives $100 each round and has a chance to get impaled by a metal pole and die
"getting impaled by a metal pole" is not a balatro mechanic, what does it mean? is it just visual? does it get destroyed?
when does it get destroyed
1 in 8 chance when
top 10 hidden balatro mechanics you never heard of
when it gives the money or before or when
At the end of each round when he gives the money
Sorry i suck at
explaining things lmao
give me a sec
Bumping this because I'm almost home from work !!
SMODS.Joker {
key = "jeongdae",
loc_txt = {
name = "Im Jeong-dae",
text = {
"{C:money}$#1#{} at end of round",
"{C:green}#2# in #3#{} chance to get impaled by a metal pole"
}
},
pos = { x = 0, y = 0 },
rarity = 1,
blueprint_compat = false,
cost = 2,
config = { extra = { odds = 8, money = 100 }, },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.money, G.GAME.probabilities.normal, card.ability.extra.odds } }
end,
calc_dollar_bonus = function(self, card)
if pseudorandom("squidgamemrbeast") < G.GAME.probabilities.normal / card.ability.extra.odds then
SMODS.destroy_cards(card)
end
return card.ability.extra.money
end
}
figure out the visual part yourself :3
N is so nice and so helpful and so cool and so awesome
Nah that;s crazy
i think that have a any sytanx error, because after I moved the copy function outside of context.press_play, my joker stopped being recognized
calculate = function(self, card, context)
local targetJoker = nil
local availablePos = {}
if context.press_play then
print('press play')
if G.jokers.cards[1] and G.jokers.cards[1] then
print('test 1')
table.insert(availablePos, 1)
end
if G.jokers.cards[#G.jokers.cards] and G.jokers.cards[#G.jokers.cards] then
print('test 2')
table.insert(availablePos, #G.jokers.cards)
end,
if #availablePos > 0 then
local chosen_position = pseudorandom_element(availablePos, pseudoseed('losted_doodle'))
targetJoker = G.jokers.cards[chosen_position]
if targetJoker == card then
print('test 3')
targetJoker = nil
end,
end,
end,
local ret = SMODS.blueprint_effect(card, targetJoker, context)
if ret then
print('test 4')
ret.colour = G.C.PURPLE
end,
retun ret
return nil
end
just copy certificate in vanillaremade and replace the seal part for enhancement = 'm_mult'
I tried that but it didn't give me mult cards just unenhanced ones
Yo your the goat 😭
what version of smods
this is a recent change
Hmm I'm not too sure, gotta check when I get home
I'll send more info when I'm home from work !
if its not the last release then thats the problem
let me try myself tho
N ive never modded before were do i actually like put this goat to run it 💀
That would be sweet
worked fine
Them im a moron, I tried for like a hour, but im a beginner. Ill try to learn what I did wrong
anyway let me make sure i dont push mult certificate and squid game joker to vanillaremade
Nah get em both in
so this joker will destroy the joker to its left and right and add chips. that part works well, and i can get it to destroy the right joker on its own too, but it won't destroy the left joker on its own
my code is pretty messy but i don't see a reason why it wouldn't work
how is math.huge used (from talisman)
hi chat
im trying to patch the new SMODS.pseudorandom_probability() to allow me to check if a probability was rolled, and if it was successful
however since the function just returns with a pseudorandom() if i try to check with the same pseudorandom() beforehand it changes the actual outcome
so is there a way to get what pseudorandom() would return without changing its rng? i dont really want to have to patch at the function if i dont have to
if anyone wants to help i'll dm you the code because it's too long to show here
dont patch it, hook it
Do you mind sending what you wrote so I can learn from it, I promise I won't steal 😋
i mean i made vanillaremade so people steal from me
yeha thats kinda the point of vremade
true i could do that instead in theory but that wouldnt fix the issue
i did local _card = SMODS.create_card { set = "Base", enhancement = "m_mult", area = G.discard } in certificate
Everyone wants you to steal from em its the wave
yes it would?
hey there
maybe you can help me out so imma throw this in here aswell
#⚙・modding-general message
thats literally the reason it was made
Thank you so much, I think I removed the base part , so that's why
it would still return with that pseudorandom() at the end and throw off the rng outcome
Iirc Winter made a PR for something like this. Hopefully it gets pulled
https://github.com/Steamodded/smods/pull/785
local SMODS_pseudorandom_probability_ref = SMODS.pseudorandom_probability
function SMODS.pseudorandom_probability(trigger_obj, seed, base_numerator, base_denominator)
local ret = SMODS_pseudorandom_probability_ref(trigger_obj, seed, base_numerator, base_denominator)
if ret then
-- yep
else
-- nope
end
return ret
end
doesnt this still call pseudorandom() twice? once in this hook and again in the original function
calling ret here would call pseudorandom() because its in the function its referencing wouldnt it
ret is true or false, it's not a function
SMODS_pseudorandom_probability_ref calls pseudorandom once
I think you might be misundertanding hooks
how do i use it in this case then
i want to check the outcome of the pseudorandom_probability check before its returned
the --yep comment is where you would put the code you want when it succeeds, the --nope where it fails
you can also make your own context there for a more general thing which is what astra was talking about
oh does it
ok i didnt know that was a thing
how does that actually work im curious
how does it get the outcome
you mean the context thing or the first part?
no i know the context bit i mean how does checking if ret then check whether the probability succeeds
SMODS_pseudorandom_probability_ref just calls the original function and saves the return (a boolean) to ret
The hook basically says "wait before you return it for real let me check what the result was"
oooh ok i see now
im used to hooks as like
extra code at the start of the function then returning the rest of the function
but this is like an extra layer after the function returns
ok thats neat
This doesn't do anything, anyone know why?
calculate = function(self, card, context)
if context.before and not context.blueprint then
local queens = 0
local twos = 0
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 2 then twos = twos + 1 end
if context.scoring_hand[i]:get_id() == 12 then queens = queens + 1 end
end
if twos > 0 and twos < 2 and queens > 0 and queens < 2 then
card.ability.extra.created_tag = true
end
end
if context.destroy_card and context.cardarea == G.play and not context.blueprint then
if card.ability.extra.created_tag == true then
card.ability.extra.created_tag = false
if context.destroy_card:get_id() == 2 then
return
{
func = function()
G.E_MANAGER:add_event(Event({
func = (function()
add_tag(Tag('tag_ethereal'))
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)
}))
end,
remove = true
}
end
end
end
end
whats the intended effect
If played and scoring hand has one queen and one two destroy the two and create an ethereal tag.
question, is there a way to end the run by its entirely if a certain condition is met, even if I need to make a seperate SMODS commands
like if I hold a certain joker for a long time
yes, win or lose?
i had to test it to see it lol
you're resetting card.ability.extra.created_tag after the first card in the hand
do it when it destroys a 2
Hey N, I have another question, I made a booster pack a while ago, and I had particles in the background, but when I exit yhe pack, all the particles don't go away. Idk how to fix that. Also the name of the pack near the bottom just says error
for the name you need group_name in your loc_txt
behold
for the other thing no idea, ive seen it happen to other people but never saw what the solution was
That looks sick, what do they do?
The first one is for upgrading a hand type called "Roundabout" which is when 5 cards are played with no duplicate suits (my mod adds a 5th suit so this hand is possible)
The second one is for upgrading a hand called "Funny" which...... is when you.... play a 6, 9, 4, 2, and 0 (which my mod adds) in order
bump
I found this
https://github.com/Steamodded/examples/blob/master/Mods/EditionExamples/assets/shaders/ionized.fs
Oooo nice
help
how do i give a poker hand a specific amount of chips or mult
When you click on a consumable or a Joker and the sell tab appears, where is that implemented?
hi there i am currently attempting to mod balatro with the brainstorm mod. I have followed a video tutorial alongside multiple forum posts and everything is working accept i do not have a mods button on the homescreen of balatro.
can someone please help me figure out what i am doing wrong this is my first time doing something like this
never mind i did it !
Card:highlight and G.UIDEF.use_and_sell_buttons
thanks :3
okay so the mods button has appeared but brainstorm itself isnt working
calculate = function(self, card, context)
if end_of_round and not context.blueprint and context.blind.boss
and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit then
local jokers_to_create = math.min(card.ability.extra.creates, G.jokers.config.card_limit - (#G.jokers.cards + G.GAME.joker_buffer))
G.GAME.joker_buffer = G.GAME.joker_buffer + jokers_to_create
G.E_MANAGER:add_event(Event({
func = function()
for _ = 1, jokers_to_create do
SMODS.add_card {
set = 'Joker',
rarity = 'Common', 'Uncommon', 'Rare'
}
G.GAME.joker_buffer = 0
end
return true
end
}))
return {
message = localize('k_plus_joker'),
colour = G.C.BLUE,
}
end
end,```
my joker doesnt trigger after the boss blind
it should spawn another joker when this blind is won
it's context.end_of_round and it doesnt have context.blind, you need to use G.GAME.blind.boss
I tried context.end_of_round before but it ended up crashing all the time
because something else was wrong
Trying to make a shader for an edition, got this crash, any idea why?
How do I play a custom sound effect?
how would i check when the player cashes out?
i somehow read it as when the player crashes out lmao
context.starting_shop?
ohhh wait thats smart actually
How do I play a custom sound effec :(
yup that works ty!
^3
Please somebody tell me how to play a custom sound effect without putting it into the game files
can you guarantee luck for testing purposes?
Yes.
set G.GAME.probabilities.normal to math.huge
This isn't working
Code?
N the code you sent for the mult card worked perfectly thank you !
thanks
...
-- Play custom sound effect
play_sound('mj_Sparkstaffuse.ogg')
end
...```
I have it in assets>sounds>Sparkstaffuse.ogg
How did you define the sound?
It's in calculate
in if context.before
bruh
No, where is the SMODS.Sound?
I need to define the path at the top?
does anyone know why the description isnt working?
how do you do this
for context the suit does work as of now
i just dont know whty the rank is not displaying
calculate = function(self, card, context)
if context.end_of_round and G.GAME.blind.boss
and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit then
local jokers_to_create = math.min(card.ability.extra.creates,
G.jokers.config.card_limit - (#G.jokers.cards + G.GAME.joker_buffer))
G.GAME.joker_buffer = G.GAME.joker_buffer + jokers_to_create
G.E_MANAGER:add_event(Event({
func = function()
for _ = 1, jokers_to_create do
SMODS.add_card {
set = 'Joker',
rarity = 'Common', 'Uncommon', 'Rare'
}
G.GAME.joker_buffer = 0
end
return true
end
}))
return {
message = localize('k_plus_joker'),
colour = G.C.BLUE,
}
end
end,```
I got it to work
but it doesnt stop spawning jokers
how do i make custom rarities?
eval G.GAME.probabilities.normal = math.huge in the console
context.end_of_round and context.main_eval and...
No.
shit

i think it's Back
how do i combine the sound and the load image together
i want it so that it plays the sound when the image is loaded
Is there a way to for a joker to check if a probability fails?
How do I make the game check if I have a specify joker at my hand?
I know the rofflatro does it but it uses its own custom context
next smods update, yes
is this fine
imma try this tysm!!
is e_holo used for holographic cards?
next(SMODS.find_card("j_modprefix_key"))
bumpity
thank you
Should i put this code anywhere in my mod or make it part of the joker's code?
outside the joker
bump
N the booster pack group_name didnt work..
may i see the code
ok
remove the group_key
lmaoooo oops
Get sealed
it worked pefect ! omg
Gotcha!
localization is hard
game crashes when i hover over pickles
debug doersnt work
It's Back not Backs
So for what the functions outputs, if i want the joker to interpret the return as true or false, do I just do like if SMODS_pseudorandom_probability_ref == true?
that's what i said!
what i wrote is that you should do
replace the yep comment for the probability succeeding and the nope for it failing
check trigger_obj if you want to check a specific object (keep in mind it can be any kind of object)
i see, would like setting ret to true if it passes and false if it doesn't work as such?
sorry if i'm kinda aloof
yeah if you want to change the result change ret
gotcha
Would this work?
No.
How could i fix it
You would do SMODS.calculate_context({modprefix_probability_fail = true}) under the else.
Then check for context.modprefix_probability_fail
Wait do i do this inside of the pseudorandom func or inside the joker?
or do i not need the function at all?
Oh wait i might get it now
Did this i think it might work
No.
Oh? What should I change?
I might also recommend waiting a couple of weeks because these contexts will probably just get added to smods
Put it in the else of the hook.
can you post the full log
I guess I can do that for now
in which if block?
Ohhhh ok
hmm no idea
Is there a way to change what sprite a joker is using in the calculate?
wait what is the effect of the joker youre making
In this specific context it happened when i hovered over a planet in the shop
yes let me pull it up
Yes.
yayy ty!
oh my god i know whats wrong here
one of the mods i have installed seems to have made a typo
is there a way i can make the particles in booster packs, move upwards?
calculate = function(self, card, context)
card.children.center.scale = { x = card.children.center.atlas.px, y = card.children.center.atlas.py } -- declare scale
card.T.w, card.T.h = G.CARD_W, G.CARD_H
if card and card.children and card.children.center and card.children.center.set_sprite_pos then
card.children.center.atlas = G.ASSET_ATLAS['loy_alty'] -- pick atlas (loy is the prefix of atlas)
if card.ability then
if card.ability.loyalty_remaining ~= card.children.center.sprite_pos_copy.x - 1 then -- loyalty_remaining is the. loyalty card procs remaining, duh
card.children.center:set_sprite_pos({x = card.ability.loyalty_remaining + 1 or 0, y = 0}) -- set sprite pos acc to loy_remaining
card:juice_up(0.2,0.2) -- solely for fun
play_sound("cardSlide2") -- this sound actually interprets as hole punching
end
else
card.children.center:set_sprite_pos({x = 0, y = 0}) -- Just In Case
end
end
end
this is functionality for punching holes in loyalty card
it takes an atlas and moves the position to the right
so the image changes
Would it be suitable to just use card.children.center:set_sprite_pos for simply swapping the sprite every round then?
Both of those functions don't exist, also no_delete = true should be outside the func but still in the event.
bump
do the boss blind calculate contexts like stay_flipped and debuff_hand work as expected in jokers?
I didn't work unfortunately
is there another way to start a new run?
Yes.
What SMODS version are you on?
You mean restart the run?
You need this version: https://github.com/Steamodded/smods/archive/refs/heads/main.zip
how would i destroy a card after it's done being played?
Is this the latest version?
Yes.
trying it now, will keep you updated
Try looking at how holding r does it.
which lua exactly
controller.lua
this?
It works now but mainly for probabilities that occur during or after a round ends
not during the beginning of the round
cuz some of the jokers I made have probabilities that occur when selecting a blind
but my joker never upgrades itself when those probabilities fail
how do i change Edition with DebugPlus?
Ctrl + Q over the card
mouse above card
Does anyone know how to check if a poker hand has been played more than once
Yes.
You have to change your jokers to use that function.
Would this work to check if a hand has been played once?
how can i make a joker thats just blueprint but 10 times
why is alpha not working in my shader
config = { hand_size = -1 },
pos = { x = 0, y = 0 },
order = 1,
atlas = "DTiny",
unlocked = true,
loc_vars = function(self, info_queue, back)
return { vars = { self.config.hand_size } }
end,
apply = function(self)
G.GAME.starting_params.hand_size = G.GAME.starting_params.hand_size + self.config.hand_size
why does it subtract 2? hand size
you say this like i havent already checked this
it calls a function
isnt there something with repetitions
but idk if its for jokes
im not good at lua but cant you use a loop to return the function mutiple times?
true, biut this feels counterintuitive
wtf? does alpha just not work??
fair, idk then srry
I'm trying to make a joker that adds chips when per every poker hand played for the first time, but it isn't doing so in my code
if I had to guess, by the time this happens the played count is 1 when it's the first time it's played
Oh I see
should i do <=
less than or equal to
Also a better way to do that would be to access G.GAME.hands[context.scoring_name] directly instead of looping through every hand
Try it
nvm figured it out
local other_joker
for i=1, #G.jokers.cards do
if G.jokers.cards[i] == card and G.jokers.cards[i+1] then
other_joker = G.jokers.cards[i+1]
end
end
local effects = {}
for i=1, 10 do
local effect = SMODS.blueprint_effect(card, other_joker, context)
if effect then
table.insert(effects, effect)
end
end
return SMODS.merge_effects(effects)
🥄
any way to get this to not account for eternals?
i've been reading steamodded's wiki page on the SMODS.Rarity but i dont understand what it's telling me
not like that, you'd have to loop through all the jokers and make a new list that excludes the eternal ones
For some reason my patch doesn't seem to be working properly
I keep getting the crash in the screenshot whenever i click on a card
[[patches]]
[patches.pattern]
target = "functions/UI_definitions.lua"
pattern = '''
if card.area and card.area.config.type == 'joker' then
'''
position = "after"
payload = '''
lock = {n=G.UIT.C, config={align = "cr"}, nodes={
{n=G.UIT.C, config={ref_table = card, align = "cr",maxw = 1.25, padding = 0.1, r=0.08, minw = 1.25, minh = (card.area and card.area.config.type == 'joker') and 0 or 1, hover = true, shadow = true, colour = G.C.UI.BACKGROUND_INACTIVE, one_press = true, button = 'lock_toggle', func = 'can_lock_card'}, nodes={
{n=G.UIT.B, config = {w=0.1,h=0.6}},
{n=G.UIT.T, config={ref_table = card.ability, ref_value = "lock_text",colour = G.C.UI.TEXT_LIGHT, scale = 0.55, shadow = true}}
}}
}}
'''
match_indent = true
times = 1
so something like this? but then how would i get the destroy effect to only target that joker
that's not what I said at all
How do I manipulate the spawning of cards from any source? I want to change the type of a card as it spawns.
you would need to hook/patch create_card
local jokers = {}
for _, v in ipairs(G.jokers.cards) do
if not v.ability.eternal then
jokers[#jokers+1] = v
end
end
SMODS.destroy_cards(jokers)
``` 🥄
How does create_card_for_shop relate to it? I assume I only need to patch the one.
i had a REALLY stupid idea for a mod but idk if i could do this without help
hear me out:
joker mastery
More of a #⚙・modding-general topic I feel like
maybe
create_card_for_shop uses create_card afaik, it just adds some shop things
is the context for starting the game different from the context for starting a run
i mean i assume it is i just dont know the code
No, because they both don't exist.
use a different font
then why does Game.start_run work for an if statement
like doing if Game.start_run??
yes, apparently that runs the code right when the game boots up
i dont think that's correct
that statement is always true
because the function exists
then the code's just running every frame?
If it's not in an update or draw function then no
if it's in calculate it might be running every context
is that line 1
then this will run as soon as it loads
im wondering if i can set the if to run when the player starts a run instead of just when the file is loaded
How do I get if a card is a planet card?
you would need to hook that function
card.ability.set == "Planet"
game crashes if too much are used, any way to have this not happen?
Make it blueprint incompatible.
hey so this is the ID of my zero rank, but im worried it will change if there are other mods, how can I get this ID from the rank?
Bump
true, but i want it to work together, unless making it incompatable does what i think it does
Is there a log or does it hard crash?
there is a log it says stack overflow
Then there is no other way.
bump
how can i make my music track override everything else?
e.g. if i'm playing cryptid and i get a big big score, i don't want it to override the music playing from my mod
Return 1.7e308 in select_music_track
i think v.ability.eternal is causing issues somehow
well i only want it to play when i have a joker of a certain rarity
which is already in there
Return it along side checking for that.
is there a way to make it so if a certain config/bool is true then give this joker a soul overlay