#💻・modding-dev
1 messages · Page 559 of 1
local card_set_cost_ref = Card:set_cost()
function Card:set_cost(self)
card_set_cost_ref(self)
if self.edition then
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
self.extra_cost = self.extra_cost - cost_sub
self.cost = self.cost - cost_sub
end
return card_set_cost_ref
end
real
for some reason G.GAME is nil
see in rust there's no such thing as null so this shit doesnt happen 😎
btw question cuz I'm curious
wait what do i put
what happens??
if self.edition and G.GAME then
ohhh okay
in rust
yeah
so you have an enum called Option
Option<T> to be specific
it looks like this
enum Option<T> {
None,
Some(T),
}
so the None variant holds no data
and the Some variant holds an instance of T
now the good part of this
is that things cant just be null
they must be wrapped in Option
so you cant just forget to do null checks because you literally cannot use the value without processing the option
Is there any downside though?
so when something returns an option you either match it, or unwrap it
not really
its slightly more work but its less work in the long run than troubleshooting null errors
Very cool feature ngl
its awesome
rust also doesnt have exceptions
it uses a similar thing to option called Result
Been thinking of learning rust cuz rust is like the next C++ of programming languages
enum Result<T, E> {
Ok(T),
Err(E)
}
result has an ok value and an error value
same situation as option
its awesome
Btw on a scale on 1/10 how hard do you think rust is?
hmm thats tough
i think theres a point where the design philosophy of the language just *clicks*
well shit
local card_set_cost_ref = Card:set_cost()
function Card:set_cost(self)
card_set_cost_ref(self)
if self.edition and G.GAME then
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
self.extra_cost = self.extra_cost - cost_sub
self.cost = self.cost - cost_sub
end
return card_set_cost_ref
end
i can help you learn rust if yo uwant
it will be way easier if someone can help you lol
the first major hurdle is understanding the borrow checker
do you know C or C++ at all?
very little of C++
yes
function Card:set_cost()
self.extra_cost = 0 + G.GAME.inflation
if self.edition then
for k, v in pairs(G.P_CENTER_POOLS.Edition) do
if self.edition[v.key:sub(3)] then
if v.extra_cost then
self.extra_cost = self.extra_cost + v.extra_cost
end
end
end
end
self.cost = math.max(1, math.floor((self.base_cost + self.extra_cost + 0.5)*(100-G.GAME.discount_percent)/100))
if self.ability.set == 'Booster' and G.GAME.modifiers.booster_ante_scaling then self.cost = self.cost + G.GAME.round_resets.ante - 1 end
if self.ability.set == 'Booster' and (not G.SETTINGS.tutorial_complete) and G.SETTINGS.tutorial_progress and (not G.SETTINGS.tutorial_progress.completed_parts['shop_1']) then
self.cost = self.cost + 3
end
if (self.ability.set == 'Planet' or (self.ability.set == 'Booster' and self.ability.name:find('Celestial'))) and #find_joker('Astronomer') > 0 then self.cost = 0 end
if self.ability.rental then self.cost = 1 end
self.sell_cost = math.max(1, math.floor(self.cost/2)) + (self.ability.extra_value or 0)
if self.area and self.ability.couponed and (self.area == G.shop_jokers or self.area == G.shop_booster) then self.cost = 0 end
self.sell_cost_label = self.facing == 'back' and '?' or self.sell_cost
end
this is the original set cost function
i have it up already
as you can see it also indexes G.GAME specifically G.GAME.inflation at the start of first line
i saw that yeah
i tried to fix
no luck
local card_set_cost_ref = Card:set_cost()
function Card:set_cost(self)
if G.GAME then
card_set_cost_ref(self)
if self.edition then
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
self.extra_cost = self.extra_cost - cost_sub
self.cost = self.cost - cost_sub
end
end
return card_set_cost_ref
end
so maybe If you add if G.GAME ~= nil then to the beginning it would fix?
If It doesn't work I have no idea ngl
yea this is odd lmfao
not sure why my joker is crashing 😔
lines line up with the file for my code sent btw
yeah
rust is a really fun language though
insane joker
bro hasn't seen cryptposting
i have not
i have only played one content mod for the game and its cryptid
i like vanilla lol
cya
you dont need the return
what does this do
oh the first line should be local card_set_cost_ref = Card.set_cost
okay surely now that i made the whole thing customizable and now that ive used that customizability for one of my existing uses it will now work correctly 100% of the time :clueless:
it seems to atleast 🎉
i can sleep peacefully now
someone said to have it
i mean it's good practice to have it but that function doesnt return and the way you're returning is wrong
the reference local was calling the function rather than storing a pointer to it
local card_set_cost_ref = Card.set_cost
function Card:set_cost(self)
if G.GAME and self then
card_set_cost_ref(self)
if self.edition then
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
self.extra_cost = self.extra_cost - cost_sub
self.cost = self.cost - cost_sub
end
end
end
its ortalab
ah
eremel said he was adding them to smods at some point
one day... 😔
uhh
also bump might not be the best thing to send in here because it's really janky and there's a lot of code in general but yk i can try
so it appears i made a mistake
it should be function Card:set_cost() or function Card.set_cost(self)
: means it has self
ahhh
i did not know that
once again i have like zero lua experience
by the way, in my deck's description it says that negatives are $5 cheaper
should i say "-$5 Negative cost" or "$-5 Negative cost"
-$ looks better imo
agreed
okay prices are no longer zero
okay so it just doesnt work
great
wait hang on
@red flower is this line good
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
not sure why my code no worky
local card_set_cost_ref = Card.set_cost
function Card:set_cost()
if G.GAME and self then
card_set_cost_ref(self)
if self.edition then
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
self.extra_cost = self.extra_cost - cost_sub
self.cost = self.cost - cost_sub
end
end
end
yo......
bro can you help with this idk what to do
it doesnt seem to want to even use the method override here
what do you need help with?
ts isnt working
i'm not really the greatest at coding but
im good at it just not lua
im fumbling around in the dark here 💀
especially cuz i dont know how smods works very well
this looks like it should work
i think i'm as braindead as you
i even tried a full manual override
function Card:set_cost()
self.extra_cost = 0 + G.GAME.inflation
if self.edition then
self.extra_cost = self.extra_cost + (self.edition.holo and 3 or 0) + (self.edition.foil and 2 or 0) +
(self.edition.polychrome and 5 or 0) + (self.edition.negative and 5 or 0)
end
self.cost = math.max(1, math.floor((self.base_cost + self.extra_cost + 0.5)*(100-G.GAME.discount_percent)/100))
if self.ability.set == 'Booster' and G.GAME.modifiers.booster_ante_scaling then self.cost = self.cost + G.GAME.round_resets.ante - 1 end
if self.ability.set == 'Booster' and (not G.SETTINGS.tutorial_complete) and G.SETTINGS.tutorial_progress and (not G.SETTINGS.tutorial_progress.completed_parts['shop_1']) then
self.cost = self.cost + 3
end
if (self.ability.set == 'Planet' or (self.ability.set == 'Booster' and self.ability.name:find('Celestial'))) and #find_joker('Astronomer') > 0 then self.cost = 0 end
if self.ability.rental then self.cost = 1 end
self.sell_cost = math.max(1, math.floor(self.cost/2)) + (self.ability.extra_value or 0)
if self.area and self.ability.couponed and (self.area == G.shop_jokers or self.area == G.shop_booster) then self.cost = 0 end
self.sell_cost_label = self.facing == 'back' and '?' or self.sell_cost
end
this also did fuckall
(expensive negatives)
literally me
are you overriding the function instead of hooking it?
i feel like theres an easier solution with hooks
read up
hook didnt do anything, i used an override to test if it was an issue with smods refusing to hook
debugging 🔥
does the modifier exist
local card_set_cost_ref = Card.set_cost
function Card:set_cost()
if G.GAME and self then
card_set_cost_ref(self)
if self.edition then
local cost_sub = self.edition.negative and (G.GAME.modifiers.rad_extra_cost_negative or 0)
self.extra_cost = self.extra_cost + cost_sub
self.cost = self.cost + cost_sub
end
end
end
SMODS.Back{
name = "Overflow Deck",
key = "rad_overflow",
pos = {x = 0, y = 0},
config = {
rad_negative_rate = 0.097,
rad_extra_cost_negative = -5,
joker_slot = -2,
},
atlas = 'Radium',
loc_txt = {
name = "Overflow Deck",
text ={
"{C:attention}-2{} Joker slots",
"{C:attention}Increased {C:dark_edition}Negative{} chance",
"{C:tarot}Tarot{}, {C:planet}Planet{}, and {C:spectral}Spectral{}",
"cards may be {C:dark_edition}Negative",
"{C:gold}-$5 {C:dark_edition}Negative{} cost",
},
},
apply = function(self)
G.GAME.modifiers.rad_negative_rate = self.config.rad_negative_rate
end
}
no idea it looks fine to me
my thoughts precisely
see if balala was written in rust this would not be an issue
is it to do with the use of self????????
i doubt it
you should check but probably not
the one where you access the config
?
how would I make something happen when I click on a joker
i think so yea
G.GAME.modifiers.rad_negative_rate = self.config.rad_negative_rate
self.config.rad_negative_rate may be nil (shouldn't be but i don't know what else it would be)
its not nil
config = {
rad_negative_rate = 0.097,
rad_extra_cost_negative = -5,
joker_slot = -2,
},
yeah but self might not be what you are expecting
yeah self is the card clicked
gotcha
this behavior works fine with rad_negative_rate so if thats actually somehow the issue
fuck me sideways then ig
yeah i wouldn't say this otherwise
i use it here
too much has been tried
local poll_edition_ref = poll_edition
function poll_edition(_key, _mod, _no_neg, _guaranteed, _options)
-- do chance roll here - if it succeeds, _guaranteed = true
if pseudorandom("radium_overflow_deck_negative") < (G.GAME.modifiers.rad_negative_rate or 0) then
_guaranteed = true
_options = {'e_negative'}
end
return poll_edition_ref(_key, _mod, _no_neg, _guaranteed, _options) -- call original function
end
how can i publish mods on the balatro mod manager?
lemme do some further testing
is G.GAME.modifiers.rad_extra_cost_negative somehow nil within a run? thats literally the only point i see that it could fail to apply the change but based on whats been said i dont think thats the case
wait you aren't setting rad_extra_cost_negative i think
i am
wait maybe im not shit hang on
am i a dumbass
not in apply
yeah i think u need to set it in apply
otherwise the variable isnt set
PR the balatro mod index, it's in the BMM thread
im aware
i think i just forgor
what in the name of
its a PR?
well fuck
Pull Request
now self explodes????
i guess
balajank
bro my dorm smells like cigarettes now who is lighting one up outside my window
ill kill them
wait nvm it crashes because i broke something else while testing
nvm chat
where is that thread?
i think it's the parentheses you added
it will crash with any editioned card that's not negative
I regret nothing
i optimized my logic a little
Gives 161156 mult... and then gets deleted
I'm trying to add a custom deck to balala (yahimod balatro) and for some reason it crashed every time I open game
wait i didnt even know that riff raff can make negatives
Can somebody help?
send your code
what are you trying to achieve with that deck
what’s the crash message
(and send the code for the deck you’re trying to make here)
I'll send
SMODS.Back({
key = "asgoredeck",
loc_txt = {
name = "The Asgore Dagger Deck",
text={
"Start with A Bluenemonial Dagger and Deer. You know what to do.",
}
}
config = { hands = 0, discards = 0, consumeables = 'c_opentolan'},
pos = { x = 4, y = 0 },
order = 1,
atlas = "Decks",
unlocked = true,
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
if G.consumeables then
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_yahimod_blueprintdagger", "yahimod_deck")
card:add_to_deck()
--card:start_materialize()
G.jokers:emplace(card)
for i = 1, 2 do
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "c_yahimod_deer", "yahimod_deck")
card:add_to_deck()
--card:start_materialize()
G.consumeables:emplace(card)
end
return true
end
end,
}))
end,
})
that the deck
crash message also?
it’ll automatically turn into a txt if you paste
ah
ARGGGFHGHH DGH
ok so the issue is
after loc_txt you forgot a comma
SMODS.Back({
key = "asgoredeck",
loc_txt = {
name = "The Asgore Dagger Deck",
text={
"Start with A Bluenemonial Dagger and Deer. You know what to do.",
}
} << comma missing
@marble stratus ^
o h
if it’s your first time then that’s a common mistake for beginners
(i’ve gotten the same error several times before)
update ur smods version twin
what
ur using a smods version from may 30, that could be why the crash is happening
a h
mods dont appear now.
wdym?
and you put the new smods version in AppData/Roaming/Balatro/Mods?
hel p
get a diff loveley patch? idk atp
i got the newest lovely patch though
redownlo ad
i did redownload!
try.. two times
ok fine ill try Two Time(s)
jus in case
i did do 0.8.0 but ill do it again
sorry i got no clue how deck modding works
nope, didnt work
ples halp saviouer
using an old version of lovely didnt work either
bill cipher i will shake ur hand if u somehow fix alll this.
How could I track each time a joker destroys itself? I'm guessing a hook into Card:remove() with a global variable, but idk what to do from there.
i am suffering
same.
coding is tghe digital equivalent of the souls of the damned screaming at you.
are you tracking it for an individual joker or for every joker that self destructs?
I want to track when any joker self destructs.
oh ok
then yeah i think ur on the right path
tho i will say hooking Card:remove can be very finicky
boowump
Still having issues with this?
ye s
Have you tried updating Yahimod?
Could you show me what portion of the code you've edited?
its at end
SMODS.Back({
key = "asgoredeck",
loc_txt = {
name = "The Asgore Dagger Deck",
text={
"Start with A Bluenemonial Dagger and Deer. You know what to do.",
}
},
config = { hands = 0, discards = 0, consumeables = 'c_opentolan'},
pos = { x = 4, y = 0 },
order = 1,
atlas = "Decks",
unlocked = true,
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
if G.consumeables then
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_yahimod_blueprintdagger", "yahimod_deck")
card:add_to_deck()
--card:start_materialize()
G.jokers:emplace(card)
for i = 1, 2 do
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "c_yahimod_deer", "yahimod_deck")
card:add_to_deck()
--card:start_materialize()
G.consumeables:emplace(card)
end
return true
end
end,
}))
end,
})
context doesn't exist in remove_from_deck
You are trying to create a joker with the key "c_yahimod_deer". Joker keys start with a j, not a c.
It doesn't let you just put jokers in the consumables slot? I'm unfamiliar with that kind of stuff.
i am in pain
use SMODS.add_card instead of using the vanilla function call
https://github.com/nh6574/VanillaRemade/wiki#jokers-or-consumables
it should automatically place it in the right area
whermst?
how would i get a list of all the jokers
im trying to make it so that if you have multiple of one card it does the negative part of the card once
joker*
so i also need the position of the joker in the jokers
actually itd be easier to change ur current code
for i = 1, 2 do
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "c_yahimod_deer", "yahimod_deck")
card:add_to_deck()
--card:start_materialize()
G.consumeables:emplace(card) -- should be G.jokers:emplace(card)
end
but yeah SMODS.add_card is a lot more convenient
th ank y ou
G.P_CENTER_POOLS.Joker has all the joker keys in order
how would i get the position of the current joker then
if that makes sense
Every joker or only owned jokers?
the jokers you currently are using
oh
G.jokers.cards
i was doing this but idk how to get the keys
what type of object is in the thing
G.jokers.cards is a table of cards
to get the key of a joker
do
card.config.center.key
assuming card is a joker
is there a way to like
get the current position of the joker
in the jokers you are using
local my_pos = 0
for i=1, #G.jokers.cards do
if G.jokers.cards[i] == card then
my_pos = i
break
end
end
this does work if there are multiple jokers of the same type right
alright tysm
Two cards cannot be the same.
Having trouble running cryptid mod correctly
If anyone is free to help, id appreciate it
hooking card:click to play noises
but it is crashing because self does not exist?
even when I check if self before running it
it WORKS
i fixed it
Try asking on the Cryptid server
hey, I'm curious if it is possible to make a consumable "upgrade" a hands chips permanently (kind of like a planet). I have implemented it using the following:
However the problem is that once a planet card is bought, it defaults back to being the chips of said hands level. (e.g. if this increases the chips by 10, and a level would give +20 chips, then the level up only gives +10 chips)
You need this in a lovely file:
[[patches]]
[patches.pattern]
target = '''=[SMODS _ "src/game_object.lua"]'''
pattern = '''
hand[self.key] = math.max(hand['s_'..self.key] + hand['l_'..self.key]*(hand.level - 1), 0)
'''
position = "at"
payload = '''
hand[self.key] = math.max(hand[self.key] + hand['l_'..self.key]*amount)
'''
match_indent = true
How does one allow seals to retrigger joker retriggers?
That works. Awesome! Thanks!
Is there a way to force a card to spawn with a specific seal for testing?
Yes.
How does one do that
card:set_seal('modprefix_key')
I'm guessing this is done with the debugger?
You mean DebugPlus?
Correct
Then you would do CTRL + E while hovering over the card.
Merci
why doesn't this work it's like 12:41 am but i gotta get this done
...
loc_vars = function(self,info_queue,card)
return {vars = {self.config.extra.winning_ante}, colours = {{0.78, 0.35, 0.52, 1}}}
end,
...
oh and
...
loc_txt = {
name ="Astro's Deck",
text={
"Start with {C:attention}2{} {V:1}Eternal",
"{C:dark_edition}Negative{} {C:attention,T:j_mktjk_astro}Astros",
}
},
...
colours should be in vars
Nothing.
I wanted to make a poker hand : Triple Pair
i really don't know why it doesn't work
i'm using the double pair code from vanilla remade btw
struggling to check for the exact jokers in context.retrigger_joker_check
like i want very specific jokers to be trigger.
What is the goal?
basically i have joker that should retrigger a very small subset of jokers
like 5 or 6 of them from my mod? ill have to count
its not a broad range and they dont have anything in common besides their theme
wondering if theres an easy way to check the name or key of the joker because my efforts suck
flag the jokers in their config
then you can just check for context.other_card.ability[" your flag"]
so just this right
.ability.extra in that case
o
without the extra was ok
i have very little idea of how the config of a joker works i just put variables in and they work
anything in config gets put into card.ability
extra is in card.ability
just .ability will work yeah
Oh you mean the check
from what im getting, extra is just a table in the config right
card.ability.extra is config.extra basically
anything in config will be put in card.ability, like N' said
icic
i think the convention is because at one point things outside of extra didn't get saved? idk
that's what the docs say in one part
yeah that was a thing ages ago
we had to put everything in extra
it has been gone for eons
Back in my day …
back in my day itayfeder was the one maintaining fusionjokers
my journey to a new run involved multiple version changes and manual installs and we didn't have any of this context.beat_boss or context.main_eval baby shit you guys have now
this new generation is so spoiled
dang new lore
no most of us started this year lol
i guess im an outlier
I have an issue
My wifi doesn’t connect to my pc when i open it does thus for like 5 minutes
Even tho i’m using a cable
did old calc have SMODS.calculate_context
I'm Old!
thank you
naw
What are you up to bepis ?
back in my day we had to do everything manually without any documentation you younguns have it so good /s
Sadly i can’t add localization to my mod because there would be so much colors
smh what's wrong with color
objection this
I think it’s painful to look at honestly
wtf.......................
hell nah i cant imagine modding without that 🥀
How do I add only Mult to a poker hand?
If i return false in in_pool does it make it not spawn ?
yes, by random means at least
oop it seems my set_particles from pseudo_open is applying it to the wrong thing 💀
how would i make it so a booster pack can spawn multiple of the same consumable even without showman
bump
two things:
- what does
stickersexpect? i've had no luck getting this to work - why do the cards spawn in the Jokers area, and how can i fix this?
stickers looks correct to me
for the second problem try adding the area to create_card
bump2
PERU?
someone knows how to make a new area, like a second consumable area?
me
where goes the code, in the main lua file?
anywhere you like as long as the file is loaded
just to be clear, making areas is like intermediate stuff so you will have to make a lot of tweaks to this
there's no nice API for it
what does JoyousSpring does?
that's the global table for my mod
i need to change it for my mod?
you dont need that, i just do it to have an easier reference to it
oh and the type should be 'joker' instead of 'extra_deck'
What’s the parameter for add_card to specify a card
a playing card?
Tarot
Yes
SMODS.add_card{ key = 'c_key' }
C lowercase ?
I was doing uppercase
F
jokerforge has the list of keys
Reading the Src for add_card -> it’s been create_card all along ->reading the src for create_card -> i’m nod emplacing my cards every time i add them
yeah that's what the docs say too

how can i get rid of this ugly ERROR badge? my localization entry seems correect (i t hink):
descriptions = {
-- jokers, etc.
Other = {
emith_tax = {
name = "Tax",
text = {
"Lose {C:money}$#1#{} for",
"every hand played",
}
}
},
misc = {
labels = {
emith_tax = "Tax",
}
}
}
hold on i have an idea nvm it didnt work
stickers.lua file (please ignore the functions, ill worry about them later) :
SMODS.Atlas {
key = "stickers",
path = "stickers.png",
px = 71,
py = 95
}
SMODS.Sticker {
atlas = "stickers",
key = "tax",
badge_colour = HEX "dcdcdc",
pos = { x = 0, y = 0 },
should_apply = true,
sets = {
Joker = true,
},
apply = function(self, card, val)
card.ability[self.key] = val
end,
loc_vars = function(self, info_queue, card)
return {vars = {1}}
end,
calculate = function(self, card, context)
if context.end_of_round and not context.repetition and not context.individual then
ease_dollars(-1)
end
end
}
misc goes outside descriptions
gng how do u get the text to look like that
alr this comes up whenebver i click to check my deck
if it's not an issue with a mod you're making pls post it in #⚙・modding-general
for some reason, the list still reads as "nil" when i evaluate the "numberarray" list
im making a deluxe yahimod.
and thisis an issue with a deck i madew
then post code
okiw
local variables reset between function calls
SMODS.Back({
key = "asgoredeck",
loc_txt = {
name = "Asgore's Dagger",
text={
"Start with A Bluenemonial Printer and 2 Deer.",
"{C:red}You know what to do.{}",
}
},
pos = { x = 4, y = 0 },
order = 1,
atlas = "Decks",
unlocked = true,
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
if G.consumeables then
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_yahimod_blueprintdagger", "yahimod_deck")
card:add_to_deck()
--card:start_materialize()
G.jokers:emplace(card)
for i = 1, 2 do
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_yahimod_deer", "yahimod_deck")
card:add_to_deck()
--card:start_materialize()
G.jokers:emplace(card)
end
return true
end
end,
}))
end,
})
hmm I don't think the deck is the problem
whar
it seems to be a problem with the whatsapp seal
does it work if you remove then entire apply function
the huh
Is there a way to "lock" a local variable during the rounds, then have it be dynamic during the shop?
elaborate?
wouldnt that get rid of the whole deck?
it would get rid of the jokers
but thats tge only thing in the de ck
oj okie
nevermind, I just had a eureka
nice
ty anyway
it broke the whole game, crashes on start
did you only get rid of the apply function
SMODS.Back({
key = "asgoredeck",
loc_txt = {
name = "Asgore's Dagger",
text = {
"Start with A Bluenemonial Printer and 2 Deer.",
"{C:red}You know what to do.{}",
}
},
pos = { x = 4, y = 0 },
order = 1,
atlas = "Decks",
unlocked = true,
})
like that
okiw
that makes game no craesg
SMODS.Back({
key = "asgoredeck",
loc_txt = {
name = "Asgore's Dagger",
text = {
"Start with A Bluenemonial Printer and 2 Deer.",
"{C:red}You know what to do.{}",
}
},
pos = { x = 4, y = 0 },
order = 1,
atlas = "Decks",
unlocked = true,
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
if G.consumeables then
SMODS.add_card { key = "j_yahimod_blueprintdagger" }
for i = 1, 2 do
SMODS.add_card { key = "j_yahimod_deer" }
end
return true
end
end,
}))
end,
})
try this
game crsahes on start
whats the crash
you probably copied it wrong
i am right, i can read the crash log lol
THANKYOUOUOI
"how to read a crash log" seems like a damn good thing to put on the vremade wiki
i thought about it but idk how to explain it
hmm yea
I'll think it over. is there any way to make a PR to the wiki?
ty!
i dont really know how it works lol
ok, no worries
I think the wiki has to be its own repository somehow, that's how smods has it set up iirc
why is yahimod in here
they're making a yahimod addon
o
im making yahimod DX
i think only certain keys are returned directly
Clearly you’re not sigma
dang.....
like this?
yeah
yw
i saw the function returning something so i kinda assumed it would return the ret table
bleh
i think it only returns the registered ones
3:
ic
well now time to solve the issue of how to get it run this without recursive shenanigans...
hold tab for the debugplus cheat sheet
(ctrl-3 while hovering over anything in the collection to spawn it)
what arguments does copy_card() take?
anyone know a way to change the odds of joker rarites in the shop? trying to do a voucher that makes rares and uncommons more likely to be in the shop
modify G.GAME.[rarity key in lowercase]_mod
cool ty
function copy_card(other, new_card, card_scale, playing_card, strip_edition)
other is the card you want to copy
new_card is a card object you want to copy to, or just nil if you want to create a new card object
card_scale is the size of the new card object, just set it to nil to default to the same size as the other card
playing_card is uhhhhhhh i dunno tbh
strip_edition is boolean, but i think it only really has an effect on negative?
playing_card is the number playing cards are assigned when added to deck iirc
@red flower question, why does returning anything will cause the game to crash?
🤔
i cant seem to figure it out
without it the code works fine
why are your screenshots getting smaller
arent the returns processed by eval card?
no they arent
:3
a
@wintry solar :3 sorry for pinging
how would i make this pop up the "Copied!" text below the joker like this without breaking out of the for loop early? (as i still want to count cards drawn afterwards)
What am I looking at?
oh so i want to hook to eval_card to have something to calculate the stats v this
right now when it does that it stops the loop early so draw_tally always ends up at 0
everything works so far except for when i return anything in context.bsr_stats
which will cause the game to hard crash immediately
i can easily add a workaround but i want to know whats causing it 🤔
SMODS.calculate_effect({message = ""}}, card)
-# and if theres potentially a better approach i can go for
is there a field for color too
message_colour?
Just colour
o
Do you have post triggers turned on?
how can i make my consumable immune to Perkeo's effect?
hmmm
i uh
don't think using card here is correct because it uh. crashes
i might be running out of ideas
If you put prints in what do you get in the log?
put in where 🤔
if its that print in the picture then it hard crashes so i cant really tell lol
what should i use instead?
self?
whats your code
that also crashes
SMODS.calculate_effect({message = localize('k_copied_ex'), colour = G.C.Chips, card})
You can still check the actual log file
full joker:
key = 'infinitejoker',
loc_txt = {
name = 'Infinite Joker Glitch',
text = {
"Add a permanent copy of every {C:attention}#2#{}th card drawn",
"to deck and draw it to {C:attention}hand{}",
"{C:inactive}(#1#/#2#){}",
}
},
config = { extra = {draw_tally = 0, draws = 20 } },
rarity = 1,
atlas = 'VTudeJokers',
pos = { x = 1, y = 0 },
cost = 5,
blueprint_compat = true,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.draw_tally, card.ability.extra.draws } }
end,
calculate = function(self, card, context)
if context.hand_drawn
or context.other_drawn
and not context.blueprint then
for _, playing_card in ipairs(context.hand_drawn or context.other_drawn) do
card.ability.extra.draw_tally = card.ability.extra.draw_tally + 1
if card.ability.extra.draw_tally >= card.ability.extra.draws then
local _card = copy_card(playing_card)
_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, _card)
G.hand:emplace(_card)
card.ability.extra.draw_tally = card.ability.extra.draw_tally - card.ability.extra.draws
G.E_MANAGER:add_event(Event({
func = function()
_card:start_materialize()
return true
end
}))
SMODS.calculate_context({ playing_card_added = true, cards = { _card } })
SMODS.calculate_effect({message = localize('k_copied_ex'), colour = G.C.Chips, card})
end
end
end
end
}```
oh right
card should be outside the table
its G.C.CHIPS btw
SMODS.calculate_effect({}, card) fill the table in with stuff
AH
doesnt seem to print out anything at all
And if you move it a line up?
it is so niche and useless i love my creation ❤️
why would you want this joker
wait why did it go from 15 to 19 after discarding 5 cards
huh??
Block that one too then 😂
oh huh its also doing the create a card animation uh. after the card gets added to the hand so it looks weird. probably should reorder things then?
so it doesnt look like its replacing a card lmao
-# @daring fern figured more out whenever youre available
-# all the values are being saved properly, but it's that they aren't being allocated
-# as you can see, burglar's hand addition value is being saved under extra, as it should be
-# howEVER, there's nothing in place for the joker to use the abilities of jokers with extra as NUMBERS as it will typically look for extra as TABLE
-# which'll get you crashes like ease_hands_played trying to compare with a table when it requires a number
can somebody help me figure that part out i am. so confused by it
Can you screenshot the code it’s awful to read copy paste on mobile
okay yeah its definitely that sometimes when discarding 5 cards it only goes up by 4 instead of 5?
which is weird
can we have SMODS.copy_card
Yes
wait really
any tips on how to start modding?
I don’t remember if they do, but if cards get drawn one by one your copy will fill a space
So you only draw four
the thing is it even happens going from like 3->7
with no copy added
seems to be rare though i cant reproduce it
check the pins in #⚙・modding-general
helelp
i don't understand what i need to do, sorry
Rather than a text table, loc_txt should contain a description table
how do I make the message pop up stay for longer?
do you guys know any mods that create new card areas? Possibly below the consumables. Anywhere really
add delay to the return
what even
i just saw that lmao
1 day further away from quantum ranks being merged
quantum ranks are over
Do my Jokers that use this rarity appear in shop like this?
key = "chatter",
pools = {
["Joker"] = true,
["Joker"] = { rate = 0.7 },
},
badge_colour = HEX("8956FB"),
}```
for every passing day, quantum ranks move 2 days further from being merged

works every time 0.01% of the time
can you merge this https://github.com/Steamodded/smods/pull/732
I am capable of merging this
but I certainly am not willing to
its funny tho
it works every time 75% of the time
I'm not even gonna pretend I'd care to try and understand what the hell this is doing exactly
before merging it I'd rather discontinue smods altogether
quantum ranks is both merged and unmerged, it isn't realized til i open https://github.com/Steamodded/smods/pulls 
Schrödinger's ranks
bump
why are you assigning to the same key twice
just the one with the rate table should do fine
Because I was tired when I wrote this code
But that doesn't answer my question...
this is fucking awesome actually i need this to be real
https://github.com/Steamodded/smods/pull/917
should be fine otherwise
How rare are they right now compared to the other rarities in the game?
lgtm
wait that's not in the wiki as reference? they'll be weighted the same as common jokers
meaning with no other rarities present, the chance of a given shop joker having your rarity is 0.7/1.7 or about 41%
It isn't, iirc
how so
looks good to me
why did you reply to it twice 🥲
it's not my pull request, just thought it should be merged lol
i'm just slow and forgot i already replied i guess? or confused it with replying to the actual PR? not sure haha
oh loll
looks good to @frosty dock
?
do cards of your rarity appear at some other rate? do they not appear at all? is there an unusual abundance of basic jimbos?
does it lag at all?
I meant that it isn't in the wiki
But no, my jokers actually don't appear at all in the shop, for whatever reason
Or at least it doesn't seem like they do
did you remove the ["Joker"] = true yet? and can I see code of a sample joker that you assigned this rarity to?
Yes and here:
key = "shnack",
config = { extra = { chips = 0, chipsMod = 0.1 } },
pos = { x = 5, y = 0 },
rarity = "cstorm_chatter",
cost = 0,
blueprint_compat = false,
eternal_compat = false,
unlocked = true,
discovered = false,
atlas = 'chatters',
calculate = function (self, card, context)
if context.joker_main then
return {
chips = card.ability.extra.chips
}
end
if context.end_of_round and not context.repetition and not context.individual then
card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chipsMod
return {
extra = {focus = context.self, message = localize('k_upgrade_ex')}
}
end
end,
loc_vars = function (self, info_queue, card)
return { vars = { card.ability.extra.chips, card.ability.extra.chipsMod }, key = self.key}
end
}```
It has?
it should be weight = 0.7 instead of rate
I'll update the wiki right away
woah wiki updates?!
we don't mind incomplete information
but incorrect information just doesn't fly
https://github.com/Steamodded/smods/wiki/SMODS.Rarity there, hope that's clearer
It is, thank you again :3
how can i have a sticker only be applied to jokers instead of all cards? i think ive tried a lot of thingfs by no
put ```lua
sets = {
Joker = true
}
I'm confused how no one has ever called me out on this. it's always been like this and it's always been wrong 
yuh i've tried this
womp womp
do you have a should_apply on your sticker definition? because that overrides sets
i forgot to PR it the last time i saw it
oh thats probably why,hold on now
and then i forgot what it was i needed to PR lol
i have this:
should_apply = function(self, card, center, area, bypass_roll)
return G.GAME.modifiers.enable_tax_in_shop
end,
and on the stake i set that global to true
i dont think you need to make a function for the flag? at least the smods.sticker page advertises it that way
tbf i also haven't been checking issues on the wiki repo
How do I keep a variable between the instances of a joker and not change even after the joker is sold and the bought again?
store it in G.GAME
how can i get the level of played poker hand?
G.GAME.hands[context.scoring_name].level
ty
how do I make a new effect trigger immediately after a previous effect?
I'm trying to make something happen in a specific sequence
return {
chips = 50,
extra = { mult = 5 }
}
like that?
thats chips first mult second
Well what I'm trying to do exactly is send a message then do the thing after its done saying the message
but if I put the thing after the message it still does it first so I think I have to make it a different effect
maybe event with delay can help? (idk)
i dont know how my answer doesnt help with that
i literally do this
is it the extra part?
either stickers are fucked up and evil or im stupid
either they apply to every single card or they dont show up at all
can i see your code
can i see your code too
SMODS.Sticker {
atlas = "stickers",
key = "tax",
pos = {x = 0, y = 0},
config = {
extra = {tax_rate = 1}
},
badge_colour = HEX("dcdcdc"),
sets = {
Joker = true,
},
apply = function(self, card, val)
card.ability[self.key] = val
end,
loc_vars = function(self, info_queue, card)
return {vars = {self.config.extra.tax_rate}}
end,
calculate = function(self, card, context)
if context.final_scoring_step then
G.E_MANAGER:add_event(Event({
func = function()
card:juice_up()
ease_dollars(-self.config.extra.tax_rate, true)
return true
end
}))
card_eval_status_text(card, "dollars", -self.config.extra.tax_rate)
end
end
}```
idk what happened with the calculate function formatting-wise
and this doesnt apply or does it apply to everything
The destroy part happens after but it creates the card instantly even with the extra part you told me to add
this does not apply at all
if i use should_apply with return true it applies to everything
oh
you need events for functions
Where would I start for fusing jokers together to create a new one?
what happens if you remove sets
also you should remove that apply function, the default one does more
I'm confused on how this works
damn
cropping is har
same thing,
if should_apply() returns true, applies it to everything
if should_apply() missing, it doesnt apply at all
did that too just now
uhh idk then, you might need to copy the entire default should_apply lol
I meant I was confused on how events worked
an event gets put into the queue and then they play in order basically, return messages are events too
should_apply = function(self, card, center, area, bypass_roll)
return SMODS.Sticker.should_apply(self, card, center, area, bypass_roll) and other_condition
end
you should call the default if you want its functionality
why did you blunder me
did u read the conversation lol
there's no need ever to copy that, you can just reference it and add whatever condition you need on top of that
But if it wasn't working for them without it defined then why would it work if they reference it? My point was more about copying what it does rather than copying it directly
not sure what that would change
that it might work
yea it didnt work, ill just wait until sticker implementation is less weird to understand, i suppose
Thx so much I got it working
oh do the one without the should_apply and set needs_enable_flag = false
weird that it defaults to true
right, enable flags
it should probably say it
does a card's cost get stored in config.center? like card.config.center.cost? realized i should prob ask here
like how the key gets stored under card.config.center.key, that sort of thing
what the fuck man
im tired, ty all
yes
thanks n
how do i add dependancies? wasn't it (in the meta data)
"dependencies": [ModFileName]
trying to make Talisman a dependency even though everyone should already have it
just consult the wiki
it's not the file name, it's the mod ID
@red flower why the game crashes (srry to disrrupt you but i was in school)
uhhh was this about the card areas
yes
ok like i said, joyousspring is the table for my mod and you dont need that part
just the self.area_name = CardArea(...)
i should write about this on the wiki
so i only edit the parts where says that?
i can't tell you that you need to "just" do that because i dont know honestly, this is probably something you need to tinker by yourself and find out
Making own card areas kinda annoying tbf
yeah
But looks like I finally made it
Hi N
Ku ra ku
i was trying to write it with the jp keyboard but didnt know the kanji
i should resume
My memory not too good with kanji
Real
for me the most annoying part about it is the responsive position - I have a custom cardarea set up, but it keeps shifting for each person I see playing the mod i'm helping develop
that happens to me too lol, i need to see how to fix that
probably changing the major of the area
It doesn't help that the borders of the screen depend on resolution
It's doable if center your stuff
Corners is not reliable place
Okay, so I made a card area for dices, where they keeped like in bag. You can even move them, but not outside of area
heh
man i hate animations. im tryna do an event to set the speed of the animation to what i want but when i switch its y pos. it just continues the animation for a little while before stopping and its annoying bruh
-- FlopprAnimations
local btct = {ticks = (5)}
local upd = Game.update
local btct_Floppr_dt = 0
function Game:update(dt)
upd(self, dt)
local Flopprobj = G.P_CENTERS.j_btct_Floppr
btct_Floppr_dt = btct_Floppr_dt + dt
if Flopprobj and btct_Floppr_dt > 0.1 and Flopprobj.soul_pos.y == 1 then
btct_Floppr_dt = btct_Floppr_dt - 0.1
if Flopprobj.soul_pos.x > 2 then
Flopprobj.soul_pos.x = 1
Flopprobj.soul_pos.y = 0
else
G.E_MANAGER:add_event(Event({
trigger = "immediate",
delay = 0.1,
func = function()
Flopprobj.soul_pos.x = Flopprobj.soul_pos.x + 1
return true
end
}))
end
--other anims here i didnt put
elseif Flopprobj and btct_Floppr_dt > 0.1 and Flopprobj.soul_pos.y == 7 then
btct_Floppr_dt = btct_Floppr_dt - 0.1
if Flopprobj.soul_pos.x > 16 then
Flopprobj.soul_pos.x = 0
Flopprobj.soul_pos.y = 1
else
G.E_MANAGER:add_event(Event({
trigger = "immediate",
delay = 0.1,
func = function()
Flopprobj.soul_pos.x = Flopprobj.soul_pos.x + 1
return true
end
}))
end
end
for k, v in pairs(G.I.CARD) do
if v.children.floating_sprite and v.children.floating_sprite.atlas == G.ASSET_ATLAS["btct_FlopprAtlas"] then
v.children.floating_sprite:set_sprite_pos(Flopprobj.soul_pos)
end
end
end
anyone here good at anims that can help?
floop the pig
I'd ask what you're trying to do but I'm going to sleep. If you're still trying tomorrow or on the weekend maybe I could help
i should be free so any help will be appreciated
are you just trying to animate soul sprites?
Yes
It's easier with custom draw functions IMO
Im tryna animate the sprite based on whatever happens in game
Take a look at Paranoia from my mod or Heartbreak
Dang, i never learned or checked draw function
They respond to cursor movement
I will thanks for the tip
If this is for multiple Jokers, you could also make it into a SMODS.DrawStep
Does the wiki talk about custom draw functions in the SMODS.DrawStep or nah?
Custom draw functions are a different thing
Oh
I think that e.g. Eremel would say that DrawSteps override the need for custom draw functions, but I disagree
Where can i learn about draw functions?
I don't know if it's written down anywhere. I imagine in some page for card objects (like SMODS.Joker), it might mention you can define a custom draw method, but that's not what I'm talking about
You can define a custom draw method for the soul sprite itself
Oh
How would i do that?
Im sorry im havent used draw before
I don't know if the feature is described anywhere
I learned it from seeing someone else's code
but where you define the position of the soul sprite in the atlas, you can also define a custom draw function for the soul sprite
I recommend looking at Paranoia from my mod because I don't remember which mod I reference. I remember looking at Cryptid but Cryptid had other stuff going on so I couldn't understand what it was doing
I did get some help from Firch so maybe Bunco might have something, although it was for something specific (determining the cursor position accurately, since I was off by some specific factor)
Great thanks!
anyone know where the rarity NAMES are stored? doing this will just display the rarity as a number
Vanilla ones are numbered, otherwise, strings.
yes thank you, but i had already figured that. can i pull those strings automatically like this? or will i just have to specify manually?
Via localize.
k_common, k_uncommon, k_rare & k_legendary.
and do they have the numbers linked to them? like the 1, 2, 3, and 4?
or do they act separately?
You'd have to "associate" them yourself, assuming, to pass the right one for localize to pull the string.
I'm having an issue where a seal I'm working on the "sleepypoints" variable is showing as nil in the seal description.SMODS.Seal { key = 'belphegor', pos = { x = 2, y = 1 }, config = { extra = { sleepypoints = 2 } }, badge_colour = HEX('d80007'), loc_txt = { name = 'Belphegor', label = 'Helluva Boss', text = { [1] = 'Each round this card adds', [2] = '{X:mult,C:white} X#1# {} Mult when scoring.', [3] = 'Increases if this', [4] = 'card is held in hand', [5] = 'at end of round{C:inactive}', [6] = '(Resets if played){}' } }, atlas = 'helluvaseals', unlocked = true, discovered = true, no_collection = false, loc_vars = function(self, info_queue, card) return {vars = {}} end, calculate = function(self, card, context) if context.cardarea == G.hand and context.main_scoring then return { x_mult = card.ability.seal.extra.sleepypoints } end if context.main_scoring and context.cardarea == G.play then card.ability.seal.extra.sleepypoints = 1 end if context.end_of_round and context.cardarea == G.hand and context.other_card == card and context.individual then return { func = function() card.ability.seal.extra.var1 = (card.ability.seal.extra.var1) + 1 return true end } end end }
You are returning nothing in loc_vars
Ah, do I just put sleepypoints in there?
Yes
Try checking for nil before returning it or else it might crash
Or say “nil”
But it shouldn't be empty, the default value for it should be 2.
Or just make sure your variable is global or initialized before this joker or else it wouldn’t exist
Are you doing local sleepypoints=2
I currently have the sleepypoints in the config extra
card.ability.extra.sleepypoints
Instead of sleepypoints
I will try that thanks
Oh i thought it’s a global variable sorry
No
No?
Seal.config.extra.sleepypoints
Im stupid omfg
Nah you're smarter than I am here xD
It’s not a card
(I’m not sure if seals take extra as argument ) because tags don’t
Aaaaa
Check SMODS.Seal
Well that code crashed it
What’s the crash
Wait let me check
It
self.config.extra.sleepypoints
Not seal
I should’ve checked instead of guessing 
That one looks to be working let's gooooo
Now I can see if the seal is actually functioning as intended or not
Also just asking why’s your loc_txt like that
I'm building the seal with joker forge
Ahh i see
I'm planning on replacing the loc_txt with proper localization later.
No it's just supposed to be a regular description
It’s gonna be pain and not worth i know you’re not going to translate your mod
I also know I'm not gonna translate my mod
Weird that jayden coded it that way
Anyways good luck
Joker forge just generates normal text box like that iirc
But in case anyone is insane enough to want to help out with translation, it'll be nice and ready for them to go at it.
Text=“text1”,text2” works fine
Maybe it's so it's easier to spot for people not as used to code
Idk i never used jokerforge he probably knows better
I'm surprised it didn't spit out the variable into that area, I should mention it in a bug report.
I think the majority just plays on english
is there a way to swap the current played hands chips and mult
To split textbox you just split the strings into multiple tables
i think you just return swap = true
Text={{“text1”},{“text2”}}
that worked thx
another question
how do i add the grey text?
{C:inactive}text{}
thankssss
can i add a timer to a boss blind? every ___ seconds something happens
Yes
how?
Every second is too much tho
Love has a time function with love.update if you pass a variable for time
Like love.update(dt)
Dt will increase by 1 every second
you can just use G.TIMERS.REAL
and also, how do i check for when a planet/planet-esque card is being used, that it only buffs one hand type? i dont want to proc this on black hole or cryptid’s 3-hand superplanets
I theres a table for hands but idk if they’re ordered in the same way as ingame
so is there no way to check for the order that shows ingame?
Just hang this on the fridge and come back later
There’s a way
I’m too lazy to read browse the wiki or read the src i’m sorry
okay lets see whats next on the ideas list
“EVIL Hiker: 5 card hands containing ONLY cards you haven’t played before are straight flushes (see The Pillar blind?)”
oh god this one sounds even worse how do i even keep track of that
you can do for loop btw