#💻・modding-dev
1 messages · Page 480 of 1
This?
SMODS.ConsumableType {
key = 'fnaf_item',
loc_txt = {
collection = 'Item Cards',
name = 'Item',
undiscovered = {
name = 'Not Discovered',
text = {
"Purchase or use",
"this card in an",
"unseeded run to",
"learn what it does"
},
},
},
default = "c_fnaf_pizza_maker",
primary_colour = G.C.GREEN,
secondary_colour = G.C.GREEN,
collection_rows = { 5, 6 },
shop_rate = 2
}```
hmm i dont see the problem sorry
anyone know why this isnt activating 100% of the time?
what's this supposed to do
How does one make unscored cards turn into a certain thing
change the number every time a hand is played
the syntax would be this
if context.before then
card.ability.extra.chosen = pseudorandom("seed", 1, 6)
end
depends on the timing you want
you can use context.individual and context.cardarea == 'unscored'
is default a valid parameter
yes
i love documentation (i saw it right after asking)
sorry after scoring
context.after then
what's your consumable's code
that didn't work for some reason
what's the entire code
on one of the if statements?
after the math.random
ok, if you set chosen to a specific number does it work?
SMODS.Consumable{
key = 'pizza_maker',
set = 'fnaf_item',
atlas = 'TarotFnaf',
pos = {x = 4, y = 1},
config = { max_highlighted = 2, mod_conv = 'm_fnaf_pizza' },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS[card.ability.mod_conv]
return { vars = { card.ability.max_highlighted, localize { type = 'name_text', set = 'Enhanced', key = card.ability.mod_conv } } }
end,
}
oh yeah youre missing the part where you insert the consumable into the type
still instant
ohhh i thought it just didnt work at all
Hi. needing some help with this:
It seems like it is trying to set the meta table for SMODS.GameObject in my overwritten 8 ball. any help?
function SMODS.GameObject:__call(o)
o = o or {}
assert(o.mod == nil, "Created object should not have \"mod\" field defined.")
o.mod = SMODS.current_mod
o.original_mod = o.mod
setmetatable(o, self)
for _, v in ipairs(o.required_params or {}) do
assert(not (o[v] == nil), ('Missing required parameter for %s declaration: %s'):format(o.set, v))
end
if o:check_duplicate_register() then return end
-- also updates o.prefix_config
SMODS.add_prefixes(self, o)
if o:check_duplicate_key() then return end
o:register()
return o
end
you need to put the sprite change in an event
it was activating like as soon as i press play hand, i want it to go when scoring finishes
i haven't had any of my questions answered recently; it would be really helpful if somebody helped me on this 😭
jesus christ finally. i had to use context.ending_shop and add_to_deck() to update the debuffed suit because context.setting_blind is too late of a timing but it works. fuck this game and FUCK context.debuff_card
what
yeah i just dont touch debuffing much haha
you mean when changing config.lua?
you're never adding your card to the consumabletype (default is not enough)
thank you for the help though N i would not have been able to work out any of that on my own
no, when changing the options in-game, they do not save after a reload
so how do I fix it?
oh that makes sense
something like this?
context:
-- 8 Ball
SMODS.Joker('8_ball', {
config = { extra = { spectral_odds = 8, spectral_base = 1, tarot_planet_odds = 8, tarot_planet_base = 3 } },
--atlas = 'reddit_jokers',
--pos = { x = 6, y = 0 },
calculate = function(self, card, context)
-- CALCULATE
end
set_badges = function(self, card, badges)
badges[#badges + 1] = credit_badge('USER', false)
end
}
)
```lua
yes but youre missing a return true in the event
got it
Lowkey I don't think I know what I'm doing
is this supposed to be a take ownership
hopefully?
thats not the syntax
hm
youre missing the take ownership part
sometimes i just don't use context.debuff_card and just manually debuff lmao
the humble SMODS.debuff_card:
i love smods debuff card
fuck debuffs don't like em fix your game thunk
what do you guys think? (mods done im js playtesting)
Is there in ipair for unscoring or am I tripping
@vast night? thought you were gonna say something 😭
no, context.full_hand has the full hand, you can do SMODS.in_scoring(context.full_hand[i], context.scoring_hand)
oop sry didnt see that
lemme see
weird. does the tab show up at all. afaik nodes should be definition
both tabs show up perfectly fine
shows up as config too
can i change the text color on the mods badge
wait hold up is it like this or
SMODS.ConsumableType {
key = 'fnaf_item',
loc_txt = {
collection = 'Item Cards',
name = 'Item',
undiscovered = {
name = 'Not Discovered',
text = {
"Purchase or use",
"this card in an",
"unseeded run to",
"learn what it does"
},
},
},
pools = {
["Consumable"] = true,
},
default = "c_fnaf_pizza_maker",
primary_colour = G.C.GREEN,
secondary_colour = G.C.GREEN,
collection_rows = { 5, 6 },
shop_rate = 2
}```
because it isnt working
i mean in that case what do i replace with definition
no, instead of "Consumable" it should be your consumabletype key
just rename nodes with definition and if your nodes are set you can try
like every mention of nodes?
ok i think it's time to switch over to new probability. how do i convert this to the new format
no just in G.UIT.ROOT
like the definition of it
and after that I insert it on the joker?
in the add_card event?
SMODS.pseudorandom_probability(card, 'YOUR_JOKER', BASE, ODDS)
alright thanks
no, you only need that and what you had before
this will take a while
ye
now everything is blank
-- config tab
local function cryptpostingConfigTab()
local crp_nodes = {}
-- http toggle
crp_nodes[#crp_nodes + 1] = create_toggle({
label = "HTTP Module",
active_colour = G.C.DARK_EDITION,
ref_table = cryptposting_config,
ref_value = "HTTPS",
})
return {
n = G.UIT.ROOT,
config = {
emboss = 0.05,
minh = 6,
r = 0.1,
minw = 10,
align = "cm",
padding = 0.2,
colour = G.C.BLACK,
},
definition = crp_nodes,
}
end
while im at it
when converting one of my jokers to the new randomness im getting this crash. any help?
SMODS.pseudorandom_probability(card, 'j_reddit_8-ball', card.ability.extra.spectral_base, card.ability.extra.spectral_odds)
lemme check that im not sqrewing you over
nope its nodes
mb
it was prob smtn else
whats this crash 😭
this is the second time..
can you post it fully
i can honestly see nothing wrong
alright then i'm back at it again
Bump, then bump again. Surely it'll make a splash if I just do it one more time.
welp try maybe copying my toggle and see if t hat works?
create_toggle { col = true, label = "", scale = 1, w = 0, shadow = true, ref_table = reddit_config, ref_value = 'enable_bonanza_packs' }
idk why col = true
oh ok it's the same reason
the game is still calling the original 8 ball function and it's checking card.ability.extra (where the odds are originally)
how do i replace the calc function 😭 idfk what the fuck im doing
the main thing is that the config works (enabling it in-game does work) UNTIL the reload occurs, in which everything is reset to false for some goddamn reason
never used take owenership but i think if you return something always in the same context it shouldnt call the original
well okay what about this? why does this crash?
It would be SMODS.add_card({key = "j_crp_bulgoe"})
oh right fuck i forgot that was already solved 😭
oopsie
okay well then yeah the config stuff is really the last thig i have to solve before pushing this commit
How can I make my joker trigger every round. So when I complete a split it does something.
so ig every split
What's a split?
blind idk
context.end_of_round and context.main_eval
(context.end_of_round and not context.blueprint and not context.retrigger and not context.individual and not context.repetition)
if you mean at end of round
No.
sank yuu
no?
context.retrigger doesn't exist.
ok
nope. even putting a return in the end dosent work. do you wanna see the whole thing
yes please
i'm pretty sure this is what cryptid uses though
let me find the code
Then it's wrong.
context.retrigger never existed.
Also context.main_eval skips the checks for not context.individual and not context.repetition
i meant a return if it fails the probability too
this is a portion of the clockwork joker from cryptid that uses context.retrigger
context.before and context.cardarea == G.jokers and not context.blueprint and not context.retrigger then
this is a portion of scalae from cryptid that uses almost exactly what i just said
(context.end_of_round and not context.individual and not context.repetition and not context.blueprint)
hmmm, i'll try using that instead then
ye i just removed that in the pasted code
try this #💻・modding-dev message
What's the "context.other:is_suit" for enchantments
SMODS.has_enhancement(context.other_card, "m_modprefix_key")?
SMODS.Joker {
key = "cassie",
atlas = 'Joker',
pos = { x = 5, y = 4 },
blueprint_compat = true,
rarity = 2,
cost = 4,
config = { extra = { odds = 3 } },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = {key = "fnaf_WIP", set = "Other"}
return { vars = { G.GAME.probabilities.normal or 1, card.ability.extra.odds } }
end,
calculate = function(self, card, context)
if context.joker_main and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
if context.using_consumeable and not context.blueprint
and context.consumeable.ability.set == 'fnaf_item' and (pseudorandom('fnaf_cassie') < G.GAME.probabilities.normal / card.ability.extra.odds) then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({
func = (function()
SMODS.add_card {
set = 'fnaf_item',
key_append = 'fnaf_cassie'
}
G.GAME.consumeable_buffer = 0
return true
end)
}))
return {
message = "+1 Item"
}
end
end
end,
}```
```lua
SMODS.ConsumableType {
key = 'fnaf_item',
loc_txt = {
collection = 'Item Cards',
name = 'Item',
undiscovered = {
name = 'Not Discovered',
text = {
"Purchase or use",
"this card in an",
"unseeded run to",
"learn what it does"
},
},
},
pools = {
['fnaf_item'] = true,
},
default = "c_fnaf_pizza_maker",
primary_colour = G.C.GREEN,
secondary_colour = G.C.GREEN,
collection_rows = { 5, 6 },
shop_rate = 2
}```
it still doesnt work
this worked! tysm
omg i saw smt hi smt
Thank you
dunno then
The goat of this server/chat
there are so many goats in here
i'm likely just going to comment out my config at this point if i can't figure out why the config options aren't saving due to how important of a feature that is lol
Agreed
what do i put in loc_vars if in config = { extra = { i have repetitions = 1, odds = 5?
card.ability.extra.repetitions and card.ability.extra.odds
so just return { vars = { card.ability.extra.repetitions, card.ability.extra.odds ?
how do i make a 1 in 5 probability to retrigger something
im looking at 8-ball in vremade and confused
if pseudorandom("seed") < G.GAME.probabilities.normal / 5 then return {repetitions = 1} end
do i have to increment the consumeable buffer with each usage of add_card before the reset, or does it only need the +1?
how do you change a different card's enhancement through code?
yes, you should
like is it
-buffer + 1
-consumable,
-message
-buffer + 1
-consumable,
-buffer 0
-message
or
-buffer + 1
-consumable,
-message
-consumable,
-buffer 0
-message
card:set_ability("m_key")
first
got it thanks
which is the dollar function that does it immediately and which is the dollar function that happens at end of round
The ease_dollar function has a parameter to happen immediately
Otherwise it's queued as an event whenever it's called
Unless you mean the entire round eval UI
i just need dollars that happen during joker_main
Wouldn't you just return dollars = number?
You'd just use ease_dollars or return dollars from a calculate function
Or use SMODS.calculate_effect?
ok
Also Something if you're gonna keep putting question marks on my suggestions without elaboration I'm probs gonna block you.
Either tell me what the issue is or don't interact with me
also i think you're right abt ease_dollars having a parameter to act immediately given thats how vanillaremade's wraith works
It's ease_dollars not ease_dollar
Cool?????? And it's a single letter mistake that can easily be sorted out by the person I'm responding to. They won't have more trouble finding it
Regardless I wouldn't be annoyed by the correction if you just added onto it in reply rather than the vague suggestion that I was incorrect entirely
it isnt made exponentially more difficult to understand what theyre saying if theyre off by one letter
the error is easily caught by anyone who spends any amount of time looking through vremade or the smods documentation
a one letter difference doesnt do enough to warrant any reaction more than "small correction, there's an s at the end"
How do I check if the player has a specified tag?
Loop over G.GAME.tags and check tag.key
Why isn't my inactive mult updating in the desc ? (yes the desc is in french ask is you need a translation)
in the game screenshot i already skipped a booster which is needed to make the Xmult gain X1
Change #1# to #2#
but it will start at 2 where it starts a X1 mult
it starts off a 1 and updates now thanks x)
:)*
Is there a way to have a joker use 2 tiles for it's texture?
No.
You would have to create a new atlas.
new atlas?
That's not how you do what you're doing anyways
You'd need to either do some fun shader stuff to accomplish this with a big atlas of the tiles and then the shader computing where on the atlas to draw from for which screen pixel to draw, or you could probably do something clunkier by creating a new child sprite where both the center and the new child contain one half of the sprite, whereas the other half is empty pixels
this is what it looks like right now.
It's only 1 tile but it's made wide with display_size
I just want it to use this 2 tile texture
but if that's not really accomplishable I'll just use the 1 tile
Ah I see
you could use a unique atlas for it and set the atlas size to be twice as wide
How would I do that?
Make a new atlas and do px = 142, py = 190
Uhh yeah I've had this issue before with some cards. Basically, the stickers are drawn respective to the reference width of the card rather than specifically the center object, though I don't know the specific underlying reason why. I did a workaround to temporarily scale up the card to draw it where I wanted it, though the method I used would also stretch the image if it was done on something without the same aspect ratio
leave it like this, its perfect
how can i become wide
expand
can you expand me
eat food
i love eating food
eat
i just ordered food as a treat :3
i forget to eat all the time
i just dont be hungry so i dont
Like clearance sale?
yes
Modify G.GAME.discount_percent
got it
Ortalab reference
?
Not too sure why this one is crashing . Any JokerDisplay wizards in chat?
I'm getting the same crash for any card using a colour field in a text_config table
wheres mr display himself at
Probably joyousing his spring
Why do I get this error?
tell me if it works
or if the crash reason changes
Yeah it was that
i am so smart
-# lie lol
you have one set of brackets too many in text
what

amazing emoji
isn't it? lmao
also i recommended using the new thing of putting the jokerdisplay directly in the smods.joker code, it's nice
I was gonna do that ngl but the external file seemed less daunting
if its so nice why is it not automatically implemented into mine
it is. the mine is exploding in 20 seconds
Alright finally done debugging all of my Jokers. My last problem now is that my Horoscope cards aren't showing their displays despite the hook
yeah
that'll do it
i could devour you
no you couldn't
ill be there at 7 tomorrow
Maximus 1.1 will officially have JokerDisplay support 🎊
I want to start giving display support but that has to wait for me to finish talisman and lack thereof compat
Sometimes shit dont work with talisman and sometimes it dont work without
finally 
Add 34 more
HELLLL NO
this version already taking long enough 😭
Smh my head
time to test all 30 
yall what could this possibly do
it checks if the table contains a value
you could combine both of them into one and make that the challenge
it's also wrong because you need to pass the table twice lol
...that'd be inverse of Jokerless, wouldn't it? 😂
oh my god youre right lmfao
i mean it could still be fun
maybe...
i think im just being silly here but i cant seem to figure out how to actually make the function trigger
im trying to make it a global thing since before it would always start the hand at high card when you pick up the joker, when i wanted it to start as the last hand you played
but im a little lost on how to actually accomplish this 
its also crashing when i hover over the joker now i guess thats the bigger issue
First thing coming to mind to ban are Standard Packs...
soul_pos like pos
i thought you had to set the rarity to 4
oh are you referring to the overlay that the legendary jokers & hologram have?
ye.
right, sorry for the confusion
oh yeah
better question actually because i realized i was approaching this fully the wrong way, if i wanted a calculate function outside of a joker, what would i replace self and card with in the function?
bump
No.
You would hook SMODS.calculate_context
thanks
whats the process for that?
check how to do list picks a random hand and then use context.debuff_hand
local smodsoldcalccontext = SMODS.calculate_context
function SMODS.calculate_context(context, return_table)
local g = smodsoldcalccontext(context, return_table)
if context.after then
-- do things
end
return g
end
what variable stores the current blind requirement
is context.debuff_hand a function or a variable
G.GAME.blind.chips
variable, check the link
ah
are you sure i thought that was the score
that's G.GAME.chips
wait so how does it actually debuff a hand
ah
wdym
i'm trying to debuff the hand that gets picked so that it's not allowed to be played
keep in mind that if you want to edit it you also need to do G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
yeah that's what it does
did you read the code in the link
no im just checking the current score in relation to the blind requirement
oh oops i sent the wrong one haha
sorry this one
https://github.com/nh6574/VanillaRemade/blob/975e35dce07617c7a9db01ce032152b07e4f0f2f/src/blinds.lua#L351
i fail to see how t-
Oh
does this work for a joker?
yes
one last thing, im trying to add a fallback here in the localization so if the hand isnt chosen yet (happens if youre looking at the collection in the menu) it still displays, but ive tried like 5 different things and its being weird
you can also return debuff_text to set the text in the middle of the screen
i love that
localize(G.GAME.sackboy_hand or "High Card", 'poker_hands')
waaait what context should i put the debuff in
ohhhh i understand now tysm
so this is like
a step in scoring that checks to see if the hand is debuffed
or something?
so like
I'm trying to have my enhancement show the image, but it just shows red deck. What would i do to fix this?
-- Astral
SMODS.Atlas{
key = 'astral',
path = 'AstralEnhance.png',
px = 71,
py = 95
}
SMODS.Enhancement {
key = 'astral',
pos = { x = 0, y = 0 },
}
no wait
why is it doing that? i'm not trying to edit any of the values, i'm just trying to check for them
without the .name i think
You need to put atlas = 'astral' in the enhancement.
blind.chips
It worked, thank you!
so will this only play the message and upgrade if i actually PLAY the debuffed hand
it will play it every time you select a card haha
Oh
there's a check for when playing
what's that
let me look it up
not context.check
so like
or do i do if context.debuff_hand and not context.check
like the old code but with that added
this
ah ok
how do i stop the first part of this calculate function from triggering at the end of the round?
what's the difference between these two
why are they different with the pseudorandom_element
does this properly debuff the hand for you? i have a joker that id like to debuff 3 specific hands in a similar manner to how boss blinds do it but im not actually sure how to make them not score
ive just been setting the score to 0 😭 which doesnt really accomplish the same thing since you can still make money and stuff
the timing, the first is at end of round and the second is when the joker is created
but yeah why is the function call different
what's with the false_to_do
and the whole card.area stuff
that's not there in the end of round one
when the joker is in the collection it uses a different seed
so it doesn't affect gameplay
ah
what version of smods
um
latest i believe
1.0.0~BETA-0614a-STEAMODDED
whats the issue
ah.
you need to change it to v.visible
?
Is it truly a good challenge if you can win
instead of SMODS.is_poker_hand_visible
no, can i see a bit more to see how you named the variables
Oh
still not debuffing it on latest i fear
can i see the rest of the code
it. didn't debuff the hand for me either
maybe it's bugged haha
theres stuff under it but its just returning xmult
my debuff just scored as usual and didn't upgrade or anything
i remember trying to get it to work earlier but i didnt actually understand how the blind code worked and it crashed first try so i just gave up LOL
oh wait i see what's wrong with both
@vague crest @median veldt change scoring_hand for scoring_name
👍
ohhhhh my PEAK it works and it tells you properly too
thank you SO much you are a godsend
so i managed to code a joker that "ends" a boss blind when selecting it
return{
G.GAME.blind:defeat(),
message = 'Ended!',
colour = G.C.FILTER,
card = card,
}
end```
and this just happens
(sends me to the cash out screen when i play a hand..)
Maybe you'd want to move that to context.first_hand_drawn? And move the G.GAME.blind:defeat() outside the return or put it as
func = function()
G.GAME.blind:defeat()
end
in said return...
...I have a Boss Blind that auto-plays the first drawn hand in its' entirety.
So, may not be too early...
is there a way to quick reload localisation
try this
#💻・modding-dev message
hmm let me see then
-# Oh yeah, the need to set those too--
do u think this formatting is off in any way
o it does work!
thanks by the way
so the poker hand must be a straight to goin X1 chips?
or does it have to contain a straight?
o alr
it changes
wording is good then
its not the wording im very good at seeing how base game jokers word things
i mean the actual placement of the words
since lines are manual
also does G.GAME.hands include modded hands
yes
sweet
here it is with something like four of a kind since its longer
WAIT I NEVER KNEW THIS EXISTED
THIS IS HUGE WTF
i love you
:3
:3
i have a contraption that puts all cards held in hand into an array, and im wondering how id check for a two pair out of these values
i realized this is a much harder thing to check for than i had in my head 😭
here's the first thing i thought of:
sort it, and then make a variable which goes up by one every time there are 2 numbers in a row that are the same, and then if the variable is greater than 1 there's a two pair
there's gotta be an easier way tho
wait that sounds super doable actually
:3
i dont remember how to actually sort it but
there's a table sort
there's also a function to evaluate poker hands in the game
you can use that to check for all the contained two pairs
oh?
lol there's the easier way
check what burnt joker does with the discards
but do it with G.hand.cards
the funtion returns something like text, scoring_hand, poker_hands
like so?
you must have missed the patch, now the Flint makes players die irl when playing
ohhh wait it works it just doesnt work if something higher ranking is there currently
how would i change it to work with higher ranking hands still?
FLIIIIINTTTT 
would that mean im just looking for the scoring_hand part instead?
no, the poker_hands
https://github.com/TheOneGoofAli/TOGAPackBalatro/blob/40b7af0800068e8d5642a5e7ba2ebc04ea855154/items/voucher.lua#L200-L201 I have a Voucher that checks for Flushes if that is of any help, accounting for Straight Flushes, Flush Houses and Flush Five, if that's of any example help. 🍞
will check this out 
why does this tally also increase on repetiton or blueprinting
if not context.blueprint and not context.retrigger_joker?
i think it's not context.repetition_only? something like that
never heard of that context in my life but i trust the process
got it working! the issue was straight up just i didnt understand what the _, was for
this example helped a lot ty
did nothing
damn
i want the counter to increase only when you score a card for the first time
is there a reason you don't do it in context.before
do what in context.before
increasing the counter
i want the cards to give +mult as they're scored ideally
you can... do both
I'm trying to make this joker activate when a two pair is played but it activates whenever the hand includes a two pair like full house. Is there anyone who knows how to fix this?
SMODS.Atlas{
key = 'TWOPAIR',
path = 'TWOPAIR.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'TWOPAIR',
loc_txt = {
name = 'TWO PAIR!!!',
text = {
'Gain {C:money}$2{} if poker hand is a {C:attention}Two Pair{}.'
}
},
atlas = 'TWOPAIR',
pools = {["Batrocities"] = true},
rarity = 2,
cost = 6,
pos = {x=0, y=0},
unlocked = true,
discovered = false,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
config = { extra = { dollars = 2, type = 'Two Pair' } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars, localize(card.ability.extra.type, 'poker_hands') } }
end,
calculate = function(self, card, context)
if context.joker_main and next(context.poker_hands[card.ability.extra.type]) then
return {
dollars = card.ability.extra.dollars
}
end
end
}
alright i'll recode the whole effect tomorrow
i have a better idea
as in, to make this effect work
instead of next(context.poker_hands... blah blah do: context.scoring_name == "Two Pair"
update: i have given the event for specifically the flint, on specifically the hierophant, exactly one frame of delay
will this fix the crash? probably, since the issue was that hierophant didn't exist yet
on specifically the flint
i hate the flint
what was the issue?
are you running something before balatro exists
-# at least according to the print check
is that even a possibility
no but it's funny
true i laughed
anyway, good night
WHAT MORE DO YOU WANT
also, good night
Im also going to bed goodnight bestie
....so what if i give it 2 frames
what's the full code for that
in an "is this blind the flint" else conditional
c_heirophant
im sorry
THUNK
valid crashout
if this works
Thank you, it worked.
god
damnit
F
no matter how solid your code
it's powerless against
coding
you know what's worse
i had went earlier "oh i spelled hierophant wrong in the key whoops"
i dont even know if this is credit worthy outside of the one thunk already has
but thanks n
don't tell her about Seltzer
or Canio
what
SMODS.Joker:take_ownership("caino",
the Vanilla key is misspelled
SMODS.Joker:take_ownership("selzer",
same with Seltzer
yeah ik
i had to use it lmao
how can i check the price of a reroll?
can I call a Joker's calculate function from anywhere, provided it exists?
Yes.
G.GAME.current_round.reroll_cost
thanks something
but that doesnt take into account if the reroll is free from jokers like clown, how would i do that?
It does for me.
if G.GAME.current_round.free_rerolls > 0 then, but reroll_cost should handle it just fine
i have this and its still adding reroll cost even with that ```lua
if context.reroll_shop then
card.ability.extra.current = card.ability.extra.current + G.GAME.current_round.reroll_cost
end
i'll just use this, thanks you two!
Have you tried putting calculate_reroll_cost(true) before it?
like this? ```lua
if context.reroll_shop and calculate_reroll_cost(true) then
No.
if context.reroll_shop then
calculate_reroll_cost(true)
card.ability.extra.current = card.ability.extra.current + G.GAME.current_round.reroll_cost
end
oh just that, no i havent, i'll try that
so that works for the first free reroll, if there's two the second one is adding 5, and the next one is adding 6 eventhough it costs 5
attempting to add a glass card when a diamond card is destroyed, but it gets stuck here for some reason?
using pretty much the same code as marble joker
can send code anyways though
this is effectively a softlock if that narrows anything down, cant select discard or play hand
Why are you using create_playing_card?
use SMODS.create_card, its typically a bit more reliable at creating the intended behavior in my experience
oh gotcha, i was just using what vremade did
No?
I would always recommend at least reading over the code of Vremade, since sometimes it can be a bit funky. I had to take ownership of all the Vanilla Jokers recently and sometimes Vremade let me down
calculate = function(self, card, context)
if context.setting_blind then
local _hands = card.ability.extra.h_plays * math.floor(((G.GAME.dollars or 0) + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
G.E_MANAGER:add_event(Event({
func = function()
ease_hands_played(_hands)
SMODS.calculate_effect({
message = localize({
type = "variable",
key = "a_hands",
vars = { _hands }
})
}, context.blueprint_card or card)
return true
end
}))
return nil, true
end
end
I'm guessing this visual bug has something to do with context.blueprint_card or card but I'm not sure how to fix it. Any suggestions?
Why can't you just return that?
Everything in SMODS.calculate_effect?
G.E_MANAGER:add_event(Event({
func = function()
ease_hands_played(_hands)
return SMODS.calculate_effect(<args>)
end
}))
like this?
No, return the table in it.
Also outside of the event.
And do ```lua
func = function()
G.E_MANAGER:add_event(Event({
func = function()
ease_hands_played(_hands)
end
}))
end
softlocks the game
calculate = function(self, card, context)
if context.setting_blind then
local _hands = card.ability.extra.h_plays * math.floor(((G.GAME.dollars or 0) + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
G.E_MANAGER:add_event(Event({
func = function()
ease_hands_played(_hands)
end
}))
return {
message = localize({
type = "variable",
key = "a_hands",
vars = { _hands }
})
}
end
end
issue persists now that i have the smods create card working
Do you require the animation?
You mean freezes?
i guess not explicitly? i feel like its a pretty good thing to have for player feel though
since the suit and rank are random so its more relevant to see it
when setting the blind, the game softlocks, as in it still runs but the player cannot do anything. None of the cards or UI appears as it should when selecting a blind
You need to return true in the event.
Try using this code instead: https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua#L515
is there a way to manually push the card into the deck? because the issues pretty clearly that it's not doing that on its own
oh huuge
i guess i could just go the same route as the one i did with panic button
this works, but itself causes a separate visual bug where the hands don't get added until the cards are drawn. this is in contrast to Burglar, where the hands appear alongside the text
happens even with trigger = "immediate" for the record
calculate = function(self, card, context)
if context.setting_blind then
local _hands = card.ability.extra.h_plays * math.floor(((G.GAME.dollars or 0) + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
return {
SMODS.calculate_effect({
message = localize({
type = "variable",
key = "a_hands",
vars = { _hands }
})
}, context.blueprint_card or card),
func = function()
G.E_MANAGER:add_event(Event({
func = function()
ease_hands_played(_hands)
return true
end
}))
end
}
end
end
changed to this, as I'm assuming you meant have all of this stuff in the return for calculate. Visual bug still occurs
Why did you turn the return into an SMODS.calculate_effect inside the return?
you're saying just return message?
if context.setting_blind then
local _hands = card.ability.extra.h_plays * math.floor(((G.GAME.dollars or 0) + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
return {
message = localize({
type = "variable",
key = "a_hands",
vars = { _hands }
}),
func = function()
G.E_MANAGER:add_event(Event({
func = function()
ease_hands_played(_hands)
return true
end
}))
end
}
end
same thing happens
if context.setting_blind then
local _hands = card.ability.extra.h_plays * math.floor(((G.GAME.dollars or 0) + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
return {
message = localize({
type = "variable",
key = "a_hands",
vars = { _hands }
}),
func = function()
G.E_MANAGER:add_event(Event({
func = function()
ease_hands_played(_hands, true)
return true
end
}))
end
}
end
if G.GAME.blind and G.GAME.blind.boss and context.end_of_round and not context.game_over then
ok i might be stupid but is this the wrong way to do an else if
elseif one word
thanks
ohhh ty my goat
also suggestion
do card.ability.extra.suitcolor = G.C.SUITS[znm_card_to_destroy_suit]
is this the right variable for playing a sound?
oh does that just work
or is it play_sound
as long as that variable is not nil, it should work
also is there a specific way i need to define the color as a variable?
you mean inside of loc_vars or something like that?
yeah
Yes.
loc_vars always expects this format:
return {
vars = {
<stuff>,
colours = {
<colours>
}
}
}
context.starting_shop
for its return at least
hm ok
context.end_of_round and context.main_eval and G.GAME.blind.boss
could i jsut do this directly?
so its play_sound?
Yes, it's play_sound("modprefix_key")
oh okayy tyyyy
it kinda icks me that VSC put yellow line over it
return {
message = localize(znm_card_to_destroy.base.value, "ranks"),
colours = {
G.C.SUITS[znm_card_to_destroy.suit] or G.C.FILTER
}
}
try this
have you considered setting up vsc to look for the balatro source folder
how to
you know how usually numbers are dependent on the config of a card? just do that but for text, works the same way
Put Mods/lovely/dump in your workspace by doing File > Add Folder to Workspace...
gotcha
return {
vars = {
card.ability.special.supernova_Xmult.."X ",
colours = {
G.C.RED
}
}
}
this works for example, with line 3 being a string that gets passed to the description of the card
for that you can extract the balatro exe into a folder and add that as a workplace
not everything is dumped, after all
hmm
whats with the question marks mr some of the thing of the dot of the com
It happens to everyone, don't worry.
he's our stockfish of our modding
Yes, but almost everything important is in the dump normally.
the ponderer
Exhibit number Butcher Vanity.
but not everything 😭
but not everything 😭
like the events
the most complete source tree is found when you directly extract the source out of the executable
and is important if you're a stickler like me and doesn't want errors like these thrown everywhere
simply make a useless lovely patch in every single file and then the lovely dumps will probably contain everything right
i said it first
i win
nuh uh
wait why am i competing we should make peace
so true lily
client issue i guess
im decompiling it
also very Ppurplre discord
and by it i mean
yes purple is a good colour
Programmer's mindset
especially #7800FF
if you saw some of my comments you would understand
1 bug patched
99 bugs appear
Meet The Programmer
I got 99 problems but yellow lines under "Event" ain't one
the real solution is to not use lsp
Use Vim.
(Please do not subject yourself to such torture.)
36,444 warnings 🔥
THIRTY SEVEN THOUSAND
warn me a little more wont you
your IDE must HATE you
i have to restart emmylua pretty often because it just gives up with syntax highlighting and it bothers me
"she doesn't bother with all the warnings, I'm just not gonna try anymore"
finally got to testing this (laptop crapped out out of nowhere 🤭 ) it returns g.c.filter every time for some reason
well it runs
does it need to be znm_card_to_destroy.base.suit?
ohhh wait maybe
yeah mb
still returning orange 💔
you have a variable znm_card_to_destroy_suit you were using before, maybe you could try that
How do you when played, turn cards held in hand into an enchantment
oh wait lowkey i never realized this in my previous code but i meant to put .suit there LOL
Is this an enhancement/seal?
Enchancement
if nothing else, your previous solution should work, simply using conditional statements to assign the color directly
When played last hand all cards held in hand turns into steel
if context.before and context.cardarea == G.play then
for k, v in pairs(G.hand.cards) do
v:set_ability("m_steel")
end
end
It's not working
whats the context for exiting a shop
Hai Nxkoo
context.ending_shop i thinnk is what Perkeo uses
Code?
Nvm I got it
context.buying_card and context.card.ability.set == "Joker"
also @unborn bay @daring fern how do you fix this
My mistake, you need to put the lovely folder in your workspace, not the dump folder.
oh
how do i revert this
When you right click the folder in explorer view, click Remove Folder from Workspace
got it
thanks
for the last time
whats the context for selling cards, skipping blinds, and rerolling
context.selling_card, context.skip_blind, context.reroll_shop
you're the goat
What the hell is this juice_up bug?
The issue appears to be within the actual code of the game itself and all I'm doing is having it return money when a 10 or 7 is scored. Do I have to manually create another juice_up function even though it literally exists inside the code?
And as far as I know, this issue is unresolved cause from what I looked at, a similar issue #💻・modding-dev message has not been resolved
remove card = self
and also, dont use self in your calculate code
oh I see
are you taking reference from source code?
I think at the time yes, and it has slipped under the radar until now because I was using talisman as a dependency until recently
Is there a way to stop triggering from happening
Would there be a way get the source code of a function?
What do you mean?
can someone name me all the scoring names please?
Like the function doesn't get retriggered from like hanging chad
print(G.handlist)
realised I forgot to mention the debuffing, how's this new description
oh ok thanks
here it is for shorter and longer hand names
yeah, which function
also what do you mean "get" the source code
like from a mod? or just so you can look at it
No, I mean with code.
I need to obtain the ifs of calculate functions to perhaps improve my quantum items to only call them when the conditions are true.
lovely patches? maybe?
No, I need the ifs in string format.
I'm confused
Like "if context.main_scoring and context.cardarea == G.play then"
ohh like get the source code of a function from a mod
uuhm i actually still don't know if that's possible
Technically yes.
unrelated I also have a question: is there a way to upgrade a joker whenever a probability fails? like is there a context for that or smth
Yes, but only on the SMODS dev version.
how would I do that, and can I wrap the joker definition in an if statement to only make the joker if you're using the dev version
#💻・modding-dev message, Yes.
^
tonumber(SMODS.version:sub(12):sub(1, -2)) >= 706 perhaps?
cool that worked
thnx
uhrm would I be able to make it so it's only jokers with probabilities that trigger it
it's not imperative that was just the original idea for the joker that I'm making for someone
i can modify it
ease_background_colour = function(self)
ease_background_colour(HEX("d9c032"))
end,
is this the proper code for background on booster packs?
Yes.
is this formatting ok?
and also do you think this is uncommon
or would it be uncommon if i made it only jokers specifically that trigger it
formatting is subjective i think
i like it to feel vanilla
how bout this tho
What part of SMODS makes it so the sources of things are formatted as "=[SMODS "..mod.id..' "'..path..'"]'?
create_card = function(self, card, i)
ease_background_colour(HEX("d9c032"))
return SMODS.create_card({
set = "Batrocities",
area = G.pack_cards,
skip_materialize = true,
soulable = false,
})
end,
select_card = 'jokers',
in_pool = function() return true end
why does my game crash whenever i open the booster pack? its fine with the shape pack but not for this, its just a different set?
It seems to be part of SMODS.load_file
how do I exclude playing cards from it, I'm not sure how this new context works
check for their "set"
whar
card.ability.set
if context.pseudorandom_result and not context.result and context.trigger_obj and not context.trigger_obj.playing_card
how do you level up all hands
check black hole's code
none in vremade
..right
its spectral
fair
nxkoo DEAD today
if pseudorandom('group_0_bc8df58d') < G.GAME.probabilities.normal / card.ability.extra.odds then
for i, v in ipairs(context.scoring_hand) do
if v == card and context.scoring_hand[i+1] then
context.scoring_hand[i+1]:set_ability(self)
end
end
end
I have this code in a main scoring context for an enhancement, it works but all of it happens instantly, how do I make the enhancement propagate when each card is scored
use events
right
D:
How do you apply a value cap? (For example, Max Spectral Cards Spawned = 25)
i'm making a seal that has 1 in 2 chance of retriggering the card but if the card retriggers it has another 1 in 2 chance of retriggering and so on. any ides on how to code the seal retriggering in
this is a really vague question
uhhhh so what context would i use for when a specific joker is added
i assume it's something with card_added but idk
I have a scaling joker, they’re supposed to give only 2 negative spectral cards but you can upgrade that if you have a joker that can upgrade their scaling.
How do I put a cap?
So it does not crash
Maybe like 10.
if context.repetition then
local random, reps = pseudorandom("seal"), 0
while random < 0.5 do
random = pseudorandom("seal")
reps = reps + 1
end
if reps > 0 then
return {repetitions = reps}
end
end
```?
please i'm actually so cooked
:(
limit it in your calculate code then
check context.card.config.center.key == "key of that joker"
Math.min?
no, math.max
bepis.
🤔
wat no fuck i wait no
math.min, yeah
god i think coding ui for 3-4 hours straight is affecting half of my brain
yeah i know 😭
bepis has become STUPID after ui brainrot
im sorry
sure
here
calculate = function(self, card, context)
if context.pre_discard and not context.blueprint then
local total_created = 0
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + card.ability.extra.cards_per_discard
for _ = 1, card.ability.extra.cards_per_discard do
local g = pseudorandom_element(G.P_CENTER_POOLS.Spectral, pseudoseed('minos')).key
local spectral_card = SMODS.add_card({key = g, area = G.consumeables, edition = "e_negative", key_append = "minos"})
if spectral_card then
total_created = total_created + 1
end
end
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer - total_created
if total_created > 0 then
card.ability.extra.xmult = card.ability.extra.xmult + total_created * card.ability.extra.xmult_mod
G.E_MANAGER:add_event(Event({
func = function()
card:juice_up(0.3, 0.5)
return true
end
}))
return {
message = localize("k_upgrade_ex"),
colour = G.C.MULT,
sound = "minos_die",
card = card
}
end
end
if context.joker_main then
if to_big(card.ability.extra.xmult) > to_big(1) then
return {
message = localize({
type = "variable",
key = "a_xmult",
vars = { number_format(card.ability.extra.xmult) }
}),
Xmult_mod = to_big(card.ability.extra.xmult),
sound = "minos_judgement",
colour = G.C.MULT,
card = card
}
end
end
end
so uhhh im almost certain im not doing this right
context.card.config.center.key = "rylen",
cardarea = G.jokers,
card_added = true,
card = "rylen",
if card.ability.extra.round < card.ability.extra.maxround and card.ability.eternal ~= true then
card.ability.eternal = true
end
end```
can yall help pwease
Remove everything above the second if except the first if
hello?
c.enhancements doesn't exist.
SMODS.get_enhancements(c)
how do i apply a limiter
for _ = 1, math.min(limit, card.ability.extra.cards_per_discard) do
still don't works
What is the goal?
is
G.GAME.blind:defeat()
a thing
No.
G.GAME.chips = G.GAME.blind.chips
G.STATE = G.STATES.HAND_PLAYED
G.STATE_COMPLETE = true
end_round()
it's new mechanic goal is find troop (value in config of enhancements) then find the least troop then destroy that
I’m ass at suggestions, I’ll let everyone else do the talking
thanks
this fails the game somehow
Code?
hold
config = { extra = {} },
loc_vars = function(self, info_queue, card)
return { vars = { "High Card", "50%" } }
end,
calculate = function(self, card, context)
if context.joker_main and context.repetition and next(context.poker_hands['High Card']) then
local retriggers = 0
local highest_rank = 0
for _, playing_card in ipairs(context.scoring_hand) do
local rank = playing_card:get_id()
if rank > highest_rank then
highest_rank = rank
end
end
if highest_rank >= 11 and highest_rank <= 14 then
retriggers = 10
elseif highest_rank <= 10 then
retriggers = highest_rank
end
if pseudorandom('DOMINATED') < 0.5 then
G.E_MANAGER:add_event(Event({
func = function()
play_sound('tngt_neverforget', 1.2)
G.GAME.chips = G.GAME.blind.chips
G.STATE = G.STATES.HAND_PLAYED
G.STATE_COMPLETE = true
end_round()
return true
end
}))
return {
message = "DOMINATED, CYCLOPS.",
colour = G.C.GOLD,
card = card
}
end
if retriggers > 0 then
return {
repetitions = retriggers,
message = localize{type='variable', key='a_repetitions', vars={retriggers}},
card = card
}
end
end
end
}
I think it's because the game sets the chips to the score because you're doing it during scoring.
oh shit
what do i do then
Try setting some config variables to true when you would do it and instead do it in context.after
yeah you shouldn't really mess with state stuff during joker calc
got it
bump
like this?
joker_main and after don't run at the same time lmao
what you do is set a variable to true when the condition you set in joker_main is true
then reference that with context.after
if context.joker_main then
-- .. condition stuff here
card.ability.extra.yeah = true
end
if context.after and card.ability.extra.yeah then
-- do stuff
card.ability.extra.yeah = false
end
Also in context.after you would just do G.GAME.chips = G.GAME.blind.chips elsewise the round will end twice I think.
it's new mechanic goal is find troop (value in config of enhancements) then find the least troop then destroy that
ah okay
so ill put retrigger in joker_main and instant win in after?
You can't retrigger in context.joker_main
Then you would check for c.ability.troops
so the good news is it doesnt crash on launch but it doesnt give it an eternal sticker still
Can someone help me if this code is correct?
--- STEAMODDED HEADER
--- MOD_NAME: Zvs Joker
--- MOD_ID: ZVSJOKER
--- MOD_AUTHOR: Zvstheworld207
--- MOD_DESCRIPTION: Zvs's joker he made for fun!
--- PREFIX: xmpl
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Jokers',
path = 'jokers.png',
px = 71,
py = 95
}
SMODS.Joker{
key = "joker2",
loc_txt = {
name = 'Zvs Joker',
text = {
'When Blind is selected,',
'this Joker gets X mult.',
}
},
atlas = 'Jokers',
pos = {x = 0, y = 0}
}
------------MOD CODE END----------------------
It doesn't appear in game
I don't have any real functions done, this is just so it shows.
It says SMODS is undefined
I'm using a tutorial, but it works there
that header is extremely outdated
For starters I'd suggest you use the updated metadata.
That should help you.
Ok
If you are still having trouble after that, do ask
what should I put as the prefix?
does it have to be some coding thing
or is it just like an ID for my mod
Prefix is like, the thing SMODS will add to most of your stuff.
If you were to make a joker, for example, the key would look like this: j_[prefix]_[key] where prefix is the prefix of your mod and key is the key you gave to your joker.
It is good practice to keep your mod prefix short, under 4 letters if possible.
For example, a mod I (and some others) am developing, Fool's Gambit, has the prefix fg.
this results in all the content added by said mod to have that prefix. i.e. j_fg_joker
I just made it ZVS
and it works
how do I give myself the joker through debug menu plus
or just the debug menu
if context.individual and context.cardarea == G.play and
if pseudorandom("among") < G.GAME.probabilities.normal / 5 then return {repetitions = 1}```
i have this now. i wanna make 1 in 5 chance to retrigger a card. how?
press 3 over it in the collection
replace individual for repetition
and then?
that's it
you have a return statement there
any idea whats wrong here?
line 206 is the loc_txt
['name'] = "My Reflection",
['text'] = {
[1] = {C:green}1{} in {C:green}5{} chance to",
[2] = {C:attention}retrigger{} a scored card"
}
},```
you're missing a "
also you don't need the [1] =
the [2] = neither?
yeah those are automatic
ooo ok
if context.repetition and context.cardarea == G.play and
if pseudorandom("among") < G.GAME.probabilities.normal / 5 then return {repetitions = 1}
end
end
end
}```
this is also erroring
what's the error
oh, remove the second if, you're still in the first if statement
or replace the and with then
ohhh i guess that makes sense
okay i dont think it works
or im just REALLY unlucky
ill paste the code for you to help me :3
name = "My Reflection",
key = "myreflection",
config = {
extra = {
odds = 5,
repetitions = 1
}
},
loc_txt = {
['name'] = "My Reflection",
['text'] = {
"{C:green}1{} in {C:green}5{} chance to",
"{C:attention}retrigger{} a scored card"
}
},
pos = {
x = 4,
y = 0
},
cost = 4,
rarity = 2,
blueprint_compat = true,
eternal_compat = true,
unlocked = true,
discovered = false,
atlas = 'CustomJokers',
loc_vars = { function(self, info_queue, card)
return { vars = { card.ability.extra.repetitions, card.ability.extra.odds } }
end,
calculate = function(self, card, context)
if context.repetition and context.cardarea == G.play and
(pseudorandom('skallywobble') < G.GAME.probabilities.normal) / 5 then
return {
repetitions = 1
}
end
end,
}
}```
please help me im lost

