#💻・modding-dev
1 messages · Page 579 of 1
like
it
definitely is
i think
since otherwise the money would just work
if this was it
wdym?
well if the whole code was the return the dollars would just apply
youre kinda confusing me
you think?
probably
i dont have anything outside of this SMODS.Joker that would apply to it
except for atlas
it only doesnt apply if i dont have space tho
it does work if i have space
did you do it
play ur mod?
yeah
problem for later lol
first i wanna get this to work
it'll only activate if you have a free consumable slot
well how do i make it only do that for the tarot
and not the money
do this before the check for space
SMODS.calculate_effect({
dollars = card.ability.extra.dollars,
func = function()
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.dollar_buffer = 0
end
}))
end
}, card)
i want the tarot if i have space and the money regardless
like before that SMODS.add_card?
how do you do do that?
before the check for space
why doesnt this work?
put three ` at the start of your message followed by lua
put three ` at the end of your message
like this
im trying to make a playing card dupe itself when it sees its being destroyed
use copy_card
the " if #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then"
yea
oh
SMODS.Joker {
key = "placeholder",
blueprint_compat = true,
cost = 6,
loc_txt = {
name = "placeholder",
text = {
'When highcard is played',
'{C:green,E:1}1 in 2 {}chance to gain{C:money} $2 {}',
'and generate a random{C:tarot} Tarot {}card',
'{C:inactive}(Must have room){}',
'{C:inactive}if only there was a way to get sillier...'
}
},
atlas = 'Jokers',
pos = { x = 3, y = 0 },
config = { extra = { odds = 2, dollars = 2 } },
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'vremade_8ball')
return { vars = { numerator, denominator, card.ability.extra.dollars } }
end,
calculate = function(self, card, context)
if context.before and not context.blueprint and context.scoring_name == 'High Card' then
if SMODS.pseudorandom_probability(card, 'vremade_8ball', 1, card.ability.extra.odds) then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 0;
G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.dollars
if #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
return {
dollars = card.ability.extra.dollars,
extra = {
message = 'Whoosh',
colour = G.C.FILTER,
func = function()
G.E_MANAGER:add_event(Event({
func = (function()
SMODS.add_card {
set = 'Tarot',
key_append = 'vremade_8_ball'
}
G.GAME.dollar_buffer = 0
G.GAME.consumeable_buffer = 0
return true
end)
}))
end
},
}
end
end
end
end
}
still doesnt work
it just seems like context.destroying_card doesnt get triggered at all
okay so with this i get a money proc and then my game freezes
there's no way to easily raise the weight of an individual joker (especially per-run), right?
I forgot
The return true in the event
For resetting the buffer
no_message = true
what i find strange is that the money procs before the card
is there a way to make it proc after the hand?
probably trigger = "after", in the event
i dont actually know truly but i would try that and see if it works
??
is it exactly that?
How could I make a consumable only useable in a pack?
like this it dont work tho
probably only return true in the can_use function if card.area == G.pack_cards
plus whatever restrictions you want
is there a detection method to not count extra triggers but only once per played card?
outside of the function?
wont that disable the whoosh effect aswell?
No because the woosh is in a seperate thing
so where exactly do i put it?
Inside SMODS.calculate_effect
SMODS.calculate_effect works the same way as a return table
gg
no
add remove_default_message = true
i feel like that one wolf with the arguing parents
you can summon eremel to correct you by saying something that is inefficient
and eremel is never wrong
I am sometimes wrong
insted of the no message one
yes exactly
Do you need math to mod balatro
you need numbers
NOOOOO
there is an entire module called math which we use a fuck ton
okay wait this is weird
now it gives all of them at the same time in one message
is there no way to make the "whoosh" msg i have also apply the money?
is there a max size that a uibox can be
some of my stuff isn't showing up on it and I don't get why
whats your full code?
bump
oh no fucking wonder actually
just send the updated code
it's saving the colours as tables
just put the dollars stuff in the bottom return
this?
except for remove default message
put the dollars line and the remove default message line in the return table
then delete that calc effect bit entirely
wont that only trigger if i have space for the tarot htho?
move where you detect your space to the function where you add the caard
okay wait im getting really confused
thats not ur bad im just bad at taking in so many instructions at 2am
so move dollars = card.ability.extra.dollars, into return {
extra ={ etc
yes, although that extra is entirely unnecessary
is it?
How do you check if or what challenge you're on?
now it doesnt trigger if i dont have tarot space
and still gives a separate message for money
although after the hand ends tho so thats good
gonna implement a pot of greed consumable.
- draws 2 cards
- those 2 cards could be anything: jokers (not legendary), consumables, playing cards. The cards drawn could even have a random edition. It could even be another pot of greed
because you haven't moved where the check for space is done
do i need to move it upwards?
no, move it into the event where you add the tarot card
the add dollar line?
or rather, the function with that event
G.GAME.challenge
so move the entire function after the check for space?
oh wait i see
holdon
okay so i wanted to see what happened if i replaced smods.blueprint_effect with calculate_joker and uh
i got spammed with repetition check warning
and it does way more calculations
what does that mean exactly im not familiar with repetition checks
it means that you're returning things in context.repetition that doesn't contain repetitions
ah i see
okay so now it does work but how do i make the money message happen withing the whoosh message
like to be more specific i want the woosh to trigger and then get the money and tarot card simulataniously
can you copy the return code and I will fix it for you?
I hope that this kind of config, splitted in sections, will be easier to understand for players. If not - then I have no idea what to do
Capitalize "actions", "zone" and remove "& Vanilla"

i simply do not understand what the categories mean besides keybinds and presets
why does your mod have info popups and what are the levels for i've never seen them
okay after alot of testing
i got it to work before and after the round
but not during like
when other jokers trigger
i wonder is there a way to like delete a basegame joker? ik taking ownership is a thing so i feel like it should be possible
you can take ownership and add an in_pool function that returns false
and you can probably add no_collection if you don't want it to appear at all
SMODS.Joker {
key = "placeholder",
blueprint_compat = true,
cost = 6,
loc_txt = {
name = "placeholder",
text = { 'When highcard is played',
'{C:green,E:1}1 in 2 {}chance to gain{C:money} $2 {}'
, 'and generate a random{C:tarot} Tarot {}card',
'{C:inactive}(Must have room){}',
'{C:inactive}if only there was a way to get sillier...'
}
}, atlas = 'Jokers',
pos = { x = 3, y = 0 },
config = { extra = { odds = 2, dollars = 2 } },
loc_vars = function(
self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'vremade_8ball')
return { vars = { numerator, denominator, card.ability.extra.dollars } }
end, calculate = function(self, card, context)
if context.before and not context.blueprint and context.scoring_name == 'High Card' then
if SMODS.pseudorandom_probability(card, 'vremade_8ball', 1, card.ability.extra.odds) then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 0; G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) +
card.ability.extra.dollars
SMODS.calculate_effect(
{
func = function()
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.dollar_buffer = 0
return true
end,
}))
end,
}, card)
return {
dollars = card.ability.extra.dollars,
extra = {
message = 'Whoosh',
colour = G.C.FILTER,
func = function()
if #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({
func = (function()
SMODS.add_card { set = 'Tarot', key_append = 'vremade_8_ball' }
G.GAME.dollar_buffer = 0
G.GAME.consumeable_buffer = 0
return true
end)
}))
end
end
},
}
end
end
end
}
hey yall, i currently have this code and i cant seem to figure out how to play the whoosh effect at the start of the round and the money/tarot generation when other normal jokers play, is there a way to set that up?
ease_ante(number)?
does it support like
+ante
*ante
and ^ante?
I'm very new to modding, only mods I've tried to make were in jokerforge 😭
ease_ante(number) adds number to the current ante i believe
Yeah
ooo cool :D
I might try to code it right now but like
I feel like you guys will suffer trying to help me cause as I said idk lua 😭
is this right
I want it to be ease_ante(current_ante) or however that's done :p
eventually might do ^ante but just doing like
ease_ante(current_ante*current_ante)
or ease_ante(current_ante*current_ante*2) however that's done
is this a good idea chat? :D
chat? :(
what are you trying to do here
ohhhh, you want to make a spectral card that changes your ante?
yeah
3 separate ones
+ante, *ante, and ^ante
cause I get runs that can get to really high antes and I just get bored cause like
skip skip play 1000 times is just... not fun
you should probably either adjust the blind scaling to keep up with typical scoring in your mod, or consider rebalancing your mod (i prefer the latter, because it means that vanilla content doesn't get outclassed by modded content)
I'm not making a joker mod :p
this is for my cryptid runs :p
- debug mods will allow you to set ante
- let me look at cryptid's analog
you should consider not playing cryptid /lh
but being able to set ante is way less fun than like fishing for a pointer to get perkeo then duping *ante a bunch of times
you should consider not playing cryptid /srs
also this is how you make spectrals
https://github.com/nh6574/VanillaRemade/blob/main/src/spectrals.lua
a lot of these are complex because they have animations and stuff
that top part is for custom consumable class
Yeah, you won't need that
but you can just have a use function with ease_ante
yeah I think I'll do that
why does the comment say tarot lol
this prob won't be public, so I just need to make something that works :p
let me fix that
yes
so is this good?
might want to add a loc_txt param
good start
pos is the position of the art on the spritesheet though, so it probably won't be at (4, 4) when you get the art in
ohhh
should it be 0 0
the art will just be a placeholder thing tho
if the art for that one is gonna be in the very top left corner, yea
with a +, *, and ^ on top of it
yeah
anyway i'd say use a central localization file instead of a loc_txt thing in each consumable, but tbh this mod is gonna be so small that loc_txt would be fine
what's a loc_txt?
basically where you put the name and description of your things
ooo alr
what do I add next
to make this work
?
didn't change 4 4 so far btw
srry abt that, gonna do that rn
are you using notepad...
there we go
...yes....
Lua's syntax for creating a function isn't function() {}, it's function() end
please use VSCode
huh
alr
I'll install it when I'm done :D
I'm just like in the mood for modding rn and I don't wanna lose that
It will make it 100x easier if you do it now
trust me
It will actually tell you if something is wrong
like this?
alr
I will start the install rn
Yeah. Well, typical formatting has the end line matching the same indent as its function line, but it can work either way regardless.
ooo good to know :D
I'm assuming this won't work tho
because no art
vscode installed
You haven't defined an Atlas for it, so it'll work, but it'll default to the vanilla consumable Atlas.
that's bad cause I won't know what card this is
how do I make an atlas and assign this to it
?
this is how my atlas is set up
SMODS.Atlas({key = 'possession_blind', path = 'Blind.png', px = 34, py = 34, frames = 21, atlas_table = 'ANIMATION_ATLAS'})
so change out all my variables (key, path) for yours
Pos 0, 0 is the Fool.
ohhh and this is a spectral
so if I see a Fool in a spectral pack I'll know it's one of these?
uhhhhhh, it might be the key, idk
but probably no name
Pretty sure it'll just have no name.
how do I make it have a name then? not too worried about graphics
loc_txt would be easiest
loc_txt = {
name = "name",
text = {
"line 1",
"line 2",
"etc..."
}
},
what are the lines?
The lines of the description of the card. Balatro doesn't automatically wrap lines around if they're too long.
I might just leave them empty but like
how do I have more htan one name?
so different cards have different names
Each card gets its own loc_txt
It's part of the SMODS.Consumable section here.
??? I thought loc_txt was a file 😭
no? you put it in the same spot as key,set,pos
You can add a localization file but for smaller mods, you can also just have it as part of your main code.
so like this?
yes, but please for the love of jimbo fix your indenting
alr :D
also you might want to change your text to span 2 lines, but it should be fine
this better?
much better
Yes.
alright, imma need to ask another question for the other ones
how do I get the number that's current ante?
G.GAME.round_resets.ante
soo
ease_ante(G.GAME.round_resets.ante) should be x2 ante?
Yes
Yeah.
right, mom said its my turn to ask for help
anyone able to tell why my hand is not allowed when i have >=4 suits?
i want this to be compatible with mods that add suits (like bunco), so thats why im not doing this the flowerpot way
nvm i just saw a typo
SMODS.Suit => SMODS.Suits
nvm, still not working
What's the code now?
srry to interrupt but what did I do wrong 😭
is game crashing? what's your issue
no, the mod doesn't appear
it's on in bmm
so ye does anyone know why it doesn't appear?
yeah balatro was closed
Add a "prefix" line to your json
while I was coding
ohhh what do I put in there
smth along the lines of "Antesq_"
You don't need the _
should work i think
Anyways, the purpose of the prefix is to help ensure two items from two mods can generally have the same name.
So for example, the key for your Plus Ante consumable will now be "c_ant_pante" due to the prefix you set.
huh
ohhh
that makes sense :D
why can't I use the cards?
No can_use function
I guess the can_use function is required for each one. I would've expected it to just default to true if it didn't exist, but oh well.
can_use = function(self, card)
return true
end,
hype
anyways, bringing this back cuz i still need help
suitcount is < 4 despite me clearly selecting >4 suits
even selecting 5 wild cards doesnt work
unless im grossly misunderstanding lua documentation, idfk what is going wrong here
Don't know for sure if this is the issue, but try using SMODS.has_enhancement(cards[i], "m_wild") to check for wild cards.
so how exactly do you do crossmod content
if next(SMODS.find_mod('the id of the mod')) then
-- insert crossmod content here
end
not the issue
hello, i have a little problem, i'm doing a challenge and when i try make it negative dont works, i'm try to see vanilla remade but it's the same as my code
do this instead of edition
According to https://github.com/Steamodded/smods/wiki/SMODS.Challenge, your edition key should NOT have e_
In addition, the edition you give shouldn't have {} around it, in general.
You might be looking at an outdated branch of Vanilla Remade because I see:
-- Monolith
SMODS.Challenge {
key = 'monolith_1',
jokers = {
{ id = 'j_obelisk', eternal = true },
{ id = 'j_marble', eternal = true, edition = 'negative' },
},
}
Cool
right, ive narrowed the problem down to SMODS.Suits not working how i thought it would
i thought it would give me a table of all suits, but i think it gives me an empty table?
ie i thought it was
SMODS.Suits = {"Hearts", "Spades", "Clubs", "Diamonds"}
but instead, it's
SMODS.Suits = {}
something is wrong possibly
because SMODS.Suits has suits in it on my end
it could be that it only populates SMODS.Suits if custom suits are added? idk
weird, i have bunco on and it uses SMODS.Suits
oh wait i just read your code
the entries in SMODS.Suits aren't strings, but the whole Suit objects
also the table isn't ordered, so you can't do #SMODS.Suits or index it with a number
you need to do this
for i, v in pairs(SMODS.Suits) do
and then i will be the string you want and v will be a bunch of extra information about the suits that you don't need
so you can just use the include file directive to add jokers from a file conditionalyl?
the what now
if you mean loading a file then yea, just call the function to load the file inside the if statement i gave you
yea load file
whats cryptids id again
Cryptid
thx
works now, ty
how do you get the id from card.seal
and does it have the mod prefix applied
"items/jokers",
"lib/atlas"
}
local crossmodfiles = {
"cryptid",
}
for i, v in pairs(files) do
assert(SMODS.load_file(v..".lua"))()
end
for i, v in pairs(crossmodfiles) do
if next(SMODS.find_mod(v)) then
assert(SMODS.load_file("crossmod/" .. v .. ".lua"))
end
end``` is there anything that stands out here?
The C in Cryptid has to be capitalized, because that's how its Mod ID is.
oh
If you ever want to check a mod's ID, it'll always be listed in that mod's json file.
oke thanks
what is actually contained in G.I.CARD?
well that's for choice mod, but what about the size?
It's "choice_mod" has in "modification to the number of choices"
ok so the joker i added in the crossmod file isnt being added to the jokers list
i know its being loaded by SMODS.load_file because it errors for syntax
not sure if i did it right
I was referring to the "choice_mod" part of "booster_choice_mod"
oh
well that wasn't working either not sure if i was doing it right
G.GAME.modifiers.booster_size_mod = G.GAME.modifiers.booster_size_mod + card.ability.extra.size
G.GAME.modifiers.booster_choice_mod = G.GAME.modifiers.booster_choice_mod + card.ability.extra.size
are they read only or is it done by a different method like booster_size_mod(x)
is it possible to move an existing uibox's position?
SMODS.Joker {
key = "opensource",
name = "Open Source",
atlas = "jokers1",
pos = { x = 1, y = 1 },
rarity = 2,
cost = 5,
blueprint_compat = true,
demicolon_compat = true,
eternal_compat = true,
calculate = function(self, card, context)
local trigger = context.force_trigger
if context.individual and context.cardarea == G.play then
trigger = (card.seal == "Green")
end
if not trigger then return end
print("we are triggering!")
local outcomes = {"c_cry_commit", "c_cry_rework", "c_cry_delete"}
local judgement = pseudorandom_element(outcomes, "nflame_opensource")
SMODS.add_card{key = judgement}
end,
}``` does ANYTHING stand out here that would make the joker not appear in the collection??
im going to go to sleep
is that atlas real
no idea then
:(
you are loading the file right
ya its erroring on typos
collection = false iirc
what
no it's currently not appearing in the collection even though he wants it to appear
how would i save someone from death if a certain value is atleast 1?
(EX: G.GAME.JCJ_extralives)
ohhhhhhhhhhh
you gotta work your programmer brain here
if (a certain value is at least 1) then (save someone from death. see Mr. Bones in VanillaRemade to do the save thing)
oh this isnt a joker
i assume they want to do it outside of a joker
i have a consumable that just gives you an extra life
then do it in the global mod calculate
(It represents a "for" loop)
you can give mods calculate functions that work the same as jokers
i might just hook the death function
i forgot mod calculate existed
...if i can do that
do it in the global mod calculate. it's easier
i have
ZERO idea what that is 🔥
Instead of name, try:
loc_txt = {
name = "name",
text = {
"description line 1",
"line 2",
"etc..."
}
},
im using a localization file, do i just fill in the key for it?
SMODS.current_mod.calculate = function(self, context)
-- this is a calculate function
-- you can return like Mr. Bones does in here
end
throw this literally anywhere in your mod as long as it's not inside anything else like a joker
source: the smods 0827 release notes https://github.com/Steamodded/smods/discussions/919
you dont need a name in the joker definition
sooo anything else that stands out
"items/jokers",
"lib/atlas"
}
local crossmodfiles = {
"Cryptid",
}
for i, v in pairs(files) do
assert(SMODS.load_file(v..".lua"))()
end
for i, v in pairs(crossmodfiles) do
if next(SMODS.find_mod(v)) then
assert(SMODS.load_file("crossmod/" .. v .. ".lua"))
end
end
``` heres my main
and is there anyway to add a counter in the main gui that shows your lives
(im planning on having it also show on the for card, but for easier access)
You’re not calling your assert
what
No () at the end of the crossmod file loading
oh
or would i just have to patch it in
can I remove the info queues that aren't the consumables themselves? For context, this card is supposed to display the info queue of up to 3 different consumables
uhh look at how entropy does it ig
what strings should i look for? im not too familiar with entropy
if im lovely patching a mod and want to use a multiline, will i have to paste in the pattern exactly? or will i be fine with leaving the lines flat
What is your current code for it?
deck of containment and entropy
(yea the value is also called entropy :()
I think it looks for exact
Minus indents for parent lines
for
so true!
thanks spaghetti monster
oh no the lua code is escaping into the game
hey so is it safe to set consumeable_buffer to 0?
when spawning a card in event
yeah i do that, should be fine
oke it just feels wrong ig lol
how to get the description of a joker as a string
localize(set = "Joker", key = "j_pfx_yourjokerkey") i believe?
ok another quick question when using the id_card function what is the ID of aces I tried 1 and it didn't work
14
if 14 is ace then what is 1?
nothing
ok makes sense
tried it gave me an error
then idk
for an info queue?
its something to do with localization
no already got that one figured out I want to get the description of all the jokers in my deck each one as a string
how would i make it so you can take a joker from a booster even if the slots are full? I already did something similar with the shop by hooking check_for_buy_space
you could try setting the joker buffer to a negative number
according to someone else
extra_slots_used = -1
not the best practice since i'm already using hooks for other similar functions
it's not joker specific
otherwise i'd be doing that
i'll just try this for now
I don’t quite remember the name of the other function but it’s something like can select card
thank you so much
I couldn't find it
done 
how could i make it so the context.blueprint_card juices up in this instead of the joker being copied. Swapping out "card" for "(context.blueprint_card or card)" doesnt seem to work
how does versioning works again
before adding the event do local eff_card = context.blueprint_card or card then use eff_card inside the event
lil bump
major.minor.patch~alpha/beta
thanks
yw
guys I'm tryna make a new poker hand of four 7s of different suits, but it doesn't work, this is my code (i've never programmed before) can someone help?
-- Primera: 4 unique suits
SMODS.PokerHandPart {
key = 'primera',
func = function(hand)
if #hand < 4 then return {} end
local unique_suits = (get_unique_suits(hand, nil, true) or 0)
if unique_suits >= 4 then
return {
cards = hand,
name = "Primera"
}
end
return nil
end
}
-- Primera 7: exactly four 7s
SMODS.PokerHandPart {
key = "primera_7",
func = function(hand)
if #hand == 4 then
for _, card in ipairs(hand) do
local val = (card and card.nominal) or 0
if val ~= 7 then return nil end
end
return {
cards = hand,
name = "Four Sevens"
}
end
return nil
end
}
SMODS.PokerHand {
key = 'Primera',
visible = true,
chips = 100,
mult = 14,
l_chips = 30,
l_mult = 7,
loc_txt = "Primera",
example = {
{ 'S_7', true },
{ 'H_7', true },
{ 'C_7', true },
{ 'D_7', true },
{ 'H_Q', false },
},
tooltip = {
name = "Primera",
text = {
"A special Napoli hand.",
"Requires four {C:attention}7{} of different suits.",
},
},
evaluate = function(parts)
if not next(parts.napoli_primera) and not next(parts.napoli_primera_7) then
return {}
end
return {SMODS.merge_lists(parts.napoli_primera, parts.napoli_primera_7)}
end
}
Is there a way to detect which card is currently scoring? Like the [3]rd card returns 3?
Hanging Chad, of course! Thanks
Alright, I just throw this into a lovely.toml file, change the variable from the code, and call it a day or is there more to do?
I think that's it
You could also make a lovely folder with individual patch files
To make things more organized
Thanks for doing the patching. I'd be cooked if you weren't here.
-# Give me a funny variable name.
-# Bonus for mentioning the G.GAME.SSS var
Super_secret_variable_responsible_for_reroll_text_that_replaced_the_SSS_var
Hey, I wanted the funny, not the looks-nice-variable-name.
And you delivered
This should work, yeah?
So that did not work cause it stays at $10.
Just do if you have the voucher do this, then have the else if you don't
I tried that approach early on and that oddly didn't work out. Apparently, this is working technically but not visually.
Yep, still at $10.
-# Why won't you change?
Have you changed the ui element?
You'd either have to change it before the ui appears or recalculate it
Assuming the patch worked
Because looking at the change text that might not be the case
Lemme re-arrange it in my voucher.lua
See the lovely/dump
lovely/dump/functions/UI_definitions
Alright, what do I need to look for?
how do you detect if a card is unscored
It looks like no changes got made.
Yep, it's in lovely.toml.
Wait, does it need to be outside of my components folder for it to get recognized?
Ok, moved it to the root aaaaaaaand:
.
Ignore the var names, they match within both files
Also you can check the lovely/dump again
You need to set that value when you redeem your voucher
Currently it’s when you press the button
Made this change, let's see if it helps
WE HAVE WORKING CODE!
how would I get every sticker that is currently on a joker?
You’d have to loop through SMODS.Stickers and check if they are present
I might make a util function for that
alrighty
why am I getting an error here saying G.GAME.hands["whicheverhandhere"].level is a table
when I print it its telling me a number
you, E' Farmer, and SomethingCom all get collab credit for doing all this.
Do you have Talisman installed?
Talisman turns poker hand levels into tables, so you would need to use to_big
Because Talisman
because thats how bignum works
talisman makes you to_big like fucking everything
used to_big on my ex wife, she was not amused
no
the hand level is already big
you would do to_big(6) instead of just 6
same with whatever that other number is
i was testing my recipe system and realized gluttonous joker is spelled as gluttenous joker 
also the thing at the end is pretty important if your mod doesnt require talisman anyway
yeah I shall add that
I dont intend to make my mod require talisman cuz am trying to keep it as balanced as I could make it
unlike cryptid 
except cryptid will also be losing the talisman dependency at some point in the future..
still not the most balanced but its something
we love exotic jokers
i mean tbf most of them arent all too insane
theres just a few more problematic ones like crustulum and tenebris and ace aequilibrium
which are just fucking stupid
isnt tenebris the one giving 25 whole joker slots AND 25$
yeah
its terribly overpowered
I hate speculo
joker slots are way too versatile to just. give 25 casually
I remember getting it on that one deck giving a free exotic and -2 joker slots
huh
huh
I prob forgot a line there
i cant believe they added None to vanilla
nothing hand
is this not a context where you can just return level_up = -1
because theres quite a few where you can
alternatively just use SMODS.smart_level_up_hand
I think it is a number
the arm remade has a number
wtf
yea
but space and burnt use true
ye
speaking of burnt what the fuck is a context.hook
It’s valid in every context
hook boss discard
I have in my Joker that resets when discard
the played hand right?
the currently displayed hand
Yes
which is the played hand
yeah so I cant really use it, the curse I made directly targets the most played hand and substracts 5 levels from it
oh okay
You can do that
Add level_up_hand = “hand name” alongside the level up return
oh
If the question is “can I do this via the return table”, most of the time the answer is yes
oh
well okay
smods.smart_level_up_hand did the animation but increased by one the level instead 🗿
am gonna attempt the space joker strat
well I cant return tables with a consumable so I will have to get the Black Hole's code, and modify it
which is roughly
25 lines
:D..
yeah
since a lot of it is just the all hand level up animation
I need like 2 update_hand_text()
its doing the leveling but
the hand name doesnt show up
and the text stays at the end
yeah but why wouldnt it allow negative leveling
what value is levels_removed
it should
and x -1
that shouldnt be an issue should it?
I dont use localization yet dont blame me
I should do smth rq
adding the config
instead of just
5
you could instead of the check just do
local levels_removed = math.min(card.ability.extra.levels_lost, G.GAME.hands[hand_current].level - 1)
what do i hook/patch to add ui stuff here
create_UIBox_blind_choice iirc
this?
ohhh
i was wondering why it was so small i thought the end was just the end of the function
You could technically do it in a hook
how can i make the variable apply for just the card
while still being able to display it
the venomcount
because
the way im doing it rn
it just changes it for every single card that has the seal
holy
am never making a ui in balatro 👍
Use card.ability.seal instead of self.config
okay i think create_UIBox_blind_choice is for this part?
i didnt see the or text or the tag
nvm
actually this could work
bump 
Use {set = set, key = key} instead of using the center.
alright, thank you
card.ability.seal not card.ability
oh
thanks
how can i make a card duplicate itself with a seal
when its being destroyed
the tag is extra iirc
because
the way i did it right now
the calculate never triggers
when its being destroyed
how do I return the number equivalent of a to_big() table
isnt it #(table)
How are you destroying it?
Why would you need to dothis
Ohh
isnt that the amount of values there are inside the table
hanged man
i thought thats what you meant
yeah for some reasons levels_removed is a to_big() table
which is why smart_level_up increases by 1 instead
cuz
to_number(variable)?
type(amount) == 'number'
That shouldnt happen unless you used to_big on some related value
thats where it comes from
bump
this should crash but lemme see
if context.cardarea == 'unscored'
to_number ~= tonumber
to_number is the talisman function
bump
like this?
No, context.cardarea cannot be G.play and 'unscored'
so i replace the g.play?
Yes.
alright
does anyone rq know the command for making a different sound play when scoring?
do you want to replace the sound or play a sound ?
Either way you should check the SMODS.Sound and the examples in smods
i have a custom recources/sounds folder with some custom mp3's in it and i want to replace the scoring trigger sound with one of the custom ones in there
You can replace the sound pretty easily just look at the examples
where do i find examples exactly?
Use SMODS.Sound, then you can put sound = <key> in a return
Or you can replace sounds entirely with it too
after reading the documentation that nassym told me to i think i got it
but it just doesnt recognize my file for some reason
is it in assets/sounds?
Yeah
i did that and now it gives this
i dont even know whythat would happen
all i did was remove sounds from recources and put them inside assets 😭
Code?
what part of the code do you wanna see?
oh
i fixed it
lol
now it gives the error that "recources/sounds/my.ogg" doesnt exist
which is true it doesnt
but how do i redirect it to assets?
No, that means that the key is wrong when you are trying to play the sound.
so like this?
It looks inside assets/sounds by default
I said the key is wrong when you are trying to play it, not that the path is wrong.
Also wtf is register_global
okay so wait
No, it would be SMODS.Sound:register_global()
No, it's modprefix_key
ohhh
when i add that back i get this error again
.
how can i make this text disapear after i used my consumable
(ignore the absurd levels)
Yes, you're not doing it right, it is exactly SMODS.Sound:register_global()
oh () instead of {}
i dont get why this isnt working tho
i know im just stupid
but
i feel like im overcomplicating things in my mind
Yes, all you have to do is copy and paste.
because currently i have this (YA being my prefix)
Propellor being the name of my ogg file
but when i run that it still checks for my recources/sounds instead of assets/sounds
i just dont get why it defaults to recources
No, that means you did the key wrong.
so for that i need this SMODS.Sound:register_global() right?
No, that registers all the files in assets/sounds as sounds using their file name.
why isnt G.GAME.sajevents initialized
so what else do i need besides
this?
You need to do it in Game:init_game_object
wait do my ogg files need my prefix attached to them?
Use SMODS.smart_level_up_hand instead.
do i hook it in the return or can i just hook it to set sajevents
You hook it and you set ret.sajevents
this i dont understand because no matter what i do it keeps looking in recources/sounds instead of assets/sounds
but what is my key supposed to be?
bcs im reading on the github about this
and i find it so confusing to understand properly
Have you tried just using SMODS.Sound?
yes thats what im doing rn
like is my key just supposed to be basically a name that i call back later?
because in atlas for the sprites thats pretty much what i do
No, I mean just SMODS.Sound not SMODS.Sound:register_global()
yeah i got that
iam using just SMODS.Sound
nothing after it besides ({
how can i force a hand draw
like is my path supposed to be assets/sounds/mysound.ogg
because it keeps looking in recources/sounds
Yes.
then why does it not do that here?
in atlas
i just call Joker.png
and it works
why does that not work in sound?
Is your sound file called Propellor.ogg exactly?
yes
Do you have file extensions enabled?
i had a huge thing with that on friday haha
yes the .ogg is the extension not the name
You need to prefix sound keys because it is perfectly plausible that you would want to play vanilla sounds
so it needs to be myprefix_Propellor.ogg?
so in here?
so myprefix_propellor?
Yea
i have a feeling itll still look in the wrong file path
but everything is worth a shot
and ive had many times in this project where i thought there is no way it'd work and it just works for some reason
now it says cant read Ogg bit stream?
Thats probably wierd file shenanigans if it can find but not read it
Try like redownloading the file or smth assuming you downloaded it from somewhere
I think
i downloaded an mp3 and then just converted it to a ogg
but i can do that again yeah
Converted in what way
Did you just rename the file or did you convert it with an app or website
with an app
you cant convert it just by name can you?
It won't work properly if you do
yeah thats what i was thinking
because there has to be a distinct difference for there to be a seperate file extension for it
that you probably cant get by just changing 3 letters at the end
I mean there are plenty of near identical file types
The extension is mostly for determening what the file should be opened in
oh i think it might have been the file
redownloading it worked
now im curios, how do i make multiple sound files register
e.g. pptx files are just zip archives, you can just rename one to be a .zip without issue
because im planning on using more
SMODS.Sound again
man learning balala is so much more fun than java
bcs this is so much easier
what im learning here in 20 minutes takes like 2 days in java
lua
wait i was playtesting two of my jokers to see if they werent too busted and i found another one in the shop
how do i make them unique?
asin only multiple can be found with showman
They should be unique by default
Duplicates sometimes just happens if you spawn them with debugplus iirc
Try typing eval G.GAME.used_jokers into the console
That should have every single currently owned joker normally
i did spawn one in like 4 rounds ago
if context.joker_main and not context.blueprint and context.scoring_name == 'High Card' then
just a quick question how do i update this to check if hand contains a stone card
local has_stone = false
for k, v in pairs(context.full_hand) do
if SMODS.has_enhancement(v, 'm_stone') then
has_stone = true
break
end
end
how do you grab card's rank again
card:get_id() iirc
could this work for setting a random edition?
I'd look at how Aura or Wheel of Fortune do it
oh
No, you would use poll_edition
No, it's SMODS.poll_seal
does it do it automatically
no like
not add to a card
add a seal to the pool
for poll_seal
If you create a seal it should automatically be in the pool.
where do you think poll_seal gets the pool of seals
im trying to make it so beating stakes unlocks more than just the next one (e.g. beating white stake unlocks red, green, and black. beating black unlocks blue, purple, and orange. beating purple unlocks orange, a modded stake, and some other modded stake. etc.)
does anyone know where i should start looking to make modifications to unlocking stakes? i've poked around but finding the right code to look at (and inject a patch into) has been a struggle
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play and not context.blueprint then
if SMODS.has_enhancement(context.other_card, 'm_steel') then
if SMODS.pseudorandom_probability(card, 'blacksmith', 1, card.ability.extra.odds) then
local original_rank = context.other_card.base.value
local original_id = context.other_card.base.id
local new_id = context.other_card.base.id + card.ability.extra.rankup
if new_id > 14 then new_id = 2 end
context.other_card.base.id = new_id
context.other_card.base.value = card.get_id(new_id)
G.E_MANAGER:add_event(Event({
func = function()
context.other_card:juice_up(0.5, 0.5)
return true
end
}))
return {
message = localize { type = 'variable', key = 'k_rank_up', vars = { original_rank, context.other_card.base.value } },
colour = G.C.SECONDARY_SET.Enhanced
}
end
end
end
end
any idea why this isnt working?
why dont you just use the same function that strength uses
What’s the context for “end of ante” specifically? Unless it’s end of boss blind.
no, its assert(SMODS.modify_rank(context.other_card, card.ability.extra.rankup))
didnt think of it that deep
which
that because source: vanillaremade strenght
context.ante_change and context.ante_end
first argument has to actually be a card
assert is just so vscode doesnt kill you for not assigning the return
??????????????
might be a little far but its litterally a joker that +1 rank why isnt your first instinct strength
it still does the same thing
wdym
attempt to index local 'card' (a number value)
how
how is that a number
what did you do
where do i cast the break?
where he put it



