#💻・modding-dev
1 messages · Page 440 of 1
like, make a boss blind that forces the game speed to x0.25 while in it and resets it back to whatever value the player had when it gets defeated
Good question
Only idea is going to the Balatro modding wiki and looking up "game speed" or smth on there
Then using what you find as reference
bump
i'm tryna use this as a template but add my own thing to it but i can't seem to get the formatting right (both of these are using the same key ("ppg") but the second one doesn't work and whenever i try implement the set money to 0 code into the main chunk of blueprint code i always get error messages on balatro that i cant seem to fix
i tried adding a key check and replacing destroyed_joker = self with destroyed_joker = key but that didn't work either
but the pic is the original func
doesnt seem like theres context.card in your SMODS.calculate_context
change context.card to context.srio.destroyed_joker, i think
how do i add new cards (i used abstract as a base so thats why its that joker i assume)
add new cards?
didn't work. also, when i try to add context.card to calculate_context it just says that context is a nil value
thanks havent though of adding new cards
Default position of abstract joker is x=3,y=3
flashbang editor
how did you add context.card to calculate_context, how you said it sounded wrong
new jokers
Probably means jokers
:3
See
well, whatever you are doing looks correct then
i just did this lol

SMODS.calculate_context({card = self, srio = {destroying_joker = true}})
is there a context for redeemed vouchers
how do u add atlas's
ohhhh so its like a spritesheet of some sort?
Link him your youtube video
Yes
my video didnt cover making atlas or anything lol
just setting up your vsc for modding, and what to do in general
does it use the assets 1x and 2x folder? or how does that work (because other mods use a folder like that)
i can finally move on to the next joker 
i think you might want to check for the voucher cardarea?
G.vouchers.cards
trying to make a Tarot card that creates a random joker from a pool
Does SMODS.add_card not work for this or is there something wrong with my code?
how do i format these into 1, it doesn't seem to be working very well (ignore joker description it's copy-pasted)
Right now it just gives the blueprint effect
how would i check for the amount of chips(or mult) the last played hand got?
(i want to make a joker that adds the chips of the last played hand, and resets after the round ends)
edit: nvm, figured it out
(the solution is card.ability.extra.chips + hand_chips under context.after)
i guess you'd use a hook
hows that
context.using_consumeable
and
if context.other_consumeable.config.center.key == "c_hanged_man" then
i think thats hanged man's key?
tysmmm!!
nah
you can claim multiple blanks
i've done this instead
it should? idk
i think the blank voucher that appears after you redeemed all vouchers is the same one with the normal blank voucher
yeah but it probably should count as redeeming a voucher different times
so that's why i didn't use card area
i would run through G.vouchers.cards, store the keys in a table so that it can ignore the same key lol
:P
Hi,can someone help with a code snippet for, disabled until joker is sold in Lua,I am new to it, thank you
like verdant leaf?
lovely
Yes
Thanks a lot
i'm trying to use larger-than-usual sprites for blinds and everything goes smoothly up until the blind is actually played; the atlas searches through the usual 68x68 dimensions rather than the custom ones defined in the smods atlas. any clue why it does this? (ignore the blind sprite)
(as shown here, i drew a sad smiley to represent the normal dimensions; it indeed goes thru them instead of the custom ones)
(the sad smiley is in the top left corner)
Which one is cooler?
The left one
Why does this happen?
how can i add an extra button to a joker like this one?
i won't be making the funny legendary effect because i would probably struggle with atlas placement
Hook G.UIDEF.use_and_sell_buttons
okk
what do i have to change in the function?
You would add more buttons to the card.
well yeah
ive learnt how the basic hooking works, but idk what i have to change for it to do so
is there any mod that adds that?
thanks
How would I make jokers draw specific cards face down? I've figured out how boss blinds do it but how can I make a Joker do that?
redid joker sprite
and what joker does it?
Why does this function not work?:
It sometimes doesn't do anything and sometimes it reduces the value.
mockup description
Which is the opposite of what I want.
heavely nerf it
Yorick on steroids
i will nerf the joker to have it 1 mult
fr
mult or Xmult
xmult
still a lot 😭
i'm not making super balanced jokers
yeah, i realised
that card probably has the power of 3 legendary joker all joined up
or more
all except for like chicot and triboulet
Weakest Cryptid Joker
That's 5 Yoricks and kinda 2 perkeos
so true 💔
but at least cryptid made the op cards a different rarity, as it's not the same level
it's more like if hologram and perkeo used the potara
is N' online?
have you verified that things are firing when they're supposed to?
sisyphus prime jonkler
@red flower where in your code do you hook the G.UIDEF.use_and_sell_buttons
same but x4 mult anytime you use a tarot card, use specifically, not sell, create, or obtain
specifically the strength card
otherwise the emperor
You could also try using FusionJokers for reference?
well ok
How do I make a Joker that mimics the Marks effect of drawing face cards flipped?
holy moly the hook is really messy (for me)
how would i look at the suits in a deck
i don't
i hook card:highlight and have my own create buttons function
oh ok
how would i make it so my calculate only works if all cards played are numbered? (so no face cards or ace)
It seems to be running everything the correct amount of times.
are you talking about the ref_table[ref_value] line?
bump
if i could have a way to get all the suits then i could in theory just iterate over that
from where you set it....
all the suits should be in SMODS.Suits
for the suits in a deck you would have to iterate through it and check card.base.suit
thanks
i’m basically checking for unique suits in a full deck
I put a print in there and the number of prints seemed to match the amount of numbers in the table.
like this line seems suspect because it could fire aok as expected but not do anything because of your default values
this (and like 10 other variations i've attempted) doesn't seem to work because if at least one card is numbered then it gets set to true anyway, even if the false should be overriding it
would something like this work
don't use context.individual and iterate over context.scoring_hand directly in joker_main
no it wouldnt
no
i need to compare it with just the key
oh
just if == k
yeah?
CHAR.FUNC.check_suits_deck = function()
local cards_of_suits = {}
for i=1,#G.playing_cards do
for k,v in pairs(SMODS.Suits) do
if G.playing_cards[i].base.suit == k then
cards_of_suits[k] = (cards_of_suits[k] or 0) + 1
end
end
end
end
why do you need to compare it with SMODS.Suits
im checking if the card has the suit, and if it does, im incrementing a spot in the 'cards_of_suits' table that correlates the the suit being checked
how do i show a description of a red seal in a deck on hover?
im not comparing it with SMODS.Suits, more just using the name in SMODS.Suits
thats the goal i mean
i get that, why do you need to check if it's in SMODS.Suits?
info_queue[#info_queue+1] = G.P_SEALS.Red in loc_vars?
How and why would you do that?
oh that makes sense actually
Instead of iterating over suits, iterate over cards
yeah
might as well add godzilla, litteraly.
that shows up all the time though
i want it to show up when i hover over specific text
like {C:attention,T:m_steel}Steel{} for Steel Cards
wait how would i handle cards without suits
ignore them probably
just a nil check?
T:red_seal or T:red or T:Red?
if not SMODS.has_no_suit(card) then
CHAR.FUNC.check_suits_deck = function()
local cards_of_suits = {}
for i=1,#G.playing_cards do
if not SMODS.has_no_suit(G.playing_cards[i]) then
cards_of_suits[G.playing_cards[i].base.suit] = (cards_of_suits[G.playing_cards[i].base.suit] or 0) + 1
end
end
return cards_of_suits
end
iterating directly doesn't seem to work, though it's possible that i'm doing this wrong
If it matters, I'm trying to add 1 to all values on a card, and it seems to be changing any number above one to ((number - 1) * 0.5) + 1 I think.
there's no context.other_card in joker_main, also you're returning as soon as you find 1 numbered card
so how would i iterate it then? if i remove context.other_card it just returns nil
and crashes
i would maybe make a table of the numbered cards and check if the table containing numbered cards is equal to the cards being scored
context.scoring_hand[i]
i would maybe iterate over scoring_hand to see if not face
needs to not be face or aces
rather than using get_id
that's more mod friendly
okay, also check for the ace id
What context is used to check for the end of a blind
simple
context.end_of_round iirc
ace is also not a face so it's the same check
thanks
if not card:is_face() and card:get_id() ~= 14
if im not mistaken, aces are considered 14s?
Yes.
yeah
How do you apply the spectral texture on a joker?
because that makes it play nice with stuff like modded ranks and pareidolia
You mean the spectral shader?
doing it like this crashes the game, saying length is a nil value
first i've seen that
probably a syntax error on the iterate line
Log?
because theres no card object that works here
that was a placeholder
Remove [i] from the top of the for loop and replace card in the for loop with context.scoring_hand[i]
please replace it with the card you are attempting to iterate over, additionally, your iteration is wrong
^
misclick
it needs to iterate over the entire hand. if it detects one card that isn't ace or face it seems to trigger either way
exactly
Then you would change it to context.full_hand
https://github.com/Steamodded/smods/wiki/Calculate-Functions is also a great place to look for all the various contexts
It doesn't have all of them sadly
doing this makes it trigger regardless of the card played (it still triggers if it contains a face or ace)
You need to replace card in the for loop with context.full_hand[i]
Except in the return.
you meant the if statement inside the for loop? that's why i was confused
yes, card was meant to be a placeholder
in the function card will always reference the card thats doing the calculation
in this case, the joker
fixing it to this changed nothing, it still triggers if face/ace are present
Replace the return passed = false break
its jumping out if one card fufills the if condition
try playing with a full hand of aces
and see what it does
yes
Then check if passed is true then return.
i can't do that if the hand i'm using is a straight lol
okay
SMODS.DrawStep{
key = 'boostershader',
order = 10,
func = function(self)
if self.config.center.key == "j_modprefix_key" then
self.children.center:draw_shader('booster',nil, self.ARGS.send_to_shader)
end
end
}
if not conditions then
passed = false
break
end
how can you check if a certain joker is owned?
if context.joker_main and (next(context.poker_hands[card.ability.extra.poker_handp])) then
local passed = false
for i=1,#context.full_hand do
if context.full_hand[i]:is_face() or context.full_hand[i]:get_id == 14 then
passed = true
end
end
if not passed then
return {
xmult = card.ability.extra.Xmult
}
end
end
if i add this to the joker, it will give it the shader?
if next(SMODS.find_card("j_modprefix_key")
anyone able to understand this error?
No, you need to put it outside the joker and replace the key.
no not the SMODS joker
sorry let me rephrase myself
if i add this to the lua
which contains the code for both the Atlas and the Joker
it will show the shader
how can i check if all played cards are hearts?
Yes, if you replace the key.
local passed = true
for k, v in pairs(context.full_hand) do
if not v:is_suit("Hearts") then
passed = false
break
end
end
if passed then
-- do things
end
is there a function to force end of game
like, if a joker is destroyed, lose the run
Yes.
this seems to only work if the hand has an ace, face cards still trigger it
but hey this is good progress
No.
then?
Check for face cards and aces separately, not together.
what's the function's name?
i thought the or check covered that 
but i'll try that and another idea i got
how do i include a range with psuedo random
like a range of numbers it can pick from
this doesnt work? why
It's xchips
is it different?
sick, this worked 
how do i write code here as a block?
```lua
-- Code here
checking for id is unreliable and excludes base game mechanics
please do not do it this way
check for face card first, then check for ace
--- STEAMODDED HEADER
--- MOD_NAME: Minos Prime
--- MOD_ID: minos_prime
--- PREFIX: minos
--- DESCRIPTION: JUDGEMENT, no not the Tarot Card.
--- AUTHOR: [FirstTry]
SMODS.Atlas {
key = "minos",
path = "minos_prime.png",
px = 71,
py = 95
}
SMODS.Joker {
key = "minos_prime",
atlas = "minos",
rarity = 4,
cost = 8,
discovered = true,
unlocked = true,
eternal = true,
blueprint_compat = true,
pos = { x = 0, y = 0 },
Joker doesn't show
can you explain how this is the case?
assets are in proper place
if it messes with other mods i don't really care too much about that
if card:is_face() then and then after that if condition if card:get_id() == 14
pareidolia
makes everything faces
for instance
the card's exact description is "numbered cards"
so pareidolia shouldn't have any effect
i'll try that though
this is still the 'proper' way
dont use smods header
use a metadata.json file
plus, wouldn't that break the joker completely if i did have pareidolia?
so even if the hand is 2, 3, 4, 5 and 6 it wouldn't trigger
You should then change it to say non-face cards.
yes, would that not be correct behavior as those cards you played would be face cards?
can i still set the main to the lua with the atlas, joker, and shader?
sorry if i'm being a bit impaitent but just bumping this so it doesn't get lost, seems to crash sometimes when spawning the joker but not all the time
you can set your main.lua file name in your metadata
im trying to do if all played hearts it gives +50 mult and if all played cards are spades then gives x3 mult but the x3 mult is given even if its a club or diamond for some reason
i tried using vanillaremade's effect of the juggler (to gain +1 hand per round) but it didn't work, anyone knows how it works?
no. it's specifically meant to be numbered cards
numbered cards are still numbered cards even if pareidolia converts them to face cards, just like how ace is always ace even if pareidolia converts it to face
otherwise jokers like scholar or fibonacci would be completely worthless with pareidolia
i fail to see how your point is relevant
your card is designed to only trigger if numbered cards, or non face cards
are played
no, non-face cards are nowhere in the description
jack, king and queen are inherently not numbered
okay, do it however, but this is confusing me
How can i keep track of how many times a card is played, not triggered but played?
After the for loop, you can do
return {
mult = passedhearts and card.ability.extra.Plusmult,
xchips = passedspades and card.ability.extra.Xchips
}
maybe i should make the description very long and change it to "if played hand only contains 2, 3, 4, 5, 6, 7, 8, 9 or 10" since i guess this is too confusing 
card.base.times_played
if played hand does not contain king, queen, jack or ace
i guess that works too
thank you but is it gonna fix my proiblem?
thank you
how do i make pseudorandom fetch a range
of numbers that i defined
i wanna make it higher than just 0.00 to 1.00
pseudorandom("seed", min, max)
thankies
I do not see xmult there. You should also remove the breaks then.
i never realized how many people made their own "change values in a joker" function
i guess im gonna try making my own too
what do i name my json
anything
i made my own and im very proud of it
sweet
function CHAR.FUNC.recursive_apply_num(table, modi, op, visited)
visited = visited or {}
if type(table) ~= "table" then return table end
if visited[table] then return table end
visited[table] = true
for k, v in pairs(table) do
local current_value = table[k]
if type(current_value) == "table" then
CHAR.FUNC.recursive_apply_num(current_value, modi, op, visited)
elseif type(current_value) == "number" then
local is_old_key = type(k) == "string" and k:find("^old_")
if not is_old_key then
table['old_' .. tostring(k)] = current_value
table[k] = CHAR.FUNC.op(op, current_value, modi)
end
end
end
return table
end
function CHAR.FUNC.change_card_values(card,mod,operation,reset)
-- OBJECTIVES --
--[[ the conventionally changable card values are stored in config, or ability.
I'd rather use ability as that's going to ensure the values are reset when the run is.
I need to 'scan' ability for certain values, throw out the base game ones that have no influence on how the card actually works,
then change them through mod, and 'save' the original values for later reapplication. Perhaps by prefixing the original values with old_?
so I need to save the card's ability table temporarily, probably manually check for things that all cards have, then only change the leftovers,
then finally tack it back onto the card.
]]
local old_table
if card then
old_table = card.ability
else
return
end
if reset then
if type(old_table.extra) == 'table' and old_table.extra.flag then
local curr_val = {}
for k, v in pairs(old_table.extra) do
if not k:find("^" .. "old_") and type(old_table.extra[k]) == 'number' then
curr_val[k] = v
end
end
for k,v in pairs(curr_val) do
old_table.extra[k] = old_table.extra["old_" .. k]
end
old_table.extra.flag = nil
return old_table
else if type(old_table.extra) == 'number' then
if old_table.old_extra then
old_table.extra = old_table.old_extra
return old_table.extra
end
end
end
end
if type(old_table.extra) == "table" and not old_table.extra.flag then
old_table.extra = CHAR.FUNC.recursive_apply_num(old_table.extra,mod,operation)
old_table.extra.flag = true
return old_table
else if type(old_table.extra) == 'number' then
old_table.old_extra = old_table.extra
old_table.extra = CHAR.FUNC.op(operation,old_table.extra,mod)
return old_table
end
end
end
this is my function
it basically recursively changes card.ability.extra
i'm not really sure why this doesnt work, but its supposed to check for two existing jokers and give one or another mult based on the result
is this an enhancement
i wish people would tell if their code is from enhancement, edition or joker first, since the contexts they use are different 😭
jokers dont use main_scoring, im pretty sure
whats the key for negative edition again
e_negative
thaks
if you want to make it so it does something per scored card, its if context.individual and context.cardarea == G.play then
Are the two xmult values exclusive to each Joker or do you want the two to add up if both are present?
but also, your if statements are weird
actually ali got it, im gonna go continue coding :3
thanks
they're meant to be exclusive
i figured if the first conditions return something it won't continue the function
yall the goats fr
That is true, but maybe store the two owned as local checks?
is there a context that restarts the round? (as opposed to being saved by mr. bones)
local elbueno, elbruto = next(SMODS.find_card("j_mucho_elbueno")), next(SMODS.find_card("j_mucho_elbruto"))
if elbueno then
if elbruto then
-- give one xmult
else
-- otherwise, give other xmult
end
end
I vaguely remember something like this in cryptid, maybe check out what they do to mess with round states
Wouldn't you just add hands and discards on the last hand?
bumping this again sorry i'm still lost on this
oh that does seem much more efficient
thanks
🤔 that seems to work
Reboot Code Card.
i guess i could do that and also reset the score to 0? (which the latter i don't know how to do)
ah yeah I guess it's the difference between resetting everything to the start of the round or just resetting hand state
G.GAME.chips = 0
either way they'll need to reset the deck and stuff
is this correct
this is true too
will look into that code card
...looks about right? I'd implement an "iteration" variable as well to prevent game lock-ups.
🤔 what do you mean by that actually
Mine has it.
local function toga_subtable(ttable, foundmodified, increase, depthiter)
depthiter = depthiter or 1
if depthiter > 32 then return end -- Just in case.
for k, v in pairs(ttable) do
if type(v) == 'number' then
local rplc = v*(1+increase)
ttable[k] = rplc
foundmodified = true
elseif type(v) == 'table' then
toga_subtable(v, foundmodified, increase, depthiter)
end
end
end
i want a joker that halves cashout money, what variable do i need to change to do that?
@midnight coyote
so i want to make a joker that gives a big reward by guessing which randomized hand ,the player has to do , so like if the hand is a flush , if the player guesses it then they receive the big reward , but i wanna know how i can randomize the hands and then check for that randomized hand?
i'm stumped
Blind reward or hands or just the entire cash out?
the entire cashout
Not sure if this will work, im trying to check when a card would be destroyed during the scoring part and have it be destroyed, im sorry if this isnt worded the best
calculate = function(self, card, context)
if context.main_scoring then
print(card.ability.extra.PlaysLeft)
card.ability.extra.PlaysLeft = card.ability.extra.PlaysLeft - 1
end
if context.destroy_card and context.destroy_card == card then
if card.ability.extra.PlaysLeft == 0 then
end
end
end,
}
I also am not sure of what to return to have the card be destroyed
this is under an enhancement
return { remove = true } i think
anyone know?
ill try that, thanks
destroy_card is the bane of my existence
real
Try looking at To-Do List.
is it a mod?
oh im dumb
youre missing an atlas somewhere
how can i make to create a joker that when i adquire X joker adds xmult?
how can i check if a run started?
Hook Game:start_run?
sorry, i dont know how to read :P
i just wanna check when the run started
._.
Yes, hook Game:start_run
can anybody think of a joker that has a random chance, and if that random chance succeeds, it does multiple effects. also jokers that have a random chance to do an additional effect within the same context (gros micheal doesnt count because of different contexts). i just need some good code examples to look at
how can i?
Wtf no I didn’t, it’s literally in the minos_prime.lua
local oldstartrun = Game.start_run
function Game:start_run(args)
local g = oldstartrun(self, args)
return g
end
🤔 i think this check might be a bit too unnecessary
does the art have 1x and 2x counterparts stored in modroot/assets/1x and 2x respectively
and then i check if oldstartrun then
or any good docs on pseudorandom in general
Yes
No, you put it between local g and return g
like the code i want to do?
Yes.
No.
seems the game over triggers before this can take effect, would i need to check for G.GAME.blind.chips =~ 1 with 0 hands instead?
sad
Try context.after and G.GAME.current_round.hands_left == 0
SMODS.Atlas {
key = "minos_prime",
path = "minos_prime.png",
px = 71,
py = 95
}
SMODS.Joker {
key = "minos_prime",
atlas = "minos_prime",
rarity = 4,
cost = 8,
discovered = true,
unlocked = true,
eternal = true,
blueprint_compat = true,
pos = { x = 0, y = 0 },
{
"id": "minos_prime",
"name": "Minos Prime",
"displayname": "Minos Prime Joker Mod",
"author": [
"FirstTry"
],
"description": "JUDGEMENT, no not the Tarot Card",
"prefix": "minos_prime",
"main_file": "minos_prime.lua",
"version": "1.0.0",
"dependencies": [
"Lovely (>=0.7)",
"Balatro (>=1.0.1o)"
],
}
heyy, does anyone know how to make a deck have only modded jokers available?
Ban every vanilla joker?
shit doesn't work
yea, but only for a certain deck/back
ok this seems to work with the wacky side effect of giving you 16 cards lmao
Yes, put it in apply.
(still need to add all the other checks but i should probably take care of this first)
how can i check when i have the joker in my joker slots?
if next(SMODS.find_card("j_modprefix_key"))
I have a Joker that rolls the chance a lot of times... by each effect.
-# Not exactly prettiest in terms of code, but functional.
if i can't fix this then i may need to rebalance the joker and make this a feature because it's kinda cool
man.
I already have that function, I'm just confused of wat I need to put in the function.
i meant when i first get it in my joker slot
for k, v in pairs(G.P_CENTERS) do
if not v.mod and v.set == "Joker" then
G.GAME.banned_keys[v.key] = true
end
end

(yes this counts down all the way to 1, and yes it's as ugly as it looks)
anyone know?
Hey there everyone
I made this web-based mod manager thing if you wanted to check it out
I think it's just about done
Enjoy I guess
Wasn't sure where to put this
pretty cool
huh 
If it's loading it just means that no one's been on the website in a while because I can't afford to have it running at full capacity 24/7
Should be pretty good if you need mod data or whatnot (assuming anyone actually shares mods there)
If you have any feedback just lemme kno
anyone know how i can check when i first get my modded joker in the joker slot?
please someone tell me what do i have to change in order to make the button say DEAL
why doesnt my achievement work?
SMODS.Achievement{
key = 'nineelevenplus',
bypass_all_unlocked = true,
hidden_name = true,
hidden_text = false,
reset_on_startup = true,
unlock_condition = function(self, args)
return (args.type == 'nineeleven') and (os.date("%m/%d") == "9/11")
end
}
i know j_ is for jokers, but whats the one for enhacnements?
how do you create a consumable?
e_ i think
This page has the details
https://github.com/Steamodded/smods/wiki/SMODS.Consumable
neat, thanks
its apparently m_
yea
i'm having a problem with my joker lua
calculate = function(self, context)
if context.joker_main then
return {
X_mult = self.config.extra.Xmult or 1,
message = "X" .. self.config.extra.Xmult
}
end
end,
on_discard = function(self, context)
if G.GAME and G.GAME.current_round and G.GAME.current_round.discards_used > 0 then
local created = 0
for i = 1, G.GAME.current_round.discards_used do
for j = 1, 2 do
local card = create_card("Spectral", G.consumeables, nil, nil, true)
card:set_edition({ negative = true })
G.consumeables:emplace(card)
created = created + 1
end
end
local gain = created * (self.config.extra.Xmult_mod or 2)
self.config.extra.Xmult = (self.config.extra.Xmult or 1) + gain
return {
message = localize("k_upgrade_ex"),
colour = G.C.MULT
}
end
end,
loc_vars = function(self, info_queue, card)
return {
vars = { card.ability.extra.Xmult }
}
end
}
how could i play a sound when using a consumable? (like a custom sound)
huh
today i learned that if you have 5 mr bones, they all self destruct at the same time
kinda wack but oh well
bump
anyone got a simple reference for how to make a deck start off by giving you a tag?
apply = function(self, back)
add_tag(Tag('tag_[key]'))
end,
i think you can just do this
I got the first part to work, but the second part doesnt add to the Xmult
if context.before then
for _,v in ipairs(context.scoring_hand) do
v:set_ability("m_OAL_Damaged")
SMODS.calculate_effect({message = "DAMAGED!"}, v)
end
end
if context.main_scoring then
for _,v in ipairs(context.scoring_hand) do
if SMODS.has_enhancement(v, "m_OAL_Damaged") then
card.ability.extra.Xmult = card.ability.extra.Xmult + 0.1
end
end
end
the ui system has been kicking my butt for the past few hours. Why is nothing consistent
localthunk made it himself 😔
(not really expecting an answer, I'm just venting, it's so stupid how all these check boxes have the same config yet appear differently)
it's context.joker_main, no?
i have that, but that part is just adding to it and not adding to the scroing
scoring
because you need to have a return { xmult = card.ability.extra.Xmult }
Nah ur just right tho. Making UI for this game blows
This is what I have, does this not work?
calculate = function(self, card, context)
if context.before then
for _,v in ipairs(context.scoring_hand) do
v:set_ability("m_OAL_Damaged")
SMODS.calculate_effect({message = "DAMAGED!"}, v)
end
end
if context.main_scoring then
for _,v in ipairs(context.scoring_hand) do
if SMODS.has_enhancement(v, "m_OAL_Damaged") then
card.ability.extra.Xmult = card.ability.extra.Xmult + 0.1
end
end
end
if context.joker_main then
return {
xmult = card.ability.extra.Xmult
}
end
end,
Please?
Yeah ui is hard
how would i debuff duplicate jokers in a boss blind?
loop through jokers, make a table for every variant found and add jokers of its type to that table, if said table has more than one joker of its type, loop through and debuff every joker after the first
if the table only has one joker of its type, clear the table etc
I think i know the issue
@pastel kernel Send full code
Does it crash ?
Code looks fine
Whats the main issue
Minos prime bruh😭
joker does not work, no negative spectrals after discards
no xmult after creating spectrals
a little bump :3c
mnos...
If you’re setting all of the card abilities to Damaged anyways why don’t you just iterate your XMult there instead of in a completely different context?
oh my god, why didnt i think of that
Sillay
horray it works!
key = "minos_prime",
atlas = "minos",
rarity = 4,
cost = 8,
discovered = true,
unlocked = true,
eternal = true,
blueprint_compat = true,
pos = { x = 0, y = 0 },
config = {
extra = {
Xmult = 1,
Xmult_mod = 2
}
},
loc_txt = {
name = "Minos Prime",
text = {
'This Joker creates 2 {X:dark_edition,C:white}Negative Spectral{} cards for every discard used.',
'This Joker also gains {X:mult,C:white}X2{} Mult for every {C:spectral}Spectral{} card created.',
'{C:inactive}(Currently {X:mult,C:white}X#1#{} Mult)'
}
},
loc_vars = function(self, info_queue, card)
return {
vars = { card.ability.extra.Xmult, card.ability.extra.Xmult_mod * 2 }
}
end,
calculate = function(self, context)
if context.joker_main then
return {
Xmult = self.ability.extra.Xmult or 1,
message = "X" .. (self.ability.extra.Xmult or 1)
}
end
end,
on_discard = function(self, context)
if G.consumeables then
for j = 1, 2 do
local card = create_card("Spectral", G.consumeables, nil, nil, nil, nil, nil, 'unb')
card:set_edition({ negative = true }, true)
G.consumeables:emplace(card)
end
self.ability.extra.Xmult = (self.ability.extra.Xmult or 1) + 2 * self.ability.extra.Xmult_mod
return {
message = localize("k_upgrade_ex"),
colour = G.C.MULT
}
end
end
}
SMODS.DrawStep {
key = "minos_prime_draw",
order = 10,
func = function(self)
if self.config.center.key == "minos_prime" then
self.children.center:draw_shader("negative", nil, self.ARGS.send_to_shader)
end
end
}``` @pastel kernel
Try this
Silly flote (i didnt think of that either )
I just be having a big massive brain
Perchance
Nothing
It should create a negative spectral whenever you use a discard
2 of them actually
key = "deardanielsr", --minda note: fix blueprint not working properly even though it's compatible
loc_txt = {
name = 'Dear Daniel',
text = {"{X:mult,C:white}X4{} Mult if",
"played hand contains",
"a {C:red}King of Hearts{} and",
"a {C:red}Queen of Hearts.{}",
"If {C:red}Hello Kitty{}",
"is in your deck,",
"{X:mult,C:white}X8{} Mult instead,"}
},
pos = { x = 0, y = 0 },
rarity = 2,
atlas = 'sanriocards',
blueprint_compat = true,
cost = 6,
config = { extra = { Xmult = 4, Xmultkitty = 8, Xmultreset = 4 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.Xmult, card.ability.extra.Xmultkitty, card.ability.extra.Xmultreset } }
end,
calculate = function(self, card, context)
if next(SMODS.find_card("j_srio_hellokittysr")) and next(SMODS.find_card("j_srio_deardanielsr")) then
card.ability.extra.Xmult = card.ability.extra.Xmultkitty
end
if not next(SMODS.find_card("j_srio_hellokittysr")) and next(SMODS.find_card("j_srio_deardanielsr")) and card.ability.extra.Xmult == 8 then
card.ability.extra.Xmult = card.ability.extra.Xmultreset
end
if context.individual and context.cardarea == G.play then
for i = 1, #context.scoring_hand do
if context.other_card:get_id() == 12 and context.other_card:is_suit("Hearts") then
card.ability.extra.kings = true
elseif context.other_card:get_id() == 13 and context.other_card:is_suit("Hearts") then
card.ability.extra.queens = true
end
end
end
if context.joker_main and card.ability.extra.kings == true and card.ability.extra.queens == true then
card.ability.extra.kings = false
card.ability.extra.queens = false
return {
Xmult = card.ability.extra.Xmult
}
end
end
}```
real quick, is there any code in this joker that prevents it from working properly with blueprint?
Edition=“e_negative”
And also grant x Mult every created spectral
Gain or do
Gain
If gain then set your
How can i edit the ante within a deck?
Wait, replace card:set_edition to Edition:e_negative?
Yes
Anyone know how I can check when a joker is first placed in the joker slots
func = function()
local card = Create_card(“Spectral”,G.consumeables,nil,nil,nil,nil,nil,’unb’),
card:set_edition('e_negative', true)
card:add_to_deck()
G.consumeables:emplace(card)
return true
end```
@pastel kernel This is how i do it
Where do I place that
Inside your for
Or add the for inside
Before local card = and end it after emplace
You should just be able to do SMODS.add_card({set = "Spectral", edition = "e_negative"})
...why does G.discard have a cap of 500 cards, anyway...
when is G.GAME.blind.triggered set?
how many cards do you need to discard???
probably just a random number. i dont think there's an actual limit in cardareas, it's just for display reasons
because it stands for DI-shy cards
it's set manually by each blind afaik
DI being 501 in roman numerals of course
is it reset at any time or would i have to do that manually as well
it should be reset
I was just perusing the CardArea definitions... as I might need to make a similiar one to G.discard for custom use.
well it resets after the blind if you want to trigger it more than once i think you need to also do it manually
i would check vanillaremade
afternoon, all!
how would i have a joker save its own key to a table through a global event?
?
elaborate?
you can save anything to G.GAME
basically when a joker calls an event i have global, i want to add code to that event that i have that saves the key of the joker that called it to a table
table[card.config.center.key] = true?
SMODS.Blind { -- The Singular
key = "singular",
dollars = 5,
mult = 2,
pos = { x = 0, y = 23 },
boss = { min = 9 },
boss_colour = HEX("6a3847"),
calculate = function(self, blind, context)
if not blind.disabled then
if context.debuff_card and context.debuff_card.area == G.jokers then
if context.debuff_card.config.center.key == "j_blueprint" or context.debuff_card.config.center.key == "j_brainstorm" then
blind.triggered = true
return {
debuff = true
}
end
local jimbos = SMODS.find_card(context.debuff_card.config.center.key, true)
if #jimbos > 1 and context.debuff_card.config.center.key ~= "j_chicot" then
blind.triggered = true
return {
debuff = true
}
end
end
end
end
}
why doesnt this trigger matador?
you can use table.insert(t, 'k') or just do t['k'] = true depending on your situation
i'll try your guys' solutions and let you know if it worked 👍
tbh it might be to prevent it from scaling infinitely
kinda like a failsafe
oh uh how would i view the table ingame again? eval something
Where do I place this again? (Assuming we’re using this version of the script #💻・modding-dev message )
yeah eval G.GAME.tablename
bet
bump
looking at vanillaremade none of the blinds set .triggered in context.debuff_card
it might be that
im in context.debuff_card though?
crimson heart does it in press_play
Inside the for loop, it’s all you need in there
okay but the blind isnt always active
how do i check if its actually debuffed something
without making it trigger on perishable jokers
does anyone have an example of the hook boss blind's effect?
i can't find it in vanilla remade
also looks like someone trolled the wiki lmao
line 19 in blinds.lua
get off fandom
vanilla remade doesn't have blinds.lua
unless it got updated recently?
it did
alr i'll check it out
'tis why we reject Fandom, embrace https://balatrowiki.org
idk save it somewhere
boss blinds dont have config though
G.GAME.chips = G.GAME.blind.chips
G.STATE = G.STATES.HAND_PLAYED
G.STATE_COMPLETE = true
end_round()
end```
ive been using this code to end the round on card sold, but obv you can sell the card outside of the round (which breaks things), how do i make it so that it only triggers in round?
then save it on the card
or do like crimson heart which assumes that it always works as long as there is a target
and G.GAME.blind and G.GAME.blind.in_blind
I got an error with line 96
like this?
thanks
did i do this right because it's returning nil
wait im an idiot i didnt initialize the table
Card:flip()
store your table in G.GAME
the flip works fine im talking about saving to the table
yeah i realized i forgot to
You didn’t initialize the table bro😭
i mean yeah that's what she said already
many people figure out what's wrong exactly the moment they ask lol it's expected
this is amazing they should keep it fr
why does this crash (in a boss blind)
omg it goes further
uhhhh i'd recommend declaring this table in start run
otherwise it's not gonna reset on new runs
i do in fact have a hook into it already so i'll just put it in there
actually yeah that'd be really bad
not to be a nuisance but is it like this?
bump
why
N amount of blinds before boss blind

gonna add support for scrolling through them too
this should be fine
this is after though
i just reordered them because i was playing around with how it works
to figure it out
500 small blinds
@wind steppe
cool
blind.triggered = true
end```
500 boss blinds
well, something went wrong and uh
what's with the boss blind defeat
2 big blinds
why are the blinds running away
yeah thats intentional kinda
so it doesnt do it per ante
also those are the same big blind
one of them is normal big (the one on the right)
the other is a mix of boss blind and big blind (left)
yeah cause im just copying it to test the ui part rn
whuh...
do me a favor and add a full house of blinds
2 small 3 big, or reverse.
still crashes
does your start run just do it every ante
G.jokers.cards
i hav another if statement up there that does do things per ante
is it per ante only when specified (like this) cause then i dont need the not check
interesting
i mean it IS a separate conditional so maybe i just
dont need it
actually yeah this'll probably work fine
no longer crashes but doesnt work with matador
damn
something insane happened that I tried to make a shader that really works and I got this for the dissorance_mask:
really cursed in a way.
clearly you shouldntve on line 162
well...
So does it really be needed?
as I saw on tutorial?
or was there something I didn't know about?
SMODS.Blind { -- The Singular
key = "singular",
dollars = 5,
mult = 2,
pos = { x = 0, y = 23 },
boss = { min = 9 },
boss_colour = HEX("6a3847"),
calculate = function(self, blind, context)
if not blind.disabled then
if context.debuff_card and context.debuff_card.area == G.jokers then
if context.debuff_card.config.center.key == "j_blueprint" or context.debuff_card.config.center.key == "j_brainstorm" then
context.debuff_card.ability.para_singular = true
return {
debuff = true
}
end
local jimbos = SMODS.find_card(context.debuff_card.config.center.key, true)
if #jimbos > 1 and context.debuff_card.config.center.key ~= "j_chicot" then
context.debuff_card.ability.para_singular = true
return {
debuff = true
}
end
elseif context.press_play then
for k, v in pairs(G.jokers.cards) do
if v.ability and v.ability.para_singular then
blind.triggered = true
end
end
end
end
end,
disable = function(self)
for _, joker in ipairs(G.jokers.cards) do
joker.ability.para_singular = nil
end
end,
defeat = function(self)
for _, joker in ipairs(G.jokers.cards) do
joker.ability.para_singular = nil
end
end
}
``` why does matador not trigger
matador 
I was trying to figure out why dissolve_mask didn't work
162 code line is the dissolve_mask line

I don't understand.
Does anyone know how to check if a joker has been placed in your joker slots for the first time 
whenever i activate this joker it prints the following error, not sure what's wrong
why isn't it returning a value?
the syntax for create_card is wrong, and it should be add_card
SMODS.add_card{key = "c_[modprefix]_mostaza"}
Can someone please help me I know this is the 2nd time doing a shader with proper verison but I've encountered na error with the dissolve mask.
or when it tries to return a dissolve mask
Hello?
help.
"void function cannot return a value" what does that even mean for dissolve mask error
has anyone encountered something like this before?e
i have no idea about shaders but that means you're trying to return a value in a void function (a function specified to have no return value)
i finally got it workies
Well, I could share the shader I've been making
for something.
I might delete this once it gets resolved.
what would you put in your config if you wanted to do an indeterminate amount of retriggers?
I should just give up on this joker.
I couldn’t get it to work
aaaaand. there's this
Holy fourth blind?!?!
Does anyone know how to do this?
Can he spin tho
im eventually going to make it so you can have arbitrary amounts of blinds
Make them always give you a eternal egg
per ante
the other one can
Which one is the other one
Hey so my seal that I made prevented cards to be debuffed, but it doesnt seen to work out, anyone got any ideia in how to fix it?
key = 'guard',
atlas = 'Enhancers',
pos = { x = 3, y = 0 },
badge_colour = G.C.RED,
calculate = function(self, card, context)
if context.debuff_card then
return {
card.prevent_debuff
}
end
end
}
Ok I think I wanna try again
How do you make animated jokers lmao
animated sprites
the method im going to use to let them scroll totally isn't just wrapping the blind choices in a Moveable object, clipping the object, and translating the choices uibox

im so stuoid
hmmmmmmm
How to animate sprite
hello guys, i'm working on a joker that is supposed to convert all scoring cards into glass cards in the last hand, and also break them after the hand is scored but i'm having trouble with destroying the cards. does anyone have any tips on how can i achieve this effect?
Is that it? If yes then damn that's insanely easy
how can this be fixed?
what are yall's thoughts on the balance of this
is it too strong or too weak or
feels too strong imo
lemme make that x0.01
so for example, scoring a king with no bonus card or whatever would add x0.02 mult
hard to gauge but that seems like a "+x0.08 per scored card"
How can i make it so Voucher's dont appear in the shop?
yeahh i'm lowering it to x0.01
how about with that?
x0.01 is weak without retrigs tho
is this an unc
specific vouchers or all vouchers
it's a legendary
or rare
all vouchers
so
is this for a deck or a challenge
i'm trying to balance it for that
Joker
legendary??
for a legendary x.04 is good imho
@worthy stirrup
i said Joker
ah
what about bonus cards?
bonus cards bust this wide open lol
do those give more than X0.25 mult? that’s busted as shit
hmm
How do you solve the "Shader uniform 'crystal' does not exist" situation?
has anyone experienced similar to this before?
mb didnt see that,
you'd want to modify G.load_shop_vouchers
so, considering both bonus cards and hiker exist
i think x0.01 would be good?
this won't modify it DURING the shop, but when loading the next shop
@tranquil gull I would do some statistical analysis on the average amount of cards played during a run and base it off of that, keeping in mind a target xmult that you think should be hit by ante 8 boss
thanks
maybe less than that even, if it works the way I think it does.
and Ace/face card would make it gain 0.02x right?
yea they would
i'll ask for help tomorrow
problem is if i make it any lower it gets rounded in the number display
i think i need to sleep
now i gotta find out how to set it back to 1 after the joker is sold
0.01x should be fine in this case then?
also retriggers would break your joker as well
stone card red seal hanging chad pareidolia sock and buskin blueprint brainstorm
altho idk if pareidolia makes stone cards into face cards
I added a custom deck skin and when I use the high contrast version, the face cards have their high contrast colors but the number cards and aces still use their regular low contrast colors, how do I fix that?
wait I eventually figured out.
bpbs shouldn't be considered, parei buskin is pretty rare, chad is alright
fair enough, what about dusk?
Does anyone know how to check for a joker that gets placed in your joker slots the first time 
Constantly changing joker pos in the atlas
so uhhhhhhhhhhhhhhhhhhhh
nothing's getting added to the table
That's cool , I heard about the frames thingy for jokers
first time in the run or first time EVER?
First time in the run
why does this not work (the table part, everything else works fine)
woah. I never seen something like this before in the server.
or having this issue
what is this "Error" thing?
add a label to the loc_txt
like this
SMODS.Edition {
key = "Loving",
loc_txt = {
name = "Love",
text = {
"Placeholder"
},
label = "Love"
},
shader = "OAL_lover",
}
when its purchased you could set a variable to true and then check if that variable was already true
gotcha
are you able to get a cards key with card.key
card.config.center.key
thank you
or you could do something like this:
on_buy then num_times_purchased +=1
if num_times_purchased <= 1 then
-insert code here-
this is pseudocode and wont actually work but I believe in you!
this is weirdly activating regardless of whats being sold
calculate = function(self, card, context)
if context.selling_card then
if card.config.center.key == "j_OAL_Dummy" then
print("I got sold")
end
end
if context.selling_card == card then
if card.config.center.key == "j_OAL_Dummy" then
print("I got sold")
end
end
end```
ty
You can do
Welp, guys I think I've done it that I've finally ported a shadertoy shader that is simple enough into the game.
while it didn't work what I'd originally thought
Slowly but surely
Yeah, I mean I did try my best to port a simple shadertoy shader that I created into balatro but yeah.
for anyone knows what shadertoy I've made and ported to balatro
it's this.
I did my best to port this bad boy
volornoid texture (idk how its spelt)
yes, I was trying to port this texture into balatro and of course what it came out was just only color alteration:
can't see any volornoids there
how would i do this part as the the thing didnt work
bump this
if context.selling_self
approx 1374.28 base chips based on a test run i just did
omg i feel dumb
SMODS.current_mod.set_debuff = function(card)
if card.seal == "modprefix_key" then
return "prevent_debuff"
end
end
This goes outside the seal.
ok let me try
at 0.01x per 5 chips, it'll get to approx 3x by ante 8
that feels weak for a legendary
For making custom cardareas, I need to hook function Game:start_run(args), ya?
Yes.
Consider, were you farming for this though? If I scored that legend in ante 1/2 I would absolutely devote my extra hands to scaling that joker
it didnt work, maybe is because of my prefix?
Code?
SMODS.Seal {
key = 'guard',
atlas = 'Enhancers',
pos = { x = 3, y = 0 },
badge_colour = G.C.GREEN,
}
SMODS.current_mod.set_debuff = function(card)
if card.seal == "guard" then
return "prevent_debuff"
end
end
yea true
It needs to be modprefix_sealkey
how do i check if a card bought is itself?
if context.buying_self
how do you use custom smods rarities?
how do i change how fast ante's scale?
it doesn't really list what to put in the rarity field of jokers though
is the key supposed to be an integer?
Modify G.GAME.starting_params.ante_scaling
thank you
No, it should be a string.
and for a joker's rarity it's "[modprefix]_[raritykey]"?
Yes.
when putting that though i get this error
Code?
is this good ?
it didn't work
fnaf_guard_seal = {
name = "Guard Seal",
text = {
"Immune to debuffs",
},
}
SMODS.Seal {
key = 'guard',
atlas = 'Enhancers',
pos = { x = 3, y = 0 },
badge_colour = G.C.GREEN,
}
SMODS.current_mod.set_debuff = function(card)
if card.seal == "guard" then
return "prevent_debuff"
end
end
You need to change card.seal == "guard" to be card.seal == "modprefix_guard"
fixed it (i forgot to put hex())
looks good to me, but just keep testing it however you can just in case
...well, gotta hide this now.
am i doing this right
More or less, yeah.
how do i get the text in the box 😭
noticed it was wrong and corrected the code now it works perfectly
awesome! ^~^
why does it not like this
you dont need to add to xmult
just return the amount of xmult you want
also use pseudorandom instead of math.random
...odd, the cards of this CardArea don't get saved.
how does "seed" work in pseudorandom?
just put some unique string for that
thats the "seed" for that particular randomized thing
so if you used say a wheel of fortune it wouldnt mess with the shops
i understood half of the things you said
just so you know im completely new to this language so use as much detail as possible or else i might not understand
basically it keeps random things from affecting eachother
id say just throw the name of the card as the seed
so something like this?
no
well
the seed would wortk
but i prob woulnt use that for it
and
oh wait holdon
yea nevermind
forgot pseudorand can have min and max'
how come this isnt ranking up the cards in hand?
if context.end_of_round then
for _,v in ipairs(G.play) do
SMODS.modify_rank(v, 1)
end
end
end,
}
ive also tried G.hand
for example if i was making bloodstone, i would make the seed "bloodstone" or something of that variety
yea i get it
why does it think that a_pleasework is a nil value
G.hand.cards
oh my god
locals are local
to the function they are called in
instead of using a local use the jokers ability.extra table
tried that; didnt work either
show
but this has worked for almost all of my other jokers
what was the issue with this one
same thing; nil error
show
un momenta
someone can help me?
Is that crash on a fresh start?
i have done that
then why do you still have the metadata in the code
i just don't remove it
me or blgh?
probably should
Something seems to be altering the result:
you
no; it's on hand played
delete the joker
and create another
it may just not have the config
not in the code
in the game
like
sell it
no
ok so it works
but it also gives 0.5X mult for every card in hand and in the deck
somehow
i feel i should've mentioned; it was at the end of round
end of round has contexts between every card lol
main_eval makes it so its just that card
so it needs an extra condition
The problem seemed to be that All In Jest was altering the values for some reason.
Seems to work perfectly now.
Is there a way to fix this incompatibility?
shiet.
if you don't instanciate it before loading it gets saved somewhere else
how would i structure the localization for a custom consumabletype in the localization file
i dont remember where
instead of Tarot or Planet or whatever you put the consumabletype key
check vanillaremade

