#💻・modding-dev
1 messages · Page 629 of 1
Anyone? has anyone have an idea how a Lovely patch would work cause right now I've been dealing with this issue to a single joker
You currently are using a Game:start_run(args) hook, yes?
yeah
Set the game.lua as target file to patch, with after for position and set
self.play = CardArea(
0, 0,
CAI.play_W,CAI.play_H,
{card_limit = 5, type = 'play'})
as pattern to target... with payload being
self.customarea = CardArea(insertargshere)
or something. Although, next SMODS release will have a custom_card_areas function for SMODS.current_mod, fwiw.
bump
Did you test that yet? From a quick glance over, should work.
alright. cause I don't think I see sometihngl ike this. but honestly I'll give it a shot.
I already have used the G.holehand thing but honestly I will try and see for myself.
The payload also can be a call of a function defined by your mod... but that probably should be checked for if the function is accessible at that point.
For this example, this lets me safely do my own things during the error handler... mainly to play the death chime of Mac Performa 5400.
thx
Pattern... and for multi-line, use ''' on both ends instead of ".
oh
usage:
local chosen = PLUTO.UTILS.pick_random_cards('bl_jokerblinds_blueprint', G.jokers.cards, math.ceil(#G.jokers.cards/2))
for k,v in ipairs(chosen) do
G.GAME.blind:debuff_card(v)
end
func:
PLUTO.UTILS.pick_random_cards = function(seed, area, n, set)
local f = 'pick_random_cards'
if not area then PLUTO.COMMON.missing_required('area','UTILS.'..f) end
if type(seed) ~= 'string' then PLUTO.COMMON.invalid_type('seed','string', tostring(type(seed)), 'UTILS.'..f) end
if not PLUTO.COMMON.is_area(area) then PLUTO.COMMON.expected_area('area', area, 'UTILS.'..f) end
if set and not PLUTO.COMMON.is_set(set) then error('[PLUTO]: ERROR: `set` is expected to be a valid set, received invalid or nil value') end
local indices = {}
if not set then
for i=1, n do
local c = 0
local function choose()
c = pseudorandom(seed, 1, #area)
if PLUTO.COMMON.tbl_contains(indices, c) then
c = PLUTO.COMMON.pick_unique(seed, area, indices)
end
end
choose()
table.insert(indices, c)
end
else
local valid_indices = {}
for k, v in ipairs(area) do
if v.ability.set == set then
table.insert(valid_indices, k)
end
end
for i=1, n do
local pick = 0
local function choose()
pick = valid_indices[pseudorandom(seed, 1, #valid_indices)]
if PLUTO.COMMON.tbl_contains(indices, pick) then
pick = PLUTO.COMMON.pick_unique(seed, valid_indices, indices)
end
end
choose()
table.insert(indices, pick)
end
end
return indices
end
687 line?
it actually worked Ali, thanks though now this is the problem now.
im back from class now but i havent gotten a response, what do i gotta do to make it work on vanilla blinds
Check SMODS blind.lua.
pick_unique and tbl_contains:
PLUTO.COMMON.tbl_contains = function(tbl, itm)
for k,v in ipairs(tbl) do
if itm == v then
return true
end
end
return false
end
PLUTO.COMMON.pick_unique = function(seed, pool, taken)
local out
repeat
out = pool[pseudorandom(seed, 1, #pool)]
until not PLUTO.COMMON.tbl_contains(taken, out)
return out
end
But atleast it's not removing the two cards. already but now I just need to figure out
where?
in lsp_def/classes/blind.lua there isn't a line 687
about the positions.
blind.lua is actually part of vanilla Balatro, so-
brb
CardArea:init(X, Y, W, H, config), so you want to adjust the first two variables.
i gotta learn how to do the bg stuff myself
i think itd be so cool if there were different backgrounds for how high your hand scores
As you're directly patching into the original function, the hook isn't necessary.
Alright, might as well get rid of the hook by commenting on it
how do i make a joker check its own edition
(self, card, context), so the Joker that's being calculated is card... and to check its' own edition, you just card.edition and card.edition.holo for Holographic, as example.
also not sure if you can make that thing invisible.
I mean under it invisible
so
like if card.edition and card.edition.holo then
insert create holo joker
yeh.
so far nothing breaks but not much works either, this deck is supposed to make every boss blind you beat have its effect last for the entire run, but it doesn't do anything, apparently this is supposed to work but only for modded blinds, i asked how to make it work with vanilla blinds but no response yet (haven't tested it working on modded blinds yet i dont have a blind mod)
elseif, not else if.
Comment out the whole if block that contains the actual card addition, add print(is_foil, is_holo, is_polychrome) to test if those variables of yours actually pass.
SMODS.add_card({key = card.ability.extra.joker, edition = is_foil and 'e_foil' or is_holo and 'e_holo' or is_polychrome and 'e_polychrome' or nil})
...even then, the condition check can be condensed to just this.
wanna know why i excluded negative?
How is it possible to make an invisible cardarea?
That'd be silly.
Add type = discard as part of config table argument... or add your custom key to G.ARGS.invisible_area_types, which is {discard=1, voucher=1, play=1, consumeable=1, title = 1, title_2 = 1} by default.
So something else in your code is causing an infinite loop.
my guess
probably since it creates itself after starting a blind
the copy creates a copy
hi sigma
687 of vanilla balatros' blind.lua is dollars = self.dollars a part of Blind:save()
The Mods/lovely/dump/game.lua version of it.
if self.debuff and not self.disabled and card.area ~= G.jokers then
oh that's blind.lua
a
wait what
game.lua:687 is p_spectral_jumbo_1 = {order = 31, discovered = false, name = "Jumbo Spectral Pack", weight = 0.3, kind = 'Spectral', cost = 6, pos = {x=2,y=4}, atlas = 'Booster', set = 'Booster', config = {extra = 4, choose = 1}},?
I meant blind.lua, oops.
oh then this ^
So what is around it?
Alright, I tihnk I need to find that right?
can't make it work, it doesn't debuff anything
function Blind:debuff_card(card, from_blind)
local obj = self.config.blind
if not self.disabled and obj.recalc_debuff and type(obj.recalc_debuff) == 'function' then
if obj:recalc_debuff(card, from_blind) then
card:set_debuff(true)
if card.debuff then card.debuffed_by_blind = true end
else
card:set_debuff(false)
end
return
elseif not self.disabled and obj.debuff_card and type(obj.debuff_card) == 'function' then
sendWarnMessage(("Blind object %s has debuff_card function, recalc_debuff is preferred"):format(obj.key), obj.set)
if obj:debuff_card(card, from_blind) then
card:set_debuff(true)
if card.debuff then card.debuffed_by_blind = true end
else
card:set_debuff(false)
end
return
end
if self.debuff and not self.disabled and card.area ~= G.jokers then
if self.debuff.suit and card:is_suit(self.debuff.suit, true) then
card:set_debuff(true)
if card.debuff then card.debuffed_by_blind = true end
return
end
if self.debuff.is_face =='face' and card:is_face(true) then
card:set_debuff(true)
if card.debuff then card.debuffed_by_blind = true end
uhhh
good news and bad news
sorry i meant G.GAME.blind:debuff_card(v)
So somehow a number is parsed into the card argument.
it stopped freezing
huh- weird
¯_(ツ)_/¯
gotta make up a new global variable
-# Brain fried... not exactly in best of mindset either - got a whole ass new court order against me. 
-# I'm sorry what? how and who?
-# also I'm sorry to hear that as well
-# Long story... but "debt" is the theme. Not for this channel, anyway.
bump part 29
i fixed it
so I got image loading to work
how do I get a gif to load
as if I try doing it the way I would normally load an image, it would give an error, saying it's an "unsupported file format"
https://love2d.org/wiki/Image_Formats Because GIF is not supported.
yea I just figured that part out
an idea I have is to split it into frames
how would I be able to get it to load the thing frame by frame, while at the same time being able to modify animation speed
split that gif up using an online tool and load the resulting images and also reduce the frame rate and size so you don’t load too much
is it possible to make my own context
like the one in calculate(self, card, >>context<<)
or would it be a different way?
I know this way.
But again, I mean the calculates' context
And there is no goal, I
'm just curious
i think it’s SMODS.calculate_context called with the context object
double check because i couldn’t but
?
you call that with the context object to run all calculates
so you can call it with whatever_context = true and calculate functions can detect for it
finally got it
now only thing left is trying to like apply the two cards into the played hand (or maybe even making that poker hand automatically updates when those two come)
https://github.com/TheOneGoofAli/TOGAPackBalatro/blob/0dcb660b209b0a89f4b4b7894038a246701aeaa4/items/hooks.lua#L355 My Bonzi Buddy Joker has its own context, aye.
Alright. now what about forcing the two cards into the scoring hand or playedhand. as I have in my concept earlier
wait I just realized that this is changes the rank right?
oh yeah i literally did that yesterday
this is a shader though
which im not sure is the best option
-- in utils.lua
function Comedy_load_gif(name, num_frames)
gif = {}
for i = 1, num_frames do
local path = (ComedyGold.path .. "assets/custom/" .. name .. "/" .. name .. "_" .. i .. ".png")
local fileData = assert(NFS.newFileData(path))
local img = assert(love.image.newImageData(fileData))
gif[i] = assert(love.graphics.newImage(img))
end
return gif
end
-- in ComedyGold.lua
if G.nuclearExplosion and (G.nuclearExplosion > 0) then
if not ComedyGold.images["explosion"] then
ComedyGold.images["explosion"] = Comedy_load_gif("explosion", 64)
end
for i, frame in ipairs(ComedyGold.images["explosion"]) do
local a = math.min(1, G.nuclearExplosion * 2)
love.graphics.setColor(1, 1, 1, a)
love.graphics.draw(frame, 0, 0, 0, xScale, yScale)
end
end
ok so It sorta works. Only problem is that it only loads the last frame, and never get's unloaded
This is making a custom context for calculate
update: got the gif to play by simply redoing the image loading part for the gif, but have the current frame be tracked as a game variable. What I should do now is try and get it to sync with the length of the thing showing
What is it that youre trying to do
oh?
SMODS.calculate_context calculates all centers with the given table as the context
i see..
how do I make sure to put the cards into the played hand thing?
I got an error once I played
How do I play audio on loop? do i just use L2ds' sound:setLooping(true)?
I want to play an audio on loop for a tag, and it doesn't stop until it's removed, which only happens by starting a new run.
i literally just told you that lmao
i slept for way too long ;-;

like 15 hours 😭😭
sleeping for too long = grants the ability to hear colors, sleeping for too little = grants the ability to @94n124912shfawaSAUDn
How long would it take to make a mod that makes rare poker hands good? As in straight flush is at least the level of flush for example?
How do I retrigger a joker?
... Uhh... That happened.
I think I'm getting close but not close enough.
had to reup cause it's not playing somehow?
still not playing
Worked just fine for me
Alright but still need to know how on earth I would fix this and maybe have to be once the hand is being played.
bump
Are you trying to retrigger it or just copy it like what blueprint and brainstorm do?
Retrigger
How long would it take to make a mod that makes rare poker hands good? As in straight flush is at least the level of flush for example?
stop repeating yourself
also this is a goofy question to ask just ask how to do it instead
How would I do it?
Like 10 minutes at most
Maybe 30 if youve never modded the game before
But it wouldnt take long at all
On average
the level_up_hand function handles hand level ups so you could hook it and make flush also level up straight flush and flush house etc etc
most of the time taken would be programming all of the checks
Yeah I'm afriad that would be too OP. My idea was that rare hands would have, minimum from inferior hand + rare hand level. But for something like straight flush it would then be straight level + flush level which is too op.
this is true but also this is strictly what you asked for pretty much
you'd need to manually balance it in every case
what is the context of removing a joker itself or a joker is getting destroyed?
like you can just halve the amount of levels it levels up
that triggers the last code thing.
so straight flush scales slower
alternatively you could also probably make straight flush scale the same as flush when the cascading levels happen but i don't want to explain how to do that rn
G.GAME.<rarity key>_mod, see SMODS.Rarity page
wait what
Is my original idea not possible / hard to do? Basically that the rare hands get a floor from their inferiour versions and anything you spend to level up the rare hand is an extra level. So basically if you have flush at level 5 and straight at level 3 then straight flush would be level 5. If you then get Neptune straight flush would become level 6.
thats possible but would be incredibly annoying for me to explain and to implement
I just wanted to make legendaries able to appear in shop for a voucher
variable modification when the humble redeem(self, card) walks in
so like G.GAME.legendary_mod = [some number] in redeem() per se ?
yeah
wait i think that won't work
its a _mod meaning it multiplies the rarity weight by that
It wont
if the weight is initially zero then it stays zero
what is this
self.config = { increase_legendary_pool_rate = 0.008, extra = {}}
;-;
is that even a vanilla thing
No
exactly
Its probably in a hook somewhere
rah
Some create_card hook or smth
self.config = { increase_legendary_pool_rate = 0.008, extra = {}}
vars = { }
else
key = self.key
self.config = {joker_slot = -1, extra = {should_increase = true, remove_amt = 0, counterbalance = 0}}
vars = { self.config.joker_slot }
end
return { key = key, vars = vars }
end,
apply = function(self, sleeve)
CardSleeves.Sleeve.apply(self)
if self.get_current_deck_key() == "b_aij_fabled" then
self.config = { increase_legendary_pool_rate = 0.008, extra = {}}
G.E_MANAGER:add_event(Event({
trigger = "after",
func = (function()
G.GAME.jest_legendary_pool.rate = G.GAME.jest_legendary_pool.rate - sleeve.config.increase_legendary_pool_rate
return true
end)
}))
else
self.config = {joker_slot = -1, extra = {should_increase = true, remove_amt = 0, counterbalance = 0}}
G.E_MANAGER:add_event(Event({
trigger = "after",
func = (function()
G.GAME.jest_legendary_pool.in_shop = true
G.GAME.jest_legendary_pool.rate = G.GAME.jest_legendary_pool.rate - 0.008 -- 0.08%
return true
end)
}))
end
end,
calculate = function(self, sleeve, context)
local deck_or_sleeve = (sleeve.config.extra and sleeve.config.extra.should_increase and sleeve) or G.GAME.selected_back.effect
if not sleeve.config.increase_legendary_pool_rate then
if context.end_of_round and not context.repetition and not context.individual and deck_or_sleeve.config.extra.should_increase then
G.GAME.jest_legendary_pool.rate = G.GAME.jest_legendary_pool.rate - 0.002
deck_or_sleeve.config.extra.remove_amt = deck_or_sleeve.config.extra.remove_amt + 0.002
end
bump
wdym exactly?
Do you mean how to use it?
play_sound('modprefix_soundkey',volume,pitch)
-# or was it pitch, volume?
you have to do SMODS.Sound{...} first
Not sure if this seems a bit more sense for texas hold em'
I mean that it doesn't work eventhough I think I did it all correctly
what on earth?
It just crashes and tells me that the file doesn't exist
how the heck do I avoid this?
Is it possible to download the exmple mods here https://github.com/Steamodded/examples/tree/master/Mods
bump part 2.9 nonvigitilion
why does this deck crash my game?
use = function(self, card, area, copier)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('timpani')
SMODS.add_card({ set = 'Joker' })
card:juice_up(0.3, 0.5)
return true
end
}))
delay(0.6)
end,
how do i make this take from a custom pool?
SMODS.add_card({set = 'poolkey'})
how do i check what cardarea a card is in?
card.area is the area object itself
so card.area == G.jokers checks if card is in the jokers area
for having something print in debugplus's logs, do i just use the print() function?
yep
cool, thanks
bump
if crash then why no crash log
this feels like a dumb question but: is there a way to tell if a playing card is in your deck or not
because apparently added_to_deck is nil for all of the playing cards that start in your deck
As opposed to being where?
You mean if it is currently in the deck or if it is in the full deck?
If it's the actual deck location, you can check the area. Otherwise you can look for it by iterating though G.playing_cards. But generally area should be a good check, as the playing cards that exist in game but aren't in your deck are probably in the shop or a booster
as in whether it's in your full deck or whether it's in a booster pack or shop
iterating through G.playing_cards seems like a horribly inefficient solution
especially as it seems unintentional that some cards in your deck will have added_to_deck defined as true (anything that gets added to your deck after the run starts will have this set correctly)
if card.area ~= G.pack_cards and card.area ~= G.shop_jokers
unintentional meaning it seems like a bug with balatro, so it may not be SMODS' job to fix it
how do i get_current_pool with repeating jokers like showman
this feels like it'd be liable to breaking if mods add any other locations for playing cards to be (of which i can think of at least one example) but i suppose it can work well enough
local oldsmodsshowman = SMODS.showman
SMODS.showman = function() return true end
local pool = get_current_pool('Joker')
SMODS.showman = oldsmodsshowman
ty
although actually this doesn't resolve the problem i was having originally, which is trying to ensure i don't do anything when initially adding the card to the deck
that is a cursed way of getting a duplicate pool
more specific context is, i have a joker that's triggering when a playing card's rank or suit changes, and this context is called when creating a copy of the card, such as via the cryptid spectral
i'm looking to only get the joker triggered when an existing card changes, but it seems like there isn't a reliable way to know whether a card is in your deck yet
I mean, if other mods add additional card areas, that will be more difficult to detect, yeah. But checking the card's area is one way. But I don't see the issue with checking if it's part of G.playing_cards, if you want to be sure.
No, just patch copy_card
context.change_suit and context.change_rank will cover this iirc
i'm using these contexts and they do not cover this
oh
Card:set_base is called from copy_card, and those contexts will trigger any time set_base is called
i do wonder whether patching the game such that added_to_deck is properly defined for your initial deck would change any behavior at all
No, you would patch copy_card
i'm not seeing how patching copy_card solves much for me here
how do i make a joker turn itself into something better
card:set_ability('j_modprefix_key')
can i do the same with consumables
Yes.
my issue is that copy_card calls set_base (as it needs to do, obviously, for the new card to have the same rank and suit as the original card), but doing so triggers the contexts for changing rank and suit, and there is no way for me to determine within those contexts whether the card is in your deck or not
i suppose your proposal is that i should be patching copy_card to add my own variable to say the card is a copy?
yippee
Yes, because that's what I did.
hm
i think this would introduce a new problem of preventing death from working though
as copy_card is also used for that
as in, if you use death to change a card, it should correctly call the contexts (as it's altering an existing card in your deck, which is the behavior i want to target)
though i guess maybe just checking that new_card is nil would be enough to recognize if it's from a death or if it's a new copy
I think copy card should be calling set base with the initial parameter set to true when there isn't a card it's copying on to
i would also think this but it seems it doesn't
yes, it's a change I'll need to make in smods I think
i think if that were changed and the rank/suit contexts were provided an initial field then yeah that would be sufficient for being able to tell whether it's affecting an existing card or not
oh ugh this actually needs to be a lovely patch
Gonna drop this soon
Is there a way to make a joker check if the jokers you own are a part of a specific group
trying to make an edition where playing a card with a specific suit will have a chance to retrigger the joker.
calculate = function(self, card, context)
local canRetrigger = false
if context.individual and context.cardarea == G.play and
context.other_card:is_suit(card.edition.extra.suit) and
context.retrigger_joker_check and
SMODS.pseudorandom_probability(card, 'comedy_greedy_edition', 1, card.edition.extra.odds)
then
canRetrigger = true
end
if canRetrigger and context.retrigger_joker_check then
return { repetitions = card.edition.extra.retriggers }
end
end
it doesn't seem to be doing anything. What can I do to make it actually work
if card.ability.set == 'Joker' and context.retrigger_joker_check and context.other_card == card and G.play and next(G.play.cards) then
local effects = {}
for k, v in pairs(G.play.cards) do
if v:is_suit(card.edition.extra.suit) and SMODS.pseudorandom_probability(card, 'comedy_greedy_edition', 1, card.edition.extra.odds) then
table.insert(effects, {repetitions = card.edition.extra.retriggers, message_card = v})
end
end
return SMODS.merge_effects(effects)
end
Why does this retrigger nothing instead of itself?
if context.retrigger_joker_check and card == self then
It's an edition
how do i apply a shader without a edition...
probably drawstep
im trying to make it so this joker spawns filler jokers and gains x mult for each one of those owned, how do i make it so the xmult properly correlates to the amount?
config = {extra = { Xmult = 1, }},
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.Xmult,
1 + card.ability.extra.Xmult*funnykittyamount}},
-- need to figure out how to define these x amount of jokers.
end,
calculate = function(self,card, context)
-- if context.other_card/how df do i create more kitty
if context.setting_blind then
return {
SMODS.add_card{ key = c_pokers_funnykitty}
-- here is where i would put my kitty spawning logic... if i had one!!
}
end
if context.joker_main then
return {
Xmult_mod = card.ability.extra.Xmult,
message = localize { type = 'variable', key = 'a_xmult', vars = {card.ability.extra.xmult} }
}
end
card.ability.extra.xmult = card.ability.extra.xmult + card.ability.extra.xmult_gain
return {
message = '+1 Kitty!',
colour = G.C.XMULT,
card = card
}
end```
the *funnykittyamount being a filler variable
also im just realizing the message return should be in the other context dont worry about that
bump part i lost track of the count please end my suffering
i still
don't get it
i need to apply the shader to a created card btw
idk man I've never worked with drawstep before, I just know it exists
:swear:
It's context.other_card not card also it's card not self
'card == card' ?
No, context.other_card == card
how do I make a deck give things like 30 chips before any joker gives stuff like x mult x chips etc
is there a way to see if any card in deck has a polychrome edition? I wanna do something like steel joker of sorts but with polychrome cards\
ballotro
card.ability.extra.poly_tally = 0
for k, v in pairs(G.playing_cards) do
if v.edition and v.edition.polychrome then
card.ability.extra.poly_tally = card.ability.extra.poly_tally + 1
end
end
You mean you want to prevent a card from being debuffed?
yea
SMODS.current_mod.set_debuff = function(card)
if condition then
return 'prevent_debuff'
end
end
tyyyyyyyyyyyyyyyyyyyyyyyyyy
why doesn't this work?
if context.other_joker and (context.other_joker.config.center.rarity == 1 or context.other_joker.config.center.rarity == "Common") then
return {
money = card.ability.extra.dollars
}
end
if context.other_joker and context.other_joker:is_rarity('Common')
...that, and dollars =, not money =.
oh right oops
How do I get if the player only has 1 tarot card?
local count = 0
for k, v in pairs(G.consumeables.cards) do
if v.ability.set == 'Tarot' then
count = count + 1
end
end
if count == 1 then
end
tyyyyyyy againnnnnnnnnnn
the edition label seems to not be working. What am I doing wrong in the loc file?
nothing, because it's a separate thing you have to localize. read the last sentence here
https://github.com/Steamodded/smods/wiki/SMODS.Edition
why does this crash?
-- in loc_vars
colours = {
HEX("000000"),
HEX("FF0000"),
HEX("00FF00"),
HEX("0000FF")
}
I was using {V:4} and {B:1} and the others in other places
colours goes in the vars table
how do i get the message here to show on this joker? every time another joker gives +mult, the upgrade message is displayed on the +mult-giving joker instead
calculate = function(self, card, context)
if context.post_trigger and context.other_card and context.other_card.config and context.other_card.config.center_key ~= "j_bfs_compressed" and not context.blueprint_card then
if context.other_ret and context.other_ret.jokers and (type(context.other_ret.jokers) == "table" and context.other_ret.jokers.mult and context.other_ret.jokers.mult ~= 0) or (type(context.other_ret.jokers) == "table" and context.other_ret.jokers.mult_mod and context.other_ret.jokers.mult_mod ~= 0) then
card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_mod
return {
message = localize("k_upgrade_ex"),
colour = G.C.RED
}
end
end
end,
i've tried card = card and card = self, but neither have worked
forget about this, I just changed the ability of the deck to one I could easily make
message_card =
currently creating a custom gradient and wondering how to access it in code (like how you can set a badge color to G.C.RED for instance)
Somehow the play_sound() crashes the game, I don't understand why
How do you apply a perishable sticker on joker creation?
I think card:set_perishable(true) with card being the created joker card
SMODS.add_card({ set = 'Scalala',card:set_perishable(true)})
smth like this?
uhhh prob not
how else would you do apply it?
SMODS.add_card({ set = 'Scalala',stickers = {"perishable"}})
music playback isn't to be done like that, see https://github.com/TheOneGoofAli/TOGAPackBalatro/blob/a2424252ea37981a37a1fe4ccb659c2cf29f08f9/togastuff.lua#L160-L167 for example
^
where do you apply the force_stickers = true?
anywhere in the table
holup i have the answer give me 5 seconds
I don't think force_stickers is necessary? Just reading the documentation
SMODS.Gradients["key"]
yea
documentation is bad
i think so bcs
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('timpani')
SMODS.add_card({ set = 'Scalala', stickers = { "perishable" } })
card:juice_up(0.3, 0.5)
return true
end
}))
``` this doesn't apply a sticker
shocking ik
figured it out by digging thru the smods source
force_sticker = true
ah alr
inside the event of function?
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
play_sound('timpani')
SMODS.add_card({ set = 'Scalala', force_stickers = true, stickers = { "perishable" } })
card:juice_up(0.3, 0.5)
return true
end
}))
Maybe im just stupid but this doesn't work
compare with this
SMODS.add_card({
key = "j_crafty",
stickers={"perishable"},
force_stickers = true
})
since this one does work
why is set Scalala is that like a rarity or?
actually doesnt matter
custom pool
ah
bump part i dont know anymore
i'd help if i could man
has to have a bunch of to_big() dw tho ali helped me
idk i have it working without to_big() 
if context.cardarea == G.jokers and context.joker_main then
if hand_chips % 2 == 0 then
return {
xchips = card.ability.extra.div_chips
}
else
return {
xchips = card.ability.extra.xchips,
extra ={chips = -card.ability.extra.minus_chips}
}
end
end
end
-# yea i know this isnt the best coding, not need to remind me
basically the exact same as the other two 🙏 fym not the best, if the other 2 did it the same its probably not bad
wait handchips is probably for the base chips?
idk if cass meant for current chips
hand_chips is current
ah okay
mod[1].id
aeuhuheuhehuhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
ml some things are annoying
why does name appear and not text
Use " instead of ' I'm pretty sure
🤷♀️
Try putting it in Other instead.
bro copied my code without knowing what to do with it
COUGH COUGH
i know this because i came up with the name description dummies
-# So then how do i use it
just put it in others
all of it?
and use it the normal people way
i dont know how the normal people do it, ive tried dd_Bitters_CassGlop in it and descriptiondummy
ik i might be dumb
Description Dummy is not how normal people do it
Other = {
dd_Bitters_CassGlop = {
name = "Re:potassium Crossmod",
text = {
'{V:1}Spawn{} a {C:dark_edition}negative{} {C:planet}Glopur{} every {C:attention}3{} rounds {B:1,C:inactive}(#4#){}',
}
}
},
so why no work?
how did you add info queue
also you don't need the "dd_" in the key
if Bitterstuff.crossmodded["potassium_re"] then
info_queue[#info_queue+1] = {set = "DescriptionDummy", key = "dd_Bitters_CassGlop", vars = {card.ability.extra.round2}}
end
mmmmmmm
dd is what i came up with
euuguhhhh so whats broken
i have it outside of Other because i don't want to clutter vanilla things
Yes.
bro im gonna throw my pc outta my window
if Bitterstuff.crossmodded["potassium_re"] then
info_queue[#info_queue+1] = {
set = "Other",
key = "Bitters_CassGlop",
vars = {
card.ability.extra.round2,
colours = {
HEX("000000"),
HEX("FF0000"),
HEX("00FF00"),
HEX("0000FF")
}
}
}
end
why is it nil
oh
noononon
nvm
i got it
listen guys i know im really annoying right now i've been bumping this for the past like 2 days but i still havent gotten like a reply or anything and i really want to make this 😭
bump ):
it might just be that decks cant make sounds idk
how would I go about appending my custom UI table to G.HUD?
getting "functions/common_events.lua:2323: attempt to index local 'center' [a nil value]
upon attempting to create a joker at the start of a blind. its saying my key to reference to the joker is forced. any ideas?
SMODS.Atlas{
key = 'Pokers', -- might need to add this later to all the everything as a tag ig
path = 'Pokers_Jokers.png',
px = 71,
py = 95
}
SMODS.Joker{ --catastic
key = 'catastic',
loc_txt = {
name = 'Catastic',
text = {
'When Blind is selected,',
'create a {C:attention}Funny Kitty{}',
'Gains {X:mult, C:white}X#1#{} Mult for each {C:attention}Funny Kitty{}',
'{C:inactive}(Currently {X:mult}X#1#{C:inactive} Mult)'
}
},
atlas = 'Pokers',
pos = {x = 0, y = 0},
rarity = 2,
cost = 6,
unlocked = true,
discovered = true,
config = {extra = { Xmult = 2, creates = 1}},
loc_vars = function(self, info_queue, card)
local kitty_count = #SMODS.find_card("c_Pokers_funnykitty")
return { vars = { card.ability.extra.Xmult + kitty_count, card.ability.extra.creates}}
-- need to figure out how to define these x amount of jokers
end,
calculate = function(self,card, context)
if context.joker_main then
local kitty_count = #SMODS.find_card("c_Pokers_funnykitty")
return {
Xmult_mod = card.ability.extra.Xmult + (2*kitty_count),
messsage = localize { type = 'variable', key = 'a_xmult', vars = {1 + kitty_count}}
}
end
-- if context.other_card/how df do i create more kitty
-- removed: #G.jokers.cards + G.GAME.joker_buffer < G.Jokers.config.card_limit
if context.setting_blind then
local jokers_to_create = math.min(card.ability.extra.creates,
G.jokers.config.card_limit - (#G.jokers.cards + G.GAME.joker_buffer))
G.GAME.joker_buffer = G.GAME.joker_buffer + jokers_to_create
G.E_MANAGER:add_event(Event({
func = function()
for _ = 1, jokers_to_create do
SMODS.add_card{ key = "c_Pokers_funnykitty"}
G.GAME.joker_buffer = 0
end
return true
end
-- here is where i would put my kitty spawning logic... if i had one!!
}))
return {
message = '+1 Kitty!',
colour = G.C.XMULT,
card = card
}
end
if context.joker_main then
return {
Xmult_mod = card.ability.extra.Xmult,
message = localize { type = 'variable', key = 'a_xmult', vars = {card.ability.extra.xmult} }
}
end
for _, catastic in ipairs(SMODS.find_card("c_Pokers_funnykitty")) do
card.ability.extra.xmult = card.ability.extra.xmult + card.ability.extra.xmult_gain
-- return {}
end
end
}
how do i add the flipping effect to ts
SMODS.Consumable {
key = 'beth',
set = 'blindconsumabletype',
pos = { x = 1, y = 0 },
atlas = 'blindcon',
display_size = {w = 64, h = 64},
config = { max_highlighted = 1 },
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.m_mult
info_queue[#info_queue + 1] = G.P_CENTERS.m_wild
info_queue[#info_queue + 1] = G.P_CENTERS.m_glass
info_queue[#info_queue + 1] = G.P_CENTERS.m_steel
info_queue[#info_queue + 1] = G.P_CENTERS.m_stone
info_queue[#info_queue + 1] = G.P_CENTERS.m_gold
info_queue[#info_queue + 1] = G.P_CENTERS.m_lucky
return { vars = { card.ability.max_highlighted } }
end,
use = function(self, card, area, copier)
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.4,
func = function()
local enhancement = SMODS.poll_enhancement({key = 'emuismeaningsmile', guaranteed = true, options = {'m_mult', 'm_wild', 'm_glass', 'm_steel', 'm_stone', 'm_gold', 'm_lucky'}})
local change_card = G.hand.highlighted[1]
change_card:set_ability(enhancement, true)
card:juice_up(0.3, 0.5)
return true
end
}))
end,
can_use = function(self, card)
if G and G.hand then
if #G.hand.highlighted ~= 0 and #G.hand.highlighted <= 1 then
return true
end
end
end
}
card:flip()
that flips itself though, not the enhanced card
chance_card:flip()
the flip() function is something all cards have access to, so as long as something is a card, you can call :flip() on it!
Hey guys,
is there any tutorial about in-game animation, as in, let's say,
moving a png across the screen?
I've planned to make some custom animation for some of my consumeables in the future.
is there a way to make sure jokers cant appear in shop
in_pool = function() return false end
Would that make it so it cant spawn in general or just shop
I don'T even know why this is happening.
And I tried to find ways to fix it and now there is a nother problem
tihsi s what's happening.
bump part ???
- once the round ends the two card on the area still put there for no reason.
- dispite it displays the thing weirdly somehow it's skipping the other cads that could easily qualify for a hand?
Am I missing something to make this joker have the +chips message appear on the planet cards?
calculate = function(self, card, context)
if context.other_consumeable and context.other_consumeable.ability.set == 'Planet' then
local planets_used = 0
for k, v in pairs(G.GAME.consumeable_usage) do if v.set == 'Planet' then planets_used = planets_used + 1 end end
return {
chips = planets_used * card.ability.extra.chips,
message_card = context.other_consumable
}
end
end,
Bump anyone knows how t ofix this?
you put other_consumable instead of other_consumeable in the message_card
classic blunder, thanks
bump again.
How would I make an edition that has a 1 in 4 to make the Joker/Card not trigger?
decided to add G.C.RETRIGGER / {C:retrigger} just for clarity
"time finish"
"use hand finish implies"
"card all is use time again""power big"
how can you check what pools a joker is in
bump
Anyone?
bump2
Hook eval_card
Bump, How do you fix this whole issue?
Code?
alright give me a moment
first was the joker.
||-- World Joker Tour SMODS.Joker { key = "worldpokertour", loc_txt = { name = 'World Joker Tour (GBA 2005)', text = { [1] = "Texas Hold Em'" } }, unlocked = true, blueprint_compat = true, perishable_compat = false, rarity = 2, cost = 5, pos = { x = 0, y = 0 }, atlas = 'j_placeholder', display_size = { w = 71, h = 95 }, config = { extra = { t_chips = 0, }, }, loc_vars = function(self, info_queue, card) return { vars = { card.ability.extra.t_chips, } } end, calculate = function(self, card, context) if context.setting_blind and not context.blueprint and not context.repetition then G.FUNCS.draw_from_deck_to_hole_hand() end if context.before and context.main_eval and not context.blueprint then --G.FUNCS.draw_from_hole_hand_to_play() end if not context.end_of_round and context.game_over == false then if context.after and not context.blueprint and not context.repetition then G.FUNCS.draw_from_deck_to_hole_hand() end end if context.joker_main then return { chips = card.ability.extra.t_chips } end end }||
The code where I had the G.FUNCS to work:
||```
G.FUNCS.draw_from_deck_to_hole_hand = function(e)
local tour_space = e or math.min(#G.deck.cards, G.hand.config.card_limit - #G.hand.cards)
tour_space = math.min(#G.deck.cards, 2)
delay(0.3)
for i=1, tour_space do --draw cards from deckL
if G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK then
draw_card(G.deck,G.holehand, i*100/tour_space,'up', true)
else
draw_card(G.deck,G.holehand, i*100/tour_space,'up', true)
end
end
end
G.FUNCS.draw_from_hole_hand_to_play = function(e, spac_)
local anycarddrawn = false
local allholehands = {}
for i = 1, #G.holehand.cards do
allholehands[#allholehands+1] = G.holehand.cards[i]
end
if #allholehands > 0 then
for i = 1, #G.holehand.cards do
for v = 1, #allholehands do
draw_card(G.holehand, G.play, (i+(spac_-1))*100/((#allholehands)+spac_), 'up', nil, G.holehand.cards[i])
anycarddrawn = true
end
end
end
end
||```[[patches]]
[patches.pattern]
target = "game.lua"
pattern = '''self.play = CardArea(
0, 0,
CAI.play_W,CAI.play_H,
{card_limit = 5, type = 'play'})'''
position = "after"
match_indent = true
payload = '''
self.holehand = CardArea(
9.5, 2.75,
G.CARD_W * 1.5,G.CARD_H * 0.9,
{card_limit = 2, type = 'hand', highlight_limit = 0})
'''
[[patches]]
[patches.pattern]
target = "cardarea.lua"
pattern = "(self.config.type == 'deck' and self ~= G.deck) or"
position = "before"
match_indent = true
payload = '''
(self.config.type == 'hand' and self == G.holehand) or
'''
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''for i=1, #G.hand.highlighted do
if G.hand.highlighted[i]:is_face() then inc_career_stat('c_face_cards_played', 1) end
G.hand.highlighted[i].base.times_played = G.hand.highlighted[i].base.times_played + 1
G.hand.highlighted[i].ability.played_this_ante = true
G.GAME.round_scores.cards_played.amt = G.GAME.round_scores.cards_played.amt + 1
draw_card(G.hand, G.play, i*100/#G.hand.highlighted, 'up', nil, G.hand.highlighted[i])
end'''
position = "after"
match_indent = true
payload = '''
G.FUNCS.draw_from_hole_hand_to_play(nil, (#G.hand.highlighted))
'''
Here's thel ovely patch.
there we go
sorry if I had to like share all the code here cause I wasn't sure if I have to like go into detail. I might delete this once it gets resolved.
what method would be safe to get the length of the purchased vouchers array within the in_pool function?
#G.vouchers.cards
how do i add a cardarea to a joker description?
you see that's what i had
why is it working now
thanks i guess
maybe had an invisible typo, kept on saying i was trying to index G.vouchers.cards
crash on this line, attempt to compare number with table
was testing if #G.vouchers.cards > 0 then
Uhh how would I make a timer that whenever it hits a number it would add more to a variable and then reset?
okay i need some help with smods internals
i want to mount a folder over the SMODS folder so that i can, for example, add SMODS/_/localization/tok.lua
this is in a non-SMODS mod
@rough furnace i see you're part of the SMODS github team, would you happen to know if this is possible?
You can put whatever keys you want in your own mods localization
what i have rn is this:
if not NFS.mount(mod_dir .. "/crossmod/SMODS", "SMODS", true) then
error("failed to mount crossmod assets")
end
yes, but
i tried putting the keys of other mods but it doesn't work
Can I see an example?
Actually your priority might have to be higher
Than the other mod
how do you load localization?
function _tokipona_init_language(self, mod_dir)
check_mount(mod_dir)
self.LANGUAGES['tok'] = {
font = 1,
label = "toki pona",
key = "tok",
beta = true,
warning = {"toki ni li sin mute a", "sina wile pana pona la o pali e nena toki", "o pali sin la ni li pona"},
}
end
[[patches]]
[patches.pattern]
target = "game.lua"
position = "before"
pattern = "for _, v in ipairs(self.FONTS) do"
payload = """
_tokipona_init_language(self, "{{lovely_hack:patch_dir}}")
"""
times = 1
match_indent = true
maybe i could move check_mount to the top of main.lua
yea here's the new one:
local mounted = false
function _tokipona_load_language(mod_dir)
if not mounted then
mounted = true
if not mount(mod_dir .. "/localization", "localization", true) then
error("failed to mount mod assets")
end
if not mount(mod_dir .. "/crossmod/SMODS", "SMODS", true) then
error("failed to mount crossmod assets")
end
end
end
function _tokipona_init_language(g)
g.LANGUAGES['tok'] = {
font = 1,
label = "toki pona",
key = "tok",
beta = true,
warning = {"toki ni li sin mute a", "sina wile pana pona la o pali e nena toki", "o pali sin la ni li pona"},
}
end
[[patches]]
[patches.pattern]
target = "game.lua"
position = "before"
pattern = "for _, v in ipairs(self.FONTS) do"
payload = """
_tokipona_init_language(self)
"""
times = 1
match_indent = true
[[patches]]
[patches.pattern]
target = "main.lua"
position = "before"
pattern = "function love.run()"
payload = """
_tokipona_load_language("{{lovely_hack:patch_dir}}")
"""
times = 1
match_indent = true
still not working though
@rough furnace basically what 'm asking is is there anywhere i can mount(mod_dir .. "/crossmod/SMODS", "???", true) to to make this work
Not really
the simplest solution would be to register a smods mod for override smods loc
this can be done without losing vanilla compat (see DebugPlus)
how would i store a card in a joker?
I'm not really familar enough with how smods loads it's localization to suggest a way to load yours after it
What is the goal?
i mean
i'm not loading it on top of a file
i wanna have a consumable that i can put inside the joker and take back out
neither is smods
you'll have to creat a meatadata with a lua file as the main file (it can be empty) in the same folder as the localization folder
or well you can use the one function to load it too if you want to do so manuaklly
You would use Card:save and Card:load
where can i find documentation on those functions?
damn that actually did it
if context.end_of_round then i think???
it's annoying to have all of the cross mod localization in one file though
You can't.
😭
I actually wrote something for loading a localization folder earlier. It might not be fully adequte but I can send the code
then how do i use them?
nah i got it
local savedcard = card:save()
local newcard = SMODS.create_card({set = savedcard.ability.set})
newcard:load(savedcard)
thanks
I'm using smth like this
If I double a joker's values, and the joker adds a number of joker slots, how do I double the slots?
SMODS.Sound({key = "crit", path = "crit.ogg",})
SMODS.Joker {
key = "teto",
atlas = "comedy_jokers",
pos = { x = 2, y = 2 },
soul_pos = { x = 3, y = 2 },
unlocked = false,
blueprint_compat = true,
rarity = 4,
cost = 20,
config = { extra = { joker_slot_gain = 1, joker_slots_added = 0 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.joker_slot_gain, card.ability.extra.joker_slots_added, colours = { ComedyColors.TETO } } }
end,
calculate = function(self, card, context)
if context.final_scoring_step and (SMODS.calculate_round_score() > G.GAME.blind.chips) then
return {
message = "+1 Joker Slot",
colour = ComedyColors.TETO,
sound = "comedy_crit",
func = function()
G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra.joker_slot_gain
card.ability.extra.joker_slots_added = card.ability.extra.joker_slots_added + card.ability.extra.joker_slot_gain
end
}
end
end,
add_to_deck = function(self, card, from_debuff) -- resets the amount added (prevents unnecessary joker slot removal)
if from_debuff then
G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra.joker_slots_added
else
card.ability.extra.joker_slots_added = 0
end
end,
remove_from_deck = function(self, card, from_debuff) -- removes any joker slots that you gained
G.jokers.config.card_limit = G.jokers.config.card_limit - card.ability.extra.joker_slots_added
end
}
I already got edge cases so that the slots gained are removed if the joker is debuffed (and the slots are added back when it is undebuffed)
i'm doing this and the load is crashing the game
Code?
if (card.ability.extra.card) then
local newcard = SMODS.create_card({set = card.ability.extra.card.ability.set})
newcard:load(card.ability.extra.card)
else
card.ability.extra.card = G.consumeables.highlighted[1]:save()
G.consumeables.highlighted[1]:remove()
end```
wait that's not it
there

i still dunno how to fix this
is there a way to see if a joker got retriggered
anyone know why this isn't working?
Is this check correct?
@daring fern got any idea why this is crashing?
since u asked to see my code earlier
Log?
This new Enhanced card of mine isn't giving its ^Mult. Can anyone tell me why?
-- Uranium Card
SMODS.Enhancement {
key = "uranium",
atlas = "EnhancedSheet",
set = "Enhanced",
pos = {
x = 0,
y = 0
},
object_type = "Enhancement",
config = {
extra = {
emult = 1.15,
cards_to_destroy = 1
}
},
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.emult,
card.ability.extra.cards_to_destroy,
},
}
end,
replace_base_card = true,
no_rank = true,
no_suit = true,
always_scores = true,
calculate = function (self, card, context)
if (context.cardarea == G.play) and context.main_scoring then
for i = 1, card.ability.extra.cards_to_destroy do
SMODS.destroy_cards(pseudorandom_element(G.hand.cards, 'm_lapsems_uranium'))
end
end
end
}
emult isnt implied like xmult or +mult is right
i thought you had to do it yourself
I dunno, I saw it in some of Minty's code and it evidently must've turned out hunky-dory.
okay but maybe they had a patch or smtn that made it implied
is this the place to look for testers or am i at the wrong place
I looked again at Minty's code, and it looks like she had to download Talisman to make it work.
talisman moment
to be fair, i'd recommend having talisman if ur using emult anyways
since it very easily passes vanilla naneinf
scale a tropical smoothie in 4 rounds with oil lamp then put them in the center of your joker slots. this trick will ruin your life because you listened to a type A chatter.
🔥
i didnt get no answer im asuming thats a no then
maybe if you show off your mod then people would be interested in trying it out
and i'd say showcasing ur mod would go in #⚙・modding-general
or make a post in #1209506514763522108
thank you for the help wise man
woah where did you get that
I installed Talisman, but the Uranium card still doesn't work. All it does is destroy a random card in hand.
also bumping this bc i'm still stumped and haven't gotten a response yet
What are you trying to accomplish here?
i'm trying to load a card that i've saved but it just crashes the game
i'm using :save() and :load() exactly how i was told to use it
You trying to retrieve a Joker card or a consumable card?
consumable
not that it should matter since the save/load functions are part of Card, so it should work regardless
also my code snippet literally says G.consumeables 😭
I'm sorry, slimestuff, but I've never dealt with this kind of code before. I don't know how to help you.
you might have to install talisman
i'm convinced :load() is just broken
or :save()
and i can't find any examples of it being used in vanillaremade
it's okay
i looked at the vanilla function tho
that could be wrong but might as well try it
other_card isn't referenced anywhere
oh yea it uses self nvm my bad
i was just looking at a hook of it used in another mod so all i saw wasthe parameters
vanilla function for reference
yeah
is your crash still this one
i need to be up early anyways and it's already past 1am
yes
it's crashing cus it's trying to index self.VT.h but the Card:load method seems to always assign nil to that, presumably cus of a typo (should be self.T.h lowercase)
so how do i fix that?
also fun to know i was genuinely right about a vanilla function being broken
and it wasn't just my shitty coding :)
you aren't returning an emult value, is why
return {
emult = card.ability.extra.emult
}
dunno, I guess just patch that line out
and see if that fixes all your issues
so just replace it with self.VT.h = self.T.h
since my thingy is for a modding event i asked an organizer and
this sounds like an issue for the SMODS team
if you don't want to patch it do card:hard_set_T() right after loading it
that's what the game does whenever it loads a card
thanks
that works
i've still let one of the smods devs know though
as this is a bug in the vanilla code that can cause probems for modders
how do i put a cardarea in a card's description
not getting much answers in modding-chat but does anyone that knows git better than me know why this is happening
i'm trying to reuse old code where i managed to do it but it's just putting the cardarea in the top-left of the screen instead
?
i've had more unique cloners than unique visitors yesterday
both of my mods spiked like this too
technically 3 of them did but cardpronouns averages 0 downloads per day so having 2 on 12/3 isnt that unusual
cryptid & talisman also kinda spiked but less so
cryptlib spiked from 0 on 12/2 to 9 on 12/3
vinny voice WHO'S BEEN SCRAPPING BALATRO MODS!?!?!?
28 were unique
seu pai
ultra dragging it
fearful emoji
How do I check if it is the end of an ante?
if context.ante_change and context.ante_end
how would i check whether a given card is a playing card or a consumable?
nvmd
how do i emplace a card to my hand and also add it to the deck
okay yea i'm stuck on this

im want to make a dynatext thing where the text teleports/shakes around aggressively but there isnt any documentation on dynatext
Hey so quick question.
Let's say I have a legendary joker that gains xmult every time a probability succeeds, and I also have a luck based edition.
How do I prevent said joker from causing a stack overflow error whenever they get that edition and I try and play a hand?
-# i can't even get any crash logs as it crashes that too
Code?
SMODS.Joker {
key = "wip",
atlas = "comedy_jokers",
pos = { x = 0, y = 2 },
soul_pos = { x = 1, y = 2 },
unlocked = false,
blueprint_compat = true,
rarity = 4,
cost = 20,
config = { extra = { xmult_gain = 0.5, xmult = 1 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.xmult_gain, card.ability.extra.xmult_loss, card.ability.extra.xmult, colours = { ComedyColors.GAMBLE } } }
end,
calculate = function(self, card, context)
if ((context.pseudorandom_result and context.result and not Comedy_table_contains(UnluckyOutcomes, context.identifier))
or (context.pseudorandom_result and not context.result and Comedy_table_contains(UnluckyOutcomes, context.identifier)))
then
return {
message = "Lucky!",
colour = HEX("43e557"),
func = function()
card.ability.extra.xmult = card.ability.extra.xmult + card.ability.extra.xmult_gain
end
}
end
if context.joker_main then
return {
xmult = card.ability.extra.xmult,
}
end
end
}
What does your edition code look like
Question
Is there a way to prevent add_to_deck effect of a card from triggering when added into a custom cardarea
Maybe I worded that shitty uh
Prevent cardarea from triggering any cards add_to_deck function?
Also how could I get a card's position on the screen? (<- I don't think I need that anymore but still would appreciate an answer hehe)
No, because add_to_deck is triggered by the creator of the card, also add_to_deck can be triggered before the card is in the card area.
I tried that.
Someone reported a bug with my mod and Im not sure as to why it acts this way
Swoobat (on the left) prevents Hearts with Red Seals to be debuffed. Mega Barbaracle (on the right) debuffs anything that's not a 7.
In theory, having both would debuff everything but 7s and red seal hearts. But here we can clearly see the 5 of hearts is debuffed despite having a red seal. Is there anything I'm missing? I figured you want the "prevent_debuff" things first in the function to prevent this kind of situation, but apparently that's not enough.
-# ...why find_joker and not SMODS.find_card?
I'm slightly baffled that find_joker works at all with no prefixes in the key
maybe it doesn't, actually. that would cause behavior shaped like this
though it would actually be swoobat not preventing any debuffs ever
i guess check real quick whether swoobat works against any boss blinds? head, pillar, plant, window if you've got smeared joker
How do I make a specific music track play for a specific boss blind?
Like if a certain boss blind is active then special music for it plays
select_music_track = function() return G.GAME.blind and G.GAME.blind.config.blind.key == 'bl_modprefix_key' or nil end
hey yall just a quick question
SMODS.Booster {
key = "arcana_normal_1",
weight = 1,
kind = 'vremade_Arcana'
cost = 4,
pos = { x = 0, y = 0 },
config = { extra = 3, choose = 1 },
group_key = "k_arcana_pack"
draw_hand = true,
loc_vars = function(self, info_queue, card)
local cfg = (card and card.ability) or self.config
return {
vars = { cfg.choose, cfg.extra },
key = self.key:sub(1, -3),
}
end,
ease_background_colour = function(self)
ease_background_colour_blind(G.STATES.TAROT_PACK)
end,
particles = function(self)
G.booster_pack_sparkles = Particles(1, 1, 0, 0, {
timer = 0.015,
scale = 0.2,
initialize = true,
lifespan = 1,
speed = 1.1,
padding = -1,
attach = G.ROOM_ATTACH,
colours = { G.C.WHITE, lighten(G.C.PURPLE, 0.4), lighten(G.C.PURPLE, 0.2), lighten(G.C.GOLD, 0.2) },
fill = true
})
G.booster_pack_sparkles.fade_alpha = 1
G.booster_pack_sparkles:fade(1, 0)
end,
create_card = function(self, card, i)
local _card
if G.GAME.used_vouchers.v_omen_globe and pseudorandom('omen_globe') > 0.8 then
_card = {
set = "Spectral",
area = G.pack_cards,
skip_materialize = true,
soulable = true,
key_append =
"vremade_ar2"
}
else
_card = {
set = "Tarot",
area = G.pack_cards,
skip_materialize = true,
soulable = true,
key_append =
"vremade_ar2"
}
end
return _card
end,
}
Im looking up how to make boosters but how do you change the sprite?
atlas = 'atlas'
ik its normally atlas but vremade works without
Yes, because the default atlas is the vanilla booster atlas.
ahhh i see i see
swoobat works
after testing a bit, i've found that sealed hearts get debuffed or not depending on the order you got the jokers in
which makes no sense
another thing how do you change the colour?
also because that's what pokermon uses everywhere lol i just copied
ease_background_colour = function(self)
ease_background_colour_blind(G.STATES.TAROT_PACK)
end,
```i see this but how do you make it your own colours?
ease_background_colour = function(self)
ease_colour(G.C.DYN_UI.MAIN, colour)
ease_background_colour({new_colour = colour, special_colour = other_colour, contrast = contrast})
end
If sync is disabled, any chance there could be a fade between tracks?
D:
I still need help with this-
can you in the place of colour use a hex?
Yes.
how do you use the hex tho?
im trying some things but
ease_background_colour{new_colour = FA9629, special_colour = 148929}
ease_background_colour{new_colour = G.C.FA9629, special_colour = G.C.148929}
but both of these dont work
HEX('FA9629')
ahh i see i see
also what does contrast = contrast mean?
question: how do i add an edition to a created joker
is there a way to make it so this guy actually uses up multiple art slots so that the full joker can be 2 jokers wide
SMODS.Joker{
key = 'bigasscat',
loc_txt = {
name = "Big Ass Cat",
text = {
"dude this guy is",
"{C:attention,s:1.5}HUGE.{}",
"{X:mult, C:white}X#1#{} Mult"
}
},
config = {extra = {Xmult = 300}},
atlas = 'Pokers',
pos = {x = {0,1}, y = 1}, -- the important part right here
display_size = {w = 142, l = 95},
pixel_size = {w = 142, l = 95},
i tried using brackets and just a comma but brackets crashes and comma does nothing
not like that
realistically you're going to have to put this joker in its own atlas
there's nothing you can do with the pos value that will have the effect you want
sounds right
ty!
why does my boss blind crash the game when spawning in
I don't think value 14 is a thing
Are you trying to debuff Aces?
yes...
At least according to vanilla code
it's so inconsistent aipusfioahughsdgsdg
problem still persists...
the answer was that is_suit and get_seal ignore debuffed cards unless you give them true as their bypass_debuff argument 🤡 it works now
huiosdhoghsiodhgioshdigsdgfsdh
Are you even sure that the blind is the problem
yes
Line 1861 of misc_functions.lua seems to be a function that gets challenges from id
huh...
it's when i hover over the blind though
and only that specific blind
Wait a fucking second
Do you have a localization entry for it
Just like, the only thing that comes to mind when thinking about hovering
Huh
Oh wait
What are those
it crashed again afsdhoiahdguihsuodg
huh
Never seen a loc entry like that
thats what i used for the jokers tho
Huh
Maybe change your Joker loc entries just in case too lol
those work fine tho
-# no the 8 is not bugged i textured the 8's like that lmao
It's weird and I'm afraid of it I'm scared man
how do i change a card's pixel_size and display_size from in update?
Somethingcom, Hey, sorry if I had to remind you about this but have you look into the code I sent ya?
-- Shiny
SMODS.Shader({key = "shiny", path = "shiny.fs",})
SMODS.Sound({ key = "edition_shiny", path = "edition_shiny.ogg", pitch = 1.0 })
SMODS.Edition {
key = 'shiny',
shader = 'shiny',
in_shop = true,
weight = 5,
sound = { sound = "comedy_edition_shiny", per = 1.2, vol = 0.7 },
config = { extra = { mult = 20, dollars = 20, mult_odds = 5, dollars_odds = 15 } },
loc_vars = function(self, info_queue, card)
local multNumerator, multDenominator = SMODS.get_probability_vars(card, 1, card.edition.extra.mult_odds, 'comedy_shiny_edition')
local dollarNumerator, dollarDenominator = SMODS.get_probability_vars(card, 1, card.edition.extra.dollars_odds, 'comedy_shiny_edition')
return { vars = { card.edition.extra.mult, multNumerator, multDenominator, card.edition.extra.dollars, dollarNumerator, dollarDenominator, } }
end,
calculate = function(self, card, context)
if (context.post_trigger and context.other_card == card)
or (context.main_scoring and context.cardarea == G.play)
or (context.using_consumeable and context.consumeable == card)
then
local multOdds = SMODS.pseudorandom_probability(card, 'comedy_shiny_edition', 1, card.edition.extra.mult_odds)
local dollarOdds = SMODS.pseudorandom_probability(card, 1, card.edition.extra.dollars_odds)
local ret = {}
if multOdds then
card.lucky_trigger = true
ret.mult = card.edition.extra.mult
end
if dollarOdds then
card.lucky_trigger = true
ret.dollars = card.edition.extra.dollars
end
return ret
end
end
}
sorry for the late response I just got up
Maybe try adding and not context.other_context.pseudorandom_result to your post_trigger
Presumably that's the issue
well the good news is that it no longer crashes the game. the bad news is that now the joker wont gain mult at all if any probability succeeds while having that edition
this issue only happens if they have that edition and that edition specifically. It works normally with any other edition (and of course without an edition)
unrelated, but how do I check how many consumables of a custom type I have bought?
The joker stops triggering entirely?
it stops gaining mult when probabilities succeed
-- in the edition's code:
if (context.post_trigger and context.other_card == card and not context.other_context.pseudorandom_result)
And it works without the edition?
I'm not sure why that code would make the joker itself stop triggering
might have found the issue
turns out in the joker code I had a thing that makes it so that it wouldn't count the edition for probability checking
I removed that part
currently checking if that changes anything
ok cool it works as intended now
its still wrong, you really shouldnt do it like that
Could anyone show me retrigger samples for seals?
I believe I am having issues with it
And want to look into something
Try looking at Red Seal in VanillaRemade
Seeing the code, I guess I now know how it works
does anyone know how to lovely patch into smods code?
trying to make an addon for a mod but i need to add more options to its mod options
idk why this isnt giving me only rare jokers
try rarity=3?
how do I make sure a sticker can only appear on jokers?
stickers dont go on anything else by default
✅
I wish that was the case
-- polymorphic
SMODS.Sticker {
key = "polymorphic_sticker",
atlas = "comedy_stickers",
pos = { x = 2, y = 0 },
badge_colour = HEX("fd5f55"),
needs_enable_flag = true,
rate = 0.15,
sets = {Joker = true},
should_apply = function(self, card, center, area, bypass_roll)
local stakeCheck = G.GAME.modifiers.enable_comedy_polymorphic_sticker
local rngCheck = (pseudorandom("comedy_preowned", 1, 100) <= 15)
local otherStickerCheck = ((card and card.ability) and (card.ability.eternal or card.ability.perishable))
local locationCheck = (area == G.shop_jokers) or (area == G.pack_cards)
local valCheck = (card.ability ~= nil) and card.ability.extra
return locationCheck and not otherStickerCheck and rngCheck and valCheck and stakeCheck
end,
calculate = function(self, card, context)
if context.end_of_round and context.game_over == false and context.main_eval then
return{
func = function ()
Comedy_reroll_joker(card)
end
}
end
end
}
here's the sticker code if that helps
why so many conditions
because if I just check if they can spawn, they will have a 100% spawn rate for some reason
you dont need to check for the enable flag
so... what should I check then?
look at vremade stickers
rarity = "Rare" should work tho
also for seals, can I also use that to destroy a card?
that's what i did when I first made the sticker, and yet it basically makes it guaranteed
like... all the time
huh no idea
return locationCheck and not otherStickerCheck and rngCheck and valCheck and stakeCheck and SMODS.Sticker.should_apply(self, card, center, area, bypass_roll)
Is there a way to make an enhancement with a held in hand effect
Not sure or I can copy the code for testing (I still have to chance so it works with my custom seal)
Nvm
ok i did the worst fix ever and just made a new pool for my rare jokers
Cant find it
context.main_scoring and context.cardarea == G.hand
how do i get what ante i'm on
G.GAME.round_resets.ante
i tried doing ante set 8 and it didn't change that value
I’m thinking of making it so a certain boss blind only spawns if you beat the previous without skipping Blinds and buying anything from shop.
Anyone know the best way to code that in?
Guyd
how do i get how many mods are enabled?
How do i get if the card has a mod seal
if card:get_seal() == 'modprefix_key'
#SMODS.mod_list
What functions do I use to transfer a playing card between the (deck/the hand) and a custom cardarea I made?
draw_card(old_area, new_area, nil, nil, nil, card)
that's giving the amount of total mods, not just the enabled ones
local count = 0
for k, v in pairs(SMODS.Mods) do
if v.can_load then count = count + 1 end
end
ty
it's counting 8 mods when only 5 are enabled
ok i checked and i think i literally just have to subtract 3?
Yes, Balatro, lovely and SMODS are in SMODS.Mods
ah that makes sense lol
Hey so giving this edition to certain jokers (like oops all 6’s) will cause it to create a stack overflow and crash the game without even giving a crash log.
I was able to fix it for 2 legendary jokers that involve probabilities, but certain others seem to cause this really big issue. How do I fix this error?
(I got the and not context.other_context.pseudorandom_result in there on my end)
I made a Joker using Joker Forge. is there any chance anyone can assist me in putting it into my game?
afaik jokerforge already exports a whole usable mod, literally just drag and drop it into your mods folder and you're good to go
oh, bet
-- Shiny
SMODS.Shader({key = "shiny", path = "shiny.fs",})
SMODS.Sound({ key = "edition_shiny", path = "edition_shiny.ogg", pitch = 1.0 })
SMODS.Edition {
key = 'shiny',
shader = 'shiny',
in_shop = true,
weight = 5,
sound = { sound = "comedy_edition_shiny", per = 1.2, vol = 0.7 },
config = { extra = { mult = 20, dollars = 20, mult_odds = 5, dollars_odds = 15 } },
loc_vars = function(self, info_queue, card)
local multNumerator, multDenominator = SMODS.get_probability_vars(card, 1, card.edition.extra.mult_odds, 'comedy_shiny_edition')
local dollarNumerator, dollarDenominator = SMODS.get_probability_vars(card, 1, card.edition.extra.dollars_odds, 'comedy_shiny_edition')
return { vars = { card.edition.extra.mult, multNumerator, multDenominator, card.edition.extra.dollars, dollarNumerator, dollarDenominator, } }
end,
calculate = function(self, card, context)
if (context.post_trigger and context.other_card == card and not context.other_context.pseudorandom_result)
or (context.main_scoring and context.cardarea == G.play)
or (context.using_consumeable and context.consumeable == card)
then
local multOdds = SMODS.pseudorandom_probability(card, 'comedy_shiny_edition', 1, card.edition.extra.mult_odds)
local dollarOdds = SMODS.pseudorandom_probability(card, 'comedy_shiny_edition', 1, card.edition.extra.dollars_odds)
local ret = {}
if multOdds then
card.lucky_trigger = true
ret.mult = card.edition.extra.mult
end
if dollarOdds then
card.lucky_trigger = true
ret.dollars = card.edition.extra.dollars
end
return ret
end
end
}
if this helps, here's what the current edition looks like.
The crash happens whenever the edition is applied to a joker
so, My joker didn't work and crashed when I added a card to my deck. If anyone can assist me, it would mean a lot for me and my friend
try ignoring both fix_probability and mod_probability contexts like you did with pseudorandom_result
the crash is gone, but it immediatley triggered it 10 times for no reason
scratch that it triggered a lot of times, but not as quickly
Either in loc_txt or via a localization file
idk how to explain what is going on, so here's video footage
bump part finale, if i can't figure out soon im probably just cancelling the mod
edit: yep thats it im done fuck this mod
how do i fix it
code?
-- Paddington
SMODS.Sound({key = "hard_stare", path = "hard_stare.ogg",})
SMODS.Joker{
key = "paddington",
atlas = "comedy_jokers",
pos = { x = 6, y = 2 },
unlocked = true,
blueprint_compat = false,
rarity = 3,
cost = 10,
pools = {["comedyGoldEdition"] = true, ["Joker"] = true},
loc_vars = function(self, info_queue, card)
return { vars = { colours = { ComedyColors.PADDINGTON } } }
end,
-- have you forgotten your manners
remove_from_deck = function(self)
G.E_MANAGER:add_event(Event({
trigger = "immediate",
func = function()
G.hardStare = 1
play_sound('comedy_hard_stare')
delay(1)
return true
end
}))
end,
calculate = function(self, card, context)
if context.debuffed_hand or context.joker_main then
if G.GAME.blind.triggered then
G.E_MANAGER:add_event(Event({
func = function()
G.E_MANAGER:add_event(Event({
trigger = "immediate",
func = function()
G.GAME.blind:disable()
G.hardStare = 1
play_sound('comedy_hard_stare')
delay(1)
return true
end
}))
return true
end
}))
end
end
return nil, true
end
}
so the triggering only happens for that joker?
for every other joker the edition functions normally
it's specifically with that joker in particular that has that wierd effect
Using Joker forge. I'm trying to make it to where the joker gains x0.25 mult for every Jack of Spades in the full deck. I'm very lost with all this.
Oh? Where did you find that?
it's in the cube icon
ohhh, alright. lemme take a look rq. one sec
thank you, btw

how do I make it exclusively Jack of Spades?
@spiral lichen
you can't sadly
aw, damn
What exactly are you trying to do?
Make glass cards have a held in hand effect
You mean you want glass cards to trigger in hand or you want to trigger an effect on glass cards held in hand?
I'm trying to make playing cards perishable/rental, and it works how I want it to except for the fact that it seems to trigger twice (e.g., each rental card held in hand causes you to lose $6, and each perishable card goes down by 2 rounds instead of 1.)
i haven't done anything special other than call SMODS.Stickers[sticker_name]:apply. does anyone know how to prevent this from happening?
I have the code for one of my Jokers within the code for the custom Enhanced card that corresponds to it. It gains Chips when my Uranium Cards do their thing -- which I can see with eval G.jokers.cards[1].config.center.config.extra.chips -- but they don't show up on the card itself. What am I doing wrong?
local card_to_kill = pseudorandom_element(G.hand.cards, 'm_lapsems_uranium')
for j = 1, #G.jokers.cards do
local current_joker = G.jokers.cards[j]
if (current_joker.config.center.key == 'j_lapsems_mutant') then
local total_chip_increase = card_to_kill:get_chip_bonus()
total_chip_increase = total_chip_increase + LAPSEMS.COPIED_FROM_ORTALAB_get_chips_from_edition(card_to_kill)
total_chip_increase = total_chip_increase + LAPSEMS.COPIED_FROM_ORTALAB_get_chips_from_enhancement(card_to_kill)
current_joker.config.center.config.extra.chips = current_joker.config.center.config.extra.chips + total_chip_increase
card_eval_status_text(not context.blueprint and current_joker, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
end
end
SMODS.destroy_cards(card_to_kill)
-- for adjusting the values of a card
function Comedy_multiplyCardValues(card, multiplier, applyToCost)
if applyToCost then card.cost = math.floor(card.cost * multiplier) end
-- if the card is a playing card
if card.base then
if type(card.base) == "table" then
for k, v in pairs(card.base) do
if type(v) == "number" and not Comedy_table_contains(ValueManipulationBlacklist, k) then
card.base[k] = v * multiplier
end
end
end
end
-- if the card has abilities
if card.ability then
if type(card.ability) == "table" then
for k, v in pairs(card.ability) do
if type(v) == "number" and not Comedy_table_contains(ValueManipulationBlacklist, k) then
card.ability[k] = v * multiplier
end
end
end
if card.ability.extra then
if type(card.ability.extra) == "table" then
for k, v in pairs(card.ability.extra) do
if type(v) == "number" and not Comedy_table_contains(ValueManipulationBlacklist, k) then
card.ability.extra[k] = v * multiplier
end
end
end
end
end
end
this is how I multiply the values of a joker. for some reason it gives a joker x2 mult as well. how do I fix that?
How can I change the big text that apears in the main menu?
You mean the logo?
yep
SMODS.Atlas{
key = 'balatro',
raw_key = true,
path = 'newlogo.png',
px = 333,
py = 216
}
thx!!
Thanks a lot to all of you, this mod is a birthday gift for a friend and I couldn't have done without your help, thanks!! I'm really grateful
in another joker
How do I apply shader to a back edition?
Bump
how do i make an effect activate right after drawing cards
context.hand_drawn
ah thanks
finally ported the unused decks into the modern balatro... well one or two graphic issues but happy with the result.
now I fixed fixed it in a way.
now up next is vouchers
snap I didn't know someone else already did that
wait somehow the effects on the decks aren't applied somehow but eh.
Finally done it.
and I didn't even have to use cryptid code.
I found a way to achive it simply
(I actually fixed the issue about the graphic errors to realized that I have to determine betwen paused or not)
now time for the vouchers
wait there was one more deck
wait there is also more decks I don't think I ahve made into yet.
dude wtf is this?
-# they are supposed to be standard Cards
Are you storing those cards in a place that is saved?
card.ability.extra.cards
You can't put cards in other cards.
fucking dammit
by the way, Something do you remember when I have shared the code for you to take al ook at it?
Yes, you're iterating over G.holehand.cards and allholehands when drawing the cards so you're drawing each card twice.
so how do I fix it where it adds in the 2 more cards that doesn't draw the card twice like that?
Or is there a way to make it seemless and not messed up like that?
and additionally how can you make the holecard pull stop one the round is over?
Like the glass effect (the 2x mult)
anyone know why this happens?
It seems like an error with the pathing for the localization? I had a similar issue with a joker but I'm not positive. The way it was having an issue was that the prefixes in the localization file were wrong so it lead to nothing and it had no text, it might be something similar
right now I was trying to like have regualr balatro loc vars thing let me show you the code for example:
not sure if there is sometihng similar as I did search in this server but...
You need to add an unlock table in loc_txt
That is the description when locked
I'll try that
Hey so a good friend of mine gave me a really funny joker idea. How would I go about implementing this, specifically the part where it gets the effect of a random boss blind?
Probably get a random Boss Blind from G.P.BLINDS, then :set_blind()?
I tried that but for some reason when I try use "localize" and also the localizaiton code somehow it just basically make it blank again
or otherwise only display "locked"
I have the code for one of my Jokers within the code for the custom Enhanced card that corresponds to it. It gains Chips when my Uranium Cards do their thing -- which I can see with eval G.jokers.cards[1].config.center.config.extra.chips -- but they don't show up on the card itself. What am I doing wrong?
local card_to_kill = pseudorandom_element(G.hand.cards, 'm_lapsems_uranium')
for j = 1, #G.jokers.cards do
local current_joker = G.jokers.cards[j]
if (current_joker.config.center.key == 'j_lapsems_mutant') then
local total_chip_increase = card_to_kill:get_chip_bonus()
total_chip_increase = total_chip_increase + LAPSEMS.COPIED_FROM_ORTALAB_get_chips_from_edition(card_to_kill)
total_chip_increase = total_chip_increase + LAPSEMS.COPIED_FROM_ORTALAB_get_chips_from_enhancement(card_to_kill)
current_joker.config.center.config.extra.chips = current_joker.config.center.config.extra.chips + total_chip_increase
card_eval_status_text(not context.blueprint and current_joker, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')})
end
end
SMODS.destroy_cards(card_to_kill)
.ability.extra
What doesa your code look like now
had to testi t on another section to test.
but yeah this is what the unlock looked like
no, just put text like normal, so
unlock = {
"some text on 1st line",
"some text on 2nd line"
}
and you can use #1# an #2# just like loc_vars but through locked_loc_vars
how does JokerDisplay pull out driver_tally
i have a card similar to this with the exact same code and the best i can do is to convert the tally into an card.ability.extra variable leading to it only getting updated each time i check the card description
alrighty-then
driver_tally updates every frame in vanilla
so like JD actually pulls out the variable that's in the game's code
it's using the value stored in card.ability.driver_tally which the game updates every frame
kinda wished there is like "text_text"
....
does someone know how i get the chips and mult when a joker is triggered. like i want the chips and mult from the score before it get multiplied
did i mess up here because the game crashes
Take a look at Line 1705 in lovely/dump/functions/misc_functions.lua.
Whatever's gone wrong, there it is.
ranks go in misc -> dictionary
I mean under misc only
so just return { misc = { ranks = { tmr_12 = "12" } } }
thx
now i need to work out how to make them like the secret hands where they dont show up unless you have one
Now, could any of you take a look at this problem of mine?
what's the loc_txt for it
how do i make it so that a usually unobtainable-in-shop joker rarity can be obtained in the shop when a deck is used
get_weight function of the rarity returns 0 unless the desired deck is active.
what's the thing to check if a deck is active?
send your loc_vars and localization/loc_txt for the joker
-- Here's the loc_vars.
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.m_lapsems_uranium
return {
vars = {
card.ability.extra.chips,
}
}
end,
-- Here's the localization/loc_txt.
j_lapsems_mutant = {
name = "Mutant Joker",
text = {
"When a {C:attention}Uranium Card{} destroys a",
"card, this Joker gains {C:blue}Chips{} equal",
"to the destroyed card's Chips",
"{C:inactive}(Currently {C:blue}+#1#{C:inactive} Chips)"
}
},
Here you're modifying current_joker.config.center.config.extra.chips but your loc_vars is using card.ability.extra.chips
Am I to
return {
vars = {
card.config.center.config.extra.chips
}
}
instead?
Just modify current_joker.ability.extra.chips, I don't see why you'd want to change the values of the center
i tried to autogenerate ranks
but whenever i have a straight that includes some of them it crashes
The ranks in the next table have to include your prefix
Within Mutant Joker's code or Uranium Cards' code?
In here
how would i fix it
return false if args.initial_deck.
calculate = function(self, card, context)
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } },
mult_mod = card.ability.extra.mult,
chip_mod = card.ability.extra.chips
}
end
if context.after and not context.blueprint then
local current_chips = hand_chips or 0
local current_mult = mult or 0
print("Current chips: " .. tostring(current_chips))
print("Current mult: " .. tostring(current_mult))
if to_big then
current_chips = to_big(current_chips)
current_mult = to_big(current_mult)
end
local mult_gain = math.floor(current_chips / 50)
local chips_gain = math.floor(current_mult / 5) * 50
print("Mult gain: " .. tostring(mult_gain))
print("Chips gain: " .. tostring(chips_gain))
local m_gain_num = tonumber(mult_gain)
local c_gain_num = tonumber(chips_gain)
print("Mult gain num: " .. tostring(m_gain_num))
print("Chips gain num: " .. tostring(c_gain_num))
if m_gain_num > 0 or c_gain_num > 0 then
card.ability.extra.mult = card.ability.extra.mult + m_gain_num
card.ability.extra.chips = card.ability.extra.chips + c_gain_num
return {
message = 'Upgraded!',
colour = G.C.RED
}
end
end
can someone help me understand why i get this error?
tonumber will return nil if the given input doesn't convert to a number.
Maybe you want to_number, seeing as you use to_big?
i forgot a screen shot
sure ill give that a try
Although you very much could just m_gain_num = mult_gain and if m_gain_num > to_big(0).
yeah true
Safest route is just to_big both values when comparing.
yeah i just made them to_number for now
oh true
do you know why that happends? cus if convert them to to string. it seems to be fine. cus otherwise the previous console log wouldnt work
as in this one
also tried this. but this also broke
hand_chips and mult already are tables.
This is why tonumber fails, but to_number does not.
How do I make a tag that changes the Boss blind to a specific Boss Blind?
there is a differnce dammit
that explains alot lol
tonumber is default Lua function, but to_number is added by Talisman.
Is it possible to have a used consumable wait for a specific context before activating its effect and disappearing?
I’d use keep_on_use I assume?
return true for keep_on_use, yeah, then set a variable on itself in the use and, if said variable is set when checking for specific context, do stuff.

