#💻・modding-dev
1 messages · Page 499 of 1
Yes.
No.
then....then why did judas give 30....twice...
let me do this fix for ijiraq first though
high card
current patch
I'm not sure then.

i am plagued forevermore
maybe i can fix iscariot's at least
dumbass 🥀 where tf is your func,,,
Is there a way to ban blinds for non-challenge decks? (I'm using a regular deck because not having calculate() sucks)
all i know is its possible bc deckcreator did it
this fixed it thank god
I should make a pr to break it
i should kill you
,,,ok what if i put the table insert in a func (losing it)
Hi winterrrr
Oh yeah tomatose im curious, why are your red and blue text colors made more pastel?
Put it in G.GAME.banned_keys
Do I put this in the apply function?
table.insert(G.GAME.banned_keys, 'bl_plant')
No, G.GAME.banned_keys["bl_plant"] = true
And yes, you put it in apply
do i remove this from the for loop?
Ok, sorry I was just going off of prior lua experience
No, because then it wont do anything.
what if i modify it to be the one you had me add?
What do you mean?
what if i change the if joker in here to the if jokers you had me add outside
No.

maybe scaling causes it to go through the for loop twice? so the calculate_joker is being called twice?
or it's getting called once for both joker and trig?
No, the problem is it's calling calculate_joker twice but it's only returning one.
oh so it's the inverse
OH HEY
maybe i reverse them?
no youre right that doesnt make sense
what if we call calculate_joker before the for loop?
will that work?
No.
....ok what if i take out the if jokers block altogether
Then it would insert nil if it doesn't exist.
ughhhhhhhhhhhhh
maybe a counter conditional for how many are in the jokers_table?
like a #jokers_table
Where?
after the G.GAME series
No.
did you ask where because it could work if i put it somewhere else maybe? 
No.
ok so calculate_joker is being called twice right
and extra_jokers_list is being set to copy_table(G.GAME.raqeffects)
so MAYBE the way things are being added to raqeffects is the issue?
or even the way it's being called in the calculate_joker override?
No, because then it would trigger all jokers twice.
right...
wait right?
raqeffects is only for Ijiraq's, well, effects
and all that goes in it are the transforming jokers' keys
why would all the fake jokers trigger twice if this was the issue?
what do you mean you dont know
that's what you said bro 😭
????
are we dementia today
somethingcom is always delusion
EDWARD ROBINSON??? WHAT ARE YOU DOING HERE???
somecom what exactly are you lost in
cause if it's reached the point where youre confused at a picture of your own message we are borderlining "cooked"
modding balatro clearly
Because the list of jokers would have the jokers twice so they would trigger twice.
I have the following code in one of my files:
local video = love.graphics.newVideo(mod.path .. "assets/video/video.ogv")
This successfully loads the video for me but crashes the game for my friend. I am on Mac and he is on Windows so we suspect that may be the issue but does anyone know why it isn't working/how to fix?
Edward Robinson bro…
ahhhhhhhhhhhhhhh
maybe it's calling calculate_joker once for joker and once for trig?
No.
should extra_jokers_list be an ipairs?
somethingcom give suggestions rather than simply denying stuff challenge
he literally made this patch 🥀 neither of us know why it's double scaling
🔥
🔥
does anyone know
probably computer issue
how can i make a joker retrigger other jokers?
Have you enabled it?
enabled... what, exactly?
SMODS.current_mod.optional_features = function()
return {
retrigger_joker = true,
}
end
Then you return repetitions in context.retrigger_joker_check
whats the px py for a tag atlas
34
Sorry I know I’m not a dev myself but here’s an idea for anyone who sees this. How about you make a joker just like the multiplier multiplier but instead with the same amount of jokers for points so that let’s say every king or queen in hand played gives 2x to points, I get that multiplier is for this purpose but what if bot the points and multi make it into the exponents, this at least seems interesting to me it might not to you but for anyone willing to make it please dm me.
I didnt quite catch it
So... Every king/queen played, gives 2x mult, or 2x chips or something else doubled?
Does the game automatically deep copy anything in G.GAME on save?
Okay yeah it does recursive table cull on it. I should be good
Yep yep
I don't have objects stored here so I don't gotta worry
Hmm..... is there a specific benefit to using G.GAME.modifiers over just G.GAME?
The vanilla game typically uses the former for challenges but I'm not sure if there's any real functional benefit
uhh how do i make the blind debuff multiple ranks
if context.debuff_card and (context.debuff_card:get_id() == id or context.debuff_card:get_id() == otherid) then return {debuff = true} end
thanks
...I am missing something trying to set G.GAME.chips in context.before, huh.
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blocking = false,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech),
delay = 0.5,
func = (function(t) return math.floor(t) end)
}))
G.FUNCS.chip_UI_set()
Is it possible to add an order to SMODS.score_card? so that the card added doesnt score first?
Here ill get a video of it
trying to get it so it doesnt score first because its causing issues
Code?
This sounds like an inverse of my Hyperlink Seal.
calculate = function(self, card, context)
if context.cardarea == G.hand and context.before then
SMODS.score_card(card, {cardarea = G.play, full_hand = context.full_hand, scoring_hand = context.scoring_hand, scoring_name = context.scoring_name, poker_hands = context.poker_hands})
end
end
No, remove that and put this somewhere in your file but outside the seal:
local oldsmodsscorecard = SMODS.score_card
function SMODS.score_card(card, context)
if not G.modprefix_sealkey and card:get_seal() == 'modprefix_sealkey' and context.cardarea == G.hand then
G.modprefix_sealkey = true
context.cardarea = G.play
SMODS.score_card(card, context)
context.cardarea = G.hand
G.modprefix_sealkey = nil
end
return oldsmodsscorecard(card, context)
end
It'll score at the correct time.
Thanks!
try initial scoring step
i should have asked: where do i put this?
Could put this below uses of SMODS.Atlas and such.
You can put it anywhere.
Nope.
As long as it's not in any joker definitions or anything.
If I just do G.GAME.chips = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech), then it's accounted for.
im using this code that i modified from vanilla remade hex to destroy all jokers, how would i make the jokers also give their sell value when destroyed?
ease_dollars(joker.sell_cost)
thanks
how do i set/change hand amount
as long as it's in the file i have the retriggering joker as i now know
No, it can be in any file.
Hand size or hands?
hands
it only worked when i moved the code into the file that the joker was in
ease_hands_played(number)
would this actually work?
If the == does check for a number between 1 and 10000, then yes.
how do i force a game over
Yeah that would give it a minute chance of being in the pool
G.STATE = G.STATES.GAME_OVER; G.STATE_COMPLETE = false?
As you're here, can I ask about
if context.before then
return {
message = localize('toga_leech'),
func = function()
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blocking = false,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech),
delay = 0.5,
func = (function(t) return math.floor(t) end)
}))
end
}
end
not actually having the eased chips stay put, instead being overwritten at the end? Or would I need to "ease" it first, then actually set to the desired value? 🤔
nothing happens
Are you in a blind?
Use context.initial_scoring_step
context.before is before the initial values are set so any changes you make will get removed
Changing to context.initial_scoring_step still did not help.
https://cdn.discordapp.com/attachments/1307810407389593630/1396413386568368128/man.mp4?ex=687dfecf&is=687cad4f&hm=247520eb9944dd7e768e51089c22c24a0ede689bf3800ae05222048d82314c7b& This occurs whether context.before or context.initial_scoring_step is used.
Oh
Those chips
I didn’t read fully
I’d need to check the code properly to see where it resets
This, per chance?
function ease_chips(mod)
G.E_MANAGER:add_event(Event({
trigger = 'immediate',
func = function()
local chip_UI = G.HUD:get_UIE_by_ID('chip_UI_count')
mod = mod or 0
--Ease from current chips to the new number of chips
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blockable = false,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = mod,
delay = 0.3,
func = (function(t) return math.floor(t) end)
}))
--Popup text next to the chips in UI showing number of chips gained/lost
chip_UI:juice_up()
--Play a chip sound
play_sound('chips2')
return true
end
}))
end
Any thoughts as to why this is making the money popup message say ERROR?
Why not use ease_dollars(card.ability.extra.money)?
Because a_money doesn't exist.
oh whats the money one?
No, just do dollars = card.ability.extra.money
In the return.
upd: problem fixed i dont need help with this
Do ping me whenever. ✌️
localize({type = 'name_text', set = 'Joker', key = "j_joker"}) I think.
thanks
is there an ease_discard but for hands instead
i've been searching for it for a while but couldn't find it
ease_hands_played
whats the difference between G.GAME.round_resets.ante and G.GAME.round_resets.blind_ante
Go figure
Try setting the value outside of the event too, I think that’s the reason
how can i make this but it draws the base card sprite
Just don’t add that bit
i don't want it to give base card chips
I think you would either hook Card:get_chip_bonus or Card:should_hide_front
where do i put it
what does G.GAME.banned_keys do? and does it actually work
It's the event that fails to "set" it. If I set it before the event, the value updates instantly and is accounted for, but the event either doesn't do anything or tries to update to the value + the extra value and I explicitly want the "easing" to work.
It bans the keys contained in it, and yes.
okay good, i thought it might not work properly since its unused in vanilla
i think its used in challenge decks
oh i forgot that
how do i get a random number from 1 to X?
pseudorandom("seed", 1, X)
thanks. is "seed" supposed to be replaced with anything?
yes, a unique string for your effect (normally some version of the object's key)
i see
at moderators
<@&1133519078540185692>
It’s because your event queues it to add, but then the event at the end of scoring queues it based off the original score too
So do you imply this then?
func = function()
G.GAME.chips = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech)
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blocking = false,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech),
delay = 0.5,
func = (function(t) return math.floor(t) end)
}))
end
So if you do G.GAME.chips = x it updates instantly right?
how do i get a numerical index of a card held in hand?
Okay this is a bit jank but I think it’ll work, keep that bit you have now, store the initial value within your joker, and set it back to the initial value in context.after
It might need to be set to the value after your first event too
Like so?
if context.initial_scoring_step then
card.ability.extra.preleech = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech)
return {
message = localize('toga_leech'),
func = function()
G.GAME.chips = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech)
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blocking = false,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech),
delay = 0.5,
func = (function(t) return math.floor(t) end)
}))
end
}
end
if context.after then
G.GAME.chips = card.ability.extra.preleech
end
-# Sorry, my brain does NOT want to cooperate due to it being too hot still. x.x
how would i get an object's own key with prefixes? just card.ability.key?
card.config.center.key
will that get the id of the copying joker instead in the case of context.blueprint?
context.blueprint_card.config.center.key
Yeah I think so, give it a whirl
Delete this line
Hmmm
...deducing from the screenshot, maybe we can postpone brainstorming of this until you can get on a PC?
Yeah good idea
Eremel do you need me to find someone to review the wiki pr?
@faint yacht like this?
uhhh which one?
there are some that you said are fine to merge that I need to get round to
Sort of, yeah. Assuming safety with retriggers and copies...
if context.before then
card.ability.extra.chips = G.GAME.chips
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blockable = false,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = G.GAME.chips + 3000,
delay = 0.8,
func = (function(t) return math.floor(t) end)
}))
G.GAME.chips = G.GAME.chips + 3000
end
if context.after then
G.GAME.chips = card.ability.extra.chips
end
Does work without wanting to time it with the message and juice up of the Joker...
you should be able to use SMODS.calculate_effect alongside it
just set blockable to be true
looks a bit jank with more than one of the effects though
-# Jank go brr.
...I've not used that for messages yet, is it SMODS.calculate_effect({message = localize('toga_leech')}, card = context.blueprint_card or card)?
no need for card =, just context.blueprint_card or card
Bringing Blueprint in and there's the jank-
I want a Joker (or Voucher) to set the Text for the Consumable slots, I figured patching the "cardarea.lua" might be the approach to do that... The below Code works just fine without the "and G.GAME.SEMBY_Test" - But I wanna activate/deactivate that effect too...
I can't access G.GAME at this position, any other Ideas?
#-- Allow editing the card-count text for the consumeables-area
[[patches]]
[patches.pattern]
target = "cardarea.lua"
pattern = '''self.children.area_uibox = UIBox{'''
position = "before"
payload = '''
if self == G.consumeables and G.GAME.SEMBY_Test then
card_count.nodes = {
{n=G.UIT.B, config={w = 0.1,h=0.1}},
{n=G.UIT.T, config={ref_table = self.config, ref_value = 'SEMBY_text', scale = 0.3, colour = G.C.WHITE}},
{n=G.UIT.B, config={w = 0.1,h=0.1}}
}
end
'''
match_indent = true
Relevant Joker Code:
add_to_deck = function(self, card, from_debuff)
G.GAME.SEMBY_Test = true
G.consumeables.config.SEMBY_text = 'Blocked!'
end
would this be how i'm supposed to add arrow key input?
Jank, but works in the end.
I'd say that's acceptable honestly
yeah I don't think you can stop that unless you just tell the display not to update
Now it needs to have that Windows ding.
...there have been many dings - which exact one you speak of?
It works in the end and the jank is visual, so that's fine.
Is there a line for custom sound effects? Like when a joker activates itself
sound = 'modprefix_key'
@faint yacht
if context.before then
Ortalab.wide = true
card.ability.extra.chips = card.ability.extra.chips or G.GAME.chips
SMODS.calculate_effect({message = 'Chips pls'}, card)
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blockable = true,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = G.GAME.chips + 3000,
delay = 0.8,
func = (function(t) return math.floor(t) end)
}))
G.GAME.chips = G.GAME.chips + 3000
end
if context.after and Ortalab.wide then
G.GAME.chips = card.ability.extra.chips
card.ability.extra.chips = nil
Ortalab.wide = nil
end
this works for multiple copies and blueprint
does anyone know why this would cause a crash?
I'm fairly sure I'm doing that cause you need to put it in a return but that won't work here
you most definitely are not doing that
If I’m trying to make a joker that checks for if a voucher gets redeemed specifically to do an action, what should I write in context?
there are 3 problems here, 1- localise isn't a function, it's localize, 2- localize needs a string argument to work properly with this message, 3- you must give calc_effect a table that is key-value
So for me it'd be
if context.before then
togabalatro.loremipsum = true
card.ability.extra.chips = card.ability.extra.chips or G.GAME.chips
SMODS.calculate_effect({message = localize('toga_leech')}, context.blueprint_card or card)
G.E_MANAGER:add_event(Event({
trigger = 'ease',
blockable = true,
ref_table = G.GAME,
ref_value = 'chips',
ease_to = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech),
delay = 0.8,
func = (function(t) return math.floor(t) end)
}))
G.GAME.chips = G.GAME.chips + math.floor(G.GAME.blind.chips*card.ability.extra.leech)
end
if context.after and togabalatro.loremipsum then
G.GAME.chips = card.ability.extra.chips
card.ability.extra.chips = nil
togabalatro.loremipsum = nil
end
?
darn Americans messing up my code, so wait how do I fix 2 and 3
I don't quite understand what that wants me to do
SMODS.calculate_effect({message = localize('k_upgrade_ex')}, card)
I find it so funny that
one of the bugs is
Didn't use American spelling
thank you tho
actually with this same joker what's the context for a joker destroyed?
context.joker_type_destroyed
eremel did you see my bug report about it
it's the same context
no :3
smods discord bug reports?
yes
wait it'll detect both jokers and consumables being destroyed?
👋
it wasn't really for me, someone else was testing it with hex and it didn't work
hi dilly!!
Sleepygg?
Me too my eyes have just opened
And im doing that thing where one eye is open but the other is still too heavy to wake up
Hell yea
Hi, is there a context for when a card is deselected?
Im beating joyous spring in bad content today myself
no, hook Card:highlight
impossible, all your content is good
Lmfao
im really excited to finish this update to start working on an overhaul of the mod
sadly that means a lot of UI
yeah just need to update vanilla destruction effects
Oh that reminds me do you guys know a good way to track time in a round
Im using love timer for an ante and it starts when it notices an ante change but im not sure how to count it for time in current round for a blind
“key” would be the name of the sound I guess
Thanks!
Anybody knows if it has to be ogg, wav, mp3 or what???
can't you do the same in Blind:set_blind
i think its suggested that the file is .ogg
🤔
check SMODS.Sound, its listed somewhere
hi bepis!
hi N', hi dilly
Hmmm maybe yea
That would probably work
i drew dog today :3
Hi bepis
i love dog
i love when u talk to dog
I need a friend of mind to hurry up and test if a specific joker works on his pc
Since he runs Linux
me too
i love talking to dogs although they probably dont understand what im saying
:3
You know they say im a dog
Thanks!!!!
dogs understand what i say they just dont like me
Dogs love me
joker didn't want to work for the life of me
refactored the code a 1000 times
I just had forgotten to return the values again
In general, how would one change the text on a button in response to some sort of event in the engine? Specifically, a UIBox_button
didnt work, maybe its cuz i didnt put the ".ogg" in the key? orcuz i placed it in the lua folder?
oh forgot to check this
ima check
hmmm i dont know if there's an easy way for UIBox_button because it's hardcoded to use a text node with static text
i would copy what that function does and use a text node with ref_table and ref_value
Thanks!
Would it be possible to simply remake the button from scratch and replace it when it changes instead?
probably, I just think that would be harder haha
The program cards from Cyptid mod creates new UI
You could have a look there if you want
I got it working and it took so long, and it's an entirely new consumable so I'm adding much more of them like that
wowzers
Safe to assume Card:apply_to_run is only used with vouchers?
how can I add the rank of a card as mult?
mult = context.other_card.base.id?
That "works" until you have to deal with face cards, which have an id higher thant 10
context.other_card.base.nominal?
If I want a tag only to spawn on small blinds what variable tells which blind is next?
ily thanks
@red flower i tried doing the lua workspace settings thing in a .luarc.json fiile in my project root but tis not playing nice
its just outright not processing it
{
"workspace.library": [
"/home/juniperg/.local/share/Steam/steamapps/compatdata/2379780/pfx/drive_c/users/steamuser/AppData/Roaming/Balatro/Mods/smods",
"/home/juniperg/.local/share/Steam/steamapps/compatdata/2379780/pfx/drive_c/users/steamuser/AppData/Roaming/Balatro/Mods/lovely/dump"
]
}
so im confused
hmmm maybe you need a relative route? im not sure
i have it as relative in my folder but im also on windows so idk
no i mean the routes for smods and the lovely dump
hmm
thats gonna be confusing
a relative route would just be ../.local/share/...
because my mod folder is symlinked into the balatro mods folder
so i can get to it easier
i wonder if i could just symlink the lovely dump and smods into my home folder?
im new to modding, how can i get the player's current amount of $?
i know what happened
my dumbass never had a lua language server installed
😭
G.GAME.dollars
k thank you
Wait you can actually configure that? I've been programming the whole time with no lsp 😅
are you using vs code?
seach up lua language server
I was using nvim, but I never questioned that I could configure the workspace
done it a second ago
😅
I thank GOD the game isn't coded in C++
any diskers in chat
What about Linux users
in progress 
not as easy to test linux as im not running it and i cant be bothered to vm it, provided it cant find disks it defaults to 1 disk anyway
so i gotta give it to a buddy of mine
why doesnt this destroy the card
if context.destroy_card and pseudorandom("seed", 1, 15) == 15 then
return { message = "...", remove = true }
end
ah thanks
Bump but better explained now, sorry for the Bump-Bump 🙇♀️
if i were wise enough id love to help you, but unfortunately i am not so wise
if N or smt show up they may be able to assist you
im sorry i cannot be of service friend
i would need to read that part of the code
It's round about line 270 in the original cardarea.lua file
my patch should be applied after ~290
what do you want to do with the count exactly? delete it?
Overwrite it entirely (add a new text) kinda like debuffing the count ig
Removing it when a certain voucher or joker is around would also work
didnt work
im trying to make the card self destruct
what type of card
joker
during its trigger
just write SMODS.destroy_cards(card) after it triggers
gotcha
the problem is that the card count is not remade unless area.children.area_uibox is removed
personally i think the easiest way is to just always replace it with your own count and just recreate the original count when you don't want it replaced
Well, if I use "if self == G.consumeables then" and then I just set the Text trough a Joker it Updates the text perfectly fine?
i tried to put the function after the return and it crashes
i put it before the return and nothing happens
the text is updated because the node has a ref_value, but the UI itself is not remade
can i see
hey guys
ive been using this code to help to make a context whenever a card is deselected
-- from [#💻・modding-dev message](/guild/1116389027176787968/channel/1233186615086813277/)
local highlight_ref = Card.highlight
function Card:highlight(is_highlighted)
if G.deck then
SMODS.calculate_context{card_selected = true, highlighted = is_highlighted, card = self}
end
return highlight_ref(self, is_highlighted)
end
it works perfectly for both selecting and deselecting a card but i dont know how to use it to check only for deselecting a card
trying to make a joker which gives chips but destroys itself if a playing card is deselected
Ah now I get what'cha mean...
But isn't my code overwriting the nodes anyways?
if context.card_selected and not context.is_highlighted then would be for deselecting
yes, that's why I say that you remove the G.GAME check and just recreate the number/limit count yourself
you can also try removing the area.children.area_uibox so it rerenders tho
That one PR I made
Ay, okay I'll def. try it 
Thank you and thank you again for the patience and time 🙏
Sorry dude
Thanks for your help but this still triggers for both selecting and deselecting cards
what about if context.card_selected and context.card.highlighted then
Ive tried both
That doesnt trigger at all im afraid
Hello, does anyone know if there is a context that is activated each every time a card changes suit?
just to be sure, the code I just sent is not the same from before without the not
its different
Wait u right my bad
Let me check
no, you need to make it yourself
how i make my context?
Thanks
working on a joke shitty jokerforge mod and we got harrison
Amd
I have merged 👍
how can i play music when a special booster kind is opened? i know what i have to do my problem is how can i use special booster kind
what’d you change 
Install instructions are now separate pages by OS instead of a single page that has "if you're using Y operating system please ...." 15 times
Is there a way for me to inject into an SMODS function?
yes, hooking
I know I can hook/inject into functions, I'm just checking if I can do it for non-vanilla functions
you can patch smods files too
it doesnt works
When balatro creates consumables for the shop (outside of boosters), does it store them in the shop_jokers object?
This is from update_shop() in game.lua.
if not shop_exists then
if G.load_shop_jokers then
nosave_shop = true
G.shop_jokers:load(G.load_shop_jokers)
for k, v in ipairs(G.shop_jokers.cards) do
create_shop_card_ui(v)
if v.ability.consumeable then v:start_materialize() end
for _kk, vvv in ipairs(G.GAME.tags) do
if vvv:apply_to_run({type = 'store_joker_modify', card = v}) then break end
end
end
G.load_shop_jokers = nil
else
for i = 1, G.GAME.shop.joker_max - #G.shop_jokers.cards do
G.shop_jokers:emplace(create_card_for_shop(G.shop_jokers))
end
end
...
can i use ownership by kind for a consumable type or is it booster exclusive?
What does the scored_card field do in get_card_areas()? Is that just what gets animated when the context is calculated?
yes G.shop_jokers is a CardArea
Yes, it's the card that the effects trigger on.
Wait, is it purely aesthetic or does it actually affect the card? I assumed it's only aesthetic because the "scored_card" field in blind calculation seems to refer to the blind's texture
Thank you chief.
Can you explain what the ❓ react is about?
What should I put as my patch target if I want to inject into SMODS' utils.lua? Is it just utils.lua or does it need some kind of file path?
=[SMODS _ "src/utils.lua"]
Wait, like this?
No, '=[SMODS _ "src/utils.lua"]'
So it needs to be target = '=[SMODS _ "src/utils.lua"]'?
Yes.
Ok got it, thanks
hey folks. so i was updating my mod after having published the repo for it, and the mod just. isn't in the list anymore. what could be causing this?
Is the JSON correct?
yeah!
one of my guesses was the "smods.find_mod", which could be messing with things (since i dont have cryptid when testing the base mod)
No, because as long is the JSON is loading properly the mod will be in the mod list.
im going to try updating smods (though that wasnt an issue before, it could be now)
im also going to try to turn on cryptid, will return with more results
mod still isn't appearing
let me send the json real quick
json file
if anything else is needed ill gladly send it
because im really confused. the mod is still in the folder, it even appears in Balatro Mod Manager as a local mod
it also appears "enabled", despite not even showing up
is there a function / variable to check the played hand type
context.scoring_name
ty
last test im going to do: gonna try and put the cryptid exclusive consumables as comments to see if the mod appears
Can anyone help me out? I'm trying to add a custom rule that allows for a calculate function in challenge decks, but I'm getting this crash that seems to happen at a short interval after blind is selected (I'll send code in a moment)
Here's my code
nothing has happened
local oldsmodsgetcardareas = SMODS.get_card_areas
function SMODS.get_card_areas(_type, _context)
local output = oldsmodsgetcardareas(_type, _context)
if _type == 'individual' then
if G.GAME.modifiers['calculate_context'] then
local fake_deck = setmetatable({}, {
__index = center,
})
function fake_deck:calculate(context)
return putcalculatefunctionhere
end
output[#output+1] = {
object = fake_deck,
scored_card = G.deck.cards[1] or G.deck,
}
end
end
return output
end
does anyone know how to detect re triggers? I've looked at cryptid's candy cane and the code did not help at all
You can't store functions in save files.
Yes.
Ohh, ok
how? please
[[patches]]
[patches.pattern]
target = '''=[SMODS _ "src/utils.lua"]'''
pattern = '''effect.message = effect.message or (not effect.remove_default_message and localize('k_again_ex'))'''
position = "after"
payload = '''
effect.extra = {func = function() SMODS.calculate_context({modprefix_card_retriggered = true})}
'''
match_indent = true
``` And use `context.modprefix_card_retriggered`
Is there any way I could make this refer to my challenge deck somehow? (That way, the calculate context rule is configurable)
Unless I'm misunderstanding, you're defining the function inside of get_card_areas, which means it's hardcoded to that specific function
What is hard coded?
Yeah I think I did misunderstand hold on
Can I define the calculate() function within my challenge deck and then have the calculate_context rule return the calculate() function for my current challenge deck?
No, you just define it literally anywhere else that is not saved on the save file.
Is the entire contents of the SMODS.Challenge entry stored in the save file?
No.
The rules are because their stored in G.GAME.modifiers
Which is in G.GAME so it gets saved.
thanks
What I want to know is, can I do something like this? (I know current_challenge_deck isn't correct, I'm just using it as a placeholder to describe what I mean)
What
Code?
Change center to G.P_CENTERS.b_red
--Metamorphosis
SMODS.Atlas{
key = 'trans',
path = 'trans.png',
px = 71,
py = 95
}
SMODS.Joker {
key = 'trans',
unlocked = true,
blueprint_compat = true,
rarity = 2,
cost = 5,
loc_txt = {
name = 'Metamorphosis',
text = {
'Gives {C:mult}+#1#{} Mult for each',
'card that change its {C:attention}suit{}',
'{C:grey}(currently {C:mult}+#2#{}{C:grey}){}'
}
},
atlas = 'trans',
pos = { x = 0, y = 0 },
config = { extra = {
mult = 0,
mult_add = 4
}},
loc_vars = function (self,info_queue,center)
return{vars = {center.ability.extra.mult_add, center.ability.extra.mult}}
end,
calculate = function(self, card, context)
local ref = Card.set_base
function Card:set_base(card, initial)
if self.playing_card and self.base then
local new_rank = card and card.value and SMODS.Ranks[card.value] and SMODS.Ranks[card.value].id
local contexts = {}
local function table_add(t1, t2)
for i,v in pairs(t1) do
t2[i] = v
end
end
local function get_table_length(t)
local i = 0
for , in pairs(t) do
i = i + 1
end
return i
end
end
end
end
}
You're overriding Card:set_base
Also move it outside of the joker.
Also please wrap your code around:
```
-- Code Here
What does that do? (Just so I can learn more about how this all works)
I don't know, I borrowed this code from CardSleeves
?
where?
SMODS.Challenges.c_modprefix_key
how would i useSMODS.Font in a text node?
because rn im doing:
{n=G.UIT.T, config={text = "➡︎", font="EF_NotoEmoji", scale = 0.8, colour = G.C.UI.TEXT_LIGHT, shadow = true}}
and it crashes with:
the font file is being loaded and doing eval on SMODS.Fonts returns:
ty <3
bumping this again because i couldn't find a way to fix it
are you sure the json is correct
i sent the json
^
didn't notice
if it's wrong then ill fix it but quite literally the only thing between yesterday and today was that i added the code consumables and it broke
it's the version
"version": "1.0.0", // ! Must follow a version format of (major).(minor).(patch)(rev). rev starting with ~ indicates a beta/pre-release version.
from the docs
oh,
didnt see that when making it
gotcha, thanks
also
this code is giving an error (apparently take_ownership_by_kind is a nil value)
is there no other way of doing this other than copying and pasting this into EVERY single ticket consumable?
im using context.post_trigger to scale another joker, how would i make it so it only scales if the leftmost joker triggers?
consider checking brainstorm in vanilla remade, quite sure it has what you're looking for
i know how to do that bit, just not sure how to like, connect it to the post trigger criteria
No, you would take ownership of the SMODS.ConsumableType
take_ownership_by_kind is only for boosters.
so you'd do?
You would create a custom object for the ticket consumables.
Also dollarReturn dollars and cost all don't exist.
Can someone please give me an entropy save file with the tutorial completed?
He crashes my game and I can't escape him
dollarReturn is part of the code. global variable i defined
returns true when a certain voucher is redeemed
global.Ticket = SMODS.Consumable:extend {
set = "Ticket",
use = function(self, card, area, copier)
end
}
otherwise it's defined asfalse
how do i make it so a specific enhancement isn't given out by spectral packs (when familiar/grim or other cards are used)
gotcha
And just use global.Ticket instead of SMODS.Consumable
in_pool = function(self) return false end
thx
how would i fetch the cost of a consumable then?
This is genuinely making me upset
whats the best way to detect what deck the player is using?
card.cost
G.GAME.selected_back.effect.center.key
thank you!
so would i write return {dollars = card.cost / 2}?
No, because you can't return in a use function.
oh
You have to do SMODS.calculate_effect({dollars = card.cost / 2}, card)
hey, im currently working on a meme mod for myself and a few of my friends. this is the first time im doing anything like this, i'm not fluent with lua (or any coding language lol). im trying to make a joker that functions identically to space joker, but it only levels up full house when you play it and im not sure how to start with that any help is appreciated :)
this boy is crashing. ticketRate is another globally defined value, so it exists. here's the error code
No, G.GAME.key_rate is the rate.
how do you use variable colors for backgrounds in localization text, if possible?
You use B instead of V
cool
do playing cards have some sort of unique index or identifier?
Try this:
calculate = function(self, context) if self.debuff then return nil end if context.cardarea == G.jokers and context.before and next(context.poker_hands["Full House"]) then return { card = self, level_up = true, message = localize('k_level_up_ex') } end end
which value is that? just need to use it for a variable for playing multiple of an enhancement
card.sort_id is different for every card and card.playing_card is the same but only for playing cards.
is it possible to have a consumable type not show up in the collection?
Yes.
how would i go about that?
no_collection = true
thank you!
im trying to make a joker that turns unplayed aces in hand into steel cards & this doesnt work what should i change
unfortunately, this did nothing 😔
is there an easy way to make this show the normal numbers as a fallback? it doesnt show anything unless it's also showing the compatible sign
youd proabbly wanna replace the joker main part with this
if context.before and context.scoring_name == "Full House" then
return {
level_up = true,
message = localize('k_level_up_ex'),
}
end
still nothing
Code?
It's (self, card, context) not (self, context)
Also remove if self.debuff then return nil end because that does nothing.
new question since i figured out the last one, when doing repetitions it returns this in the console because i have a joker which copies other jokers in order to find out when they do that kind of trigger, but it doesnt actually copy the joker
is there a way to make those not appear?
thank you, i'll give it a shot
Yes, Code?
this is what im working with
it works now but theres no like,visual for it,just turns steel
how would i make it more apparent
uhhh could juice up the card
unexpected symbol near "}" am i missing something?
Yes, you're missing an end
(context.other_card):juice_up(0.8, 0.8)
something like that i think?
You're not returning ret
i mean if i return ret itll copy that joker right?
Can someone remind me where I set challenge rule descriptions? I can't find it on the wiki
thank you it works great
i dont want it to, im just having it check when a joker triggers in order to gain mult
No, use context.post_trigger
SMODS.current_mod.optional_features = function()
return {
post_trigger = true
}
end
wouldnt post trigger also trigger for when a joker scales? thats what i was using before but i ran into that issue
like every time you played a 2 wee joker would trigger it
What is the goal?
you can check for the source trigger of whatever context.post_trigger triggered from
iirc
this is what im going with
Why would messages not count as triggers?
hey folk! so it's crashing with this error and when removing the global part, it does absolute nothing. any ideas?
no real way to detect whats actually happening in a trigger unless you do some real crazy hooks stuff probably
No, it's in context.other_ret
i guess im more looking for when a joker returns something then
Yes, global is supposed to be your mod global.
my definition of a trigger for the purpose of the joker was just anything that blueprint would copy
oh
because that lets me add a compatible incompatible thing too which is nice
Messages are returns.
so it has to be my mod prefix thing? like i have to put NotVanilla.Tickets?
ok i guess thats not what im looking for then
No, it would be your mod global.
that does have SOMETHING but thats still pretty basic for detecting what a joker is doing
Sorry @proper relic, I went to do other things
Like this:
No, that has everything.
(I was joking it's alright lmao)
It's the entire return from eval_card
Like what?
I dunno what's going on in here but I approve of the ❓ spam
like anything other than this you cant see from that?
Ok
im going to assume this is wrong
because other stuff doesnt go in the return table
No, that's correct.
Like what?
its just the return table
literally how would this help telling you what a joker does for the purposes of only triggering on certain joker effects
or this
anything that isnt a pretty basic scoring effect will just return a message
Yes.
and the original point was to not have a context.post_trigger thing trigger on scaling
also, the tier 2 voucher is appearing regardless of me having the tier 1 voucher or not. is this supposed to happen? (the requires might be formatted wrong, idk)
and you cant really detect scaling with context.other_ret
The key needs to be a string.
i will say the joker works perfectly gameplay wise with how i want to rn ! the only issue is that it puts weird messages in the console with repetitions specifically
uh not necessarily
itd also work with like, hallucination
Yes, use context.post_trigger
gotcha
That's not possible unless you specify which jokers you don't want.
can you actually say things instead of just question mark reacting everything
well i mean it does work with hallucination rn
cool
you could blacklist certain contexts or return table values but thats really it
you cant make it not work only on specifically scaling effects
at least not easily
unfortunate
Someone told me I was overriding Card:set_base, but I don't know how I'm doing it.
Also is this what dollarReturn was supposed to be for?
yeah! when this voucher is redeemed, it sets dollarReturn to be true
You should be using G.GAME.used_vouchers
otherwise dollarReturn just sits there at false
Because that value will reset if you reload.
oh shit didnt know that
Also if it's the sell value it would be card.sell_cost instead of card.cost
so how would i check if this voucher is in G.GAME.used_vouchers? do i iterate using a for loop and check if the key is equal to the voucher key?
if G.GAME.used_vouchers["v_modprefix_key"]
oh that's much easier than what i did
if i do use post trigger, how would i check to make sure it's the leftmost joker?
if context.other_card == G.jokers.cards[1]
isn't this currently grabbing an element in a number value
like im pretty sure this wouldn't work
yep i was confused
hm yeah its less buggy than the other implementation but isnt really at allwhat im looking for
ill ponder
what're you trying to do?
Where is the rarity of a joker stored?
joker.config.center.rarity
can i check for if G.jokers so my joker wont crash trying to render nil localization in the collection?
Yes.
now would it be if G.jokers or do i need the cardarea and cardarea etc
if G.jokers then
--code
end
or
if card.area == G.jokers then
--code
end
No, it would be if G.jokers
ok i thought so
How could I delete the "New Run" button when you're in a game and you press Esc? There's a bug where it crashes the game when you click anything in Galdur on that specific menu in my modpack and I'd like to just disable it entirely because I keep forgetting and click it.
is it possible to have a deck start with an eternal card? I'm using cavendish for the joker, and it summons, but isn't eternal, and literally nothing I try works.
Yes.
Remove everything except the event and do: ```lua
if not G.jokers then return false end
SMODS.add_card({key = "j_cavendish", stickers = {"eternal"}})
thanks so much! appreciate the help!
even when i reset the unlock, the card continues to already be unlocked on launch? i even ran an eval, and it returned wheel_fails as 0? so it shouldnt unlock?? and yet every time i open the game after setting the unlock state to false it's unlocked???
"what are you trying to do?" Unlock condition of failing WOF 3 times in a row
had a working version before using ownerships, but that shouldnt be necessary now that there's a probability calculation function expansion
What's the unlock behavior look like on the card itself?
?
also mind you you're checking if not ret then which means that it'll reset G.GAME.wheel_fails when the wheel of fortune fails instead of succeeds
...i did it backwards?
other than that, what does this mean? like the description?
The check_for_unlock function on the center, or the unlock_condition property
Hi everyone can someone give me an example of smods.Challenges? (Like a template for making the balatro challenges yk)
look at vanilla remade
just the standard unlock check
replace that whole block with return args.type == 'hpfx_nope'
really? What’s the dif?
you shouldn't use unlock_card(self) in the center function, the SMODS behavior calls it for you based on if the function returns true or false
regardless I think with all these fixes you just need to reset your profile
Since you can't relock already unlocked/discovered cards without doing so (or manually removing them in some other code)
Im just resetting it with the shorty systems thing
and the center has both discovered = false and unlocked = false?
well yeah ofc
I’ll try your fix
Is this new btw
cause I haven’t had to do this
or is it “old” but because of how this unlock works
It's not that you can't, but it just means it's ignoring the framework given to you
makes the code less readable if it's not following the API standard
I see
should I do this for all of them then?
Personally yeah
Otherwise if it's giving an unlock pop up every time you reset your profile, it means that the unlock type is being sent more often than you think
if it doesn't and it's already unlocked with no fanfare, then your profile isn't being reset correctly
why do ALL played cards with this enhancement get the probability boost when any one of them fails?
you're setting self.config (the center's config) instead of self.ability (the instanced copy of the config on the card)
use self.ability in general
i remember trying that on some other enhanced card and it was causing issues
Could be a different use case or an unrelated bug
ok but wait i might have a special case here (also note that this unlock works)
regardless, change all instances of self.config in that screenshot to self.ability and it'll work
return (args.type == 'hpfx_7mult' and to_big(args.mult) >= to_big(7))
yeah that's what i expected
oh well nevermind then lmao
Your loc_vars function is causing a crash, what does it look like?
works fine with self.config
all these variables exist, the self.ability table does not
oh wait, i'm a moron. you should be using card.ability in all of these cases
oh shit yea
self is the center, not the instanced card
(sometimes get turned around b/c the vanilla functions inherently use self where it does actually refer to the card, in functions on the Card table)
(in SMODS api functions it generally does not, it calls the functions from the center defintion where self is not an instance, and then passes in the instance as card)
Anyone know why this doesn't seem to set card.ability.extra.improved to true? I'd like to have the card behave differently when three or more jokers of this particular rarity are owned. The alternate behaviour does work fine if I set improved to true, but this code can't do that apparently.
if G.Jokers and not context.blueprint then
local organs = 0
for i = 1, #G.jokers do
if G.jokers.cards[i].config.center.rarity.key == "willatro_organ" then
organs = organs + 1
if organs >= 3 then
card.ability.extra.improved = true
else
card.ability.extra.improved = false
end
end
end
end
for i = 1, #G.jokers do should say for i = 1, #G.jokers.cards do
Also it's G.jokers not G.Jokers
alternate more concise code:
if G.jokers and not context.blueprint then
local organs = 0
for _, v in ipairs(G.jokers.cards) do
if v.config.center.rarity.key == 'willatro_organ' then organs = organs + 1 end
card.ability.extra.improved = (organs >= 3)
end
end```
hey so wheel_fails isnt changing past 0? despite the amount of nopes?
(first call: before 3 nopes)
(second call: after 3 nopes)
wheel of fortune key is c_wheel_of_fortune
How do I check a time variable? I want to make a pulsing effect
but prob doesnt use that?
oh I see right cause this is from probability vars
(funny because im the one who wrote that code)
okay so this is the current defintion for pseudorandom_probability
function SMODS.pseudorandom_probability(trigger_obj, seed, base_numerator, base_denominator, identifier)
are you using the vars for the wrong function?
seed is the second argument, and identifier is the fifth argument that you don't have
I'm trying to adapt the Better Tags mod but after a long while of combining cat tags it starts to lag really bad. I'm trying to diagnose that lag, but it doesn't seem to be anything obvious.
so then what the hell is this?
where is this?
there's two lsp definitions for the function
I only see these two
---@param base_numerator number
---@param base_denominator number
---@param key string|nil optional seed key for associating results in loc_vars with in-game probability rolls
---@param from_roll boolean|nil
---@return number numerator
---@return number denominator
--- Returns a *`numerator` in `denominator`* listed probability opportunely modified by in-game effects
--- starting from a *`base_numerator` in `base_denominator`* probability.
---
--- Can be hooked for more complex probability behaviour. `trigger_obj` is optionally the object that queues the probability.
function SMODS.get_probability_vars(trigger_obj, base_numerator, base_denominator, key, from_roll) end
---@param trigger_obj Card|table
---@param seed string|number
---@param base_numerator number
---@param base_denominator number
---@param key string
---@return boolean
--- Sets the seed to `seed` and runs a *`base_numerator` in `base_denominator`* listed probability check.
--- Returns `true` if the probability succeeds. You do not need to multiply `base_numerator` by `G.GAME.probabilities.normal`.
---
--- Can be hooked to run code when a listed probability succeeds and/or fails. `trigger_obj` is optionally the object that queues the probability.
function SMODS.pseudorandom_probability(trigger_obj, seed, base_numerator, base_denominator, key) end```
in smods/lsp_def/utils.lua at around line 600
genuinely no idea where you're getting that
now i dont know 😭
There is an error that the lsp_def calls it key instead of identifier but it's benign, and they're in the same location
Either way, your function should be this:
function SMODS.pseudorandom_probability(trigger_obj, seed, base_numerator, base_denominator, identifier)
and your check should be
if (identifier or seed) == 'wheel_of_fortune' then
Or whatever you want to name the variables. Doesn't matter
How does one show extra decks on the Deck View menu?
where the hell am i getting this from
is it
pulling from get_probability_vars??
its whatever i guess
ill just fix it and move on
Actually different question
Where is G.C.DYN_UI.BOSS_DARK stored, I want to do a thing with it
globals.lua
😭
I forgot I can just write a colour lerp function
winterrrrrrrrr....
did you literally mean "(identifier or seed)"
or did i interpret right and i was supposed to choose
how do i add icons to a mod
assets/<res>/modicon.png
Does there need to be a delay between save_run() and G.FUNCS.go_to_menu() to ensure the save file gets written?
No.
You make an atlas with the key being "modicon"
If you mean the icon in the mod menu
Check the dump to see if wheel of fortune even passes an identifier
I suspect it's just the seed
where would i look
In card.lua
Helo
Hola
o puedo crear más archivos
Looks like it's the seed
use SMODS.load_file("path/to/file.lua")()
note that steamodded needs your mod to at least have it to function
Ahhh, thanks
changing the check to seed then
And other cuestion
shoot
what is the name of the balatro programming language, when I tried to read the code I didn't understand anything.
Lua
5.1
https://www.lua.org/manual/5.1/es/ fortunately 5.1's manual is available in es if you prefer (literally the only version that has it)
Thanks
How can I get the value of the biggest discarded card?
Oh my god, thnks very much its hard read in english
I know about context.other_card.base.nominal but how'd go about iterating the cards, maybe a for loop?
finally 
hell yeah!!!
i have to update the unlock descs now...
since im using return
in context.pre_discard loop through G.hand.highlighted
The unlock descs should def be more human readable no?
wrong person to ask im barely human
i think the comment at the bottom is clear
okay fair, "human readable" usually just means "something that doesn't look like code"
Yeah the desc should just be Nope! on Wheel of Fortune 3 times in a row
Ooh, I was doing something similar but I was using context.discard
Thank ya!
that takes the fun out of itttt
the whimsy winter
dont tell me youve forgotten the whimsy
i didnt have any grip ones
If I wanted to check if a blind was beaten in one hand, would I just do G.GAME.current_round.hands_played == 0 or will it have updated to 1 by the time I make that check
I think it'd be 1 by that point
Okii
Thank u
i do this for a joker paired with context after and it seems to work
i just check if the chips scored are above the blind req
True
fixed up a little
does SMODS.add_card({ set = 'set', edition = 'edition'}) work?
that's what set_edition is for im pretty sure
thanks srockw
Do dynamic descriptions support randomization? Like if i wanted to do a probability thing each time i hover over the card, and the success will have the line say one thing otherwise it'll default to something else? I know i can do this (image), but that's guaranteed as long as you possess the card
you could do a local variable with pseudorandom
and check if the variable is 1 or 2
true...
local locRandom = pseudorandom('blahblahblah',1,2)
and then in the loc_txt you could check
if locRandom == 1 then
text = ""
else
text = "...?"
end
actually
hear me out
would returning locRandom = 1 and "...?" or "" also work
table
local table
and you randomize the element that it picks from
and declare that
hold on let me write the code
why would i need all that for a choice between two lines bro 😭
because then you only need to write #1#
and the randomization does itself
actually i didnt put it in a string
put both in a string
loc_vars = function(self,info_queue,center)
return{vars = {descRandom[pseudorandom('blahblahblah',1,2)]}}
end,```
if it returns an error please let me know but it's not supposed to
that's how it works with the image i sent already
oh it's hover over
do we have a context for that
@daring fern do we have a context for that (my apologies for the ping)
didnt find anything in the wiki
A context for what?
something like this would work yeah
hovering over a card
fuck yeah im learning basic lua
== 1
but yes
No, but you would either put it in loc_vars or hook Card:hover() I think.
oh loc vars alr covers the hover bit?
yes
ah
yeah
thanks you 2
i was just saying i dont need all that if it's just a one or the other lmao
How do I change the colour of dynatext
colour = {G.C.RED} in config
Not colours?
-# omg bepis hiiiiiiiiiiiiii
boo
uhh i dont think so 🤔
Okii
hii
-# and astra too i guess 🙄
-# ugh toma's here...
-# ughhhhhhhhh
this bit already sucks lmfao
Hey, just wondering if anyone else knows how to achieve this with SMODS code, I asked Victin but he never responded...
Basically I just want to selectively make a scored card skip the "already played/discarded" void and go right back into cards held in hand
helo tomato 
Weird
if I do colours then nothing happens
if I do colour then this happens
@red flower did you reimplement G.C.DARK_EDITION as an SMODS Gradient for VanillaRemade?
You would almost definitely have to make a patch for this
wait there shouldnt be any brackets nvm
and now nothing happens again 
nope
aight
wait so it did work it just doesn't do anything
N what's the table for the scoring cards in a hand real quick
context.scoring_hand?
table
so do i just do local cardThing = context.scoring_hand[1]?
thatd be the first card
yeah i want the first scoring card
oh gotcha
also whats the table for all played cards
like cards that were already played
yeah like i want all cards that have been played in a round
I think you might need to make that manually
I was gonna say "maybe the discards deck" but that includes discards
actually the discards deck would work
because im fetching the first played scoring card in a hand and logging it
and then trying to find it in the already played cards deck
since it only logs whenever a hand is played i can use that
so you're fine with it also counting cards you've discarded and not just cards you've played?
yeah
in that case it's just G.discard.cards
gotcha
No, it's G.discard.cards
Is there any way to track score
Im asking cuz my friend dosent know and im ass at code 💔
cool
bump 
didnt bepis answer that already
it didnt work
_ _
yeah no im not doing this shit
what happened bro 😭
someone much more skilled than me is gonna code this guy's joker
maybe you did it wrong
i cant create infinite local variables and destroy every instance in the deck of the cards listed in those local variables and then create them again
ALLOY.total_health = G.GAME.health + G.GAME.shield
if ALLOY.total_health < normal_min_health then
health_text_UI.config.colour = health_negative
elseif ALLOY.total_health > G.GAME.health_max then
health_text_UI.config.colour = health_shielded
else
health_text_UI.config.colour = health_normal
end
...the hell is the effect?
just use a table
i dont,,,, ui,,,,,, 

oh yeah
and then i destroy every card for all indexes in the table
how did i not think of that

i can’t tell if this is sarcasm and you forgot about for loops or not
can u try putting a health_text_UI:recalculate() after changing the color
o true
go focus on class >:(
true...
i forgot about local tables
this also doesn't seem to do anything tho
weird
there's probably something more i need to do
im, half certain changing colour should update the DynaText automatically
lovely


