#💻・modding-dev
1 messages · Page 228 of 1
I found the implementation casting it to blue a bit weird
and when the variable is greater i return that
yeah
Deep cut reference to our server but changing Jimbo quotes is fun
I don't think it matters what the default colour is
Also I need to use save states for debugging purposes more often
Is it intentional that it ignores Blueprint compatibility?
I assume so
blueprint compat is purely a UI value
That's why I assumed so
Oh does blueprint compat not also prevent a blueprint context from being fired?
no
You have to manually code it
Which makes sense for multi-part effects that are partially compatible
we should probably make it an actual functional value though
@wintry solar by the way do you know what's the correct way to debuff and recalc debuff on cards now?
would this work?
create_card = function (self, card, i)
local epicsigmajimbotable = {
spawntarot = {
set = "Tarot",
weight = 1
},
spawnplanet = {
set = "Planet",
weight = 1,
},
spawnjoker = {
set = "Joker",
weight = 1
}
}
local jimbotableweight = 0
local randomnumber = pseudorandom(pseudoseed("haimynameisJIM"))
for i = 1, #epicsigmajimbotable do
if randomnumber > jimbotableweight + i.weight then
jimbotableweight = jimbotableweight + i.weight
else
return SMODS.create_card({
set = i.set,
area = G.pack_cards
})
end
end
end,```
I do not
it should yes
How could i make a new type for ante instead of round.
oh it should be epicsigmajimbotable[i]
where
all the is
Is it even possible for Ranks and/or suits to even have unique function?
i.weight and i.set
well yes
Oh cool. How would I go about doing that?
ough it works
ooh, that's a fun addition. Does every card just have a limited amount of uses?
it doesn't turn the cards you play into garbage, just a random 1-2 cards in your deck whenever a hand is played
yeah, you can destroy them with tarots or various jokers
Not me adding if context.blueprint then return end to every single joker
can i see the code now
hi chat, need some help getting this damned joker to work
im trying to destroy the cards contained within card.ability.extra.die (they are added correctly and stuff, just the destroying is difficult rn) after scoring is done, but this damn context.destroying_card and :start_dissolve are driving me up the wall after trying to wrangle it for ages now, how do i do this correctly?
if context.before then
card.ability.extra.count = 0
card.ability.extra.die = {}
for k, v in ipairs(context.full_hand) do
if not table_contains(context.scoring_hand, v) then
card.ability.extra.die[#card.ability.extra.die+1] = v
card.ability.extra.count = card.ability.extra.count + 1
end
end
elseif context.repetition and context.cardarea == G.play then
local triggers = card.ability.extra.basetrig*card.ability.extra.count
return {
repetitions = triggers,
message = localize('k_again_ex'),
card = card
}
elseif context.destroying_card and not context.blueprint then
if table_contains(card.ability.extra.die, context.destroying_card) then
return { remove = true }
end
end
end```
create_card = function (self, card, i)
local epicsigmajimbotable = {
spawntarot = {
set = "Tarot",
weight = 1
},
spawnplanet = {
set = "Planet",
weight = 1,
}
}
print ("your epic fortnite table has" .. #epicsigmajimbotable .. "entries in it milord")
local jimbotableweight = 0
local randomnumber = pseudorandom(pseudoseed("haimynameisJIM"), 0, #epicsigmajimbotable)
for i = 1, #epicsigmajimbotable do
if randomnumber > jimbotableweight + epicsigmajimbotable[i].weight then
jimbotableweight = jimbotableweight + epicsigmajimbotable[i].weight
else
return SMODS.create_card({
set = epicsigmajimbotable[i].set,
area = G.pack_cards
})
end
end
end,```
@red flower here
oh yeah sorry i didnt notice because it's hard to read code on mobile lol
if your table has named entries you need to use pairs()
in this case i actually would delete the names from the table, you don't need them
i thought it was a test case
because the max size of the number is based on table LENGTH and not total table weight
well yeah it is a test case but
i wanna make sure it works
the problem is that table[i] doesn't exist if the fields are named
Where are the temporary values for tags reset?
m
you're trying to destroy non scored cards?
m
precisely
and to my knowledge they are being added to the die table
so i just want to destroy everything in it
use context.destroy_card instead
also I think you need to enable the unscored feature for that? is that right?
in place of the first context.destroying_card right?
i presume checking if context.destroying_card is contained in die is still correct
destroying is only on scored cards
it has
hey @red flower it still crashes
ooh hang on is this a very recent thing
my smods might be out of date if so
may i see it
create_card = function (self, card, i)
local epicsigmajimbotable = {
{
set = "Tarot",
weight = 1
},
{
set = "Planet",
weight = 1,
},
{
set = "Joker",
weight = 0.3
}
}
print ("your epic fortnite table has " .. #epicsigmajimbotable .. " entries in it milord")
local totaltableweight = 0
for i = 1, #epicsigmajimbotable do
totaltableweight = totaltableweight + epicsigmajimbotable[i].weight
end
print ("and it has a total weight of " .. totaltableweight)
local jimbotableweight = 0
local randomnumber = pseudorandom(pseudoseed("haimynameisJIM"), 0, #epicsigmajimbotable)
for i = 1, #epicsigmajimbotable do
if randomnumber >= jimbotableweight + epicsigmajimbotable[i].weight then
jimbotableweight = jimbotableweight + epicsigmajimbotable[i].weight
else
return SMODS.create_card({
set = epicsigmajimbotable[i].set,
area = G.pack_cards
})
end
end
end,
it keeps saying that t is nil
why is that
oooh yes replacing all my context.destroying_cards with context.destroy_cards and updating smods did the trick it seems
one more thing though, is there a way to add a message over the destroyed cards while they're being destroyed
do i just add a message inside the return{} next to remove = true?
is there a way to add tarots that are rarer than other tarots? replacing a certain percentage of tarots would also work for my purposes for this
^ same with spectrals and planets, i assume they'd work the same though
message and message_card iirc
message_card?
im not familiar with that one
yeah if you return a message it's on the joker i think, just return message_card = the destroyed card
nope no idea
you need to put the weight sum in the pseudorandom but i dont think its the problem
yeah i did that but i rolled it back so i could show you
WAIT
when i hover over i
it says its a redefined variable
does that mean anything
HOLY SHIT
I FIXED IT
HOLY FUUUUCK
I CHANGED I TO V AND IT WORKED
congrats omg!!! :3
when i see those i get scared DGAK:DSGDASG
it sensed your happiness
what is ur crash screen btw
no they're locals they're destroyed after the function ends
i assume you're creating a card somewhere with SMODS.create_card, you need to pass in a table for it to work
i am
this is how you create the table
my code is up here
oh maybe it never hits the else
yeah cause your else statement is the one that returns the table you need
create_card calls smods.create_card with the result so if you don't return anything it might do smods.create_card(nil)
but
it's saying t is nil
oh wait
pg
pff
im dumb
the thing that goes in parentheses IS t
right?
yes
but how is that even possible?
no, that part is correct
if ur not returning anything it defaults to nil i think
so wait
hold on
let's say
i have a table of total weight 3
if i generate a random number between 0 and 3
then it can never be higher than the total weight of the table
so what gives
That's not usually how you'd use the weights
Where are the temporary values for tags reset?
Usually you compute the ratio of each item's weight to the total weight
Then compute the running sum of weights until it's higher than the generated number
idk
.
you did the opposite but it should work too
unless you're generating the number wrong
are you sure you added the correct max to pseudonumber here
How do I go about making it so a rank has a card lose value each time it's played?
im gonna send my code one more time
create_card = function (self, card, i)
local epicsigmajimbotable = {
{
set = "Tarot",
weight = 1
},
{
set = "Planet",
weight = 1,
},
{
set = "Joker",
weight = 0.3
}
}
print ("your epic fortnite table has " .. #epicsigmajimbotable .. " entries in it milord")
local totaltableweight = 0
for v in pairs(epicsigmajimbotable) do
totaltableweight = totaltableweight + epicsigmajimbotable[v].weight
end
print ("and it has a total weight of " .. totaltableweight)
local jimbotableweight = 0
local randomnumber = pseudorandom(pseudoseed("haimynameisJIM"), 0, totaltableweight)
for v in pairs(epicsigmajimbotable) do
if randomnumber >= jimbotableweight + epicsigmajimbotable[v].weight then
jimbotableweight = jimbotableweight + epicsigmajimbotable[v].weight
else
return SMODS.create_card({
set = epicsigmajimbotable[v].set,
area = G.pack_cards
})
end
end
end,```
is there anything blatantly wrong here
you would also need to change these to v.weight and v.set
why does it say i is a redefined local though
.
ooooooohhh
that
actually makes a lot of sense
would it be ok if i did for _, v in ipairs since i isnt used
yeah
did u replace the other for
I have a question about SMODS. You know how when you use create_card it doesn't actually emplace it in the card area and it just ends up like... on the screen and you can just drag it around wherever? Is there like a way to check for a card like that somehow, like does it actually exist in a way that it can be referenced?
which one
create_card = function (self, card, i)
local epicsigmajimbotable = {
{
set = "Tarot",
weight = 1
},
{
set = "Planet",
weight = 1,
},
{
set = "Joker",
weight = 0.3
}
}
print ("your epic fortnite table has " .. #epicsigmajimbotable .. " entries in it milord")
local totaltableweight = 0
for _, v in ipairs(epicsigmajimbotable) do
totaltableweight = totaltableweight + v.weight
end
print ("and it has a total weight of " .. totaltableweight)
local jimbotableweight = 0
local randomnumber = pseudorandom(pseudoseed("haimynameisJIM"), 0, totaltableweight)
for _, v in ipairs(epicsigmajimbotable) do
if randomnumber >= jimbotableweight + v.weight then
jimbotableweight = jimbotableweight + v.weight
else
return SMODS.create_card({
set = v.set,
area = G.pack_cards
})
end
end
end,```
WHY doesnt this work
SMODS.add_card auto-emplaces, but I guess that's not really your question. unemplaced cards don't have an easy reference for you to grab, you'd basically have to iterate over all card instances in G.I.CARD and check for each card if it has an area
Where are the temporary values for tags reset?
they also don't get saved in any way. so if you reload the run, they're just gone
Yeah, I'm also aware of that, I've decided not to think about that problem just yet lol
fair enough haha
aure please bless me with your infinite knowledge. why is it telling me that t is a nil value
if you're the one creating the free cards, your best bet should be to store the cards somewhere yourself
create_card always expect a return value
From here it looks like there's a chance the function returns nothing
that looks about right
i copy pasted ur code and it worked
lol
planets and jokers
okay so its not a card type issue
you might need a default return
How would I go about implementing rescoring
Like after when the scoring ends, scoring will commence another time
Looked up chats and saw stuff about SMODS.score_card but there are a lot of ways to use it so I'm confused
SMODS.calculate_main_scoring is a full scoring loop, you can look at how it's implemented
how would i use create_replace_sound so that a sound only replaces the standard balatro bgm once during a specific state of the game every time that state happens
it has a problem when the random number is exactly 3
which it probably shouldnt be
If you want, say, a 50/50 chance, then the intervals x < 0.5 and 0.5 <= x <= 1 have the same size
so you only need to check all but the last option
oh it's because pseudorandom only takes ints
w h a t
or maybe the issue is elsewhere XP
it's rounding 2.3 up to 3
This totally works exactly how I wanted thank you so much
so no decimal weights
hahaha
got it
awesome
I might have to ditch the idea I had :(
okay
i got it
and THAT
WAS THE EASY PART
now i have to do the HARD PART
which is all the MINIGAME BULLSHIT i wanna do
good luck
how do i have a sound play once, overriding the background music, then have it resume the background music once it's done playing? I wanna have a victory theme but I don't want it to keep looping >_<
I really don't know how to have my rank change values, so I'm just gonna have it as a solid 9 for now
i think multiranks are something that was said to be very hard to do but they were considered at one point for SMODS
you can read these messages for why
Ah, got it. Mine would keep it's place in the rank order, but I get why they don't want to implement it
oops
i love discards
waiter waiter, more discards please!
I'll just do some unique Jokers for my rank instead.
I did find something like this across different mods on GitHub
for _, v in ipairs(context.scoring_hand) do
SMODS.calculate_main_scoring({cardarea = v, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands}, v == G.play and scoring_hand or nil)
end
Is this one of the proper ways of using it? Still not sure where I should use this since I'm getting the error attempt to call field 'calculate_main_scoring' (a nil value)
i want to make a custom joker but i dont know how to code, is there any tutorial out there?
But I'm tired working on rank and suit stuff, so I'm gonna take a break and make some new mechanics for my mod
i also dk if you meant an enhancement that switches its rank every round but
besides those, https://github.com/Steamodded/examples/tree/master
i feel like we should have a pin for these resources just so people have a good place to get started
No, I meant. I added a custom rank, but I want it to be unique in that it loses value over time and then resets.
ohhh i see, well i feel like that would be okay enough since it only ever has one value per round?
but i feel like it would be more like an enhancement than anything
because if you just do an actual rank I think it'll lose value once and then it'll be like an Ace or a King
Fair but. It's the Cat Rank. Cats have 9 lives.
true
It's fine though, I'm not too upset about it.
Getting up there, only stops when round ends. (for a short time)
It's just something that would've been neat
I tried this joker, if you try to play the same cards with a joker from the start, by 6 ante from one card it will be about $20
since SMODS.Rank doesn't really have a calculate function I don't know if that would be possible, but again, an Enhancement probably would be better?
not enough discards imo
80k should be balanced
you'd discard your entire deck
Its only when you get a certain tag, then it stops between every action just to add more discards
Probably. I wonder if it's possible to make an enhancement that automatically applies to all copies of rank? That could solve my problem, I think.
hmm dk
maybe it'd be possible to target it through G.playing_cards, since that's your entire deck?
Boss Blind where the number of hands is reduced by the number of discards:
-50 billion hands
And instant loss
Working out well
I really like that The Board joker
I made sure the description was similar
Still need to make the functionality work
I have an idea for someone to implement.
Infinity Balatro.
There are no blinds, instead there is a progress bar for which you get money.
The store is accessible at any time, it is updated every 5 rounds or for money.
The first 5 rounds (According to the number of points for the first 5 blinds) there is no debuff, then every 5 rounds a random debuff as with the boss blind.
The deck is also restored every 5 rounds.
How to crash your game speedrun
It is possible to increase the size of the blinds, but still limit hands and discards between every 5 rounds
I could use events, maybe, actually. I'll try that later. As I said, I'm tired of working on this rank, trying to get it to work.
Gn
omg roguelike balatro
the idea sounds fun actually
would anyone know how to implenment this by the way
or atleast how to check for negative cards in jokers and consumables
idk but u can try find something for it on the SMOSD wiki
And also u can try find mods that work with editions, for study
Shall get to work then, thank you
so like
"Every Negative Card will give X3 Mult?"
you could make it so that it goes through each card area (G.consumeables, G.hand.cards, context.full_hand/G.play.cards, and G.jokers.cards) and check if those cards have edition.negative
that sounds like what it is I have to do yea
will look into making it check each area
look how the game does it in card_character.lua, i gotta get to it eventually too so idk for sure but you should start there
opening and closing the deck is not supposed to add a permanent event to the event queue... right
I thought this was an issue with my custom deck but this seems to just, happen?
okay so
looking into it
i have discovered the function Card_Character:init
which takes 5 args
x position, y position, width, height, and "config"
there's also Card_Character:move(dt), which makes him move to a specified location
Card_Character:add_button, which... adds a button
presumably
is there a way to find what card would have been generated from create_card while hooking into it?
would just running a proxy create_card within the hook and checking the value of that card be the same seed-wise?
obviously avoiding loops
though, idek if i should try to keep seed rng intact considering it's probably different anyways
Hey there, pretty much copied what golden card does, but want to destroy the face cards instead of turning them to gold, I tried searching and code-diving but what I attempted to piece together doesn't explain much, how would one even destroy a card?
calculate = function(self, card, context)
if context.cardarea == G.jokers and context.before and not context.blueprint then
local faces = {}
for k, v in ipairs(context.scoring_hand) do
if v:is_face() then
faces[#faces+1] = v
v:set_ability(G.P_CENTERS.m_gold, nil, true)
G.E_MANAGER:add_event(Event({
func = function()
v:juice_up()
return true
end
}))
end
end
if #faces > 0 then
return {
message = "Harvested!",
colour = G.C.PURPLE,
card = card,
destroying_card = card
}
end
end
end
Is there really no simple replacement for
To destroy cards?
use context.destroying_card instead of context.before and return { remove = true }
https://github.com/Steamodded/smods/wiki/calculate_functions
(you can still do the return in context.before for the harvested message)
placeholder asset but this is fucking awesome
oh that's cool
would create_card(_type, area, legendary, _rarity, skip_materialize, soulable, forced_key, key_append).key get the key of the created card? or is there another way to do that
Ah, so I add extra if condition for context.destroying_card and put it in its own return? How would I pass the cards?
Havent touched modding in 1-2 months, and when I did, it was with old-calc. Are there any differences with old/new calc apis, and are there any resources available that lists them?
it's called for every scoring card so you can do
if context.destroying_card and context.destroying_card:is_face() then return { remove = true } end
Oh! Thank you!
never done a deck with a calculate function, why would this be crashing?
it would be .config.center.key
also you might want to save the created card in a local beforehand
true
i think it doesn't like the return true
it probably expects a table
This worked great! Thank you for your help!
ah right
i don't think there are, the calculate wiki page is your best option
ok problem, this still spawns the card as if it were being generated to your consumables or the shop instead of just creating it as a variable
Yea I was scrolling through it, nothing major seems changed. Ill just have to test the cards I have and see if they still function
what are you trying to do
get the key of a randomly generated card with those input parameters without actually creating the card, basically simulating opening a pack
currently it gets the key right but it also creates the card and just puts it on the screen
for what reason?
FUUCK YEAH
gomer
gomer
thats not gomer actually
i made him to test spawning Jimbo and having him say custom lines
because it's creating the card?? it just doesn't have anywhere to put it so it just puts it on the screen ig
no, i mean why are you trying to get the key
there are simpler ways
but it depends on what you want to accomplish
effectively i want to get the key of every tarot card generated and use it to replace certain tarots with certain other ones
oh so you want to change the tarots in the pool?
yeah but with weights and letting me change it with jokers etc, by hooking into create_card
i recommend hooking get_current_pool instead
why?
Do contexts not work when I'm overriding a function
that does the key thing that you want, it gives you the current pool and you can replace the list
you would still need to hook create_card to change the area if you want other sets so tho so maybe it's not much better
yeah i don't think that's super useful for what i'm trying to do
is there a way to modify a card after its creation rather than before? because hooking into create_card modifies it before it's created
and i want the RNG of tarots to stay the same with my stuff applied after the fact
I wouldn't hook create_card, i would patch it
ok what does that do and how do i do it
still looking for any help on either this or my undiscovered legendary joker description issue
look at the lovely readme
basically you can add things in the middle of functions instead of the beginning or end
wdym
Nvm
yeah
how would i go about making something happen whenever a booster pack of a certain type is opened
without the help of a joker
hmm hook SMODS.calculate_context?
how would i get the key of whatever tarot it creates though?
you would check center here
you can change it there and then change the area depending of what you're changing it with
what do I set pools: to in order to remove that card from all pools? just false?
I want an enhancement to never show up naturally in booster packs, via spectral cards, etc
you mean in_pool?
Is there a way to resize jokers in runtime? Like make a joker change scale at the end of an ante/scoring round?
Changing display_size/pixel_size doesn't seem to work
or, yeah that I guess, got mixed up with the enhancements page having a parameter called pool
yeah just make a function that returns false
hey
do you guys know the func that runs whenever the game has to open a booster pack
so is this formatted correctly? first time doing patches
it doesn't seem to do anything but idk what i did wrong
i think the pattern has to be only one line
can it still look for multiple lines? or do i have to do before center = G.P_CENTERS[center]?
i would do the second option
i think you need to use regex for multiple lines but I'm not sure
question
this also does nothing
which area is the area where booster pack cards are displayed?
G.GAME.somethinsomethin_hand.cards, yea?
is it not just G.pack_cards?
im not sure
worked for me
well it does nothing for me
check the lovely/dump to see if the code is there and check if you have lovely updated
i don't know what the first part means and i set this up days ago so i'd be surprised if it wasn't up to date but i also don't know how to check that
inside your mods folder there's a lovely folder
it's unchanged there
when you open the game what version of lovely does the console say at the top
it says
1.0.1o-FULL
1.0.0~ALPHA-1426c-STEAMODDED
oh wait console
thought that said screen
0.7.1
what should i be doing to initialize the patches? again haven't done this before
yeah
this is the whole thing
is it in the root of your mod's folder?
yup
functions/common_events
im stupid
me too
ok now i just have to figure out how to actually add what i want to
i can make a global function in my mod then use it in the patch right?
yeah
pog ok i got it working this is way easier than mixins
quick question which do you think would be harder to obtain
three pairs or a five card straight
straight
Hi bepis
hi peak :D
straight easily
ok cool, thats what i was thinking
so whats the pre-prefix thingy for PokerHand keys?
(not the one you set up in your mod the one thats 'j' for jokers and such)
hey chat sorry for like parroting the same thing over and over
just like 'p' or something?
but like i cant find anywhere else in this server where someone has given a solution
whatcha got?
i know that mult card not multing was a commonish bug cuz i've found a couple of posts reporting it
but i don't see any fix
i have a joker which changes the suit of the cards in your hand
that sounds very esoteric
but any mult card that get converted this way no longer give mult
thats
weird
EVEN if you apply the mult enhancement AFTER the suit conversion
yeah i personally dont got anything
youre in the right place to ask though so likely someone does got something for ya
what smods version do you have
0301a
damn
have you tried without one
how do i update it
do i have to manually install from the hub
cuz i just used the mod manager to install
fixed it
does in_pool work for tarots? putting in_pool = false doesn't work
or does it have to be a function that just returns false?
a function yes
i was about to go to bed so it depends on how quick that is
so
i tried to do a hook for Card:open
and its telling me that self is nil
but i dont use self anywhere
show your code
local jimbos_special_sauce = Card.open
function Card:open()
local ret = jimbos_special_sauce()
if self.ability.kind == "jimbo" then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 2,
blocking = true,
func = (function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 4,
func = (function()
local Jimbo = Card_Character({x = 9.9, y = 2})
Jimbo:add_speech_bubble("cherrysmod_shuffle" ..math.random(1, 6), nil, {quip = true})
Jimbo:say_stuff(6)
return true
end)
}))
end)
}))
end
return ret
end```
oh thats self literally 4 lines in
fuck
change
function Card:open()```
to
Card.open = function(self)```
good evening everyone
that's the same thing
and then change
jimbos_special_sauce()```
to
```lua
jimbos_special_sauce(self)```
-# what do you mean by special sauce
is it actually? i thought it was different because you had to replace the function entirely
what did you update your code to
what you told me to
show it again
local jimbos_special_sauce = Card.open
Card.open = function(self)
local ret = jimbos_special_sauce(self)
if self.ability.kind == "jimbo" then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 2,
blocking = true,
func = (function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 4,
func = (function()
local Jimbo = Card_Character({x = 9.9, y = 2})
Jimbo:add_speech_bubble("cherrysmod_shuffle" ..math.random(1, 6), nil, {quip = true})
Jimbo:say_stuff(6)
return true
end)
}))
end)
}))
end
return ret
end```
oh what
wait
its working but its not doing none of the shit i told it to
i think you're missing return true in one of the events
in that case, is there any reason to change
Card.open = function(self)```
to
function Card:open()```
besides style choice?
when i replaced that with 1 == 1 it just froze
i dont think so
that's the return thing i think
Anyone’s got good examples of custom consumeables ? Bonus point for custom sets as well
what about .config.center.kind
never kill yourself!!!!!
nil
okay now how do I force ui nodes to be stretched out
minw
would i set that to the width of the parent node
I have yet to figure out the mysteries of localize
I really want to find a way to get Cats to give a gradually decreasing amount of chips cuz I had a banger joker idea but it requires cats to function in a specific way. If I can't get it to work, I might just scrap cats all together
thats a function ?
yes
what does it allow to do over loc_text and normal localization
localize is the function found in balatros'd deepest guts that actually handles variables and sometimes sets up UI nodes because why not
also whats the hand zone that the game uses when ur selecting a card from a pack
i was looking if there was something better
i think desc_from_rows uses filler?
i think it's just G.hand
Nah I thought G.pack_cards was right
no yeah i want the cards in the booster
the part where the planet cards show up when you open them for example
i want that
yeah G.pack_cards lol
i'm trying to make a joker with a very specific sprite size (i didn't do the art), what am i doing wrong? (it should theoretically look square, like how photograph does)
G.pack_cards.cards?
What exactly are you trying to do there?
also i did this and now it says pack_cards is a nil field
Whaat's your code
discord nitro is restricting me.
ill post it in halves
local jimbos_special_sauce = Card.open
Card.open = function(self)
local ret = jimbos_special_sauce(self)
if self.config.center.kind == "jimbo" then
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 2,
blocking = true,
func = (function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.1,
func = (function()
local Jimbo = Card_Character({x = 9.9, y = 2})
Jimbo:add_speech_bubble("cherrysmod_shuffle" ..math.random(1, 6), nil, {quip = true})
Jimbo:say_stuff(6)
return true
end)
}))
for _, v in pairs(G.pack_cards.cards) do
G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 3, func = (function()
v:flip()
play_sound("card1")
return true end)
}))
end```
local pitch = 0.5
local delay = 1.5
local extra_loops = 3
G.E_MANAGER:add_event(Event({
trigger = after,
delay = 0.7,
func = (function()
::jump::
if pitch ~= 1 then
G.E_MANAGER:add_event(Event({trigger = "before", delay = delay, func = (function()
G.pack_cards:shuffle('aajk'); play_sound('cardSlide1', pitch); return true
end)}))
pitch = pitch + 0.1
delay = delay - 0.1
goto jump
end
::justsomemore::
if extra_loops ~= 0 then
G.E_MANAGER:add_event(Event({trigger = "before", delay = delay, func = (function()
G.pack_cards:shuffle('aajk'); play_sound('cardSlide1', pitch); return true
end)}))
extra_loops = extra_loops - 1
goto justsomemore
end
return true end)
}))
return true end)
}))
end
end```
yippee!!!!
anything glaringly obviously wrong here?
No not off the top of my head
okay so
it MIGHT
MIGHT
have something to do with the game trying to process the ipairs statement before the cards actually ENTER G.pack_cards
is there a way to delay this whole bit of code somehow?
Oh the bongcloud opening, that's awesome
make the event trigger after?
shit uhhh wrong reply
does anyone know?
oh true
ok so i did that and then my game froze and then closed
Did you remember to return true in all of your events?
so uh, why is a skin mod crashing someone else’s game when it’s not crashing mine
Yeah
Want me to send my code again just in case?
Yeah since you've made your changes I could take a fresh look
this genuinely perplexes me because like
local jimbos_special_sauce = Card.open
Card.open = function(self)
local ret = jimbos_special_sauce(self)
if self.config.center.kind == "jimbo" then
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 2,
blocking = true,
func = (function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.1,
func = (function()
local Jimbo = Card_Character({x = 9.9, y = 2})
Jimbo:add_speech_bubble("cherrysmod_shuffle" ..math.random(1, 6), nil, {quip = true})
Jimbo:say_stuff(6)
return true
end)
}))
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 1.6,
func = (function()
for _, v in pairs(G.pack_cards) do
G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 3, func = (function()
v:flip()
play_sound("card1")
return true
end)
}))
end
return true end)
}))```
local pitch = 0.5
local delay = 1.5
local extra_loops = 3
G.E_MANAGER:add_event(Event({
trigger = after,
delay = 0.7,
func = (function()
::jump::
if pitch ~= 1 then
G.E_MANAGER:add_event(Event({trigger = "before", delay = delay, func = (function()
G.pack_cards:shuffle('aajk'); play_sound('cardSlide1', pitch); return true
end)}))
pitch = pitch + 0.1
delay = delay - 0.1
goto jump
end
::justsomemore::
if extra_loops ~= 0 then
G.E_MANAGER:add_event(Event({trigger = "before", delay = delay, func = (function()
G.pack_cards:shuffle('aajk'); play_sound('cardSlide1', pitch); return true
end)}))
extra_loops = extra_loops - 1
goto justsomemore
end
return true end)
}))
return true end)
}))
end
end```
and what step exactly is it freezing at?
at the pairs bit
how confusing
I'm assuming you've tried doing this with context.opening_booster before the hook?
not sure how to get context from a function that doesn't use it
i seem to have messed up the ordering a little bit lmao
are you suggesting i need to hook INTO context.opening_booster??
ignore the fact that they're all giving zero money
Oh right this isn't a joker, hm
it's ok im unhelpful with a lot of things
gang
somewhat approached what i want
kills you
explodes you with mind
hey @plush cove do you have any idea what the fuck i need to do with this
now I'm digging for source of the white description box because I have no need for that if anyone does please let me know digging through UI code vexes me
welp
im going to bed
whoever can make that bit of code work before tomorrow gets 1 dollar from my paypal /srs
how do i even
youre a magician
a literal coding magician
ive seen what you can do
this has got to be child's play
my letters stickers are not being scaled if i use card.T.x = card.T.x * scale
how do you draw a joker how legendaries are, with two layers?
Kinda. Two different sprites are needed, the base and the "soul" (the part that floats above the base)
use the "soul_pos" attribute. It takes coordinates just like "pos" and uses the same atlas
np
is it the same way for consumables? like soul but for planets or tarots too
Yep!
and i assume hologram does the same thing
Indeed it does
oh i guess undiscovered consumables do that too right?
Also yep
speaking of, how would i go about giving specific consumables a different undiscovered sprite?
or would i have to patch that
not a new type of consumable, just like a new tarot that i want to have a different undiscovered sprite
@sturdy compass do you have any idea why my shit doesn't scale
I think that's a patch thing
Wdym?
wtfart
i want to scale properly
I'm so bad at UI stuff so I have no clue ðŸ˜
NOT THE JUICE 
i gotta set up a github sometime
definitely if you're making a mod. Makes hosting releases that much easier
yeah i'm still way way prerelease but def gotta sometime
Even for pre-release, it just keeps the code safe in case something catastrophic happens. You just never know
true
what defines the different ways soul, hologram, legendaries, and undiscovered layers move? they all act differently
is there an easy way for a joker to check if jokers you have are vanilla?
That I’m unsure of unfortunately
i hate programming
i love when a steamodded update forces me to rewrite a bunch of shit
sorry
i need help
so i'm trying to make it so that this joker just gives me a discard at the end of every round
like lemme just paste the code
okay or not
so this code is what handles the discards and hands i get at the end of every round
there's this code that adds two to the end of round discards if you didn't discard this round
both of those are in the calculate function for the deck
here's the code for the drunkard that's supposed to just add 1 to the end of round boss discards
but it's really weird
because like
if no discard on boss: 2 discards from not discarding and 1 discard from drunkard = +3 discards, this works
if discard on boss: 1 discard from drunkard = +1 discards, but this doesn't work, it just doesn't do anything
so my theory is that the take_ownership stuff being in the apply function for the deck makes it so it doesn't get added to the calculate stuff properly
sorry for text wall i just needed to vent some frustration
I need reword suggestion.
Also, does eternal_compat only affect how they appear in shop, or would it be impossible to apply Eternal on a joker if its eternal_compat is false?
Hmm
Learning yet more things about lua
Im assuming that, by default, a Card's children sprites arent ordered (since they're named keys), so the order in which they're drawn is effectively random based on backend stuff
im trying to make this card convert all fours into an enhanement (like midas mask)
is the code right?
context.other_card doesn't refer to a card in the scoring hand, because you are in context.cardarea == G.jokers
context.other_card is used with context.individual and context.repetition and you are excluding those above
ohhhh
I would try if context.cardarea == G.play and context.before and context.individual and not context.blueprint
thats why it crashed
also if you use the code I provided, remove the loop over context.scoring_hand
and change v:set_ability and v:juice_up to context.other_card:set_ability and context.other_card:juice_up
bump
5% score requirement
earn $1 at end of round
payout increases by 1 every 5 rounds
sell this card to create a leveled up version
didnt see score requirement
if i were to be honest this seems a little complex
been toying a lot with "when score is burning" cards
ooh i've been thinking about making some jokers that do that
though never looked into how to actually detect when you're on fire
score goes on fire when your current mult * your current chips exceed or match the blind requirement
not counting the score you already have from previous hands
can you put custom consumables in the same collection category as, say, tarot cards?
"if you score more than the blind requirement in one hand" is prob better wording
Do you know any practical way to make a new suit?
SMODS.Suit
I have an idea for a hardcore mod of vanilla Balatro.
Each joker loses some of its parameters with each hand played.
Each joker has a chance to be destroyed after a hand is played and it increases with each hand played.
Each played card loses some of its parameters and also always has a chance to be destroyed and it increases with each hand played. 
Try comparing the target joker key and the vanilla key list?
All you need is a vanilla joker key table and the key of what you're going to check.
so id need to get the id of like all 150 jokers?
Usually jokers are from mods of format "j_mod_joker", and vanilla ones are of format "j_joker"
Maybe, they are all in the source code of Balatro
Or someone has already made such a table
if someone has that please share i do NOT want to look for all 150 ids just to make 1 joker suggestion lmao
In theory, you can simply check whether your joker matches the format "j_*_joker" and if not, consider it vanilla

And you don't even need a table of 150 jokers
@plain apex Maybe you need this?
not exactly sure how to check for that but i'll certainly try something with that
you should be able to check if the joker has joker.config.center.mod iirc
how to "exclude" certain tags from poll_tag ?
if anyone knows what the hell is going on please tell me thank you
Okay so, I dont really know how to work the blueprint parameters at all
first one is for the message to pop under the blueprint when it makes a burger
and the second one is for the burger itself, i want the blueprints to actually score, and say Nom as a message. (the basic blueprint compact stuff does work with things, but for these two cards its a lil buggy. the burger one, the first blueprints scores, and nothing else does and then the burger will say eaten! for the amount of blueprints)
dont use calc_effect unless you know what you're doing
ellaborate?
I think Eremel is trying to say that in 99% of usecases, SMODS.calculate_effect doesn't need to be used and returning a table works?
there's absolutely no need to use it here, and that's probably why blueprint is being weird
also there are assumptions that your joker will return a table on trigger
which might be the thing fucking with blueprint yeah
because it doesn't return anything blueprint doesn't think it has done anything
oh ive been using calc_effect for my message stuff since it seemed more simple from what ive been told ðŸ˜
in my experience, it's usually the other way around haha
you can just
return {
message = "Burger",
colour = G.C.DARK_EDITION
}
oki lemme see how that goes
but then the burger itself is a lil weird with blueprint
you need to add not context.blueprint to any parts you don't want to be replicated
so like, how would that look? i was the scoring to be on all, but the text Eaten to just be on the burger, and then Nom for the blueprints (because its funny) but like rn the scoring is messed up where it scores only once with a blueprint and nothing elseincluding the joker itself actually scores
well you're setting a flag that it's been scored and not allowing it to be scored more than once
your flag is entirely useless here apart from disallowing blueprint behaviours
is there not a context.blueprint
if you wanted a different message on the blueprints, you could do
if context.after and context.blueprint then
return { message crap here }
end
if context.after and not context.blueprint then
return { eaten message crap here}
end```
for when you want something to not activate on blueprint you just do not context.blueprint
oh it also happens on seals ðŸ˜
wtfff
Check the wiki but usually you can pass a table of objects you want
If the issue is Orbital Tag, Paperback has a fix
do you have 1x sprites in your 2x file or something?
I think you need to resize the sprites of the internal elements too iirc
i think calling set_sprite might just work
was fuckin around with the area and when i press 2 it looks proper
there
it might work too if you apply the letters after you've scaled the cards
it actually does work
do you plan to keep the red seals on the cards?
okay so the message in the middle i want it to display the Number, and it cases a crash.
in the past i had it say +1 +1 +1, but i would prefer it to say 1 2 3
yeah, it'll be type = joker iirc
ah
custom table would not work with modded tags
right?
it's a niche thing but still
poll_tag is a vanilla function right?
also dont mind the double layer of context eor and me, because a return caused issues, but i want the variable number to be listed and its causing crashes ðŸ˜
I know poll_edition for sure is
actually I don't think poll_tag is a thing
yeah
I don't remember what the function is called
get_next_tag or something like that iirc
in vanilla?
why would you ask for help using a function that you've created?
I have no idea what these functions do
No, I'm asking about if there's a way to exclude certain tags to be generated by X effect
And if there's a function for it
There's add_tag
But can I make it exclude certain tags?
Instead of creating a custom table of tags
So, I could maintain mod compat with modded tags
oh btw how do i lock cards so that they can't move
pinned pins it to the left
and it actually reversed my name ðŸ˜
pin them in the opposite order?
No, i mean, sprites
message = ''..card.ability.extra.entitytimer
it needs to be a string
oooh
It works if you use all Tags to create the table
But then how do I exclude certain tags from that table?
You go over the table and remove them
So you imply that I should make a table of all possible tags manually?
I mean such a table already exists, but you shouldn’t edit it directly. That’s basically what polling functions do anyways
Can you reroll a boss blind during it?
Probably
Anyone?
Your tab definition function doesn’t have anything in?
I don’t see how you could tell it to load something that doesn’t exist
But its the button thats crashing im pretty sure, but what can i put there just for testing
i went of the DNA code for this, but what my issue is, is that Its copying only one type of card instead of copying each. like if i play a flush of 5, 4, 3, 2 and A. i would get 5 4's
i tried making a variable to count up but it does it only once (hence the 4, instead of 5)
how would i make it count up for scored cards?
well played cards even
well i just made it able to go from 5 to 4, but then it stays 4 because i moved the +1 lmao
💸
Do you have the card area code on gh?
y
any ideas??
is there like a G variable for general scoring card position or something?
couldn't you just copy the context.other_card
dna
????????
what im mainly wanting is for it for each individual card to add one to the handplace variable but it seems it only does that once ver full hand
i think i am really stupid LMAO
you are my sunshine
@manic rune...
helo
That looks sick
it looks cool, but is there nothing else going on? :(
@wintry solar what if I want to use Blueprint effect but keep the original message colour?
i personally checked #1338302514616995892 for implementing card areas :3
-# What specifically
roy
In general or in an UI node?
well i put it back to what it was but then its only doing the handplace + 1 only once
In it*
What makes a food joker... a food joker?
In what sense
I don’t remember but aiko’s code is on GitHub
The thrill of development
Im pretty sure the onl thing there is a card_area_preview
Asking because I can't decide if "chanpagne tower" could be count as food or not.
Does it expire
DEVELOPMENT RESUMES TOMORROW
Hey Ocemu, you should add a check like this
if context.other_card and context.other_card:is...
YESYEYSEYES
Need to do it in that order too. First be sure that the item you are checking exists before you check it's properties
Niceeee
I haven't decide its effect yet.
So it depends on expiry?
aiko yori what though? Reminds me of hana yori dango
Like Cola and Popcorn and Luchador and Seltzer
what does this do?
Wait, Luchador is edible??? /jk
How can I get two different interactive variables in my Joker description?
are there any guides for setting up a development environment for Balatro mods?
Okay i got it fully working now :D
or like a github repo
just had to move the context.after outside the context.individual
you put in placeholders in your loc_txt and then pass them in using loc_vars, it's that simple! Be sure you don't reference vars that don't exist or the game will crash. There is like zero null-safety in Lua
Or you might say nil null-safety
I know about return {vars = {center.ability.extra.Xmult}} in loc_vars but what if I need both return {vars = {center.ability.extra.Xmult}} and return {vars = {G.GAME.probabilities.normal}}?
it actually isn't that sensitive
it only crashes if you try to use vars without any existing
return { vars = { card.ability.handsTillReady, card.ability.multBounty } }
You can put them in comma separated list
i do wish there was some kind of optional chaining built into lua
Another joker finished!
?
alright I'll check this out
-# bump
wtf???????
as for dev environment, i recommend having your full mods folder open in vs code or similar so that the LSP has access to definitions from steamodded
Jolly Joker
at least i got the thing working
oh.
(dont mind multiplayer error)
(my uni blocked balala multi)
oh it's Lua that's interesting
Me failing to configure the LSP: ðŸ˜
I thought Balatro would've been made with Unity (just had a feeling) but that makes sense since I've never seen the Unity intro when opening the game
you can disable it now i believe
is there any way to access the cards in the tarot area the same way you can access the jokers?
Then do it manually and don’t use the helper function
So I was looking at the texture files, (just recently started modding) wth is the weird looking deck next to plasma?
Any mods that use a simple card area
day 2 of trying to get this to work. if there are any code magicians in chat, i need your help. its freezing at the for _, v in pairs bit
have you tried debug printing what v is?
if you've been at it for 2 days, probably
G.pack_cards is a CardArea, not a list of cards
you'd want to iterate G.pack_cards.cards
Erratic?
I felt like Tens weren't getting a lot of love in box, so I decided to think about something...and I love progressive chip growth cards. Then I remembered someone with a connection with 'TEN', Akuma from street fighter
From there it was thinking about how to make it fit an animal theme
I'm doing good, ty
Any new stuff you're working on?
blind calculation mostly
no, smods doesn't really touch it
Now, what is jolly
i'm sure it can be added eventually but it's not a priority to document base game code
pairs
Do you know any mods that use card area
joyousspring 🙂
That are simple
😦
?
G.GAME.blind.in_blind
This scary math stuff...
What config does G.UIT.O need
Usually things are positioned starting from their top left point. If you want to find the center, you add half their height and width
Not exactly what’s happening here tho
{object = --[[some Node object here]]}
Would { object = nodes = {} work?
How would make it as big as one tarot card?
So, I know how to add the description of stuff like stone card and such next to my joker description. But how can I add a custom description next to my joker description?
i tried that and it said G.pack_cards was a nil table
Use the size of a card
then you're not in a booster pack
it's the area that you select cards from in a booster pack
so there's no need for it to exist when one isn't being opened
wha are you trying to do?
something something events inside events? 🤔
im trying to:
- detect when a certain type of pack is opened (done)
- spawn jimbo and have him say a custom quip (done)
- flip over selectable cards and shuffle them (NOT done)
won't work i think
i tried events inside events
show code
functions inside events
local jimbos_special_sauce = Card.open
Card.open = function(self)
local ret = jimbos_special_sauce(self)
if self.config.center.kind == "jimbo" then
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0,
blocking = true,
func = (function()
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 5,
func = (function()
local Jimbo = Card_Character({x = 9.9, y = 2})
Jimbo:add_speech_bubble("cherrysmod_shuffle" ..math.random(1, 6), nil, {quip = true})
Jimbo:say_stuff(6)
return true
end)
}))
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0,
func = (function()
for _, v in pairs(G.pack_cards.cards) do
G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 0.5, func = (function()
v:flip()
play_sound("card1")
return true
end)
}))
end
return true end)
}))```
local pitch = 0.5
local delay = 1.5
local extra_loops = 3
G.E_MANAGER:add_event(Event({
trigger = after,
delay = 0.7,
func = (function()
::jump::
if pitch ~= 1 then
G.E_MANAGER:add_event(Event({trigger = "before", delay = delay, func = (function()
G.pack_cards:shuffle('aajk'); play_sound('cardSlide1', pitch); return true
end)}))
pitch = pitch + 0.1
delay = delay - 0.1
goto jump
end
::justsomemore::
if extra_loops ~= 0 then
G.E_MANAGER:add_event(Event({trigger = "before", delay = delay, func = (function()
G.pack_cards:shuffle('aajk'); play_sound('cardSlide1', pitch); return true
end)}))
extra_loops = extra_loops - 1
goto justsomemore
end
return true end)
}))
return true end)
}))
end
return ret
end```
i had to send it in 2 messages because its too long

you can send as file but sure
oh right thats a thing
uhhhhh
getting freaky
maybe having cards debuff everything wasn't a good idea lmao
I’ve been thinking of creating an invisible auxiliary Joker to handle debuffing across all of time
Small Blind, Big Blind, Boss Blind, Packs
this works with a debuff context that takes advantage of can_calculate
I'm removing the can_calculate checks from functions called in eval_card as it prevents this kind of thing from working properly
What is eval_card doing?
can_calculate has an argument to ignore the debuff state
joker idea:
starts and stays insanely strong, but has a chance to end the run every time it triggers
eval_card calls a bunch of calculation functions and gathers the results
it calls can_calculate itself (conditionally with ignoring debuffs now), but the functions it calls were calling it again
recursive calling which would cause the game to lock up
which is not needed and just prevents debuffed cards from being calculated when they should, so I'm removing those checks
I feel like the individual checks are necessary but the starting one isn’t
still looking for help with either this UI issue or my undiscovered custom legendary joker description issue 
The point is that if a card becomes debuffed or is destroyed mid scoring
It stops being considered afterwards
The boolean value to ignore the debuff state should allow effects that can change it to proc
Unless the card for example has been destroyed
ðŸ˜
is there a difference between creating a custom joker via SMODS.Joker**()** and SMODS.Joker**{}**? 
no?
ok, making sure that that wasn't the culprit for my description issue
Lua handles foo{…} as foo({…})
i see
I see, but then shouldn't eval_card should be performing those checks instead of the functions themselves?
the point is I'm passing a flag to ignore debuffs by context, and not all of these functions receive context
Two things:
- At which point of the scoring process are we talking about?
- It’s possible that
can_calculateshould receive the context, or at least a table that may or may not include the context
How do I make a custom tooltip for my Joker?
As I said, if there’s a sequence of different effects applying, can_calculate should be used before trying to apply. Outside of Events, I think this should be handled automatically



