#💻・modding-dev
1 messages · Page 488 of 1
@manic rune i need jelp
hi
this @manic rune
let me send the code and explain it to you
And how can i do that? 🥲 Sorry if this is an dumb question the only thing im good at is changing the sound
vol = 1,
pitch = 1,
key = "music_spamton1",
path = "music_spamton1.ogg",
select_music_track = function()
return next(SMODS.find_card("j_silly_spambot")) and string.len(G.GAME.blind.name) > 0
end,
})```
isn't it an error from another mod rn?
this deck gives out negative tag
each round
but whenever i hover over a card
it shows that crash
might be related to stuff in love.draw
loc_vars = function(self,card,info_queue)
return{vars = {}}, --return stuff in here
end,
it works fine in a joker
that's really odd
check SMODS.Joker documentation, it has that
i dont think you are meant to put love objects to G.GAME
oh really?
damn
is there somewhere a list of card.ability. ?
other than looking at the code, no
what are you trying to find
vol = 1,
pitch = 1,
key = "music_spamton2",
path = "music_spamton2.ogg",
select_music_track = function()
return next(SMODS.find_card("j_silly_spambot")) and G.GAME.blind and G.GAME.blind:get_type() == 'Boss' = true
end,
})
I've got this Joker to be completely functional whenever its being played in a game but whenever I check it in the collection on the main menu it crashes. I was wondering if theres a way to just get it to display 0 in the collection while still functioning in a game.
= true, ffs... remove it...
how would i change this so that it can't buff itself, just the other jokers
Add a default value for the argument passed to math.floor, aka math.floor(x and y or z). You have the x and y part but not the z one
I tried adding "or 0" at the end there but it still crashed
Cus that is outside the math.floor call
The stuff inside math.floor is nil when G.playing_cards doesn't exist
And that's why it crashes
It expects a number
vol = 1,
pitch = 1,
key = "music_spamton1",
path = "music_spamton1.ogg",
select_music_track = function()
return next(SMODS.find_card("j_silly_spambot")) and string.len(G.GAME.blind.name) > 0 and not G.GAME.blind:get_type() == 'Boss'
end,
})
SMODS.Sound({
vol = 1,
pitch = 1,
key = "music_spamton2",
path = "music_spamton2.ogg",
select_music_track = function()
return next(SMODS.find_card("j_silly_spambot")) and G.GAME.blind and G.GAME.blind:get_type() == 'Boss'
end,
})
this is supposed to play the 1st music in small and big blinds, and the 2nd music is suppsoed to play in boos blinds. right now, this only plays the boss blind's music in boss blinds, and the default balatro music in small and big blinds.
why that happen?
In your first one not G.GAME.blind:get_type() == "Boss" remove not and replace == with ~=
What is kings id?
13
thx
For future. In vanilla it goes from 2 to 14 where 14 is an ace
thank you
well I run into another problem
I have this code that i frankensteined from what I could find
hate to be a bother but I'm getting a new crash report. do you know how to fix this?
It's propably wrong but what's most importantly it crashes the game
You put them in the wrong order
The "or 0" would come right before closing the first yellow parenthesis
I have no idea how to do this I just put together pieces from example jokers
Move the modify_rank line before the return
And inside the return you can put a message or something if you want
Also what is the crash
like this?
Oh I see, you are meant to pass context.other_card to modify_rank, not card
Sorry I meant after closing
That worked thank you so much!
Sorry but I don't understand
SMODS.modify_rank(context.other_card, -1)
Thx it works
#💻・modding-dev message
BUUUMMMP x3
Doesn't that just mean G.P_CENTER_POOLS.Ingredient doesn't exist
anyone has the card key for the soul spectral?
is there an achievement argument for buying a joker
Ok sorry for another question
but can I make it that queens turn into kings and kings turn into queens
the game is telling me that field is_poker_hand_visible is a nil value. anybody know why this is happening?
local _poker_hands = {}
for handname, _ in pairs(G.GAME.hands) do
if SMODS.is_poker_hand_visible(handname) and handname ~= card.ability.extra.poker_hand then --Returns nil for some reason
_poker_hands[#_poker_hands + 1] = handname
end
end
card.ability.extra.poker_hand = pseudorandom_element(_poker_hands, 'CosmicTomfoolery_warrior')
return {
message = localize('k_reset')
}
end```
update smods
You can use SMODS.change_base(context.other_card, nil, "Queen") for example
what are some good examples of mods that are simpler that use custom rarities so i can have a look at the code and see how its all done in more detail than looking at smods docs
Try using hanging chad with it
how can i detect if a boss blind has an A or S in it, and debuff it?
if so
in the localized name?
yes
i forgot vanilla remade also shows rarity code
plus would it work with modded ones too?
Is it possible to make it that it has like a little animation of card changing/text appear?
and for it to go card by card
localize{ type = "name_text", set = "Blind", key = G.GAME.blind.config.blind.key } gives you the name
detecting what letters it has should be an easy google search probably:3
does this only work with boss blinds?
its supposed to only work with boss blinds
yes but there's no easy function to do it, you need to check how the vanilla cards do the animations
(i recommend vanillaremade)
it works with any blind
check for boss blinds yourself beforehand
Your current way will repeatedly change the rank of a card if it's retriggered
where can i find it?
how do i prevent it?
thx
Using change_base instead of modify_rank
does anyone know how to remove those two lines on the borders? they aren't in any of my atlases :/
does anyone know how to fix the problem of a custom booster pack giving a custom consumable having a bunch of green particles like floating around the consumable for some reason? i think ive heard that this is a problem others have had and im wondering if a way to fix it has been found
key = 'crt',
loc_txt = {
name = '{C:purple}C{}{C:attention}R{}{C:purple}T{}',
text = {
'"Hey folks, looks like the censors ARE gonna kill me!"'
}
},
atlas = 'crt',
pos = {x = 0, y = 0},
rarity = 4,
cost = 8,
if G.GAME.blind and G.GAME.blind:get_type() == 'Boss' then
G.GAME.blind:disable()
message = 'Censored!'
end
}```
where's the calculate
also i recommend looking at chicot
chicot?
worked a charm, thank you!
nvm
key = 'crt',
loc_txt = {
name = '{C:purple}C{}{C:attention}R{}{C:purple}T{}',
text = {
'"Hey folks, looks like the censors ARE gonna kill me!"'
}
},
atlas = 'crt',
pos = {x = 0, y = 0},
rarity = 4,
cost = 8,
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint and context.blind.boss then
G.GAME.blind:disable()
message = 'Censored!'
end
}```
210 is the last line
Missing an end
yup
the message doesnt appear, is this easily fixable
key = 'crt',
loc_txt = {
name = '{C:purple}C{}{C:attention}R{}{C:purple}T{}',
text = {
'"Hey folks, looks like the censors ARE gonna kill me!"'
}
},
atlas = 'crt',
pos = {x = 0, y = 0},
rarity = 4,
cost = 8,
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint and context.blind.boss then
G.GAME.blind:disable()
message = 'Censored!'
end
end
}```
You're not returning it
mb again
Hi something
hold
key = 'crt',
loc_txt = {
name = '{C:red}C{}{C:attention}R{}{C:red}T{}',
text = {
'"Hey folks, looks like the censors ARE gonna kill me!"'
}
},
atlas = 'crt',
pos = {x = 0, y = 0},
rarity = 4,
cost = 8,
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint and context.blind.boss then
G.GAME.blind:disable()
return{
message = 'Censored!'
}
end
end
end,
}
what wrong now
You have an extra end
thanks you
Can i make it that it changes at the time the card is scored?
because now they do it instantly
I feel like half your problems would go away if you installed a Lua LSP
i did nerd
....guys where's the probability context guide they were talking about am i stupid
you have to use it too btw
In the release notes I believe
oh yeah there it is thanks lmao
Put it in an event.
And how do I do that?
And out of the return.
G.E_MANAGER:add_event(Event({
func = function()
-- code here
return true
end,
}))
And where in the code do I put it?
Outside of the return.
Ok and then I refer to it in the return?
No?
How do I get Balatro to ignore files with the .swp extension? I use vim and it creates swap files to save the buffer I'm working on, but starting Balatro with one of those present causes an immediate crash. I can disable swapfiles, but I'd rather find a way to keep them around.
Answer: add *.swp to .lovelyignore. Disregard. 🙂
key = 'crt',
loc_txt = {
name = '{C:red}C{}{C:attention}R{}{C:red}T{}',
text = {
'Reduces required scores by half, but has a 1 in 6 chance to crash the game'
}
},
atlas = 'crt',
pos = {x = 0, y = 0},
rarity = 4,
cost = 8,
config = { extra = {chance = 6}},
loc_vars = function(self, info_queue, center)
return { vars = { G.GAME.probabilities.normal, center.ability.extra.chance } }
end,
calculate = function(self, card, context)
if context.setting_blind then
if pseudorandom('crt') < (G.GAME.probabilities.normal / card.ability.extra.chance) then crashGame() end
return {
message = "Censored!"
}
end
end,
}```
why bug
How do I force a game save?
return { vars = { G.GAME.probabilities.normal, center.ability.extra.chance } }
replace with
return { vars = { G.GAME.probabilities.normal, center.ability and center.ability.extra and center.ability.extra.chance or 0 } }
actually 0 might not be the best value
what is the 0?
ok
my guess based on the error is that you're executing on an object without center.ability.extra
Is there a way to "claim ownership" of the shop, such that rerolling does something without the use of jokers?
save_run() iirc
worked 🙂 thank you
no, I would hook SMODS.calculate_context for that
or hook the function that does that
Can you elaborate any?
About what a hook is or why SMODS.calculate_context?
What a hook is
It's a way to attach functionality to functions that already exist basically
https://forums.kleientertainment.com/forums/topic/129557-tutorial-function-hooking-and-you/
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
here's an example of how i hook calculate_context https://github.com/nh6574/JoyousSpring/blob/c0a24f9ba7e75f51d8ec09f22f12329c7a837cca/src/effects.lua#L6
ignore the first if condition
So like this?
that's not hooking, that's overriding
local calculate_context_ref = SMODS.calculate_context
function SMODS.calculate_context(context, return_table)
-- your code before
local ret = calculate_context_ref(context, return_table)
-- your code after
return ret
end
from what N sent
I'm so confused, where is the hook actuall occuring?
maybe it's clearer now?
Not even a little bit
SMODS_calculate_context_ref(context, return_table) runs the original function and saves the return to ret
you're basically adding stuff to the original
You're saving what the function was before, then you're overriding the function, but making sure to use the reference to what the function was before inside, so you're essentially adding code to it
Ohhhhhhh
Does anyone know whats causing this crash?
Why are you calling add_round_eval_row in calc_dollar_bonus?
I was digging around in this channel seeing if anyone had the same problem as me and someone did so I tried doing what they did to see if it'd work
I'm trying to double eor cash
Yes, you don't need to call it.
it's.... it's beautiful.....
ok wait is mod_probability constant
like will it update the descriptions or
Where can I find documentation on the Balatro API?
like if i double the numerator, will the numerators of cards in descriptions automatically update accordingly?
as long as those cards use get_probability_vars for their localization would be my guess
do the basegame ones do that
If you mean on vanilla functions, there's almost none
Darn, okay.
What happens if multiple objects use fix_probability
the closest is this i think https://github.com/Steamodded/smods/tree/balatro-lsp/lsp_def/vanilla
i think it just applies the last one
Let's say I have a joker that makes all probabilities a 1 in 2 chance, like the example in the release, what happens if there's another joker that makes them all a 1 in 3, would it just be the order of the jokers in the cardarea
iirc it is from left to right like normal
would it just be this order then
yeah
And where do blinds come in
i think blinds are first? I was just gonna say that i would be nice to have the order of object calculations somewhere
the whole joker... contained within itself... damn you smods...
I'd modify the denominator instead of numerator when halving tbh
0.5 in 2 doesn't look as good as 1 in 4
and by halving i mean reducing in general
How would I make a text input that only accepts numbers?
true.... ok ok got it
For G.GAME[key:lower() .. '_mod'] where do I put the number to modify it by
G.GAME.key_mod = number
So I don't need to claim ownership of the rarities?
no
It's saying cannot be used as a statement
can i see the code
G.GAME.common_mod
also it's because you're missing the assignment (the = number part)
Can you jusst type it out, I don't feel like decrypting that rn
i did????
you gotta put in a bit of graft man
What am I supposed to assign to what
G.GAME.common_mod = 33550336
the number you want to that variable, like shown here
i do recommend brushing up on a bit of basic lua
I've been coding till 3 in the morning for a week now
What actually changed the weight htough?
There's nothhing to call that number.
it's a global that the game will later check when generating rarities
me too? don't ask for help if you don't want to actually code the thing in yourself
I just wanted what the full line was supposed to say bro
It's literally not that deep
I main Python, JavaScript and Rust, not Lua.
Hello modding of the dev
hi dilly
How are you N
🛌
im getting up
:(
Well I made this and it's crashing the game
I don't know how it should look
Log?
You need to put context.other_card in a local variable outside of the event I think.
Okay, so this is to test card destruction based functionality. I thought it would count down each time a card is destroyed, per card destroyed, but it only counts down when card destruction occurs, how can I fix this?
with this i have card as my ref_table but it doesnt work and when i eval .config.ref_table its nil
#context.removed is the amount of cards removed
is this using it in your own joker or with regular blueprint?
own joker
ughhh I kinda don't know how to do it
have you checked how vanilla remade does it, i think i dont use that
ill take a look rn
local other_card = context.other_card
colour = compatible and mix_colours(G.C.GREEN, G.C.JOKER_GREY, 0.8) or mix_colours(G.C.RED, G.C.JOKER_GREY this is from vre, what is 'compatible' reffering to in this case
it's a couple of lines up
the difference with regular blueprint is that it wont update as you drag it i think
I did it and it still crashes
Yes, you need to use other_card instead of context.other_card in the event.
ahh i see, i didnt know = can have and args
It works
Thanks a lot!
If I'm ownershipped into WOF for an unlock, but it's based off the base game one, which uses the old probability, do I have to change it?
Yes.
got it
btw if you need to check if it fails isnt it easier to hook one of the new functions now?
i dont trust take ownership
if i can do that i will
wait you said hook, that means i dont need a joker
which function is it
to the overrides file!
is there any better way to do this
pseudorandom("seed", min, max)
?
i remember someone saying that putting event in a G.GAME crashes the game
somehow
that'd just recurse forever and die x.x
oh no
you want to check if key == 'wheel_of_fortune' then do stuff end
context.main_eval now always equates to nil in ``context.joker_main` in newest smods release
it's been breaking all my damn jokers!!
you were never meant to use those two together
Can I make the message being send in this event, not after
oh no it doesn't like that
what is your goal?
because when i put it in return it plays after
and when i put it in the event it dosn't work
consecutive wheel fail counter that triggers an unlock at 3 in a row
previously done in an ownership but according to the update i shouldnt need to?
i assume there is some other command to send messages inside of those
put it in an SMODS.calculate_effect
I'm not sure on how to do the consecutive part, but you want to first get the return value of form(card, num, denom, key), then check if that is true or false to know whether the chance failed or not
or is that farm
as in farmer
well i have the consecutive part already
like i said this is just the ownership i had before but im converting it into the new update
which was it resetting with each success, and incrementing with each failure
key = 'spambot',
loc_txt = {
name = '{C:purple}Spam{}{C:money}bot{}',
text = {
'Earn {C:money}3 Kromer{} at the end of a blind - UPGRADE IN [(#2#/#3#)] ROUNDS!'
}
},
atlas = 'spambot',
pos = {x = 0, y = 0},
rarity = 2,
cost = 6,
config = { extra = { dollars = 3, round = 0, maxround = 6 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars, center.ability.extra.round, center.ability.extra.maxround}}
end,
calc_dollar_bonus = function(self, card)
return card.ability.extra.dollars
end
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint then
local _msg = "UPGRADE"
card.ability.extra.round = card.ability.extra.round + 1
if card.ability.extra.round >= card.ability.extra.maxround then
local _msg = "UPGRADED"
SMODS.destroy_cards(card)
end
end
end
}```
why bug?
that's more than a bug
i saw that but i have no idea about graphics so idk maybe
ok so this works but still it goes after the score message
you have a syntax error
please just use the lua extension, which willl tell you where it is
is there a way that it goes before the score
i am bro
nvm i fixed
turn it on 😭
it is on
anyway new bug
key = 'spambot',
loc_txt = {
name = '{C:purple}Spam{}{C:money}bot{}',
text = {
'Earn {C:money}3 Kromer{} at the end of a blind - UPGRADE IN [(#2#/#3#)] ROUNDS!'
}
},
atlas = 'spambot',
pos = {x = 0, y = 0},
rarity = 2,
cost = 6,
config = { extra = { dollars = 3, round = 0, maxround = 6 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars, center.ability.extra.round, center.ability.extra.maxround}}
end,
calc_dollar_bonus = function(self, card)
return card.ability.extra.dollars
end,
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint then
local _msg = "UPGRADE"
card.ability.extra.round = card.ability.extra.round + 1
if card.ability.extra.round >= card.ability.extra.maxround then
local _msg = "UPGRADED"
SMODS.destroy_cards(card)
end
end
end
}```
have you considered putting it before the score
i dont see any red squiggly lines bro
?
card
how
oh
whats your code
cus this time it's not a syntax error
oh my goodness gracious
i meant your formatting but
relatable
end
end
end
end
Dosn't change anything
the order is
The card is scored and at the same time changed
no like
in a separate event
still the same
can i see what you did
add a delay to the second event?
oh i didn't read up enough
ur good 👍
Now it just waits 1s before scoring and changing
Maybe it's because that it does both at the same time
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.5,
func = function()
-- code here
end
}))
?
on the second event
Yeah that's what I did
I think that might be the case
but I don't know how to change that
set blocking to false??
on which one?
better idea here's what i usually do for multiple events
why this batch of code no work?
if context.setting_blind and not context.blueprint then
do return{
message = 'UPGRADE'
} end
card.ability.extra.round = card.ability.extra.round + 1
if card.ability.extra.round >= card.ability.extra.maxround then
do return{
message = 'UPGRADED'
} end
SMODS.destroy_cards(card)
SMODS.add_card{ key = "j_silly_spambotNEO" }
end
end
end
}```
set the first to immediate and the others to after
MY LUA EXTENSION ISNT PICKING IT UP
did you try installing it
blehhhhh
what's not working
yes its installed
is it enabled
Ok now the chaning is after the scoring but message still waits for everything
it wont "upgrade"
potentially nightmarish question, how would one go about making an edition that cant be destroyed or disabled? if the "destroyed" part is too much mmaybe just the disabled part ackackackack
it's so weird
yes its enabled
why is there a do with no for
have you tried disabling and reeenabling it
Which extension did you install
the only thing it doesnt like is the ends
end
end
}```
key = 'spambot',
loc_txt = {
name = '{C:purple}Spam{}{C:money}bot{}',
text = { "Earn {C:money}3 Kromer{} at the end of a blind",
"UPGRADE IN [(#2#/#3#)] ROUNDS!"},},
atlas = 'spambot',
pos = {x = 0, y = 0},
rarity = 2,
cost = 6,
config = { extra = { dollars = 3, round = 0, maxround = 6 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars, card.ability.extra.round, card.ability.extra.maxround}}
end,
calc_dollar_bonus = function(self, card)
return card.ability.extra.dollars
end,
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint then
return{
message = 'UPGRADE'
} end
card.ability.extra.round = card.ability.extra.round + 1
if card.ability.extra.round >= card.ability.extra.maxround then
return{
message = 'UPGRADED'
} end
SMODS.destroy_cards(card)
SMODS.add_card{ key = "j_silly_spambotNEO" }
end
end
end
}```
You have two extra ends
where
the last two
Is there maybe any other way to send a message in event?
Also, once you have no more red underlines, right click anywhere on the text and click "format document", it will make it so much easier to read
and you will see that your code is not doing what you want it to do, cus you have stuff all over the place
dude i forgot about format document i need to do that
did the trigger params not work for you
I recommend setting format on save
it's a vscode setting
i know mr. Something im sleep deprived.
As I said the message is sending but only after the entire hand is finished
it like goes on the end of the queue no matter what
yeah i remembered dw
for the debuff part you can do SMODS.debuff_card(card, 'prevent_debuff', 'source') in on_apply (and remove it on on_remove)
for the destruction part maybe you can use the new context for non-playing cards, i don't know for playing cards
Cus calculate_effect with a message already sends an event
so what should i do
Did you already try putting the modify_rank in an event, and the message in a return after the event
Yeah that does the same thing
theyre trying to have the message before the modify btw
jic
before or at least at the same time
forgot to check this with you btw
why the hell is ui so confusing here 😭
try
SMODS.calculate_effect({ message = "whatever", immediate = true }, card)
assert(SMODS.modify_rank(other_card, -1))
MAC USER SPOTTED
mac is the default for the screenshot plugin
you're meant to call farm before the check, otherwise you're removing all probabilities for anything but wheel of fortune
you can't tell me this is understandable
on first glance
well to be fair, most modders won't go straight into UI work when they make their first mod
I think it's fair to trust that anyone reading UI documentation is willing to thug it out
Still the same thing
it goes after the hand finishes
Okay maybe you shouldn't use context.individual then
That is for doing something whenever a card scores
well i can't say no to that
Well i wanted the effect to only apply to cards that scored
though i wish i had a second monitor to make myself a cheat sheet
most modders won't go straight into UI work when they make their first mod
uhhhhh
you can still do that without individual
so what should be there
oh god that'd be horrible
but that's it right (pretend it's local in the ss and that i didnt forget to put it there)
Depends on what you want it to do exactly, do you want to modify the cards before the hand is played, after the hand is played, do you want the rank changes to take effect for the hand they're being played on
Ok so it should go like that
looks right to me
You play a hand, the cards change and message is sent at the same time, they get scored
what did i do 💔
They can also change after they get scored
the main problem here is that message is desynchronized from the change
make people trapped in the worse ecosystem mad ig?
local other_card = context.other_card
if context.individual and context.cardarea == G.play then
if context.other_card:get_id() == 13 or context.other_card:get_id() == 12 then
if context.other_card:get_id() == 13 then
G.E_MANAGER:add_event(Event({
func = function()
SMODS.calculate_effect({ message = "test" }, card)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 1,
func = function()
SMODS.modify_rank(other_card, -1)
return true
end,
}))
return
{
}
else
G.E_MANAGER:add_event(Event({
func = function()
SMODS.calculate_effect({ message = "test" }, card)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 1,
func = function()
SMODS.modify_rank(other_card, 1)
return true
end,
}))
return
{
}
end
end
end
end
}
use windows
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
local other_card = context.other_card
if context.other_card:get_id() == 13 or context.other_card:get_id() == 12 then
if context.other_card:get_id() == 13 then
G.E_MANAGER:add_event(Event({
func = function()
SMODS.modify_rank(other_card, -1)
return true
end,
}))
return {
message = "boop"
}
else
G.E_MANAGER:add_event(Event({
func = function()
SMODS.modify_rank(other_card, 1)
return true
end,
}))
return {
message = "boop 2"
}
end
end
end
end
well, this works perfectly fine by me
whats the difference between parts._2 and parts._all_pairs?
how to add waiting in code
yknow like the usual wait() command?
it doesnt seem to work here
delay(seconds)
should this work?
well, the literal one would be love.timer.sleep(1) that's in seconds, but that will freeze your entire game for a second, you want to use delay(seconds) alongside an event
im not sure since it uses G.P_CENTERS[card]
no, the 2nd one needs to be a card, not a center
so this code spawns 20 spambot neos when the regular card is spawned in the middle of a blind, so how do i fix this
key = 'spambot',
loc_txt = {
name = '{C:purple}Spam{}{C:money}bot{}',
text = { "Earn {C:money}3 Kromer{} at the end of a blind",
"UPGRADE IN [(#2#/#3#)] ROUNDS!" }, },
atlas = 'spambot',
pos = { x = 0, y = 0 },
rarity = 2,
cost = 6,
config = { extra = { dollars = 3, round = 0, maxround = 6 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars, card.ability.extra.round, card.ability.extra.maxround } }
end,
calc_dollar_bonus = function(self, card)
return card.ability.extra.dollars
end,
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint then
return {
message = 'UPGRADE'
}
end
card.ability.extra.round = card.ability.extra.round + 1
if card.ability.extra.round >= card.ability.extra.maxround then
return {
message = 'UPGRADED'
}
end
SMODS.destroy_cards(card)
SMODS.add_card { key = "j_silly_spambotNEO" }
delay(2)
end
}```
Right click your code and click "format document" and you will see that your add_card and destroy_cards are all outside of the if statements
do u know the table where all the jokers are held?
The jokers the player has at the time?
alll jokers that are loaded into the game
What is the goal?
G.P_CENTERS is where they're loaded, but they're not jokers yet
They're just the skeleton of a future to be joker
G.P_CENTER_POOLS.Joker
Well I added a 1s delay to the event and made blocking false and it looks good
thx for all the help
glad to hear
would this work? i see tons of squiggly lines, but...
key = 'spambot',
loc_txt = {
name = '{C:purple}Spam{}{C:money}bot{}',
text = { "Earn {C:money}3 Kromer{} at the end of a blind",
"UPGRADE IN [(#2#/#3#)] ROUNDS!" }, },
atlas = 'spambot',
pos = { x = 0, y = 0 },
rarity = 2,
cost = 6,
config = { extra = { dollars = 3, round = 0, maxround = 6 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars, card.ability.extra.round, card.ability.extra.maxround } }
end,
calc_dollar_bonus = function(self, card)
return card.ability.extra.dollars
end,
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint then
return {
message = 'UPGRADE'
} end
card.ability.extra.round = card.ability.extra.round + 1
end
if card.ability.extra.round >= card.ability.extra.maxround then
do return {
message = 'UPGRADED'
} end end
SMODS.destroy_cards(card)
SMODS.add_card { key = "j_silly_spambotNEO" }
delay(2)
end
end
}```
no, if you see squiggly lines your game will not launch
so why wont it work?
you probably want something like this
calculate = function(self, card, context)
if context.setting_blind and not context.blueprint then
card.ability.extra.round = card.ability.extra.round + 1
if card.ability.extra.round >= card.ability.extra.maxround then
SMODS.destroy_cards(card)
SMODS.add_card { key = "j_silly_spambotNEO" }
delay(2)
return
end
return {
message = 'UPGRADED'
}
end
end
🥄
thank you kind soul
bump
so with pseudorandom_element gone, how would something like perkeo work?
that function is not gone
the new probability stuff doesn't affect how you'd use that one
i can just leave that alone then awesome
how would i implement pseudorandom to a sound function
and context.main_eval
thanks
now its not spawning
Is this a joker?
a deck
with the new probability changes, is there a way to specifically make only lucky cards have a higher probability?
Yes
Yes.
(for a joker that increases lucky card odds by 1 every time one succeeds)
resets at end of round obviously
You can check if a roll is being performed on a lucky card by either checking context.identifier or context.trigger_obj
ah, okay i figured but wasn't sure if they were that specific
I’d say go for trigger_obj since there are technically two identifiers for lucky cards
i assume lucky cards were patched to use smods probabilities
oh yeah, mult and dollars?
Yup
sick, will try it out later
bump
am i able to make the game speed faster than it should be when a joker is held?
Yes.
gulp
its a matter of changing a single variable really
one of my terrible commons literally just makes the game faster and thats all it does
try this
context.end_of_round
and not context.blueprint
and not context.repetition
and not context.individual```
on it
i mean if its for a deck i dont think you need not context.blueprint but it shouldnt break stuff either
just in case
Parakmi and Freedom
whats the context for
discarding a hand and selecting a card
context.pre_discard and that doesn't exist.
you could make your own selecting context pretty easily tbf
for example?
Hook Card:highlight() I think.
local highlight_ref = Card.highlight
function Card:highlight(is_highlighted)
SMODS.calculate_context{card_selected = true, highlighted = is_highlighted, card = self}
return highlight_ref(self, is_highlighted) --idk if this returns better to be safe ig though
end```
oops typo
you can really do this type of stuff for anything you want tbh
i have various custom contexts
anything?
basically
is this correctly making lucky cards have +1 higher odds every time one triggers? it seems so but chance can be so finnicky that i really wanna make sure it looks right to other people
No, you need to return the numerator.
shit, you're right
local highlight_ref = Card.highlight
function Card:highlight(is_highlighted, ...)
SMODS.calculate_context{card_selected = true, highlighted = is_highlighted, card = self}
return highlight_ref(self, is_highlighted, ...) --idk if this returns better to be safe ig though
end
Max compatibility
that too
i was going to but i couldnt think of a purpose for more vars here
and generally you want to avoid more vars in general
since if multiple people do it then stuff breaks
It's you think, but some guy theoretically can add own thing
well yes not breaking if someone does something weird is better
but i dont think every weird decision should be accomodated
Who knows what cryptoposting guy will add tomorrow
its just really easy to do so here
Okay, other case. When vanilla game will be updated and LocalThunk himself decide add smth to it?
i dont think thats gonna happen here
i have a pretty good feeling its not gonna happen here
But you have a lot more places patched like this. There's probability that in one of them somth will be added
So be better just be ready for unexpected things
Imagine debugging this kind of issue
any ideas why are they unused all of the sudden
If you can prevent issue theoretically, why not
Because you're not using them?
how could a blind modify probabilities with the new system? this is what i previously had for a blind that set all odds to 0:
i used all of them
whats the best way to apply an edition to all selected cards? (i actually need just 3 but i can do that part myself)
if you add any args to a function im getting you in real life
loop through G.hand.highlighted and use set_edition on each
args being unused isn't an issue
oh
not you
oh that scacres the fuck out of me
those named objects are just variables with set names that are used in the function
@limber blaze game crashed btw
i see
Use context.fix_probability
whats the crash message
hold on
blinds don't have context..?
ohhhh you're right
i was gonna say youre quite silly
i forgor
everyone has contexts
nuh uh, i disabled them for me
D:
SMODS.calculate_context = function() end
hi N 👉 👈

hewwo
hey folks
how are you
is anime epic rn or are you not viewing
modding chat only ever has an aneurysm
Nowadays it just feel horrible..
ive always considered it very hectic, its why most of my messages are in here even if not specifically dev related
Maybe I should make my own collection of UI components for all needs to make life others easier?

civil war before Talisman 2 is crazy
i was watching space battleship yamato but mom said i needed to do homework 🙄 (i need to finish a uni project for tomorrow)
im sure nobody would tell you to perish over a easier ui way of things
i have several uni things due tomorrow as well as finals at the end of the week and im doing nothing
lets goo
ive decided i will fuck it we ball
I'm feels pretty confident with UI rn
more power to you then
how do you check what edition a card has?
card.edition.key
thank you!
you shouldn't need type = variable. I have a variable tooltip that doesn't require that
It's possible your Credits set isn't being parsed by default
You will want to put it inside the Other set if you don't wanna mess with that
okay, so, i have this bit of code for repetitions on a certain card edition, but the problem is that the game crashes if a card without an edition is played because its trying to index a nil value on the second line here
if context.repetition and context.cardarea == G.play and context.other_card.edition.key == 'e_votd_indis' then
return {
repetitions = card.ability.extra.repetitions
}
end
end,```
how would i go about fixing this?
(context.other_card.edition or {}).key this will give you a default value for the edition if it doesn't exist
got it, thank you!
does SMODS.smart_level_up_hand accept negative values for its amount argument, or do I need to call a different function to decrease the level of a poker hand
it will work
ok thanks

guys
Is there a list of sound IDs?
i was going to ask to ask but i remember what i saw
so
i'll just give some context
i have a mod with 9 jokers
8 if you exclude blank joker, as it has a placeholder effect
but what matters is that
when i exported the mod
and put it in the mods folder
when i checked
there were only 4 jokers
the shining light, face joker, drawn joker and bidirectionality
are they all in the same file?
basically everything in the game is in the same file
the 'main' file
except the core stuff and assets
what do you mean "core stuff"
Yes, resources/sounds in the extracted exe
the json
were you able to successfully playtest them? like does the problem only occur after you export?
what
did you ever see the Jokers in-game
This error pops up when I check my deck ingame. Short error: src in steammoded attempts to index a null value
Any insights?
Soooo, was there ever a time where you saw all 9 jokers ingame
no
could you send the code for one of the Jokers that isn't appearing
just one?
or the entire main file if possible
either works
but if there's a problem with one it might be wrong with all of them (that aren't appearing)
How do I detect if a Joker is being viewed in shop/in joker slots vs the collection?
Try updating SMODS to the latest release
As well as your mods
give me some time
I'll give it a shot.
if card.area.config.collection then for collection
if card.area.config.type == 'shop' then for shop
thank you
as for jokers slots if card.area == G.jokers then
if you're trying to send the file, sometimes the file size is too large for Discord
mad annoying
that's also why I suggested just sending the code for one of the Jokers, if you can't figure out how to send the file
is 14.753 too large?
KB?
just send the code for one of them dog
my guess is that if we find a problem with one it will exist in the others as well
name = "Mega Joker",
key = "unknown_joker",
config = {
extra = {
Xmult = 4
}
},
loc_txt = {
['name'] = 'Mega Joker',
['text'] = {
[1] = '{X:mult,C:white}x4{} Mult.'
}
},
pos = {
x = 1,
y = 0
},
cost = 6,
rarity = 3,
blueprint_compat = true,
eternal_compat = true,
unlocked = true,
discovered = true,
atlas = 'CustomJokers',
soul_pos = {
x = 2,
y = 0
},
loc_vars = function(self, info_queue, card)
return {vars = {}}
end,
calculate = function(self, card, context)
if context.cardarea == G.jokers and context.joker_main then
return {
Xmult = card.ability.extra.Xmult
}
end
end
}```
wait
why is it called 'unknown_joker'
nevermind.
i found out.
EVERY JOKER THAT DOESN'T APPEAR IS CALLED 'unknown_joker'
BECAUSE THE MOD CREATING ENGINE GOT AN UPDATE
easy fix at least
and i was skeptical on how only the jokers i've altered were there
including the shining light, for some reason
now i know why
this could've been avoided if i was more attentional but thanks anyways
how would i have a card apply eternal to itself?
card:set_eternal(true)
This thing seems to be ticking down(?) when I select a card instead of when cards are destroyed?
I'm dumb asl yall I basically copied the counting part from Jazzercise and I still fucked it up
cus you're changing the count when it's every context except remove_playing_cards
change else to elseif and give it a condition
local hands = {}
for k, v in ipairs(G.GAME.hands) do
if v.visible then
table.insert(hands, k)
end
end
for i = 1, 4 do -- The D8 picks 4 hands to change
local index = math.random(1, #hands)
SMODS.smart_level_up_hand(card, hands[index], false, math.random(-2, 2))
table.remove(hands, index)
end
my CS professors are gonna be dissapointed in me
I just wanna pick 4 random hands with no duplicates, only allowing the discovered hands (so no Flush Five, Flush House, or Five of a Kind if they aren't visible)
like genuinely I'm still trying to learn lua as I go, so ik this is gonna sound dumb, but I don't know how it's every context except the one I want?
because else means "in every scenario except this one"
basically, unless the first condition passes, the else will run
Firstly, use SMODS.is_poker_hand_visible, Secondly, use pseudorandom_element and pseudorandom
Also have you tried looking at Immolate?
I was using pseudorandom element before, but I don't want duplicates, and modifying the table by removing elements after they are chosen sounds like a bad idea
pseudorandom and math.random are the exact same except pseudorandom takes a seed.
pseudorandom_element could potentially choose the same thing twice in a row if it's not removed from the table. I'm assuming you mean pseudorandom_element(G.GAME.hands) and I don't want to be removing elements from that
pseudorandom_element returns the index as the second output.
And no, I don't mean that.
I am trying to take ownership of bunco's stakes so that they come after my own "persimmon stake" and before gold, but for some reason, come after ruby stake (originated in the new balanced cryptid branch) despite it not being specified. Is there some missing steps to this or are bunco's stakes just that bugged?
(yes iam using the jimbocarrot branch)
local hands = {}
for k, v in ipairs(G.GAME.hands) do
if SMODS.is_poker_hand_visible(k) then
table.insert(hands, k)
end
end
for i = 1, 4 do -- The D8 picks 4 hands to change
local _, index = pseudorandom_element(hands, reroll_type)
SMODS.smart_level_up_hand(card, hands[index], false, math.random(-2, 2))
table.remove(hands, index)
end
still isn't working properly
reroll_type is the seed, yes it is a string
if context.after and G.GAME.chips < G.GAME.blind.chips
Why does this activate even when the hand is about to win? Check for remaining hands removed for clarity.
because context.after happens before the score is directly updated
context.before, context.individual and context.after all happen for hand scoring, and only after then is the hand score added to your round score
so you need to use a context outside hand scoring
or I think you can get the current score
and add it to the round score
and check for that
How do I get the hand score?
either check hand_chips * mult or do whatever you need in context.final_scoring_step
I'm actually going insane
G.GAME.hands can't be indexed by number? like what? why
Did you look at Immolate?
YES
Even though the stakes are applied in order in game, the display is completely wack (and going into stake view hard crashes the game)
I'm honestly unsure on how to fix it or is there no way to fix it?
Code?
it looks terrible rn bc I'm debugging:
local hands = {}
print(G.GAME.hands[1])
for i = 1, #G.GAME.hands do
print("REACHED")
if G.GAME.hands[i].visible then
table.insert(hands, #hands + 1, G.GAME.hands[i])
end
end
pseudoshuffle(hands, pseudoseed(reroll_type))
print(hands)
for i = 1, 4 do -- The D8 picks 4 hands to change
-- SMODS.smart_level_up_hand(card, hands[i], false, math.random(-2, 2))
end
line 2 prints nil
Yes, G.GAME.hands is key indexed.
I'm just trying to copy the contents of the table but the table is always empty bc apparently you can't index G.GAME.hands by number
Also you should be using SMODS.is_poker_hand_visible
well earlier I tried this:
for k, v in ipairs(G.GAME.hands) do
print(k)
print(v)
if SMODS.is_poker_hand_visible(k) then
table.insert(hands, #hands + 1, k)
end
end
and it never even reached the prints
Yes, you need to use pairs
uh no thats just how it works
ipairs iterates using integer keys
I understand that, I was just frustrated
Lua is new to me and iteration through arrays/lists/tables in other languages almost always works with integers. It just kinda annoys me that Lua makes no distinction between arrays and maps like Java or Python does
rounb
What would be the easiest way to give an upgraded version of a vanilla joker? I guess I'd need to get 1. Get the id of the joker to be upgraded, and then 2. Give a joker with the corresponding "upgraded" id. I just cannot think of how to connect the two right now, and I don't know if what I'm saying even makes sense.
if you don't want to create a whole new card, you could modify the Joker's existing config
Like make Jimbo give +6 instead of +4 or something
It's going to be a whole new card.
Have a table that is like ```lua
local upgrades = {
["originalkey"] = "newkey"
}
you could copy the code of Invis Joker, how it becomes a new card, but it also modifies the card's existing config to be upgraded however you want it to be
No, you would do card:set_ability("newkey")
And get the key by using card.config.center.key
I'll have to come back to this in the morning, I'm far too tired for this.
i changed my code to be a bit simpler and talisman is still refusing to cooperate
SMODS.Joker {
key = "tea_green",
config = { extra = { xmult = 4 } },
rarity = "kls_lingo",
atlas = "Jokers",
blueprint_compat = true,
pos = { x = 2, y = 3 },
cost = 7,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.xmult }}
end,
calculate = function(self, card, context)
if context.joker_main and card.area == G.jokers then
if G.jokers.cards[1] == card then
return {
xmult = { card.ability.extra.xmult }
}
end
end
end
}
it still says attempt to compare number with table
i feel like it's the G.jokers.cards[1] == card somehow. not working. but that isn't a very talisman thing
I’m running into a new problem.
Did you start a new run with your joker
yes
Which line is the crash on?
let me check
Oh wait
No, it should be xmult = card.ability.extra.xmult
without the {} around it
what's the usecase to check if a card is a certain rank?
are you asking how you'd do that, or why anyone would do that
how i'd do that
like i need the if statement
other_card:get_id() == 7 to check for 7s for example
Code?
to check if the card is in a played hand and scoring, should i do if context.cardarea == G.play and other_card:get_id() == "rank" then?
Remove the sounds/ from the paths.
not quite, what do you want to do exactly?
i want to check if a played card is of a certain rank so i can give it an effect (for example, idk, jacks give +11 mult)
No, it would be if context.individual and context.cardarea == G.play and context.other_card:get_id() == rankid
ah i see, many thankses
I recommend looking at https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua for how to implement any joker that has similar behaviour to an existing vanilla joker
you can just ctrl + f for their name
thats what i do lmao
though i didn't quite see a joker like that
i think 8 ball could've worked idk
Am I also supposed to rename them as jokerprefix_sfxname instead of just sfxname?
but still many thankses
scholar or fibonacci is pretty similar
how do i make a joker that checks for multiple ranks contained in a hand
No, it's modprefix_key
as in like if hand contains [multiple specific ranks], do [this]
Oh
i can't think of any vanilla jokers that do anything similar
local ranks = {}
for k, v in pairs(context.scoring_hand) do
ranks[v:get_id()] = true
end
if ranks[1] and ranks[2] and ranks[3] then -- replace these with the ids of the ranks
-- do things
end
```?
gimme a sec to unpack this i still cannot get over lua for loops
i recommend first thinking when you want your effect to happen
that will define which context you use
nah that was directed to you
would this bit of text work? i have a local variable named "rank" that changes at end of round and a table with the names of the ranks
oh
im afraid it wouldn't work because of the formatting of the text (the attention color starts at one bit and ends at another)
depends on where you defined rank and Ranks
tho generally you want to use loc_vars for passing variables to your localized text
Is it possible to just add eternal to a joker in SMODS.Back?
and here, rank is outside of the quotations
why can't i send "message.txt"
yes
it can be through calculate or that uhhh function that runs at the start of the run
-# never made decks before so idk
if rank is defined inside loc_vars then yeah, this won't work
so, do i put it outside or inside loc_vars?
the table is outside of smods.joker entirely, so im assuming i should also do so?
for the variable, i mean
it won't update dynamically if you do that
you need to return it from the loc_vars function for it to not be a static piece of text
help
im assuming this wont work because, once again, the text is not inside quotations
So in your loc_txt you have can have #1#, which corresponds to the first variable returned from loc_vars, like so
return {
vars = {
"some text 1", -- #1#
"some text 2", -- #2#
-- and so on
}
}
(i should probably find a way to put it inside quotations)
you want everything in quotations, so just remove the concatenation and just put Played {C:attention}#2#s{} give... and in loc_vars do
return {
vars = { "whatever", rank[Ranks] }
}
``` for example
oh, okay!
so, i can define rank outside of the table, and all i gotta do is reference it in loc_vars, correct?
yeah, you can
thanks you! ill test it out
this is really important to know cause i deadass thought you could only define thigns in loc_vars inside of the config extra table
okay so it said "attempt to index global 'rank' (a number value)" so what should i do in this scenario
What is rank and what is Ranks?
that means your rank variable that you defined is a number, and you're treating it as if it was a table when doing rank[Ranks]
wait did i swap them out
lmaoo
its normally table[value] right
or am i mistaken
No, it's table[index]
thanks yall
my bad, my bad
i keep forgetting the obvious distinction from v and i lmao
is there a variable to count the number of scoring cards played before they are scored?
#G.play.cards
is that the whole hand or just the scoring cards
the whole hand
#context.scoring_hand
What's the context to detect debuff
uhhhh
in a card's remove_from_deck you can check if from_debuff and run code when that happens
i don't know if that's exactly what you wanted
The card itself being debuffed or any card?
The playing cards
Hook Card:set_debuff
Does that detect if the playing card is debuff or make it debuff
It makes a card debuffed, and that's why hooking it can be used to detect that.
what's the variable for the round counter? i can't find it in G.GAME.round_resets so idk where it is
oh lmao it's just G.GAME.round
is it possible for a joker to have 2 separate sounds in 1 return?
how tho
heres my code
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
local c = context.other_card
local is_last_card = c == G.play.cards[#G.play.cards]
local sound = "tngt_birdthatihate"
return {
xmult = 2,
focus = context.other_card,
mult_mod = card.ability.extra.mult,
message = localize{type='variable',key='a_mult',vars={card.ability.extra.mult}} or is_last_card and "T H A T F U C K I N ' B I R D T H A T I H A T E." or nil,
sound = sound or is_last_card and "tngt_thatFUCKINbirdthatihate" or "tngt_birdthatihate",
colour = G.C.RED
}
end
end
}
return {
sound = "sound1"
extra = {
sound = "sound2"
}
}
Ohhhhhhh
I don't know why, if I remove context.individual it says
[SMODS grinrot "src/jokers/voodoo.lua"]:30: attempt to index field 'other_card' (a nil value)
Yes, because context.other_card doesn't exist in every context.
Don't remove it.
But context.individual makes it so that the joker triggers triple_chip_gain on each played card
What is the goal?
Gains +6 Chips for played 6s, exactly 3 6s gains +36 Chips
And currently if I play a Three of a Kind of 6s it adds 108 chips to the joker
what does #1# mean?
i saw people putting it on descriptions
my jokers don't have that and the text doesn't change
like i know it's probably the variable thingy
but, what exactly, is it?
Then you would do context.before and iterate over the played hand.
i am a bit confused
ok so
loc_vars is an area inside of an object
it does 2 things
- send info_queues i'll come back to those
- return a
varstable
any variable in the vars table is sent to joker's descriptions
they are referred to using #1#, #2#, #3#, and the number is their index in vars
so if i do
return {
vars = {card.ability.mult}
}
for example, the joker's mult value will be sent to #1#
i'll check for a mention of loc_vars in the main file
nevermind
the 'main file' was expurgated
now the jokers have individual .lua files
the loc vars area also allows you to use info queues
you know those little tooltips that show up when you hover over a card that mentiosn another card
like how the chariot tarot has a tooltip teaching you about steel cards
yeah that's what that is
you can add custom info queues or those of other game objects
yeah ok so you need to do this during a context that isn't context.individual
context.indivdual iterates over every scored card and runs on every card
context.before is better here, this happens 1 time before the hand is scored, but after the hand has been played
you then have to iterate through the played hand with either G.play.cards (all played cards) or context.scoring_hand (scored cards only) to check the ranks of each card
for index, value in ipairs(G.play.cards do
inside this loop, value is the currently checked card, and index is its position
how does number format work
Have you tried making it a function?
it was initially a function yeah
i tried with both approaches
im pretty sure theres no difference, since
works the exact same
Is it possible to destroy cards after the hand is denied? (Like when youre playing against the mouth and it debuffs your hand / rejects it)
how do i hook into the shop pricing
Hook Card:set_cost()
Yes.
thanks
I tried a destroy_card context afterwards but it only gets rid of the cards, doesn't destroy them
im using context.debuff_hand; but I've tried adding a context.destroy_card as well but it doesn't really recognize it
i also tried remove = true after debuff = true but same thing
Yes, you need to hook Blind:debuff_hand
i should also mention its within a joker
i might just rethink my effect because I wanted to avoid hooking into it ^^;
local oldblinddebuffhand = Blind.debuff_hand
function Blind:debuff_hand(cards, hand, handname, check)
local g = oldblinddebuffhand(self, cards, hand, handname, check)
if g then
for k, v in pairs(G.play.cards) do
v:start_dissolve()
end
end
return g
end
```?
just gives me a "function arguments expected near function"
I fixed the code.
lemme try
i was testing out my other hook
i have a hook into debuff_hand from a different card in my mod so I was going to use some parts of it for this effect
thank you for the help! there's still a couple quirks i have to fix in the hook (some conditions for the effect) but it works
Does it create ghost cards?
yep
fixed
Code?
-# if it work, it works
But it doesn't work?
yeah it doesnt work thats the problem
Then just hook it normally?
so how
whats the base weight of a buffoon pack?
thanks!
do someone knows how to create random tags ?
is this right
No.
You don't need to call Card:set_cost
It's automatically done when a card is created.
so i delete original set cost?
Yes.
Also why are you using rawget?
Also each cards unique id would be card.sort_id
from reference
actually, here
take a look
i rewritted it
nxkoo i say this as a friend
this is horrid
is there literally any reason why this is part of a joker (???)
thanks trif
Where have you copied this cursed code from