#💻・modding-dev
1 messages · Page 589 of 1
<@&1133519078540185692>
Boom
Ty 👍
It's 0.7 times scale.
thanks
in eval_card, card should point to the joker, right?
im trying to use destroy_cards to destroy some cards but im messing up marking the cards to be destroyed (what im trying to do in the first image). i feel like im messing up something really obvious 😅
local variables are not kept between contexts
also context.individual already loops through all cards, you don't need to loop inside it
SMODS.destroyed_cards doesn't exist, it's SMODS.destroy_cards
cheers, programming is hard when im tired :))))
sorry to bother you again but I got an error where table is "nil". i assume that means that I can't include it in config? if thats the case, how would i declare it for use in both contexts?
No, but you can't put cards in other cards.
what would you suggest for making a table in the joker to store those gold cards that can be used in both contexts?
like whats the common practise for this type of thing in balatro modding?
would card in this instance be context.other_card as thats the one being checked for the enhancement?
yeah
can i refer to a different joker's variable?
how would i destroy all cards then that I've marked for destruction in context.after or would i have to destroy the card in that same context?
probably not, but would be nice i think
you can just do it in the same context but best practice is to use context.destroy_card actually
yes
what's the objective?
I don't get it
No, use Card:is_suit
the diamond card on the right does that counting already
that was my approach for a while but it was causing issues when using it alongside retrigger_joker_check
so i would like
heartsindeck + (different joker's variable) diamondsindeck
you don't need this hyperoptimization, it's easier and less error prone to just count twice, especially because is_suit already accounts for it
i see
how do you destroy a card instantly
SMODS.destroy_cards(card, nil, true)
oke
calculate = function(self, card, context)
if context.open_booster then
local newcard = card:create_card(card, 1)
local set = card.ability.set
SMODS.destroy_cards(newcard, nil, true)
end
end``` also is this a stupid thing to do
card:create_card doesn't exist
what's the effect supposed to be
when booster is opened, create the default card for the set
that's hard because boosters don't store the set anywhere and they can also have different sets
even in vanilla
thats why im approximating it by having it generate a card and getting its set
oh i get it now, yeah i wouldn't do that
i would get the first card in the booster area
uhhh no idea
hmn
so i should set up an event that returns false until the booster area's first card is non null?
and then run the code
if it doesn't generate before then yes that's what I would do
oke cool
bump2
isn't that covered in VanillaRemade?
no
Feels like something that should be.
i dont think there's anything ui related there
the only questions about UI are not done
Anyone know what mods I could look into for that?
mine :3
something like this
https://github.com/nh6574/JoyousSpring/blob/e0cdbd2da1daeb698eb2ebe14693811e8ab59e65/src/graveyard.lua#L521
You have a mod for a joker idea I have?
The joker goes like this: Once every ante, you can buy a rare or uncommon joker and get it in its own booster pack next ante. The rest of the time, it doesn't do anything except look flashy.
i don't understand what that means even
what part are you confused on?
where do you buy the joker from? the shop? what does its own booster pack mean?
also i don't play many mods so i don't have examples of effects at hand
I was thinking the joker is a phone, so you'd buy it digitally and it ships!
mb can someone help me pleasecan someone help me with this? dont mind the mods though i was trying to make something
Why did you use a double not here xD chosen = not not open_banishment,
You click on it, and a tab shows up maybe on the left saying "Buy r/u joker? ($n)" then you do and wait till it ships to you in a boooster pack
what's the code
there
it ensures it's a boolean, not very relevant
ohh ok yeah i get it
i don't know anything similar to give you pointers
do you know at least where to make a left tab?
that's the same file
like a button?
on the joker?
Yeah, like the sell and use ones
the game keeps crashing if i pick 5 cards during a blind
my mod i linked earlier adds buttons too, search for card:highlight
is this for a mod you're making?
Nice! I'll figure out the other part as it does.
yes,equipped with new jokers,blind and seals
The... code crashes?
Do poker hand levels start at 0 or 1?
in_pool = function(self, args) --equivalent to `enhancement_gate = 'm_stone'`
for _, hand in ipairs(G.GAME.hands or {}) do
if hand.level > 1 then
return true
end
end
return false
end
mostly just wanted to check if a hand was higher than 1 for a pool check
lmme do a few adjustments
1
awesome ty :>
similar to add_to_hand during modify_scoring_context, for deciding which cards do score, is there a remove_from_hand?
yea its in the smods wiki
wait this is documented? 💥 hold on
it's not
not finding it in calculate functions
but remove_from_hand is indeed a thing
oh i was close
can we edit how many cards a booster pack has inside it using vouchers?
bump
yes, there are a lot of vouchers and jokers that do it
i'm very original you see
the number of cards a booster has is based on the config value of the booster
Yes, change G.GAME.modifiers.booster_size_mod
search for booster_size_mod
https://github.com/Steamodded/smods/discussions/919
oh or that
why is this not on the wiki 💔
more undocumented vars my beloved
i think it's missing the chosen tab
i literally just sent the documentation
thats a changelog
with documentation
After I added chosen = true, I get this error:
that one is usually when your node is too nested
i know what rage against the machine is
i dont follow what that has to do with what you're replying to
So what would be some things I could change?
ok, i get what that means now but i still don't follow what that has to do with what you replied and why you moved the conversation to modding dev
try unnesting some ui nodes like
{ n= G.UIT.C, nodes = {} }
instead of
{{ n= G.UIT.C, nodes = {} }}
ai is not good at reading logs for balatro
BULLS ON PARADE
ai goes against the entire thesis of rage against the machine lmao
not with their consent
i don't care
Is this too vague of a description?
like this yes? (I tested it it works)
would be nice to have it be added +1 instead to accomodate for other vouchers that pretty much does the same thing
either way ai sure as hell isn't making anything for me
btw
Hi trif!
hellooo
then just add 1 to it
it's joever
what do you think about trump using ai

chat there's a rule about this
hello
shut up about ai discussion of it is banned
why would I waste my time on someone like this
can we kill this guy
everyone else block the guy
true true
there are infinitely many better uses of my time
I think rolling around in the mud would be more productive
driving up the electricity bill by 30% to ai generate motorcycle crashes 💜
shuuut uuuuuup
disengage
Muse Dashへの楽曲収録を記念して、ばやちゃおさんから特別仕様のMVをいただきました!
⇣「描いてみた」動画はこちら
https://youtu.be/wBo_-GPXDcQ
動画内に登場するキャラクター達はばやちゃおさんの創作『魔けモン!』のキャラクターです。
https://bayachao.wixsite.co...
modding-chatting in modding-dev 😥
aight got it
this is probably baby shit for the real programmers i feel kinda bad
I miss my x += num
idk it crashes when i do that
hawk.lua
they're saying they miss it in lua but yeah the way to do it is the way you did it
is there an easy way to detect if a copy_card call is being used to actually make a copy of a card in-game and not just for e.g. the deck view
if not G.SETTINGS.paused?
how to do recursion inside calculate?
how do i make a joker immune to changes made by oops / and other changes that could be made to the probability?
call calculate
don't do that, use no_mod in pseudorandom_probability
otherwise probability detection wont work with it
how to do that?
create a function
that does the actual stuffs
what r u trying to do
then calculate is a wrapper
for the function
local function recursive(card, ctx)
-- do things
if card.ability.extra.skibidi_id > ctx.skibidi_id then
recursive(card, ctx)
end
end
then in calculate
ok thx
{
calculate = function(_, card, ctx)
recursive(card, ctx)
end
}
for factorial and stuffs like that use a lookup table
recursion is usually last ditch
what is the difference between just using math.random(num1, num2) and using pseudorandom_probability?
math.random is unseeded
you should always use the pseudorandom functions over the base random stuff
will there be any issues when using unseeded?
well
yes
yes
main menu -> load run will also give different results
it will be independent from run seed
so running the same seed twice will give different outcomes
iirc
only ever use math.random for things that dont affect gameplay
so unless its something thats not important gameplay-wise, dont use math.random
yeah dang i should stop multi tasking
ok thx
i may be dumb how do i target another mod in a lovely patch? =[SMODS (mod_id) "(relative_file_location)"]?
Yes.
noted, thank you
when I try to call the function inside the function it says undefined global named func
uhh...
did you not declare the function beforehand
wdym by that?
weeeeeeellllll
you know what they mean
local count = 0
count = func(card, context, count)
why does this make it nil?
show the code for the func function
func = function (card, context, count)
if SMODS.pseudorandom_probability(card, "xmpl_glitchyness", 1, card.ability.extra.immutable.odds) then
count = count + 1
func(card, context, count)
else
return count
end
end
you need to return the recursive call, otherwise it just throws out the result
What in the world could cause cards to flip/become ghosted???#1335221042204901396 message
actually uh
in general this is kind of weird
First time seeing smth like that
ok thx
how do you fire a warning with debugplus
documentation is pretty cool https://github.com/WilsontheWolf/DebugPlus/blob/master/docs/dev.md#logging
oh
hey can someone look at this i can't seem to get it working
i'm trying to make this joker immune to probability changes
key = "recycled_joker",
atlas = "j",
pos = { x = 3, y = 0 },
rarity = 3,
cost = 8,
blueprint_compat = true,
config = { extra = { xchips = 2, xmult = 2 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.xchips, card.ability.extra.xmult } }
end,
calculate = function(self, card, context)
if context.joker_main then
if SMODS.pseudorandom_probability(card, tostring(G.GAME.seed), 1, 2, "recycled_joker", true) then
return { xchips = card.ability.extra.xchips }
else
return { xmult = card.ability.extra.xmult }
end
end
end
}```
wwwwwhyyy are you getting the seed directly
i can put anything in there right?
yea
How do I make a field for user input in a window?
what would be a better solution?
anyway i don't see anything wrong?
generally you make the seed a string related to the joker/whatever the effect is on, but there's nothing objectively wrong about doing it the way you're doing it
when i use this joker while having oops the result is always xchips
what version of smods are you using? the ability to prevent probabilities from being modified was only introduced in 0827
smods-1.0.0-beta-0827c
strange
i mean i can try to change the seed
worth a try? i literally don't see anything else out of the ordinary
still need help on this it runs fine for me but other people crash trying to run this
unfortunately that wasn't it
is it possible to fully replace a joker return
works fine on my end, how are you testing it?
i have no idea why
Are you playing rounds or loading a save state or reloading the game or what?
new runs
did you install smods from balatro mod manager?
no from the github page
maybe you have been really lucky lmao
maybe xd
but yeah no_mod works for me
hmmm
how to double the level of played poker hand
return { level_up = G.GAME.hands[context.scoring_name].level }
yeah or this if it's not in calculate
do you have cryptid installed
ok thx
ah no i tried with no mods
i think cryptid makes my joker behave weird
some mod might be hooking it wrong because it's a new argument to the function
it works fine without it
yeah it might have an incorrect hook, cryptid has some probability shenanigans
alr thanks
bingo
i used cryptid for testing other jokers that why i had it installed
i'll put in a bug report on the cryptid discord
Some time ago I made a joker that reveals the next 5 drawn card but I just discovered that for some reason the UI registers only the rank and suit of said cards and not if they have an Edition/Enhancement/seal.
How is it possible to fix this?
instead of c_base get the enhancement key
for edition and seal it's a bit more complicated because you need to save the card first and then give it the edition and seal
you can maybe use copy_card instead
but what happens if I put the enhancement key when there are no cards with said enhancement?
will it register them as defaults or..?
if you get the center key for a card without enhancement it will be c_base
also this means that I must put ALL the enhancements keys
including my custom ones...
i think you didn't understand what i said
use G.P_CENTERS[G.deck.cards[number].config.center_key]
Is there a way to set up a deck/back so that it prevents specific jokers/vouchers/etc. from showing up? i.e. I don't want Wasteful/Recyclomancy to show up for the deck
yes add them to G.GAME.banned_keys iirc
ooh alright
oooh now it works, thank you so much!
one question tho:
how does it like... work?
I didn't quite figure out what I exactly missed
'c_base' is the default card which was what you were using
that just uses whatever the current enhancement is
aight
so I always getting the base version of the playing cards
thx for the clarification N'!
I completely redid some code i had from yesterday to turn played face cards into queens, I took midas mask and combined it with some of ouija. It was working (though not as intended) so i redid it, i think it's better overall but now i'm getting an error instead of the wrong result. It's trying to set the suit to nil. I'm not sure why, i expected it to work fine since it's almost exactly the same as the original code i took
calculate = function(self, card, context)
if context.before and not context.blueprint then
local faces = 0
for _, scored_card in ipairs(context.scoring_hand) do
if scored_card:is_face() then
local _rank = 'Q'
faces = faces + 1
for i = 1, #context.scoring_hand do
G.E_MANAGER:add_event(Event({
func = function()
local _card = context.scoring_hand[i]
assert(SMODS.change_base(_card, nil, _rank))
scored_card:juice_up()
return true
end
}))
end
end
end
if faces > 0 then
return {
message = "Sweet!",
}
end
end
end
}
I think the rank is just called "Queen", not "Q"
as a quick follow-up, how would I get all the keys from a pool? I want to loop through a pool I've created containing all the banned keys
I'll try that, thanks
G.E_MANAGER:add_event(Event({
delay = 0.1,
func = function()
assert(SMODS.modify_rank(context.other_card, 1))
return true
end
}))
why not work?
That worked perfectly, tysm!
Is there a way to hide these? I want this card to be indistinguishable from a normal card
Nvm I figured it out
G.P_CENTER_POOLS.objecttypekey
ty!
Mister "Code-Problems" is back
Here's the joker code
Anyone know any clean fixes?
wheres "config = { extra ={ copy}}?
... nowhere?
so why are you trying to do something with it
I was trying to unlock jokers to see them show up in the shops
no why are you trying to do something with card.ability.extra.copy
i don't see it anywhere else in the code either
Cuz it's DNA but worse
"top to bottom" closes in line 60, it should close in line 69
no that's a hook
I tried to close it there, game yelled at me
top to bottom is fine
the joker itself does nothing, all it does is indicate that wrap_around_straights are supposed to happen
mb
DNA has card.ability.extra.copy because it has config = { extra = { copy = 1 } }. it's a configurable value for how many copies to create. you don't have that. either add that line to your joker or remove the loc_vars function
those... those aren't the right designs. And the names aren't there...
you need localization
and an atlas
well you need to do localization
and set which atlas you're using
yea you already have the atlas, you just need to tell each joker to use that atlas
Is that like a line at the top of the unified code, or is it per joker?
every joker has is own (atlas = "")
i'd rather not, but thanks for the offer
one of them loaded right, but the other two are invisible
you probably got the pos wrong for the other two
i see you have them at y = 1 and y = 2, but y is the vertical positioning
i assume your atlas has them all in a row, so you need to change the x value instead
And their names aren't there
that would be localization
documentation, once again, is really cool
https://github.com/Steamodded/smods/wiki/Localization
How do I make a field for user input?
if context.mod_probability and not context.blueprint and (G.cardarea == G.play or G.cardarea == G.hand) then
return {
denominator = context.denominator * 2
}
end
why this not work?
G.cardarea isn't a thing, and context.mod_probability doesn't get a context.cardarea (which is what i assume you were trying to check)
then how to do it?
what's your goal? is this a card modifier of some kind?
joker making glass harder to break
you should check if context.identifier is whatever identifier glass cards give for their probability rolls
you can figure that out by just having if context.mod_probability and not context.blueprint then print(context.identifier) end
ok thx
even if what you were doing did work, it'd have unexpected effects because there are other cards that roll probabilities when they're played or held in hand (lucky cards)
the identifier ensures that you're only affecting glass cards
bump
object nodes have the option for a text input field
i love zero documentation
Is it possible to have a deck/back double the interest at the end of round? I don't think decks can reward bonus money
decks can do calculates and other stuff just like any other card
though here you would just increase G.GAME.interest_amount by 1
How do I make one?
its.. ui 😱
actually
its not an object node
i forgot that its a seperate node type
G.UIT.I
documentation is so fucking cool
https://github.com/Steamodded/smods/wiki/UI-Guide
It doesn't show when I use that
brilliant way to get out of writing docs
fr lmao
im not an expert at ui but iirc text input fields need an id field or smth like that
plus a width and height so it actually shows
create_text_input function
Why does local position = pseudorandom{"bossRiddle", 1, #CSTORM.boss_riddles.Jokers} result in the error number expected, got table?
use parentheses, not curly braces
Shit, my bad. Sorryyyy
what is the table for all consumables?
(if there is one, I hope)
just do set = "Consumeables" in create_card
I'm trying to check the suit of the first two cards in a scored hand in a before context but I am getting a nil value specifically the second card I read. Specifically in the following line of code
if(context.scoring_hand[2]:is_suit("Clubs")
How do I get the second card in a played hand?
aight
the card is correct, but doesnt exist if the hand only has 1 scoring card
you should do if (context.scoring_hand[2] and context.scoring_hand[2]:is_suit("Clubs"))
so real
thank you
okay so, um I have no idea how did this happen.
How can I fix it in order to make the consumables get created in the consumables area?
How can I make this text move? Like the Joker names, for example
Theres no area in add_card
Add area = G.consumeables, to it
aight
Looking near Text motion modifier in https://github.com/Steamodded/smods/wiki/Text-Styling might help.
has to be dynatext, iirc
no idea how text animations work for ui though
Is it documented somewhere?
i dont think so
fire
Lovable?
hmm that's not bad
how can I set the edition of a consumable I just added?
should I make a local variable that stores the created consumable?
it would just be edition = 'e_negative' I think
oh, aight
How do I use dynatext?
as beautiful as you
Hi Dilly o/
Thinking of making an Xmult version of misprint, how do I achieve the description effect?
awwwwwww
man im just happy that there's going to be a proper way to make patches now
we're almost out of the dark ages
yea thats gonna be absolutely fantastic
UI needs to be less scary (easier) too
https://github.com/nh6574/VanillaRemade/blob/24ee6098f692a58a34d573dec5a86a347c5fd13a/src/jokers.lua#L641-L669 look at this and then pray that the changes you make to it work
also idk how background colours work with ui text you'd probably need to nest the text elements
what function handles spawning consumables for the collection
What are ref_table and ref_value for?
Didn't work, it just shows blank
im pretty sure it doesnt work if you dont have a text in your localization
should at least have a single empty line like misprint does
if you have that then idk
sorry for bringing this up again but the last suggestion worked, and now my joker is turning cards to the correct rank, but it's turning ALL scored cards into said rank instead of just the faces. could anyone figure a solution? I tried putting
if scoring_card:is_face() then
after defining card and before it changed the card's rank but it didn't change anything, i think i do need the statement but i can't determine where to put it
calculate = function(self, card, context)
if context.before and not context.blueprint then
local faces = 0
for _, scored_card in ipairs(context.scoring_hand) do
if scored_card:is_face() then
local _rank = 'Queen'
faces = faces + 1
for i = 1, #context.scoring_hand do
G.E_MANAGER:add_event(Event({
func = function()
local _card = context.scoring_hand[i]
assert(SMODS.change_base(_card, nil, _rank))
scored_card:juice_up()
return true
end
}))
end
end
end
if faces > 0 then
return {
message = "Sweet!",
}
end
end
end
how would i check if a given card is in the collection
not if it has no_collection if a card object is in play or in the collection
Anyone got any other ideas?
Why does the create_text_input stuff crash my game?
n = G.UIT.ROOT, config = {r = 0.1, minw = 8, minh = 6, align = "tm", padding = 0.2, colour = G.C.BLACK}, nodes = {
{n = G.UIT.R, config = {minw=1, minh=1, colour = G.C.MONEY, padding = 0.15}, nodes = rows },
{n = G.UIT.R, config = {minw=1, minh=1, colour = G.C.CSTORM.GIT, padding = 0.15}, nodes = {
create_text_input{
max_length = 30,
all_caps = true,
ref_table = Answers,
ref_value = "answer",
align = "cm",
callback = function()
check_riddle_answer(Answers.answer:lower(), Riddle.answer:lower())
end
}
}}
}
}```
Nvm, I got it
how would i go about making an oil lamp type effect
How do I add to the current score?
don't
(use the new Blockbuster value manipulation API maybe, check #1406740128231194644 for more details)
calculate = function(self, card, context)
if context.first_hand_drawn and not context.blueprint then
local eval = function() return G.GAME.current_round.hands_played == 0 and not G.RESET_JIGGLES end
juice_card_until(card, eval, true)
end
if context.cardarea == G.jokers and SMODS.end_calculate_context(context) and G.GAME.current_round.hands_played == 0 then
local currChip = hand_chips
local currMult = mult
card.ability.extra_chips = card.ability.extra_chips + currChip
card.ability.extra_mult = card.ability.extra_mult + currMult
mult = 0
hand_chips = 0
return {
message = localize('glutton'),
}
end
if context.joker_main then
return {
chips = card.ability.extra_chips,
mult = card.ability.extra_mult
}
end
if context.end_of_round and G.GAME.blind.boss and not context.blueprint and card.ability.extra_chips ~= 0 and card.ability.extra_mult ~= 0 then
card.ability.extra_chips = 0
card.ability.extra_mult = 0
return {
message = localize('k_reset')
}
end
end
this worked before I updated steammodded, any clue why it crashes now?
[SMODS Rickie "items/rimuru.lua"]:18: attempt to call field 'end_calculate_context' (a nil value)
use three tick marks at the start and end of a whole code block, instead of one at the start and end of each line, to make it easier to read
like this
bump
you just edited it to look better, yes
anyway I can only assume smods removed the end_calculate_context function in an update. what does that check do anyway?
honestly I don't recall at this point, I just came back to this after 2 months of not touching Balatro
Oh, and how do I check if a new run got started?
I wanna make an Xchip joker, does G.chips work so the joker knows how many chips there are?
Cos there's no xchip function.
there is an xchip function
you return xchips same as you would for xmult or mult or chips
also if you wanted to get the amount of chips for another reason you would use hand_chips
not G.hand_chips or G.GAME.hand_chips just hand_chips
howdy! this one's a little loaded but I think it's my last question for the day
I'm trying to make a deck so that every future instance of a specific consumable type gets replaced with one you already have; i.e. if you have Death in your consumables, all other Tarot cards will turn into Death.
I have my create_card_for_shop hooked so that it should do this + a custom function to do so but it's not working, plus it doesn't solve the other issue of every other way of obtaining a card turning into the right one. Any advice?
-- replaces a card with a card in the player's consumables if possible; takes a set and returns the KEY
function replace_with_player_consumable(set)
local shuffled_consumeables = G.consumables
pseudoshuffle(shuffled_consumeables, "j8mod_shuffle")
print(shuffled_consumeables)
for i, consumable in ipairs(shuffled_consumeables) do
print(consumable.ability.key.." is part of "..set)
if set == consumable.ability.set then
return consumable.ability.key
end
end
return nil
end
local ccfs = create_card_for_shop
function create_card_for_shop(area)
local card = ccfs(area)
if G.GAME.selected_back == "b_j8mod_hypnotic" then
local new_key = replace_with_player_consumable(card.ability.set)
if new_key ~= nil then
card:set_ability(new_key)
end
end
return card
end
Nvm got it working
now what variable determines the back of the text?
for Xmult?
hook the normal create_card instead of create_card_for_shop
and instead of set_ability just return a different key
How do I add to the current score, how do I check if a new run got started and how do I allow spaces in create_text_input?
dinamically changing config.center.config seems to not be affecting calculations
shame, i made such a clean recursive function too
holy hell was I outdated, that was for steammodded 0.9.8, new context would be context.final_scoring_step
baby is working again
Fixed my Undiscover mod as well
for v in pairs(SMODS.Centers) do
SMODS.Joker:take_ownership(v,
{
discovered = false
},
true -- silent
)
end
So if I'm understanding it correctly, with the new probability changes I could do something goofy like an enhancement that checks if a joker's probability is below 1/2, and then add 1 to it if so?
yep
although note that because it's via calculate functions, the enhancement might not get to it before e.g. oops all 6s modifies it first, and it'll see the doubled probability from that
(i dunno if enhancements calculate before or after jokers)
From what I'm seeing from how it's written, 6s should do it directly to mod.probability so that shouldn't be an issue
i think oops interacts with the new system now. maybe. i dunno for sure
but either way, it could still be an issue with any other modded content that interacts with probabilities like that
that's what I'm saying though, my assumption is when you get it it sets the global modifier
either way it does it's thing on buy and shouldn't be a problem
I can just whip something up to check after I fix all my probability stuff
How would I set the ability of a card to a random card from a specific pool?
(trying to set a joker to a random joker from my mod)
pretty tricky task, just did that myself technically
nice, lol
I'm trying to make the classic "deck that makes your jokers show up more often"
had to like. make a dummy joker card and manually trigger it n shit its a huge drag
in that case like
cant u just do card:set_ability(center of your card from ur pool)
to change a card into one of ur jokers
that's what I got going
But I'm not sure what the pool/set is for all my modded jokers
and I can't really create a card to do this b/c it's setting the ability
is there a mod that adds a whole seal-type thing to jokers but as a whole new thing
i can check out
one chat is enough man be patient
no, modding chat was more correct
but its for mod development
you can go thru rarity pools and check jokers to see if they have ur mod attached to them
youre looking for a mod, no?
that's a modding chat thing
if you're looking to reference code for your own thing, then yea this is the correct place. otherwise #⚙・modding-general was more correct
anyway Balatro Goes Kino adds Counters, and Paperback adds Paperclips
yea but im looking for it so i can check the code out to develop my mod
🫡
thanks
i'd probably recommend referencing paperclips instead of counters, because counters are a lot more involved and they can apply to jokers too (unless that's what you want)
i guess technically paperclips "can" apply to jokers in that they're stickers under the hood, but they're designed to only work on playing cards
there's still no way to check for the prescence of a sticker in a unified way right? even though now you don't need to apply the specific id of the sticker applied
oh okay thanks
yea i don't think there's anything for that unfortunately
I assume that'll get added at some point later and then I can cry and update my stickers again
But for now I only need to remove one entry of the apply function
how would i make an enhancement trigger after all the other card scoring is done (base chips, edition, etc)
its the fucking stupid shader shit
you have to use the edition1 var somehow
yea that crash indicates an issue in the shader.fs file itself
you can make a useless if statement with the edition1 variable
edition1.x > 2 * edition1.x or some shit
you hate to see it
Can someone help me or give a sample code on how to make a tarot card when used on a card replaces it Enhancement?
vanillaremade is pretty cool
https://github.com/nh6574/VanillaRemade/blob/24ee6098f692a58a34d573dec5a86a347c5fd13a/src/tarots.lua
Thanks for the help
u want to create an UIBox with the major set to G.ROOM_ATTACH iirc
i gotta go outside rn though sorry, i will get back to u when i get home
It seems like I can just offset the position by values in G.ROOM_ATTACH.container.T
How do I add the face decals on legendary jokers?
You mean the floating sprite?
Yeah starting to suspect it's soul_path
No, it's soul_pos.
yea
technically no, but it's a lot more effort than just putting the floating sprite in the same atlas
or wait lemme check the documentation hold on
ok yea you can't easily put the floating sprite on a separate atlas
No, you can use the set_sprites function.
which is why i qualified my statement with "easily"
And change card.children.floating_sprite.atlas
it's certainly possible, but often not worth the effort
Yes, but it's 3 lines.
still more effort than just putting the floating sprite in the same png as the base sprite
Jonkler Idea: "Real Joker" (joker itself is just a guy dressed up as Jimbo)
Effect: gains 0.5 mult if hand played is possible with a normal deck of cards (maybe except high card idk yet)
maybe a other caveat is it resets if you play a hand that's NOT possible with a normal deck ex. flush five
What's the best way to make a joker that copies the effects of every joker in the current run?
You mean every joker owned or every joker ever owned in the run or every joker that exists or every card that has ever shown up during the run?
Quick question: Does anyone know if there is a list of possible vanilla args.type arguments somewhere? (For card unlocking)
All of your jokers here
Yeah every joker owned.
...be mindful such can result in a stack overflow - I tried that myself before and it was one hell of a headache.
local effects = {}
for k, v in pairs(G.jokers.cards) do
if v ~= card then
local effect = SMODS.blueprint_effect(card, v, context)
if effect then
effect.colour = G.C.RED
end
table.insert(effects, effect)
end
end
return SMODS.merge_effects(effects)
Oh boy
-# At least such was the case for me, especially the probability contexts that would just loop constantly.
No, it wont break unless the card you're copying is copying the card and it's not using SMODS.blueprint_effect
thx
I personally had to add the (context.mod_probability or context.fix_probability or context.check_enhancement or context.blueprint or context.pseudorandom_result) as filter back when I still used it. 😅
loc_vars = function(self, info_queue, card)
local r_value = ""
local r_mults = {}
for i = card.ability.extra.min, card.ability.extra.max do
r_mults[#r_mults + 1] = tostring(i)
end
local loc_mult = ' ' .. (localize('k_mult')) .. ' '
main_start = {
{
n = G.UIT.T,
config = { text = ' X', colour = G.C.MULT, scale = 0.32 }
},
{
n = G.UIT.O,
config = {
object = DynaText({
string = r_mults,
colours = {G.C.MULT},
pop_in_rate = 9999999,
silent = true,
random_element = true,
pop_delay = 0.5,
scale = 0.32,
min_cycle_time = 0 }) } },
{
n = G.UIT.O,
config = {
object = DynaText({
string = {
{ string = 'rand()', colour = G.C.JOKER_GREY }, { string = "#@" .. (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11) .. (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.suit:sub(1, 1) or 'D'), colour = G.C.RED },
loc_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult, loc_mult,
loc_mult, loc_mult, loc_mult, loc_mult },
colours = { G.C.UI.TEXT_DARK },
pop_in_rate = 9999999,
silent = true,
random_element = true,
pop_delay = 0.2011,
scale = 0.32,
min_cycle_time = 0
})
}
},
}
return { main_start = main_start }
end,```
How do i make it so the X# mult here has the red background?
Using blueprint or brainstorm causes the card to activate more times than I'd like lol
Would it be best to make it blueprint incompatible for balancing?
Oki
Does anyone know what the unlock requirement code that Brainstorm uses looks like?
I need to copy it.
nice
how do you set a sticker on a card?
How do you get the current round number when triggering jokers?
I want a joker to do smth in odd numbered rounds and smth else on even numbered rounds for context.
card:add_sticker('modprefix_key')
thank you
G.GAME.round
Thx
This isn't working, specifically G.jokers.cards[1]:add_sticker('modprefix_key')
card:add_sticker('modprefix_key', true)
that works, thank you
calculate = function(self,card,context)
if context.first_hand_drawn and not context.blueprint then
local eval = function() return G.GAME.current_round.hands_played == 0 and not G.RESET_JIGGLES end
juice_card_until(card, eval, true)
end
if context.before and G.GAME.current_round.hands_played == 0 and #context.full_hand == 1 then
local scored_card = context.scoring_hand[1]
scored_card:set_ability('m_mult', nil, true)
G.E_MANAGER:add_event(Event({
func = function()
scored_card:juice_up()
return true
end
}))
return {
message = localize('k_upgrade_ex'),
}
end
end,
What's the best way to make it so the joker adds a random enhancement?
something like
local enhancements = {}
for k,v in pairs(G.P_CENTERS) do
if v.set == "Enhanced" then
table.insert(enhancements, k)
end
end
local enhancement = pseudorandom_element(enhancements, "some seed")
this will get you the key of a random enhancement, put that in set_ability()
assuming i didn't forget or miss anything, which is always possible
always use debugplus to test stuff to make sure it's what you think it is
...wouldn't it be simpler to
card:set_ability(SMODS.poll_enhancement({guaranteed = true}), nil, true)
?
Yes.
or that lol
i forgot that existed
How do I add specific jokers to a booster pack? To have it work similarly to buffoon packs, but just have a list of jokers that can appear?
Thx
Does it exclude stone cards?
Includes, as Stone is an enhancement.
Fair
Oh yeah what about making it so only cards with no enhancement are affected?
And so stones don’t get drawn?
Only stone cards or all enhancements that replace the card?
is there a list that stores all unlocked hands, or do i need to manually check through G.handlist?
I want to make the joker enhance a card without an enhancement with anything but stone…
On second thought maybe any card can be enhanced with anything but stone.
G.GAME.hands and check for SMODS.is_poker_hand_visible(key)
card.ability.set == "Base" iirc
No, it's not next(SMODS.get_enhancements(card))
do we care about quantum enhancements in this context?
local options = get_current_pool('Enhanced')
for k, v in pairs(options) do
if v == 'm_stone' then
table.remove(options, v)
end
end
card:set_ability(SMODS.poll_enhancement({guaranteed = true, options = options}), nil, true)
Thx
Yes, because the card counts as having an enhancement.
define "counts as"
Is treated by almost everything as having an enhancement.
okay, is that what we care about?
or do we care about "there's not already an enhancement there that will be overridden if we add this one"?
Sorry, spontaneous curiosity
that was directed at 515 anyway
grand, thanks ^u^
like - are quantum enhancements supposed to be completely equivalent to real enhancements, or are they supposed to be subordinate?
am i completely misunderstanding the design goal?
what is the difference between using strings message = "hello" and using localization message = localize("k_hello_ex") and is there any benefits?
the benefit of localization is that you can localize
like, the result of localize("some_key") can depend on what language the game is set to
(provided it's actually been translated, of course)
ok thx
how to change the text inside the loc_text using the calculate function?
how to check if a card is not scoring?
How do you know what enhancement the affected card currently has? That way using the joker on an enhanced card does not enhance a mult card to a mult card for example.
card.config.center.key
Thx
how to write custom info_queue?
just let it go already
someone always has to have the last fucking word instead of letting the conversation die down
go away
<@&1133519078540185692>
I would assume the person who brought back a dead conversation from yesterday
about a topic that's not even allowed to be discussed here
someone hurting your feelings doesn't make you automatically in the right
I have a paper due in 2 hours so I’m just going to say, if anyone continues this conversation you’re getting banned
❤️
gl with your paper
I lowk procrastinated too much 💔
i'm looking to replace this draw function, as it's not working properly
tilting the card doesn't interact with the shader
like, the light reflection doesn't shift
also, why is this tooltip appearing on Apollo's Bracelet?
it doesn't have loc_vars
Is there anything in the lovely dump in generate_card_ui that's adding an info_queue?
which script is that in, UI_definitions?
No, common_events.lua
hmm, seems like the only thing changing anything is MmmmmJokers
i'll disable it and see if that fixes it
alas, fix it it did not
here's the dump if u wanna take a look for urself
what do u mean by this
wat do u mean by this, too 🤔
is it like, retriggering the effect that retriggers jokers?
i suppose an easy way out of this would be like, patch/hook into whatever code that handles joker retriggers and multiply the number of retriggers if its retriggered
Yes.
making a huge guess it has to do something with eval_card, lemme check
yeah here, i think
if you run eval_card on a joker again in here then it should hopefully be rescoring?
though if you want it to like, rescore on all contexts then u probably can just hook to eval_card, run the ref function twice and merge the effects, idk
No, because it wouldn't activate retriggers again.
dang
wat about this :3
No, because it would just trigger twice.
whats the difference between that and rescoring though
Rescoring would happen after all triggers and retriggers are done and then activate triggers and retriggers again.
i feel like what i suggested should do that, since the first local a1 = eval_ref(...) for instance would include both the triggers and retriggers of the first time, then the second local a2 = eval_ref(...) would include those of the second time
if you merge them together, iirc ret from a2 will only run after a1's ret which should be identical? idk
🤔 unless eval_card doesnt account for retriggers which i can see why
Yes, eval_card doesn't include retriggers.
dang.
lemme find something else
hmm
how about SMODS.trigger_effects?
that should account for retriggers
-# hopefully
No.
wtf really
retriggers aren't real
how do i remove this (making a new stage/states)
No, that is used in SMODS.trigger_effects
im gonna cry
idk, my only idea rn is to figure out whatever function that has the return table of both triggers and retriggers, so you can merge them both together through SMODS.merge_effects....
uuuh... is it normal that with the coupon tag the booster packs prices become -1?
Okay nvm, I figured it out why it does that.
Some time ago I made two vouchers and one of them it adds one extra booster pack in the shop and makes it so booster packs cost 1$ less.
How can I fix this?
(I was thinking about specifying which voucher is allowed to modify the hooked set cost function but I'm not sure...)
self.cost = math.max(self.cost-1, 0)
just for clarifying can you remind me what does the math.max() command do?
takes the higher value among the two
aight
for instance, if self.cost-1 is 1, then since its higher than 0, it will be taken
else if its a negative number then it will take 0
thanks Bepis and Somethingcom!
the opposite is true for math.min
oooh I understand it now
How do I add to the current score, how do I check if a new run got started and how do I allow spaces in create_text_input?
Game:start_run
Okay and how do I allow the user to type spaces in a text input field?
Is that the overall score or just chips?
It's the blind score.
Wait, does update not exist in SMODS.Blind?
Yes, it doesn't.
does anyone have any idea what could be causing this artifact
it only affects one row of a specific sprite atlas
it doesn't show inside of image viewers or editors, only in-game
like the stone card description on the stone Joker but I wanna do my thing not just premade description and name
Really early WIP of a timetravel patch debugger. When complete it'll let you scrub through the patch timeline so you can see how different patches interact, etc. Should be cross mod easier
Oh and I added tabs to the editor
so you can keep stuff open while you work
4th dimension debugger when?
🤔
does the mod description allow blank lines? I feel like it looks a bit crowded
As far as I know, there is a way to completely override the mod description tab.
I don't know exactly how it works, but there is an option for that.
Well, more than an option, a function.
if you are already using a localization file just have a line with a space in it
hey guys how do i make my custom consumable not appear in the shop? like spectral cards
okay ill just set it to 0
ok yeah if you leave it empty it's set to 0 too
bump
put it in set Other in the loc file and then do info_queue[#info_queue+1] = { set = "Other", key = "the key of the entry"}
where is the text part?
you put it in your localization file like joker text (but in Other instead of Joker)
can you show me an example I learn best with these
is there a way to check highlighted cards independent of cardarea?
like if i want to check if i have a consumable highlighted, no matter if its in G.consumebles or in G.pack_area or G.shop
if card.highlighted
aha thank you
in localization/<locale>.lua
return {
descriptions = {
Other = {
your_custom_info = {
name = 'type something',
text = {
'type something',
},
},
}
}
}
thx alot
is there someone named ethan in this chat
@gaunt thistle
wake up ethan
How can I add specific jokers to a custom booster pack? Like listing a bunch of jokers, and other than that it's like a buffoon pack
some more ui experimenting
Hi friends! I was just playtesting Rayquaza when I got this crash. Anyone know what this means?
jokers occasionally just return true instead a table
i assume something that cares about this forgot to typecheck other_joker_ret
How to make this take in the values of the Joker
this is inside the Other Set
text = {
"Gains {X:chips,C:white}X#3#{} Chips",
"When {C:diamonds}Diamonds{} or {C:hearts}Hearts{} are scored",
"Currently: {X:chips,C:white}X#4#{} Chips"
}
so jokers can just... crash the game because they feel like it?
returning true in a normal context should just mean that the joker was triggered/checked but had no effect
but in this case some mod is checking other_joker_ret, which i assume comes from a blueprint escque effect?
so i think whats happening here is that the mod youre testing modified context blueprint with a patch but isnt typechecking other_joker_ret before trying to index it
something like that
well for some context i had a brainstorm hooked up to Rayquaza
could you check your lovely dump
go to mods folder > lovely > dump > card.lua and see what line 2650 is doing
yeah then its the blueprint effect crashing
is rayquaza your joker or?
yes, but idk why it would be crashing, because brainstorm worked several times with Rayquaza before it ever crashed
do you perhaps have a return [bool] in your rayquaza calc function?
No, that's return nil, true
i don't believe so
whoops, guess i misremembered
well i have a single return true
i believe this is the problem
but i'm confused as to why it would only crash now. it never crashed before this
return true is treated as return { remove = true }
can u help me with this error
update lovely
im on 1.0
we're at 2.0
thanks that helped
also make sure you didnt forget the dump_all property in your patch file
tell me how do i get as enlightened as you are
the worst part of this is the else ifs instead of elseifs
i worked 6 years at rizzard
as a janitor
the end is never the end
best janny they ever had
how do I display the name of a custom consumable?
I tried making a label but it still doesn't work
you have to make a custom localization, I'd imagine
a custom localization?
yeah I already did that
I also made a label to see if it worked but it still doesn't
maybe I should modify the label
for that specifically you need to localize b_modprefix_consumabletype_cards = "something" in misc -> dictionary
aight
another question: for labels is it necessary to add the modprefix before the key of the consumable type?
yea, for the badge it's k_modprefix_consumabletype (also in misc -> dictionary)
are you sure that if I put the modprefix it works?
cuz I removed both modprefixes and it works fine.
when I add them instead it gives me error like it did before
idk
@chrome widget sorry for the ping, wanted to reach out since you're the most knowledgable on the subject, I think
How'd you get your joker shaders working with the distortion effects so that they don't encroach on other parts of the card atlas? And do edition shaders work with your cards? Mine break when not editionless/foil
how do i have a non-card function get called on update?
Clarify the question? Are you referring to a specific shader of mine?
Yeah, Starry-Eyed Jokestar (iirc) has a wavy effect applied to it that's similar to what I'm trying to do with one of mine
(Werewire's edges are supposed to be wavy but are disabled since they went into Color Cafe/D100's sprites)
Oh! Yes, that one actually specifically had this problem
But there's two solutions to it
Starry's full atlas looks like this, with the two wavy bar effects having these individual sections, and the shader control having this math for the wave effect. The constant 0.01 modifier there is the function amplitude, and when set too high, the actual wave pulls too far of neighboring pixels in the atlas. The alternative is the modifications within the sin function (wave_t and the radians result primarily) which affects the level of distortion within the amplitude (I think it's called phase shift but it's been a while since I did trig)
However, the alternate solution is to just use individual atlases for effects that you want clear borders on. Starry is actually one of the more complicated Joker atlases I use but unlike a lot of modders, my cards have individual sprite files. Some of them specificially separate out a number of individual shader effect textures to prevent any overlap, such as Joker M having some different masks that it applies in its shader, which are just passed in with extern Image
Some of these admittedly need consolidation, but with the exception of a few edge cases (ironically, also Joker M), it tends to make working with unique art effects easier
Joker M for reference. I had to fiddle with it because the UV calculation I was using expected single atlases, not big multi-card atlases like vanilla uses, so eventually I fixed that and it now works regardless of atlas size
Still trying to make this joker work
This is all I have right now
Trying to figure out how to detect if this card had a destruction attempt made on it
sorry for the delay, but yeah, this makes sense! I'm curious what the process is like inputting the uniform for the image given I'm also gonna be doing the Deltarune Prophecy thing at some point haha
so is the shader conflict thing with Polychrome/Holographic/Negative an atlas issue as well? is there a specific way you do the draw function in the joker so that the shaders work together, or is that something I'd have to hook/use a DrawStep for
how do i create an event only if the previous event has finished?
Oh, yes! I actually have additional code basically set up to do a "late center" draw step, wherein I set certain cards to skip the center.draw() function call and pick it up later after the edition has been drawn so the effect doesn't get hidden behind it
In rare cases I've just implemented edition drawing custom for cards, but that only works for very limited effects
Let me get you the code for that
much appreciated 🙇
love the effects too btw, insanely creative stuff
So this is a little messy since I'm on mobile, my full hooked center draw step has a bunch of custom branches for specific cards that need special behavior, but the thing at the bottom is what I'm referring to. If any card has card.late_center_draw set, then it skips calling the center function until the later step after editions in priority
-- prevent late drawing centers from drawing twice
SMODS.DrawStep:take_ownership('center', {
func = function(self, layer)
--Draw the main part of the card
if (self.edition and self.edition.negative and not self.delay_edition) or (self.ability.name == 'Antimatter' and (self.config.center.discovered or self.bypass_discovery_center)) then
self.children.center:draw_shader('negative', nil, self.ARGS.send_to_shader)
elseif not self:should_draw_base_shader() then
-- Don't render base dissolve shader.
elseif self.config.center.key == 'c_fnwk_streetlight_notorious' and self.children.noto_layer then
self.children.noto_layer:draw_shader('fnwk_stand_notorious', nil, nil, nil, self.children.center)
elseif self.config.center.key == 'c_fnwk_bluebolt_insane' then
local hue_mod = math.rad(G.TIMERS.REAL % 1 * 360)
G.SHADERS['fnwk_stand_insane']:send('hue_mod', hue_mod)
self.children.center:draw_shader('fnwk_stand_insane')
elseif not self.greyed then
self.children.center:draw_shader('dissolve')
end
--If the card is not yet discovered
if not self.config.center.discovered and (self.ability.consumeable or self.config.center.unlocked) and not self.config.center.demo and not self.bypass_discovery_center then
local shared_sprite = (self.ability.set == 'Edition' or self.ability.set == 'Joker') and G.shared_undiscovered_joker or G.shared_undiscovered_tarot
local scale_mod = -0.05 + 0.05*math.sin(1.8*G.TIMERS.REAL)
local rotate_mod = 0.03*math.sin(1.219*G.TIMERS.REAL)
shared_sprite.role.draw_major = self
if (self.config.center.undiscovered and not self.config.center.undiscovered.no_overlay) or not( SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].no_overlay) then
shared_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)
else
if SMODS.UndiscoveredSprites[self.ability.set] and SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite then
SMODS.UndiscoveredSprites[self.ability.set].overlay_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)
end
end
end
if self.ability.name == 'Invisible Joker' and (self.config.center.discovered or self.bypass_discovery_center) then
if self:should_draw_base_shader() then
self.children.center:draw_shader('voucher', nil, self.ARGS.send_to_shader)
end
end
if self.late_center_draw then
return
end
local center = self.config.center
if center.draw and type(center.draw) == 'function' then
center:draw(self, layer)
end
end,
}, true)
SMODS.DrawStep {
key = 'late_center_draw',
order = 22,
func = function(self, layer)
if not self.late_center_draw then
return
end
local center = self.config.center
if center.draw and type(center.draw) == 'function' then
center:draw(self, layer)
end
end,
conditions = { vortex = false, facing = 'front' },
}```
Ye. Unfortunately the only way to easily do fully procedural stacked shader effects with the vanilla editions would probably be to like..... get the direct color information on a sprite pixel-by-pixel, then record it as a new image, then apply that custom as the image drawn for the main center child prior to the edition being drawn, then draw it, then reset the image. And doing that every frame feels a bit clunky and unperformant
So instead I go the route of just having a lot of these effects work like floating sprite cards do, where the floating sprite in vanilla doesn't apply the edition normally, just to the card below
Yw!!!
blockable = true makes the event wait for other events
Im assuming thats what you mean
Yes, but it's automatically set like that.
Also J8 thank you for expressing interest in my work!! I'm firmly in a low period right now and I'm not making much progress so it's nice that people think about it even when I'm not actively prompting discussion
yeah ofc!! i would've reached out in DMs to nerd out about shaders and stuff if I could lol
which is fair lol
🏳️⚧️ unfortunate consequences 🏳️⚧️
I would be interested to hear your thoughts on using DrawStep vs :draw Winter, I know Victin has some very strong opinions on the two methods but I'm not aware of anyone who has actually used either thoroughly enough to where I would trust there opinion
Oh! I've used :draw fairly often for custom behavior that doesn't warrant a full draw step
Primarily for layered effects atop the standard center, which are most cards when trying to be relatively accurate to the vanilla style
Primarily, :draw() is good because it allows more compartmentalized code, at least how I have it set up. Being able to have the draw behavior on the center itself means I don't risk breaking something if I disable and remove the center, and it's easier to clean up and bugtest when it's all in one place
But I'm also someone who organizes putting all my shader stuff in one file rather than individual draw steps with relevant files, mostly because I tend to reuse and expand ones rather than creating new ones when I don't need to
I'm still really curious why Foil - and only foil - doesn't break anything
do you have any thoughts on the differentiation between the two for editions?
Foil is the only vanilla shader that draws transparent pixels
For editions specifically? Like mentioned above I did need to make that workaround to call :draw() after editions, so honestly if it could be called post-edition by default I'd probably prefer it
There are some rare occasions that I prefer that effects just get quashed by editions entirely because I think they'd be way too visually busy I suppose
no i mean, in an update function, check if the last event was successful before creating another
do you have any editions that use a layering of different shaders, similar to negative?
ahhhh, that makes sense
comes up b/c when I was working on the Werewire shader, you could see the original non-shader'd card behind it
But yeah this is my typical setup for a bunch of cards for these custom effects, rather than making a unique drawstep. Which results in this effect + editions
oooh
Ironically, for all I've worked with shaders, editions are actually the only thing I haven't made for my mod
hell yeah
I need to make one, and it's gonna be one of the final things I add, but I can't advise there
jeebus how
Is there a way to "append" functionality when taking ownership in SMODS, instead of outright overriding it?
hook
local ref_func = [nameoffunction]
function nameoffunction
ref_func()
end
You seem pretty knowledgable on the two styles though, so I'd like to know what you think about what would be the best way to have an edition that does apply multiple shaders interacting with a card that has multiple extra layers across mods, if that's something you can make sense of 🤣
Ough, that's a toughy. The shader I was gonna make for my one edition would probably use two separate effects, but I don't know yet how I'd set it up if it would be separate shaders or just combined into one
that is a very valid response
(IMO vanilla negative probably doesn't need multiple shaders too)
Would something like this work when taking ownership:
local ref = SMODS.Jokers[joker_key].calculate
SMODS.Joker:take_ownership(joker_key, {
calculate = function(...)
ref(...)
-- Additional functionality
end
}
i dont see why it wouldnt?
Oh good, the Love2D site is experiencing a cloudfare error. Well I was gonna check if there's an easy way to get pixel out information for an entire sprite once it's been drawn
tho im not sure if vanilla jokers are stored in SMODS.Jokers
I'm not sure that there's a way that currently exists to allow something like that to blanket work, afaik all the shader code (which I would personally house in a DrawStep) would refer to specific layers directly to determine what to apply it too, and having extra layers from some other mod that you aren't in control of, there's no way to recognise those
maybe you could get the calc from the G.P_CENTERS table instead?
I'm trying to make this for my mod, any guides for the code?
if you're taking ownership of a joker and want to maintain the original calculation code, just don't return anything in your take ownership function
i think they wanted to extend it
you can't store the original code anywhere though
yes that's what I mean, write your new function and just don't put a return at the end
it'll then run the original code afterwards
Okay yeah so there probably is a way to do this, it's just wonky and I doubt very good performance wise
no
Lemme explain: I want to have asort of mini-shop where you can buy an uncommon/rare joker through the phone, and have it show up in a mini booster pack like a box.
for clarification, I was using Jokers as an example, but I'm intending to take ownership of the chips Scoring_Parameter to add more calculation keys, but I didn't want to copy what's already been written and stuff
oh
I think a better solution would be to add official multi-shader support for editions so they don't need a custom drawstep, and then some sort of way to register new layers to that
yea idk then ive never touched it
bump
you should be able to do something like this yes
you can also just hook SMODS.calculate_individual_effect and add your keys to the table that I forgot the name of instead
Basically, per Love2D, the Image type is a drawable that contains pure pixel information. You could, if im not mistaken, create a new Image per drawable child, then draw each shader to it, and feed the pixel data from the last shader draw into the following shaders so they have the actual cumulative result of multiple shader-drawn layers as a single texture. And then once that's done, you draw the result of the image to the final card quad, instead of just a texture per child
Based on this description, I'd say to start, you'll need to figure out how to make UI and patch/hook UI functions to get the "mini-shop" going
That would be a major overhaul, but it would mean reducing the number of drawn children from each card to 1
that'd majorly increase the computation before that though, no?
Mhm, probably
It's moreso just a button on the joker's left side saying "buy joker? ($price)"
Like I said, it's wonky and I doubt performant
Ah
But without benchmarking it, idk
Imma loosely start with riff-raff as a coding base, since it creates common jokers in a similar, if unanalogous way
Sorry got called for something, I'll try to brb asap
That helpful at all Eremel? I know I can't really give a straight yes or no answer
That'd be an implementation I would use, lol
When I did shaders in Game Maker Studio they had surfaces that let you stack shaders like that
Yeah it's basically the same thing. I don't use Images very often but that's how the NES emulator works, it draws to an image from the NES PPU using Image:setPixel() or whatever and then the full image is just drawn to the screen using regular methods
-# you have an NES emulator in your Balatro mod?
Correct
holy shit, awesome
yoooo holy shit awesome
I also just have it set up as a config tab if you want to dump your own roms into it and play the least performant emulator known to man. I'll likely have to provide the mod without the three roms used for its actual in-game item anyway if I don't want to face some trouble
I haven't seen it
took this in mind and tried seeing what it'd look like factoring transparent pixels and the wavy effect works as intended
oooo!!!!
guys would trying to figure out how to make a balatro mod help me get into coding
YEAHHHH MEGA MAN
(biggest mega man fan here)
couldn't find card:highlight
I'm aware it could be in there, but I searched, and nothing
YOOOOOOOOOO
yeah
downloading this immediately
ok then here we go now
-# on the offense
Got it now, sorry bout that!
My dream project is a combined remake/demake of X4-X6, been wanting to make something like that for a while, esp because I'm a big fan of X5 and the game itself has some really wonky systems
i could introduce you to the engine I use
You use Megamix according to the posts here
yee :D
Unless you've moved on from there
Megamix isn't super oriented towards the X games afaik and would need a pretty big overhaul
correct, but the systems are still a good foundation
Episode Zero exists
That's true
Now, do I sub in my card in place, or what?
Can I add jokers individually to a custom booster pack?
Like have them all listed and working similarly to a Buffoon pack, but only offering the listed jokers? They're also in the normal buffoon packs (as they should be), so I don't want to separate them from the normal joker set
it's more complicated than that and I don't really have the energy to explain in detail rn but what that does is replace the part where the game makes the buttons for my function that makes the sell and use buttons + new ones
I was considering trying to build my own ECS engine using some Love2D plugins I've seen, since I've had some professional experience working on an engine that splits between ECS physics/rendering and object-oriented scripting, which was a good system (but also potentially overkill for a single-persn project)
yes, make an objecttype
so, go step-by-step and be careful?
werewire 🔥🔥🔥🔥
:D
Where can I see how that works? VanillaRemade has no objecttype in jokers or boosters
uhh idk if that's what i would say. if you're new to balatro modding then it might be difficult is what I'm saying
should be on now, give it a go
👍
Well, I am.
Thank you!
you can also make the objecttype and add the key to your joker's pools
good luck
self.highlighted = is_highlighted
local can_summon = JoyousSpring.can_summon(self)
if self.highlighted then
self.children.use_button = UIBox {
definition = {
n = G.UIT.ROOT,
config = { padding = 0, colour = G.C.CLEAR },
nodes = {
{
n = G.UIT.R, config = { ref_table = self, r = 0.08, padding = 0.1, align = "bm", minw = 0.5 * self.T.w - 0.15, maxw = 0.9 * self.T.w - 0.15, minh = 0.3 * self.T.h, hover = true, shadow = true, colour = can_summon and G.C.JOY.RITUAL or G.C.UI.BACKGROUND_INACTIVE, button = can_summon and 'joy_perform_summon' or nil }, nodes = {
{ n = G.UIT.T, config = { text = localize('k_joy_summon'), colour = G.C.UI.TEXT_LIGHT, scale = 0.45, shadow = true } }
}
},
}
},
config = {
align = "bmi",
offset = { x = 0, y = 0.65 },
parent = self```
must be the new button code I'm looking for, is it?
basically, this one is for packs specifically so it adds the button to the bottom (and obviously includes a bunch of things that are mod-specific)
well not "adds"
it replaces
Mmmm. Anything you got on the left that does add a new button?
the other ones
oh sorry i have nothing on the left actually
but the process would be the same
ah, gotcha
So take ownership of the use and sell buttons, and add one offset on the left
is that loosely right?
there's no take ownership of functions
you either hook it, patch it or override it (i do the latter, others do the former two)
I could hook on the code to the phone joker, yeah?
Just code it separate, and then hook it onto it like my Top To Bottom
set up button leftwise
display "buy joker?" and price of joker
if clicked_on then
set-up tag to open booster_box
(tag makes booster_box, which contains only buy_joker_on_phone
open booster_box after small_blind_shop)```
button function pseudocode
why do you override functions
do you hate other mods
me when i don't know the context of the conversation:
(i make an entirely different function)
like the button function I highlighted?
Does anyone know why my booster pack has no name and description in-game? They are empty, even though I have a loc_txt with name and text in it
Morning
I am trying to test my mod (remotro) so I need to give myself all of the jokers, how do I do this? SMODS.create_card() hasn't done what I wanted it to do
I have put it in a loop so they can all spawn
Use debugplus
oh nvm worked it out lol
can I stop it keep making jimbos though
I ideally want them to all load at once so I can just get their tables saved all at once
What do you guys think of Joker Forge?
i don't understand what you posted tbh

