#💻・modding-dev
1 messages · Page 476 of 1
I ended up doing this, which is a bit clunky
mm, so it seems that the game still wants the card i'm returning to my hand to be discarded
the face-down card is not interactable, and doesn't move with the card area
How would I go about changing the width of a UI node
I tried doing something like this but it didn't do anything
local healthbar_UI = G.HUD:get_UIE_by_ID('healthbar_UI')
healthbar_UI.config.w = healthbar_UI.config.maxw * ALLOY.health / 100
healthbar_UI:recalculate()
G.HUD:recalculate()
omg it works now, thank you so much!!
i have made a monster
we already got a 69 joker back in criptid
i want him to also give 420 chips and add a gold sticker on each card played
i think i know how to add the chips function but no idea if it's possible to give stickers
Create a custom “upvote” seal
lmao
You mean gold seal? Like talisman?
Or gold modifier like Midas mask?
nah gold seal
although gold modifier could be cool if it wasn't in the game already
It does
Search up Midas mask
There’s nothing wrong with making something that exists somewhere else though
okay i can't get this to work. i'm assuming i need to remove the card from play as well?
funnily enough this is still, weaker than some vanilla legendary jokers
for now atleast
my idea was funny 69420 number + reddit gold = stonks
funnily enough, is it possible to make a joker that debuffs your played cards?
@red flower sorry to ping! do you know what i've done wrong ;u;
no idea, sorry
is this supposed to create a card or draw a card
draw the first played card back to hand
have you tried flipping the card at any point in this
i'll give it a go
wait didn't Gold Seal do this before!
there's a remnant of its code in state_events
I don't think only flipping the card is a good idea because I suspect it would have a phantom copy in G.discard that might cause problems
it has true instead of nil
okay progress! the true seems good, but the card is still flipped and cannot be selected
isnt the emplace here forcing the card to that location regardless of whether it was actually drawn or not
i've removed that, nothing changed
return {vars = {localize((G.GAME.current_round.rankvar_card or {}).id or 14, 'ranks')}} why is this showing up as ERROR, does it expect a string instead
i think cryptid has a code card that returns the last played hand to your hand iirc
yes, it expects the rank key, not the id
thank u dearly
nvm i think cryptid uses a custom global for it
unless G.GAME.last_hand_played_cards is vanilla
this isn't working, what should the references for the key and affected sprite be?
My mod is almost complete !
I am missing one more big step then just some polishing and play testing for balance
nvm! found it ^u^
My last big step is making my custom deck, need to work on it tonight. Thanks to everyone who has helped me so far
I am trying to make a deck where only my modded jokers show up in the shop but the problem is that i don't want my custom jokers to appear in the shops at all in the other decks
I am using a different rarity to make that happen but its still hard because I cant make them spawn naturally, I have an idea but I'll see what I can do when I get home
i think you can just modify the in_pool for those jokers
Like directly in the jokers and not the rarity? Because I have the rarity have a weight of 0 so they don't appear in the shops
I will try this when I get home, I hope it works
yeah jokers can have their in_pool set individually (thats how cavendish and gros michel work)
alternatively, you can give your rarity a weight but only have get_weight return your rarity's weight if you're on that modded deck
but if you set your jokers in_pool manually then they can have vanilla rarities
how do i check if a loc value currently exists
Omg thank you for that advice I think its going to help a lot
Also is there a way I can put my mod on the mod manager? Or do I need someone to put it for me? How does that work
is there a context for when a joker is destroyed? not sold, specifically destroyed?
On the dev branch, yes. It’ll be release ready in a few days
cool
I am once again asking for how to save cards in a variable in the run save file
?
eh
ill just figure it out i guess
G.localization is the loc table
could i do if G.localization.Other.blahblahblah
G.localization.descriptions.Other but yes
okay
any of you guys know how can i get blinds requried score and current hands score ? i am trying to create a joker that will be activated when i pass the round with only one hand.
G.GAME.blind.chips for the first hand_chips * mult for the second
final_scoring context is apropriate to check those right ?
yeah
okay thank you.
when i try using this joker, i get the error "main.lua:6289: card.lua:347: attempt to index field 'config' (a nil value)"
anyone have an idea what's causing it?
does context.purchase exist or something
does it???
genuinely no idea what could be causing that
it only crashes upon playing a card, so it shouldn't be trying to call a purchase
if you're testing with a version of the joker you had previously, sell that and add it again
it can't find the config variable in the joker that was created before the config variable existed, if that's possible
this was on a fresh run spawning it in with DB+
they were asking a separate question dw
ah okie
context.buying_card
thank you
how do you check if a joker no longer exists 🤔
calculate = function (self,card,context)
if context.final_scoring_step and G.GAME.current_round.hands_played == 1 then --
local required = G.GAME.blind.chips
local current = hand_chips * mult
if current >= required then
G.hand:change_size(1)
card:start_dissolve();
return{
message = "Caught"
}
end
end
end
``` i have a problem with when i add current round hands played == 1 part card doesnt dissolve. but when i dont add that to condition. joker gets destroyet before skoring animation ends
hmm, strange
tried to set up blueprint compat with this Joker, and the effect is copied, but the Blueprint tooltip still displays as incompatible. How do I go about adjusting this?
i actually need it to dissolve when we catch the required in our first hand
or alternatively, is there something that works like the opposite of set_ability? like, a function that runs when the joker is removed 🤔 (not remove_from_deck, because i dont think that runs with the collection menu)
if it's set as true then it should display correctly, try starting a new run or make sure you saved the file?
hooking Card:remove?
fair
it would be the latter NOOO
lol
played around with commenting out code, it looks to be something in this section of code that's causing the crash
yeah that worked LMFAO, thx a bunch
(my ADHD achilles heel is often forgetting the most basic shit KEKW )
probably context.other_card because you don't have a strict enough context check
the enhancement may be getting set to nil? not sure
oh yeah, that too
how would i make it stricter? i have this running inside a if context.cardarea == G.play and context.other_card == context.scoring_hand[1] then currently
also dont use math.random, use pseudorandom or pseudorandom_element
what's the intended effect?
nvm just read it
this has the params func = 'can_use_consumeable' which is held in G.FUNCS, but that isnt stated anywhere in the node so how does it know thats what function its supposed to call
if context.before and #context.full_hand == 1 then is what you want instead
or scoring_hand intead of full_hand if you want 1 scoring card instead
can you elaborate
like the screenshot is not even complete?
tried it with that, now i'm getting the crash that context.other_card:set_ability(card.ability.extra.chosenenhance) where other_card is a nil value
do i have to set other_card to be the played card manually?
{n=G.UIT.C, config={align = "cr"}, nodes={
{n=G.UIT.C, config={ref_table = card, align = "cr",maxw = 1.25, padding = 0.1, r=0.08, minw = 1.25, minh = (card.area and card.area.config.type == 'joker') and 0 or 1, hover = true, shadow = true, colour = G.C.UI.BACKGROUND_INACTIVE, one_press = true, button = 'use_card', func = 'can_use_consumeable'}, nodes={
{n=G.UIT.B, config = {w=0.1,h=0.6}},
{n=G.UIT.T, config={text = localize('b_use'),colour = G.C.UI.TEXT_LIGHT, scale = 0.55, shadow = true}}
}}
}}```
is the use button for consumeables and the func it uses is `can_use_consumeable` which is held in G.FUNCS, but G.FUNCS isnt stated anywhere in the node so how does it know that the function its using is the correct one the coder wanted in G.FUNCS
oh wow both at the same time
you want context.full_hand[1] instead of context.other_card
ohh ok i get it now
it's always in G.FUNCS
does anyone know why shaders on my cards are weaker than normal cards
so when its searching for a function it always just checks in G.FUNCS?
yes, so if you make your own it has to be there too
ahh that makes sense ty for clearing that up!
can someone tell me why this line is showing 'ERROR' in the description,
return {vars = {localize((G.GAME.current_round.rankvar_card or {}).rank or 'A', 'ranks')}}
but this line is not and works as intended
return {vars = {localize((G.GAME.current_round.suitvar_card or {}).suit or 'Spades', 'suits_singular')}, colours = {G.C.SUITS[(G.GAME.current_round.suitvar_card or {}).suit or 'Spades']}}
am i being silly
what's G.GAME.current_round.rankvar_card.rank ?
G.GAME.current_round.rankvar_card = { rank = 'J', id = 11 }
it has to be the rank key, not the card_key
so 'Ace' not 'A'
but...
BRUH
i swear that was how i did it initially and it didnt work
im too tired
thank u <3
does anyone know of any mods that have jokers with use buttons? i need some inspiration since im struggling a tiny biy
how do i make a joker give 2 dollars every time an ace is scored?
JoyousSpring :3
if context.individual and context.other_card.base.id == 14 then ease_dollars(dollar value) end
oh rly? any idea what joker might have that?
you're missing the cardarea check
ah yeah i forgor
these can be used as consumables: https://balatromods.miraheze.org/wiki/JoyousSpring/Jokers/Solfachord
the ones that say tribute have an activate button: https://balatromods.miraheze.org/wiki/JoyousSpring/Jokers/Generaider
they're all done in the same file tho
when do you call your create_use... function?
you can also click on a symbol on github to find where it's used
I have some cool combo and we'll balanced ideas for jokers and spectral cards. If some Wana add them to there mod then I can share my ideas (don't need any credits or something). Just let me play these ideas once they finished.
oh maybe thats why my code didnt really work
and also how do you make the joker wiggle when it uses its ability? Thank you
its still not working how do i do it now
whats the code
im still not good at modding
is this a joker?
ye
main_scoring doesnt exist for jokers and also it doesnt happen at the same time as individual
if context.individual and context.cardarea == G.play and context.other_card:get_id() == 14 then
return { dollars = 2 }
end
thats how i would do it
awesome it works!
ty!
because multiplayer mod is too cool to do that ig idk
is it possible to change a joker's rarity?
and also store all jokers in the collection in an array
maybe they had to rework it for the lives system
G.P_CENTER_POOLS.Joker is an array of all jokers
ohhh thats BEAUTIFUL
this is gonna be the hardest thing ive coded so far but itll be sooo funny if it works
they still coulda changed the text to be like live lost
How can I set the score after scoring?
i did something similar a while ago
Weird thing happening to my game
this just sets the mult to one specific thing which i feel like could do what youre looking for
in my case it sets it to 0 at the final scoring step so your hand doesnt score under a condition
i have this happen sometimes i think its a weird out of memory thing
try removing some mods from your folders its straight up just a scary unexplainable computer thing in my experience
itll fix itself if you approach your computer like youd approach a scared horse
Is it at all possible to determine where a function object came from? I'm trying to figure out what event is piling up in G.E_MANAGER.queues.base and, other than adding a bunch of diagnostics to Cryptid, can't think of a way to do that.
...I guess I could wrap G.E_MANAGER:add_event and use the debug module to determine stack traces.
how would i remove a value from an array?
table.remove(array, index)
sick
How would I determine the actual source listing of a file, eg game.lua, after mods have modified it? Is there a Lovely function that'll do it?
actuallyyyy in this case a better question might be, is it possible to shuffle the order values appear in an array
pseudoshuffle(list, seed)
list is the array
seed is whatever string you want
awesomeee
wait ena dream bbq mod,,,,
thats crazy one of my jokers is inspired by ena too
Neat

Cool effect. I made mine weird.
am i missing anything? it seems like thats whats crashing
ohhh shit so weird erratic scaling xmult
i fw that heavy
Put the znm_bologna in quotes.
You can play my mod at https://discord.com/channels/1116389027176787968/1385424277469134888 if you want.
oooh sick ok
ok now im really confused, it's still crashing?
this is the log it's giving me if anyone has any insight
You don't need pseudoseed. The pseudoshuffle function will already do so by itself.
oh gotcha
still nothing 💔
i wonder if it's even this thats crashing i was pretty sure it was
Is it the same error?
pseudoshuffle sorts tables
also you do need pseudoseed
is it possible to retexture suits and ranks added by other mods other than just straight up editing the files of it?
probably not, what's the objective
I'm trying to shuffle the order of values in an array
what's the ultimate objective
grab all the rarities of jokers, and then distribute them randomly across them so all the jokers have randomized rarities but there's still a proportionate amount of commons uncommons rares etc
instead of the rarity number you could make them into tables like { rarity = 1 } so you can use pseudoshuffle
yeah a table sounds right here
ive never used one in lua before, whats the process for that?
is it possible to just convert an array into a table and then go about my day fro mthere
tables are what the { stuff-goes-here } syntax is called
rather, { stuff-goes-here } is how you create a table inline
local t = {rarity = 1} is a table with one key: rarity, where t.rarity gives you 1
if you see a . anywhere between two identifiers (names/variables) in Lua, 99.9% of the time the left side is just a table
alright i see
an array is a special kind of table where the keys are numbers from 1 to however many items you want in your table
(note that the term "array" does not mean anything to underlying Lua; it's all just tables)
so whats stopping me from shuffling it exactly if it's technically a table?
The issue (only just learned this now) is pseudoshuffle requires, essentially, an array of tables.
(you could also just copy what pseudoshuffle does and remove the part that crashes by checking for sort_id)
You can just write a version of pseudoshuffle -- ^
function my_pseudoshuffle(list, seed)
if seed then math.randomseed(seed) end
for i = #list, 2, -1 do
local j = math.random(i)
list[i], list[j] = list[j], list[i]
end
end
and then just use my_pseudoshuffle(arr)
Place that function somewhere in your code
Note that this version does require you to specify a seed.
Otherwise you could get the same results every time
yep for sure for sure
ohhh this would proabbly help with the other deck issue i was having too
now that i understand this stuff better
ok wait its still crashing 💔
waittt nope this isnt your issue im doing something silly
i didnt realize the errors actually giving the line to me now teehee
That's usually the cause 🙂
this is whats going on over there
Yeah znm_bologna_jokers[i] is likely nil
Another thing, checking for rarity == (1 or 2 or 3 or 4) wouldn't actually work. Since you just want vanilla rarities, those will be numbers, while modded rarities will be strings. You can instead check type(G.P_CENTER_POOLS.Joker[i].rarity) == "number"
^^ the reason for this is that (1 or 2 or 3 or 4) will always be 1, due to how the or statement works in Lua
ohhh thats interesting
actually it might be this
this might be not properly adding it as a joker
(a_true_value or something) will give you a_true_value. (false_or_nil or something) will give you something.
i had to edit this hook to fix some issues relating to cryptid but now it doesn't work anymore, how do i fix this
Do you get a crash, an error, or?
it just does not function, previously it functioned but crashes on occasion, but i havent run into a crash yet
...also does array[#array+1] = value work in luajit? I always used table.insert
the intent is to remove modded jokers from the pool
It does work.
G.P_CENTERS[v] do you mean i instead of v here?
im not sure, i had a lot of help with this code
Depends what G.P_CENTERS is
Nope, v is correct
the problem is that youre returning the original pool again
return pool, pool_key at the end instead
^ oh duh that's the thing
You're doing all this work and then just calling and returning the original function, which doesn't know about all the work you did
this is what the function looked like originally
but i had to edit it because it was crashing cryptid's new equilib deck on the rebalance branch
this function worked before but it did crash ingame at random times
What's the exact crash message?
it closed to desktop, no message
this doesnt look too intrusive to me, I would guess the problem is on cryptid's side imo
Line 145 in the original version is correct. Line 145 in the version you posted is incorrect. You want return pool, pool_key
this is what was wrong with the original code apparently
probably not the issue but I would rename no_modded_jokers to something more unique, with your mod's prefix preferably
what is the correct color for this? this just shows as G.C.FILTER
colour = G.C.PLANET
let me check what cryptid does
G.C.SECONDARY_SET.Planet iirc
ah
specifically this branch
it worked 
oh yeah, try readding the , ...
also this seems to work fine but i need to test more
also this means that cryptid would also crash with my mod lol
i dont know how to recreate the ingame crash
it just happens sometimes
so
ill test it out
how do i get an smods reference from an atlas
is there like a
SMODS.query("lat_hacknet")
can you elaborate?
like
instead of supplying the keyname as a string in a joker
i wish to get its actual reference to supply into a separate game object
G.ASSET_ATLAS["modprefix_key"]
and if i were to do the same with shaders? would it still be atlas
or would it be asset_shader
tried that
unless my shader code is wrong
i think its correct
extern number speed = 0.0059;
extern number freq = 50.0;
extern number borderPx = 0.5;
vec4 effect(vec4 vcolor, Image tex, vec2 tc, vec2 sc)
{
vec2 uv = tc;
vec3 bg = Texel(tex, uv).rgb;
float t = clamp(time * speed, 0.0, 1.0);
float thickness = borderPx / sc.y;
float flash = sin(time * freq) * 0.025 + 0.5;
vec3 col = bg;
float borderPos = 1.0 - t;
if (uv.y > borderPos)
{
float darkR = 1.0;
float brightR = 0.9;
col.r = mix(darkR, brightR, flash);
col.g = bg.g * (1.0 - flash * 0.8);
col.b = bg.b * (1.0 - flash * 0.8);
};
if (uv.y < borderPos + thickness && uv.y > borderPos - thickness)
{
col = vec3(1.0);
};
return vec4(col, 1.0);
}
mine is in there
also anyone know why my balatro keeps going black
balatro jsiut froze my discord
they tryna stop me
he's grown too powerful (apologies if you're not a he)
also <@&1133519078540185692>
chat i GOTTA join that server
smh bro fell for the trap
Banning him auto-deletes all his messages IIRC
didnt seem like it
unless it takes a bit
nah im actually jimbo himself thank you very much i will be suing you
Was this resolved? I don’t see anything
yes thank you
yeah its gone for me
Alr I was a little late lol mb
my shader is being loaded
is there a command to try running a shader as an overlay
this is a test function i set up for it
is there a way I can detect what hand a round was ended with? I tried
if context.scoring_name == card.ability.extra.poker_hand and context.end_of_round and not context.game_over and context.cardarea == G.jokers
but it no work
eh?
SMODS.Joker{
key = "topiary_tree",
name = "Topiary Tree",
config = { extra = { odds = 6 } },
pos = { x = 3, y = 0 },
cost = 7,
rarity = 2,
blueprint_compat = true,
atlas = "duo_joker",
loc_vars = function(self, info_queue, card)
return { vars = { G.GAME and (G.GAME.probabilities.normal * 1) or 1, card.ability.extra.odds } }
end,
calculate = function(self, card, context)
if context.individual and context.cardarea == G.hand and not context.end_of_round and not context.blueprint then
if context.other_card:is_suit("Clubs") then
if pseudorandom("theduo_topiary_tree") < G.GAME.probabilities.normal / card.ability.extra.odds then
SMODS.calculate_effect({func = function()
G.E_MANAGER:add_event(Event({
func = function()
local random_tags = {"tag_uncommon", "tag_rare", "tag_negative", "tag_foil", "tag_holo", "tag_polychrome", "tag_investment", "tag_voucher", "tag_boss", "tag_standard", "tag_charm", "tag_meteor", "tag_buffoon", "tag_handy", "tag_garbage", "tag_ethereal", "tag_coupon", "tag_double", "tag_juggle", "tag_d_six", "tag_top_up", "tag_speed", "tag_orbital", "tag_economy"}
local selected_tag = pseudorandom_element(random_tags, pseudoseed("create_tag"))
add_tag(Tag(selected_tag))
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end
}))
return true
end}, card)
card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, { message = "+1 Tag", colour = G.C.FILTER })
end
end
end
end
}
this joker basically has a 1 in 6 chance for club cards held in hand to create a tag, but it crashed upon trying to make one
local tag = Tag(selected_tag)
tag:set_ability()
add_tag(tag)
```?
though, oddly enough, it can make a lot of tags, it just dies on some random unknown tag
alright then, just replace the
local random_tags = {"tag_uncommon", "tag_rare", "tag_negative", "tag_foil", "tag_holo", "tag_polychrome", "tag_investment", "tag_voucher", "tag_boss", "tag_standard", "tag_charm", "tag_meteor", "tag_buffoon", "tag_handy", "tag_garbage", "tag_ethereal", "tag_coupon", "tag_double", "tag_juggle", "tag_d_six", "tag_top_up", "tag_speed", "tag_orbital", "tag_economy"}
local selected_tag = pseudorandom_element(random_tags, pseudoseed("create_tag"))
add_tag(Tag(selected_tag))
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
with this?
No, you just replace add_tag(Tag(selected_tag))
ah
Also why not get a random tag from G.P_TAGS?
most of the code above is copied from jokerforge
i'm unsure on how to actually get a random tag, but that would be a lot more convenient
bump 
Just replace local selected_tag = pseudorandom_element(random_tags, pseudoseed("create_tag")) with local selected_tag = pseudorandom_element(G.P_TAGS, pseudoseed("create_tag")).key
bumpbump
Yes.
getting an error when i tried to launch spore
im kidding but
my ui code is messin
wait i think i see the fix
how then
G.GAME.last_hand_played
thank you
ok yeah fixed it
is there a way to manually reroll individual items in the shop? the cards I create aren't actually shop itmes by the look of things
wdym they aren't actually shop items?
i need someone much better than me at smods and comb through my code at some point haha
if it works, it works... even if slightly less efficient
hopefully in a month or two when it can create consumables and editions and whatnot i will be better at smods and this kinda thing will happen less
what even is the purpose of putting
if context.cardarea == G.jokers ... then
in joker conditions
none
it might help if there are other cardareas your joker can be in
they aren't purchasable, even though I call create_shop_card_ui on the card after creating it
woah how did you make a use on a joker
three days of pain lol
damn
I'll be pushing the code to git once I get this Joker working if you want to copy it, but I would look at N's mod since he did it way better
use the dice like 100 times and youll cause a memory leak
but yeah the cards just stick around forever and aren't purchasable in the shop
create_shop_card_ui(card)?
they would also need to remove a card from shop
_card = create_card("Joker", G.shop_jokers, nil, nil, nil, nil, nil, "reroll_shop")
create_shop_card_ui(_card, "Joker", G.shop_jokers)
that's the code I use, something is wrong with it probabaly since the create_shop_card_ui doesn't seem to work
Why aren't you using SMODS.create_card?
this would create a card, meaning there would be 3 cardfs in chop
doesn't this emplace the card into a certain area
Yes.
local _card = SMODS.create_card({set = "Joker", area = G.shop_jokers, key_append = "reroll_shop"})
G.shop_jokers:emplace(_card)
create_shop_card_ui(_card)
any ui wizards know how i can make the text be on the left side, and the checkbox on the right
Is the text not already on the left side
I think those text boxes are just long enough that they look left-justified
print("rerolling: ".._card.config.center.key)
local _card = SMODS.add_card({set = "Joker", area = G.shop_jokers, key_append = "reroll_shop"})
create_shop_card_ui(_card)
well i mean, it doesnt look that way
like all the way on the left
touching the left wall
the print statement only runs when the reroll function gets triggered, and obviously the card isn't actually being changed
does it only reroll jokers into other jokers
yeah, that's why pluto is staying the same, its not supposed to mess with that
ok, then this is probably not the ideal solution but you can call :set_ability on the joker in the shop
(and :set_cost after)
well I kinda fixed it?
hes jsut getting lucky and keeps rolling noodles
I think I just need to delete Ramen now
I'm trying to make a joker that can only copy blueprint and brainstorm and while this works for blueprint when I tried to sub in brainstorm it no longer copied it. Does anyone know what the problem is?
Alright the reroll works, but I think I just created one of the most ridiculous bugs ever
if a Joker gives hands or discards it gives them even while in the shop if it gets rerolled by this card, even Vanilla ones like Drunkard
the extra hand/discard goes away if the shop is closed or the card is skipped, so its technically only a visual problem, but this is still insane
Did you merge the returns?
yeah, you probably dont want add_card
you want create_card and emplace
I'll try SMODS.create_card
the SMODS create_card tho
how would I do this?
SMODS.merge_effect
Grr...... destroy card contexts are sent to jokers before they're sent to enhancements........
This is annoying
stup
stup?
AAAAAAAAAAHHHHHHHHHHHHHHHAsklcnaqnwfianslcaiwfcasclknqlwnfaw
there's like 4 cards stacked on top of each other there btw
Hmmmm trying to figure out how to do this without editing glass cards directly
and they dont have a Buy button 😭
I need to retrigger a glass card's chance to break
But I also don't want to roll it before glass cards normally roll that chance, so I can pass on it if they're already going to break, since that would just advance the seed unnecessarily
You would put the effects in a table then do return SMODS.merge_effects(effects)
so giving it a 7/16 chance to break?
yeah
The effect is "Retrigger glass cards, but also retrigger their chance to break"
sorry for asking but how would I put the effects in a table?
local effects = {}
local effect = SMODS.blueprint_effect(...)
if effect then
table.insert(effects, effect)
end
I guess I'll just settle for taking ownership
yea I think that's probably the only way
I did a similar thing with wheel of fortune
remove the surrounding table from tyesd
oh that wont work because its two nodes
Im very smart and cool
SMODS.Enhancement:take_ownership('glass', {
calculate = function(self, card, context)
local ret, post = ref_glass_calc(self, card, context)
if context.destroy_card and context.cardarea == G.play and context.destroy_card == card
and not context.destroy_card.glass_trigger then
local shatter_mes = SMODS.find_card('c_fnwk_iron_shatter')
local valid = false
for _, v in ipairs(shatter_mes) do
if not v.debuff then
valid = true
break
end
end
if valid and SMODS.pseudorandom_probability(card, 'glass', 1, card.ability.extra) then
card.glass_trigger = true
ret = ret or {}
ret.remove = true
end
end
return ret, post
end,
}, true)```
I eated this
add those two nodes individually
Hello!!!!!!!
god dammit im getting the black screen glitch again
im only setting a node because i just need it to represetn nothing
sleepys mod is very cool
idk why it is so small tho
holy shit yugioh
:o
im checking if a variable is provided by my function, if it is, display it through ui, if not, dont display it, how im tryna do this is by setting a varable to be my ui, and if there is no description variable set that variable to nothing, and display whatever the variable is
im trying to explain to you what im doing
you literally responded ?
like what else am i meant to gather from that
you seemed confused
yeah I'm confused as to what your original response had to do with what I said
yeah N's mod is crazy lmao
kyesd has two nodes inside a table, you need to add them to your other table individually
that's what causing the crash
yeah
is there a table unwrap function i can use there
unwrap()
uhh maybe it wasnt that
It's unpack no?
yeah that
Make them bigger is not a big deal
TheFamily.UI.scale and TheFault.UI.tabs_per_page
why is my balatro black
that didnt do what i wanted
my balatro is making everything black
TheFamily.rerender_area()
perfect, thank you
unpack doesnt exist either??
ok no yeah thats readable now
exist
It's just unpack, not table.unpack
Issue somewhere in here...
it works
ignore how the screenshot goes off the window
the balatro was black
and was blocking my software
like can jimbo stop being black
hes too black hes covering my window
HES INFECTING MY OTHER PROGRAMS
OH GOD
SOUNDPAD
ITS BLACK
we're about to witness the death of RatMilk
ITS TAKEN OVER SOUNDPAD, AND BALTRO ISNT BLACK ANYMORE
I CLOSED BALATRO ITS STILL BLACK
OH GOD HELP
Discord's going next
ITS ALREADY TAKEN DISCORD BEFORE
IT FROZE DISCORD ONCE
ok i got it to stop being black
now
how cow pow wow, tow pow, gow yow
also how cna i change the
change default color of the localize box
nvm figiurted it tout
nvm i didnt
💔
I'm starting to think your GPU is just dying
i think it was some fucked compat with soundpad
because i towkred when i closed it
and i could see balatro only if my cursor was on the grab window
kinda wondering what's wrong here
is it crashing
no, its just not doing anything
wait this should be a loop
It should?
yeah, context.individual is when individual cards are scored
also youre calling the card's ability when it would be other_card
Oh
i gotta find my code where i actually loop through the played hand so i can help better, hold tight for a bit while i get the code open
alr hold on lemme get this all together rq
i find it amusing that smods has a dedicated function for free rerolls and NOTHING else
no free packs, vouchers, etc
for k, v in pairs(G.play.cards) do
if v.ability.carfi_cisF or v.ability.carfi_transF then
SMODS.Stickers["carfi_mushroom"]:apply(v, true)
end
end```
wdym
SMODS.change_free_rerolls(10) vs hooking into set cost
bump
should this make a button that will toggle a button to true or false in my config.lua?
it would be cool to have a SMODS.change_planet_cost or something
apparently this (1) line in this (2) override crashes the game (3)? any ideas?
bought buffoon pack, clicked on shoot the moon. crashed on click
I think it would be better and more general to be able to change cost and sell_cost independent of set_cost imo
that would be fire
i might work on that
instead of having them coupled
<3 much love if you implement this
rn in my mod i patch set_cost and have extra variables
the only reason i knew how to do it was from vanilla remade haha
context.set_cost would be funny
context.playing_game when
how would i go about making it so a card isnt able to be sold
hook Card:can_sell_card
is there a way to modify the pool of Boss Blinds?
i'm making a deck where only the Amber Acorn can appear, and i've got no clue how to do that -u-
override get_new_boss function
is there zero easier options
yes
a harder option is hooking the function that calls can_sell_card
oh well sorry an easier option is to make the card eternal
smods should have a thing where you can just set can_sell_card to false in the card's code
I'm confused, I don't see a call to ipairs in the source code anywhere near line 2168 of this file
set tag eternal haha
the ipairs is in your code somewhere, not in the lovely code
ok I'll look for it, thanks
im sure that in order to have a card be eternal when you buy it id probably have to hook that anyway
no its much easier to force set tags
when you buy it?
even in the collection it will have the tag
set_ability = function(self, card, initial)
card:set_eternal(true)
end,
this is how jokerforge does it
thats not what i was saying
specifically when you buy it yeah
that would be more fucked
lmao
and rude to the player if you ask me
but i can probably figure out smth like having an add_to_deck function that sets the card to be eternal
thats kinda the point of it ngl lol
anti-balatro mod, tags are made invisible completely
you only know if you got perishable when the joker dies after 5 rounds inconspicuously
you only know you got rental when your econ starts dying
that would be stickers, not tags
though the funnier option here would be making all seals invisible and removing the enhancement atlas
i set up a deck earlier today that randomizes the rarities of jokers when the run is started, and like it technically works in that it changes the rarities (for like baseball card for example) but it doesnt affect the shop in any way, and using the soul still gives the vanilla pool of legendaries, is there any way to fix this?
am I able to influence a tooltip on a card from loc_vars?
like I want the tooltip to be variable:
charges = {
name = "Charges",
text = {
"Charges: {C:yellow}#1#/#2#",
"{C:inactive}#3#"
}
},
info_queue[#info_queue+1] = { set = set, key = "charges", vars = { 1, 2, 3 } } iirc
so would it just be like, reinitializing it sorta? like having it recalibrate
yes
a lot of those things get done on start up
you will also need to revert it when the run is closed
because i found the vanilla code and im wondering if doing what youre suggesting is just as simple as placing it there again in like an event or something
ohhhhh wait true that explains why it was happening in other decks maybe
yeah a lot of these things are global and not meant to be modified
🤭
minor bumpage
bruh im too tired u right
https://github.com/Steamodded/smods/wiki/Text-Styling this page has all the valid ones
you could use C:money
or C:gold
true
i was slightly too late
every now and then i get to be the guy who knows the answer instead of asking for stuff and ill do it like my life depends on it 🙏
ui elements extends Moveable which have juice up function, just like cards
cool
is there a way I can add a version requirement to the dependencies in smods.json
like I want to make sure that the player has a certain version of SMODS since I use some pretty recent stuff from it
Yes.
how
"Steamodded (>=version)"
ok update
it's whenever you click on ANY card in ANY pack
same crash
if i were to add another card into the title screen, would it work by just typing another emplace function
No, you would have to create another card.
i figured
is there a way to code to generate random consumables?
Yes.
or a random tarot would even be good
should be
any consumable?
just like emperor
Yes.
just different limitations on what type it can be
via a joker i mean, sort of like that joker that does it at the end of the shop
guy that gives 2 random tarots
forgot whats its called
ah
theres one in cryptid that does that so yes
Yes.
how would i go about that can i ask
or perhaps could someone point me in the right direction
intellisense for this would be helpful
Get a random element from G.P_CENTER_POOLS.Consumeables
thank you very much
pools = {Meme = true} is how you add meme jokers to the pool of meme jokers, right?
Yes.
Is there documentation on how to patch functions?
and how would i destroy a random consumable? sorry i've just never worked with consumables before
You would get a random card from G.consumeables.cards and do SMODS.destroy_cards(card)
is it possible for a joker key to have too many underscores?
ughhhh
i mean thats cool but hh
trying to figure out why rerolling the shop into this card crashes the game
the line in question key = card.ability and card.ability.extra.new_key or "j_hpfx_not_fortune_teller",
What is that line?
where are the crt shader values set?
area = G.consumeables
}```
oops
Why are you creating a card?
would create_card not work?
convert the left error into the right error
Yes, but you said you were destroying cards?
what is the different between adding and creating a card
Rather have actual help
well destroy one, then add a random one
still reading
i should've been more specific
oh. mb
Yes, you would do: ```lua
local consumeable = pseudorandom_element(G.consumeables.cards, "seed")
SMODS.destroy_cards(consumeable)
SMODS.add_card({set = "Consumeables", area = G.consumeables})
i'm assuming i'd have to make sure it abides by the consumable card limit
if consumables are less the limit than it, then do that
G.consumeables.config.card_limit right
No, because if you destroy a card, there will be a new slot.
negatives from perkeo
i'm not creating negative consumables
so if i have 2 normal consumables, and loads from perkeo
they mean that if the card destroyed is negative you'd go over the card limit
The error talks about descriptions, and loc_txt has description. Could that be the issue?
a lazy solution is to make negative cards ineligible to be chosen for destruction
yeah lol
seems like there's something up with how you're doing your description that's causing it to knock out. maybe make it description instead of the plural descriptions?
if context.setting_blind and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then from Cartomancer
oh lars said it already
local consumeable = pseudorandom_element(G.consumeables.cards, "seed")
if not (consumeable.edition and consumeable.edition.card_limit and consumeable.edition.card_limit > 0) then
SMODS.destroy_cards(consumeable)
SMODS.add_card({set = "Consumeables", area = G.consumeables})
end
is there a difference between adding and creating a card
No dice
SMODS.add_card automatically adds to deck and emplaces.
that's hilarious lmfao
cuz now that you changed it from description to descriptions it's complaining about description not existing :)
misc.descriptions doesnt exist
isn't it just descriptions? no misc?
G.localization.descriptions yeah
wait this is in miscGDI I WAS RIGHT THERE
sniped
but yeah descriptions and misc are 2 different sections
(i didnt even know SMODS.Filler was a thing)
It's not
🤷
I'm making it
yeah
It's basically jokers but not as restrictive
hypee
jokers but good
what function is called when a run is started
Game:start_run
thanks 
n do you know enough about generate_ui to help figure out a crash,,,,
oh i forgot i was reading yours too
oh cool carry on then
can i see the rest of the cards code
either
one moment then
i only need the SMODS.Joker
youre missing a config to initialize extra
got lost in the sauce
i can get away with just this right
yes
nice
oh god ive been doing that to the ones that didnt use extra vars
ive gotta go fix those
can you loop something an amount of times based on a local variable?
local amount = 10
for i = 1, amount do
-- loop
end
okay i was just missing the 1 before the variable, thanks
not used to lua yet
Lua is like a cursed mishmash between Python and C
used to C# with modding but I used godot for most stuff which is baby language so
could this mentality (missing an initialization) be the reason the game crashes when i click on any card in a booster pack or is that something entirely different
no idea, i would need to see the crash
so real
ill link it
it was further up
i think .nodes[2] doesnt exist
ok but if i remove that is it gonna break the custom button
cause i have this
you can check if it exist and only add it if it exists
in a booster the buttons are different
so like
local inner_nodes
if "this is a joker" then
if "this is the card's booster pack ui" then
inner_nodes = ret.nodes[1].nodes
else
inner_nodes = ret.nodes[1].nodes[2].nodes
end
end
?
maybe, i dont know the ui structure of buttons off the top of my head haha
card.ability.set == "Joker"
cause card.area.config.type == 'joker' is for the area right
but i had the right format?
yeah

does the game keep track of defeated boss blinds or do i have to do that myself
i had to do it for specifically the crimson heart for an unlock
that's fine idm doing a patch
let me get what i did for mine rq then
overrides file on the left, main file on the right
it IS cardarea.lua right
cause im not
seeing one? (an area name)
whole lotta G.hand and G.deck
cardareas are usually defined in game.lua iirc
ohhhh ok
so i'm back to annoy the professionals with another question
is there a way to change the edition of every playing card in your hand at once
probably just loop over all the cards and change the edition
for i = uhhh
Like some
for _, card in ipairs(G.hand.cards) do
what is _?
I forget the name uhh
nullifying operator?
It's normally the index but you don't need that
for index, value in ipairs(table)
oh they're just called discards
if you don't use one of them is normal to change it for _
aight cool
evil how pack_cards is only mentioned as a string in cardarea_focus (in game.lua)
and i hate to ask this because it's stupid but how do you change the edition of a playing card
wait does Lua have discards?
You use underscores in other programming languages because naming a variable as a discard does a very specific thing in memory
playing_card:set_edition("e_key")
card:set_edition("key") i think
i dont think so? but maybe
I've never really thought about it
Like in C or C# or whatever, if you name a variable _, it's just not even assigned to in memory at all
for _, in
i think that would be a syntax error
i mean for _, v in
i normally use python and it doesn't do anything either I don't think, it's just convention
I'm pretty sure it's just C-based languages
It became a convention in other languages because C-based languages are so dominant
though _ does still do a lot of weird things in python
well it fixed the buffoon pack... the celestial pack though?
im gonna have to do it for each huh
can it also transform planets??
no 😭
i only did jokers
(for now)
ok i found the uidef for this function
this is the conditional for consumables in boosters im guessing
the joker area is just sell which makes sense
it's specifically this line that crashed it btw in case i didnt send
where would i put a run-wide variable
the formatting threw me off
trying to set up a table with a list of defeated blind keys
thank vs autoformat, i didnt do that
G.GAME
how would i reset that at the beginning of a run?
it auto resets
i think
oh yeah
I never knew
!!!
you have to go out of your way to have it NOT reset each run lmao
just use config???
What are the parameters from draw_card()? I'm seeing values set to nil and true/false but what no idea what they're affecting
holy shit my format math is working
holy shit chat
it looks correct now!
kinda
scale is a lil
funky
and also
how do i change the default color in a localize box
draw_card by itself is a diff function though so in case you meant this one
need it to be white/grey
Yes thats what I was looking for. Thank you
what's the vanilla prefix for blinds? b_?
so set the box's colour to G.C.white?
bl_
thank you
Is there a way I can set the desired score? Seems like I can set mult in context.final_scoring_step, but not chips.
Yes.
How?
It's hand_chips not chips
i could set the text internally with {C:white} but that seems too much work
how do i set its default
like basically making {} into {C:white}
How do I check if a particular joker is owned?
if next(SMODS.find_card("j_modprefix_key"))
is this G.UIT.T
if so then u can have colour = G.C.WHITE in config
G.C.WHITE, not G.C.white
i accidentally gave all the basegame boosterpacks my mod badge oh no
how
how do i not do that
are you taking ownership
no im overriding for a custom button
for specifically certain jokers you own
but it crashes the game when boosters get involved
no clue how that would add your mod badge, can u show me the code
ignore the "and card.area", i just added that
this was the crash when i tried to open a standard pack that had my mod badge
mm i dont add buttons like that, so dunno
do you wanna see the button itself
sure
i got no idea what i'm doing here.
that makes two of us 😭
how did you get the checkbox and the text
so confident
odd, changing colour should change the default color of the text
maybe SMODS.localize_box doesnt work like i initially thought then
agre
draw_card() seems to be the source of countless headaches
I have some cool combo and we'll balanced ideas for jokers and spectral cards. If some Wana add them to there mod then I can share these ideas (don't need any credits or something). Just let me play these ideas once they finished.
why
am i stupid
that file gets loaded for sure
is this not how you define global functions
Yes, but does it get loaded before you're calling it?
how would i affect the values of other jokers?
Change values in card.ability
is this the wrong way to do this
Yes.
is there another way to do variable cost
and how would I affect the blind requirement?
G.GAME.starting_params.ante_scaling
editing this value messes with how fast they SCALE, but idk about effecting the requirements directly
G.GAME.blind.chips = G.GAME.blind.chips * [value]
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
and whats the context for blind start?
context.setting_blind I believe
context.setting_blind yeah
I'm trying to use context.other_ret to see if a Joker gives chips, but is there any way I can use this to pull information about the Joker that gave the chips?
context.other_card
I tried context.other_joker but it doesn't have what I need
I thought this was onyl for scoring cards? Not Jokers?
so if i wanted to decrease the mult by a certain percent, would this be it?
No, jokers are cards.
alright so how do I use that to see when another Joker gives chips? Because I've tried calling that Joker's calculate function from elsewhere, but the game hates that apparently
i get a table index is nil error on the final line, is self.key returning nil?
how would i get the key of the defeated blind?
self.config.blind.key
how would i check if the joker to the right is compatible or not?
(blueprint compatible)
can you have a joker with a custom rarity show up in the shop without adding it to the Joker pool? no matter what default_weight i use i can’t seem to find my joker in the shop, but i know it’s in the pool
if card.config.center.blueprint_compat
Perhaps you could add it to one of the consumable pools?
how do i add a reference to a seal and edition in translation?
like how Trance will show the descritpion to blue seal along with its own descritpion
info_queue[#info_queue+1] = G.P_SEALS.modprefix_key
i don’t really want them to show up in any consumable packs or anything
info_queue[#info_queue+1] = G.P_CENTERS.e_modprefix_key
is there a way to just. make a new pool to have them show up at all
What is the reason for not putting it in the joker pool?
don’t want them to appear in buffoon packs
then to lets say half all values of a joker, would i just loop through card.ability and half all numbers there?
No.
I have a function for this though.
function SEALS.modify_joker_values(card, modifytbl, exclusions, ignoreimmutable, withdeckeffects)
if not card or not modifytbl then return nil end
if withdeckeffects == nil then withdeckeffects = true end
local cardwasindeck = card.added_to_deck
if withdeckeffects and cardwasindeck then card:remove_from_deck(true) end
exclusions = exclusions or {}
local ops = {"=", "+", "-", "*", "/", "%", "^"}
local function modify_value(ref_table, ref_value, isdirectlyinability)
if type(ref_table[ref_value]) == 'table' and (ignoreimmutable or ref_value ~= "immutable") then
for k, v in pairs(ref_table[ref_value]) do
modify_value(ref_table[ref_value], k, false)
end
elseif type(ref_table[ref_value]) == 'number' and ((not (exclusions[ref_value] == true or exclusions[ref_value] == ref_table[ref_value])) or not isdirectlyinability) then
for i, v in ipairs(ops) do
if modifytbl[v] then
ref_table[ref_value] = SEALS.perform_operations(ref_table[ref_value], v, modifytbl[v])
end
end
end
end
for k, v in pairs(card.ability) do
modify_value(card.ability, k, true)
end
if withdeckeffects and cardwasindeck then card:add_to_deck(true) end
end
function SEALS.perform_operations(val1, op, val2)
if op == "=" then return val2 end
if op == "+" then return val1 + val2 end
if op == "-" then return val1 - val2 end
if op == "*" then return val1 * val2 end
if op == "/" then return val1 / val2 end
if op == "%" then return val1 % val2 end
if op == "^" then return val1 ^ val2 end
end
how exactly would i use this?
ok huh i guess that doesnt work on Backs
Yes, you would put {T:classprefix_modprefix_key} in the description.
You would do modify_joker_values(card, {["/"] = 2}, {x_mult = 1, x_chips = 1}) I think.
can i do something like this? (im trying to temporarily half it, as the joker is basically a bad mimic)
Can you have it so a joker makes a certain blind appear?
Probably.
Yes.
how so?
Change G.GAME.round_resets.blind_choices.Small or G.GAME.round_resets.blind_choices.Big or G.GAME.round_resets.blind_choices.Boss to the key of the blind.
i think i screwed something up
Code?
i genuinely have 0 idea what the issue is so heres the entire code:
SMODS.Joker{
key = 'j_dummy',
cost = 6,
rarity = 2,
blueprint_compat = true,
loc_txt = {
name = "Dummy",
text = {
"Copy the ability of the joker to the right,",
"but all of the values are HALVED.",
"{C:inactive}#1#{}"
}
},
atlas = "Jokers",
pos = {x = 0, y = 1},
config = { extra = { compatible = "Incompatible" } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.compatible, } }
end,
update = function(self, card, front)
local _myid = 1
if G.jokers then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then _myid = i end
end
end
if G.jokers and G.jokers.cards[_myid + 1] then card.ability.extra.bptarget = G.jokers.cards[_myid + 1] end
if G.STAGE == G.STAGES.RUN then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
other_joker = G.jokers.cards[i + 1]
end
end
if other_joker and other_joker ~= card and other_joker.config.center.blueprint_compat then
card.ability.extra.compatible = "Compatible!"
else
card.ability.extra.compatible = "Incompatible!"
end
end
end,
calculate = function(self, card, context)
local other_joker = nil
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i + 1] end
end
modify_joker_values(other_joker, {["/"] = 2}, {x_mult = 1, x_chips = 1})
local thing = SMODS.blueprint_effect(card, other_joker, context)
modify_joker_values(other_joker, {["*"] = 2}, {x_mult = 1, x_chips = 1})
return thing
end
}
what's it supposed to be doing?
it copies the ability of the joker to the right, but it halves all values
(ex: if the joker to the right gave 50 chips, the dummy joker would give 25 chips)
yuh i think i fucked something up
If it's in every context you probably want to do modify_joker_values(other_joker, {["/"] = 2}, {x_mult = 1, x_chips = 1}, nil, true)
and replace / with * when im done copying it?
Yes.
still spams events
could be the update function?
putting the update function in comments to see what happens
My mistake, try replacing the last true with false
Is there a way to prevent a game over like what Mr Bones has going on, but outside of a Joker? I don't know how to gain access to "context" outside of cards
Yes.
How would one go about that
It's not a Joker or a consumable or anything
Try hooking SMODS.calculate_context and changing SMODS.saved to true in context.game_over
truee
Is there a way to do on click events with a joker? (the card itself)
what variable is responsible for the player's current score
hook to Card:click()
fun blind concept
the j*b
Rather than a random debuff of a blind, you can choose which joker to go without. So you can easily buy a dummy joker to avert it if you want to, but it's also nowhere near as intrusive as Crimson Heart since you can choose the best option to debuff
Regardless it's more likely to make a difference on early antes
Crimson Heart but its fair
Regardless I'm glad I helped toma with the button stuff yesterday because I basically just ended up copying most of my own homework for it here




