#💻・modding-dev
1 messages · Page 409 of 1
H_2 for 2 of hearts
i'll take a look
time to go for the 4
thanks ^^
N, I cba to look now, do you remember if your get_current_pool change for editions culled e_base?
yes
it checks if the editions have in_shop
and i added it to the vanilla editions but not base
I only learned it was a thing while doing that honestly
how do i see a playing card's suit
oh wait
nvm
ill just check vanilla remade my goat
card.base.suit
thanks
John VanillaRemade
hi vanillaremader
reading the book with the author in front of you
mm, i don't exactly know what Grim is doing
whats the function that return's a joker's chips/mult/whatever without actually using return {}?
i see it's patching some stuff relating to added_menu_button, but that seems to just be making sure it's only there once
like, if i want multiple effects at once without returning the function
SMODS.calculate_effect
ahh ty
hey is this debuff source a little much or are we good
add the modprefix so it doesn't clash with another mod, it's too generic
:p
how is that too generic
i know three guys who did that
what if
i'm gonna start using that debuff source too
q: on
is it better now >:(
yeah
yes
that's a great mod prefix
the N part is important
the plant mentioned
debuff sources are useful because it means your debuffs are guaranteed to always exist
isn't that a mod suffix
im making steamodded 2
instead of disappearing when you use death on completely different cards
with blackjack and hookers
so steamodded
Retriggering jokers is still an optional feature, right? Or is it base Smods now?
optional
it's optional
I must be doing something wrong, because with this code I just crash when trying to view the deck of the challenge.
deck = {
cards = {
{ s = 'Clubs', r = '10' }
}
}
s = 'C', r = 'T'
i goofed earlier mb sorry for confusing you
using SMODS.calculate_effect if i had to guess
How would I physically move the title screen sprite a bit to the left? Trying by looking at others code but im failing
i think that doesn't work with retriggers?
right
unamused angry grr
that doesn't work with retriggers
you need to nest extra tables i think
can you not use extra tab-ok yeah
but what if the return table already has an extra
i know someone who can answer that
i guess you just find the one that doesn't by looping through them and putting it there
you need to find the next empty extra table
which reminds me i wanted to PR that as an smods util
you should pr NOW
but what if it has infinite extra tables
go beyond infinity
what if it has 0 returns but infinite extra tables
trick question, just make space in the hotel
is mario there
do i do this or what
you have to store the return value of blueprint_effect
first, the SMODS.blueprint_effect should be outside the table to work
like return SMODS.blueprint_effect(..)
in 99 out of 100 cases you don't need to use self.name, what do you want to use it for?
you'd just use self.key
Okay, have to tag the jokers to a separate pool to account for the separate joker limit.
If I only want the Extra Deck (will rename as needed later) to appear for a certain deck, do I change the toggle for show.extra.deck from the number of extra deck jokers is more than 0 to something like requisite deck is in use ? Or do I just set the toggle switch in the deck event? Or do both need to occur for different reasons?
the first one
im recycling code from the hook
but ill just use self.key
uhh
if you're making a blind with SMODS.Blind you don't need to check for the key
i was doing that before but it only copies 1 time
you forgot to include self in the function params
yes this is the correct usage of it
kk
to do what you want to do needs more work
yeah im asking how do i do the more work
yeah im trying to find an example of what you want because ive seen it done well before
oh alright take your time
all in jest and bountiful do it incorrectly 😭
okay so self.key does not exist in the context?
local function to recursively search the effects table until it doesn't have extra?
how would i go about making a joker turn itself into another joker?
that's what i'd do
i would make it spawn the new joker then destroy itself
haya is so amazing honestly
https://github.com/hayaunderscore/PayasTerribleAdditions/blob/96fce84cdf9db6cd66b2ceed1f903a5d3995c752/content/jokers/ahead/printhead2.lua#L15
if i can guess id say you make a card.dissolve on a context check and then do a function like
function addPobre()
local card = create_card('Joker', G.Jokers, nil, nil, nil, nil, 'j_prefix_joker')
card.sell_cost = 4
card:add_to_deck()
G.jokers:emplace(card)
end
uhhh self.config.blind.key
What could I use to have a challenge deck start with one random card?
okie
kk ill look into it
yours is more simple but what you want to do is combine both returns using the function in the second link
so what you're saying is that we need SMODS.combine_effects or smt
works
yes
making it after dinner :3
would this preserve the edition of the joker?
:D
most likely no
hmm, ill have to figure something out for that then
SMODS.destroy_cards(card)
SMODS.add_card { key = 'j_prefix_key', edition = card.edition }
is what i'd do
that would work yeah
yeah thats much better
card:set_ability("other_key")
i use it a lot and nothing wrong happened
i think that was fixed
awesome
Is there something I can call that tells me what deck is in use? Like an already defined "variable" (I'm sure I'm not using that word in the right context), or do I need to figure out how to go the long way?
not for modded jokers apparently
it changes size accordingly if you turn it into a vanilla one
damn
G.GAME.selected_back iirc
ok so i tried doing this and now its still only doing the blueprint thing once
maybe
im just trying to figure out how to do it
cz i gen cant find anything on how to do this
I think you want
local ret1 = SMODS.blueprint_effect(...)
local ret2 = SMODS.blueprint_effect(...)
return Balaling.recursive_extra({ret1, ret2}, 1)
sorry sometimes my advise is less useful when im on my phone where i cant bother coding than when im on my pc haha
Plus you're eating dinner, right? Something tasty I hope?
no you're FINE dude you're literally the goat
i just set up the rice cooker actually
if it works can you really say they did it wrong? 
im making that PR while i wait
all in jest's breaks if any of the copies returns an extra table
i think bountifuls just doesnt work? unless im reading it wrong
nvm
i might try them out and send them a pr
how do i see the current level of the played hand?
G.hands[context.scoring_name].level? i think
thankies
I'm trying to make a consumable that can sell a Joker, how to I make sure that it can't pick an eternal joker and it can't be used if all jokers are eternal
slight correction, its G.GAME.hands
oh yeah
in your can_use function you want to return true if at least one joker isn't eternal
as for the selling part, idk
I'm planning on making a joker based on the amount of prime cards in your deck, but I'm not sure how to theme it, can anybody think of a pun or fun wordplay for it? there's got to be something good there
Make it look like a soda or something, like the Prime drink lol
hm, but then it's a food joker that doesn't act like a food joker lol
hiya! i have a consumable type — two questions:
- is there a way to make each card of the type appear several times, showman-like? [i'm using SMODS.ConsumableType]
- i'd like to place one card of the type in the booster pack area, each shop — how can i do that?
i don't think you can do #1 on your type, you'd have to do it on each consumable
i think you can return true, { allow_duplicates = true } in in_poll for each
in your in_pool function of each consumable you'd do that ^
for the shop you would probably hook/patch create_card_for_shop? I'm not sure where boosters are created or what the booster area is called rn
https://github.com/Steamodded/smods/wiki/SMODS.Consumable here's the steammodded page for consumables
(oh ya, checking, does cost need to be defined for each, or can i define a default for the type?)
will look into that ^^ cheers
you can't define one for the type, no
you need to define the cost for each consumable
gotcha ^^
there is technically a way to help with that if your consumables have a lot of shared properties
for example, you can do
MyConsumable = SMODS.Consumable:extend {
cost = 4
}
and then to create consumables you'd use MyConsumable { .. normal stuff here .. } without having to put the cost in each
not worth it if you only have 1 or 2 shared values imo
ah, gotcha :D
Adds SMODS.merge_effects that takes any number of arrays of tables and nests them using the extra field.
Useful primarily for copying multiple cards with SMODS.blueprint_effect.
Additional Info:
...
i think i should have done this at a time im more awake honestly
How would one make cards have a chance of breaking when triggered
i mean. like glass cards but on triggering i
(so if theyre retriggered a lot they have a bigger chance of breaking)
The context for destroying a card is separate from the scoring trigger, so you could check in the scoring if the card should be destroyed, and just set a flag on the card
Then in the destroy context, check for that flag
Alright thank you
how would i add a consumable to the shop pool, not too dissimilar to what ghost deck does for spectral cards?
damn
dead chat
As I understand it, Ghost Deck just increases the Spectral Rate to a non-zero value.
If the consumable belongs to one set, but you don't want the whole set to be added, maybe you can temporarily override that individual consumable's set?
In total honesty, I am not the person who should be answering this, but maybe this will springboard you to a better answer.
SMODS.Back {
key = "ichor",
atlas = CHAR.G.deckatlas.key,
pos = { x =1 , y = 0},
apply = function(self,back)
G.GAME["ritual_rate"] = 2
SMODS.add_card({key = 'c_charcuterie_phase'})
end
}
@hushed field
What's the crash?
hold on
i copied this from my lovely log
so theres a certain part where it notices that main.lua is missing, this is false, i have a main.lua
but otherwise
functions/common_events.lua:2316: attempt to index local 'area' (a nil value)
oh
i need to give it an area
Hey so
My first time modding tarots
Can i
Use {c:attention} and others in tarot description ?
yes, theyre just like any other description
always assume you can, objects not having text styling should be the exception
anyone got an idea of how to change the joker used in the splash of the game?
how can I check whether or not a card has an enhancement? right now I have:
if G.hand and #G.hand.highlighted == 2 then
if G.hand.highlighted[1].config.mod_conv ~= nil and G.hand.highlighted[2].config.mod_conv ~= nil then
flag = true
end
end
but it doesn't work properly
SMODS has a has_enhancement function
W, thanks
How could I make a challenge deck start off with one random card?
G.hand.highlighted[1]:has_enhancement() is throwing an error because "has_enhancement" is nil
I'm guessing I just didn't access the card properly
You can search the SMODS code to see how to call it
This can help too
what is happening to my card 😭
Rank 0 :O
its 10 just the sprite is messed up 😭
its not. supposde to do that
oh waiy 💀 i fixed it. i had the pixel size messed up
why smods have a cat?
Cats are fluffy
so the cat its responsible for when my mods crashes?
no
it's john smods' cat
its responsiblke for when ur mods work
tis a beautiful kitty
i like cats
bro, why is my mod crashing :3
i cant read anything 🔥🔥🔥
Hey all, I am attempting to view into the future (like The Soul but as a mod). I am able to generate the next card from the shop, but no matter what I do, it always advances the actual game seed as well. I believe must be because when I am attempting to copy the seed, it copies by reference and not by value. I think my inexperience with Lua specifically is hurting me here. Any thoughts?
Showman.SEEK.GAME.pseudorandom.seed = G.GAME.pseudorandom.seed
i had one of the names as JNRR and then i changed it to JNAM, but that didnt fix it
I've got this so far to make a random suit and rank, but I can't use G.GAME for a challenge deck, what should I use instead?
local SMODS_calculate_context_ref = SMODS.calculate_context
function SMODS.calculate_context(context, return_table)
local suit = pseudorandom('split', 1, 4)
for i = 1, suit do
if suit == 1 then
G.GAME.willatro_split.suit = 'S'
elseif suit == 2 then
G.GAME.willatro_split.suit = 'H'
elseif suit == 3 then
G.GAME.willatro_split.suit = 'C'
elseif suit == 4 then
G.GAME.willatro_split.suit = 'D'
end
end
local rank = pseudorandom('split', 2, 14)
for i = 2, rank do
if rank < 10 then
G.GAME.willatro_split.rank = 'i'
elseif rank == 10 then
G.GAME.willatro_split.rank = '10'
elseif rank == 11 then
G.GAME.willatro_split.rank = '11'
elseif rank == 12 then
G.GAME.willatro_split.rank = '12'
elseif rank == 13 then
G.GAME.willatro_split.rank = '13'
elseif rank == 14 then
G.GAME.willatro_split.rank = '14'
end
end
return SMODS_calculate_context_ref(context, return_table)
end
is there a way I can remove the enhancement from something
local _suit = pseudorandom_element({"Spades", "Hearts", "Clubs", "Diamonds"}, pseudoseed("whatever"))
local _rank = math.random(2, 14)
I guess that's better than what I did, but still doesn't fix my problem.
what are you trying to change? make every card the same suit and rank at random from the start?
I have this all in a function, and I want to be able to use these values within a challenge deck.
hello modding dev people im having a weird thing goin on in my game that i can find a grand total of 0 info on would it be alright if i asked yall if you know anything or is that not a thing this channel is supposed to be used for
bump
idk but let me look
This channel is 99% stupid questions, 1% answers.
i dont know whats up with the "X" above some cards. they just started showing up after i loaded the game during a run
if i remember correct i also saw a joker in the shop with an x above it
anyone know?
local SC = nil
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.2,func = (function()
local SC_scale = 1.2
SC = Card(G.ROOM.T.w/2 - SC_scale*G.CARD_W/2, 10. + G.ROOM.T.h/2 - SC_scale*G.CARD_H/2, SC_scale*G.CARD_W, SC_scale*G.CARD_H, G.P_CARDS.empty, G.P_CENTERS['j_joker'])
SC.T.y = G.ROOM.T.h/2 - SC_scale*G.CARD_H/2
SC.ambient_tilt = 1
SC.states.drag.can = false
SC.states.hover.can = false
SC.no_ui = true
G.VIBRATION = G.VIBRATION + 2
play_sound('whoosh1', 0.7, 0.2)
play_sound('introPad1', 0.704, 0.6)
return true;end)}))
game.lua line 1445
i would patch that area and replace the card within G.P_CENTERS[] with whatever you like
do you need information on lovely patches?
how would one go about pulling the level of the played poker hand? im trying to make a joker that gives chips based on the level of the played poker hand (+30 chips per level) and im just not sure how to start going about it
G.GAME.hands["hand_text"].level
thank you 👍
anyone that is smarter than me/Chatgpt know?
this seems like an issue with brainstorm.
ur like the random guy on Stack Overflow helping everyone
yeah but i feel like im missing files cuz when i try to find the files from the error, there is just nothing there
some of the files are going to reference things from the base game, as most of steamodded's API can be boiled down to just making base game functions more friendly to interact with.
i see, is there a way to view them all together or just deal with it? im on Mac unfortunately
Though im pretty certain that Brainstorm does not play nice with later versions of steamodded but let me confirm that and if I am correct I'll attempt to give you a better option.
thanks
like it launches and everything but as soon as I make any input whether keyboard or mouse it crashes
yes, upon closer inspection brainstorm has not been updated in about half a year, which tells me it is likely not compatible with later versions of the API
thats unfortunate, i loved brainstorm
bump
is it lovely?
Card:set_ability("c_base")
how does context.blueprint work? i have a joker that works on its own but even with blueprint_compat = true it doesn't copy. figured i have to throw context.blueprint in somewhere
not likely. im afraid that i really do not know all that much about brainstorm, perhaps another member could assist you
thanks anyways and keep being great
What can I even do in a challenge beyond the basic stuff?
can i see your joker's code?
usually blueprint works by copying the return value of whatever your joker does, afaik
oh well then that might be the problem, i do SMODS.calculate_effect since that worked on another joker that had multiple triggers
but i can just replace with returns if thats required
usually the ideal method is returns
calculate effect is used if you want to do something before you return
if context.cardarea == G.play and context.individual then
if pseudorandom("bool") < G.GAME.probabilities.normal / card.ability.extra.odds then
SMODS.calculate_effect({
card = card,
message = "BOOL",
Xmult_mod = card.ability.extra.Xmult,
colour = G.C.MULT
})
end
if context.other_card:get_id() == 2 then
if pseudorandom("bool") < G.GAME.probabilities.normal / card.ability.extra.odds2 then
return {
card = context.other_card,
message = "YEAH!!",
Xmult_mod = card.ability.extra.Xmult2,
colour = G.C.MULT
}
card.ability.extra.Xmult2 = card.ability.extra.Xmult2 + card.ability.extra.Xmult2_gain
end
end
end
end```
in this case, would it only copy the return in the 2nd if?
what would be the best way to grab the string of the played poker hand?
they were both calculate_effects at first, but if it only does the return{} then ig it wouldnt do the calculate effect in the first if
calculate = function(self, card, context)
if context.cardarea == G.play and context.individual then
if pseudorandom("bool") < G.GAME.probabilities.normal / card.ability.extra.odds then
return {
card = card
message = "BOOL",
Xmult_mod = card.ability.extra.Xmult,
colour = G.C.MULT
end
if context.other_card:get_id() == 2 then
if pseudorandom("bool") < G.GAME.probabilities.normal / card.ability.extra.odds2 then
return {
card = context.other_card,
message = "YEAH!!",
Xmult_mod = card.ability.extra.Xmult2,
colour = G.C.MULT
}
card.ability.extra.Xmult2 = card.ability.extra.Xmult2 + card.ability.extra.Xmult2_gain
end
end
end
end
remember
once you return something, any code after cannot be executed
plan around this
yeah fair, just didn't know that was a requirement for blueprint until now
thanks for the help
yup yup
sorry to be pushy but im bumping this again because i wanna get this joker done before i go to bed ackackack
context.scoring_name
thank you :3
i find modding this game fun, i just wish the documentation was more fleshed out
np
we all do 😭
mood. honestly if i find the time tmrw i might document some things
I'm trying to make a deck where all probabilities are guaranteed but idk what to add to make it work, it keeps saying "normal" for all probabilities when setting it to "v + 2" to test it
G.GAME.probabilities.normal is what you want
if you're manipulating the game's probabilities
yeah
let me pull some code i made to help you out
thanks
i have a joker that does something where all probabilities don't occur that sets all probabilities to v * 0
add_to_deck = function(self, card, from_debuff)
for k, v in pairs(G.GAME.probabilities) do
G.GAME.probabilities[k] = v * 4
end
CHAR.FUNC.ease_risk(999)
G.GAME.RISK_LOCK = true
end,
remove_from_deck = function(self, card, from_debuff)
for k, v in pairs(G.GAME.probabilities) do
G.GAME.probabilities[k] = v / 4
end
G.GAME.RISK_LOCK = false
CHAR.FUNC.ease_risk(-100 + (G.GAME.round_resets.ante * 10))
end,
this was for a joker, but im sure you can adapt it
Anyone know why steel cards made with this joker don't score?
calculate = function(self, card, context)
if context.before and context.main_eval then
local new_cards = {}
for i = 1, 2 do
for k, v in ipairs(context.scoring_hand) do
if v.seal or v.edition or next(SMODS.get_enhancements(v)) then
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
local copy_card = copy_card(v, nil, nil, G.playing_card)
copy_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, copy_card)
copy_card.states.visible = nil
new_cards[#new_cards + 1] = copy_card
G.E_MANAGER:add_event(Event({
func = function()
G.hand:emplace(copy_card)
copy_card:start_materialize()
return true
end
}))
end
end
end
SMODS.calculate_context({ playing_card_added = true, cards = { new_cards } })
return {
message = localize('k_copied_ex'),
colour = G.C.CHIPS
}
end
if context.destroy_card and context.cardarea == G.play and
(context.destroy_card.seal or context.destroy_card.edition or next(SMODS.get_enhancements(context.destroy_card))) then
return {
remove = true
}
end
end
Do i do the same thing for a deck?
i would do the probability changing code on apply
here let me kind of workshop something
apply = function(self,back)
for k, v in pairs(G.GAME.probabilities) do
G.GAME.probabilities[k] = v + 1000 -- Realistically makes everything happen all of the time
end
end
applying this now
it gave an error??
hold on i think apply = function(self,back) will work
probabilities show "normal" instead of a number
hmm
OH!
apply = function(self,back)
G.GAME.probabilities.normal = G.GAME.probabilities.normal + 1000 -- Realistically makes everything happen all of the time
end
try this?
check how oops does it
Oops?
oops has to have a check for removing it, but a deck wouldnt
OH
oa6
oops all sixes
yes
Oh no i did for a joker i was making
i tried doing it for a deck but ig it doesn't work the same
really?
yeah
here
i tried to do something like = v or smthn
set stuff to "normal" instead of a value
What should I do to reset this for every new run?
local SMODS_calculate_context_ref = SMODS.calculate_context
function SMODS.calculate_context(context, return_table)
split_suit = pseudorandom_element({"S", "H", "C", "D"}, pseudoseed("split_1"))
local _rank = math.random(2, 14)
if _rank < 10 then
split_rank = '' .. _rank
elseif _rank == 10 then
split_rank = 'T'
elseif _rank == 11 then
split_rank = 'J'
elseif _rank == 12 then
split_rank = 'Q'
elseif _rank == 13 then
split_rank = 'K'
elseif _rank == 14 then
split_rank = 'A'
end
return SMODS_calculate_context_ref(context, return_table)
end
what is the bigger issue
im fixing it rn
how does pseduorandom work if you dont specify a min and max
is a random float between 0 and 1?
trying to make a deck change all cards to a random edition but my code isn't working
It's v:set_edition not v.set_edition
very simple mistake on my part my bad
Can someone explain to me why context.card.set == 'Joker' is false here when buying a joker from the shop? I can't figure it out
context.card.ability.set == 'Joker'
you are a legend 🙏
Ok so I got this joker working, but the text only updates after it's used rather than fully dynamically like cloud 9/steel joker etc.
here's my code
calculate = function(self, card, context) if G.STAGE == G.STAGES.RUN then card:update_alert() card.ability.extra.prime_cards = 0 for k, v in pairs(G.playing_cards) do if (v:get_id() == 2 or v:get_id() == 3 or v:get_id() == 5 or v:get_id() == 7) then card.ability.extra.prime_cards = card.ability.extra.prime_cards+1 end end end if context.joker_main and card.ability.extra.prime_cards > 0 then card.ability.extra.mult = card.ability.extra.prime_cards*(card.ability.extra.mult_mod) return { mult = card.ability.extra.mult, card = card } end
do I need to hook where it does all the other global updated things or is there a simpler way
Put the part where you get the number in loc_vars
mb sorry
all good :).
also
if (v:get_id() == (2 or 3 or 5 or 7)) then
card.ability...
end
would probably be a more efficient way to write that
hey @daring fern I know you told me how to do this before, but how should i go about actually implementing this?
You could either rescore the card or somehow check if the card to the left of every played card is that and retrigger it normally.
No, that's not how lua works.
too bad
could i grab the card to the right and just repeat it 3 times
but first check if there i a card to the right, ofc
this would check to see if 2 is existent, and if it isnt check if 3 is existent, if not.. so on so forth
which 2 is always gonna be existent so its only gonna check it the ID is 2
does lua have match / switch
No, because when the enhancement is calculated it wouldn't be the time to check for repetitions on the next one.
hm
rescore; elaborate?
Rescore means retriggering but it allows retriggers to happen again.
is there any way i could get an example of how i could go about this? any mods, etc
well my idea isnt letting the card to the right repeat itself
its more blueprint-esque in how it works
Familiar has a seal that retriggers the leftmost card using rescoring.
it copies what the card to the right does 3 times on top of what the card does on it own
hm alright
ill look in to that
Oh that video is busted wiw
dont know why i said this, was thinking of
if v:get_id() in [2,3,5,7]
which is probably not possible in lua either
in is only for for loops I think.
yeah most likely
but it (lua) is made to have extremely basic interpreters so its good at what its designed for ig 🤷♂️
the closest equivalent would be:
if {[2] = true, [3] = true, [5] = true, [7] = true}[v:get_id()]
pythonpilled
this worked, tysm
so like is what I did for my get id inefficient and I should do something more efficient or is it really not that big a deal at this small a scale
Ideally you should make your code as easy to read as possible, and 4 lines accomplishing the same thing is counter productive for that
Again, ideally
If you don't feel like doing it, it won't be the end of the world
Thunk also has misspellings in his code, i wouldn't treat the source code as a holy bible or anything
is there a way to have a blueprint type card but for only a specific select of Jokers
Yes.
how so
Do the jokers have to be owned to be copied?
yes
Then you would get a random joker that matches a list of keys from the owne jokers.
unironically got gaslit into thinking it was spelt "consumeables" and a friend had to correct me when I had it that way on the card description
some of that code is a bit unneeded but eh
is there a reason this joker isn't doing anything with blueprint? i'm simply attempting to create a random card (of the Silly type) every 15 discards. it works for the base joker, but blueprint simply does nothing (updated screenshot)
I'm working to implement a mod that works like The Soul, the seed analyzer.
I can successfully generate cards in the shop; however, whenever I do, it seems to either remove the joker(s)/item(s) from their respective pools, or just spin up something else with rng.
Example: With the seed ABC123, the first jokers in the shop are Foil Throwback and The Trio (*I have on steammodded which messes with rng slightly, meaning the results are different from The Soul online). If I play into the shop, I see it. If I generate the first joker, my console output says foil throwback, but then when I get to the first shop, it is a foil To The Moon. The second joker is still The Trio though
Any thoughts?
how do I have it to flip the direction of blueprint
Im guessing something like g.jokers.cards(i+1) replaced to g.jokers.cards(i-1)
when you generate a card it advances the seeded rng
I have what I hope is two parallel RNG seeds
Altho im new to lua and modding this stuffs, so im just guessing from logic
the other culprit is that using the stock function marks the generated joker as used, so it cannot be generated again without showman
create_card
bump, blueprint not working for some reason
Which part of it, as I haven't been able to figure it out
it resets discards_remaining before bp triggers
try moving the reset inside the event
bump
shoot, sorry for reply ping
having it reset in the event means it wouldn't reset if the max number of consumables is reached
which i do want it to do
then uh. just add a sanity check for that
wdym by that
if slots full then reset
else event + reset
I don't understand how the gift card changing card sell values works. I want to equal a Joker/Consumable's sell value to a variable;
Equaling other_card.sell_cost does nothing to the card's sell value in game;
Equaling other_card.ability.extra_value adds to the card's sell value
worked, ty!
now to figure out why the effect is onyl showing on the base card and not bp
not sure why that's happening
bump #2
are you just wanting a blueprint that copies the joker to the left?
basically
Then you would do ```lua
local other_joker
for i=1, #G.jokers.cards do
if G.jokers.cards[i] == card and G.jokers.cards[i-1] then
other_joker = G.jokers.cards[i-1]
end
end
if other_joker then
return SMODS.blueprint_effect(card, other_joker, context)
end
https://github.com/nh6574/VanillaRemade/blob/1ef3fa9be831bd31a321133f11a2604ea65c6ba0/src/jokers.lua#L3831 pretty sure you can basically just copy this but do [i - 1] for other_joker
How would I make a consumable not be destroyed after using it
Code?
o
thanks
It got buried by other messages so I'll ask it again
I don't understand how the gift card changing card sell values works. I want to equal a Joker/Consumable's sell value to a variable;
Equaling other_card.sell_cost does nothing to the card's sell value in game;
Equaling other_card.ability.extra_value adds to the card's sell value
hooooold on i think i got it
card:set_cost()
card.ability.extra_value = (-card.sell_cost) + number
card:set_cost()
```?
Yeah that should work, thanks
there was a + I forgot to set to -
The constructor for Card auto-set the "used_jokers" for the joker ability to true, thus why it would get skipped. So setting it back to (whatever it was before, to cover the corner case where you already had the one) solved it :D
And now that I can predict the shop, time to slap on a neat gui and maybe do some math and shit.
somthing is fucking up and idk what
they're not the only ones, those are just examples, they don't do anything, they just print "incompatable" for some reason
ok, so its on a select few???
ALL of these are saying compatibility with Salamander
they don't actually copy, but they just say it
Is there a way to set the price of a consumable in the shop
Hook card:set_cost
how do I make a joker text that shows how much chips it currently gives (a scaling chip joker)
You can take a look at the "modded vanilla" mod to see how it's done
does the game have something to track your current run's most used tarot card
yeah I have been looking at that but I cant figure it out
do you mean as a message or in the description
2 things
- show config for card
- show current localization text for it
is chip_mod the gain here?
yeah
you wanna use loc_vars for your localization text (loc_vars makes it so anytime a variable in your card's config is modified, it'll change the number in the description)
ohhh
loc_vars = function(self, info_queue, card)
return {
vars = {
card.ability.extra.chip_mod, card.ability.extra.chips
}
}
end,```
and then in the localization text you can use #1# to refer to the chip gain, and #2# to refer to current chips
woah
something like lua text = { 'Gains {C:chips}+#1#{} chips', '{C:inactive}(Currently {C:chips}+#2#{} {C:inactive}Chips)',
(some card descriptions ive seen manage to successfully wrap the s of chips into a condition like <s#1#> or something but i havent been able to replicate that on my own)
thank you for help!
np, the localization is pretty much the only part of balatro coding that i know well enough to help others with lol
is there a way to get the list of cards held in hand? like context.scoring_hand?
G.hand.cards
does it need the context.cardarea = G.hands beforehands?
also does it react well (as in, is a strict context) for enhancements check with quantum on?
I'm pretty sure you could just do not context.check_enhancement if you're not sure.
but then that would prevent me from checking enhancement? I'm trying to do a similar check as flower pot but for cards held in hand
No?
context.check_enhancement only gets called when SMODS.has_enhancement is trying to check for quantum enhancements.
how do i force a card to be drawn from the deck during a blind?
gotta hook shuffle i guess
wether i use discard or pre_discard, it prints me 8 (default hand size) on discard, and the accurate size (6 if i played two cards) on hand played
if (context.before or context.pre_discard) then
print(#G.hand.cards)
end
Ok so I am trying to make a custom challenge and when I select my Challenge it just crashes :/
key = 'Simon says: 32',
loc_txt = 'Simon says: 32',
jokers =
{
{id = 'thirtytwo', eternal=true },
{id = 'simonsays', eternal = true},
},
vouchers =
{
{id = 'v_magic_trick'},
},
unlocked = true
}``` That's the entire code I have about this challenge am I missing something or did I do something wrong?
Your joker keys need to be like j_modprefix_key
oooh, that makes sense thank you!
Hmmm still crashes with the same error :/ ```SMODS.Challenge {
key = 'j_Jokeful_simonsays32',
loc_txt = 'Simon says: 32',
jokers =
{
{id = 'thirtytwo', eternal=true },
{id = 'simonsays', eternal = true},
},
vouchers =
{
{id = 'v_magic_trick'},
},
unlocked = true
}``` Do I need a SMOS.Atlas or something like that for challenges?
No, I meant your jokers keys not your challenge key.
oh 😭
Also the key can't have spaces.
Yea I fixed that also
Also loc_txt should be a table.
now it works thank you!!!
It's card:set_ability not card:apply_to_card
oh thanks
How could you do a Xchip? Or is it just not possible?
return {xchips = number}
This cool effect—I’d really love to add it to my enchantment right now, but I’m not sure how to do it. Has anyone made something like this before?
so i'm trying to create a rare consumable that has 1 in 4 chance of giving you a random tag, i am trying to use the P_TAGS but it returns length of 0, is there any way to get the entire tag list and iterate over it?
It'd be pretty doable with shaders. The difficult there is just learning shaders, generally, but not anything Balatro specific
so i have been looking at this localization example and i tried following it
but still not working, dont know maybe i dont get C_exmp_spectral,
like is the name used somewhere else or what?
any advice?
p_tags is a dictionary
iterate through it with pairs
ipairs reports nothing on dictionaries
thanks!
my stupid brain forgot what pos was for :P
from what i was told, its the position of your sprite in the sprite sheet
maybe the comma in the closing entry }, some programming languages shit themselves if you have a comma but no object after
ohhh yea
the example works, mine doesnt, i copied paste and just changed name
Not lua.
If I access G.hand.cards while playing a hand, does that include the played hand or no?
i dont think
printed this morning #G.hand.cards, and it takes the after played before drawn, held in hands
no, those are now in G.play
.cards
works for me
although it does seem to keep including cards discarded
o
to my great despair
ill hope it works out i guess
That's due to the timing of the discard, as they don't get moved to an in-between area, like G.play would do for play. But I can definitely see that feeling unintuitive
How do I find the right coordinates in my sprite sheet?
rows and columns?
wait nvm I probably found the problem
Why isnt my lovely injector working
it keeps crashing
can someone please help me 😭
umm, send a photo of the crash
i cant send photos but i can send the crash error
ERROR - [♥] lovely-injector has crashed:
panicked at crates/lovely-core/src/lib.rs:315:51:
called Option::unwrap() on a None value
asked gpt but it didnt really help me that much
@daring fern can u help?
this
now u wait for someone who know how to fix lovely "not me lol"
what's your lovely version?
0.7.1
your localization is still wrong
I Know
well, show it
is that what shows up at the top of the console?
well that's not what i asked
hi again ^^
do you have any mods
Its no longer invisible but now its a white square :<
are you on the steam version
oh wait actually
seals dont go in enhanced
i've been looking at the code for booster spawning, and am trying to figure out how to put a Resource card in there, and i've found that the game uses G.shop_booster to store them
that's a start ^^"
aha, okay, that's called in update_shop, so i can probably hook that ^^
it goes in "other" ....
now i feel like an idiot, had the vreamade in front of me and didnt think to check it
was on another example
How do I check the sticker of a card
Depends on the sticker. The vanilla ones each just set a book to true
Bool*
o
what bool might that be
Depends on the sticker
For example, eternal stickers just set the card.ability.eternal value to true, iirc
fair
The vanilla implementation of stickers really means that they're just a visual indicator. There's not really much of a sticker framework, so they're a bit quirky compared to seals or enhancements
fair
was hoping to test whether or not a specific consumable had a certain modded sticker or not
still not working
show
aren't you missing the +
also you don't need to add seal at the end if your key doesn't have it
first Seals is the prefix right? then no im not missing +
oh then yeah
same issue
what's your key for the seals
Should be "Other" not "other"
yeah the keys should also be like "Seals_Jade"
still no
not this either
show the loc file again pls
the key should be self.key .. "_seal"
i can stream if u are up to it
alot easier
oh wait really
im off to work sorry
its okay
but yeah append "_seal" at the end i was wrong on that lol
meaning? i should just put _
Yea if your seal key is called "Jade" then it should be jade_seal
i wish this was documented 🙄

hi n
haya.toml
hi hayaya
Show your loc code and seal code
i was trying to find code on gh yesterday for doing multiple blueprint copies and yours was the only correct one i found thank you
am struggling ;u; there's gotta be an easier way to add a card to the booster area, in the shop ;u;
😭
Do you just want to add it when the shop is opened?
i've hooked Game:update_shop, but i don't know what to do dfgkjndf
SMODS.add_card{key = key, area = G.shop_booster}
?
i have a hook for SMODS.calculate_context that adds an extra booster in a similar way in context.starting_shop
@maiden phoenix u can see the code in the vid
ah :D
awaiting instructions ....
Oh your loc key should be seals_jade_seal
idk if that will work automatically because you need to add the shop ui to the card too
i'll give it a go ^^ what arguments does calculate_context take?
context, return_table
Finally 🥳
not crashing
but seals not showing
it shows me this
You forgot to put your atlas in your Seal object
this?
do i change something?
hmm, okay, i'm getting this error now
local context_ref = SMODS.calculate_context
function SMODS:calculate_context(context, return_table)
if context and context.starting_shop then
SMODS.add_card { key = pseudorandom_element(G.P_CENTER_POOLS.phanta_CatanResource, pseudoseed('monopolychosenresource')).key, area = G.shop_booster }
end
context_ref(context, return_table)
end```
ah wait ignore
forgot to return ^^
SMODS.calculate_context not SMODS:calculate_context
Include it in your Seal object atlas = "Seals_atlas"
Also I think your SMODS.Atlas should be defined above your seals
Not sure if it causes issues if it's below
yay perfect!! it does need the shop UI though, but i can add that :>
(also, first shop blueprint fkjgndfkjgfd)
wait, just checking, are there any SMODS functions that add card UI?
ah yeah ^u^
does SMODS.add_card return the added card?
grand :D
The pos in your SMODS.Seal objects is the x,y coordinates of your sprite in the spritesheet, try modifying those
So for example if you want the top left one it'd be {x = 0, y = 0}
every seal is its own sprite
Oh they're individual? Then you must make a SMODS.Atlas object for each seal
yay :D
worked
13/333*389*SC_scale,
13/333*389*SC_scale*(G.ASSET_ATLAS[baldatro].py/G.ASSET_ATLAS[baldatro].px),
G.ASSET_ATLAS[baldatro], {x=0,y=0}) ```
what part in here do I change to move my sprite left physically? closest i got was moving the texture left but it still cut off on the left side
spectrals issue?
i guess its the same as the seal issue
gonna review the code and see if i can fix it
deleted everything i did the last 10 mins and still the same
somewhere in your code you have #pool
pool is a variable that has no value nil
you cant take #nil
# is the length operator
it's in smods code
you probably have the wrong key when you create a card or something like that
🆙
gonna go through it again 😩
found in which code the issue is
dont know what the issue is
its here somewhere
If I do card:get_id() of a King, will the response be 13 or 'King'?
13
How would I take ownership of a challenge?
jokers = {
{id = 'j_Jokeful_gold', eternal = true}
}
}```this is what I tried to do, but it crashes with this crash log
(I fixed it below is the correct code for anyone asking on how to do it aswell)
```SMODS.Challenge:take_ownership('rich_1',
{
jokers = {
{id = 'j_Jokeful_gold', eternal = true},
},
},
true --makes it "silent"
)```
the code in screenshot two appears to be the relevant snippet causing the crash
in case it's important, screenshot two precedes screenshot three code-wise
would love to help but i have no clue
it works fully if you get rid of the SMODS.destroy_cards(dead) line but that line is kinda integral to the point of the card
And changing the code after it to use the complement to the dead array doesn't fix it either
found it
Is there a "total hands" variable? Not in the round, but total for the current game
Total hands played, I mean
local card = create_card() How does this function work?
More often than not, you should use SMODS.add_card instead.
ooh, How would that work?
SMODS.add_card({key = "j_joker"}) would add a normal joker to your joker slots.
ooh, okay thank you!
Is it possible to make something trigger every time the word joker appear in screen
Even adding tetris in balatro?
I mean.
yes
yes
It is possible.
woah
you literally have
classic, GM or modern
turing
tuning machine
Tolkien machine
toning machine
talking machines
tanning machine
tiring machine
ok this is very much accurate
couldnt get one of my cards working that iterates through the hand
and in an attempt to identify the problem i eventually just copied the entire calculate function from raised fist VR
and it doesnt do anything
i tested raised fist specifically so it should work
i believe you, i had mine working at one point too
just not sure how i could have messed that up
show code?
calculate = function(self, card, context)
if context.individual and context.cardarea == G.hand and not context.end_of_round then
local temp_Mult, temp_ID = 15, 15
local raised_card = nil
for i = 1, #G.hand.cards do
if temp_ID >= G.hand.cards[i].base.id and not SMODS.has_no_rank(G.hand.cards[i]) then
temp_Mult = G.hand.cards[i].base.nominal
temp_ID = G.hand.cards[i].base.id
raised_card = G.hand.cards[i]
end
end
if raised_card == context.other_card then
if context.other_card.debuff then
return {
message = localize('k_debuffed'),
colour = G.C.RED
}
else
return {
mult = 2 * temp_Mult
}
end
end
end
end
i mean that looks like raised fist
indeed
so it does nothing?
correct
wait
okay yeah nvm
thought it was because of loc vars
but there are none
wait part 2
might need a new copy of it cause i changed the code and loaded a save
that wasnt it 😔
Bump
oh
maybe you need to iterate through that list
like
for i in dead
smods.destroycard(i)
instead of passing dead as the argument
or
for i in #dead
SMODS.destroy_cards(dead[i])
for i in dead
SMODS.destroy_cards(i)```
one of those
balatro uses love2d right?
yes
No, SMODS.destroy_cards can take a table.
https://love2d.org/wiki/love.graphics.newImage
For some reason I cant make this code to work
This error appears for me
Oki lemme try
oh
i was wrong
.
is there a other code that I can use?
What is the goal?
make a image appear when blind is beaten and make it dissapear after a few seconds
Try looking at other mods that do that.
oh ok
uhh
I have no idea if any other mods have done that but
Ill try to look for one
It actually almost worked tho
I got a different error
apparently there is a difference between destroying a table all at once or individually
is this the best way to check if a card is rankless?
if context.other_card.config.center.no_rank then
...
end```
Different Error does not mean Almost Worked
SMODS.has_no_rank(card)
iirc
I mean "almost worked" as in the Joker almost finished executing visually
It crashed at the very end instead of in the middle
thanks!
are the events before or after destroy_cards?
after destroy_cards
destroy_cards doesn't remove it from G.hand.cards?
it does but youre doing the loop before they get destroyed and executing the events after
I feel like I require clarification as to what events we're referring to
these
oh that
yeah those happen after
I figured if they were removed from G.hand.cards that G.hand.cards would just update to be a smaller table
I replaced it with the complement tho so now it works 
it doesnt update until the destroy_cards event finishes
to clarify the destroy_cards line is like literally the line before the screenshot
well
now that it's a loop it's not technically but you get what I mean
as long as it works it's fine by me 
Hello guys, trying to make a booster, but I'm really not sure of what I'm doing rn... does someone have an example you could show me ?
did that for now
my main problem is idk how to say "take this type of card"
in metadata whats the difference between "name" and "display_name"?
Display name is what shows on the badge I think.
badge?
like the rarity, etc
ohhhh
yeah
I think the name is what shows when you look at it in the mods menu.
wait really-?
It does it automatically.
whats a fake joker lol
A card that is not a card but has the properties of a card.
c a r d
ohh interesting
it doesn't work
What is the line that is crashing?
You need to return get_joker_return also you need to move it out of the context check.
oh
is there a prerequisite to using card.ability.extra_value
is that a property all cards have
or all non-playing cards
it now doesnt work too, but debug says this
Yes.
Code?
ok
Also do you want it be a loop and have the same order everytime or do you want it to be random?
that order
i mean
it should go from det to perseverance
then back to det
and that does it
side note something that always bothered me about that
the problem is that its still not working
det and perserverence are synonyms
Code?
i removed the {} there's no other change
undertale's problem tbh
does it matter what i call the metadata file?
yeah thats all i meant
yeah
lore problem
fr
id name it mod_name.json
not sure if it matters
okay thanks
but just in case
No.
and main.lua is necesairy?
No, it's whatever you labeled as main_file in the JSON
okay
Are you sure it is doing nothing?
yeah, it should give me $1 when 10 is scoring, but it aint
does the priority of the json matter?
That's what order the mod loads in, low loads earlier, high loads later.
Did you keep the get_joker_return function the same?
so the json at 0 is good?
Yes.
well i think i have a problem there
this part
it crashes the game
ty
oh
ok np
IT WORKS
TYSMMM
!!
also last question
how can i make these save?
the currentlies
do i add em at config extra?
You mean the values save if they come around again?
yeah
It should already do that.
oh but they dont show
I haven't figured that out yet.
well np then
is there a good way of changing just the purchase price of a card?
Hook Card:set_cost?
okie doke ^^ thanks
Um does anyone know why this is not working..?
This error shows up every time when the round ends
Aren't you overwriting love.draw?
love.draw is what draws everything on the screen.
i can't see what i did wrong here -u-
local set_cost_ref = Card.set_cost()
function Card:set_cost()
if not self.ability or self.ability.set ~= "phanta_CatanResource" or not G.GAME or not G.GAME.PhantaCatan or not G.GAME.PhantaCatan.free_resources then return set_cost_ref() end
return 0
end```
wait no ignore -u-
dfkijngjdkfgnd
mm no, didn't work
local set_cost_ref = Card.set_cost()
function Card:set_cost()
if not self.ability or self.ability.set ~= "phanta_CatanResource" or not G.GAME or not G.GAME.PhantaCatan or not G.GAME.PhantaCatan.free_resources then return
set_cost_ref() end
self.extra_cost = 0
self.cost = 0
end```
the error happens on game startup
You would do something like: ```lua
local oldsetcost = Card.set_cost
function Card:set_cost()
local g = oldsetcost(self)
if conditions then self.cost = 0 end
return g
end
Also a lot of ors without brackets is not good.
what goes in main.lua?
ah gotcha
Everything mostly.
No, you do SMODS.load_file the assert is not necessary.



