#💻・modding-dev
1 messages · Page 650 of 1
okay i found it and it is
horribly split up but okay then
undiscovered under other and then some random stuff under misc in dictionary and labels
mm does anybody know how to go about making a joker resolve an effect while its debuffed? i want a joker to detect when a different joker is sold so it undebuffs itself
look at Card:can_calculate
thx :)
brah
i think you may need to include a key or smth of the sort to notify the consumable that you're including this info
is the key not just the key for the consumable
how would i make certain consumable type to appear in certain pack
like for example i want this set to appear in spectral packs
soul_set = "Spectral"
im a bit lost on what can_calculate actually does- do you know where i could look to properly read up on it?
wait lemme grab the code
soul_set?
this stuff
under the consumable code
theres not a way to do it under the consumable type iirc
if it returns true it can run calculate
nothing, you need to hook it
im not really sure how i would hook can_calculate to do this- is there a mod that does something similar i could refer to?
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
(alternative option)
mm i understand hooking, im just not sure on can_calculate-
oh, this would help, what parameters are passed to can_calculate
like does it recieve context?
i think the point is that usually debuffed cards return false in can_calculate, but by hooking it you can make it return true for your specific case
OH
so just make it return true if its debuffed otherwise run normally, and them detect if its debuffed on my own in calculate?
that makes so much sense, thank you 😭
you should only make it return true if it's debuffed and it's your specific joker, to avoid other debuffed cards doing things they shouldn't
cant i just hook within my specific joker or do i need to hook onto the generic can_calculate?
function hooks are always generic
j_lemon_myjoker
thank you
wrong channel
- one of your mods you have installed is likely causing the problem,
take out every mod you have and put them in one by one to check which one is causing the issue
thank you shrimp
i restarted on my mod ( everything made it crash ) and ive alr made 21 jokers
mod's ready to play...
if anyone wants...
(id probably bump your own thread that its ready to play if youve updated it with something)
does anyone know if there's a way to add to the debuffed description? i do want to indicate this additional ability
would anyone wana playtest my mod? i updated it and it seems like it works now?
is there a function that i can hook (or patch) to prevent gameovers
not like mr bones, like if you hit 0 hands you don't lose instantly, you can keep playing hands
guys- is there a way to debuff a card in hand till the end of the round
Yes, end_round
how do i load my localization file.
shouldn't need to, smods loads it automatically
When it's highlighted? Card:highlight 
then why would it not?
namely Oops! The game crashed: [SMODS galdur "galdur.lua"]:1085: attempt to index local 'loc_target' (a nil value)
thankers 👀
what's the exact name of your loc file?
and you're sure it's formatted properly?
do you have any issues if you turn galdur off?
Trying to make my own Custom Booster Pack! How do I get rid of the card ui appearing?
it looks like this without galdur.
send your localization file, it's easier if i can look at it and point out what's wrong
yea this isn't quite right
as per the documentation, everything inside the return table needs to be wrapped in another table labeled descriptions
so basically it should be this:
return {
descriptions = {
["Joker"] = ...
}
}
Does the class Card which includes all jokers, playing cards, consumables... have some unique key to tell apart each Card instance?
what do you need that for? cards do have unique identifiers (I don't recall under what key), but they aren't all that useful because they don't survive a reload
I am intending on putting each card with certain attributes in a system that will be changing through the course of the game (because I will be changing it often mid-game I don't really want to iterate through every single card into the system, but rather the cards with those attributes). And in that system I want a correlation between the cards and their keys - every time I change those attributes the system will be notified, but the system itself has to keep track of which card sent the notification, so a key will be very handy in that regard
hmm, so if they are not surviving a reload, I might need to do something about that as well
What does G.GAME.legendary_mod affect?
I thought it affects soul rate but it doesnt change
actually, I might be able to implement a relation between the cards and the system without Card-related keys (they could be system-related)
Question. Should I be bothered to add keybinds API in Handy so you can add own ones?
It supports key conbinations and when I'll have time to rebuild it again will support holding properly too
is there an easy method of getting the number of hands played in the current blind?
subtracting current hands from max hands wouldnt account for artificial hand decreases
ohh
i could just increment a counter
damn i'm kind of stupid huh
G.GAME.current_round.hands_played
Is there a vanilla/smods implementation for making a card you can't drag?
Oh wait
states.drag.can I think
Yeah okay exactly that
I'm trying to filter the G.P_CENTER_POOLS["Joker"] list for a random blueprint_compatible Joker to feed into SMODS.blueprint_effect, but it doesn't work. Checking the table for the pool and stuff in G.jokers.cards and it looks very, very different. Is there any way to get the G.jokers.cards[i] equivalent for a randomly selected Joker from the center pool or would I have to add it to a custom Joker area and get it from there just to use it in blueprint effect?
P_CENTER_POOLS has prototypes (the centers) while G.jokers.cards has cards, you would need to create the card object somehow
I would recommend looking at Ortalab's Pinkprint
can somebody explain to me why the joker still appears in the shop/packs
what is that warning in in_pool saying
Figured, at least I learned something. Thanks!
it's outside the joker definition
huh
SMODS.Joker {
key = "despair",
loc_txt = {
name = ":despair2:",
text = {
"You are not supposed to see this."
}
},
rarity = 1,
atlas = 'despair',
pos = { x = 0, y = 0 },
no_collection = true,
cost = math.huge,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = true,
perishable_compat = true,
config = { extra = {} },
loc_vars = function(self, info_queue, card)
return { vars = {} }
end,
calculate = function(self, card, context)
if context.joker_main then
return { mult = -math.huge }
end
in_pool = function(self, args)
return false
end
end
}
so?
ok it's inside calculate
Looking at green joka on vremade, is that really the only way to check for a discard?
Just feels kinda silly
what's the silly part
No, context.pre_discard exists.
ah if you mean discards in general yes
The fact that we check for the last card in the discard to know that discard happens
green joker does it for the animation iirc
Oh, awesome
Oh
<@&1133519078540185692>
why do my game crash when I try select my jimbo deck
key = 'Decks',
path = 'rsgdeck.png',
px = 71,
py = 95,
}
SMODS.Back({
key = "jimbodeck",
loc_txt = {
name = "Jimbos Favorite",
text={
"Start with {C:attention}#1#",
"{C:green}Vanilla Jokers{}",
},
},
config = { hands = 4, discards = 4,},
pos = { x = 1, y = 0 },
order = 1,
atlas = "Decks",
unlocked = true,
apply = function(self)
G.E_MANAGER:add_event(Event({
func = function()
if G.jokers then
SMODS.add_card({key = 'j_joker'})
return true
end
end,
}))
end,
})
Missing loc_vars function.
loc_vars = function(self, info_queue, center)
return { vars = { self.config.hands, self.config.discards } }
end,
I'm so fucking confused, I thought context.before runs once??????
fixed it didnt need the # # between the number and i started with 8 hands and 7 discards randomly
because i had the hands and discard set to 4 both
SOMEHOW, the effect that triggers on context.before triggers multiple times. This DOES not happen with the context.pre_discard
Ignore that return true btw, it isn't relevant 😛
can you show the full function?
key = 'backtobasic',
loc_txt = {
name = 'Back to Basic',
text = {
'Each playing card',
'without any {C:attention}enhancement{}',
'and {C:attention}edition{}',
'gives {C:mult}+#1#{} Mult'
}
},
atlas = 'Jokers',
rarity = 2,
cost = 6,
unlocked = true,
discovered = true,
blueprint_compat = true,
perishable_compat = false,
config = {extra = {mult = 4}},
loc_vars = function (self, card, info_queue)
return { vars = { card.ability.extra.mult}}
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play and not next(SMODS.get_enhancements(context.other_card)) and not context.other_card.editon then
return {
mult = card.ability.extra.mult
}
end
end,
}```
loc_vars args are wrong order, should be self, info_queue, card
I moved the check for Joker being rightmost in this one but it's not like it stopped triggering multiple times after that
also at the calculation it need to be
self, context, card
Blunder
so it scales more than once?
It moves more than once, too. More specifically, it scales until it moves to the rightmost slot
oh
yes
I get it
if you move it, the calculation back end will run it again and skip whatever you moved
because it just goes in order of positions
do the movement in an event
key = 'barun',
loc_txt = {
name = 'Barun',
text = {
'Each {C:attention}King{} held',
'in hand gives',
"{C:mult}+#1#{} Mult"
}
},
atlas = 'Jokers',
rarity = 1,
cost = 6,
unlocked = true,
discovered = true,
blueprint_compat = true,
perishable_compat = false,
config = { extra = { mult = 1.5} },
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.hand and not context.end_of_round and context.other_card:get_id() == 13 then
if context.other_card.debuff then
return {
message = localize('k_debuffed'),
colour = G.C.RED
}
else
return {
chips = card.ability.extra.mult
}
end
end
end,
}```
this code makes my barun make 1.5 chips not 1.5 mult why??
dummy i solved it myself i had it with chips not mult at the return after my else
if context.end_of_round and context.game_over == false and not G.GAME.current_round.discards_left ~= 0 and not context.blueprint then
local Chippy = card.ability.extra.chips - (card.ability.extra.additional * G.GAME.current_round.discards_left)
if Chippy > 0 then -- Only subtract if result stays above 0
card.ability.extra.chips = card.ability.extra.chips - (card.ability.extra.additional * G.GAME.current_round.discards_left)
return {
message = localize { type = 'variable', key = 'a_chips', vars = { -(card.ability.extra.additional * G.GAME.current_round.discards_left)}},
colour = G.C.CHIPS
}
Hello, just trying to fix up my issue where the text show this when losing chips, could someone help me about it please ? It's most definitely in the message but unsure exactly what
a_chips is for positive values, a_chips_minus for negatives
what causes this specific crash?
thanks !
Does anyone know how to prevent Certificate from spawning a modded Seal? I want my seal to only be obtainable with a spectral card. I already prevent it from appearing in booster packs.
in_pool = function() return false end in the seal code.
Thanks!
you're trying to access the atlas ja_jokers somewhere, but no atlas with that key was ever created
at a first guess i suspect you're really trying to access the vanilla jokers atlas (though i think it might be Jokers, capitalized) and just need to add prefix config
Can I detect if a card is being juiced up?
if card.juice?
The goal is not juicing the same card twice without making a variable specifically for tracking that because I'm lazy
not juicing the same card twice when?
Yeah this works, thank you!
A joker that starts juicing when you have consumables, and since you can get consumables from purple seals, I check for that every hand drawn
But turns out juicing the card can stack and make it go hyper mode
you can use juice_card_until
I do that, but it can get activated multiple times
So checking for card.juice solved that
oh I guess it depends on when you trigger the juice originally yeah
-- When hand is drawn
if context.hand_drawn and next(G.consumeables.cards) ~= nil and not card.juice and not context.blueprint then
-- Wiggle while used = false
local eval = function() return card.ability.extra.used == false and not G.RESET_JIGGLES end
juice_card_until(card, eval, true)
end
without knowing the actual effect, it's hard to know, but I imagine you don't need to check it every time you draw a hand
Without and not card.juice the effect will keep stacking on every hand drawn
Which was the problem lol
I mean I don't but I think it's a nice touch for this joker
So this works fine
what is the actual effect?
Once per round you can sell a consumable to destroy a random card in hand
So if you have consumables I want the joker to signal to you that you can use it
Since you can get consumables from seals and other jokers and whatever else, I want the wiggling to start at any point during the blind
But that caused it to stack
So and not card.juice solved that
How do I modify a Blind's reward money? This code doesn't activate in time.
calculate = function(self, blind, context)
if not blind.disabled then
if context.end_of_round and context.game_over == false and context.main_eval then
self.dollars = self.dollars * math.max(G.GAME.current_round.hands_left, 0)
--update_blind_amounts() -- Which do I use?
G.GAME.blind:set_text()
end
end
end
return {
descriptions = {
Other = {
j_hft_faust = {
name = "Devil's Hand",
text = {
"{C:attention}4{} cards with",
"no common {C:attention}Suits{}",
"or {C:attention}Ranks{}",
},
},
},
},
misc = {
dictionary = {
ph_dagonet = "Retreat!",
},
},
}
Can anyone see what I'm doing wrong with my Mr. Bones-esque run save ability. The text always says "Saved by Mr. Bones"
why is your joker in Other
what are you returning in calculate
if
context.game_over
and context.end_of_round
and context.main_eval
and G.GAME.round_resets.blind_states.Big ~= "Defeated"
and card.ability.tick == 1
then
card.ability.extra.tick = 2
return {
message = localize("k_saved_ex"),
saved = "ph_dagonet",
colour = G.C.RED,
}
end
It's got a bad key, it's for an info_queue
what version of smods do you have
"1.0.0~BETA-1224a-STEAMODDED"
out of date?
that's in my "version" file in the steammodded folder
yeah, the info_queue above it is working fine
no idea then
nw, I'll keep investigating
I'm trying to make a boss blind that adds some temporary cards during the blind. I want these cards to always be added to your hand whenever you play or discard, but I'm having an issue. If my hand is full (ie I play a card and have 8/8), no card is added. Is there a way to always have a card be added?
(I have yet to add a check for the round ending, and will add that)
SMODS.Blind {
key = "spike",
dollars = 8,
mult = 2,
pos = { x = 0, y = 26 },
boss = { min = 3 },
boss_colour = HEX("4AAD42"),
config = { spiny_cards = 1 },
calculate = function(self, blind, context)
if not blind.disabled then
if context.hand_drawn then
for i = 1, blind.config.blind.config.spiny_cards do
local _card = SMODS.create_card{ set = "Base", enhancement = "m_poko_spiny", area = G.discard , key_append = "poko_spike" , no_edition = true }
table.insert(G.playing_cards, _card)
G.hand:emplace(_card)
_card:juice_up()
end
save_run()
end
end
end,
remove_spiny = function()
for _, card in ipairs(G.playing_cards) do
if SMODS.has_enhancement(card, 'm_poko_spiny') then card:start_dissolve() end
end
end,
disable = function(self)
self.remove_spiny()
end
}
hand_drawn is called when a hand is drawn, so you would need another context
context.drawing_cards maybe
Any takers?
This seems to be working. Thank you!
Change self to blind
is there a way for a tag to apply a continous effect for a round? i would like to make a tag that doubles all chances for a single round
i dont see any mention of a calculate function on the docs page for tags but knowing the smods documentation it might still have one so idk
ok thx
ugh wdym you cant make a tag yep at the end of a round without using the money eval context
that doesnt. work for what im doing
might have to scrap the clover tag for now
doubt it's very hard to set up a custom tag context
heck, you could probably just call the tag context during context.end_of_round in the mod calculate
How can I make a player fight the same blind another time? (They get the payout and the shop)
More precisely, the Big Blind
after defeating the blind, change G.GAME.round_resets.blind_states.Big to "Upcoming"
just make sure you have a condition on this so you don't have the boss blind infinitely
i think the safest timing for this would be upon entering the shop
where are things like ante/hands/discards display in the code?
i recommend looking at the key for the text in the localization files and then searching for that in the code
it's the best way to find ui functions
ty
Howdy! Is there any way to check for if a specific card is in the played hand when a joker is triggered? For example, my joker already gives X2 mult, but I want it to give an extra X1.5 if a king of hearts is in the played hand.
I understand that part, but how do I check the list for the King of Hearts specifically
reference VanillaRemade and see how e.g. the idol does it
it's slightly different because it works in context.individual, but you can do for _, other_card in pairs(context.full_hand) do and then other_card acts like context.other_card does in the idol's code
https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua#L3874
gotcha, will look into
found the problem! Had to check Lusty Joker and Baron to find exactly what I was looking for, tyvm!
have cardareas been changed recently? G.deck.config.true_card_limit no longer seems to exist
yes
what do you need to check that for instead of card_limit
i frankly dont remember, but what i was trying to check was the total amount of cards in the player's full deck
i think #G.playing_cards should work just fine for that
cool
how do i set a custom G.GAME variable to be 0 when a run starts? should i patch the part where the base game sets hands and money and stuff or is there a better way
perfect ty
how can you test a seal
I usually use zokers mod menu to test everything I make how can you test a seal
what
Its coded with ai
dang
And used to not work at all
I dons't want to use it at all now
https://github.com/WilsontheWolf/debugplus is the true debugging goat
hold Tab once you install it, it'll explain everything
how is my seal so bad that it just exits the game
when I hover over it
thus there must be somehing wrong with the localazation
what is wrong
maybe in the atlas
how would i make a "fake" locked joker for the collection that cant be unlocked and has no actual impact on spawning, pools. etc? i want my crossmod jokers to show as locked with the unlock condition being to install the mod
afaik seals should be the full size of a card
make the unlock condition always false?
i kinda have no idea what im doing with UI so i wrote this code to literally just copy the round display and use it for a prestige thing i made, it works but seems to reset to 0 like half a second after updating, how do i make it Not do that
this wouldn't work with unlock all
you might have to actively re-lock it
oh right
ortalab demo did something like that i think
crash, freeze, or instantly close
instantly close
i assume 101 is your mod?
yes
sj is your prefix right
yes
your seal has altas instead of atlas
ok that fixed the visual glitch
but not the game instantly closing\
SMODS.Voucher{
key = 'carton',
pos = { x = 8, y = 2 },
cost = 10,
config = { extra = { sell_gain = 1 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.sell_gain } }
end,
calculate = function(self, card, context)
if context.end_of_round and G.GAME.blind and G.GAME.blind.boss and G.jokers and not context.blueprint then
return {
func = function()
for _, j in ipairs(G.jokers.cards) do
j.sell_cost = (j.sell_cost or j.cost or 0) + card.ability.extra.sell_gain
j:set_cost()
end
end
}
end
end
}
is there a reason this voucher doesnt work?
it shows this
that fixes it
i think you're using pseudorandom_probability wrong in the calculate
how do you relock a joker?
you could look into the ortalab demo? i know they have jokers that can never be unlocked (the jokers that werent in the game yet)
wow the code for the ortalab demo is fucking awful to read
i cant find where its doing it
maybe im looking at the wrong demo or smth idk
this ain't working
ok im looking at a demo that actually has this now and uh. those jokers arent actually locked lmao
they just look locked
theyre just normal unlocked jokers with the locked joker texture
i mean like yeah that works too i can do that
how would i hide the rarity badge of a joker?
figured it out,
set_card_type_badge = function(self,card,badges)
return {}
end
j
J
bump
hi! I'm having a really weird issue where when I use card:set_debuff(true) on a playing card where if i set_debuff(false) on a completely unrelated joker, it also undebuffs the playing card? im quite confused why this happens
^ to clarify, both of these happen in the calculate function
Is there an array of joker only cards in the shop that I can pull from after rerolling?
no but G.shop_jokers.cards has all of them and you can filter by jokers manually
That sounds perfect, how would I do so?
loop through it and check if card_in_shop.ability.set == "Joker"
So the idea would be, if I wanted to modify a variable that counts all of the jokers
for i = 1, G.shop_jokers.cards do
if context.card.ability.set == 'Joker' then
card.ability.extra.count = card.ability.extra.count + 1
end
end
right?
for i = 1, #G.shop_jokers.cards do
if G.shop_jokers.cards[i].ability.set == 'Joker' then
card.ability.extra.count = card.ability.extra.count + 1
end
end
or
for _, card_in_shop in ipairs(G.shop_jokers.cards) do
if card_in_shop.ability.set == 'Joker' then
card.ability.extra.count = card.ability.extra.count + 1
end
end
Cool cool! Last bit, does the first joker in the shop count as index 0 or index 1?
lua is 1-indexed
so I should do ```lua
if card.ability.extra.count > 0 then
yes
perfect, thanks a bunch!
Och, wait, I just realized it might come up with a false positive when referencing the index in another part since jokers aren't guaranteed to be left oriented.
What's the best way to go about targeting the right-most joker in the shop to make it negative?
theyre sorted left to right
so the last joker you find is the rightmost
So if I had a shop with death on the left and joker on the right, setting the shop_jokers card at [i] to be negative would still make the joker negative and not death?
what is [i] in this case
not [i] mb, setting the card at [card.ability.extra.count]
no because youre only counting jokers
local rightmost_joker
for _, card_in_shop in ipairs(G.shop_jokers.cards) do
if card_in_shop.ability.set == 'Joker' then
rightmost_joker = card_in_shop
end
end
if rightmost_joker then rightmost_joker:set_edition("e_negative") end
it iterates over a integer indexed table (an array) in order
the first value is the key (in this case 1, 2, 3, 4, etc) and the second one the value
I see I see! Very useful, I learn so much
Hm. I dragged-and-dropped the music and some sfx I wanna use for my mod directly into the game to test them out, and the sound effects are working, but the game won't start when I replace music1.
This is what the crash message says
Could not read Ogg bitstream stack traceback: [C]: at 0x7ffe366258a0 [C]: in function 'newSource' engine/sound_manager.lua:27: in main chunk
What do your sound objects look like?
It's also saved as music1.ogg
Your SMODS.Sound object is what I'm asking about
I kinda pushed aside the mods' main file for later, but I suppose now is later. I was getting impatient and commented it out. I apologize for what you're about to see
This is actually pretty fine. I think the only thing that needs to change is return 10 in select_music_track
And also the path since you said it's different now
Oh! Ok, I'll see if that works
I also recommend setting up a sync field so it does properly sync with booster OST and the like
['music1'] = true,
['music2'] = true,
['music3'] = true,
['music4'] = true,
['music5'] = true
}```
How would I set up a consumable that increases a card's chips (like hiker) by an amount equal to the consumables of the same type used? (+1 chips if zero consumables used, +2 if one, so on and so forth)
card.ability_perma_chips = card.ability_perma_chips + (1+G.GAME.consumeable_usage_total.consumabletypekey)
Cool cool! And I'd just replace consumabletypekey with the modded consumable key I make?
No, you would replace it with the consumable type key.
gotcha
It's still not working 😰
vol = 0.6,
pitch = 0.7,
key = "music_main",
path = "music_main.ogg",
select_music_track = function()
return 10
end,
sync = {
['music_main'] = true,
['music2'] = true,
['music3'] = true,
['music4'] = true,
['music5'] = true
}
})```
bump 2
Feels like you aren't giving enough info tbh
Are you sure it's not just prestige value actually going down for some reason
oh it is (also i knew i recognized you from somewhere lol)
sorry if im asking too much but I have no idea why its doing that (this is the only relevant part of the code)
Because you're setting it to 0 in SMODS.current_mod.reset_game_globals
isn't that just when the run starts tho
Yes, but it's also every round.
you said the file is saved as music1.ogg?
Oh nvm just saw it got solved in #⚙・modding-support
Yup! Onto new problems for me hehe
is there an equivalent to consumable_usage_total for triggering a joker?
You mean you want to know how many times a joker has triggered?
Ye, 1 specific joker
No, there isn't, you would have to count the triggers manually.
does anyone know how i could add onto the debuffed description for a specific joker?
maybe you could look at how invisible joker adds the “removes negative from copy” text onto itself and do it that way
tho idk if it’ll actually work when the joker is debuffed
this but also return replace_debuff = true in loc_vars
https://github.com/nh6574/VanillaRemade/wiki#how-do-i-change-the-name-or-description-of-a-card-dynamically
How would I set a shop joker to be negative
I'm working on alternate artwork configuration for my mod, and some jokers' alternate artwork make use of soul_pos while others don't. I know you can use the update function in order to card.children.center:set_sprite_pos, but does this apply to soul_pos and any extra info you give it (like for Hologram)
tl;dr how would i make a card look like either Photograph or Hologram based on a boolean
No, you would use card.children.floating_sprite:set_sprite_pos
ahhh, okay, thanks!
would it be possible to change the card atlas and pixel size as well
Yes, card.children.center.atlas = G.ASSET_ATLAS['modprefix_key']
sick, thanks
and if I just wanted to enable/disable the floating sprite?
card.children.floating_sprite.states.visible = false?
how do you check with code what mod a joker is from?
(mod wont exist for vanilla)
also original_mod if you wont want to take into account take ownership
ah that doesnt seem to work for jokers in the collection
great
wai tno it does what
How can you make it so that you face the Big Blind twice? (Joker effect)
ok when its from SMODS.collection_pool i can skip the config.center
Patch end_round and reset score and hands and discards.
But I want the player to still get the shop and the reward
G.GAME.round_resets.blind_states.Big = 'Select' in context.end_of_round?
You mean you want the player to be able to skip the blind twice?
Like if you faced the blind twice, yeah
However that would be a free tag each ante...
Is it balanced?
You would probably do G.GAME.round_resets.blind_states.Big = 'Select' in context.skip_blind and the reset the blind UI.
Ok
How do you reset the blind UI though?
Wait...
Wouldn't it be better if the second blind is... Unskippable?
You would use some of the code from G.FUNCS.reroll_boss but the Big blind instead of the Boss blind.
Ok
Thanks for the help!
G.play.cards (or context.full_hand) is in order, just loop through with ipairs and as soon as you find a Jack break the loop
My question is: How do you get the player's most played hand?
vanillaremade is a great reference for that, you can check e.g. how obelisk would get the most played hand
https://github.com/nh6574/VanillaRemade/blob/main/src/jokers.lua#L2062
local jack
for k, v in pairs(context.full_hand) do
if v:get_id() == 11 then
jack = v
break
end
end
how could i get a mod's display name from its id?
SMODS.Mods[id].display_name
awesome thx
does this wording make sense?
and how would i access the last hand the player played?
is that a thing or do i have to record it myself
G.GAME.last_hand_played
Thanks!
it does make sense but it took me a second to figure it out
for clarity id change "largest" and "smallest" to "most common" and "least"
yeah those are probably clearer
How do I check in context.individual if other_card has any Enhancement?
if next(SMODS.get_enhancements(context.other_card)) then
SMODS.get_enhancements returns a table of all the enhancements that the card has (accounting for quantum enhancements); you need the next to check if it has any because it'll return an empty table if it doesn't, and that still counts as true in lua
is there any way i can estimate how wide a string will appear as text if i know its scale?
perfect, thx!
I mean, put it in the game and see
Then tweak accordingly
i do not know what the string is until runtime
but i figured out a kinda hacky solution anyways
the point is that any arbitrary string could be here, because it's pulling from every installed mod's display name (scroll up for context)
i think love2d has functions that can handle that, but i don't remember exactly off the top of my head, and i'm not sure how it could be translated to balatro UI dimensions
yeah i used love2d's get width function on a string that fits nicely into the box, and then used that to do some math so that any text should fit roughly in
so I've been doing messages on my cards like this
message = '+' .. card.ability.extra.triggered * 2,
But I have a joker that adds both chips and mult, and I'd like it to come out looking like +X/+X, but can't figure out how to get the card.ability.extra.triggered * 2 to show on both parts
message = '+'.. (card.ability.extra.triggered * 2).. '/+'.. card.ability.extra.triggered * 2?
alright, what can i hook to recalculate the hand when reordering cards in your hand
can't you reorder them before the hand is calculated
Why in the world did I not think of that, tysm
i have an enhancement that makes a card copy the rank and suit of the card to the right so i need to recalculate bc it's now placement dependent
cant it do that before the hand is calculated?
like during context.press_play
yes, but i want it to recalculate when you're selecting a hand and reordering cards in your hand
context.evaluate_poker_hand?
so that the preview is accurate
that doesn't get called when cards are reordered
that's the problem
i think you might be able to call it manually let me check
well i need to be able to know _when _ to call it
one of the contexts is called when reordering
i know because i tested yesterday
i think modify_scoring_hand?
i need to run G.hand:parse_highlighted() whenever cards are reordered
but i don't know how to call things "when cards are reordered"
that's my problem
Node:stop_drag iirc
nope that was a mod
is a Card a Node
but it does it on Node:stop_drag
yes
card stop drag wasnt called when i tried to do the same thing iirc
ok how would i get what mod a card's seal is from?
or more specifically the seal of a card in the seal collection page
G.P_SEALS[card.seal].mod
thx
Okay so there's an issue here.
I'm using context.scoring_name and G.GAME.last_hand_played to compare the current hand to the last hand the player played
thing is, they're always the same!
Do I have to keep track of this manually?
I'm not sure what to do...
You would set a variable to G.GAME.last_hand_played in context.press_play and use that instead.
Ooh, I see! Thank you, I'll see if that works.
comments that say TARGET: in the code are for lovely patches right? you can't like hook onto them or whatever?
Yes.
neat-o
SMODS.Rarity {
key = 't6',
loc_txt = {
name = 'Tier 6'
},
default_weight = 0.7,
badge_colour = HEX('FFD700'),
get_weight = function(self, weight, object_type)
return weight
end
}
My jokers with this rarity all have a cost of 3 set, but don't seem to be appearing in the shop. Any ideas?
If you haven’t got it sorted yet, I do something similar here https://github.com/EremelMods/Ortalab/blob/main/objects/jokers/stonehenge.lua
how would i make a joker that does something when it's destroyed? is there a context i can use for it or is it more difficult than that?
stupid question: how do you detect if the player is in the Big Blind?
another probably stupid question: how do you check if it's the first hand of the round?
In the remove_from_deck function, check if not from_debuff
if G.GAME.blind.config.blind.key == 'bl_big'
if G.GAME.current_round.hands_played == 0
Thanks!
can provide more info if needed
question: where does the game decide on which tags to generate for an ante?
You need pools = {['Joker'] = true}
get_next_tag_key in functions/common_events.lua
Always the basic stuff. Thanks :")
thank you!
Or if SMODS.is_active_blind('bl_big').
saving this for what im doing rn
can i actually use calculate function for enhancements
most of the stuff ive seen is config heavy
Yes.
If you want it when played and scoring then it would be:
if context.main_scoring and context.cardarea == G.play then
-- Code
end
there we go
I had an idea for a Joker... I want to check how many King and Queen pairs there are in the scoring hand. How would I do that?
local text, loc_disp_text, poker_hands = G.FUNCS.get_poker_hand_info(context.scoring_hand)
local count = 0
for k, v in pairs(poker_hands['Pair']) do
if v[1]:get_id() == 12 or v[1]:get_id() == 13 then
count = count+1
end
end
I don't think this does what I intended...
Ideally what I want is that count increases IF the hand has a King AND a Queen in it
So in a full house like this -----> KKQQQ
count would equal 2
You probably can count the number of kings in the hand, count the number of queens in the hand, and take the lower number for what you wanna do
you can just change this to have a boolean for kings and one for queens
I don't know how to count that 🥲
I don't know where the cards of the hand are in context.scoring_hand
As in I don't know how to get the cards
context.scoring_hand is a table of cards
so context.scoring_hand[1] would be the first card
OH
My bad dog
I thought it had other data in there
I swear I tried that and it didn't work 😭
Maybe I'm just dumb
okay thank u !!!!
Vanilla Remade comes in crazy again
as always 🗣️

what deck function gets called every frame
how do i make a joker retrigger itself multiple times? kinda like jerko from the all in jest mod
i read that joker name wrong
if context.retrigger_joker_check and context.other_card == card then return {repetitions = number} end
do i put that inside the calculate function?
Yes.
though you need to have the joker retrigger optional feature enabled yeah?
well it didn't work, here's what i did ```calculate = function(self, card, context)
if context.retrigger_joker_check and context.other_card == card then return {repetitions = 50} end
if context.joker_main then
local op = math.random(1, 4)
local val = math.random(1, 9)
if op == 1 then
return {
mult = val,
}
elseif op == 2 then
return {
mult = -val,
}
elseif op == 3 then
return {
xmult = val,
}
elseif op == 4 then
return {
xmult = (1 / val),
}
end
end
end```
as neokat mentioned joker retriggering is an optional feature, you need to enable it in your mod
https://github.com/nh6574/VanillaRemade/wiki#what-are-optional-features
sidenote, instead of math.random you should be using pseudorandom so the results are consistent with the same balatro seed
ok it works now thank you!
chat do we think 1 in 10 is too high or too low for this
i think it's fine
what if it destroyed the leftmost joker instead of a random joker
you'll find out during playtesting if you have a few people play
why does this create random cards of the selected key's set, rather than the actually specified card key
is it banned?
yes
its in vanilla im pretty sure
i thought creating specific cards would bypass it
it bypasses in pool but not that, i had many Banner crashes reported to me because of that
i guess i can just temporarily unban
and create the card in between
and just return a card
is there away to get the current number of jokers
trying to makea pseduorandom for the banana command
but instead of just making a guess of how many jokers someone might have rather just put the current amound of jokers in
#G.jokers.cards
local random = pseudorandom("ttv_389201", 1, #G.jokers.cards)
so something like this
if you're trying to get a random joker you can just directly do this
local random_joker = pseudorandom_element(G.jokers.cards, "ttv_389201")
but if you specifically need the index then yea do what you wrote
not really it's just a simple few lines
if is_on_cooldown() then return end
local RanSet = {"j_gros_michel", "j_cavendish"}
local RanSelect = math.random(#RanSet)
local RanCreate = RanSet[RanSelect]
local random = pseudorandom("ttv_389201", 1, #G.jokers.cards)
if G.STAGE == G.STAGES.RUN and G.jokers then
if #G.jokers.cards > 0 then
G.jokers.cards[random]:set_ability(G.P_CENTERS[RanCreate])
end
end
end```
pseudorandom_element actually returns the index as the second value
oh cool
you shouldnt need it regardless
i'll take it for a spin see if it works
eh it works
now I just need to set it where it doesn't replace a banana with a banana
now just need to figure that out
I get how to use f #SMODS.find_card('') just need to figure out hwat the games equivalt of ignore it is
Having trouble getting my Mr. Bones style run-save mechanic to not show the message "Saved by Mr. Bones". I've followed advice I've heard elsewhere, but when I change the "saved = true" to "save = 'ph_dagonet'", it doesn't see it as valid.
Calculate function of the card
calculate = function(self, card, context)
if
context.game_over
and context.end_of_round
and context.main_eval
and G.GAME.round_resets.blind_states.Big ~= "Defeated"
and card.ability.tick == 1
then
card.ability.extra.tick = 2
return {
message = localize("k_saved_ex"),
saved = "ph_dagonet",
colour = G.C.RED,
}
end
if card.ability.extra.tick == 2 and context.starting_shop then
G.GAME.round_resets.blind_states = { Small = "Select", Big = "Upcoming", Boss = "Upcoming" }
card.ability.extra.tick = 0
end
if context.beat_boss then
card.ability.extra.tick = 1
end
end,
Here's the localisation file
return {
descriptions = {
Other = {
info_devils_hand = {
name = "Devil's Hand",
text = {
"{C:attention}4{} cards with",
"no common {C:attention}Suits{}",
"or {C:attention}Ranks{}",
},
},
},
},
misc = {
dictionary = {
ph_dagonet = "Retreat!",
},
},
}
could do what I do I just grab what I need from a in-game joker using joker forge
if context.end_of_round and context.game_over and context.main_eval and not context.blueprint then
if to_big(G.GAME.chips / G.GAME.blind.chips) >= to_big(0.25) then
return {
saved = true,
message = localize('k_saved_ex')
}
end
end
end```
look how mr. bones does it and tweak it from there
I miss read it
Mb
if the issues jsut the message
message = localize('k_saved_ex')
The revive message
At cashout
Thats different
Also why are you copying from joker forge when vanillaremade exists
Just easier for me
I use mixture of everything
Joker forgae vanilla and smods wiki
Joker forge takes a bunch of time to export and does everything way jankier though???
It just sucks as a reference too because the code is very unclean
Somethings don't work
Yeah
So I get it
And the obsession with (function() ... end)() in the middle of if statements
I made a joker that supposed to inscrease chips when u use a bonus face card but it increases regardless
so that's something I gotta fix later
but just trying focus more on the twitch commands
When theres a fully functional recreation of everything in vanilla with no issues and readable code and not limited to joker forge supported features
I see no reason to use joker forge instead
I can guarantee you that doing simple effects seperately with joker forge when you actually know how to code is just slowing you down
Also you can again just copy paste from vanillaremade which is way faster
i've been learning as I go
Been using joker forge less and less
I just use it if I wanna see how an ability works and see if I can tweak it to what I want it to do
Well okay thats definitely different than just using it as a reference i would say
Which i thought was implied
Why would you hit up vanilla
Okay yeah
Everything is organized pretty well idk
And you can just ctrl F to find things in a file
it's why I say sometimes
majority of the time it's fine
alright
i'm gonna say i'm a dumbass
I had no idea this part existed lmao
What part
the src
with how everything functions
I just figured it was a wiki for explainig how to code stuff
lol
the only thing i've really been using forge for rn
is keep the sprite sheets organized
too lazy to manually add it into a photo editor
then getting annoyed when it's one pixel off

honestly that's reasonable
I think aseprite probably has some features that make it easy to organize sprite sheets but having jokerforge automate it is probably still easier
plus I like the idea how joker forage does file structure
I can just organzie my jokers as seperate .lua files
in a folder
instead of going through one big single lua file looking for specific joker to edit
yea you can set that up manually, I think the vanillaremade wiki even explains how it works
oh I know i've been manually doing it now
the only thing I wish I can figure out is replacing this local jokerIndexList = {1,2,3,4,5,6,7,8,9,10,11}
instead of adding a nother number lol
I have gotten better at this compared at my first mod attempt tho
if context.end_of_round and context.main_eval and G.GAME.blind.boss and #G.jokers.cards + (G.GAME.joker_buffer or 0) >= G.jokers.config.card_limit then
if #SMODS.find_card('j_tcgyugi_Spirit_E') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_E' }
elseif
#SMODS.find_card('j_tcgyugi_Spirit_A') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_A' }
elseif
#SMODS.find_card('j_tcgyugi_Spirit_T') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_T' }
elseif
#SMODS.find_card('j_tcgyugi_Spirit_H') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_H' }
end
end
end
})```
what it used to look like before

Want to do a command to see if I can flip the games ui
But not sure if that would be possible without having to find every individual thing drawn on screen
and telling a command to mirror it
Does SMODS.find_card also find tags?
no
fair nuff
how do i define new colours again
thank you
should i just do the same thing but with G.C in order to use the colour elsewhere
you can just address that table if you want but G.C is shorter
alr
hi chat quick question
im having this issue here since its my first time working with tags
tryna get a tag that generates specifically jokers from my mod
this works so far but if i have two of the tag, the first joker generated does not quite have their price set to 0, do y'all know a way to fix this?
one thing i've been trying to figure out is how some mods have changed the background color on the main menu
it should be local card = create_card(...) methinks
you're setting a global, which future tags are changing and then the event that the yep function creates doesn't get around to running any of its code until after the last card has been created
OH
i forgot the local 😭
my bad
thx !!!
ive been scratching my head at this going like "i dont really see whats wrong" i forgot to type local that was supposed to be there 💔
yea it works now
thx
why is it doing this what
key = "Ace",
pos = { x = 10, y = 0 },
atlas = "ReducedDecksAtlas",
unlocked = true,
config = {ante_scaling = 1.5},
loc_txt = {
name = 'Ace Deck',
text = {
"Start run with only",
"{C:attention}Ace{} left in the deck",
"and a {C:attention,T:tag_coupon}Coupon{} Tag.",
"{C:red}X#1#{} base Blind size"
}
},
loc_vars = function(self, info_queue, center)
return { vars = { self.config.ante_scaling } }
end,
apply = function(self, back)
G.E_MANAGER:add_event(Event({
func = function()
if not G.playing_cards then return true end
local cardtable = {}
for _, v in ipairs(G.playing_cards) do
cardtable[#cardtable + 1] = v
end
for i = #cardtable, 1, -1 do
cardtable[i]:remove()
end
G.deck.config.card_limit = 0
local ace_card = SMODS.create_card{
set = "Base",
rank = "A",
area = G.deck,
skip_materialize = true
}
G.deck.config.card_limit = 1
SMODS.calculate_context({
playing_card_added = true,
cards = { ace_card }
})
add_tag(Tag('tag_buffoon'))
play_sound('generic1', 0.9 + math.random()*0.1, 0.8)
return true
end
}))
end
}```
youre not adding the card anywhere
change create_card for add_card
also the playing card added context is not called when the deck is created usually
how do i do stuff between after the last card isscored and jokers are scored
whats the key for the perishable sticker?
perishable
how to reproduce?
You're doing something with the Card class or any update func?
crust out of context
what should i fix on my mild salsa card so heart cards gain +1 mult when scored and increase each time its played something is causing the heart cards to not get it and sjust says error
key = 'mildsalsa',
loc_txt = {
name = 'Mild Salsa',
text = {
'Every played {C:hearts}#2#{} cards',
'permanently gains',
'{C:mult}+#1#{} Mult when scored',
},
},
atlas = 'Jokers',
rarity = 2,
cost = 5,
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, 'suits_singular')}}
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.RED
}
end
end,
}```
the jokers function is mixed with lusty joker and hiker
thanks for the help
chat what colour do you all think time would be
question, why does
if G.playing_cards[i]:get_id() == 10 then
G.playing_cards[i]:set_base(G.P_CARDS["D" .. "_" .. 10])```
not work but
``` if G.playing_cards[i]:get_id() == 9 then
G.playing_cards[i]:set_base(G.P_CARDS["S" .. "_" .. 9])```
works?
the card key for rank 10 is T
Was there a way to change the menu swirl's colours that keeps other mods in mind? Or is it mostly just a free for all brawl?
Thats a great question actually, I never considered it and realized it must be a brawl
yea pretty much just a free for all thing
i could integrate it into my current_mod.menu_cards PR tho 🤔
I've been trying to make a spectral card with a second layer like the soul card but I havent been able to get the second layer to show up using soul_pos
Code?
what do you have soul_pos set as
just to double check, you've got the soul image in both your 1x and 2x atlas files?
I dont
that would be the issue
is that what the problem's from?
if you have pixel smoothing turned on in the game settings, it loads the 2x files. if you have it turned off, it loads the 1x files
I have it turned off
you should have it in both regardless
I finally got it to work....
what was the issue
is there a way to make a sound's pitch not be affected by a hand speeding up?
prrrrobably by manually calling play_sound in an event instead of putting the sound in the return table
(don't quote me on that it's just a hunch)
Yes, you would use play_sound in an event in a func in the return.
tanks :3
How would one get if a card (any card) is created by a Joker?
you can't
the closest would be to check the seeds one by one
but that wont have mod compat
how would i suppress the "hand limit is below X" message from the smods hand limit api?
wait nvm im stupid
how do I get the key of a selected joker?
selected as in highlighted or as in you have the card object
selected like the card object in game
seljoker.config.center_key
G.jokers.highlighted[1].config.center_key?
how do sprites work, id like to add one just sorta chilling in the bg
je;p[ what did i set up wrong ? description doesnt show in game and seal functionalit doesnt seems to be working
It should be context.main_scoring not context.individual
chat what do i add a sprite to in order for it to be always drawn
This is super weird, looks correct to me
Oh wait is your Other category under descriptions?
@lyric wadi this might be your issue
yea that looks like the issue, it's currently on the same level as the misc table which means it's probably outside the descriptions table
who here knows how sprites work
I kinda do
i need to have a sprite positioned at the center of the screen
but still be able to move it
Lucky for you, SMODS.create_sprite exists now
where do i learn more about this
how do i have that stick to the middle of the screen tho
Honestly good question lol
the Partners mod is probably a good place to look? partners spawn at the start of the game in a specific spot, they're draggable, and they persist for the whole run
What exactly does enabling the optional cardareas do? You can still access G.deck and iterate through G.deck.cards without the optional deck cardarea being enabled, right?
enabling the optional cardareas allows cards to calculate from those areas (e.g. an enhancement that scales whenever something happens even if you haven't drawn it yet or even if you've already discarded it)
Oh interesting
you can just create the sprite object and it should appear on the screen im pretty sure
the constructor has an x, y argument
if you want to make it draggable i would look into hotpot's ads probably
Do I need to do anything fancy to have multiple files with lovely patches or do I just put them all in a lovely folder and they'll all load automatically?
Like N said, sprites have x and y values that you can manipulate
how do i get the x and y values that correspond to the center of the screen
i'd look into washee washee's code from yahimod
that's a different question
probably G.ROOM.T.w /2?
also T.h?
its automatic yeah
ill save yall the trouble, ive got it (i think), you just need to take half of G.ROOM's width/height and add G.ROOMS x/y to it (for some reason)
Nice
now im having a completely different issue regarding making the sprite lmao
anyone know when decks are planned to get their update function readded
ok so I have this calculate but the chips and mult seems to be reset after the upgraded I did a lil thing to walk around but it doesnt work sometime I think (some playtester said that they had lose some run because of that)
chips and mult are in hand_chips and mult, not G.GAME
I mean my overcharge trigger for upgrading a random hand but it's while the scoring so the score that was already calculate get reset
idk if the thing you say @red flower fix that
If you're upgrading a random hand mid-score, but said hand ends up being the one that's played, effect of that won't be applied 'til the next time you play it.
Just call the regular level up function and it should just handle the mid-score upgrade of a hand, then return back to the values as is.
like that ?
...why are you still setting G.GAME.chips? Just call the level up and that's it.
Should show the level up animation and set values back, yes.
ok I'll test it out
Visually something like such.
Tried to put such in an event?
ow I could wait I'll show you a video of whats happening
it goes from 400 X 19 to 150 X 19
...that appears to be a sticker, why not do it under if context.main_scoring and context.cardarea == G.play then or if context.individual and context.cardarea == G.play then?
Cause I dont want it to be retrigger
and not context.repetition
its cause I want it to be trigger after held in hand card and just before joker
Then it it's not being called right enough for the values to be restored properly.
yeah the return cant work because its random hand and it can be 2-3-or more random hand
...well, technically, it can.
it depends on how many overcharge you've discarded
Either way, you may probably need to manually save the current values, call the level up, then restore them manually, perhaps?
-# Or someone else will step in with a better solution- 😂
but it could be trigger at end of the hand no?
context.after?
local levelups = {}
for i = 1, val, 1 do
local ht = pseudorandom_element(hands, pseudoseed('okokokok123'))
table.insert(levelups, { level_up_hand = ht, level_up = 1 })
end
return SMODS.merge_effects(levelups)
Or something like this.
I'll try that it looks clean
yea it doesnt work either
...it'd be easier if that triggered after the scoring is done, why the specificity between held in hand abilities and Jokers?
idk I'll make it after
Probably because doing the level ups mid-scoring doesn't reset the values properly. As I said, you'd need your own function to save the values, call the level ups, then restore the values.
yeah it work fine with context.after
👍
ok uh
if (context.joker_main and #context.scoring_hand > 4) or context.forcetrigger then
local eligible = {}
for _, playing_card in ipairs(G.play.cards) do table.insert(eligible, playing_card) end
for _, playing_card in ipairs(G.hand.cards) do table.insert(eligible, playing_card) end
for _, playing_card in ipairs(G.deck.cards) do
if SMODS.has_no_suit(playing_card) then
local pc = pseudorandom_element(eligible, "nflame_buzzy")
SMODS.score_card(pc, context)``` idk why this isnt working
it crashes somewhere in talisman
...at least mention said crash.
How do you disable all base boss blinds in your mod?
it just points to a line number with no crash msg
Show regardless.
INFO - [G] 2026-01-27 19:47:44 :: ERROR :: StackTrace :: Oops! The game crashed
talisman/coroutine.lua:189:
Stack Traceback
===============
(1) Lua upvalue 'orig' at file 'main.lua:612'
Local variables:
msg = string: "talisman/coroutine.lua:189: "
(*temporary) = Lua function '?' (defined at line 31 of chunk [SMODS _ "src/logging.lua"])
(*temporary) = string: "Oops! The game crashed\
"
(2) Lua local 'handler' at file 'debugplus/console.lua:618' (from lovely module debugplus.console)
Local variables:
msg = string: "talisman/coroutine.lua:189: "
(3) LÖVE function at file 'boot.lua:352' (best guess)
Local variables:
errhand = Lua function '(LÖVE Function)' (defined at line 617 of chunk [lovely debugplus.console "debugplus/con
sole.lua"])
handler = Lua function '(LÖVE Function)' (defined at line 617 of chunk [lovely debugplus.console "debugplus/con
sole.lua"])
(4) field C function 'assert'
(5) Lua field 'update' at file 'talisman/coroutine.lua:189'
Local variables:
dt = number: 0.0701644
(6) Lua field 'update' at file 'talisman/coroutine.lua:210'
Local variables:
dt = number: 0.0701644
(7) Lua function '?' at file 'main.lua:955' (best guess)
(8) global C function 'xpcall'
(9) LÖVE function at file 'boot.lua:377' (best guess)```
Huh.
yea
ddoes anything stand out
is the issue that im passing the context table straight from the calc call into score_car
Potentially? Try saving context to a local variable then pass that instead?
do u mean lua local ctx = context
or a shallow copy
oh it could also be an infinite loop?
ok setting joker_main to nil fixes it
but also its not actually scoring the cards
Tried passing the actual context used for scoring cards, be it played or held?
wdym the actual context
i have a mod that i last updated in july of last year
how hard would it be to update that mod to current smods?
it adds like 20ish jokers and about a dozen consumables
local add_to_pool_ref = SMODS.add_to_pool
SMODS.add_to_pool = function(prototype_obj, args)
if prototype_obj.key:sub(1, 2) == "bl" and not prototype_obj.original_mod then
return false
end
return add_to_pool_ref(prototype_obj, args)
end
wdym
What type of scoring do you want that to do?
Ah thx
Played and scoring cards? Held in hand cards?
Check the randomly chosen cards' area, then set ctx.cardarea = G.play or ctx.cardarea = G.hand respectively?
ok
so like
if pseudorandom("nflame_buzzy") > 0.5 then
-- handle the played cards
else
-- handle the held cards```
local area = pseudorandom_element({G.hand.cards, G.deck.cards}, "nflame_buzzy")```
ctx.cardarea == pc.area, even, as you're directly checking played and held cards.
oh
alr
its still not scoring the cards
for _, playing_card in ipairs(G.deck.cards) do
if SMODS.has_no_suit(playing_card) then
local pc = pseudorandom_element(eligible, "nflame_buzzy")
local ctx = {individual = true, cardarea = pc.area}
for k, v in pairs(context) do ctx[k] = v end
ctx.joker_main = nil
SMODS.score_card(pc, ctx)
G.E_MANAGER:add_event(Event({
func = function()
playing_card:juice_up()
return true
end
}))```
Not sure then, being honest. 
-# Why aren't you just local ctx = context, then setting the ctx.cardarea?
context changes constantly. ctx would be static here.
ok
also i think i have to set the cardarea to play?
copyying what ortalab wallet does
If you want held in hand abilities to score on a card, ctx.cardarea = G.hand.
bam therre we go
You're doing scored effects on held in hand cards this way.
thats what i intended
rescore implies additional scoring on cards that already had been scored respectively.
yes but it also explicitly identifies held-in-hand cards as a viable target
rescore card in held hand would imply held in hand effects.
rescores as played card?
just "score" or "trigger" would be best i think
i like trigger, although i suppose that also implies it'd trigger held-in-hand effects
There's a reason I separated such scoring to be either targeting the played and scoring hand or held hand.
-# Easier to write a description for, too.
Even I am having a tougher time trying to formulate a better description for Buzzy Beetle.
Also, that'd mean if the hand contained more than 5 cards and at least one card is unscored, that'd proc it as if it was scored if the roll lands on it.
Probably not very. Most changes would probably have to do with patches which you can track down on your lovely logs
oh uh im using context.scoring_hand and not g.play
Assuming that is changed for the for _, playing_card in ipairs(G.play.cards) do table.insert(eligible, playing_card) end line.
yea
also whats the diff between "score", "rescore", and "perform additional scoring"
i see, good to know
For me, "score" is the regular scoring, but "rescore" and/or "perform additional scoring" I tie with effects respective of their CardArea.
Is there a way to modify what jokers appear in shop?
so "score cards in held hand" would work?
On its' own, yes, but trying to fit that in same sentence mentioning played cards is a bit of a mess.
unless you mean if a joker can appear or not
Might as well try tackle my first code round, this is meant to be a finsher blind that has the player play the rank that most of in their deck, how am I doing rn?
thats a lot of red
debuff_hand needs to be a table
modify would work
How would I put that in the deck's code?
hhhhhh what do u think would be the proper wording
calculate function
oh so calculate can go on decks too?
yes
yep
did not know that
theres no deck var tho, its just context(self, context)
incorrect
Show me where to start.
huh,,
did u look at smods
can i use context.modify_shop_card to change one joker into another joker?
what are u trying to do
"If scoring hand contains at least 5 cards, for every Stone Card in remaining deck, this Joker scores a random card in played or held hand.", perhaps?
don't ask questions you aren't prepared to know the answer to
I get some of it.
nah but really
I'm just wanting to make a custom list of jokers that can appear in a deck
@loud summit where should the table start?
ok then it was the second thing
wdym
alr
use G.GAME.banned_keys to ban jokers
would that go in apply
yes
you can also hook in_pool if you want to just ban a rarity ig
and do i have to manually ban everything
Again for context: "This is meant to be a finsher blind that has the player play the rank that most of in their deck."
yeah
ughh
oh you could loop over G.P_CENTERS
you dont need to go key by key if they have something in common
and check the rarity of each one
they do
Playing the a card of the rank that is most of in the deck... you may need the debuff_hand function instead of the debuff table then.
well thats not a vanilla effect so you have to code it manually
yeah
finding the most common rank in deck isnt that hard tho
you loop over G.deck.cards and tally each rank
...well, G.playing_cards in this instance. Unless the remaining deck is implied.
i assume its set on blind generation
like how the ox works
Guess I have make some code for the beaver to read the deck.
would that go in the decks apply function, or calculate
apply because you do it once at the beginning
SMODS.Joker{
key = "santile",
config = { extra = {odds = 4, chips = 150}},
pos = { x = 2, y = 3 },
rarity = 2,
cost = 5,
blueprint_compat=true,
eternal_compat=true,
perishable_compat=false,
unlocked = true,
discovered = true,
effect=nil,
soul_pos=nil,
atlas = 'grasslanderJoker',
calculate = function(self,card,context)
if context.individual and context.cardarea == G.play then
if SMODS.has_enhancement(context.other_card, 'm_stone') then
return {
chips = card.ability.extra.chips,
colour = G.C.CHIPS
}
end
end
if context.after and not context.blueprint then
for _, scored_card in ipairs(context.scoring_hand) do
if SMODS.has_enhancement(scored_card, 'm_stone') and SMODS.pseudorandom_probability(card, 'grasslanders_santile', 1, card.ability.extra.odds) then
SMODS.destroy_cards(scored_card, nil, nil, true)
end
end
end
end,
loc_vars = function(self, info_queue, card)
local numerator, denominator = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'grasslanders_santile')
return { vars = {numerator, denominator, card.ability.extra.chips}, key = self.key }
end
}```
Anyone know how to make it so the stone cards have the shatter animation when destroyed
hook SMODS.shatters
how do you add chip bonus to a playing card in context other than jokers
is G.GAME.banned_keys an array or what?
the same way
nope G.GAME.banned_keys[key] = true
...isn't it context.other_card?
Ah ok
oh you would want to check if other_card is card also
bc otherwise it would scale all cards in the hand
i dont think theres other_card in main_scoring
wait isnt the scoring effect usually through context.individual
so would it be this?
if G.P_CENTERS[i].rarity > 1 then
G.GAME.banned_keys[G.P_CENTERS[i].key] = true
end
end ```
this is a seal
Let's attempt to have me understand on how to code a deck reader just to declare a rank for a bossy beaver.
you want to check if its a string too
just add it if its not equal to 1

