#💻・modding-dev
1 messages · Page 159 of 1
I know you can dissolve it, just a lot more involved, then you gotta ease money, destroy the card and send the message, and I found that trying to do it that way, it plays the messages in a weird time
Don't forget after G.E_MANAGER events
Seeing all this im really not looking forward to making my own mod ;-;
you should try it out! this is like the advanced stuff
its really not that bad, im making it sound like a bigger deal than it is 😛
I plan to do some complicated stuff tho like custom face cards and what not
Then why the fuck does LT sometime not use it?
Cant wait to make the art for em
is it a LT moment?
LT?
LocalThunk
I can post some of the ideas if your curious:3
because dissolve has the dissolve animation, then removes
remove straight up removes it
If not it will stay my evil secret mod
They didn't specify if they wanted the card to dissolve or not so 🤷
bruh
in my mind destroy = dissolve, is there a bigger difference?
Here me out
We make the card explode instead and make a custom animation
If you don't use start_dissolve it just pops out of existence
Thatd be way cooler fr fr
green screen explosion
It would go hard
Or like
The stupid green screen car crash into helicopter falling into plane explosion
That ones always a banger
start_car_crash 
start_epic_car_helicopter_plane_crash *
the message plays after the card is dissolved, and the money is added at the exact moment the consumable is dissolved, so it makes it difficult to tell where the money came from lol
I think that seems fine
Send the destruction in a function through func = function
card:start_dissolve()
end``` like this?
card.ability.extra.remaining = card.ability.extra.remaining - 1
card_eval_status_text(card, "extra", nil, nil, nil, {
message = "Depleted!"
})
ease_dollars(1)
func = function()
card:start_dissolve()
end
end``` is the entire thing with the context check
Probably needs to be in an event inside the function too
Idk if its the lack of sleep but i cant even look at this
Its all just
Mush
Like my brain
sleep
are you familiar with LUA?
Wait no where’s the return table gone
you cant use that for consumables I thought, I tried a bunch of things with that and it wouldnt dissolve/destroy the consumable
Ive tried a few times, i lost my apartment so the stress probably keeping me up rn
Not even 2 melatonin knocked me out o.o
Ill hit a wall eventually tho so im not worried


Hopefully when i move back home ill have a bit more freetime so i can start working out again, and work on a balatro mod
Ik this mod idea is a hit
do you know which contexts it works in that would be relevant to consumables?
Either way ik ill enjoy it
It wouldn’t be relevant to consumables which is why you need the function
I'm having a weird problem. Trying to space two strings on a button, and with a Row/Column setup the text keeps shrinking:
how do you add chips and mult, when scoring a joker?
I'd look into two simple jokers that do that. I'm pretty sure you return a table with "chips" or "mult". If you return both, it should add both.
maybe your padding is too big?
which jokers do that?
none of the vanilla jokers add chips and mult when being scored
Walkie Talkie's method didn't work
The joker adds the chips and mult yea?
Scholar is the easiest one. Here's his bit of code:
if self.ability.name == 'Scholar' and
context.other_card:get_id() == 14 then
return {
chips = self.ability.extra.chips,
mult = self.ability.extra.mult,
card = self
}
end
That's inside function Card:calculate_joker(context)
if context.joker_main then
return {
chips = X,
mult = Y
}
end```
I got my thing working... it feels janky, but looks great lol
ignore the -2 dollars when I play a hand, its part of the custom deck im using to test things easier, if I dont play a straight, I lose 2 dollars 
Found out that my scaling is dropping every few frames by 4%
Anyone got any ideas why scale is changing randomly?
Not without seeing any code
Haven't touched the UI.ua code besides looing into a debug print. Here's the UI table:
n = G.UIT.R,
config = { id = 'enter_shop_button', align = "cm", colour = shop_color, minh = 0.6, minw = 2.7, outline = 1, outline_colour = darken(shop_color,0.3),
padding = 0.07, r = 0.1, shadow = true, hover = true, one_press = true, func = 'can_enter_shop', button = 'enter_shop', maxw = 2.7 },
nodes = {
{
n = G.UIT.C,
config = { align = "cm", minw = 1.3, minh = 0.5, outline = 1, outline_colour = G.C.L_BLACK },
nodes = {
{ n = G.UIT.T, config = { text = open_text, scale = 0.45, colour = G.C.UI.TEXT_LIGHT, shadow = true, minh = 0.5, outline = 1, outline_colour = G.C.L_BLACK } }
}},
{ n = G.UIT.C, config = { colour = G.C.UI.TEXT_DARK, outline = 1, outline_colour = G.C.L_BLACK } },
{
n = G.UIT.C,
config = { align = "cm", minw = 1.3, minh = 0.5, outline = 1, outline_colour = G.C.L_BLACK },
nodes = {
{ n = G.UIT.T, config = { text = cost_text, scale = 0.45, colour = G.C.UI.TEXT_LIGHT, shadow = true, minh = 0.5, outline = 1, outline_colour = G.C.L_BLACK } }
}},
}
The text keeps getting smaller, XD
Ignore the -2 dollars when I play a hand, its part of the custom deck im using to test things easier, if I dont play a straight, I lose 2 dollars 
I think this works nicely calculate = function(self, card, context) if context.before and card.ability.extra.remaining > 0 then card.ability.extra.remaining = card.ability.extra.remaining - 1 return{ dollars = 1, focus = card, card = card, } end if context.end_of_round and context.individual and card.ability.extra.remaining == 0 and card.ability.extra.destroyed == false then card.ability.extra.destroyed = true SMODS.eval_this(card, {message="Depleted!"}) card:start_dissolve() end end
message = "Depleted!"
})``` this instead?
I dont need it to calculate at all though, just needs to display the message
Thank you 😭
yes ofc
i saw that and i was like
thats gotta be in the vanilla game
it matches so well
Hey eremel, quick question: do you know what's the color used for face down cards in the deck? I think it's an orange but which orange
audghjdfvsjk 🥺
I guess my question is, whats the difference in the 2 functions?
Think I found the infinite shrink recursion. If the container is having to be shrunk, it'll keep getting the shrink applied every update frame.
where did you call the shrink to happen?
I didn't. It's in the basic shrink ui code
ahh
if v.config and v.config.scale then v.config.scale = v.config.scale*fac end
It'll keep applying that everytime fac isn't 1.0, and it's set based on maxw or maxh
AH! If you set your minh/minw too high and it's too large for the parent container, it'll keep trying to shrink the child container, and it'll only shrink the contents of the child
I would guess at attention
so I wanna try adding this card to the yuigioh card mod
is it possible to lower the game blind limit
in middle of a match?
was gonna do something where u could discard a card to lower the blind by like 100 or something
I think so yeah
G.GAME.blind.chips = math.floor([your number])
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)```
this worked for me
i'm guess I need to do something with math.floor?
ok
is the you number how much to subtract or
it assigns a new value
ok
Guess i'll look and see how the big blind boss does it's colculation
and see if I can fiddle with that to
I need something based on how manay discards u do
Or do you think it would be better for deleting a joker card for 1000 offf a blind
🤔
if you’re going to take an amount off of the blind, do it multiplicatively
I have a Joker that reduces the Blind requirement per score of a card.
You think should go with the original design of destiny board
or use the censored final message
this doesn't work, it displays a blank message and does nothing
will try _mod
working slightly better, but not really.
it adds 2 mult and shows a red blank message
code:
calculate = function(self, card, context)
if context.joker_main then
return {
chips_mod = card.ability.extra.chips,
mult_mod = card.ability.extra.mult,
}
end
end```
Which steamodded version are you dev'ing on?
Yea 😅
what would be the script for a joker to trigger something on the end of round
when u win
if context.end_of_round and not context.individual and not context.repetition then
what does your joker do?
just adds a card to the joker slot
so its ability is +1 Joker slot?
It's adding a custom joker card
ohh i see
if you want a message to be displayed, then you should follow the procedure for returning a message
if you want it to be silent, no need iirc
ok
anyone know of a mod that has a joker that makes a hand score as a different type of hand. for example a pair is actually scored as a 3oak.
tryna figure it out but am failing so would like to look at someones working code for it
if context.end_of_round and not context.individual and not context.repetition then
SMODS.add_card { set = 'Joker', key_append = 'Spirit_E' }
card:start_materialize()
end
})```
should I use calculation
(you forgot context in your param)
perfect. I can write code in such a way that which variable is affected, is itself a variable. Making my plans compatible with other mods.
Does anyone know why my game gets really laggy when I tab out? The only thing I added is custom sprite for undiscovered cards with lovely patches
After testing a bit, this patch seems to be the issue
# Set Alignment undiscovered soul sprite
[[patches]]
[patches.pattern]
target = "card.lua"
pattern = '''
local shared_sprite = (self.ability.set == 'Edition' or self.ability.set == 'Joker') and G.shared_undiscovered_joker or G.shared_undiscovered_tarot
'''
position = "after"
payload = '''
if self.config.center.set == 'Alignment' then
shared_sprite = Sprite(0, 0, self.T.w, self.T.h, G.ASSET_ATLAS[self.config.center.atlas or self.config.center.set],
(self.config.center.undisc_soul_pos))
end
'''
match_indent = true```
thoughts?
-# and no its not debugplus' performance logging thing
?
calculate = function(self, card, context)
oh
SMODS.add_card { set = 'Joker', key_append = 'Spirit_E' } created a radom card?
instead of the card I had set
Yes
?
If you want a specific joker you need to add a key field
SMODS.add_card { set = 'Joker', key = 'Spirit_E' }
also is there away to set this to do it only once?
or some ducktape work around to make it not do it again for another 9999999 rounds
Having some trouble with SMODS.add_card()
What are the proper arguments to use with it? I keep getting an error attempt to index local 'area' [a nil value], either 'area' or 'center' throws that error. i have no idea what i'm doing
SMODS.add_card{key = "j_prefix_myjoker"}
add set = 'Joker'
It can guess the area trough its set
does taking ownership of jokers affect how they spawn for a given seed? I'm trying to modify the text of a joker that appears in the ante 2 shop for a given seed (greedy joker), but whenever I do that using take_ownership a different joker spawns, and if I take ownership of that one instead, I get greedy joker
add a config value like activated = false check if activated is false and if it is, create the card and set activated to true. If you want that card created once trough all copy of that joker you'll have to use a G.GAME variable
The add_card lines I'm using:
local slotmaster_card = SMODS.add_card({
set = "Joker",
key = "slotmaster",
legendary = false,
rarity = 3,
skip_materialize = true,
soulable = true,
})
The errors I'm getting:
(3) Lua global 'create_card' at file 'functions/common_events.lua:2213'
Local variables:
_type = string: "Joker"
area = nil
legendary = boolean: false
_rarity = number: 3
skip_materialize = boolean: true
soulable = boolean: true
forced_key = string: "slotmaster"
key_append = nil
area = nil
center = nil
(*temporary) = table: 0x08ead728 {j_mime:table: 0x08eb36e0, j_sdm_magic_hands:table: 0x08d81300, j_ring_master:table: 0x08ec3e48 (more...)}
(*temporary) = number: 15
(*temporary) = table: 0x08819590 {handle:function: 0x087ee168, __index:table: 0x08819590, init:function: 0x0881a3f8 (more...)}
(*temporary) = table: 0x08819590 {handle:function: 0x087ee168, __index:table: 0x08819590, init:function: 0x0881a3f8 (more...)}
(*temporary) = boolean: true
(*temporary) = table: 0x08a0d700 {ref_table:table: 0x088f9c80, blockable:false, trigger:ease, func:function: 0x08f2f660 (more...)}
(*temporary) = number: 14.2582
(*temporary) = string: "TOTAL"
(*temporary) = string: "contrast"
(*temporary) = table: 0x08819590 {handle:function: 0x087ee168, __index:table: 0x08819590, init:function: 0x0881a3f8 (more...)}
(*temporary) = boolean: true
(*temporary) = table: 0x08c15288 {ref_table:table: 0x088f9db0, blockable:false, trigger:ease, func:function: 0x090bde18 (more...)}
(*temporary) = number: 14.2582
(*temporary) = string: "attempt to index local 'center' (a nil value)"
Your key is missing j + your_mod_prefix at the beginning
should be like j_modprefix_jokerkey
alright. let me dig around. I don't know if I set my prefix properly or what's going on.
local slotmaster_card = SMODS.add_card({
set = "Joker",
key = "j_dexp_slotmaster",
legendary = false,
rarity = 3,
skip_materialize = true,
soulable = true,
})
Did you make a header/metadata json file in your mod?
yeah, but the joker definition doesn't have a prefix config'd
Ooh you could check if next(SMODS.find_card('j_modprefix_jokerkey')) is true and if not create the card then, it's easier this way
oh
Didn't know I could do that
If say, "E" is sold, would "D" be able to recreate a "E" or not?
I haven't gotten that far yet
Ah ok
Is there a way to conditionally load a lovely patch if a specified mod is present?
Idk, you could ask here https://discord.com/channels/1116389027176787968/1214591552903716954
Thanks 👍
I believe that's not possible, but you could do it the other way around?
using next(SMODS.find_mod("mod")) then*
next(SMODS.find_mod("mod"))
does it make any difference in add_card if I'm using smods-old-calc or the newest version?
I don't know how old add_card is, I've just been using it recently in new calc
what more does this function add
add_card wasn't changed in new calc iirc
it accounts for disabled mods and provides
then I must be doing something wrong, still... hmm
Here's my full add_card code:
local find_slotmaster = SMODS.find_card('j_dexp_slotmaster')
if find_slotmaster then
print("[DEBUG] Found Slotmaster!")
local slotmaster_card = SMODS.add_card({
set = "Joker",
key = "j_dexp_slotmaster",
legendary = false,
rarity = 3,
skip_materialize = true,
soulable = true,
})
else
print("[DEBUG] Couldn't find slotmaster")
end
it prints the "Found Slotmaster", so it's definitely "j_dexp_slotmaster" key, so I'm not sure what's throwing the attempt to index local 'area' [a nil value] error
So I wanted to access a glass card's xmult like the Hiker joker but...
(See the screenshot from game.lua)
Does this mean that instead of
context.other_card.ability.extra.Xmult = context.other_card.ability.extra.Xmult + card.ability.extra.card_Xmult_mod
I'll need to use
context.other_card.ability.Xmult = context.other_card.ability.Xmult + card.ability.extra.card_Xmult_mod ?
does take_ownership change the key of a joker?
only if you explicitly change the key yourself
it's actually context.other_card.ability.x_mult
yes that's a thunkism
thanks, I'm trying to understand how take_ownership affects seeded runs
trying to change some text on a base game joker but it seems to stop it appearing where it should
so something like this if context.end_of_round and not context.individual and not context.repetition then SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_E' } next(SMODS.find_card('j_tcgyugi_Spirit_E')) SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_A' } card:start_materialize() end
or do I have it backwards
or wold I have to use a elseif
Your card will add E for sure and then if it finds E (which it will) it will add A
Not sure thats what you're trying to go for
Btw the next(SMODS.find_card('j_tcgyugi_Spirit_E')) bit needs to be an if check
Nutshell if previous card exists don't create that one create the next one
looking at the code that checks for if the exodia cards exists
SMODS.find_card('j_tcgyugi_Spirit_E') = 0 then
would it be something like this?
either if not next(SMODS.find_card('...')) then or if #SMODS.find_card('...') == 0 then works
something ate my #
now it's correct
if context.end_of_round and not context.individual and not context.repetition then
#SMODS.find_card('j_tcgyugi_Spirit_E') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_E' }
return
elseif
#SMODS.find_card('j_tcgyugi_Spirit_A') == 0 then
SMODS.add_card { set = 'Joker', key == 'j_tcgyugi_Spirit_A' }
return
elseif
#SMODS.find_card('j_tcgyugi_Spirit_T') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_T' }
return
elseif
#SMODS.find_card('j_tcgyugi_Spirit_H') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_H' }
return
end
end```
so would this work
or should I remove the returns
would anyone know how to display the current mult just like the Stone Joker would for jokers like these (live updating every time your deck updates)
that looks like you need to start learning how to code in lua
Damn like who asked u?
give it it a shot see what happens
people are trying to help you out but it doesn't seem like you understand what they're telling you
doesn't help when ur being condescending and going "just learn it" 
bump
I was trying to give each card its own undiscovered sprite and soul sprite, but it keeps lagging like that for some reason
-# I guess I'll ask Aure later
FINALLY got this to work 😄
Huge thanks to everyone who helped!
Guys, any help on how to count the cards in the deck and keep track? i want to make a joker work based on how many card of each suit i have. for example to give xmult if i have more hearts in my deck, etc
@frosty dock thx it worked
if context.end_of_round and not context.individual and not context.repetition then
if #SMODS.find_card('j_tcgyugi_Spirit_E') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_E' }
elseif
#SMODS.find_card('j_tcgyugi_Spirit_A') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_A' }
elseif
#SMODS.find_card('j_tcgyugi_Spirit_T') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_T' }
elseif
#SMODS.find_card('j_tcgyugi_Spirit_H') == 0 then
SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_H' }
end
end
end```
ducktape and glue works everytime

EATH
Just need to add in the insta win code from the exodia one and it's basically done
which is just basically a copy paste job
btw what's the code again to detect if there is not enough room for joker slots lol
this is just broken lol
Y’know what. Gonna do a poll for #1318248620125851749 after seeing this and the MTG one. Complete the trifecta possibly
debugplus has an instawin button btw
Yeah sorry, that wasn't very nice of me.
I've just seen this before where people come in with questions and others respond with helpful answers but because they're not familiar with Lua as a language or programming as a whole they don't know how to apply the knowledge they've been given.
I recommend taking a look at e.g.
- https://ebens.me/posts/lua-for-programmers-part-1/
- https://www.lua.org/pil/contents.html
or googling "learn to program in lua" and finding a guide/tutorial that works for you
It's good dude
I've been in a lot of modding groups and the attitude of just learn it doesn't really help ppl
It scares ppl off because they think coding is diffcult in scary when it really isn't it's like putting a puzzle together sometimes ppl just don't see the piece that's missing
it's ugly but it works haha
the ways of programming
lol I'd make that shorter for sure if it were my code
It's fine it's just a meme mod anyways
doubtful this will be the next cryptic mod everyone plays
mostly that's just me hating boilerplate code
it'll just be a nother haha funni then they delete it mod
so eh
next question, on a joker what context.* do I use to detect when a boss has been defeated?
if context.end_of_round and context.boss then ?
wondering if I should change my context to boss instead of round
just to nerf the insta win
🤔
if context.end_of_round and context.main_eval and G.GAME.blind.boss then
aure sorry if I keep asking you but do you possibly know why it does that
you are making a new Sprite every frame!
don't!
that looks like you're making extra sprites that aren't being cleaned up
me silently stealing this

@frosty dock one last thing what's the line to check for if there's not enough joker slots
if you want your code to be long do this instead
if context.end_of_round and not context.repetition and not context.individual and G.GAME.blind.boss then
should probably add that in to

Is there a way i can change the colors of the suit names in joker descriptions, for example ancient joker, through a texture pack?
if #G.jokers.cards + (G.GAME.joker_buffer or 0) >= G.jokers.config.card_limit then iirc
I understand, but I've also seen people in here whose questions eventually boil down to "code this for me", just spread out over 15 different questions
And sometimes people are willing to help with teaching Lua from scratch, but sometimes it's imo better to tell them they should learn the language itself first
do I need to put it in as another if statement with another then since I already have one with the if context?
I need to come up with a way to break that check specifically ngl
if that's how you write code, sure
but you can combine it into the existing if statement with another and
i'm just asking becuase lol calculate = function(self, card, context) if context.end_of_round and context.main_eval and G.GAME.blind.boss then if #G.jokers.cards + (G.GAME.joker_buffer or 0) >= G.jokers.config.card_limit then if #SMODS.find_card('j_tcgyugi_Spirit_E') == 0 then SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_E' } elseif #SMODS.find_card('j_tcgyugi_Spirit_A') == 0 then SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_A' } elseif #SMODS.find_card('j_tcgyugi_Spirit_T') == 0 then SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_T' } elseif #SMODS.find_card('j_tcgyugi_Spirit_H') == 0 then SMODS.add_card { set = 'Joker', key = 'j_tcgyugi_Spirit_H' } end end end
ok
so I can just do something like if context.end_of_round and context.main_eval and G.GAME.blind.boss and #G.jokers.cards + (G.GAME.joker_buffer or 0) >= G.jokers.config.card_limit then
yeah
running low on glue but ducktape is king
meh
if you wanna get to being able to make things by yourself, learning it proper is usually better for that
I've learned a bit from you helping me sometimes takes a second to stick
fair
Hola not sure if this is the right spot but I'm wondering if anyone can gauge the balance on this for me
I don't think it seems broken but I also am not sure if it seems useful either
hm
Not even in Checkered?
you'll never get a lot of mult out of it
but the extra discards are a good tool
it's fairly situational, which makes for a good rare
checkered is a weird deck. a lot of jokers that arent normally great are amazing like the castle
I'd consider increasing the mult probably
it'll be easy to activate but idk like 5 hands discarded (albeit for free) to get to 2x seems like a lot of work.
I mean HtR is 0.5 for a single card
I feel like that's more reasonable of a value for a rare
I did think that initially, but it does also offer the refunded discard but not sure how much that's worth Xmult-wise
i would almost go .75 like the glass joker if you dont refund the discard. the checkered deck is about the only deck that could really abuse this but it makes for an ambitious deck building goal like Flower Pot and Drivers License
it resets each round
and this also resets at end of round
.5x
It'll print "A BLIND WAS SKIPPED" but not "A BOSS WAS DEFEATED". I don't think that context is detecting the boss blind defeat.
calculate = function(self, card, context)
if context.end_of_round and context.main_eval and G.GAME.blind.boss then
print("[INFO] A BOSS WAS DEFEATED!")
elseif context.skip_blind then
print("[INFO] A BLIND WAS SKIPPED!")
else
-- print("[INFO] Waiting...")
end
end
X0.5 with refund or X0.75 without refund
...are you sure you're defeating blinds and not skipping them
The end of the day if you discard 5 flushes to get 2.5x that’s 25 cards out of your deck, potentially 16 if you have the 4 finger joker
oh wait refund the discard
also it should be "contains a flush" because what if you accidentally discard a straight flush or flush house or thats your build
I want it to trigger differently when a Small or Big is skipped than when a boss is defeated. it's a high risk high reward kind of joker.
i read that as discarded cards go back to hand
No. So you are still limited to how many cards you have in your deck
that would have made it infinite right
good point, I do have it working that way in the code already
this doesn't seem to work
game doesn't crash
oh lol
this only works when your slots are full
so I got it backwards
change >= to <
LOL
Have been messing around with this for a while and can't figure it out. What I want is to be able to modify the text on a base joker and have it show up in the shop as it would have done unmodified. When I set a seed, the expected joker does not show up if I have used take_ownership.
Essentially, I'd like to be able to guarantee that a number of modified jokers turn up in shop 1, shop 2, etc. I'm using a set seed so I know which should show up, but it deviates from the expected sequence when I take ownership, even if I don't do any changes to them. Any ideas on how I could achieve this?
the winning a boss blind doesn't seem to be working
not even sure it it was the <=
🤔
I'm having the same problem.
if context.end_of_round and context.main_eval and G.GAME.blind.boss then doesn't seem to work
i'm gonna dig into the vanilla game
what smods version?
i'm using whatever the latest -old-calc is
unless there's been a big update
what I've said is specific to new calc
ah, makes sense
1315b is like 2 weeks old, I think main_eval was added after that
yeah in fact you're one version off from when I added main_eval
imagine not developing on latest 💀
just learn git (updating is just typing two words in terminal)
I know but still too lazy
I read this and thought -old-calc would be the way to go, but apparently not
Regular users stands for "people that don't develop mods"
why using git when you have github desktop (press one button instead of typing two words)
Also I should remove that note
makes sense. I'll update and try again.
because I hate myself
i just started modding

bah. it's early enough in the dev of my deck/joker mod that it wont be painful to switch
um how would i go about changing the hand selection size
like how many playing cards you can select
ok so i am trying to port my mod to new calc
change G.hand.config.highlighted_limit I think
do you have a hook on eval_card?
oh riught
it has two return values now
oh
yup that was it
updated my smod and it worked

everything functions
well bed time
well it would work if it werent for the fact that i cant play the hand
can i make joker changing music?
select_music_track = function()
return next(SMODS.find_card("your joker key here"))
end,
put this in the smods for your music file
right that's a thing that exists
fuck i pressed enter too early
HUZZAH!
thanks for the kick in the pants
note: you might want to give it a priority value. just returning it like this will have or overwritten by most other sources of music changing
return next(...) and 100 or nil
okay woo I solved my problem in the ugliest way possible (it doesn't matter too much, this mod is for me only). If I just take ownership of every joker in order, then it seems to preserve things.
I don't recall what function you need to hook, but cryptid does something like that
that's... concerning
taking ownership shouldn't change the order
is there a joker template? ie - what font is used, what is the aspect ratio size of joker cards?
the size is 71x95 including a 1px border on each side
I think the font is somewhere in the modding forum, idr where
the game font is 6x11m (im pretty sure)
however as far as i know there isnt a font for the joker text
yeah there's not an "official" font for the joker text but I'm pretty sure someone made one
from my testing that seemed to be the case. So for instance on seed "4QS4EVER", shop before ante 2 should give greedy joker. If you take ownership of greedy, you get lustful instead.
if you keep telling people to use 100 prio ill need to change mine to 1.8e308
ok I'll use 99
thank you
also, if I take ownership of every joker in order, but greedy is first instead of 2nd, that shop will spawn Joker instead
yeah that doesn't seem right. I'll investigate
WOW lmfaooo
sob i cant find this 😭
all i can find is this which isnt that helpful if i dont even knoww where it defined
Is it possible to get a video file like an ogv or avi to play within balatro
I got an idea I wanna try out
ask love2d
Reading Cryptid code sounds like a recipe for disaster
Is this the correct way to get the atlas?
It keeps crashing
yeah someone made Balatro play an episode of family guy recently
its like a bowl of spaghetti if the spaghetti was somehow more tangled than regular spaghetti
Lmfao
Can u link it
I gotta see it
uh I don't think they published it
It's fine I just want to see it lol
I have the code for playing the video somewhere though
I was gonna add to the instant win condition cards
Where just plays a video file of the cards winning animation from a gane
Try to send it back to main menu
After the video is over
function create_UIBox_custom_video()
local episode = pseudorandom('familyguy', 1, 7)
local file_path = SMODS.Mods["Buddy"].path..("/resources/episode%s.ogv"):format(episode)
local file = NFS.read(file_path)
love.filesystem.write("temp.ogv", file)
local video_file = love.graphics.newVideo('temp.ogv')
local vid_sprite = Sprite(0,0,11*16/9,11,G.ASSET_ATLAS["ui_"..(G.SETTINGS.colourblind_option and 2 or 1)], {x=0, y=0})
video_file:getSource():setVolume(G.SETTINGS.SOUND.volume*G.SETTINGS.SOUND.game_sounds_volume/(100*100))
vid_sprite.video = video_file
video_file:play()
local t = create_UIBox_generic_options({ back_delay = ({73,whatever})[episode], back_label = localize('b_skip'), colour = G.C.BLACK, padding = 0, contents = {
{n=G.UIT.O, config={object = vid_sprite}},
}})
return t
end
Even debugging peoples code where they’ve based it off cryptid is a pain, it’s written so unintuitively imo
im gonna die from all of this code searching 😭
yes the whatever is a placeholder
has anybody else ever made something related to playing more than 5 cards
The wordle mod does
well funny thing idk what thats called
You mean Aikoyori's Shenanigans?
it's G.FUNCS.can_play
I don’t know what it’s called either 😂
Reminds me of the era when everyone based their mod on Mika's mod, making one of their joker crash 😂
it's very possible that I am misunderstanding the mechanics of why it is happening, but that is definitely the outcome
thank you blind person
blind person playing balatro?
is that a Black Hole mod reference??
-# Ok I get it, Im totally getting ignored lol
nevermind it didnt work goddamit
That's for using "bruh" twice on me today
vrej
fuck you blind person
Wow
wowwwww
jk
Make black hole mod but for people who can see
white hole lmao
Only after we add the alt f4 quick restart keybind
that's how I test black hole
fr
lol
actually I just turn my monitor off smh
Why don't you just stab your own eyes?
because I don't hate myself that much
mf playin inscryption
are you 100% sure
100#
100#
I'm choking stop
def not me reaching to the wrong side of my keyboard
imagine having to reach for any keys
sob
I'm just typing with brooms from my bed smh it's easy
anyways please guys i need mental health help
then go to #mental-health-help
-# what do you mean that doesn't exist
-# okay okay go ahead
No more SMODS...
I’m not actually sure. What’s your mod prefix?
hmm so im pretty sure this is not it
😭
actually how is it not it
cs_
alas i did not know that was a function please forgive me
gets exploded
I tried with and without but it keeps crashing
okay you can stop pinging me now
ok
myst may I ask for your assistance
I tried making the sprite outside of that function but im stuck with getting the atlas
It says atlas is nil
what color is the random chance text (i.e. the 1 in 2 chance text for jokers)?
green
Wait, did you set your prefix to “cs_”
iunno
Ok good
Why can’t you use the standard undiscovered sprite in smods?
my cards arent exactly rectangle shaped so I made a custom undiscovered sprite for them
That’s what SMODS.UndiscoveredSprite is for
the floating question mark is also placed incorrectly so I have to replace it
I did try that but it doesnt seem to work for custom centers
How so?
because the check for undiscoveredSprite is placed inside an if that checks for specific centers
but however, what's the correct way?
im stuck there ç-ç
Looks like it allows any centers to me?
it does?
From what I can see on mobile yeah
It goes to the default one
i know, but like what's the {C:} code for that
...green
That is a custom sprite…?
You mean the question mark?
yes
That’s not what the undiscovered sprite is
not even no_overlay?
You can turn it off by setting no_overlay = true, I don’t think there’s functionality for a custom one right now
What expression should I put in there?
I see, and is this not possible either?
What is this code trying to do?
The one you linked
Revive the shattered glass cards, even though not the case
Long story short, I made it work earlier but I was creating the sprites inside the function which apparently kept creating sprites
So I had to make the sprites outside somewhere else, for which I need to get my atlas
But it keeps crashing
The question mark?
the floating question mark yes
I can just patch smods later today to let you control it easier if you prefer?
that would be neat
oh
how are you planning to do that
i think i do card instead?
It’s just be a property on the undiscovered sprite,
There’ll be other contexts that have individual = true`
Actually maybe not
Why is other card nil? 🤔
why is the card null
# Set Alignment undiscovered sprite
[[patches]]
[patches.pattern]
target = "card.lua"
pattern = '''
elseif self.config.center.consumeable and self.config.center.demo then
self.children.center = Sprite(self.T.x, self.T.y, self.T.w, self.T.h, G.ASSET_ATLAS["Tarot"], G.c_locked.pos)
'''
position = "after"
payload = '''
elseif not self.params.bypass_discovery_center and _center.set == 'Alignment' and not _center.discovered then
self.children.center = Sprite(self.T.x, self.T.y, self.T.w, self.T.h, G.ASSET_ATLAS[_center.atlas or _center.set],
(_center.set == 'Alignment' and _center.undisc_pos))
'''
match_indent = true```
For the undiscovered sprite I've used this lovely patch, since in the dump code the sprite is only set after it checks for specific centers
Same goes for undiscovered description
lmk if I got it wrong
this is what its supposed to look like
(i know it darkens in the game)
((im just talkjing about how not crisp the texture is))
(is there another way to make a 2x export easily???)

i require... balancing assistance. this generates a bit much planet cards
flower pot treatment
no but srsly why is other_card null
how much flower pot do i need
does anyone know how to use has_enhancement? im trying to count how many wild cards are in the deck like stone or steel
ok it looks a little better
maybe remove the first part entirely
@frosty dock mr smods why is the other card null sometimes
how do I add my own rules text right here?
one effect is LAME
I've been trying for a bit now
and BORING
and balanced
altho im not sure what youre going to do with eternal rental spectral cards, isnt that a downside?
chat do they know
no lol
everything in lobcorp has a downside lol
I see no upsides in that card tho
are you supposed to get it while eternal so your consumable area is doomed
ah ok understandable
I slept a bit :^)
welcome back
Hai myst, i see your still busy
Oh chat its over
I have a lot of stuff to do today but as soon as im done im gonna start working on my epic chess themed mod
yippee!
also how would I change jimbo to have another sprite/be another Joker? cause I have a Joker in my mod that's going to be pretty similar to Jimbo's ability and I don't want him appearing all the time in my shops
1 in 3 chance of creating planet card then
how can I check if the flames are showing?
if current hand score is more than requirement 😭
Love your pfp 
thankies
how do I get the requirement?
also, would it still work at the end of round?
no clue if you don't show me your context checks
Did this crash?
It’s because of the event
ah right
You’ve destroyed the card in the bottom check
So by the time the event fires the card has already gone
I think
hi chat, im trying to make a joker that copies glass cards when they break, im at a bit of a loss though, i've tried looking at Glass joker's code but didnt get anywhere, and here i've just tossed DNA's code into context.glass_shattered which expectedly didnt work, any ideas how to make it work
if context.glass_shattered then
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
local _card = copy_card(context.full_hand[1], nil, nil, G.playing_card)
_card:add_to_deck()
G.deck.config.card_limit = G.deck.config.card_limit + 1
table.insert(G.playing_cards, _card)
G.hand:emplace(_card)
_card.states.visible = nil
G.E_MANAGER:add_event(Event({
func = function()
_card:start_materialize()
return true
end
}))
return {
message = localize('k_copied_ex'),
colour = G.C.CHIPS,
card = self,
playing_cards_created = {true}
}
end
end```
not even this works sob
I dont think I can even add my atlas with lovely patches since files are loaded with smods ç_ç
-# will be waiting for an update
I GOT HERE FIRST
SCREW YOU SKY
couldnt tell you why its mad at me
how do i destroy card after the hand finishes scoring
hey everyone! sorry for bothering, I am very new in modding stuff but I would really like to learn how to, does anyone know a good tutorial or a way to learn how to mod balatro?
context.destroying_card
https://github.com/steamodded/smods/wiki start here
so like this?
you can ask here if you have any questions
thank you a lot!
yeah seems alright
😭
guys can you help i need the bowling rail guards why doesnt this work :(
i figured out why SMODS.add_card wasnt creating a card... it was, but the card was invisible cause i fucked up the pos, lol
genuinely seems like such an insane mod
that looks so fucking cool
How do you access and change variables in the global variables script?
For example if you wanted to change the colour of the small blind or a card suit.
guys i am fixing bug
how would I get the chips and mult after each card and joker is evaluated?
i know that this is definitely possible i just forgot how:
how do i check how much a hand scored?
and what the current blind is?
and how much you currently have to the current blind?
basically i wanna check if a played hand beats the blind or not
only the played hand without the additional joker calculations?
i guess with them
then idk
I'm also trying to find that out
I just know how to do it without the joker calculations
me and joe are making a joker that gives you money if after all the joker calculations, you get more score than the blind requirement
and we know how to check for it, just not how to check after all the calculations
do you know how to check for the blind?
yeah, this i believe
G.GAME.blind.chips is the amount of the blind then
yeah
are you sure this doesnt work? would this not account for all the jokers
like have you tested it
it does work, but it triggers before the cards are even scored, probably because its in "if context.joker_main then"
yeah, when it gets to that joker
so this code is fine
it just has to trigger after the calculations
Delete your dissolve line
like is there another context.something that triggers after the calculations but before context.end_of_round
preferable a context.after_hand or whatever
yeah
'context.after' ?
i tried that, it just doesnt trigger
What do I use to have a joker destroy another random joker currently in play?
Check "Ceremonial Dagger" code
What your Joker does exactly?
if context.after and context.main_eval and hand_chips * mult > G.GAME.blind.chips then should be what you’re looking for
would this work for a seal ?
thats how my seal triggers as well
but i dont know if this translates 1 to 1
also, for the seal, would i put that in calculate?
What does the seal do?
it gives $10 at the end of round if the burning effect is triggered (if score of hand > than blind requirements)
x2 mult (have that), if the played hand doesnt beat the blind, it has a 1 in 2 chance to break
Wait hang on why did I put end of round, should be context.after 🤣
So not if it one shots, just if it beats generally?
fellas i need help
i just want to check if a card is played but not scored and it wont do the thing 😭
Yeah I’d just need to check some code before writing the check, give me a few minutes
😭
Have you added this unscored context?
anyway how do i set ability one by one
Its more complex than that, check the Tsunami mod, it has plenty of effect with unscored cards
right, sounds good
Use the delay sprites argument
i mostly took this from the green seal from cryptid
context.unscored isn’t a thing unless you’ve added it
why did iset that to null lmao
But generally, cards that are played and unscored don’t have any calculations thrown at them
(how would one do that.............)
well i guess i can see how cryptid added that context
because that would be incredibly useful to have in our dev
we have a buncha stuff with unscoring
This is a seal right?
yea
ill check on this
I’m not sure there’s a clean way to calculate unscored cards
thank
Card:destroy()
context.destroying_card = card
so like
Card:destroy(card)
?
its a sigil
or
seal
sorry
okay depends
first of all not this ever
LOL ok
technically you can do Card.destroy(card) but card:destroy() is the exact same thing
mhm
so would it JUST be that
like is there any other things i need to add for a seal ?
if you're doing it in a calculation there's a context that checks for that, you just return true when you want the card to be destroyed
if pseudorandom('overclocked') < G.GAME.probabilities.normal / self.config.odds then
card:destroy()
end
end```
this is in calculate
im honestly not sure if the IF statement works
so im using this to check if it does
don't straight up call card:destroy()
i imagined not lol, sorry im new to most of this
that just immediately vanishes the card out of existence
i see
yeah that's okay
if it's in context.after you need to do something a bit more complicated
oh wait
nvm you can just do card:start_dissolve()
like above card:destroy? or replacing it
tsunami is the one that fuses splash with everything right? i cant find any code for unscoring cards
replacing
kk!
is there actually no way to check if a card is unscoring 
ok how do i do the same with dissolve card
Ask the mod author
if context.after and context.cardarea == G.play and G.GAME.chips > G.GAME.blind.chips then I believe
thank you!
god damnit
if pseudorandom('overclocked') < G.GAME.probabilities.normal / self.config.odds then
card:start_dissolve()
end
end```
didnt break
this was in calculate, which may be a problem?
oh its destroying, hold on
oh lol?
G.GAME is nil when you're in the main menu

I just have it on the first indent, so I need to wait for the "game" to start before I can change things?
yeah
is there a way to change the values that the game uses though
also indent doesn't matter so im going to assume you mean the outermost scope
what specifically are you looking to change
everything can be changed
blind colours
all colour info is inside G.C somewhere
you can change specific colours fairly easily with https://discord.com/channels/1116389027176787968/1248865517112918016
how do i delay this
I would like to find out how to change it directly. Can you do it with localization?
I can see the first message in that thread is returning a large table of colour values. Is that something I can do?
delay(time)
before the line
i give up, i have no way how to check if a card is played but not scored
@dusk shoal
hi
if context.destroying_card and (hand_chips * mult) + G.GAME.chips > G.GAME.blind.chips then and do return { remove = true }
@dusk shoal
!
looks like G.C.BLIND has all of them
you can change those directly (e.g. G.C.BLIND.Big = RGB(255,0,0))
unless im misreading?
you use the destroying context like I just posted
if pseudorandom('overclocked') < G.GAME.probabilities.normal / self.config.odds then
return { remove = true }
end
end```
so like this?
looks good
ah ok
not sure what you mean by RGB instead of HEX, but I will test the line
it's slightly different if its from a joker
aghk didnt destroy it
wait
do i replace return (remove = true) with card.dissolve maybe?
both exist, HEX is for hex codes, RGB is for 0-255 red-green-blue values
it might have just failed your roll
rgb throws an error, but anyway I did a hex black value, but instead of changing the small blind's colour, it changed the whole background to the black
G.C.BLIND.Small = HEX("000000")
main menu top right
ty !
of course, nearly 2 months out of date
wuh woh
blame my friend
he gave me the link
wheres the new one then ?
i can probably find it myself but
i trust you more than me
ty !
this might break some stuff you have atm because you are on old calc, not new calc
so i just delete steammodded-main?
yup
made a great challenge
if not context.repetition_only and context.cardarea == G.play then
return {
x_mult = self.config.x_mult,
}
end
if context.destroying_card and (hand_chips * mult) + G.GAME.chips > G.GAME.blind.chips then
if pseudorandom('overclocked') < G.GAME.probabilities.normal / self.config.odds then
return { remove = true }
end
end
end,```
for some reason this is not the blind's colour, but the ante's background colour 
G.C.BLIND.Small = HEX("50946e")
change not context.repetition_only to context.main_scoring
kk!
you'll also want to reference this page for all the calculation contexts
ok so its not repeating a bunch but NOW its not destroying 😭
question! is there a way for an event to stop its function and ALL subsequent events in the case of an emergency?
like a full stop?
what did you change?
if context.main_scoring and context.cardarea == G.play then
return {
x_mult = self.config.x_mult,
}
end
if context.destroying_card and (hand_chips * mult) + G.GAME.chips > G.GAME.blind.chips then
if pseudorandom('overclocked') < G.GAME.probabilities.normal / self.config.odds then
return { remove = true }
end
end
end,```
just context.main_scoring
the destruction should still work then
did you beat the blind?
nop
@violet void on newest version (1331a) add overlay_pos = {x = 0, y = 0} (uses your undiscovered atlas)
how does the game do the random misprint text
it's empty in localization
alright cool destroying works
sorry I must have misread
WOOHOO!! overclocked works
do I need to make this much code to colour the blinds?
the trance one has 579 lines, and another script aswell
I'm assuming this is the actual colouring part
--color injection
function Trance_set_globals(G, dt)
for k, v in pairs(Trance) do
if is_color(v) then
if is_color(G.C[k]) then ease_colour(G.C[k],v,dt) else G.C[k] = v end
elseif type(v) == 'table' then
if not G.C[k] then G.C[k] = {} end
for _k, _v in pairs(Trance[k]) do
if is_color(_v) then
if is_color(G.C[k][_k]) then ease_colour(G.C[k][_k],_v,dt) else G.C[k][_k] = _v end
end
end
end
end
if Trance.MULT then ease_colour(G.C.UI_MULT,Trance.MULT,dt) end
if Trance.CHIPS then ease_colour(G.C.UI_CHIPS,Trance.CHIPS,dt) end
if G.P_BLINDS then
for k, v in pairs(Trance.BOSSES) do
if G.P_BLINDS[k] and G.P_BLINDS[k].boss_colour then G.P_BLINDS[k].boss_colour = v end
end
end
end```
finding the thing to colour with the index of the colour's name from the globals variables but I don't think this is different than how I am currently finding it?
G.C.BLIND.Small
what is eff and post in eval_card
G.C.BOSSES
this is considered nil
even though the Trance mod has it listed as such
so the "C" is wrong?
[SMODS _ "src/utils.lua"]:1203: attempt to index local 'edition' (a nil value)
any idea why i'm crashing when playing a hand?
Ok I figured it out by looking more at the Trance script. You have to use this directory if you want to colour blinds. Apparently the blind boss colours are not in the globals script, and the small/big blinds are considered bosses.
G.P_BLINDS.bl_hook.boss_colour = HEX("10000e")
G.P_BLINDS.bl_small.boss_colour = HEX("10000e")
dynatext or something, it's probably in ui_definitions
nvm it's just on card.lua
is there a function i can run to update the card ui box
ive managed to get it to change every time you hover over the joker but I want it to change while you're still hovering over it
not to interrupt any conversation but i finally got this finished and im so proud of it
It returns the ret table and the post table
Dynamic Joker UI for Skyscraper and Lvl. ? Death
am I supposed to write all the code on "main.lua"? I'm sorry I'm just starting to learn how to use everything
bump
you can specify the main file and call other files from it
how so
ohhhh, thank you a lot
i'm trying to do the misprint +mult text thing and ive got it updating every time you hover over the joker but not while you're still hovering on it
i want it to update while its still being hovered
using the misprint method won't work for my purpose because I need other text in the description
misprint leaves its entire description blank in localization and i need to put other stuff there
also something like this but with a DynaText object has the same result
It's not what I did for Cow IIRC but it's probably what I'd do nowadays… maybe
😢
but i don't want it to look like that colored bubble
i just want it to have the misprint text with other text around it
That's fine
As I said you can probably just do this
but with a DynaText object somewhere inside
What I did was to add a main_end function to the return of loc_vars
Which manually creates the UI
so you can have it look like whatever
none of this makes any sense to me
Here's the relevant code from Lvl. ? Death, @stiff locust:
local misc = NFS.load(SMODS.current_mod.path .. "/misc_functions.lua")()
local _generate_main_end = function(card)
local main_end = 0
if not misc.is_in_your_collection(card) then
local handname, _ = G.FUNCS.get_poker_hand_info(G.hand.highlighted)
local backwards = false
for k, v in pairs(G.hand.highlighted) do
if v.facing == 'back' then
backwards = true
break
end
end
local active = false
if handname and handname ~= 'NULL' then
local lvl = (G.GAME.hands and G.GAME.hands[handname] and G.GAME.hands[handname].level) or nil
active = (not backwards) and (lvl and lvl % card.ability.extra.lvl_mod == 0)
end
local colour = (backwards and G.C.FILTER) or (active and G.C.GREEN) or G.C.RED
local txt = (active and localize('k_active')) or (backwards and "???") or localize('k_vic_inactive')
main_end = {
{n=G.UIT.C, config={align = "bm", padding = 0.02}, nodes={
{n=G.UIT.C, config={align = "m", colour = colour, r = 0.05, padding = 0.05}, nodes={
{n=G.UIT.T, config={text = ' '..txt..' ', colour = G.C.UI.TEXT_LIGHT, scale = 0.3, shadow = true}},
}}
}}
}
else
main_end = nil
end
return main_end
end
return {
…,
loc_vars = function(self, info_queue, card)
return {vars = {card.ability.extra.Xmult, card.ability.extra.lvl_mod}, main_end = _generate_main_end(card)}
end,
}
the important part is that the function _generate_main_end defines main_end and returns it
That's an old implementation so it could probably read better
Here's Skyscraper:
They're both more complicated since they need to check what cards the player currently has selected
Including possibly face-down cards
For you, you probably only need to directly return main_end
so how would one take ownership of a edition that doesnt have a shader?
and main_end should probably be a column with one or more rows, and each row has one or more text and/or DynaText objects
For some reason Lvl. ? Death has just column instead of a column with a row inside, but it looks fine, so
Actually, that's not quite true; if you want e.g. xMult text, you need some extra columns inside the row
Lovely has finally updated
That's why the outer column in Lvl. ? Death contains a column with text inside, instead of just text
i hate to repeat myself
you're making less sense the more you explain it
To do what you want, I reckon the easiest way is to build a main_end manually, which means you need to construct the UI manually
This part from Lvl. ? Death, for example
the easiest way right now would be to run a function that updates the joker's ui box
I mean that doesn't exist
and I think it introduces overhead every frame the game is running
Try 5L2L'ing it Marie 👍
no it's better to start with 2L then 5LL because that gives you 3 hits instead of 2 and you can't go back into 5L a second time in the same blockstring graaagh
what does that have to do with balatro
So, for example, here you'd replace the inner column node into a row, then have it contain text and/or DynaText nodes
why does my card pay rent now
Overhead in programming is similar
You'd be adding a function to the update loop which runs every frame
Yea but if they block high it can go for a quick weak mixup
that's the cost of running the game
it's not a table
well it is a table
columns and rows don't make sense to me here
nobody does that, people block fuzzy which means to block low and react to overheads because overheads are generally slower and less common than lows
from the mouth of
spoketh the 
We don't play against the same ppl ig
thus G.UIT.C is a column
why is it so hard
there's 3 different things here
the only code i've understood so far is the code where level ? death checks hand levels
and you loading a different lua file
again all you probably need is to return main_end; you probably don't need anything else
so you just need to write the tables that represent what the UI should look like
it's funny how my aikoshenanigans mod is my first balatro mod
you say that like it's so easy
I think it's easy to mentally visualize what the UI should look like
do you have a non-updating example of what the text looks like
i do
can you show your code?
["j_tsun_oil_spill"] = {
["name"] = "Oil Spill",
["text"] = {
"Every {C:attention}played card{} counts in scoring",
"{C:attention}Extra scored cards {}give {C:red}+#1#{} Mult",
"{}when scored",
"{s:0.7}{C:inactive}(Misprint + Splash){}",
},
},
the #1# is the text that randomly changes
So, you can keep the first line there
The rest would go into main_end
What you have is a column containing three rows
one row for each line of text; the column stacks them vertically
the second and third lines have a single text node each
the first line has three text nodes and one object node
IIRC
as in: text, text, object, text
First for attention color, then the normal color, then Misprint, then normal color again
so it's a new text node for each color?
yes
okay



