#💻・modding-dev
1 messages · Page 644 of 1
I hate how random but also not random it feels when it crashes too ugh
i be having that sometimes
my recent issue was i was crashing after playing a hand mid scoring, managed to fix that and now i crash much less, but still eventually
its mostly just combing through the stuff you do and seeing if there are potential issues
<@&1133519078540185692>
how would i check to see if a sold card is a Joker?
card.ability.set == "Joker"
if you want to know how to check a sold card at all check context.selling_card on the docs
Is there a way to use in_pool on a card with a specific rank and suit?
I can only hit one or the other category and not a specific combination
the suit and rank are passed to the in_pool functions of ranks and suits respectively iirc
Oh wait I could just check the rank in the suit's pool or vice versa
when using SMODS.scale_card, how would i get the "Upgrade!" message to display after a card is scored? my code looks like
-- Upgrade when a Queen is scored
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 12 and not context.blueprint then
SMODS.scale_card(card, {
ref_table = card.ability.extra,
ref_value = "currentQueenScale",
scalar_value = "queenScaling"
})
end
and while the scaling works, the message is displayed before the card scoring animation plays, which looks a little awkward. if i use an event with "immediate" trigger, the message only displays after all cards have been scored, which also isn't the goal
ok so adding not context.selling_self to it doesnt cause it to not trigger on itself
selling_self is separate
you need to explicitly check that the card sold is not your card
would i need to run a for loop to find it in the jokers?
no_message = true in the scale_card function, and return the message afterwards
yknow fair enough lol
no, just check context.card ~= card
somehow i did not think of that
the next contexts wiki is so much nicer
ok coming from the support channel: i've installed malverk and did its api thing but it crashed so i definitely didn't do it right lol.
attached is the crash and the code i added to the mod's .lua
as far as i can tell it doesn't recognize malverk? or given its negative priority doesn't recognize it in time at least??
it's just AltTexture without Malverk. i think
🇺🇸
i hate that pixel on the left
that worked! guess i should have trusted the example code in the malverk readme a bit more
thanks!
its just line art lmao, i fixed it immediately after i posted this lmao
I don't hate pixels i actually love all pixels equally
i hate drawing people, why did i choose a tarot of all things
you don't necessarily have to make it a person
you could turn it into a portal reference, make the dude look like the stick dude in the portal 2 logo, and make the building he's escaping from look like the shack chell exits at the end of portal 2
:3
yeah but this mod supposed to be kinda vanilla+
also stacks with glass perfectly
how do i get the current blind's key
G.GAME.blind.config.blind.key
how can i add multiple consumable types to one collection
i dont think you can without patching or hooking the collection functions
you can make them the same consumable type and then use an ObjectType to classify them maybe
How do I get context.other_card to work within an Event? Defining it as a local variable didn't work.
G.E_MANAGER:add_event(Event({
trigger = 'immediate',
blockable = true,
blocking = false,
func = function()
if not G.GAME.blind.effect.extra.has_been_disabled then
blind:disable()
card_eval_status_text(context.other_card, 'extra', nil, nil, nil, { -- This line produces a crash.
message = localize('ph_boss_disabled')
})
end
return true
end
}))
You need to define it as a local variable outside of the event.
balacing question...
so i wanna make a joker called hello planet for my vocaloid mod.
obviously i want to make it a planet gen joker, and i want it to have smth to do with heart cards
but like "generates played hands' planet if it's only made of hearts" (or has no hearts at all) sounds WAY too broken. but if i limit it to just your first played hand then. idk seems too... burnt-y????
wh
oh yeah the post above
sigh
? what happened
scam bot, dw abt it
o gotcha
So from this ugly code, how do I make it pull Jokers from the SMODS.ObjectType rather than manually adding the Jokers to the pack?
return {set = 'objecttypekey'}
Thanks
So just so I'm clear: JUST the return statement or throw that inside the create_card function?
how would one retrigger a random card played
Now the message doesn't show up at all.
local card_to_message_from = context.other_card
G.E_MANAGER:add_event(Event({
trigger = 'immediate',
blockable = true,
blocking = false,
func = function()
if not G.GAME.blind.effect.extra.has_been_disabled then
blind:disable()
card_eval_status_text(card_to_message_from, 'extra', nil, nil, nil, {
message = localize('ph_boss_disabled'),
colour = self.boss_colour
})
end
return true
end
}))
Yes, the return gets put into a SMODS.create_card
Do you need to know how to retrigger or to select a random card?
select a random card and retrigger it
basically i'm expanding on aiko's scrabble deck
AKYRS.LetterJokerTby {
key = "dbl",
atlas = 'AikoyoriJokers',
pos = { x = 2, y = 6 },
unlocked = false,
blueprint_compat = false,
rarity = 2,
cost = 4,
config = { extra = { xchips = 2, cap = 5, odds = 10 } },
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 2, card.ability.extra.odds, 'tby_dbl')
return { vars = { card.ability.extra.xchips, card.ability.extra.cap, numerator, denominator } }
end,
calculate = function(self, card, context)
if context.joker_main and context.full_hand then
local cap_count = 0
for i = 1, #context.full_hand do
if cap_count >= card.ability.extra.cap then break end
if SMODS.pseudorandom_probability(card, 'tby_dbl', 2, card.ability.extra.odds) then
cap_count = cap_count + 1
return {
message = localize('Letter doubled!')
}
end
end
if cap_count > 0 then
return {
for i = 0, cap_count do
#this is where i want to retrigger
}
end
end
end
}
For re-triggering:
Return
repetitions = card.ability.extra.repetitionsin yourcalculatefunction
i mean repetitions would be 1 right
You could make it 100 repetitions.
-# Highly advise against it for the CPU's sake.
its a double letter i'm repeating it once
for a maximum of 4 different letters
wait i could jut
Then I guess you could get away with repetitions = 1. Maybe, don't exactly trust me on that.
effect seems to be "1 in 10 chance to retrigger a played card, ignore all subsequent successful rolls" rather than "retrigger a random played card"
i found it nvm
i want it to have a 1 in 10 chance to retrigger, rolling the chance each card, with a maximum of 5 times
so i can effectively with a lot of luck, retrigger 5 different cards
AKYRS.LetterJokerTby {
key = "dbl",
atlas = 'AikoyoriJokers',
pos = { x = 2, y = 6 },
unlocked = false,
blueprint_compat = false,
rarity = 2,
cost = 4,
config = { extra = { cap = 5, odds = 10, repetitions = 1 } },
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 2, card.ability.extra.odds, 'tby_dbl')
return { vars = { card.ability.extra.repetitions, card.ability.extra.cap, numerator, denominator } }
end,
calculate = function(self, card, context)
if context.joker_main and context.full_hand then
local cap_count = 0
for i = 1, #context.full_hand do
if cap_count >= card.ability.extra.cap then break end
if SMODS.pseudorandom_probability(card, 'tby_dbl', 2, card.ability.extra.odds) and context.cardarea == G.play and context.other_card == context.scoring_hand[i] then
cap_count = cap_count + 1
return {
message = localize('Letter doubled!'),
repetitions = card.ability.extra.repetitions
}
end
end
end
end
}
changed to this
uh, no
you must return {repetitions = num} within context.repetition and context.cardarea == G.play
doing it in context.joker_main has no effect iirc
so
if context.full_hand then
local cap_count = 0
for i = 1, #context.full_hand do
if cap_count >= card.ability.extra.cap then break end
if SMODS.pseudorandom_probability(card, 'tby_dbl', 2, card.ability.extra.odds) and context.repetition and context.cardarea == G.play and context.other_card == context.scoring_hand[i] then
cap_count = cap_count + 1
return {
message = localize('Letter doubled!'),
repetitions = card.ability.extra.repetitions
}
end
end
end
Correct. Repetitions are for the cards.
Well, it's not crashing it. It's not exactly spawning the correct Jokers, either.
this is how I would do it
if context.before and not context.blueprint and not context.retrigger_joker then
card.ability.targets = {}
local cap_count = 0
for i = 1, #context.full_hand do -- I'm not sure about this one, did you mean context.scoring_hand?
if cap_count >= card.ability.extra.cap then break end
if SMODS.pseudorandom_probability(card, 'tby_dbl', 2, card.ability.extra.odds) then
cap_count = cap_count + 1
card.ability.targets[#card.ability.targets+1] = context.full_hand[i] -- here too
end
end
end
if context.repetition and context.cardarea == G.play then
if type(card.ability.targets) == "table" then
for i = 1, #card.ability.targets do
if context.other_card == card.ability.targets[i] then
return {
message = localize('Letter doubled!'),
repetitions = card.ability.extra.repetitions
}
end
end
end
end
true for scoring hand, because if full hand would be used it would be useless since it would not score if it wasnt a word
No, what I meant was the return from the create_card function of your SMODS.Booster will get put into a SMODS.create_card after it is called, if it is not already a card.
in order to do filtered retriggers, you must:
- perform the filter in
context.before, saving targets inside a table incard.ability - check if
context.other_cardis one of the targets, returning{repetitions = num}incontext.repetition
ok so i'm guessing this double word joker wouldn't work either?
AKYRS.LetterJokerTby {
key = "dbw",
atlas = 'TbyJokers',
pos = { x = 0, y = 5 },
unlocked = false,
blueprint_compat = false,
rarity = 1,
cost = 3,
config = { extra = { xchips = 2, cap = 4, odds = 10 } },
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'tby_dbw')
return { vars = { card.ability.extra.xchips, card.ability.extra.cap, numerator, denominator } }
end,
calculate = function(self, card, context)
if context.joker_main and context.full_hand then
local cap_count = 0
for i = 1, #context.full_hand do
if cap_count >= card.ability.extra.cap then break end
if SMODS.pseudorandom_probability(card, 'tby_dbw', 1, card.ability.extra.odds) then
cap_count = cap_count + 1
return {
message = localize('Word doubled!')
xchips = card.ability.extra.xchips
}
end
end
end
end
}
i kinda have a hard time figuring out how this joker stuff works despite trying to read from VanillaRemade
So the way I'm understanding this is:
I don't need that SMODS.create_card because the create_card function will basically pull from the ObjectType already.
i'm hesitating between doubling chips and retriggering all cards tbh
retriggering would make more sense in a scrabble context
And in that case, then this SHOULD work.
iirc the create_card field accepts both table and Card object as return values
there's also another argument called i
But with that, I don't get the Jokers from the ObjectType's pool.
should i just not return at all
on the total
huh
i wanted to multiply the chips because there were too many xmults in aikoshen letter decks
no I mean, where would you like to execute the xchips
scored hand
so each card scored?
this is a bit of a silly question but, can extra variables store arrays?
why not
Yes, they can store anything except functions, Objects, and tables with metatables.
sweet
again i think about it and i guess retriggering all cards to "double the word" would make more sense? either that or xmult and xchips
What am I doing wrong? It's only spawning Jimbos.
try specifying everything needed, like in buffoon packs
yea i suspect maybe the area = G.pack_cards is necessary
I'm specifying everything.
Let's see if it works
SMODS.kill_card("j_Joker")
what's your mod's prefix
WCCO.
Wait, lemme chuck that in.
not in the set
you need it in the joker keys in the object type definition
I need this to work atp
oh wait it's called "crossover pool" it's probably spawning cards from other mods isn't it
or supposed to be doing that
No, it shouldn't be pulling from other mods.
Is my SMODS just cursed or something?
no
Should I try and change the ObjectType key?
honestly, no idea
I don't specify the cards field
I specify the pools field in each joker instead
hm, could someone help me identify the issue here? I tried to implement a queue, however I get an error when entering a shop before any cards are destroyed
send crash screen, otherwise we have no idea where to debug
Lua tables start at 1, not 0
huh
https://www.lua.org/pil/11.4.html wondering why this starts at 0 then...
unless im misunderstanding it
that's a custom data structure being implemented in lua
it's not really relevant to basic lua syntax
yeah, i tried reimplementing the variables the same way in my code
it says unexpected character near } (l:27)
I shifted first to 1 and last to 0 and still got the same error
ok
so
apparently deleting all the logic still causes the error
so
now i dont know what the issue is 😭
Yes, the for i = 1, #context.scored_hand do is missing an end
yeah i saw and fixed that
now its annoying me about
card.ability.targets[#card.ability.targets+1] = context.scoring_hand[i]
specifically the unexpected symbol near =
No, it's because you have , on the line before that.
how do i find the blind of the current anti without being within the blind
G.GAME.round_resets.blind_choices.Boss
this will be the most useful thing i learn about this game 
how do i get a card's edition from context.card?
context.card.edition.key
oh? you need .key? i was able to get it to work with .edition
key = 'bootleg',
shader = 'holo',
prefix_config = {
-- This allows using the vanilla shader
-- Not needed when using your own
shader = false
},
config = {
extra = {
odds = 8
}
},
in_shop = true,
apply_to_float = false,
sound = { sound = "ttv_fart_sound1", per = 1.2, vol = 0.4 },
disable_shadow = false,
disable_base_shader = false,
loc_txt = {
name = 'Bootleg',
label = 'Bootleg',
text = {
[1] = '{C:green}1 in 8{} chance to fail'
}
},
unlocked = true,
discovered = true,
no_collection = false,
get_weight = function(self)
return G.GAME.edition_rate * self.weight
end,
calculate = function(self, card, context) --change from debuff to failed proc
if context.pre_joker or (context.main_scoring and context.cardarea == G.play) then
if SMODS.pseudorandom_probability(card, 'e_ttv_bootleg', 1, card.edition.extra.odds) then
end
end
end
}```
what can I put after pseudorandom to not make a joker proc it's abilities
if the roll fails
how do you make a global like global variable
that can be shared between things like multiple jokers or other calcs
G.GAME.variable = value
wh
then i must be doing something else wrog
im trying to make a joker unlocks when 10 playing cards are destroyed in a run but from my testing it's not unlocking
AKYRS.LetterJoker {
key = "tby_dbw",
atlas = 'tbyJokers',
pos = { x = 5, y = 0 },
unlocked = true,
blueprint_compat = false,
rarity = 2,
cost = 5,
config = { extra = { xchips = 2, xmult = 2, cap = 4, odds = 10 } },
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'tby_dbw')
return { vars = { card.ability.extra.xchips, card.ability.extra.xmult, numerator, denominator, card.ability.extra.cap } }
end,
calculate = function(self, card, context)
if context.before and not context.blueprint and not context.retrigger_joker then
card.ability.targets = {}
local cap_count = 0
for i = 1, #context.scoring_hand do
if cap_count >= card.ability.extra.cap then break end
if SMODS.pseudorandom_probability(card, 'tby_dbw', 1, card.ability.extra.odds) then
cap_count = cap_count + 1
card.ability.targets[#card.ability.targets+1] = context.scoring_hand[i] -- here too
end
end
end
if context.cardarea == G.play then
if type(card.ability.targets) == "table" then
for i = 1, #card.ability.targets do
if context.other_card == card.ability.targets[i] then
return {
message = localize('k_akyrs_db_succ'),
xchips = card.ability.extra.xchips,
xmult = card.ability.extra.xmult
}
end
end
end
end
end
}
ok so basically i want the message and xchips/xmults to apply to cards that got the odds so i lazily copied and pasted another joker but it keeps buggering me with repetitions
what am i doing wrong
and now it just applies the joker as if the odds were 1 to 1
kinda confused on how to make a new card modification category.
How would someone go about changing gold, glass, stone, steel, and lucky cards from enhancement to a different (mod) category?
local table = "j_clown, j_happycat"
if context.pre_joker or (context.main_scoring and context.cardarea == G.play) then
if SMODS.pseudorandom_probability(card, 'e_ttv_bootleg', 1, card.edition.extra.odds) then
SMODS.Joker:take_ownership(table,
{
calculate = function(self, card, context)
end
},
true)
end
end
end
}```
i've tried several deferent things seems the closes i can get to anything is using take_ownser ship
but console keeps telling me the jokers don't exists
i've tried with and without the prefix as well
I'm pretty sure it does, but I just want to make 100% sure
in_pool works for consumables, more specifically spectral cards too, right?
Check the code for blueprint in vremade
has anyone got an example voucher?
I'm just wanting a shell at the moment so i can test art ingame
Apologies for the weird crop. This was a pain to get on phone.
??????????
What's the code
the set or rarity is probably wrong
cant send but the rarity was wrong
Alright
??????? the atlas EXISTS?? ITS USED BY LITTERALLY EVERY OTHER JOKER??
if context.pre_joker or (context.main_scoring and context.cardarea == G.play) then
if SMODS.pseudorandom_probability(card, 'e_ttv_bootleg', 1, card.edition.extra.odds) then
card:set_debuff(true)
else
if G.STATE == G.STATES.NEW_ROUND and card.disabled and card.area ~= G.jokers then
card:set_debuff(false)
end
end
end
end```
it's spaghetti but it works

card.disabled is something you added?
I think it's copy pasted from old code I had
trying to get disables to work
guessing it's not needed
it works in-game
it disables the joker
when onces the round is over enables it back
well thats not what i said
can it say Nope!
probably
SMODS.Joker {
key = "REDACTED",
atlas = "REDACTED_joker_atlas",
pos = { x = 3, y = 1 },
rarity = 1,
order = 1,
unlocked = true,
blueprint_compat = false,
cost = 3,
config = {
REDACTED
},
loc_vars = function(self, info_queue, card)
REDACTED
end,
update = function(self, card, dt)
REDACTED
end,
calculate = function(self, card, context)
REDACTED
end
}```
the same atlas is used by all other jokers in this mod
blind be speaking
anyone got any idea..
what's the atlas code
also sharing this full log can help
SMODS.Atlas({
key = "REDACTED_joker_atlas",
path = "REDACTED/joker_atlas.png",
px = 71,
py = 95,
})
that looks fine yeah
is the png in the correct directory
yes it works fine for every other joker
check for typos
no typos
is the game crashing or is just the sprite wrong
game crash
what's the crash
why is you not look at image i attach
atlas = "REDACTED_joker_atlas",
path is wrong
i litterally copied the atlas part from another joker
that has it working just fine
did u copy paste it correctly
is the new joker loading after the atlas
maybe you forgot a peice of it when copying over
do you have 1x and 2x of the atlas
yes
wait why are there parenthesis
yes
SMODS.Atlas{
2 key = "REDACTED_joker_atlas",
3 path = "REDACTED/joker_atlas.png",
4 px = 71,
5 py = 95,
6}
try this
the parenthesis dont change anything
i said it works fine for every other joker!!
and it makes sense even if redacted!!
gtg
chat im caving i gotta make a joker with scry (look at top cards of deck) how do I do that
G.deck.cards[#G.deck.cards] is the top card, then it goes backwards
if you want a little animation of the cards flipping i have the excavate mechanic (ygo version of scry) in my mod
I think this is good for now
You think a 1/8 odds is decent too much or too little?
that could be cool if its cool with you that i use it
yeah i dont mind
https://github.com/nh6574/JoyousSpring/blob/773063732b1995dbe9977e86ac0859baeabae122/src/effects.lua#L486
should i make a card like mild salsa that adds +1 mult to heart cards like hiker but for mult and only heart cards
how can i have the current hand size
anyone know why this is happening in the shop cardareas?
local oldsetcost = Card.set_cost
function Card:set_cost()
local g = oldsetcost(self)
if self.area == G.elle_spamton_shop then
self.cost = math.max(pseudorandom("elle_spamton_price_" .. self.sort_id, 0, 100), 0.001)
end
return g
end```
G.hand.config.card_limit
if #G.hand.config.card_limit - #context.scoring_hand == 0 then
return{?
No, it would just be G.hand.config.card_limit not #G.hand.config.card_limit
update you lied to me
apparently there is no self.area
so it's nil == nil
what's the correct way to get a card's area here
Yes, because Card:set_cost is called before the card is emplaced into an area.
ah
why what was the problem
i added the escb prefix to the SMODS.Audio key and it proceeded to work just fine even though the message I replied to stated i didn't need to do that
ok it works as intended now
there's probably something else wrong somewhere because you don't need to
smods ignores the prefix so it's not double prefixed too
i dont really care tho anyway because the tag works as intended (ignore the fact you can't make the music stop playing that's a feature not a bug) so i can finally move on to something else
and probably yell about it in here as well
yo chat help would be much appreciated, trying to turn played jacks into stone cards o7
other_card should be context.other_card and change "stone" in the set ability function to G.P_CENTERS.m_stone
ty boss o7 i was just using the code from vanilla remade for that part lol
it can be a string but it was missing the m_
how can i access/change base hand chips/mult values permanently
G.GAME.hands['modprefix_key'].chips and G.GAME.hands['modprefix_key'].mult
awesome
SMODS.upgrade_poker_hands also does that
oh does it support upgrading them by arbitrary values
yep
how so
in this case im just looking to double both values
i don't get it is it just this
pass a custom function function(current, base, parameter) for custom modifications to the parameters in a Poker Hand (if left blank defaults to normal level up method)
i would kill for
a code example
code example lies within level_up_hand
it's been patched to use SMODS.upgrade_poker_hands
i don't know what that means
am I supposed to find the function in the smods code
(how do you even begin with finding that)
Mods/lovely/dump
you know what, I'll do the honor
function level_up_hand(card, hand, instant, amount)
amount = amount or 1
SMODS.upgrade_poker_hands({
hands = hand,
func = function(base, hand, parameter)
return base + G.GAME.hands[hand]['l_' .. parameter] * amount
end,
level_up = amount,
from = card,
instant = instant
})
end
don't specify level_up field and your changes will be permanent
where the hell did you find that
mine looks completely different
I'm so lost
oh you know what
that's probably an old log file
alright well I found that now
this doesn't help
I don't get what the l_ is for and this doesn't tell me what to put in parameter
you dont replace those, G.GAME.hands.key.l_mult is the mult for leveling up the hand
if you are not leveling up then the operation should be different
like base + amount
but it's concatenating a string how does it do that with two different values
it runs for every single parameter (i.e. chips, mult, any other modded parameter)
oh oh oh right so you don't change parameter
granted all of this im deducing from reading the code there i never used this
yeah its pretty new and im fuckin stupid
maybe what somethingcom said is easier but i remember modifying the chips/mult directly used to reset when the hand was leveled up
idk if thats still true
G.GAME.hands[hand].chips and G.GAME.hands[hand].mult
is there G.GAME.hands[hand].level or should I not use that i mean
i guess this is a preference thing idk if I should double the hand's "level" when i double its chips and mult
it would be stronger if it changes the levels so I'm leaning towards that cause it could open some synergies or something
uh
I set base chips to 10 before using Pluto
does G.GAME.hands[context.scoring_name] exist during context.after
yes
cool
is there a context that runs right after the first hand is drawn
context.first_hand_drawn
nice
if context.after and G.GAME.hands[context.scoring_name] then
SMODS.upgrade_poker_hands({
hands = { G.GAME.hands[context.scoring_name] },
func = function(base, hand, parameter)
return base * 2
end,
from = card,
instant = true
})
end
this is crashing instantly on playing hand what did I do wrong
hands = context.scoring_name
some contexts run a lot while jokers are highlighted, not sure which ones, but if you have anything on lazy updates it could be causing it
i have a joker on lazy updates that runs constantly when highlighted so thats what im basing this off
perhaps you're just doing a lot during those contexts
i would also like to shake the screen that sounds fun
G.ROOM.jiggle = number
thx
are card.T.x and card.T.y the position of the revealed cards
i'd like to display them below the joker that reveals them instead of over the deck
oh i almost have it actually
every time i try to change T.y the card just vanishes
oh they're just very small numbers
i see
What's in generate_card_ui() responsible for setting name?
Changing specific_vars.name doesn't change name
this line (and the ones before conditionally)
keep in mind this is not a string, localize returns a ui structure with the name
I am still uncertain on where each UI part is generated.
Name, descriptions, whatever the fuck is on main_end, info_queue
the flow is all inside generate_card_ui, generate_uibox_ability_table and g.uidef.card_h_popup
they use localize a lot obviously
strangely specific circumstance here
i need to scale a joker every time a function is run and outputs a value
whats the best way of doing this without live update
i am hooking the function which is to say its not my function
iterating through all the jokers and manually incrementing feels
inefficient for a function that will be happening lots of times
eh i did it that way anyway
call a context
hmm
i thought calculate context was for joker effects
but also im a little lost
how does it know what context to run
if the context name isnt put in calculate effect
oh im just stupid thats calculate context
not effect
i still wanna know how it knows what context to run
i figured it out
i should probably set it to get notifications for pings
I know you said you figured it out but I will put an answer here in case you missed anything/someone else has the same question.
Calculate context is a function used to run calculation events at any moment in time that you wish. You create your own context (a context is just a key-value table) with whatever information you need to pass in. For example, SMODS.calculate_context({my_special_context = true}) could go in a function hook, and then you could do if context.my_special_context then in any objects calculate function and it would trigger at the appropriate timing.
There are some more advanced uses if you need to handle return values specifically, but as a base, that should cover most uses.
the thing that im confused about is why the code example on the vanillaremade wiki runs calculate context twice
(addendum: it's good practice to put your mod prefix in custom context names)
the one it runs during the hook doesnt have modprefix_context_name
so how does it know what context to run
it not twice, the first part is the code and the second an example
oh
i can make them different boxes
it looked like it was all in the example
anyway hiii eremel :3 I hate to be a pest about smods PRs but I did just open a new one yesterday
I saw
I have some concerns about it from the description but I haven’t looked at the code to see how it works in practice
I see
I think abstractly it's a good idea to have some support in smods for adding title screen cards, but I'm certainly up for redoing the implementation
Yes it’s on the list of future features
I think the way you’ve chosen to access the cards is incredibly fragile and unreliable
It might be better to return a table of actual cards rather than the add_card args
That way any modifications can be done prior to them being sent to the handler
hm I see
There’s no way to guarantee the card you want otherwise
oh you can pass key = "something" just like with create_card
and all the other SMODS.create_card arguments like edition and whatnot
the example I gave used set because I specifically put in the randomization support for set
Hi modders and others! As of now, we’ve introduced the <@&1460584319486791871> role, exclusive to moderators meant to look over the modding chats
(as of now, me).
If there’s an issue regarding the people or modding specifically, please ping the modding mod role. However, if something such as a scam bots sends a message, pinging mods normally is heavily encouraged.
This is applicable to all of the modding channels, not just this one. I’m here for yall dw 🧡🧡🧡 much love everyone
-# won’t be pinned here
oh I see
yea I'm a bit iffy on that one in general, the main reason it's there is because ruby suggested something of that nature
Sorry for interrupting
no worries lol
I think it is specifically useful only for the first card
yea lol
the only case i've really seen of a mod modifying a card that isn't the vanilla ace is entropy replacing the cryptid that cryptid adds
maybe the menu_cards function could just receive the vanilla ace directly as an argument
(or all of G.title_top.cards)
Yeah, I’m not sure atm. I think it would be useful for a function to define behaviour that can’t be don’t through create_card but finding the right card to modify could cause an issue
i think it might be better to just give them keys at that point
I’ll try get a proper look this week though, as it’s a feature I’ve already done some thought/discussion about before it shouldn’t get stuck in PR hell for too long
how do i add so this mult hiker only add it to a specific suite
key = 'mildsalsa',
loc_txt = {
name = 'Mild Salsa',
text = {
}
},
atlas = 'jokers',
rarity = 1,
cost = 3,
unlocked = true,
discovered = true,
blueprint_compat = true,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {extra = {mult = 1}},
loc_vars = function(self, info_queue, card)
return {vars = {card.ability.extra.mult}}
end,
calculate = function(self, card, context)
if context.individual and context .cardarea == G.play then
context.other_card.perma_bonus = (context.other_card.ability.perma_bonus or 0) +
card.ability.extra.mult
return {
message = localize('k_upgraded_ex')
colour = G.C.MULT
}
end
end,
}```
for the specific suit part you should check one of the suit jokers
for the perma mult: https://github.com/Steamodded/smods/wiki/Perma-bonuses
man i love xnil mult (i don't know how to do this properly)
i hope this is correct
key = 'mildsalsa',
loc_txt = {
name = 'Mild Salsa',
text = {
}
},
atlas = 'jokers',
rarity = 1,
cost = 3,
unlocked = true,
discovered = true,
blueprint_compat = true,
perishable_compat = false,
pos = {x = 0, y = 0},
config = {extra = {mult = 1, suit = 'Hearts'}},
loc_vars = function(self, info_queue, card)
return {vars = {card.ability.extra.mult, localize (card.ability.extra.suit)}}
end,
calculate = function(self, card, context)
if context.individual and context .cardarea == G.play
and context.other_card:is_suit(card.ability.extra.suit) then
context.other_card.perma_mult = (context.other_card.ability.perma_mult or 0) +
card.ability.extra.mult
return {
message = localize('k_upgraded_ex')
colour = G.C.MULT
}
end
end,
}
#1# refers to the first value returned in loc_vars, #2# the second, etc. Theyre not the numbers displayed
i think i tried that but it threw the xnil on the currently amount instead (for some reason)
i'll reboot again tho just to make sure the code wasn't fucking with me
ah wait no problem found i think
ok i just juggled a bunch of the stuff around and that seemed to do the trick
works like a charm
How do I trigger the "hand will not score" message?
and like how to I only trigger the message on only one condition, preventing it from triggering anywhere else
(I'm making a boss blind, for context)
is there an easy way to get cards to return to the hand after they are played
have you look at the code for the blinds that do that
eremel is working on this for the next smods version iirc
dammit id like to do it now if possible
i wouldnt know personally
i only know one example and its betmma vouchers
I dont even wanna begin trying to understand betmma code
Couldn't find anything iirc
you couldnt find the code or you didnt know how it worked?
It’s on dev branch
Release estimated on 29th ish
a bit of both
when you say dev branch do you mean latest source code or a different github branch
you just need to return debuff = true in context.debuff_hand https://github.com/nh6574/VanillaRemade/blob/9b0f346ee534f855416100b316e8eccfcb314c77/src/blinds.lua#L352
im not sure making my mod depend on an smods dev version will be a good idea
will make note of it for the future
The latest source code is the dev branch, yeah
I wouldn’t recommend depending on a non release build at all though
How do I check the first and last card of a played hand?
played hand or scoring hand
Cuz I want a joker that if (id of first card) is (id of last card), gives like 10 mult
either way, refresh yourself on this https://github.com/Steamodded/smods/wiki/Calculate-Functions
hey fellers, so basically i'm trying to make a joker similar to pareidolia, but just for figures
-- 3. Logica di valutazione della mano (fuori dalla definizione)
local evaluate_poker_hand_ref = evaluate_poker_hand
function evaluate_poker_hand(cards)
-- Controlla se possiedi il joker (usa il prefisso corretto se necessario)
local has_trinity = next(SMODS.find_card("j_trinity"))
if has_trinity then
local original_ids = {}
for i, card in ipairs(cards) do
original_ids[card] = card.base.id
-- Se è J, Q o K, trattalo come un 11 (Jack)
if card:is_face() then
card.base.id = 11
end
end
local ret = evaluate_poker_hand_ref(cards)
for i, card in ipairs(cards) do
card.base.id = original_ids[card]
end
return ret
else
return evaluate_poker_hand_ref(cards)
end
end
i did not know i could return a function with a joker...
stickers = {'perishable'}
thats a function hook
thats strange, why is the parameter for eternal so special that it has its own thing?
i believe those are the vanilla ones and stickers is smods?
I was thinking that but I didn't want to assume things, thx for confirming
i mean i am assuming
oh ok lol
Oh thanks, i've had lost the messages
I guess that is a logical conclusion
no, i mean outright
in the same area as the chips and mult returns
thats what im saying, that code doesnt have calculate. it is a separate function hook from the joker
so the joker is not returning anything
key = "dawgium",
set = "xiferp_Element",
atlas = "Golden_Brick_Road",
cost = 3,
pos = { x = 9, y = 6 },
unlocked = true,
discovered = false,
config = { extra = { element_no = 98, odds = 29, yes_is_no = false }},
keep_on_use = function(self, card)
return true
end,
can_use = function(self, card)
if card.ability.extra.yes_is_no == false then
return true
end
end,
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'c_xiferp_dawgium')
return { vars = { numerator, denominator } }
end,
use = function(self, card, area)
yes_is_no = true
end,
loc_txt = {
name = 'Dawgium',
text = {
'Adds x5 mult per first and last card',
'in your next five-card hand.',
'(1/29 chance to radioactively decay)',
},
},
calculate = function(self, card, context)
if card.ability.extra.yes_is_no == true then
if context.individual and context.cardarea == G.play then
if context.other_card == context.scoring_hand[#context.scoring_hand] then
G.GAME.xiferp_rowseven_xmult = (G.GAME.xiferp_rowseven_xmult or 1) + 5
SMODS.destroy_cards(card, nil, nil, true)
end
end
end
if context.individual and context.cardarea == G.play then
if SMODS.pseudorandom_probability(card, 'c_xiferp_dawgium', 1, card.ability.extra.odds) then
SMODS.destroy_cards(card, nil, nil, true)
SMODS.add_card({ key = 'c_xiferp_curium' })
end
end
end
}```
Not only is this cardd not doing anything, it's not even getting used.
yeah probably because
you arent even setting a variable on the card
you need the card.ability.extra there
where?
in the use
and for the "it's not even getting used" part
you have a keep_on_use function set up to always return true
It is staying, it's not leaving when it should have been used
Okay, that chunk of code is now read, but still no x5 mult
Supposed to be on the last card of a 5-card hand, I played a 5-card hand with Dawgium, and no x5 mult
you arent even returning any xmult
Hang on...
local give_xmult = G.GAME.xiferp_lineseven_xmult or 0
return { xmult = give_xmult }
end```
this is in the same file, so clearly I am
less code doing it this way
fine
No dice
the code reads " if context.other_card == context.scoring_hand[#context.scoring_hand] then xmult = (G.GAME.xiferp_rowseven_xmult or 1) + 5
I play a scoring hand, and no xmult at all
just return xmult = 5 ??????
also
return in the first place
instead of arbitrary xmult = ...
if card.ability.extra.yes_is_no == true then
if context.individual and context.cardarea == G.play then
if context.other_card:is_suit(card.ability.extra.suit) then
G.GAME.xiferp_lanthanide_mult = (G.GAME.xiferp_lanthanide_mult or 0) + 20
SMODS.destroy_cards(card, nil, nil, true)
end
end
end
end
}```
snippet of one such card
answer
why do you have a convoluted system to do something that is a single line of code
also its return { xmult = ... } and not xmult = ...
It was less stress in the moment
for me
GOTCHA
have you considered #1386843228330004611?
brutal
@unkempt bronze you may want to considering trying Joker Forge
the double down is crazy
double down like from blindside
NO
If I want my cards made, I'll make them myself and test them
The slander is funny but it's good that you're here trying to learn and do things the hard way
If they fail, I'll try to work at it until they don't
Don't let your mistakes discourage you from trying ❤️
alright then good luck with your future endeavours
its all a big learning experience, just remember to use all the resources
vanilla remade, smods wiki, others mods are all great examples
there are seldom ideas you are trying to do starting out that havent been done before so there are no shortage of places to learn
same to you
even a trivia boss blind?
probably out there somewhere, people have made some wacky blinds
It would be easier if there was a definitive place to start from that would link to all of these things, cuz everything's kinda disjointed
It takes some research to find all the resources you can use
the modding resoruces tab has a few so far, otherwise just seatching through github is a good way to stumble
i think you might have to do this one yourself
no
(read: I don't want to do all of that, I struggle with coding a single card as it is)
if you struggle with making a single card then making like custom buttons and ui and all probably isnt an amazing next step
Gotta start small and get experience
If anyone wants to try to help with that boss, please do and thanks
does anyone know how i'd go about triggering an edition multiple times without just fully retriggering the card?
if context.other_card == context.scoring_hand[#context.scoring_hand] then
any clues as to why this isn't accivating the last card of a hand?
context.other_card is evaluated together with something else
you need another context i.e. context.discard
What is card.T.x? Tryna see how Death works
Tbh why does Death's code in vremade accomodate for using it on any number of cards instead of just two
Just for educational purposes?
it's the x position on the screen
I wonder why it's done this way instead of like local rightmost_card = G.hand.highlighted[#G.hand.highlighted] or something
because that table is in highlighted order
Oh wait really? Dang
also it doesnt, the only part that does i think its generic to the cards with the same animation
where on earth is the code that handles subtracting hands/discards when a hand/discard is used
found it
how do i spawn a speciific rarity of joker from a pool like "Food"
I have a sticker that has a chance of applying a debuff to the joker when a hand is played, but I'd like it to only apply for that hand, but the sticker doesn't run its calcs when it's debuffed so not sure how to approach it
set = "Food"
i didn't ask how to spawn it
how do i spawn it so that its from a specific rarity and pool
i think the objecttype needs to be set up with rarities
you could add an undebuff calculation to your mod object calculate function
I'm trying to make an unlock condition for one of my Jokers, "Own two Jokers (Jimbos) at once". This is what I have right now to test it, at this point no messages are printed when I add obtain a Jimbo. Not sure what I'm doing wrong, but if I had to guess it's probably something to do with how it's checking the key?
if context.card_added and context.cardarea == G.jokers then
if card.config.center.key == "j_joker" then
G.GAME.jimbos_owned = G.GAME.jimbos_owned or 0
G.GAME.jimbos_owned = G.GAME.jimbos_owned + 1
print("Jimbos owned: " .. G.GAME.jimbos_owned)
if G.GAME.jimbos_owned >= 2 then
check_for_unlock({type="jimbos_owned"})
end
end
end
where is this code in
it's in a separate file called calc.lua, it's where I've made the logic for most of the unlocks in my mod and it's worked so far
I'll try adding this code to the joker instead
see what it does
no I was asking because putting it in the joker definitely doesn't work
oh
context.card_added doesn't have a context.cardarea
take that part out of the if statement
Chat does anyone have an easy pointer for how to have a joker spawn tags?
I’m making one that’s essentially just To Do List and it pays out with tags
Ideally it’s specific tags, but still
I think all you need to do is add_tag(Tag("tag_key")), where tag_key is the full key of a tag (like "tag_rare" or "tag_modprefix_something")
there used to be extra work involved for specifically orbital tag but smods should handle it automatically now
👀
and how would i do that
I believe there's a way to make it so it creates a tag from a pool of tags you choose, though I haven't made something like that yet
I am aware of some consumables from mods that do this though
no idea
the way is to just randomly pick a tag with a pseudorandom function and then do what meta said
ah neat
Think ExtraCredit has something like that, so I'll see about cannibalizing that code
if you need to pick any tag vanillaremade wiki has the code for that
Good to know! Where should I look for that? I browsed over To Do List, Cola, and the Tags section already but wanted more input
the github wiki not the repository
Is it complicated to make animated jokers?
not anymore, the latest smods release added support for animated sprites pretty much everywhere
documented here https://github.com/Steamodded/smods/discussions/1131
you'll want to put every frame of the animation in a row on the atlas, one after the other
#x# is the index of your returned variables
literally just replace #0.003# with 0.003
as you can see #1# is chips so it will show 5 (and not 1), #2# is numerator and #3# is denumerator)
so this shows
wouldnt hard setting description text fuck with shit like oops all 6?
idk i use jokerforge, in which its modifier compatibility is minimal
i mean sure, it has oa6 support baked in, but that's about it
because if u put text instead of the variable returned, you would not get the prob updated like this
no no, i do oa6
jokerforge probably shits out a proper description tho
debatable (it uses loc_txt instead of a central localization file, and some really weird formatting for how the text is laid out)
i can't debate i dont use jforge
yeah if you want to have modifier support, you gotta painstakingly replace each number with a variable
"painstakingly"
it is when you realize you forgot some somewhere and you need to look through all 80 jokers
loool
just put the variables in in the first place :clueless:
btw don't put "end" as a variable, it breaks stuff
Any mod that removes tarot animations completely? If not, how hard would it be to develop?
handy's animation skip probably does that (but also a lot more)
I haven't been able to find how to use animation skip on handy, I'll take another look at it. I can put the speed up to 512x but wanna remove animations completely
was in the middle of testing my mod in a multiplayer game and an asteroid crashed me since i had some custom hands defined, would it be as simple as patching this hand priority list in networking/action_handlers.lua? not sure if other people have made their mods mp compatible and if its this simple
or function()
local hand_priority = {
["Flush Five"] = 1,
["Flush House"] = 2,
["Five of a Kind"] = 3,
["Straight Flush"] = 4,
["Four of a Kind"] = 5,
["Full House"] = 6,
["Flush"] = 7,
["Straight"] = 8,
["Three of a Kind"] = 9,
["Two Pair"] = 11,
["Pair"] = 12,
["High Card"] = 13,
}
local hand_type = "High Card"
local max_level = 0```
It's definitely in there somewhere. You could also try the handy beta
Chat am I fucking stupid
cant see shit in that screenshot
probably something on one of the lines before it
^ show the entire joker definition
key = "malvi",
blueprint_compat = true,
rarity = 2,
cost = 6,
pos = { x = 4, y = 11 }, -- change these
atlas = "corru_atlas",
config = { extra = { flavours = {'tag_polychrome','tag_negative','tag_rare','tag_investment','tag_voucher','tag_handy','tag_garbage','tag_coupon','tag_double','tag_economy'}
}, poker_hand = 'High Card' } }
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = {key = 'tag_investment', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_voucher', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_polychrome', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_negative', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_handy', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_rare', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_garbage', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_coupon', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_double', set = 'Tag'}
info_queue[#info_queue+1] = {key = 'tag_economy', set = 'Tag'}
return { vars = { card.ability.extra.flavours, localize(card.ability.extra.poker_hand, 'poker_hands') } }
end,
calculate = function(self, card, context)
if context.before and context.scoring_name == card.ability.extra.poker_hand then
add_tag(Tag(pseudorandom_element(card.ability.extra.flavours, pseudoseed('malvi'))))
end
if context.end_of_round and context.game_over == false and context.main_eval and not context.blueprint then
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
_poker_hands[#_poker_hands + 1] = handname
end
end
card.ability.extra.poker_hand = pseudorandom_element(_poker_hands, 'vremade_to_do')
return {
message = localize('k_reset')
}
end
end,
set_ability = function(self, card, initial, delay_sprites)
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
_poker_hands[#_poker_hands + 1] = handname
end
end
card.ability.extra.poker_hand = pseudorandom_element(_poker_hands, 'vremade_to_do')
end
}```
oh that's
hang on
you have one too many closing braces for your config table
^ and missing a comma
comma is which line?
the end of your config table as well
oh nice thanks, just blind
realizing that VanillaRemade does not include the descriptions so lol
by talos it works
i love when my shortcomings stem from syntax
thank you!!
I will be back tomorrow most likely
that worked, thanks!
also, does anyone know how to split all (using overflow mod)? I have split one and split half, but I saw on dr spectered's video he split all at the same time
it uses a localization file, like mods should
How could one make all music play in reverse?
So I've never actually tried to do controller support before - does anyone know how the mod page icons do hovering for controllers?
Trying to make a voucher that replaces the leftmost shop slot with a joker that isn’t common or uncommon.
how do you replace leftmost shop slot
SMODS.Voucher {
key = "industryconnections",
loc_txt = {
name = 'Industry Connections',
text = {
"Rightmost {C:attention}shop slot{} is always a {C:attention}Joker{} that isn't {C:common}Common{} or {C:uncommon}Uncommon{}",
}
},
atlas = "ic",
pos = { x = 0, y = 0 },
config = { extra = { shop_slots = 1 } },
loc_vars = function(self, info_queue, card)
return { vars = { lenient_bignum(card.ability.extra.shop_slots) } }
end,
redeem = function(self, card)
local _, key = pseudorandom_element(SMODS.Rarities, "industry") if key == "common" then key = "rare" end if key == "uncommon" then key = "rare" end if key == "cry_cursed" then key = "cry_exotic" end if key == "crp_abysmal" then key = "crp_mythic" end if key == "unik_detrimental" then key = "unik_ancient" end if key == "valk_supercursed" then key = "valk_exquisite" end
local card = SMODS.create_card { set = "Joker", rarity = key, edition = 'e_negative' }
create_shop_card_ui(card, "Joker", G.shop_jokers)
card:set_cost()
card:start_materialize()
G.shop_jokers:emplace(card)
end,
calculate = function(self, card, context)
if (context.reroll_shop or context.starting_shop) then
local _, key = pseudorandom_element(SMODS.Rarities, "industry") if key == "common" then key = "rare" end if key == "uncommon" then key = "rare" end if key == "cry_cursed" then key = "cry_exotic" end if key == "crp_abysmal" then key = "crp_mythic" end if key == "unik_detrimental" then key = "unik_ancient" end if key == "valk_supercursed" then key = "valk_exquisite" end
local card = SMODS.create_card { set = "Joker", rarity = key, edition = 'e_negative' }
create_shop_card_ui(card, "Joker", G.shop_jokers)
card:set_cost()
card:start_materialize()
G.shop_jokers:emplace(card)
end
end,
}
how do you make this voucher not spawn a second card after reroll or sum
ok nevermind it just works now wtf
Holy key check
i'd recommend a dictionary check over the numerous if statements tbh, like an index of the before and a value of after, e.g.
local keyDict = {
common = "rare",
uncommon = "rare",
cry_cursed = "cry_exotic"
}
with something like if keyDict[key] then key = keyDict[key] end, fairly certain that would work
whats the function for the main menu button i need to hook it
G.FUNCS.go_to_menu
just dumping my process here
that was i initially did, gave me xnil on the currently amount, i tried switching it to the text unknowing about how exactly it worked, and when i switched it back and wondered what the fuck was the problem, i switched the positioning of the variables in loc_vars and APPARENTLY that did the trick???
mind you this is just the text, i haven't tested the joker actually working because i haven't found it in a run and i cant bother to use the debug menu
obligatory curator plug
#1418332561771593809 would make finding jokers from specific mods easier i mean cough
duly noted
ive been having trouble finding the jokers (one of them spawned out of a buffoon tag i got from the adrenalina tag i coded a while ago which was absolutely funny)
so that'll help
how can I prevent the player from pressing play hand/discard for a set time
uhoh that's not right
it just doesnt show values past 3 decimals
but they are still there
it's x1.012 mult
or .015 or .018
it truncates
what does that even mean
it's a reference to the song the joker is referencing
they're all references to eurovision songs in this mod
oh
its prob because end_of_round hits like 8 extra times unless you add
and context.main_eval
i'll try that real quick
hm the number jumped up by x0.02 even with the context.main_eval put in
and it did it again after the next round i'm confused
Hook G.FUNCS.can_play and G.FUNCS.can_discard
i tried that
when i tried to replace the buttons' functions with dummy functions the game crashed
returning false before completing the hook didn't work either
You would just do e.config.colour = G.C.UI.BACKGROUND_INACTIVE e.config.button = nil and not run the original function.
also implementing the scoring (aka the thing that actually makes the mult go off) crashes the game
the context.joker_main looks like it's outside of the calculate function
i'll try and pop it right after the multgain to see if that helps
ok that seemed to do the trick
need to test the joker first tho
ok the joker might have suddenly started adding the right amount of xmult randomly
i love it when code works and there's no reason fo it
How do I make like a poker hand that is weaker then high card but only triggers if 5 cards are played and the lowest card is under the rank of 5 basically taking the idea from phanta mod
<@&1133519078540185692>
Bam
Consider playing around with context.create_shop_card, return of which should contain a table that you'd pass into SMODS.create_card.
You'd probably have to force Balatro to use a buffer for playback, which is filled by reordered samples from back to front. 
odds dont update old cards
for example u test a card and ur not satisfied so u close ur game and change the odds, ur card in the save will have the same odds
but u can spawn a new card with ur new odds from ur joker menu or smth
i wasn't even testing the functionality of the card at the time, just the joker description which i know updates on a save (source: me doing it to add a song lyric to the other joker ive made)
well either way i was looking in the collection so
what matters is the joker works as intended so
once I get art ill probably commit
ive been doing this while the joker has absolutely no art at all
what does it do
gains x0.003 mult every round (starts at x1)
ioo
invisible joker wishes it could be this invisible (its intentional i dont have the art right now)
is there a way to add a word wrap if text gets too long?
with attention_text
offset doesn't seem to work
or atleast have the text shrink if it gets too long
I think I figured something out
with maxw
well that didn't work
just makes the text smaller
Anyone know if context.getting_sliced has a way to get the card that’s doing the slicing?
Can’t really find info on context.getting_sliced in general
Sorry not context card
Nvm
card.getting_sliced just prevents the card from calculating for event reasons
so its just a boolean
Yeah I ended up figuring it out after looking into the dagger code on vanilla remade
Still works for my purposes I’m just attempting to make a card that has custom effects if it gets sliced by dagger
Since madness and possibly other modded guys do it too I’m trying to implement a check to make sure its dagger specifically
Is there a quick and snappy way to check if a single joker has no edition?
Something along the lines of “if card.edition == nil”
just do if not card.edition then
if it's to the right of dagger and not eternal?
Gotcha thank you
Yeah I ended up doing that
Joker normally dies upon beating a boss blind so it’s set to be incompatible with eternal anyways
something about pools?
I ran eval G.P.CENTER_POOLS.CrossoverPackOne and it found all the Jokers no problem.
So it can't possibly be that the ObjectType is incorrect.
The only thing I can think of is that the SMODS.create_card is somehow incorrectly made.
Issue: having it as set still doesn't make it work.
yeah i dont know why not
I've tried using pools instead of create_card, multiple variants of SMODS.create_card, and honestly, I'm thinking of hard-coding them in the pack.
are the jokers in the pool
i dont mean in P_CENTER_POOLS, i mean if theyre allowed to appear
Oh my god. They've all been set to in_pool = false this whole time, and I never bothered to check that.
Time to fix that and I'm gonna take a year-long hiatus.
Wait, no, because that wouldn't stop them from spawning in packs, that's only for the shop, right?
And these Jokers are only supposed to be in the pack.
its for any random method
so including packs
if you want them to be pack only add a key_append to your create card and check for that in in_pool
You know, that kind of makes sense. But I got the pack working through hard-coding, so ultimately, I'll take my win and shut up now.
I'll write that down for later, though
So about this: How exactly do I implement this?
I’m trying to check if a joker in a specific spot is a specific joker
Trying to do it by doing something like
“if the_card.key == “key” then”
Could be I’m not putting the key properly but I think it might be something else
the_card.config.center.key
Thank you
Figured it would be something like that but I always struggle to know the exact syntax to use
You do not know how much I am celebrating getting this pack working as I dreamed.
Small question: For weight, what exactly is the scaling on that?
trying to make a deck that unlocks when Red AND Blue Deck are beaten, why doesnt this work
ok can someone tell me what this on-load crash is about i dont understand what its trying to tell me
does it not like the file name?
you can't beat two decks at the same time, you need to set some global probably
it's a syntax error
show the code
the "error processing file" part comes from using SMODS.load_file, keep reading the rest of the line and you'll see the actual error
and yes post code
you have so much code in a return table
that's not how that works
jokerforge has so much code in a return table*
i figured it was jokerforge
you're gonna have to code this yourself
wah i dont fucking know lua :(((((
even if all the syntax is fixed up, this'll copy a random joker, not the leftmost joker 😭
currently just deleting everything that breaks so that i can playtest without having to fix it
because if i tried to fix it now, it'll probably just end up more broken lol
this is awful
please do it from scratch
oh
i see now
nvm its still trying to index a nil value
oh woops, notepad + didn't save
vol = 0.6,
pitch = 1.0,
key = "music_drop",
path = "music_Drop.ogg",
select_music_track = function()
return SMODS.Mods.jamod.config.Drop and G.STAGE == G.STAGES.MAIN_MENU
end
}``` the song wont go back to base's song for some reason
nevermind its fixed
function Card.highlight(self, is_highlighted)
if is_highlighted and self.ability.set == "Joker" and self.area == G.jokers then
self.children.jabong_fih = fishop_ui(self)
elseif self.children.jabong_fih then
self.children.jabong_fih:remove()
self.children.jabong_fih = nil
end
return highlight_ref(self, is_highlighted)
end```
ignore that is is stolen from vremade, how would i make this detect just the specific joker
self.config.center.key == "j_modprefix_key"
the card that has the enhancement or another card?
the card that has the enhancement
you would need to do it somewhere else like mod calculate because the enhancement wont run while debuffed
ah ok
what does
"Found effect table with no assigned repetitions during repetition check"
mean
it means your code is returning in context.repetitions without returning repetitions
most likely one of your context checks is not strict enough
ok
Is there a mod that will help with insane hand size, reserved parking, mime loops? Using talisman, handy, cartomancer, and it still takes wayyyy too long to add up money
Without talisman it just crashes and with talisman it takes several minutes to elapse all calculations
tf you doing man
Breaking the game
Basically, I need to optimize performance so my potato doesnt crash with hundreds of jokers
I have animation skip on everything (not unsafe though). But I also have like 4 different mods that help w animations and performance
I'm talking like in the thousands of hand size + jokers. No clue how to make it work.
I'm in the low hundreds rn and it won't work, and I need it to be able to handle a million times more basically
Bigmem does absolutely nothing fyi
Its coded entirely by ai and is complete nonsense
I have never heard of that
I just have talisman, handy, and cartomancer for performance right now
where to download cryptlib
try Yorick
other than that i dont think there are any performance mods
what would the implementation look like in this function?
key = 'Winds',
card_key = 'Wi',
lc_atlas = 'bm_honors',
hc_atlas = 'bm_honors',
pos = {x = 0, y = 0},
ui_pos = {x=0,y=0},
keep_base_colors = true,
in_pool = function(self, args)
if G.GAME.selected_back then
//condition if the rank is x return false
return string.find(G.GAME.selected_back.effect.center.key, 'b_bm_mahjong')
end
end
}```
args and args.rank == "key"
nice, i'm just gonna pull a yanderedev and
key = 'Winds',
card_key = 'Wi',
lc_atlas = 'bm_honors',
hc_atlas = 'bm_honors',
pos = {x = 0, y = 0},
ui_pos = {x=0,y=0},
keep_base_colors = true,
in_pool = function(self, args)
if G.GAME.selected_back then
if string.find(G.GAME.selected_back.effect.center.key, 'b_bm_mahjong') then
if args and args.rank == "bm_North" or
args and args.rank == "bm_South" or
args and args.rank == "bm_East" or
args and args.rank == "bm_West" then
return true
end
end
end
end
}```
I could make a table and iterate over it
key = 'Winds',
card_key = 'Wi',
lc_atlas = 'bm_honors',
hc_atlas = 'bm_honors',
pos = {x = 0, y = 0},
ui_pos = {x=0,y=0},
keep_base_colors = true,
in_pool = function(self, args)
if G.GAME.selected_back then
if string.find(G.GAME.selected_back.effect.center.key, 'b_bm_mahjong') then
local legal_ranks = ["bm_North", "bm_East", "bm_South", "bm_West"]
for i = 1, #legal_ranks do
if args and args.rank == legal_ranks[i] then
return true
end
end
end
end
end
}```
ok fine
that's not how it works
forgot a return false
local legal_ranks = {
bm_North = true,
bm_East = true,
bm_South = true,
bm_West = true,
}
if args and legal_ranks[args.rank] then
return true
end
didn't know lua had support for that
nvm
im trying to make it so you cant sell a specific card, but it errors attempting to index config, a nil value
G.jokers.cards is a list of jokers in the joker area
you want self.config.center.key
aight thanks
is there a way to get the yorick mod to preserve eternal stickers when merging jokers together?
I think I'll delete yorick mod because of this and it doesnt properly copy burglar or certificate
stacking jokers is hard sadly
yeah it doesnt even copy mime and reserved parking properly 🙁
I'll just go back to hiding all my jokers using cartomancer mod
Not too big an inconvenience though because I have a program where I can edit my save file to automatically sort thousands of jokers
Explain why scoring e500 takes maybe 10 seconds to process but making $10,000 takes a full 5 minutes to process
well, I have little coding knowledge but it's looking like I'm going to have to literally make a mod to speed up money scoring, and make a mod to hide/stack/simplify giant hand size
it depends on the amount of operations not the score
if you get e500 in 10 operations its going to be slower than $10000 in 1000
obviously the real numbers are higher
yeah makes sense. with just 200 jokers, I have 4 mil operations that have to trigger, and it just scales exponentially as I get more
i would just recommend not playing with that amount of jokers
then you have to endure the times
:(((((
literally will be unplayable lmao
I'd have to leave my pc running for a month straight to process one hand at this rate
I'll figure something out
yes and we usually tell people that if they have to wait more than like 1 hour to treat that run as won and move on
I could always just abort and then use console to give myself the calculated amount of money, but that's not very cool
it's not about winning the run
it's about breaking the game to a disgusting level
my point is not to dissuade you from playing the style you want (although i personally find it incredibly boring) but to spare you the time wasted on this
long calculation times are a common problem since cryptid is a very popular mod
at this rate, yes, it would be a waste of time
also this will be in vanilla lmao
the only options are justify using console which is not ideal, or coding something from the ground up specifically for reserved parking money
What program should I use for actually writing the mod? Saving text files as .lua does not feel like the best system
Thank you! I didn't realize VanillaRemade also had a wiki, this is good to know
I'm using overflow but sometimes it doesnt merge all and I have to manually merge about 15 different smaller stacks. Any way to fix this?
Also is there a way to split all? (instead of repeat split 1)
All the links on the VScode github cannot be found, do you have any suggestions?
btw i would recommend asking non-dev questions in general or support
what do you mean
ok
When I click the download link on https://vscodium.com/, it takes me to here: https://github.com/VSCodium/vscodium/releases. From there, every link I have tried takes me to a 404 not found page
oh, try the ones from the previous release those seem to work
Ok, thank you !
Hello everyone, I was trying to make a card enhancement but the game kept crashing. What seems to be the problem?
does anyone have the coding knowledge to help me make a mod that can handle millions of reserved parking triggers and speed it up😭
Nope, sorry man
post the crash too
I figured lol🥲
is there a list of every context ?
there is not some more probably forgotten context
i think this was missing one but it got a rewrite recently so 99% are here
oh nice yeah I see its not like I remember
ok so the enhancement works now but when trying to view the enhancements in the collection, the game crashes
I've updated SMODS and most of my other mods where possible, but the game just crashes whenever I try to play any hand.
I have no idea how I have even caused this.
[I do apologise if I have posted in the wrong channel again]
Arguably it is regarding a mod I am making since it is difficult to playtest my own mod if I cannot play a hand.
if this is not about a mod you're making then it should be in #⚙・modding-support
try switching talisman for amulet if you have it
Alright, I don't know how well Amulet will work with Talisman dependent mods. [I also do not currently have it, so I shall work on acquiring it]
it should be a drop in replacement
Over Talisman or replacing talisman?
Right, that makes sense.
After removing two mods that no longer worked, playing a hand brought up this error instead.
For context, I am running the latest version of Cryptid, and the latest version of amulet I could find on the internet.
again, #⚙・modding-support
Is there a way so my variable doesnt get reset when I continue the run its just reset when the run is started
You need to save it to G.GAME
also for runs you need to hook the start run function
How do I get started making a mod/learning how to make a mod?
thanks
this is also a good resource:
https://github.com/Steamodded/smods/wiki/Your-First-Mod
thanks as well
could you guys help point me to the right direction? I want to make a joker which modifies playing cards in booster packs. I know there's a way to modify shop cards with context.modify_shop_card so I was wondering if there was something like that for booster packs
there isn't
what do you want to modify specifically
When my custom enhancements are trying to show up, the game crashes weither in game or in the collection. Any chance someone knows what is happening and how to fix it?
I just want to add a random seal to playing cards which don't have any
you can maybe just check the cards in G.pack_cards when the booster is opened
like that ig
Oh
um
when is that function called
also the first line should be G.GAME.giga = G.GAME.giga or {}
wait no im dumb
do this
disregard this
um in a condition ig
cause I was having a thing about voucher in it too
and it work fine with the voucher
assuming you're in a context that has context.scoring_hand in the first place, yea
So I've done smth weird - does anyone know if the "multiple text input cursors" thing is fixable? To say nothing of the crazy misalignment that happens afterwards
i have a patch for it
wait
# fix multiple text input focus
[[patches]]
[patches.pattern]
target = "functions/button_callbacks.lua"
pattern = '''if G.CONTROLLER.text_input_hook then'''
position = "at"
payload = '''if G.CONTROLLER.text_input_hook == e.parent then'''
match_indent = true
bless you kind stranger
so it turns out SMODS has a patch for this also (at least 1224a does) - notable because this patch wasn't finding any targets. The way to handle it with the SMODS patch I discovered was to assign a unique id when creating the text input
can anyone help me with creating a mod? I have little coding knowledge and am mainly using chatgpt to help me but it's not doing a great job haha
I just need a simple mod that disables reserved parking or makes reserved parking a 0 in 2 chance
You could just use Banner to disable it
I don't want to ban it though. I want to own it but it does functionally nothing.
Then I create a mod that calculates how much it would've made and just manually gives me that amount of money
Wouldnt it be easier to just use an animation skip mod like Saturn
If you just dont want to wait through all the parking animations
100 reserved parking * 100 mime * 200 hand size = 2 million triggers. It builds up the event queue and it'll take a lot of time to load anyways
don't ask why I have that many jokers, I just do
nvm I figured it out
now I need to make a mod to manually add the calculated money
I don't think this theoretical mod you want would solve your issue
^
why not?
my issue is that reserved parking was taking an insane amount of time to calculate. Now it will effectively happen almost instantly
I think it solves my issue perfectly, and I can't think of any alternatives
The calculate time would remain if I am not mistaken, you're just moving it away from the jokers and onto something else
the problem with the jokers is it is a massive amount of $1 retriggers. 100 x 100 x 200 = 2 million retriggers. The alternative is simply do the math of 100 x 100 x 200 and give myself $2 million
The calculation isn't what takes forever. It's the retriggering and event queue.
Does Talisman/Handy animation skip not just do that already