#💻・modding-dev
1 messages · Page 572 of 1
is there an example of how to add a new perma bonus on a card?
that is
not one of the existing ones
Excluding bonus chips here I assume?
check how that does it
perma_d_dollars time
What's the difference between table.insert(table, value) and table[#table+1] = value?
barely anything
in terms of performance, table[#table + 1] = value is slightly faster because you don't have to interact with the table module, but it's pretty much negligible
table.insert mainly exists because you can provide an optional position parameter to insert to an arbitrary location in the table, e.g. table.insert(table, 1, value) appends value to the front of table
insert is technically cleaner but if you don't trust passing by reference (me) then the latter is pretty much the same
I realized it doesn't actually matter for what I'm doing, but that's good to know in the future, thank you!
Actually nevermind it does matter lol
Does mod calculate() function go before or after Joker calculate()?
after
Ok, good to know, thanks!
??????????
How is that a nil value, I literally defined it as 0 on line 549
Hello friends (if anyone's here at this hour). I'm having trouble with a joker acting up. It doesn't work as intended, but it also hasn't crashed at all.
What is ut
*it
Necrozma here is supposed to check if Solgaleo or Lunala are directly to its left or right at the end of the shop, destroy itself and the other Joker, and create Dusk Mane Necrozma or Dawn Wings Necrozma respectively. However, it does nothing.
although the code I used doesn't actually destroy the other joker yet, I was going to ask about that anyways
How could I make a certain joker spawn in a pack less often, similar to black hole or the soul? I'm currently just spawning the cards for the pack based off rarity.
Holy moly are you the same guy from the unseen explosions server
This is crazy
lmao, yep.
Gng this is wild
There are dozens of us, dozens!
how do i figure out which mod is taking so much goddam memory
i keep getting oom crashes
its DEFINITELY something in the actual save game
since loading a saved game instantly drops ths fps
What's the order of cards in G.playing_cards? Are the new ones added always at the end?
Can one mod add in more than one deck to the customize menu?
calculate = function(self, blind, context)
if context.post_trigger then
if SMODS.pseudorandom_probability(self, 'ghostly', 1, 3) then
if context.other_card.config.center ~= G.P_CENTERS.j_tdec_photoquestion then
context.other_ret.jokers = {}
return {
message = "Fading",
colour = G.C.WHITE
}
end
end
end
end
This crashes the game when oops is present so I suppose I should add it to context.other_card as well
nevermind it crashed again 
it crashed with no exit log
Yes, you need to check and not context.other_context.mod_probability and not context.other_context.fix_probability
gotcha
Also you should be doing EMPTY(context.other_ret)
The reason why context.other_ret = {} doesn't work is because context.other_ret is just a reference to the actual ret.
calculate = function(self, blind, context)
if context.post_trigger then
if SMODS.pseudorandom_probability(self, 'ghostly', 1, 3) then
if context.other_context.mod_probability and not context.other_context.fix_probability then
if context.other_card.config.center ~= G.P_CENTERS.j_tdec_photoquestion then
EMPTY(context.other_ret)
return {
message = "Fading",
colour = G.C.WHITE
}
end
end
end
end
end
Something like this I assume?
No, it would be not context.other_context.mod_probability
i hate to interrupt but
i am at my wit's end...
i'm trying to inject code with lovely,
i have the exact code i want to replace, copy-pasted, properly formatted, word-for-word, into the pattern field.
it SHOULD work, but it just DOESN'T.
it refuses to recognize the code that's RIGHT THERE. :(
i'm so close to having this work, if anyone can assist me, please please let me know.
i can send the mod files if it would help.
wtf lucky
Have you tried looking at card.lua in the lovely dump?
do you need to be replacing the whole entire block
this'd also be a good idea
oooh true. i should do that.
how do i do that,
seems to have crashed again
if another mod patches it at all [notably smods, probably] then your patch wont go through
since itll change the very specific requirements that your patch already has since it needs all those lines to be the same lmao
go to your mods folder, should find a folder called lovely
inside of it, go to the dumps folder
that's basically just the game's code after lovely patches have been applied
ahhh thank you thank you
out of curiosity what are you doing
i'm making it so when you use wheel of fortune it plays the funny flipnote gamblecore meme
You have to check that before you do the probability check.
oh,,
ah..
i think it would be a lot easier to use an smods mod and a global calculate function to do that
easier maybe
but i have no idea how to do any of that i am like a level 1 programmer
yeah it worked, thank you
but if you do stick with a lovely patch i would try and shorten the required pattern because unless you need to replace all of those lines it just makes it more susceptible to being broken by other mods
level 0 even
SMODS.current_mod.calculate = function(self, context)
if context.using_consumeable and context.consumeable.config.center.key == 'c_wheel_of_fortune' then
return {func = function()
G.E_MANAGER:add_event(Event({
func = function()
play_sound('modprefix_key')
end
}))
end}
end
end
the smods wiki and vanillaremade wiki are good resources if you do want to learn [beyond just the one mod]
damn. that. is way simpler than i thought
smods is great
hey team, anyone know how to get the pool of a card from just it's key? I'm trying to make a showman effect but only for planets. Right now I'm hacking it in a really goofy way that feels bad
local smods_showman_ref = SMODS.showman
function SMODS.showman(card_key)
if next(SMODS.find_card('j_aij_void')) and not next(SMODS.find_card('j_vremade_ring_master')) and card_key:find("^" .. "p_") then
return true
end
return smods_showman_ref(card_key)
end
the joker in question is the void one
check for G.P_CENTERS[card_key].set == "Planet"
also all consumables are prefaced with c_ so this would unfortunately not work because of searching for "p"
sweet, thank you! also is there any way to distiguish if the player is opening a pack? if I can I'd like it to only happen in the shop
idk i tested it and it seemed to work, tho obviously not the way to go lol
strange but if it works lmao
there probably is but
i am not immediately aware of it
why is my red sub-uibox is on the bottom right. am i missing something?
local old_update_shop = Game.update_shop
function Game:update_shop(dt)
old_update_shop(self, dt)
if not G.GAME.Insert_Photo
and G.GAME.round_resets
and G.GAME.round_resets.ante == 8
and G.GAME.round_resets.blind_states
and G.GAME.round_resets.blind_states.Small == 'Upcoming'
and G.shop_jokers then
G.GAME.Insert_Photo = true
local card = SMODS.create_card {
set = "Joker",
area = G.shop_jokers,
key = "j_tdec_photoquestion"
}
create_shop_card_ui(card, 'Joker', G.shop_jokers)
card.states.visible = false
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
card:start_materialize()
card.ability.couponed = true
card:set_cost()
return true
end
}))
G.shop_jokers:emplace(card)
end
end
How would I make this joker appear alongside the other jokers instead of replacing one of them? I've tried tinkering with how tags do it but I realized they replace one of the joker slots
Why are you doing this in Game:update_shop?
fixed this, i needed to use uit.root
i tried doing
SMODS.current_mod.calculate = function(self, context)
if G.GAME.round_resets.ante == 8 and G.GAME.round_resets.blind_states.Small == 'Upcoming' then
if context.starting_shop then
local card = SMODS.add_card {
set = "Joker",
area = G.shop_jokers,
key_append = "v",
key = "j_tdec_photoquestion"
}
create_shop_card_ui(card, 'Joker', G.shop_jokers)
end
end
end
it works
turns out i was overcomplicating things
although i'd like to ask if there's a way to make it so the cards don't appear so bunched up
G.shop_jokers.T.w = math.min((G.GAME.shop.joker_max+1)*1.02*G.CARD_W,4.08*G.CARD_W); G.shop:recalculate()?
yup that's it, thank you
How do I make one of those tutorial cutscenes
Hi! I have this problem where the label for edition is shown up as "ERROR" in game. Other labels work just fine. So does name and desc for edition. It's just the label for edition that doesn't work. Does anyone see the problem?
Edition labels don't have the e_ prefix.
Yes.
Is there a channel for crash logs?
How do I make custom background image for a blind? Do I have to make a shader for it or can I just somehow draw an image over the original one?
I saw people do that but I can't find any documentation on background images what so ever
1s
Nitro ran out
The shader is unnecessary
ah
How are you doing btw marie
— add a check for a specific blind and you’re golden
omg thanks
bad
i wanna do so much in terms of balatro modding and I just can't do all of it
I'm juggling 3 major projects and 1 minor project at once and I don't want to drop any of them
and three of them require me to do art and I can't do art
i feel like tsunami should've been done by now if I got my shit together but it just sucks cause there's no art on 90% of the things and people don't like that
jokebox is really underwhelming in terms of fulfillment but I still feel like I should commit to it
splatro is going fine in terms of production but in terms of gameplay it's not going fine
and there's that secret project I have that hasn't gotten done because it keeps getting feature crept and overshadowed by everything else I'm doing
I want to make things for people that people will see that's what makes this worth doing but that just doesn't happen
I don't feel like I should give up considering sunk cost fallacy or whatever I learned a whole coding language for this I don't want to just drop it right now
that's not easy to do especially not in good morals
I would feel like shit asking for art from people if they didn't come to me first because it just feels unfair to them as if they're doing it of obligation
Maybe there’s some people out there who can do art but can’t code and looking to make a cool mod
Or be a part of one
discord just put me in fucking limited access i'm gonna lose my shit what is this
what did I do????
i'll figure it out
later
Are you associated with war crimes in the past 50 years bychance 😭
that's the thing though, they'd want to do art of their own things that they care about, it's not easy to find an artist who would willingly draw some form of water on at least 65 cards because they care about it
Fair
I would’ve wanted to help but I’m terrible at art myself
art is really difficult
i've been trying to learn it and I don't know how they do it
I can shade cylinders and spheres so I can shade a mean peanits if I felt like it but that's about it really
I make digital art for fun i would say i’m decent but it doesn’t translate well , anyways this is not the channel for this discussion
that's true
coding would be easy if not for the art I could probably finish tsunami in like a week if it was just coding now that I know my way around shit
still despise SMODS.change_base() though
if there are no change_base haters I am dead
that may be kinda stupid question... but where exactly should I check for a specific blind? I mean in what moment of code?
context.setting_blind
yeah but like to get all that background changer code inside if? or just some part of it?
G.GAME.blind.config.blind.key == "bl_[mod prefix if it's a modded blind]_key"
sorry if it looks scuffed I'm on my phone
yeah yeah I may have just phrased that wrong. I know how to check for a blind. I don't know WHERE to check for it here
local update_ref = Game.update
function Game:update(dt)
update_ref(self, dt)
if G.GAME.round_resets.ante == 0 and G.jokers and G.jokers.cards then
for _, j in ipairs(G.jokers.cards) do
if j.config and j.config.center and j.config.center.key == "j_tdec_photoquestion" then
if G.GAME.blind.config.blind.key == "bl_tdec_famine" or G.GAME.blind.config.blind.key == "bl_tdec_pestilence" or G.GAME.blind.config.blind.key == "bl_tdec_war" or G.GAME.blind.config.blind.key == "bl_tdec_death" or G.GAME.blind.config.blind.key == "bl_tdec_beast" then
local blind_def = G.GAME.blind.config.blind
if blind_def.boss_colour then
ease_background_colour { new_colour = blind_def.boss_colour, contrast = 1 }
end
end
end
end
end
end
Idk how relevant this is, but it's what I use to change my blind's backgrounds, although it's conditional it is basically the same premise
Code?
how does your localization look like?
you need an entry in uhh misc/labels(?) for the rarity name
uhh where do i need to hook the game to add new globals "properly" a la G.GAME.[myglobal]?
I feel like there should be an easier way to retrieve the second from last card in the scored hand
so if its a global that i just want to exist at the start of the run, i do something like
SMODS.current_mod.reset_game_globals(run_start)
if (run_start) then
G.GAME.[myglobal] = [value]
end
end
```?
yeah
noted thank you
I need help.
Those 3 nodes are suppose to show in purple, light blue and navy (like Tarot, Planet and Spectral), yet they are all text-black for some reason I couldn't diagnose.
is it possible to let something calculate on a card (a.e a seal) even if a card itself is debuffed easily
i already have a workaround im wondering if im missing smth again :clueless:
is scoring_hand not sorted? i made it so it sorts it by position now but maybe i didn't change that in retrigger_function
Here's what I did, which does work
Hope this helps (Only the relevant snippets)
bump
It's G.C.SECONDARY_SET
Yes, hook Card:can_calculate
whats the global variable to check the current chips scored?
G.GAME.chips
ty
Did you find a solution for the sprite being invisible unless the run is exited and re-entered?
Have you tried doing card:set_sprites(card.config.center)?
Right after spawning it?
Yes.
Literally card:set_sprites(card.config.center) or replacing card with c_cstorm_aries?
local card = SMODS.add_card(...)
card:set_sprites(card.config.center)
OMG that works, thank you so much!
Okay, something that shouldn't take long: Can I change 'Joker' to 'Consumable' without patching?
No.
It seems to only work for vouchers and jokers.
So I would need to patch that? If so, you don't happen to know where that is located in the game files, do you?
I'd imagine it's in ui definitions, don't quote me on that though
I'd check if i could
I do, create_UIBox_card_unlock
Okay, thank you
Making a joker that is basically the horse from Yahimod but its not working, it keeps crashing whenever it spawns
local upd = Game.update
function Game:update(dt)
upd(self, dt)
if G.jokers then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].ability.name == 'j_fnaf_balloon_boy' then
local _bb = G.jokers.cards[i]
local _bbc = G.P_CENTERS.j_fnaf_balloon_boy
if _bb.ability.extra.round < _bb.ability.extra.maxround and _bb.ability.eternal ~= true then
_bb.ability.eternal = true
end
end
end
end
end
SMODS.Joker {
key = 'bb',
atlas = 'Joker',
pos = { x = 0, y = 0 },
rarity = 1,
cost = 3,
unlocked = true,
discovered = false,
blueprint_compat = false,
eternal_compat = false,
perishable_compat = false,
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = { key = "fnaf_sprite_WIP", set = "Other" }
end,
add_to_deck = function(self, card, from_debuff)
SMODS.add_card('j_fnaf_balloon_boy')
card:start_dissolve({G.C.RED})
card = nil
end,
}
SMODS.Joker {
key = 'balloon_boy',
atlas = 'Joker',
pos = { x = 0, y = 0 },
rarity = 1,
cost = 3,
unlocked = true,
discovered = false,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = false,
no_collection = true,
config = { extra = { x_chips = 0.5, round = 0, maxround = 3}},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = { key = "fnaf_sprite_WIP", set = "Other" }
return { vars = { card.ability.extra.x_chips, center.ability.extra.round, center.ability.extra.maxround}}
end,
calculate = function(self, card, context)
if context.joker_main then
local bb_voice = math.random(1, 3)
return {
x_chips = card.ability.extra.x_chips,
func = function()
if (pseudorandom('fnaf_bb_voice') < 1 / 3) then
card:juice_up(0.1, 0.2)
if bb_voice == 1 then
play_sound('fnaf_bb_voice1')
elseif bb_voice == 2 then
play_sound('fnaf_bb_voice2')
elseif bb_voice == 3 then
play_sound('fnaf_bb_voice3')
end
end
end
}
end
if context.setting_blind and not context.blueprint then
card.ability.extra.round = card.ability.extra.round + 1
if card.ability.extra.round >= card.ability.extra.maxround then
card.ability.eternal = nil
end
end
end,
}
SMODS.add_card takes a table, not a string.
either way
the card is spawning
but still crashes
ok wait
different crash report
this might help
You're trying to index center which doesn't exist, because it's card
ok it worked
How do I give undiscovered consumables a description?
bump
or check vanillaremade (if you use a localization file, it goes in descriptions -> Other -> undiscovered_modprefix_consumabletypekey)
How to make a copying of a random joker
pseudorandom_element(table, 'seed') returns a random element of the table you pass to it
so do this
local copied = pseudorandom_element(G.jokers.cards, 'seed')
local ret = SMODS.blueprint_effect(card, copied, context)
...
(probably replace the seed with something relevant to this joker, like its key or whatever)
why is my G.UIT.T appearing only when i click into the text input?
scr = SMODS.current_mod
-- there are conditions here, ommitted for brevity
G.FUNCS.overlay_menu{
definition = create_UIBox_generic_options{
back_func = "scr_go_back",
contents = {
{n = G.UIT.C, config = {align = "cm", padding = 0.1}, nodes = {
{n = G.UIT.T, config = {text = "Enter Up Keybind", scale = 0.5}},
create_text_input{
prompt_text = "...",
max_length = 12,
all_caps = true,
ref_table = scr.config,
ref_value = "up_keybind",
align = "cm",
callback = function()
scr.config["up_keybind"] = scr.config["up_keybind"]:lower()
SMODS.save_mod_config(scr)
end,
w = 3,
h = 1,
text_scale = 0.5
},
}
}
}
}
}
end
Thanks
where can I get a list of the ingame booster packs. I had found it at some point but I forgot (I need it to make a table including only the mega variants)
like for example for a list of editions I just grab them from G.P_CENTERS and then it starts with e
nvm
it started with p not b
🗿
yea
(b is for decks, because they're "Backs". i.e. the back of the card)
G.P_CENTER_POOLS.Booster should work too
G.P_CENTER_POOLS has a seperate table for every single type of center, you dont need to look at the prefix
sounds nice I'll look into it more often thx
hiya, I've found that when enhacing a card to stone, specifically before the round, it visually loses it's rank and suit and becomes just a white card for a second before becoming stone. Anyone know if theres a workaround?
put it in an event if it isnt already
got it, I'll try doing that
uhh, did I do it right? Now it just turns white
G.E_MANAGER:add_event(Event({
func = function()
v:set_ability(G.P_CENTERS.m_stone,nil,true)
v:juice_up()
return true
end
}))
sorry for wack code pasting, idk how to send it nice like people do sometimes
v is the card, i'm in a loop
like this
but that should be correct yeah
v:set_ability(G.P_CENTERS.m_stone)
sweet ty!
just so I don't do this again, what are those last two arguments for?
Anyone know what this is called in the game's code?
initial which is only true when the card is created, and delay_sprites
thanks again :)
Is there a way to block a player from skipping a blind? Would it require a patch?
any good mod to look at for creating popup menus?
I know the plantain mod does it if you wanted to look at that
Interesting, I'll have a look
but yeah I think it requires a patch
*loud cough*
you might need to elaborate
i mean like with G.FUNCS.overlay_menu()
oh UI is great fun
if you just want to know how to overlay some ui then you can look at vanilla
UI is great fun if you have done html before otherwise its "waaa nested tables"
blue frog what I need to do to improve
yeah ive done html its still scary lmao
fair
but ive heard complaints about nested tables with i personally disagree with, thats like the least bad part of ui
at least nested tables are avoidable by splitting stuff up between functions
thats great to troubleshoot
well deeply nested tables that is
i mean its very much like html in the sense that its more likely to just not work instead of crash
(except html doesnt crash at all from what i know but yk what i mean
quick question if anyone knows it off the top of their head, if I have a context for after buying something, will that happen before a consumable is used if someone hits buy and use
I can go and test it if no one knows but I thought I'd check
im pretty sure it happens before the consumable is used
also just say context.buying_card lol
what the actual fuck
also true
Ty for the tip, just what I needed
sweet, glad it worked :)
Where would I go to find what all the paramaters of smt like create_card are for
if it's a new smods function like create_card, there's a good chance it's documented on the "Utility" page on the smods wiki. if it's not there, or if it's a vanilla function, then there should be a bit of documentation for the function in the SMODS lsp_def folder (vanilla functions would be in vanilla), but it's not super readable because it's in a format designed for the language server protocol
you can, of course, also just dig around until you find the original source code for the function
awesome thank you, that utility page was one of the ones I hadn't explored yet and it seems super useful
does anyone know why this isn't working? (for custom enhancement)
what's "not working" exactly
it's supposed to retrigger neighbouring cards but nothing's getting retriggered
the print is printing the context.other_card's stuff just fine
hm
what happens if you take out the message and card from the return?
because if it's getting into the innermost if statement then the issue has to be something with the return i think
isn't the card the thing that'll get retriggered?
no, it automatically applies the retriggers to context.other_card
Does it display the message?
playing cards can only retrigger themselves though
no
that may be it then
how would i have playing cards retrigger other cards then
Sorry to butt in, anyone know how to get a key in this scenario? It's probably just me misunderstanding what context.consumeable is but I'm not sure how else to get the key
if context.using_consumeable then
local used_planet = context.consumeable.config.center.key
hm
uh, this
if context.using_consumeable then
if area == G.pack_cards or true then
local used_planet = context.consumeable.config.center.key
G.E_MANAGER:add_event(Event({
func = function()
local card = create_card('Planet',G.consumeables, nil, nil, nil, nil, used_planet)
card:set_edition("e_negative", true)
card:add_to_deck()
G.consumeables:emplace(copied_card)
return true
end
}))
end
end
My joker that creates jokers doesn't create them with stickers in challenges that make all jokers have stickers, like Riff-Raff does
have you tried looking at riff-raff's code?
I did the area thing wrong I think which is why I'm skipping it for now. Also I don't check to make sure its a planet but I'll get to that
the local card thats a nil value here is the argument to emplace, you put the wrong variable name there
copied_card doesnt exist
it uses its own trigger context
i think it's because the stickers are applied when it's the Joker set but i might be wrong
(scary)
oh im just stupid thx, thats leftover from perkeo code
please use SMODS.add_card
try looking through the files for SMODS.calculate_context and see if you can find said context anywhere
?
uh, I prolly can, why's that. It does work now
i'm saying it uses context.crimson_trigger
search the entropy github for "SMODS.calculate_context" to find where it calls that function with crimson_trigger = true
for SMODS.calculate_context
it does that in the seal
yeah that's it
obv i can't do that but yeah that's it
shorter, better syntax so less prone to errors, you get any benefits from smods fixing stuff
in this case SMODS.add_card{key = used_planet, edition = 'e_negative'} will work
oh cool, good to know
sorry just copying stuff from other stuff so I never know which is the better way to do things
honestly tempted to just make a different effect, now that i know entropy has the same thing as a seal
oh i see now, i mean you could just copy the crimson seal code then
copy from vanillaremade :3
yeah but perkeo doesn't create a card
i thought vanillaremade always used add_card when possible
it copies it
that doesn't have an smods utility (yet)
yeah I just wanted smt negative so I assumed I should look at perkeo but that makes sense
i guess i'll just check if you're playing a challenge with that rule enabled? it's really bad practice but
Or i could patch the game and have it apply for the 'Food' set too
this might not be the question for this channel but do you guys know about any mods with interesting blind effects? I'm working on a 5-phase boss blind and I'm struggling to make fair and fun effects for each one of them. This is more about creativity rather than code
I need some more inspiration
uuuu entropy maybe?
paperback has a set of blinds all themed around musical notation
there are actually more music blinds planned for future updates too (taupe treble is only implemented in the latest beta)
all of them seem pretty interesting actually
What app/website is that?
it looks like google spreadsheets
stop impressing me every time
good idea actually
Can someone help me test my mod? Or just play it?
I know it's possible to disable Jokers, but can I do it with everything in the game ? And how do I do it ?
if you want to ban something you can do G.GAME.banned_keys[key] = true
thats the same way challenges do their bans
thanks
it's the spreadsheet for all implemented + planned content in paperback
it's public access, here's the full sheet https://docs.google.com/spreadsheets/d/1PASVdFEUthutKjdsQ8aZ0w863nwBcSf285EYwWuR1lQ/edit?gid=1146496286#gid=1146496286
When you make a custom deck, how do you set the cards it contains? I saw in the abandoned deck there was a tag for no face cards, and erratic had a tag for it, but can you manually define the whole deck?
i am unfortunately not the concept creator for pretty much anything in paperback, i'm just here to code what's in the spreadsheet :P
ok so i'm trying to use this code, but it doesn't seem to do anything at all.
SMODS.gamblecore2.calculate = function(self, context)
if context.using_consumeable and context.consumeable.config.center.key == 'c_wheel_of_fortune' then
return {func = function()
G.E_MANAGER:add_event(Event({
func = function()
play_sound('gamblecore2_gamble1')
delay(1.2*G.SETTINGS.GAMESPEED)
end
}))
end}
end
end
yes, it should be SMODS.current_mod.calculate
ohhh i see
chat is G.playing_cards guaranteed to be your full deck even in the middle of a round?
isnt G.playing_cards just the amount of cards in your deck
i thought G.deck.cards is that
it's a table
i can see in vanillaremade that cloud 9 loops over it
and now that i think about it, it does that in loc_vars, so it should indeed be the full deck no matter what
ive definitely gotten a number value error before when trying to loop over G.playing_cards before i thought
Does anyone know if there's a way to manually declare a deck when you make a custom SMODS.Back? From the Abandoned deck and Erratic references, they both have tags and aren't defined card by card
yeah
idk 🤷♀️
that's playing_card singular
Playing cards is your entire deck, yes
thanks all
i don't think so, you have to do it in apply afaik
but maybe the challenge configs work
Alright, thank you for the info!
do you know how to use it ?
Is it possible to prevent flipping card when it discarded?
exactly what i did there
G.GAME.banned_keys.<key> = true
that bans the object with that key
is context.after for when a hand is done scoring?
yes
oki
how would i go about replacing a vanilla consumable entirely with an smods consumable? i'm not sure how i would do it with take_ownership
depends on what you mean by replacing
uhh how do i do attention text, similarly to plasma's balanced one
is major the thing its "attached" to?
yeah
ty
and hold is how long it stays on screen i assume?
i think so
I'm so sorry but I don't even know how to make that.. Can you help me ? Just for one
i'm making a custom wheel of fortune card that i want to replace the vanilla wheel of fortune with, i have the code modified from vanillaremade, would i be able to just shove it into a take_ownership function like this?
okay what are you trying to do currently
i forgot, per item
yeah something like that should work
then its the same but in a dependencies table in your object definition
it's not much but i'm proud i figured it out :)
Hi people
I wanna do a joker that does something when a pack is skipped while no items from it have been taken (matters for a Mega Arcana pack where you can pick 1 and then skip for example). How can I check how many cards you can select while in a pack? There's probably a variable out there that tracks that but idk which it is
I want to disable everything in the base game (jokers, vouchers, consumables, ...)
im pretty sure you can check if an object is from a mod/which mod its from but i forget where thats stored
upgrade is kinda vague
Based on Pokermon (which removes all og jokers from the game, leaving only the pokermon ones), and assuming v.config.center.mod is correct, putting this in your lovely.toml file should work
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = "if v.yes_pool_flag and not G.GAME.pool_flags[v.yes_pool_flag] then add = nil end"
position = "after"
payload = '''
if not v.config.center.mod then add = nil end
'''
match_indent = true```
you could add what it upgrades into in the info queue
Tooltip?
ohh
Oh hey Nova!
hello
Rarity upgrades every 3 rounds
yeah probably smth like that
yes but that's a very very long line
also im called eris smh
hey H.
FUCK
Ok H. Nova👌
hi
xd

like yorick does for example
Why are you H
it says like every 23[x] discards
slimed in the hood
Eris H Nova
H'
How that would change anything exactly
Im confused
removes a line
You can do 3[x]
for counters I always do "Does this every 3 rounds. (0/3)"
like yorick
I'd just say "Upgrades in X rounds" and change X when needed (so every round)
Guys I might sound insane but I want the text look alinged by word count preferrable, so lines wont look like this:
ssssssssssssssss
sssssssss
ssssssssssss
ssss
that looks bad
ssssssssssss
sssssssssssss
sssssssssss
ssssssss
i mean thats how most things do it
sure
Upgrades every 3 [x] rounds wouldn't change the alignement
how the lines are organized is like the one consistent thing
usually most lines are of similar length
imo i think the text looking like a square looks bad
a bit of imbalance makes it easier to read
No no, the argument is whether it should specify "upgrades RARITY" or just upgrades
yeah true
Rick : yo
Yes!
what else would it upgrade other than the rarity
i don't think specifying rarity is needed
That's why Im asking folks here
theres mods that have upgrading editions
Im not sure
it upgrades to random edition + seal
then wait 3 rounds and find out
experiment
you don't have to babysit players on every single little effect 😭
Here's some of mine, ignoring reskins
while I usually agree with that sentiment i dont think adding rarity to be more clear there would ruin anything
that's my personal philosophy
but it might be wrong
for new player experience
do you think new players will play your mod
There a lot of ppl that download random mods without a back thought
:^)
their issue not mine 
does anyone know how i could hide the ui element that normally has the player's currently hand here
have you seen experienced balatro players
playing mods
they dont read either
FTFY
is this a new state you added? i have code for that
i am having weird issues with creating a joker from a custom pool (CardJoker) added by my mod, which returns the error of bad argument #1 to ipairs, but if i replaced it with a different pool, it would work without any issues
this is the code, and it is located inside of SMODS.Back, if that helps
yes
K, I'll go with just upgrade for now
@slim ferry Should we use Yorick's variant of counting?
or keep as is?
idk, i think its just fine already imo
woah another letter enters the ring, we have N and H
kk
no '
does anyone know which variable i need to check to access this value while in a pack (i know how to get the selection amount of a pack outside the pack, but idk how to do it during the pack)
# CardArea:draw()
[[patches]]
[patches.pattern]
target = "cardarea.lua"
pattern = "(self.config.type == 'deck' and self ~= G.deck) or"
position = "before"
payload = '''
(self.config.type == 'hand' and state == G.STATES.JOY_SIDE_DECK) or''' # change this for whatever state
match_indent = true
hiii
hi N
G.GAME.pack_choices i think
lemme test that rq
and I don't know how to do that
i would look at how pokermon does it
i would share how i do it in my mod but its very convoluted
i literally sent you the solution
scroll up
i didnt test it but it should work
thanks but, what is the lovely.toml file ?
works perfectly, ty
you need to make one
in your mod files
Hey Dilly
Doing okay. Been distracted by rl stuff so only made incremental progress on modstuff recently
That's it! thx
like this ?
it be that way, im not sure what more ill be doing anytime soon
it needs a manifest at the top
also curious if it's possible to apply shaders to ui elements
don't forget the manifest header for the whole file (which is explained in the link N sent)
My current in progress art is this, though I've made more progress since I posted this shitty draft
something like that ?
yeah
i still like it
TwT
so that doesnt work
How can I lower my hand with the cards, as it happens when you play hand?
how would I make cards get drawn back into the deck when you discard/play them so you can use them again in the same blind?
I no clue how to pull that off
so i'm multiplying the delay by the game speed,
thinking it would make it the same 1.2 seconds on each game speed,
but it's still ever so slightly faster on faster speeds than 1.
i'm not sure what to do about this?
everything is working perfectly except the timing is off :(
replace v.config.center.mod by v.mod
i think it works (i only have Joker, the blank voucher, Handy Tag, Strength, Pluto)
nice
just i says me that when I'm trying to open a card booster :D
(btw thanks)
so it uses the global default but that isnt a seal
its what i said above
seals dont have a default so if there are no available options it tries the global default instead
is there something like G.FUNCS.draw_from_discard_to_deck() but for played hands?
I guess I just need to make a custom seal
oh that's kinda dumb lol
played card go to discard after playing
as i know
oh
i mean it makes sense, all seals are always in the pool in vanilla
yeah
How can i lower cards in hand, as it happens when you play hand?
i think you're not setting the correct state
and, with this, can i still add things to my mod and they will be available ?
im trying to copy play_cards_from_highlighted function, but i didnt understand all of it, include states :/
it include G.STATE = G.STATES.HAND_PLAYED and G.STATE_COMPLETE but i don't understand how they work
this only disables anything from the base game
any modded stuff will stay
it sets the state to that so that other functions can check for it, it's kinda complicated to explain because you need to read the code to understand what balatro's state machine does for each state
ty, im just move G.STATE = G.STATES.HAND_PLAYED and G.STATE_COMPLETE into another function and it works!
do you guys know where in the code pack hand size is handled? I know I need to make a hook I just can't find it
what are you trying to do
there isnt any pack hand size it just uses your normal hand size and draws cards the same way as anywhere else
I want a joker that increases hand size only in booster packs
there's probably some jank way to do that with like increasing hand size only when round ends and then goes back to normal when exiting shop but that probably has issues
that's how i would do it honestly
you can also do it in the open booster and end booster contexts
theres an ending booster context?
or because you cant discard (usually) you can also draw more cards when the booster is opened
yeah
what are those contexts? also like I still don't know where all the contexts are in source code it would be nice to just be able to look at all of them
context.end_booster or how it spells?
you can search globally for calculate_context to find most of them
let me check what it was called
open_booster and ending_booster
idk if ending_booster is called when the booster is skipped so maybe check that one too
alright cool thanks
Hello friends! I'm having a bit of trouble with a joker i'm working on
Necrozma here is supposed to check if Solgaleo or Lunala are directly to its left or right at the end of the shop, destroy itself and the other Joker, and create Dusk Mane Necrozma or Dawn Wings Necrozma respectively. However, it does nothing.
Although I don't know what the code would be to destroy the other joker involved
you're probably right lol
yeah probably just. put the whole block inside the context check instead of checking for it 4 times
also you could probably turn the checks for the same key into a single check so its not as long
context.open_booster you increase it, context.skipping_booster and ending_booster you reduce it
i wanted to optimize it like that anyways but i couldn't figure out how
you have an accessible list of all contexts in this file, it's pretty useful
paste the two checks into a single if statement and use the hit or statement so you have like (check 1) or (check 2)
is it possible we could get in a call to explain this to me
just do a little (if right and right.config.center.key == "legendar_lunala") or (right and right.config.center.key == "legendar_lunala") then ... end
also i dont have a mic so call wouldnt change much lol
i see
i seem to be doing something wrong but it looks ok to me
what's weird is that it worked when it wasn't in that func = function() but it has to be in the G.E_MANAGER:add_event(Event({ so that the delay works
is there a card with no edition
because editionless_jokers seems to be empty
crash
oh i
wait
i don't think so?
i mean it worked for vanillaremade anyway
i know i wrote vremade lol
oh oops
but that checks if there are any in can_use
still crashing
whats it look like now
yeah i dunno, i had something that was working before anyway i was just trying to simplify things a little
i'll just go back to what i WAS doing
oh
how do i set generate_ui to the default one for jokers
just set it to nil?
in what context?
still doesn't do anything
try getting rid of the context.ending_shop in the individual checks and put everything in if context.ending_shop then ... end
arent you missing parenthesis around the smods.add_card argument
...put an "if" statement inside an "if" statement?
also ever heard about pokermon lol
it's my own mod
no, put the code in that check
No, Lua just allows that. That's why you see SMODS.Joker { all the time, for example.
lua allows passing a single table without ()
oh ok
wait
if i'm only putting the code inside the context.ending_shop check
it wouldn't check for the specific jokers next to it
well yeah you
unless i am sorely mistaken
still need that inside the context check
guys what's wrong here 🥺
else on the wrong if statement
are you sure gif
xchips are not vanilla
ohhh thats probably it
😭
Imagine existing here
Else on the wrong IF statement does not cause errors. Instead, in this case, your else code will run in EVERY CONTEXT except for Joker Main in the G.jokers card area.
i got this code from testing a jokerforge pr, almost made it to prod
lmao
i'm still very confused about this lol
if you still need xchips you can try to manually set the chips value i think
if context.ending_shop then
--all the code you have currently
end
yk what im changing my nick here
E 🔥
i was joking about something else, xchips work with smods
where can i find all the names of scoring variables you can put in the "return" of a card?
by searching among a bunch of different jokers I found these (i dunno if the versions with caps all work, i wrote them just in case), but idk if that's all of them or im missing some
i just want the names that influence chips and mult, idc about money or anything else
i hath an image of it
one moment
ok the thing is there are two different jokers that can effect the one we're currently coding
a lot of these dont exist lol
i don't think it would be right to put the code for both of them in the context.ending_shop check
yeah i made up a lot of these lol i just assumed stuff
thx!
i mean youre doing everything in that context
you can do as much code as you want in any given context check
ok but im probably gonna implement it wrong
learning experience
i have a list that includes the talisman ones too if that helps
https://github.com/nh6574/Repertorium/blob/1184b50c950c354ad22e14a6bf35b48152ac781b/src/utils.lua#L4
i will totally steal that thx
There's no stealing in this industry
i dont think people should ever copy from any of my mods and specially not vanillaremade
hides all the lines i took from vanillaremade
ok when i ended shop, Necrozma (by itself) created Dawn Wings and Dusk Mane (which i don't want to happen)
whats the code look like
there's probably a really simple miscommunication that i'm misunderstanding with our conversation
At the start I believe I had vremade in my random seed for weeks
you should have EVERYTHING in the context.ending_shop check, not just the card creation
but you said i'm not putting "if" statements inside "if" statements
what do you want me to do here
ohhh
i
think i misunderstood what you meant then
just put the context check around the whole code
lol
crash
what does the code look like now
inside the function not outside 😭
is it not IN the function???
if context.ending_shop
calculate = function(self, card, context)
Means the if is outside the function. Just swap their positions. And add a then to the end of the if line.
is this right or have i dug myself into an even deeper pit
its
mostly right
missing an end though
put another end at the end right before the function end
It's not missing the end, the end is too early.
nah it's not too early
no
????
thats just because of wierd formatting
it's an indent issue you're looking at, which the code doesnt care about
Ah, I see.
just add another end before that end and it should be good
unless there are other bugs
what????
from what little i know about LUA i don't think that's right
but again i could be misunderstanding
youre just missing an end for the context.ending_shop check
so you gotta add an extra one before the end of the function
you mean like this????????
yes
WHAT????????????????
calculate = function(self, card, context)
if context.ending_shop then
local my_pos
for i = 1, #G.jokers.cards do --find own position
if G.jokers.cards[i] == card then
my_pos = i
break
end
end
local left = G.jokers.cards[my_pos-1] --left joker
local right = G.jokers.cards[my_pos+1] --right joker
if (left and left.config.center.key == "J_legendar_solgaleo") or (right and right.config.center.key == "J_legendar_solgaleo") then
card.ability.extra.is_destroyed = true
G.E_MANAGER:add_event(Event({
func = function()
SMODS.add_card {key = "j_legendar_duskmanenecrozma"}
SMODS.destroy_cards(card, true, true)
return true
end
}))
end
if (left and left.config.center.key == "J_legendar_lunala") or (right and right.config.center.key == "legendar_lunala") then
card.ability.extra.is_destroyed = true
G.E_MANAGER:add_event(Event({
func = function()
SMODS.add_card {key = "j_legendar_dawnwingsnecrozma"}
SMODS.destroy_cards(card, true, true)
return true
end
}))
end
end,
^ With proper indentation, that's how your funciton looks. The difference between the two final end statements makes it clear where the missing end is.
any advice on this?
THERE'S ALREADY AN END THERE ON THE SAME INDENT
yeah because
the code doesn't give a shit about indent lol
LUA IS SO STUPID
it's just visual for us humans
format document gets confused when you have missing ends
indent makes code easier to read
you could write your whole code on a single line
🔥
only language i know that actually cares about indent is python
i hate that thats possible
i'd rather watch actual beheadings than do that
99% of programming languages allow single-line coding.
balatro code
1 line
a balatrillion characters
🔥
IT DIDNT CRASH
you just didn't indent your code properly, so for you the code looks fucked but for lua it's fine
true programmer happiness
and you know what the best part about this is?
it still doesnt work as intended
IT STILL HASN'T DONE ANYTHING
well what does the code look like now
you should use an IDE to code, so you can check code errors more easily
true programmer problem
should be the last time as i sent it here
Just to be clear, what is the intended effect of this Joker?
if you have necrozma + solgaleo or lunala, it deletes both and creates dawn wings or dusk mane
if you have all 3, probably only works with the one on the left, ig
you should probably set up the smods and balatro lsp lol https://github.com/nh6574/VanillaRemade/wiki#3-set-up-the-lua-lsp
would help a lot with coding
i'm pretty sure i have a LUA lsp
I see one issue: Your joker keys are wrong.
What's your mod prefix? It should be "j_modprefix_legendar_solgaleo", also all in lowercase. Sometimes your Js are uppercase.
modprefix is legendar i assume
Right whoops. Then the issue is just the J thing.
oh yeah uppercase js
to be frank i only have the code set up so it deletes necrozma, it shouldn't delete solgaleo or lunala yet but only because i don't know how i would do that
i feel like if the prefix was wrong it would have crashed by now
why this happens if i have ''not G.hand.highlighted[1].destroyed''
didn't know about that, should this work or do i put the entire path from the root?
it should be either from the root or relative to the settings.json file
I'm just talking about in your if statments that check, like, left.config.center.key == "J_legendar_solgaleo". When the string you're checking is wrong for any reason, that only means the if statement is always false.
so i add ../ before so it leaves the .vscode file?
OF COURSE IT WORKS NOW
yeah
assuming the steamodded folder is there
it's in the screenshot lol
ok now that the fusion works how do i delete the other joker that isn't necrozma
smods.destroy_cards but instead of card you put left or right depending on the one you need
left and right are set to card objects that can be used in the same way as card
the problem is the joker it's fusing with can be on either side
well separate the code by left and right
guys do you like the joker
Oh god
:3
instead of doing if it's on the right or on the left then you do if it's on the right then else if it's on the left then
how do i make my custom enhancement's config.extra values work with quantum enhancements
do smth like
destroy_card = left or right
SMODS.destroy_cards(destroy_card, whatever other arguments)
No, that'll destroy left first regardless of what Joker it is.
no?
because the code is inside the check for the type of joker
oh
wait nvm
uhhhhhhhhh
fuck
idk
i hope you guys find this fun
why not just put the SMODS.destroy_cards inside an if statement
because i would hate to be dragging you through so much grief for something I might be the only one playing for
anyone know what to do,,?
Right now, your two if statements check for solgaleo, then lunala.
You can instead check if left and (left.config.center.key == "j_legendar_solgaleo" or left.config.center.key == "j_legendar_lunala") then then do the same for the right. The way, the first if statment can destroy left, and the second can destroy right
that is a wonderful idea
idk im doing fine, ive seen a ton of extremely infuriating things in this chat
such as:
not knowing how to set a variable
wait
if context.after then
if context.card and card:get_id() == G.GAME.current_round.tdec_beast_card.id then
I have no cluewhy this isnt working, the id is valid but anything below this if statement just isnt triggering
context.card doesnt exist in context.after
gg
WHY ARE YOU M
what would I use instead, since this is a blind effect
wtf
funny
for loop
ight
why is everyone me
damn
How do I get something to trigger on the card when the card is played in the calculation function? Return card = self doesn't seem right cuz it references the joker.
what do you mean.
calculate = function(self, card, context)
if context.ending_shop then
local my_pos
for i = 1, #G.jokers.cards do --find own position
if G.jokers.cards[i] == card then
my_pos = i
break
end
end
local left = G.jokers.cards[my_pos-1] --left joker
local right = G.jokers.cards[my_pos+1] --right joker
if left and (left.config.center.key == "J_legendar_solgaleo" or left.config.center.key == "J_legendar_lunala") then
card.ability.extra.is_destroyed = true
local key = (left.config.center.key == "J_legendar_solgaleo" and "j_legendar_duskmanenecrozma") or "j_legendar_dawnwingsnecrozma"
G.E_MANAGER:add_event(Event({
func = function()
SMODS.add_card {key = key}
SMODS.destroy_cards(card, true, true)
SMODS.destroy_cards(left, true, true)
return true
end
}))
elseif right and (right.config.center.key == "J_legendar_solgaleo" or right.config.center.key == "J_legendar_lunala") then
card.ability.extra.is_destroyed = true
local key = (right.config.center.key == "J_legendar_solgaleo" and "j_legendar_duskmanenecrozma") or "j_legendar_dawnwingsnecrozma"
G.E_MANAGER:add_event(Event({
func = function()
SMODS.add_card {key = key}
SMODS.destroy_cards(card, true, true)
SMODS.destroy_cards(right, true, true)
return true
end
}))
end
end
end```
esz can you try this
M pls help i'm looking at vanillaremade's lucky cards and i don't see what i'm doing wrongg
It should work fine normally.
wait, right now i have it set up where it looks for solgaleo, then lunala. if we're instead looking for the direction, we would then have to figure out whether it's solgaleo or lunala anyways
wait i forgot the additionnal destroy
edit i fixed it
well it's not
Code?
yeah thats what key = (bla bla bla) is doing
it checks which of the two it is
just replace the whole calculate function?
yes
Does the exact joker matter? The end result is the same in your previous code.
i removed the , at the last end, add it back
You made the Js upper-case in the joker key strings. Those should be lower-case.
-# elle_prob is just so it has cryptid support without messing with cryptid-less behaviour
How to check if card is not destroyed?
I literally copy pasted what you wrote
here
crashed
No, the J_legendar_solgaleo issue again.
Where is line 198?
did you put back the coma on the last end like i said
oh
jokes are illegal now 😔 🥀
I only noticed the issue after I pointed that out later in this conversation
the elle_prob function
the comma is on the last end
i'm willing to bet that it's because of the extra end before the one with the comma
Sometimes I'm just bad at getting them.
What are you inputting as odds?
the joke is that js stands for javascript
I WAS RIGHT
funy
what,
i dunno my code as the right amount of end
card.ability.extra.odds
you can check!!!!!!
i think you kept one extra end on your side when copy pasting
its probably this yeah
BUT I THOUGHT WE NEEDED AN EXTRA END
WE HAD ESTABLISHED THIS PREVIOUSLY
yeah but here you were replacing the entire code you already had right
because you had an issue
i fixed it
you just got given working code
you are going in the special thanks section
hold on lemme see
if no it might be due to the upper case J on J_legendar_solgaleo and J_legendar_lunala, just make them lower case j instead
Your code previously had improperly-formatted indents that were eliminated by the replacement code. It was never an "extra" end, it only appeared that way due to the indents.
nope we're back to square one
it's not doing anything
.
do that
then try again
Yeah
i should've fixed that before giving you the code but i just didnt notice
Didn't know message_card like that, thanks 
oh ok
how does the psychic add the text which tells you that you can't play your hand?
you mean the permanent one when the currently selected hand doesnt work or the "Not Allowed!" text
because i only know the latter
congratulations!!!! now one of the core mechanics of the fucking mod works as intended
mb for turning reply ping off @daring fern here's what i put in odds
and it's all thanks to Maelmc
nice
swag
i love that variable = (boolean and string) or string works, it's so useful
actually there's one more thing i want to do with it
variable = (anything and string) or string works too btw
ok so guys skipping booster DOES count as ending booster lol. I auto lost when I skipped a booster pack
😭
what do you need it for
yeah the first one 
how would i make it so if BOTH of them are next to necrozma, all three of them fuse to make Ultra Necrozma, skipping the Dusk Mane and Dawn Wings forms
Does it work fine normally but if you make a card count as that enhancement it doesn't work?
My blind is supposed to pick out a random rank and you need to use that rank to "damage" the blind, effectively reducing its score requirement in real time. I want the text to just stay there and always tell you which rank is currently effective
it works normally but stops working the moment i try using quantum enhancements with it
check how the mouth does it maybe? i dont remember if thats permanent
if (left and left.config.center.key == "j_legendar_solgaleo" and right and right.config.center.key == "j_legendar_lunala") or
( left and left.config.center.key == "j_legendar_lunala" and right and right.config.center.key == "j_legendar_solgaleo")
then
-- the event
-- code to delete all 3
-- code to add ultra necrozma
elseif left blablabla the code you already have```
i could maybe try to make it unconditional
alright i'll see how it goes
Blind:alert_debuff
oh
btw guys
fun blind hand debuffing fact
theres an unused line in the base game's localization files for a confirmation to play your hand if it would be debuffed by the blind
which wouldve required you to press play twice
before it let you play the debuffed hand
another fun fact, the not allowed message is not localized in vanilla balatro
this is iffy
why
