#💻・modding-dev
1 messages · Page 599 of 1
sure hold on
i feel like the scoring parameter text might also be an issue?
unsure
maybe
i mean i dont really feel a need to optimize stuff unless it goes below 60 fps for me
fair i just noticed big lag spikes that felt kinda bad
hmm well i notice them in the video when selecting cards and pressing play
i mean since i see expo chips i'd assume ur using talisman's exp chips
nope
huh
ur own implementation?
maybe
How do you manually set the rotation of a UIbox? I've tried changing the transform rotation but that doesn't appear to be doing anyting
set up my dice mod to do the new text-on-cards stuff i figured out
i need to adjust the timing obviously, and i also need to figure out how to dynamically center the text if it ends up being 2 or 3 digits, but otherwise it's looking very nice
and now i don't need a 101-sprite-wide atlas lmao
hello when I leave the game and return to it my variable is filled with these values. What is this? I expected nulls I could do a if for do I make a val == "MANUAL_REPLACE"? xD
or how can I make a on_load function to reset this var to {}
It means you put something with a metatable in a place that is saved.
Which includes cards.
indeed I had cards saved
What is the goal?
I have a joker that destroys a hand and then recreates it
I save the destroyed cards
to recreate those cards
Yes, you would have to use Card:save and Card:load
so I would save a card when adding it to the table, but then how would I load it?
Card:load
fair enough, was talking about how to use the method but I've looked at the code now xD
How would I set a random rank to pick for a joker, but make it never change at end of round?
probably using a local set to false, make it select the rank only when it's false and then make it true in the same function
When do I run this?
can i see your code
ok i think the issue was this running literally every single frame
I did the other parts except for this cuz idk how
I'm trying to do smth like mail-in rebate but the rank never changes
Is there a context to run this like on buy or something?
Added minecraft splash screen quotes for funsies
a separate add_to_deck function in your joker
I have an issue where if I have multiple copies of the same joker and that joker uses pseudorandom_element as part of its calc func, all copies will have the same outcome
is there a way i can make them all have different outcomes while still using seeded pseudorandom_element?
Code?
local function reset_vremade_mail_rank()
G.GAME.current_round.vremade_mail_card = { rank = 'Ace' }
local valid_mail_cards = {}
for _, playing_card in ipairs(G.playing_cards) do
if not SMODS.has_no_rank(playing_card) then
valid_mail_cards[#valid_mail_cards + 1] = playing_card
end
end
local mail_card = pseudorandom_element(valid_mail_cards, 'vremade_mail' .. G.GAME.round_resets.ante)
if mail_card and yourlocal = false then
G.GAME.current_round.vremade_mail_card.rank = mail_card.base.value
G.GAME.current_round.vremade_mail_card.id = mail_card.base.id
yourlocal = true
end
end
i think something like that should work
calculate = function(self, card, context)
if context.before and next(context.poker_hands['Three of a Kind']) then
local non_awakened_jokers = {}
for i = 1, #G.jokers.cards do -- Non-awakened jokers into a table
if not G.jokers.cards[i].ability.chak_awakened then
non_awakened_jokers[#non_awakened_jokers + 1] = G.jokers.cards[i]
end
end
if #non_awakened_jokers ~= 0 then
local chosen_joker = pseudorandom_element(non_awakened_jokers, 'chak_trinity') -- Pick rand non-awakened
CHAK_UTIL.use_consumable_animation(card, chosen_joker, function()
chosen_joker:add_sticker('chak_awakened', true)
play_sound('gold_seal', 1.2, 0.4)
return true
end
)
return {
message = 'Awaken, my love!',
colour = G.C.CHAK_STICKER_AWAKENED
}
end
end
end,
it's the code for mir
tl;dr apply a sticker to jokers without that sticker
lmk if you find out i have the same issue with an edition
no what
don't do that
just put an add_to_deck function in the joker
the code in that function will run once upon obtaining the joker
yeah that's better
im tryna help but i started coding like two weeks ago just for balatro modding
my code is a mess
although actually if you want it to have its value decided already in the shop, do set_ability instead (that runs once upon creating an instance of the joker)
any ideas?
Have you tried adding card.sort_id to the seed?
how so?
pseudorandom_element(non_awakened_jokers, 'chak_trinity'..card.sort_id)
ill try
that worked thank you 
@plucky berry this solution worked
bump
is there literally ANY documentation on SMODS.JimboQuip by now?
there's been some in the 0827 changelog since the feature released
Looking good, but for some reason it tells me my G.GAME... variable is nil, how do I fix this?
wait actually it can't call global 'functionname' now
so im trying to use SMODS.blueprint_effect() to copy a random playing card from the deck
it's uh. not returning anything
Yes, SMODS.blueprint_effect is for jokers.
well yeah but
here
local random_seed = (G.GAME and G.GAME.pseudorandom.seed or "") .. "." .. "hypr_junkdrawer"
local triggercard = G.deck.cards[math.ceil(pseudorandom(pseudoseed(random_seed))*#G.deck.cards)]
if not triggercard then return {message = "Empty Deck!"} end
local effect = SMODS.blueprint_effect(card, triggercard, {main_scoring = true, cardarea = G.play})
if not effect then return {message="Failsafe?!"} end
card:juice_up(0.3,0.4)
return effect
--returns {Message="Failsafe?!"}
i got it to work Once and i have no idea what i did
local other_card = pseudorandom_element(G.deck.cards, "hypr_junkdrawer")
local eval = eval_card(other_card, {cardarea = G.play, main_scoring = true})
local effects = {}
if eval.playing_card then table.insert(effects, eval.playing_card) end
if eval.enhancement then table.insert(effects, eval.enhancement) end
if eval.end_of_round then table.insert(effects, eval.end_of_round) end
if next(effects) then
return SMODS.merge_effects(effects)
end
eval_card exists???
Yes.
How do I use eval to spawn a Joker with an edition?
SMODS.add_card({set = "Joker", edition = 'e_modprefix_key'})
Thank you :3
trying to make the joker display Charm Tag! when it creates a charm tag but it's not doing so
Yes, k_charm_tag_ex doesn't exist.
is there a way to make it exist or is it just hardcoded
add a localization entry for it
actually
hold on
i have a better idea
use the localization of the charm tag
one sec while i figure out how
do message = G.localization.descriptions.Tag['tag_charm'].name.."!"
@muted trout
Yes, move it out of the event.
trying to also show a message for this joker, im getting around to fixing it again
<@&1133519078540185692>
ykw nvm im keeping it messageless
bump 3
suit has to be capitalized, like 'Spades' or 'bunc_Fleurons'
it's a local variable, meant to store a random suit
those, to my knowledge, need not capitalization
how does it search for said random suit
is someone able to tell me why a message wouldn't be displayed here??????
print(suit)```
Like this!
And that part works
Well, the suit's just giving one, but it's not applying it still
want the whole consumable code?
no im good
does the message have to be in the return?
oh
yea
to change the rank, should I do a similar thing?
Like, swap out suit with rank?
assert() is a function returns its given value(s), but throws an error and crashes balatro if said value is nil
if was directed at me it doesnt work still
Ah. So, is that a yes I can swap suit with rank (mostly) or no?
yeah but put it 3rd
I had it like this for some time
trigger = 'after',
func = function()
SMODS.change_base(card_to_change, suit)
return true
end
}))
end```
that... should simplify it
ok both of you im gonna be fr i have no idea why your code is failing and im tired as shit so. im gonna go do something else, probably sleep. sorry
i already have one in my mod dw
Well, one for mine if you wouldn't mind
nah
im just keeping this messageless and nonblueprintable atp this code gotta be cursed or smth
Say, what are you trying to do?
make a joekr display a message when it produces it's tarot card
but it's not doing that
i may just completely redo the code
Hmm. I don't know how to help with that barring looking at the bananas in VanillaRemade
anything else?
nothing else is an issue atm
gn
Actually, I seem to have some details off
local xiferp_up_a_step = SMODS.poll_enhancement({guaranteed = true, type_key = 'shuffletheseed'}) and local xiferp_edition = poll_edition('xiferp_barium', nil, true, true, { 'e_polychrome', 'e_holo', 'e_foil' }) seem to not be pulling anything
replace the fat return with this
return {
func = function()
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound('timpani');
SMODS.add_card { set = 'Tarot' }
card:juice_up(0.3, 0.5)
G.GAME.consumeable_buffer = 0
return true
end
}))
end,
message = localize('k_plus_tarot')
}
already scrapped the joker srry
lmao rip
is there a way to make it so the copied card is glass???
ok ty
does anyone have the link to the vanilla jokers done in steamodded, i lost that link
omg thank u
also does anyone have like a 2X version of the vanilla joker sprite sheet?
does anybody know how i could make a seal that makes a card trigger a certain amount of times based on how much money you have?
as in it triggers once for every e basically
so at 0 dollars the card is debuffed, at 1 it triggers once, at 10 it triggers twice, etc etc
check out vanilla remade they have a reimplementation of every card
in this case you can probably look at the red seal implementation, going from something like this
SMODS.Seal {
key = 'Red',
pos = { x = 5, y = 4 },
config = { extra = { retriggers = 1 } },
badge_colour = G.C.RED,
calculate = function(self, card, context)
if context.repetition then
return {
repetitions = card.ability.seal.extra.retriggers,
}
end
end,
loc_vars = function(self, info_queue, card)
return { vars = { self.config.extra.retriggers } }
end
}
to something more like this
SMODS.Seal {
key = 'money_retrigger',
pos = { x = 5, y = 4 },
badge_colour = G.C.RED,
calculate = function(self, card, context)
if context.repetition then
return {
-- change the /10 to be / (money per retrigger)
repetitions = math.floor(G.GAME.dollars / 10),
}
end
end,
}
I have not tested this code but it would probably work
okok tysm
so the math.floor thing means it'll divide by 10, then do that again and again until it hits 1?
math.floor just rounds down
oh ok, so how would i make it do it based on powers of ten rather than just a retrigger for every $10?
repetitions = math.floor(math.log10(G.GAME.dollars))
ahh ok tyty
also to give the last used tarot card on discard for a seal would i be able to just replace the smods.add_card({ set = 'Tarot' }) line in purple seal with smods.add_card(G.Game.last_tarot) since the fool uses G.Game.Last_tarot_planet to determine the last tarot/planet card right
just this bit here
No, G.GAME.last_tarot doesn't exist.
Also that's not how you use SMODS.add_card
use your mod.calculate() in context.using_consumeable to check whether the used consumable was a tarot and if so save its key to G.GAME["a mod specific variable"]
is it possible to do the opposite of this? making it so glass cards have a higher or lesser chance to shatter?
Yes.
how?
context.mod_probability
and how do i use context.mod_probability? new stuff i dont know anything about
👍
(go up to that convo, should have some information. And also look at Oops all 6s in vremade, or Union Help in Paperback)
a challenge for the tgirls, as a treat
YEAHHHHHHH
For the record the deck is 6 jacks of the default suits
Does it explicitly check if the jacks were turned into queens or is the goal just to get a deck with the same number of queens of the same suits
Basically it bans everything that destroys cards, and you auto-lose if you have less than 24 cards or you have any rank except jack or queen
jestrogen goes so hard here
I want to make a joker that allows Straight Flushes to be made with gaps of up to two ranks, how would I be able to do that?
You would have to patch get_straight and check if the hand contains a flush, then use a recursive function to get the next ranks of each next rank.
I mean like, how do I patch that? Ideally to add on the code rather than replace it?
[[patches]]
[patches.pattern]
target = '=[SMODS _ "src/overrides.lua"]'
pattern = '''
if skip and (wrap or not SMODS.Ranks[v].straight_edge) then
for _,w in ipairs(SMODS.Ranks[v].next) do
ret[#ret+1] = w
end
end
'''
position = "at"
payload = '''
if type(skip) == 'number' and skip > 1 then
local function get_next_ranks(rank, skip, ret)
if skip > 0 and (wrap or not SMODS.Ranks[rank].straight_edge) then
for _,w in ipairs(SMODS.Ranks[rank].next) do
ret[#ret+1] = w
get_next_ranks(w, skip - 1, ret)
end
end
end
get_next_ranks(v, skip, ret)
elseif skip and (wrap or not SMODS.Ranks[v].straight_edge) then
for _,w in ipairs(SMODS.Ranks[v].next) do
ret[#ret+1] = w
end
end
'''
match_indent = true
Thx, will see what I can do with this
Is there a context for after pack opening is concluded?
I think so considering how red card works, recommend checking vanilla remade
Thank you, I completely forgot about Red Card!
Just checked and it has context.skipping_booster, so not the one
You mean when the pack is opened or when the pack is closed?
When it's closed
No, hook G.FUNCS.end_consumeable
Or alternatively a context that goes before setting_blind
What do you mean?
I want a pack that adds jokers to a pool, the way I have it now is that opening the pack gives eternal negative copies, and setting blind will kill those jokers and add them to the pool
The issue is, if you choose a joker that does stuff at the start of turn or when setting blind, they might trigger even though they're being destroyed, and I want them solely for the reason of having reference jokers to add to the pool
So I meant that when setting blind, it would trigger before anything else that triggers on setting blind, and kill them before they would trigger
Hook SMODS.calculate_context
Thank you!
I really feel like I should finally learn how hooks work as that seems to be the answer to most stuff, instead of trying everything to have a workaround that doesn't need hooks
ok that makes sense
Gonna be honest, I have no idea how to use this as I am still pretty new to modding, sorry.
It's a lovely patch, you put it in a toml file. Check the lovely documentation and other mods' implementations for more details
How to make a custom reward in the cashout screen independent of any jokers or such
Patch G.FUNCS.evaluate_round
Thanks
how do you create a dummy card with a name
is there a way to detect if a card was created?
how can I make a deck where you don't have some ranks ?
context.card_added?
that could work
and then context.card to see what card was created
Is there a way to make a shader that makes cards translucent?
bump
Can I use vanilla joker as a texture for back of custom deck, without making custom assets for my mod?
bump
I tried running this code, but it throws an error: ‘attempt to reference field ‘atlas’ (a nil value).’
key = "onecard",
atlas = "Joker",
pos = { x = 5, y = 6 },
...```
nevermind, solved the problem
Have you tried using ' instead of "? Sometimes that makes a difference iirc
Maybe try putting print() at different places in the code to see when it crashes
Well, I fixed it, so it's fine now
Okay
(at least it's working as I want it to)
I just tried using single quotes instead of double quotes, but I still get the same error. As I understand it, the error message says there’s no atlas field for SMODS.Back, but the Steamodded API docs suggest that it should exist.
It says that it can't find the atlas you set, meaning there is no atlas named "Joker"
Oh yeah, I had assumed it wrong. Thanks for the explanation, I needed that since I’m new to Lua.
You're welcome
Now I have an all-new error: ctrl-c'ing my cards breaks the game
SMODS.Consumable {
key = "cerium",
set = "xiferp_Element",
atlas = "Golden_Brick_Road",
cost = 3,
pos = { x = 1, y = 7 },
unlocked = true,
discovered = true,
config = { extra = { 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,
use = function(self, card, area)
card.ability.extra.yes_is_no = true
end,
calculate = function(self, card, context)
local id = context.other_card.get_id()
if context.individual and context.cardarea == G.play and id == 3 or id == 5 or id == 7 or id == 9 or id == 14 then
if card.ability.extra.yes_is_no == true and (lanthanide_mult or 0) > 0 then
lanthanide_mult = (lanthanide_mult or 0) + 20
local give_mult = lanthanide_mult or 0
SMODS.destroy_cards(card, nil, nil, true)
return { mult = give_mult }
end
end
end,
loc_txt = {
name = 'Cerium',
text = {
'Adds +20 mult per odd card for',
'the hand after this is used',
},
},
}```
Here's the code of the card
You're not checking if context.other_card exists at all.
No, remove the calculate function.
And put it all in use or...
No, put it in your mod calculate
Also you should be doing what Odd Todd does.
so, put all of the stuff that was in the calculate and put it elsewhere. I- that- That's probably smart...
(I was trying to calculate it in the card itself)
local id = context.other_card.get_id()```
like this?
No, it's context.other_card:get_id()
And you can shorten the check to just if context.other_card then.
How did I miss that typo
: and .
And it doesn't even work as I thought it would
(no +mult per odd card)
Code?
SMODS.Consumable {
key = "cerium",
set = "xiferp_Element",
atlas = "Golden_Brick_Road",
cost = 3,
pos = { x = 1, y = 7 },
unlocked = true,
discovered = true,
config = { extra = { 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,
use = function(self, card, area)
card.ability.extra.yes_is_no = true
end,
calculate = function(self, card, context)
if context.other_card then
local id = context.other_card:get_id()
end
if context.individual and context.cardarea == G.play then
if (context.other_card:get_id() <= 10 and
context.other_card:get_id() >= 0 and
context.other_card:get_id() % 2 == 1) or
(context.other_card:get_id() == 14) then
if card.ability.extra.yes_is_no == true and (lanthanide_mult or 0) > 0 then
lanthanide_mult = (lanthanide_mult or 0) + 20
local give_mult = lanthanide_mult or 0
SMODS.destroy_cards(card, nil, nil, true)
return { mult = give_mult }
end
end
end,
loc_txt = {
name = 'Cerium',
text = {
'Adds +20 mult per odd card for',
'the hand after this is used',
},
},
}```
I used someone's guide to have it use then destroy after giving mult
(and set up to copy it for more with other cards)
lanthanide_mult doesn't exist so it will never be greater than 0
this one.
I set it to 0 at the start.
it exists
local lanthanide_mult = 0
This is the code for it
No, local variables aren't saved.
Well, how else do I set that up so that it does get saved?
Put it in G.GAME
ah. so.. local G.GAME.lanthanide_mult = 0
No, remove local
G.GAME.lanthanide_mult = 0?
Yes.
Any place to put it in the file? (guide says to put it outside of consumables, but inside the file)
No, it would be inside the consumables.
G.GAME.lanthanide_mult = (G.GAME.lanthanide_mult or 0) + 20
lemme see
SMODS.Consumable {
key = "cerium",
set = "xiferp_Element",
atlas = "Golden_Brick_Road",
cost = 3,
pos = { x = 1, y = 7 },
unlocked = true,
discovered = true,
config = { extra = { 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,
use = function(self, card, area)
card.ability.extra.yes_is_no = true
end,
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:get_id() <= 10 and
context.other_card:get_id() >= 0 and
context.other_card:get_id() % 2 == 1) or
(context.other_card:get_id() == 14) then
if card.ability.extra.yes_is_no == true and (G.GAME.lanthanide_mult or 0) > 0 then
G.GAME.lanthanide_mult = (G.GAME.lanthanide_mult or 0) + 20
local give_mult = G.GAME.lanthanide_mult or 0
SMODS.destroy_cards(card, nil, nil, true)
return { mult = give_mult }
end
end
end
end
loc_txt = {
name = 'Cerium',
text = {
'Adds +20 mult per odd card for',
'the hand after this is used',
},
}
end
}```
Like this?
so like that code?
not like that code, it's not giving any mult or destroying itself
SMODS.Consumable {
key = "cerium",
set = "xiferp_Element",
atlas = "Golden_Brick_Road",
cost = 3,
pos = { x = 1, y = 7 },
unlocked = true,
discovered = true,
config = { extra = { 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,
use = function(self, card, area)
card.ability.extra.yes_is_no = true
end,
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:get_id() == 3 or context.other_card:get_id() == 5 or context.other_card:get_id() == 7 or context.other_card:get_id() == 9 or context.other_card:get_id() == 14 then
if card.ability.extra.yes_is_no == true then
if (G.GAME.lanthanide_mult or 0) > 0 then
G.GAME.lanthanide_mult = (G.GAME.lanthanide_mult or 0) + 20
SMODS.destroy_cards(card, nil, nil, true)
end
end
end
end
end,
loc_txt = {
name = 'Cerium',
text = {
'Adds +20 mult per odd card for',
'the hand after this is used',
},
}
end
}```
Think I broke something
Nevermind, fixed it
Hey friends, I'm working on a joker right now, and I want it to take you back an ante after a boss blind, but only when it's in the leftmost position. How would I get it started?
if context.modify_ante and context.ante_end and card == G.jokers.cards[1] then
return {modify = 0}
end
and that's in the calculate function?
Yes.
wait is that it? or is that just how I would start the function
No, that is everything.
wow that is a lot more simple than I expected. last time I tried to work it out with y'all we were talking about hooks and all sorts of complicated stuff
Also, is there a way I can make a specific function not copyable by blueprint?
Because I was testing out Arceus and it created TWO copies of Ultra Necrozma when I fused Dawn Wings with Solgaleo
if not context.blueprint
ok cool thank you!
I want to make a joker that decreases blind size, when it decreases the blind size though, it isn't displayed. How do I change that?
Ooh ooh! I think I can help you!
Could you explain to me how, please?
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
Let me test it
Thanks a lot
did I miss out on something? (custom boosters)
That's a common error I've noticed, and I wanna know how to fix it myself
wait actually no
ohhh
alr
documentation sure is cool
https://github.com/Steamodded/smods/wiki/SMODS.Booster
How do I make deck have certain cards in
I did enter smth in group_name
asking context sure is cool
it's not actually literally group_key, you set a specific group key in the booster and then localize that key
well that makes sense now
name = 'Element Pack',
text = {
'Pick 2 of 8 Element Cards to use later',
},
group_name = {
'Elements'
},
}```
Like this?
not a table, just group_name = 'Elements'
you may want to use a table if you plan on having more than one group appear
based based based
forcefem
is it forcefem if i want it to happen
voluntaryfem
medically assisted fem
Hey does anyone know why when I make a custom enhancement or seal and try to make my custom joker create cards with that new enhancement/seal the game crashes like it isnt registered properly?
Are you sure it actually is?
send the code
when I try any other enhancement it works correctly
It's m_modprefix_key
- you should use
SMODS.add_cardinstead ofSMODS.create_card, it handles the emplacing (and iirc the context calculate?) for you automatically - your key is entirely wrong, in the create_card or add_card call it should have
enhancement = "m_modprefix_radiantqueen"(where modprefix is replaced with your mod's prefix)
No, it does not call the context.
ah ok
ohh now it works tysm you're amazing
Clearly I'm appealing to the right audience lmaooo
anyone know how i add +1 hand during joker scoring
try
ease_hands_played(number of hands)
inside your context
oki
can someone give me an example of ^X formatting in text
like what is the standard color etc. of that
for exponents dark_edition is usually used
since it's not vanilla there's no "correct" answer but yeah dark_edition
that being said if you use the basic mult or chips colors for exponents i will find you
ahahahha
Trying to alter values on consumables from the outside. I've got it working, insofar that it actually changes what a tarot card would do, but I'm not entirely sure how I'd be able to consistently make the loc_vars actually reflect the internal values of a card. I suspect I'd need to change the values stored in card.config.center.config to reflect the values in card.ability.consumable, but that seems to still not get through
Is this change at creation or when the consumable already exists?
When it already exists
Hmm yeah that's rough. Cardsleeves does something similar but is restricted to creation so it works out
youd need to change the values in card.ability.consumeable, card.ability.extra, and card.ability
nah, that's not the issue
is this on vanilla consumables?
might just be card.config instead of card.config.center.config
going through the code I want to say it's reading from card.config.center.config for the loc_vars like Ice said originally, but I didn't double check that in-game
I tried reading directly from the ability table and had that not work either, but maybe I set that up incorrectly in some way 🤔
god it is so frustrating how balatro automatically truncates ANY numbers you give to its loc_vars to remove the decimal point
how do i/can i disable that
i dont think it does that
might be one of your mods
because like. hologram
and lucky cat
and others
how tf did you even
in loc_vars
return { vars = {G.hypr['trickcoindesc']}}
in update
G.hypr['trickcoindesc']= '{C:green}'..pct1..dot..pct2..'{}'..G.localization.misc.dictionary['k_hypr_workaround']..G.localization.descriptions.Back.b_blue.text[1]
huh
Ok so wait, are you trying to change the dictionary text on the fly?
yes
can you escape the color codes?
that part's working
If so there's a very easy way to do that
like with a backslash
and keep the colors
in the loc_vars return, you can specify key = and then a string pointing towards the dictionary key
what i'm trying to do is make it say 12.5% chance instead of 12% chance
changing the dict text on the fly was an attempted workaround
which didn't work
👆
Ok so I patched in the code and managed to make my joker just be a shortcut clone
How would I be able to make it so the code checks if the hand is a straight flush and if true, the skip value is 2?
local smods_shortcut_ref = SMODS.shortcut
function SMODS.shortcut()
if next(SMODS.find_card('j_grasslanders_emmie')) and next() then
return true
end
return smods_shortcut_ref()
end```
2 instead of true
Thx
Now about checking if the hand contains a flush...
Ik I can't just do context.poker_hand('Straight Flush') because this function is very out of context.
if next(get_flush(hand)) in the patch?
I'm not sure if I'd like to implement that into the patch as it could interfere with other jokers I would want to make.
Could it be called from the SMODS.shortcut() function by any chance?
No.
This isnt working :(
What is not working about it?
I click on the challenge, and it crashes
fixed it
although decks use "joker_slot", challenges need to use "joker_slots"
dk why
Hello friends! I come with an issue that I'd like resolved
Xerneas gives a bonus 1.2x mult to every card played. However, as soon as a hand started scoring, it crashed. Can someone figure out what's going on?
whoops
perma_bonus doesn't exist in your config.
this is damn near vanilla, only ortalab, lovely and smodded on red deck after resseting my profile
put perma_bonus in config, but it gave me the same error
Code?
Did you start a new run?
i restarted the game, but i could probably do a new run to be safe
Greeting modders of ballsatro
can you not use ^ in lua for exponents?
Less of a specific Balatro modding question and more of a Love2D shader question, but how would I draw an image in a shader? I've got the basic uniforms properly working (an image and its width/height as a vec2) but the texture itself only shows up as one solid color
// This is what actually changes the look of card
vec4 effect( vec4 colour, Image texture, vec2 texture_coords, vec2 screen_coords )
{
// Take pixel color (rgba) from `texture` at `texture_coords`, equivalent of texture2D in GLSL
vec4 tex = Texel(texture, texture_coords);
// Position of a pixel within the sprite
vec2 uv = (((texture_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
vec4 depths_tex = Texel(depths_texture, vec2(prophecy.y/prophecy.y)/depths_dimensions);
if (tex.rgb == vec3(1.0)){
tex.rgb = depths_tex.rgb;
}
// required
return dissolve_mask(tex*colour, texture_coords, uv);
}
isn't it math.pow
you should be able to, why?
show the line where you use it
bumping this - not sure if I'm misinterpreting what the second parameter in Texel is meant to be
okay I got it :D the thing I was looking for was texture_coords
is it possible for the soul sprite to have a different display_size to the backing? i have a soul sprite that's wider than the card but i don't want the joker's hitbox to also be that wide
why does incrementing count inside the for loop change it from a number to a table?
i was trying to make a joker that would change the font of the game when a hand is played, but my game keeps crashing and i dunno how nor why, can anyone help me?
Oops! The game crashed:main.lua:2312: bad argument #1 to '?' (filename, File, or FileData expected)
Do you have Talisman installed?
Talisman turns hand levels into tables.
How do I prevent a consumable card from ever showing up in the shop?
in_pool = function(self, args) return args.source ~= 'sho' end
'sho' Is supposed to be 'shop',yes?
No.
Alrighty then
Is there a way to make a shader that makes cards translucent?
how do you change the ante
try ease_ante(number of antes)
how would i add another card to the title screen?
steal aikoyoris code
im trying to find it
it's the main menu hook in modules/hooks/general.lua in aikoshen
How to make to a booster pack unskippable?
Why are the numbers the wrong way around when leveling up the mult? I want it to say 16 + 3, not 3 + 16
do you know how?
I have an idea how to
Here's the relevant code
is store_joker_create a native config or is it unique to Cryptid?
nvm found the answer UwU
bump
I'm trying to make a Sticker that would return itself to the shop after its sold or destroyed; to make sure it targets itself, would i use something like key = self or something else?
is it possible to disolve a card without it making the disolve sound?
bump
how to set hand size to a set number
G.hand:change_size((-G.hand.config.card_limit)+number)
ok thx
can i make it so an event stops letting the player play any hands for a select time?
are you directly calling Card:start_dissolve?
yes
it has a silent argument, does setting that to true not skip the dissolve sound?
not sure how to actually set them is the thing
card:start_dissolve(nil, true)
is there a reason why it crashes when blueprint copies it
i mean i could just not make it compatible with blueprint
It's return nil, true
@royal seal hey are you the person who made the pokermon mod? and if so is this the mod not working correctly or are not all of the cards been given art yet? its fine if not just not sure if its not working right for me
Yeah as far as I'm aware its working, that's very odded. Perhaps its an issue with steamodded
Theres like some cards that dont hsve this issue tho like I think all the mega and a handful of regular pokemon and also all the item amd energy cards are fine
So idk
Yeah I'm not sure, that exact issue hasn't been reported before
I think the other mods I had on were cartomancer, talisman, deck sleeves, malverk and thats it
Same issue when also adding the 2 pokermon mods that are on the mod manager
Other modded cards work fine though
the game crashed when i destroyed a card (which gives a chance to create a spectral with this joker)
It's #G.consumeables.cards
works perfectly now tysm
after i code in this next joker i'll have my first 15 done, would anyone like to try the small mod out?
yes
I would love to
i wanted to post a spongebob gif but spongebob is evil also thanks
Can you infoqueue stickers?
i would imagine you can, considering that they automatically infoqueue themselves on cards that have the stickers
hold on, lemme check if paperback does it for ultra rare (that joker spawns other jokers with the Temporary sticker)
ok yea you can
info_queue[#info_queue + 1] = { set = "Other", key = "modprefix_stickerkey" }
Thanks!!!
anyway i'm gonna throw this over here bc it didn't really catch any traction in the smods server, and i'm a little stupid so i'd really appreciate feedback on if this feature seems hard to use/what utility functions (if any) might make it better :3
this is a potential new SMODS feature that makes it possible to draw a Love2D Canvas object as a card sprite in-game, allowing you to modify it on the fly and e.g. render text as if it was printed on the card (normally, UI objects can't follow the 3D effects on cards because they don't get rendered through any shaders like cards do). i initially put this together for the blockbuster counters api but it could definitely be super useful in other places (i have at least two unrelated concepts i'm personally planning to use this for)
right now the state of it is essentially "you have to put love.graphics calls in the DrawStep where you render the CanvasSprite so you can actually put stuff on the canvas", and that might not necessarily be a bad thing! it's a fairly advanced feature, but i feel like it's at least a little bit barebones
i'd also like to see if anyone has any use cases beyond "drawing indeterminate text on a card", because right now the drawing code is hardcoded to assume the canvas will have an aspect ratio of 71:95 and idk if anyone has plans to use it on something other than a playing-card-shaped object
(note that you can just use set_sprites() or vanilla/smods animation systems for most cases, this is primarily useful if you have potentially dozens or hundreds of possible unique graphics you want to display on a card object and you can generate the graphic itself from just a single value or whatever)
https://github.com/Steamodded/smods/pull/1020
an example use case is demonstrated and linked in the PR's description
@tepid crow I think I figured out that crash btw
for _, v in ipairs(G.P_JOKER_RARITY_POOLS[4]) do
G.GAME.banned_keys[v] = true
end```
Entirely unrelated to sleeves but if you're interested. I had code banning all Legendaries because of a sleeve giving a guaranteed Legendary at Ante 6 in exchange. It seems like the crash is related to the game not knowing how to handle no available legendaries in the pool, possibly because of the code for guaranteeing the first legendary each run not being gold stickered, and it ends up saving bad data about the seed
is there a way to get a random key from an Objecttype?
im trying to make a booster pack that, when opened, creates cards of a specific enhancement type but im getting kind of lost figuring out some of the finer details
Yes, pseudorandom_element
gotcha
do you just insert the key of the objecttype or is there a specific thing you need to start it with
pseudorandom_element(G.P_CENTER_POOLS.objecttypekey, 'seed')
coolio
hm, okay weird thing, it seems to be outputting the entire table? kjdhfksdfhj
Code?
one sec
okay
I feel like it has something to do with my objecttype but im not Entirely Sure
AHA
OKAY
ive located the issue
IM A GENIUS
thanks for the help!!!!
how can i force the game to save?
for the run? try save_run()
i haven't come across an error like this yet so im curious what i need to do
it worked, thanks!
i've seen this error while coding in custom boss blinds and it's not actually related to images (in my case, at least)
i... don't remember/know the exact thing that needs to be done for this error to be fixed (or show up in the first place) but i stopped seeing it eventually
i found the corrupted png and exported a new version over
all good
now as for the ACTUAL reason im here
SMODS.Sticker {
key = "unkillable",
badge_colour = HEX("a86232"),
pos = { x = 0, y = 0 },
atlas = "unkillable",
calculate = function(self, card, context)
if not inscrypt_unkillable_triggered then
inscrypt_unkillable_triggered = true
return
end
if not (context.destroy_card or context.selling_self) then
return
end
G.E_MANAGER:add_event(Event({
trigger = 'after',
func = function()
-- Re-run after Oroboros finishes upgrading
local joker_key = card.config and card.config.center and card.config.center.key
if not joker_key then
return
end
local new_card = SMODS.create_card {
set = "Joker",
key = joker_key,
area = G.shop_jokers
}
if not new_card then
return
end
create_shop_card_ui(new_card, nil, G.shop_jokers)
G.shop_jokers:emplace(new_card)
-- Copy updated stats (after Oroboros upgraded)
if card.ability and type(card.ability.extra) == "table" then
new_card.ability.extra = {}
for k, v in pairs(card.ability.extra) do
new_card.ability.extra[k] = v
end
end
new_card:start_materialize()
new_card.states.visible = true
new_card.ability.couponed = false
new_card:set_cost()
new_card:add_sticker("inscrypt_unkillable", true)
inscrypt_unkillable_triggered = false
return
end
}))
end
}```
This code is meant to make it so that the card attached to the sticker reappears in the shop
it works.... but infinitley. all at once.
i spent like five hours yesterday redoing the code over and over again and fine tuning it
infinitely as in it clogs all slots in the shop?
i learned so much about lua just to end up with no results TvT
no as in it creates itself infintly
beyond the shop slots
not even ChatGPT can give me an answer as to what's wrong
you could... create a local variable somewhere when you add the joker to the shop, and next time you try to add it, check if the variable already exists
and reset said variable when exiting or rerolling the shop
already did that with local inscrypt_unkillable_triggered and it doesn't seem to work no mater the combination i use
either it creates itself infinitley or the code stops itself in its tracks and doesnt create a new version in the shop
maybe you should create it elsewhere..? i don't really know where though
it's a global value that exists outside of the sticker code
guys what do i need to make +score and xscore work (like astronomica or mayhem)
i don't think it's in talisman and it's def not in smodded
Why are the numbers the wrong way around when leveling up the mult? I want it to say 16 + 3, not 3 + 16
bump2
you can either disable the function, by creating a mod that essentially just removs the skip function whenever you are in a booster pack or you can (im not 100% sure) remove the toggle
I want to make a specific kind of booster packs unskippable not all of them
i assume still can do it tho
I imagine that this requires some sort of patching right?
wdym?
I mean making a lovely patch
ok I will try patching
I could try looking at ur code, but I’m not 100% sure.
I honestly haven’t modded Balatro, just got into it but i have modded other games
--- STEAMODDED HEADER
--- MOD_NAME: Othermod
--- MOD_ID: Othermod
--- MOD_AUTHOR: [Ai gen goku]
--- MOD_DESCRIPTION: somethings awaits !
--- MOD_PREFIX: other
----------------------------------------------
------------MOD CODE -------------------------
-- made so that other mods in the other genre works
-- {hehe mod comPAT} local usingprefix=SMODS.Mods and SMODS.Mods{"Name"} or false
NFS.load(SMODS.current_mod.path.."Others/Othermod_Jokers.lua")()
NFS.load(SMODS.current_mod.path.."Others/Othermod_Packs.lua")()
----------------------------------------------
------------MOD CODE END----------------------
guys how outdated is this?
Oh my god
I havent coded balatro mods for 2-ish years
bump
Crossmod functions for making certain jokers appear when you have a mod on
your event doesn't appear to ever return true
which means it will keep running every frame forever
also I'm not sure you're using that triggered variable correctly, there's only going to be one of them and it will be set to true any time the sticker is calculated anywhere?
generally, if chatgpt has no clue what's going on, the problem is something to do with how the game works and not a lua issue
just be careful, because it will never ever tell you when it doesn't know what's wrong
How do I keep a Card from getting debuffed?
And how do I use a gradient as a badge color?
how do you spawn two cards of a modded enhancement using a held in hand card?
chat weird question
i think
how can i make a joker permanently remember how many runs it has been used in
if that's possible
save it to your profile or mod config
guys how can I check if the jokers have been moved ?
let's break it down
first, i assume "using a held in hand card" means "copy all attributes of the given card, but give it the new enhancement"
step 1: copy the card
local card1 = copy_card(G.hand.cards[i]) (where i is the position of the card in hand).
step 2: apply the new enhancement
card1:set_ability("m_modprefix_enhancementkey")
step 3: do it again for a second card
step 4: calculate the playing_card_added context so that e.g. hologram counts the new cards
playing_card_joker_effects( { card1, card2 } )
it's an enhancement
yes
that's what step 2 handles
no, the enhancement creates 2 cards with 900n1's "blankcard" enhancement.
ok
you can still do this in the enhancement's calculate function
silenced gives 2 blank cards when held in hand then self destructs
to be clear, do you want it to copy a card or not?
not really no
candycane suggested i use the same snippet twice
since i'm basically making the same card
a blank ace
ok
then what you have already seems fine? do you still need help
do you still need help or not
yea
ok
with what exactly
you need to describe what's not working if you're still trying to do the enhancement, or you need to explain what this new problem is if it's related to whatever's in crk.lua
how can i make it so vscode doesn't think SMODS is a warning
as in, its given a yellow underline, the code works 100% i just dont know if i can make it dissapear
Install lua extension
i can't help you if you don't fucking explain what's wrong
the card does not do what it says it does
what is it doing then
oh wait
you need to use context.main_scoring for enhancements, not context.individual
Maybe it)s my fault for making always_scores = false
that. might also be an issue
actually no it's not
it's just the context thing
always_scores is false by default
does anyone know how to make a ui badge not marquee-scroll and instead just. get wider
Because no rank and no suit?
no
just in general
always_scores makes it behave like stone cards in that it'll score even though it's not part of the poker hand
just change context.individual to context.main_scoring and see if that fixes it
if you dont mean mod badges then those should work like that by default
@royal seal any idea how to fix this? or if theres a mod i have on that could be causing this?
I just had a quick question, if I have lovely installed do I also need steam modded?
This breaks for some reason```lua
SMODS.destroy_card(card, nil, nil, nil, true)
This is how the card self destructs
Right well this is completely broken screen recording apparently 😮💨
dont think so, but steam modded is used by like every mod ever
So is steam modded the framework and lovely the injector?
when will you understand that just saying "this breaks" is incredibly unhelpful
you need to explain how it breaks. if it's crashing, show the crash log. if it's not crashing, describe the current behavior and how it differs from the desired behavior
I guess
yes
lovely makes modding possible, SMODS makes modding a lot easier
alright thank you
I can’t copy the crash log anymore.
you can screenshot
back in my day we had an obfuscated demo and a dream (wasn't my day)
back in wilsons day
you can also just find the log in mods/lovely/log, open it in notepad, and scroll to the bottom
the top of the crash is a lot more helpful than the stack traceback
anyway it's destroy_cards, plural
What variable for shaders is the current sprite of the card it is on?
I'm unfortunately not sure as I can't reproduce that specific problem youre seeing. Maybe double check that the image files are all there in the folder, and you could also try using a different release or version of steamodded just to double check. Sometimes there's errors with the latest steamodded code that get fixed quickly
context.destroy_card and SMODS.destroy_cards
yep
Oh
thanks ill see what i can do
this might be wrong in so many levels```lua
calculate = function(self, card, context)
if context.cardarea == G.hand and context.main_scoring then
SMODS.add_card{ set = "Base", rank = "A", enhancement = "m_ninehund_blankcard" }
SMODS.add_card{ set = "Base", rank = "A", enhancement = "m_ninehund_blankcard" }
if context.destroy_card then
SMODS.destroy_cards(card, nil, nil, nil, true)
end
end
end,
Ok it works
bump
this is literally some of the most normal code I've ever seen
I’m gonna see if Silent Salt Cookie also works.
His last issue is not destroying glass cards.
Blank cards*
if context.destroy_card should be outside of the context.main_scoring check, anyway.
i wonder if i did this correctly (Silent Salt Cookie Joker)lua if context.individual and context.cardarea == G.hand then if context.destroy_card and SMODS.has_enhancement(context.other_card, 'm_ninehund_blankcard') then card.ability.extra.emult = (card.ability.extra.emult) + card.ability.extra.gainwiped SMODS.calculate_effect({ message = "+^"..card.ability.extra.gain.." Mult", colour = G.C.FILTER, instant = true}, card) return {remove = true} end end
bump2
That doesn't sound OP at all. Getting to return to the shop is great, but it's still super situational. I would generally prefer being able to dig during a blind to use my tarots, etc. There's a lot of value you can get out of a blind, from (for instance) interest, gold cards, blind rewards, joker scaling, and so on, that you're missing from this. I would only consider taking this if I'm in ante 1 or 2, on a small blind not on white stake, and I don't have much I can do in the blind.
and even then it's pretty marginal
no this is pretty balanced
but most tags are, so it's fine
it’s stronger than most other tags but most other tags are fucking ass
finally a reason to skip
the money gain is probably less than the money you'd gain from playing the blind anyway (although it gains more relative value if it shows up on a small blind at red stake or above)
so it's about the same level as other tags?
how would this work with double tag ? lol
lemme. test that lmao
leave shop an,d get immediatly back to it
oh interesting idea, I'll bet it triggers again when you leave shop, so you get +$10 and get to shop twice
it should do this imo
sounds like a bug you should fix
it should give $5 and take you to the shop, then when you exit the shop give you another $5 and take you back to the shop
true bc that does reset rerolls
it’s pretty similar to investment tag in terms of when it’s good
is better on red stake thougj
and refreshes boosters
The interaction between this and double tag makes this actually quite powerful
good on anaglyph
Ok so basically Silent Salt is a self sustaining Deck Fixing joker…
Evil
I like it
anyway to hot reload mods or do I have to restart the game every changes ?
restart the game
hold alt f5
also restart runs when you change things
@flat mountain @wind steppe the DebugPlus mod has save states - save with z+1/2/3, load with x+1/2/3
incredibly useful for mod testing
yeah already using it to easily spawn my joker
how to check if a specific kind of booster pack is opened?
i know
if you change the code though
save states don’t help
is this too strong of a spectral
(you pull it from the spectral pack instead of using it immediately a la cryptid code cards)
no seems fine
Anyone know why my shader only works on cards of the first column from their spritesheets?
try doing something with modulus on the texture coordinates or uv or something?
What?
It's fine, I just don't know what you mean by that
do you know what modulus does?
No
here 1s
it basically just wraps it
it's formally defined as mod(x, b) = ((x/b) - floor(x/b))*b
Okay, how would I implement that the best way?
just use mod()
it's a builtin
or it might be modf() or fmod() i forget
are these too strong
how do decimal antes work
they interpolate the blind size log-linearly
seems fine then
local orig_get_blind_amount = get_blind_amount
function get_blind_amount(ante)
local fract_ante = math.fmod(ante, 1.0)
if fract_ante == 0 or fract_ante ~= fract_ante or not (fract_ante > -math.huge and fract_ante < math.huge) then
return orig_get_blind_amount(ante)
end
-- Log-linear interpolation
return
(
orig_get_blind_amount(math.floor(ante))
^ (1 - fract_ante)
) * (
orig_get_blind_amount(math.floor(ante + 1))
^ fract_ante
)
end
easy button actually looks a bit weak tbh
fair
0.8?
yea
that's fair
can i ask why you aren’t using math.ceiling btw
I don't get where I implement mod() in my code
it's floor(ante + 1) not ceil(ante)
it doesn't actually matter but
for correctness
all of the things in my mod are implemented 🎉 now i just need to draw the assets
huh, when starting a blind the event queue just keeps piling up, how can I debug what cause that ?
btw why does this just not grow to the width of the mod name, only wrapping when it hits the edges of the gray box
i mean
No, I mean like using it. Or do you mean that it does that for everything by itself?
i know why, it's parented under the same thing the voucher label is
i mean like
mod() is a builtin function in glsl
like mix() or dot()
Okay, I don't know where to use it in my code, like on what variables and stuff. That's what I was trying to say there
ohh okay
it's just
you could probably use it to wrap the x and y coordinates of the texture atlas when plugging it into the relevant parts that aren't fetching the actual card texture
Could you explain that to me on my code, please?
idk where your code is doing what so i probably wouldn't be able to
local oldfunc = Game.main_menu
Game.main_menu = function(change_context)
local ret = oldfunc(change_context)
if PRegalia.config.pip_menu then
G.SPLASH_BACK:define_draw_steps({
{
shader = "splash",
send = {
{ name = "time", ref_table = G.TIMERS, ref_value = "REAL_SHADER" },
{name = 'vort_speed', val = G.C.vort_speed},
{name = 'colour_1', ref_table = G.C, ref_value = 'PSEUDOBLACK'},
{name = 'colour_2', ref_table = G.C, ref_value = 'PSEUDOGOLD'},
{name = 'mid_flash', ref_table = G.C, ref_value = 'mid_flash'},
},
},
})
end
return ret
end
trying to make my custom menu's colors to change depending if the config is on or not, it only works the first time the game start, but when you come back to the menu, it goes back to the default colors, anyway i can keep it the custom colors ?
idk if that's the problem but it should be Game.main_menu = function(self, change_context) and oldfunc(self, change_context)
Maybe it could be why, i'll give it a shot
I saw the custome logo title atlas always stay so yeah
Do these comments help explain it?
Thanks that solved it
is it possible to make a joker predict what joker's are gonna be next in the shop? like next shop or reroll
Can anyone help me with my problem?
[[patches]]
[patches.pattern]
target = "functions/button_callbacks.lua"
pattern = '''
if G.pack_cards and (not (G.GAME.STOP_USE and G.GAME.STOP_USE > 0)) and
(G.STATE == G.STATES.SMODS_BOOSTER_OPENED or G.STATE == G.STATES.PLANET_PACK or G.STATE == G.STATES.STANDARD_PACK or G.STATE == G.STATES.BUFFOON_PACK or (G.hand )) then
e.config.colour = G.C.GREY
e.config.button = 'skip_booster'
else
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
e.config.button = nil
end
'''
position = 'after'
match_indent = true
payload = '''
if Card.config.center.group_key == "k_would_you_rather_pack" then
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
e.config.button = nil
end
'''
how to get the config.center.group_key from the booster pack?
my {C:attention}brother{} has a very {X:blue,C:white}special attack{}
Hello friends! I recently added a voucher to my mod (admittedly with the help of jokerforge) and it's not showing up in the collection, and I don't think it's loaded into the game at all. i tried modifying the main.lua file to include it, but it's still not showing up. How can we fix this?
Does your mod shows up in balatro's mod menu?
yes it does.
And the voucher is inside when you click on it?
no, the voucher isn't loaded in the game. the files are there, but the game just doesn't want to load them.
Can you show the voucher code?
Sorry can you send a screenshot? Im on phone
Is vouchers/legend_aura.lua get loaded in main.lua?
Does load_vouchers_folder get called? Meaning is it written somewhere else?
Anyone know why my shader only works on cards of the first column from their spritesheets? Please just someone help me TwT
i don't know, would you know where it's supposed to be?
Can you find, say, where load_rarities_file is called?
Or similar functions with content that properly loads?
it's further down in main.lua
hold on i might have fixed it
You added the missing func call?
i think i did
Neat
bump
Its trying the load the folder instead of the files inside, did you modify the function?
ohhhhhhhhhhh
ok i got it working
but in a slightly spaghetti-code way
it's looking for vouchers.lua in the main folder for the mod
but I don't have one there
so i just copied legend_aura.lua from the vouchers folder and put it in the main folder
but it's working now
Well I mean if it works
bump
Hey guys I've got a question. How do yall make those seamless gradients for your cards (like the background of bean joker, Oops all 6s, etc...) ?
How to fix problem with smods take ownership on vanilla jokers where the lovely file card.lua still tries to apply the original effect?
is it possible to halve an individually scored card's chips with a joker? but like only if the joker is in the deck, otherwise its normally scored
Does anyone here understand shader?
can you show a code example of when this is happening?
Are you able to help me with that?
yeah i have no idea sounds like love2d jank
ill ping someone who
knows shaders
uh
Okay, thank you
What?
how do i make it so that a group of jokers can only appear in the shop once a specific joker is in the main joker slots
SMODS.Joker:take_ownership("j_matador",{
loc_txt = {
name = "Matador",
text = {
"{C:attention}X#2#{} Boss Blind Size",
"Gain {C:money}#1#${} Per Card Scored",
"During a Boss Blind"
},
},
config = { extra = { dollars = 4, extra_blind_size = 2 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.dollars, card.ability.extra.extra_blind_size } }
end,
calculate = function (self, card, context)
if context.setting_blind and G.GAME.blind.boss then
G.GAME.blind.chips = G.GAME.blind.chips * card.ability.extra.extra_blind_size
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
end
if G.GAME.blind.boss and context.cardarea == G.play and context.individual then
return{
dollars = card.ability.extra.dollars,
func = function()
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.dollar_buffer = 0
return true
end
}))
end
}
end
end
}, true)
here is a matedor rework
Hmmm trying to come up with the easiest way to mark that a joker has been "triggered" in a run. I believe I need to hook SMODS.calculate_individual_effect?
or just SMODS.calculate_effect if ret.calculated = true?
you could try throwing a return nil, true at the bottom of the calc function
You could make a global
that's kind of assumed yeah
bump
By the way, are you able to help me with my shader problem? It's doing weird stuff and I don't know why or how I could change it
It works now thanks
Okay, that's fine. So, my shader should mirror the left side of the joker it is on onto the right side. It does that but only for the first Column of the sprite sheet (left of blue line). The others it just does nothing (it triggers my debug lower, to be correct). Do you know why this might be or how I could achieve that shader on a different way that might work?
-# That was the wrong file, oops
Just means your original UV coordinates are incorrect afaik
If they can't scale past the first column
How do I change that?
your local coordinates are wrong
yeah
I think
the standard uv calc the game does is
MY_HIGHP_OR_MEDIUMP vec2 uv = (((tex_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
the entire sprite sheet is sent to the shader, so your local.x is likely only < 0.5 for the first column
I've sometimes needed to modify this, specifically for transforming one texture coord to that of another:
MY_HIGHP_OR_MEDIUMP float width_mod = texture_details.b / image_details.x;
MY_HIGHP_OR_MEDIUMP float height_mod = texture_details.a / image_details.y;
MY_HIGHP_OR_MEDIUMP float x_pos = (uv.x + texture_details.x) * width_mod;
MY_HIGHP_OR_MEDIUMP float y_pos = (uv.y + texture_details.y) * height_mod;```
(I honestly don't remember why the original didn't work here)
Okay and how would I change my shader to work?
Okay okay right I see now
The conversion I just did here was for a mask shader of a different atlas size than the base card, so it correctly scales the pixel coordinates for one "unit" of the larger atlas to the smaller single image atlas used by the mask
the x_pos and y_pos I showed you will give you the local position within the single sprite (0-1), rather than along the whole atlas
replace your local with
float width_mod = texture_details.b / image_details.x;
local = vec2((uv.x + texture_details.x) * width_mod, uv.y);```
This'll give you the correct local x coordinate for each sprite in the atlas
And then it should work?
assuming the rest of your math is good, it should?
But I haven't looked into it deeper
I think my math needs adjusting XD
WOA
Jimbo everywhere
That's actually cool what
The largest jimbo you ever seen
W I D E J I M B O
it is wide witch checks watch Thursday
Lol intervention
I wanted to ask about stickers and after buying a Joker with it nothing is printing
I'm having an issue with a blind disabling cards. This is for even rank cards. When the blind starts, the card do debuff (cards in my hand are visibly so), but when the I check the deck... the game crashes. Any help would be appreciated
calculate = function(self, blind, context)
if context.debuff_card and context.debuff_card.area ~= G.jokers and not G.GAME.blind.disabled then
if not SMODS.has_no_rank(context.debuff_card) and
(context.debuff_card:get_id() <= 10 and context.debuff_card:get_id() >= 0 and context.debuff_card:get_id()% 2 == 0) then
return {debuff = true}
end
end
end,
Back to where I was a few hours ago...
Trypophobia mod lol
We getting there
May I request your help again? I can't make it work
The code I gave you from earlier only squashed to the local x coordinates so you can repeat it with the y coords too
replace your local with
float width_mod = texture_details.b / image_details.x;
float height_mod = texture_details.a / image_details.y;
local = vec2((uv.x + texture_details.x) * width_mod, (uv.y + texture_details.y) * height_mod);```
logically that should work assuming it's squashed into local space
hi i missed the start of this conversation can you send me the details of whatever this is thank u (i have plans to write up some shader guides, and this seems helpful/relevant i think?)
Then why isn't it working...?
Shader guides would be very nice
Oh yeah it's just a simple scaling for texture coordinates between atlases of different sizes. In this context, I need to get the "local" coordinate of an individual sprite in a larger sprite atlas to map onto a single mask texture that's only 71x95
Because the actual coordinates fed directly into texture_coords are respective to the full atlas dimensions
cool, thanks
There is nothing wrong with this, is there?
vec2 local = (((texture_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
float width_mod = texture_details.b / image_details.x;
float height_mod = texture_details.a / image_details.y;
local = vec2((uv.x + texture_details.x) * width_mod, (uv.y + texture_details.y) * height_mod);
if (local.x > 0.5) {
local.x = 1.0 - local.x;
}
vec2 mirroredUV = (local + texture_details.ba + texture_details.xy) / image_details ;
vec4 tex = Texel(texture, mirroredUV);```
you don't need to convert back to that mirrored UV
you shoud just be able to do Texel(texture, local)
Now it just mirrors the atlas
Those are Greedy Joker, Lusty Joker, Wrathful Joker and Gluttonous Joker
yo how would i remove vanilla content when my mod is enabled
mmm yeah that implies that the local is still scaled to the whole texture for whatever reason
Any idea why?
Looks like you do gotta scale back, but I'll give you a different calc that's the reverse of what I did
The first half of the atlas is not affected, only the second
well yes that's because of the if local.x > 0.5 part
That's what I thought
you're only mirroring the right half of what you assumed was the individual card, but what's actually the whole atlas
vec2 local = (((texture_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
float width_mod = texture_details.b / image_details.x;
float height_mod = texture_details.a / image_details.y;
local = vec2((uv.x + texture_details.x) * width_mod, (uv.y + texture_details.y) * height_mod);
if (local.x > 0.5) {
local.x = 1.0 - local.x;
}
local = vec2(local.x/width_mod - texture_details.x, local.y/height_mod - texture_details.y)
vec2 scaled_tex_coords = (local * texture_details.ba + texture_details.xy*texture_details.ba)/image_details
vec4 tex = Texel(texture, local);```
That converts back to the original full uv coordinates, though that's typically used for the dissolve effect
vec2 local = (((texture_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
float width_mod = texture_details.b / image_details.x;
float height_mod = texture_details.a / image_details.y;
local = vec2((uv.x + texture_details.x) * width_mod, (uv.y + texture_details.y) * height_mod);
if (local.x > 0.5) {
local.x = 1.0 - local.x;
}
local = vec2(local.x/width_mod - texture_details.x, local.y/height_mod - texture_details.y)
vec2 scaled_tex_coords = (local * texture_details.ba + texture_details.xy*texture_details.ba)/image_details
vec4 tex = Texel(texture, scaled_tex_coords);```
And this should be back to base texture coords
Which one do I use?
The latter is more likely to work
This are the results, both don't work
All have the shader applied to them
I don't get why it's not working
Neither me, but unfortunately that's a consequence of dictating through someone else rather than experimenting with it myself. Chances are I did some math wrong somewhere
I mean, you could experiment with it yourself, if you'd like to
That involves pulling myself away from the thing I'm currently working on
You don't have to experiment on it now, I can wait. If it means that in the end it might work, then I'm happy
That's fine
And thank you for helping me in the first place, I really appreciate it :D
😊
How do I add a dependency of a specific mod on a Joker?
Just ping me, write me dm or in https://discord.com/channels/1116389027176787968/1414216997943644291 to let me know when you tried some stuff
dumb hand idea: flush spectrum
a hand containing at least 5 wild cards (4 with four fingers)
someone is here to help me?
wrong link at first oops
in what line i put the code?
remove the dependancy then
I didnt even make it dependent
I gave it cross mod content
@solid salmon do this then
Othermod = {}
Othermod_Mod = SMODS.current_mod
Othermod_Config = Othermod_Mod.config
if next(SMODS.find_mod("FusionJokers")) and Othermod_Config.OtherFusions == true then
Othe_has_Fusion = true
else
Othe_has_Fusion = false
end
SMODS.load_file("Others/Othermod_Jokers.lua")()
if Othermod_Config.OtherFusions then
SMODS.load_file("Others/Fusions.lua")()
end
Othermod_Mod.config_tab = function()
return {
n = G.UIT.ROOT,
config = { align = "m", r = 0.1, padding = 0.1, colour = G.C.BLACK, minw = 8, minh = 6 },
nodes = {
{ n = G.UIT.R, config = { align = "cl", padding = 0, minh = 0.1 }, nodes = {} },
{
n = G.UIT.R,
config = { align = "cl", padding = 0 },
nodes = {
{
n = G.UIT.C,
config = { align = "cl", padding = 0.05 },
nodes = {
create_toggle { col = true, label = "", scale = 1, w = 0, shadow = true, ref_table = Other_Config, ref_value = "OtherFusions" },
}
},
{
n = G.UIT.C,
config = { align = "c", padding = 0 },
nodes = {
{ n = G.UIT.T, config = { text = "Other fusions", scale = 0.45, colour = G.C.UI.TEXT_LIGHT } },
}
},
}
},
}
}
end
i used this
how do i add something to the end of another card's name?
this is for upgraded planet cards, i'd like to add +s to their names
im new to making new decks, is there a way to make initial face cards be glass cards?
In the process of reworking the Achievement Tab so that it's more in line with descriptions elsewhere and supports text formatting
Looks nice :3
forgive the solution looking obvious
loc_txt
the way that you do the glass card thing is to have an event that changes the cards in G.playing_cards
what would the event have to contain?
a for loop, an is_face check and a set_ability call
im not in the mood to write it out, sorry
Im trying to make a joker that will do an effect when a playing card in hand gets triggered (e.g. steel card doing its thing). but I cant get the joker to trigger
I tried context.individual and context.cardarea == G.hand but it does the effect for every card in hand
it is done
Struggling to figure out how to force scaling on these boxes to have a consistent size
currently suffering the classic modder problem of "wants to try playing with more mods but doesn't want to have said mods mess with idea of how to balance their cards" lol
(well, mostly for mods trying to be somewhat vanilla like I suppose, but u get what I mean, right? lool fnjsdkj)
play joyousspring then
nooooo, not agaain, please 😭 lmao /j
(I cannot understand yugioh mechanics lmao to save my life lmao)
(no offense lol, just not my type of thing lol dfnsf sorry 😔)
how do i make it so that a joker destroys a specific joker
how do i change G.shared_soul
I have some ideas for possible effects for editions I have that I wasn't sure on before, so, if u know, please tell me if these are possible and if so, how I might be able to go about coding them, thanks! :3
- Vouchers in shop cost $1 less
- x2 mult before scoring hand (basically doubling your base hand mult)
I just know that back when I was trying to make editions before there was some trouble with making passive effects work w them lol
why its error?
my code:
SMODS.Sticker{
object_type = "Sticker",
key = "sk_joked",
atlas = "sticker",
pos = { x = 1, y = 5 },
badge_colour = HEX("#19f519ff"),
rate = 0,
should_apply = false,
no_sticker_sheet = true,
prefix_config = { key = false },
loc_txt = {
name = "Joked",
text = {
"1/2 chance to laugh instead of score",
},
},
}
I'm going to bed dfjksdnkf I is tired ndfjksnfkjd :<
if u know pls @ me lol, so I may come back to this in the morning perhaps dsfkjsdnk
is it possible to get the poker hand without context.scoring_name? I am trying to get the number of planet cards for the current poker hand without actually playing it, for something with JokerDisplay
jokerdisplay has functions for it
john joker display
how does something like red seal count toward the trigger count? if i make an enhancement that can retrigger how can i make a joker pick up on that?
it's basically hardcoded, you would need to hook this
https://github.com/nh6574/JokerDisplay/blob/73c707e86bd289be62f942fd0b4b3507185b54fe/src/api_helper_functions.lua#L209
whelp, an attempt was made
how would i go about changing the sprites of the small and big blinds

i donnot know how to make a joker usable
idk, I just checked baron's code and the conditionals are context.individual and context.cardarea == G.hand.
so now i will use that same method i used for the blind because im clueless on how to make a active ability for a joker.
MAKING IT ENTIRELY IN LOVELY.
Because it checks for kings in hand
Does anyone happen to know how to trigger a joker whenever any card gets destroyed (not discarded or sold)?
checks
ik
So I don't know why your joker shouldn't work.
Unless you are doing additional checks.
Then I don't know.
I'm not rn
Wait I think I just got an idea
"You used F5"
It gave me a whole new perspective
And I was able to see a chest I couldn't have seen before
But whatever I thought of checking for context.repetition
and right on top of that chest there was a locked hopper, and if you bothered checking it, you would find the solution for coding problem!
See if printing stuff yields any results.
Can't do stuff rn (school in 30min)
Which prompts me to this

How tf would you help me? End school earlier?
idk
Isn't there a check for that in context
if you can test stuff we can figure out and find out
idk
Last time I did any joker wizardy was like 2 months ago.
I forgor my contexts and how the fuck they work.
^ this
also how would i go abt removing the vanilla blinds when my mod is enabled
Ortalab does change those sprites right
i dont think so?
Nope they do
p sure they just replace small and big blinds
from what im seeing in the source
