#💻・modding-dev
1 messages · Page 191 of 1
doesn't get_id() just return card.base.id?
I check for numbered cards by just doing not card:is_face() and card:get_id() ~= 14
lololol
Where do I get the card?
if SMODS.has_no_rank(self) and not self.vampired then
return -math.random(100, 1000000)
end
return self.base.id
end```
sort of
true but true
ah with the exception of stone and whatever the vampire interaction is
I think my idea was to have it so it supports modded numbers or smth but idk
Why exclude aces?
usually a store sells packs of 52 french cards.
idk man give me some gosh darn context
A is not a number?
is A a numbered card?
I’d say ace is a numbered card yeah
It sould be.
😭
Oh.
excusez-moi?
Oh no
damn
I'm gonna come back to this, because I would love to be able to figure out how to keep it at one enhancement, that just changes its base sprite depending on the suit
Does this count as context
that actually makes a lot of sense, honestly
welp time to fix that 😭
A doesnt have a face, so obviously its not a face card
dang, now i have to rename "numbered" cards is baliatro, great
the game really doesn't consider aces face cards or numbered cards
and this is more of an smods question than a coding question
as evidenced by the deck view
i mean technically aces being numbered implies that cards are actually in at least base 11, not base 10
card here is the joker being scored, and in context.joker_main there is no other card
are you possibly looking for context.individual in which case context.other_card is the card being scored?
Yes, this count as a context, but what number exactly do you want to turn into Xmult_mod?
ngl im lowkey lazy as hell
i already added 11 jokers, and i have to rewrite most of its code
because of this 😭
Oh god
so i'm looking at the SMODS api and i actually have no idea from the docs how the base id is spawned for custom ranks
Nice button though
(description pages, basically)
I tried for a little bit to add a button and had a hard time
thanks, N' and other pep helped me a lot lol
i have a feeling card:get_id() might conflict across mods or be dependent on load order
Can the joker itself be the button instead?
that can't consistently be used, it's just in order of being registered
in fact, 95% of my code is inspired if not straight up adapted from his code 😭
you can use card:get_id() == SMODS.Ranks['key'].id
there you go @manic rune, get_id() is vastly inferior to checking the value lol
a good idea actually, but as someone who clicks on jokers for fun i think it can be annoying
though i would definitely add that as an option in the configs
thanks wizard :D
Every time you have to re-order the description changes page…
Or using any consumable on the homer
Joker
Would you like to show us the description you'd prepared for this joker?
That would help us understand the effect you want to achieve.
mhm, theres that too, so i think while having the extra button means having to go through an extra step, its probably best this way
Or a keybind thet changes the page whilst it’s being hovered
I don’t think the back and forth is a good user experience
oh thats good
Keybind + button = perfection
The cards value, like how many chips it gives
true, true, though its only 3 pages so its not THAT bad ❤️
So like A->+11, KQJ->+10, and number for number?
at most 5 pages if i have to predict for my future updates
That’s so much 😭 why do you need that much text?
it will certainly look better after this change though lol
O-oh
Yes, exactly
I feel like you could also split this up into some info boxes
it would flood the screen horizontally then 😭
adding the page stuff is definitely the best approach, as it allows me to add more mechanics to a joker without having to worry about it covering the entire screen
And what timing to you want to apply the Xmult?
When a card scores? Or after card scoring?
Yeah fair
When card scores
this, for example
this will definitely be the first joker to cover the screen if i were to go with the same approach 😭
that is a very long description
yeah, but im adding pages to descriptions that you can scroll with keybinds/button
so it shouldnt be too bad now
^ this is a demonstration
pagination for description is crazy
i think Q and E should be fine for the keybinds?
i hope no mods conflict with that, somehow
or maybe i can just add custom keybinds
that should solve the problem
time to see how to detect keys
DebugPlus definitely uses either or both of those keybinds
I wonder how hard would it be to detect the description is being shown/rendered
oh yeah, i forgot
one day we will have a keybinds menu and it will look exactly the same as a minecraft modpack
Controlling for balatro when
the uibox should be a child of the card
or just detect when the create uibox func is called
don't forget the until recently unrebindable narrator hotkey
. which version did they
Narrator - narrator on
i have seen keybinds from mods which literally required a combination of keys 😭
1.19.4
add rebinds to narrator
Mfs be making the LinkedIn hotkey look like child’s play
narrator - narrates all
Then I'd suggest you to useif context.individual and context.cardarea == G.play then local xmult = nil if context.other_card:get_id() == 14 then xmult = 11 elseif (context.other_card:get_id() <= 13) and (context.other_card:get_id() >= 10) then xmult = 10 elseif (context.other_card:get_id() <= 9) and (context.other_card:get_id() >= 2) then xmult = context.other_card:get_id() end if xmult then return {Xmult_mod = xmult} end endinstead.
narrator - narrates chat
Typing Sound >
< Someone being shot and carried to a van so that they will be disposed of in a river
i will definitely try my best to add all characters from the game lol
but for now, i will add all characters from v1.0 first
Something near if...
How would I grab a specific atlas by name for this line?
card.children.front.atlas = _atlas
How does your code look like right now? Include the line count, please.
Bad
the context isnt supposed to be in the return
place all of it outside
(once again, absolutely diabolical circling)
So like this?
nah fr 😭
mhm
you can remove the context.joker_main part
since theres no use for that rn
No, I wasn't talking about your circle.
no, i know exactly what you are talking about
oh also
wouldnt it better if you use x_mult instead?
since i think if you use Xmult_mod, there wont be a message
or maybe there is, idk
SMODS handled that so that it's all the same. (As long as it's compatible.)
oh i see
Heh, this joker is very op
it really is
14 000 000 from a J to 8
So I create a table of Suits then I check scoring hand for any unique suits and add them to the table. Ig "local suits" is a number since we add +1 to it? So I just multiplied the scaling of the joker by the the number of suits in the table (I totally butchered it)
This, but focus on Lua.workspace.library
card.ability.extra.x_mult = card.ability.extra.x_mult + (card.ability.extra.scaling * suits)
you're multiplying a table by a number here, this won't work
and you're returning in your for loop
But how can you add +1 to the table then?
suits[suit]
it is a number then
Pro tip: open your mods folder as your workspace, so vscode can see yours smods install
i'm becoming increasingly confused
what exactly are we trying to do
give me the description of your joker
gains 0.05 mult per unique suit in played poker hand
oh
sorry if I wasnt clear
damn, this is convenient, KeyboardController has the exact thing i need rn lol
So, I know it reaches this line, but why does this not change the sprite for the card?
print("club!")
card.children.front:set_sprite_pos({x = 4, y = 5})```
children.center
not children.front
i know that since i worked on a mod just for changing sprite automatically lol
CanI see my Joker in the shop?
guys
I didn't update for a month cuz i was on a vacation
I was on 1326a
Now is in 1421b
Did calc change?
i dont think so, unless 1326a counts as old_calc
sure enough, it works!
if context.before and not context.blueprint then
local suits = {}
for suit, _ in pairs(SMODS.Suits) do
if context.scoring_hand[i]:has_suit(suit) then suits[suit] = true end
end
for suit, _ in pairs(suits) do
card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.scaling
end
return {
message = localize('k_upgrade_ex')
}
elseif context.joker_main then
return {
xmult = card.ability.extra.x_mult
}
end
the two for loops can be merged
one sec
Wait, so you only need to check if there is or isn't a suit, instead of how many there is with each suit?
yes
if context.before and not context.blueprint then
local suits = {}
for i, other_card in ipairs(context.scoring_hand) do
for suit, _ in pairs(SMODS.Suits) do
if other_card:has_suit(suit) and not suits[suit] then
suits[suit] = true
card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.scaling
end
end
end
return {
message = localize('k_upgrade_ex')
}
elseif context.joker_main then
return {
xmult = card.ability.extra.x_mult
}
end
wait
i missed something
lmao
Then wouldn't you need a list of booleans instead of a list of numbers?
Ig so but could it be like counting the number of different suits in scored hand instead?
fixed
Maybe like, counting how many trues in that list?
2 questions. Can i change the sell value and how do i change the rairity
I think baliame just created what I've said
the original suggestion went back to us not actually understanding what the intention was so we gave an overly generalized utility function that counts all the suits
I'm sorry😭
I think I'm just having a hard time wrapping my head around the data structures, because I still do not fully comprehend what a 'center' actually is
centers are prototypes for different things kinda
I think it can be trace all the way back to SMODS.Center.
smods/src/game_object.lua line:1011
search balatro source code for self.ability.name == 'Cryptid'
SMODS.add_card({ key = 'c_world', area = G.consumeables})
c_world can be replaced with any tarot card's key.
or use the SMODS convenience function which I never looked up exists
I mean like a 7
Or a jack
this is a function already in the game, right?
create_playing_card is the function you're looking for but it's a vanilla thing so it won't hold your hand
Wdym it wont hold your hand?
I would've suggest you to have a look at Familiar/Grim/Incantation code, but...
so why does this kind of assignment work for my custom sticker, but not for this enhancement?
card.ability[self.key].extra.suit = "Spades"
this looks cursed
egg
It's a function of UIBox in ui.lua:
function UIBox:get_UIE_by_ID(id, node)
if not node then node = self.UIRoot end
if node.config and node.config.id == id then return node end
for k, v in pairs(node.children) do
local res = self:get_UIE_by_ID(id, v)
if res then
return res
elseif v.config.object and v.config.object.get_UIE_by_ID then
res = v.config.object:get_UIE_by_ID(id, nil)
if res then
return res
end
end
end
return nil
end
I do not touch the ui with a 50 foot pole
...hm
So this is the code I mentioned.
somethings wrong
why is that when i press "e" specifically, this pops up?
i basically adapted the code from KeyboardController so that might be it
but i cant exactly figure out why it pops out
Maybe something else was bound with E?
Last question.
...i have no clue myself
BalatroSR.config_tab = function()
local loc_options = {}
for i, v in ipairs(hsr_keybind_options) do loc_options[i] = localize(v, 'hsr_keybinds') end
BalatroSR.current_keybind = BalatroSR.current_keybind or 'hsr_turn_page_left'
BalatroSR.current_keybind_val = BalatroSR.config.keybinds[BalatroSR.current_keybind] or ''
return {n = G.UIT.ROOT, config = {r = 0.1, minw = 5, align = "cm", padding = 0.2, colour = G.C.BLACK}, nodes = {
create_toggle({label = localize('hsr_keybinds_enable'), ref_table = BalatroSR.config, ref_value = 'enable', callback = function() BalatroSR:save_config() end }),
{n = G.UIT.R, config = { align = "cm", padding = 0.01 }, nodes = {
create_text_input({
w = 4, max_length = 9, prompt_text = BalatroSR.config.keybinds[BalatroSR.current_keybind],
extended_corpus = true, ref_table = BalatroSR, ref_value = 'current_keybind_val', keyboard_offset = 1,
callback = function(e)
BalatroSR.config.keybinds[BalatroSR.current_keybind] = BalatroSR.current_keybind_val
BalatroSR:save_config()
end
}),
}},
create_option_cycle({
label = localize('hsr_current_keybind'),
scale = 0.8,
w = 4,
options = loc_options,
opt_callback = 'hsr_select_keybind',
current_option = BalatroSR.current_keybind_idx or 1,
}),
}}
end
function G.FUNCS.hsr_select_keybind(e)
local hook = G.OVERLAY_MENU:get_UIE_by_ID('text_input').children[1].children[1]
hook.config.ref_table.callback()
BalatroSR.current_keybind = hsr_keybind_options[e.to_key]
BalatroSR.current_keybind_idx = e.to_key
hook.config.ref_value = BalatroSR.current_keybind
G.CONTROLLER.text_input_hook = hook
G.CONTROLLER.text_input_id = 'text_input'
for i = 1, 9 do
G.FUNCS.text_input_key({key = 'right'})
end
for i = 1, 9 do
G.FUNCS.text_input_key({key = 'backspace'})
end
local text = BalatroSR.config.keybinds[BalatroSR.current_keybind]
for i = 1, #text do
local c = text:sub(i,i)
G.FUNCS.text_input_key({key = c})
end
G.FUNCS.text_input_key({key = 'return'})
--KBC.current_keybind_val = KBC.config.keybinds[KBC.current_keybind]
BalatroSR:save_config()
end
those r the code
How do I modify the discard times valure
Thanks for helping out! I'll credit you in the mod
Ctrl+Shift+F,
and then search G.GAME.round_resets.discards.
Or you can just use ease_discard().
apparently, the set_sprites() function in your SMODS.Enhancement{} is not called when you use a suit-changing tarot card on an enhanced card
time to see how to detect keys pressed
shouldnt be too hard
i have to somehow find the part where it restarts when you hold R, where could it possibly be
that should give me a clue on how to implement this
https://github.com/Steamodded/smods/wiki/SMODS.Keybind does this not work?
ok so how would i add a use button for a joker with custom text? i know its done via patches but no idea on how to do it
nope, you actually dont need patches
oh really?
If you want to modify it like Merry Andy, put G.GAME.round_resets.discards = G.GAME.round_resets.discards + card.ability.extra.discard_mod in add_to_deck, and put G.GAME.round_resets.discards = G.GAME.round_resets.discards - card.ability.extra.discard_mod in remove_from_deck.
And add ease_discard(card.ability.extra.discard_mod) and ease_discard(-card.ability.extra.discard_mod) under each of them.
mhm, i did that without one
if you'd be willing to share sometime in the future
i was carried by N' heavily, but i will try
mhm, theres generate_ui in SMODS.Object
.
wait, wrong explanation
I MEAN
you can instead use hooks
it gets worse, because when you go to view the deck it doesn't even recognize the correct sprite to begin with
this part is basically overriding how balatro adds buttons like "SELL" to cards, i think
how can it appear correctly in my hand but not in the deck???
ahhhh
and this is the function stuff
i very much adapted joyousspring's code to make this (its a mod)
so i highly suggest checking that out
lel its fine
Wait, where do i search?
i was very lucky to be guided early on ngl
else it would have certainly taken me days, if not weeks
I think I might still need some rewording...
i think it should be Mult instead of mult
Ctrl+Shift+F searches through every file in your workspace.
Which I should've specify to do that in lovely/dump
when in doubt, update the sprite every frame...
update = function(self, card, dt)
it's dirty but it works
also, i think you should do "5" instead of five
since, uh, this (its 1, not one)
and theres no "." at the end of the description either
so what does this part actually do? i dont really know how uis work
As I've specified before, it's hard coded.
oh, it adds buttons to the joker
I recommend profiling this with DebugPlus (Ctrl+P to show stats, Ctrl+V to start and stop profiling), it might have a pretty major performance impact
for my case, its "SELL" and "SWITCH DESC"
oh i see
so the first part here removes the sell button and the ui function adds it back?
...huh
mhm
how can I retrigger jokers?
the "else" part is basically ignoring all of those stuff if its jokers you dont want to add buttons to
am I just looking at the fps or is there any other value I should care about?
you should have this line first, preferably at the top of everything
hm
then you can do stuff like this
(just uh, dont mind the other context except for context.retrigger_joker_check)
Ctrl+P will show the time spent per-frame in different functions. Check without your update hook first, then again with it on to see if there's an obvious difference
Been working on something. 
damn????
thats really cool!
Planning on making balatro the electronic board game
Ctrl+V starts the profiler. Play the game for 20 seconds or so, move your card around, interact with things, then stop it again and check the console to see a table of how long the game spent in each function over the course of that 20 seconds. If your update hook is high on the list, it might be having a big impact
we are adding this as a new update to the real life balatro 🗣️
Expect a YouTube video to pop up in around 1-2 months once I finish the full prototype
I have a lot to do with working out the scoring system but after that I should be fine.
thanks! I've never used those kinds of tools before so the explanation helps
Total parts for it should cost around 40-60 to build without bulk pricing.
so im guessing you can place cards onto something, then the sensors will start looking from left to right?
Is this using a little NFC tag?
bro wtf is that
ion remember this existing
optional features lol
there r even stuffs like quantum enhancements
Yes nfc stickers. Peep the bit architecture
which allows you to add multiple enhancements to playing cards
since when did this exist?
no clue either, i started modding relatively recently
lowkey want to make it so that you need to somehow hold B,A,L,T,R then finally press O for an easter egg
I guess and-chain every key is easier than setting up a sequence lock.
Under the play surface there is a belt driven dolly that moves nfc read/writers under the cards giving us a massive amount of room for negative jokers
I don't see Stone cards here Found it!
oh thats very cool
imagine being able to mod real life balatro tho 😭
@fresh swallow How would you handle tarot, planet, and spectral cards?
im guessing there will probably be a zone where if you put a consumable card there, it will be detected and used
no clue how that would work with consumables that select highlighted cards and do stuff tbh
Oh of course, you have to write the changed states to the cards too. Awesome
Strength and Death might prove problematic
honestly for strength
Already figured out. Playing cards will be sleeves and you will have plastic inserts to change the card visually
just replace a card with another card lol
looks like i lost the buttons entirely :b
Not a problem. I have a seed system for that, you can change any card to any card without issue and it will retain the change until the start of the next game
oof
Visually you just use a dry erase marker on a layer under the sleeve
its probably something to do with the create buttons function
Neat!
ok but real quick, how would Cryptid the spectral card work?
time for some experiments
You use the crytid card by laying it on the field, behind it you put the card you want to copy and 2 cards from the spare deck to turn into the first one
oh, thats neat
ig for naninf strat you would need to buy 6 decks lol
...im actually surprised by how straightforward this is
but uh, wait
can key_pressed be changed?
Everything can be changed if you try hard enough
i mean, if the stuff already loaded in then will it read the new keybind if it were to be changed
the power of hooks and patches 🔥
but i really hope it will, else im gonna need to do some work here
Surely you could just iterate through SMODS.Keybinds to find the binding you're after, then change matched_keybind.key_pressed
Perkeo will exist but the voucher that gives 1.5x for each planet can’t. It just not going to work for the way I am building it.
i can see why, idk how you even put like 200 negative planet unless you do stuff like Cartomancer lol
(stacking consumables)
The consumable slot is managed by the player not the computer, I did not want to have a 4th nfc reader/writer in the game board
i see
1# reads played cards, 2# reads jokers and 3# reads cards drawn off the deck
A 4th one would just be overkill
The game will only have 4 buttons needed to play it. Everything else is done by playing “Function cards”
Function cards are used to reroll shops/buy packs/skip blinds
id honestly love to buy this one day, but since im in vietnam i doubt the shipping fee will be cheap 😭
best of luck to you tho ❤️
i still dont understand why its not creating the buttons
Sorry to interrupt, but which function handles speech bubbles?
Will you need a screen to indicate some of the random or chance-based events? Like Certificate creating playing cards, Idol and Ancient Joker's preferences, Hallucination creating Tarots, etc
code?
is this how i do it?
Yup built in 3 inch display to show details for certain event and to show the blinds/blind requirements
i mean, it certainly works, but if i change the keybind in the settings then it will still be the keybind when you initially opened the game
probably have to manually change this then
Here is the display for money, ante hands and discards
looks like my cable management
Hands and discards are tracked by leds
The 3x seven segment bank is for money and the 2x is for ante
Cable management is an issue when every part needs 7 wires
That's awesome. Arduino-friendly LCDs just seemed too easy, clearly
I need to create a new file if i want to create a new rarity?
Not necessary, but kinda suggested.
It actually all depends on you.
...or can i just make it so that you need to restart for the keybinds to reload themselves
hmm
cartomancer and handy have configurable keybinds i think
you can check the code for those
oh sweet
huh
any mods that adds new raritys so i can take a look?
thank
Cryptid~~, unfortunately~~.
alright the button is there. How do i get it to actually do something?
rn im gettin a crash on press
its this part
which you will be adding a G.FUNCS with that exact name, i think
This is significantly cheaper to make. By large margins.
That whole assembly display is like .50$ of parts
am I dumb or it should be here?
Oh, are you considering mass-producing this?
Wtf this is gonna be peak
hmmmmmmmmmmmmm
yes, I want to try approaching local thunk once I have a fully functioning prototype.
Cartomancer does seem to support changing keybinds
I am trying to make it cheap. 30ish-40 dollars to produce it
Retail estimate is somewhere close to 100$
There is a reason I am building it off of a super cheap chipset
Esp32-S3
2 dollars for the processor will be really good for keeping costs down. Just optimizing my code has been hell
the worst part is, this is correct
what's a good weight for a rare-er version of legendary? like mythical or sum
.001 is good?
is that for the joker to spawn in the shop?
Saw you mentioning e-ink displays last year, was cost the main reason for going the paper-and-sleeves route instead?
cuz it'll retrigger all jokers lmao
It’s due to the cost of the e-inks along with refresh rate issues.
Would you like to wait 2 mins to discard and draw?
cryptid experience
wtf you made quantum enhancements?!?!??!?!
does it actually like work for jokers or nah
this is the last part I need to patch in
ah
I spent so long getting the sprites to load correctly and writing the function to actually handle them
The nfc stickers are actually the most expensive part of the game. You need around 320 of them. At .05$-.08$ a piece it really boosts the price by 20 bucks
And I am going with some of the tiny bit more pricy once to allow for more read and writes
but in theory making them compatible with rank-based jokers should be relatively straightforward, just tedious
Wow, why so many?
2 playing card decks, 149 jokers, 80 sum arcana/spectral/planet/function cards.
Showman does not exist unless I sell more jokers
it's also not very computationally efficient but I streamlined it a little bit. Definitely not scaleable for certain kinds of custom hands
how do i check if we r currently in a run?
i want to make it so that it will check highlighted cards when the key is pressed, but will it crash if you are not in a run
Makes sense that Showman would make things outrageous. Supporting almost every other feature of the game on paper sounds like a pretty insane goal, but it seems like you've thought through all the little details, which is awesome
I would have to sell showman and blank cards that you use a function card to turn into the designated copy
Would love to see more of the development as it comes together, i love intricate electronics projects like this. Would you make a thread or a discord server for it?
all right, time to patch all the rank-based jokers now
can i somehow do this to unhighlight a joker then highlight it immediately afterwards lol
SMODS.ObjectType {
key = 'Food',
default = 'j_egg',
cards = {},
inject = function(self)
SMODS.ObjectType.inject(self)
-- Insert base game food jokers
self:inject_card(G.P_CENTERS.j_gros_michel)
self:inject_card(G.P_CENTERS.j_egg)
self:inject_card(G.P_CENTERS.j_ice_cream)
self:inject_card(G.P_CENTERS.j_cavendish)
self:inject_card(G.P_CENTERS.j_turtle_bean)
self:inject_card(G.P_CENTERS.j_diet_cola)
self:inject_card(G.P_CENTERS.j_popcorn)
self:inject_card(G.P_CENTERS.j_ramen)
self:inject_card(G.P_CENTERS.j_selzer)
end
}
end```
```if not SMODS.ObjectTypes.Food then
SMODS.ObjectType {
key = 'Food',
default = 'j_egg',
cards = {
["j_gros_michel"] = true,
["j_egg"] = true,
["j_ice_cream"] = true,
["j_cavendish"] = true,
["j_turtle_bean"] = true,
["j_diet_cola"] = true,
["j_popcorn"] = true,
["j_ramen"] = true,
["j_selzer"] = true,
},
}
end```
does anyone know why neither of these methods are actually adding these jokers to the pool
I thread is made
This list is a lot longer than I wanted it to be
Raised Fist
Fibonacci
Scary Face
Hack (works with Wee Joker)
Pareidolia
Even Steven
Odd Todd
Scholar
Business Card
Ride the Bus
Sixth Sense
Faceless Joker
Superposition
Baron
Cloud 9
Midas Mask
Photograph
Reserved Parking
Mail-In Rebate
Walkie Talkie
Smiley Face
Sock and Buskin? (Works with Wee and Triboulet)
Wee Joker
The Idol
Hit the Road
Shoot the Moon
Canio
Triboulet```
💀 good luck
thank you 🫡
how can i check if a specific joker belongs to a specific mod?
HMMMMM
i have to somehow force the joker to reload its generate_ui
you might be able to parse its key and get the prefix
there's probably a better way though
so that if i were to hover my mouse onto the joker and press the keybinds to scroll between pages
the new description will be loaded in
what ability could i give this joker?
i was thinking something to do with stone cards
you probably want card:hover and card:stop_hover
maybe make it so stone cards now have a certain rate to destroy themselves upon played, and if they were, give bonus chips to the joker? like, +100 chips or something
oh thats a really cool idea
oh theres that function? sweet, thanks
maybe "Scored Stone cards have a 1 in 4 chance to be destroyed, this Joker gains X0,5 Mult for each card destroyed this way"
i was thinking it would be leaning a bit more towards chips, since stone cards give a lot of the
I think I'm going to define an is_rank() function that takes an array of accepted values, and then replace literally every rank-based conditional for the jokers with that
maybe X(n) Chips instead?
mm yea but there's already stone joker for that
wait why is there a double maybe
Go check SMODS.create_mod_badges in smods/src/utils.lua line:388
I don't really like XChips that much
oof
yeah i suppose x mult is fine too
it helps stone cards build to at least have another source of mult gain lol
it's basically the same thing anyway
ya fr
i also thought of a Punk Rock joker, "Stone Cards also act like Steel Cards, Steel Cards also act like Stone Cards"
oh thats cool
still gotta draw that one tho
this description is way too long
how do i shorten it
wait ok i have an idea
"1 in 4 chance to destroy scored stone cards" might be a bit shorter
this + "Gains X0.5 Mult for each"
This feels so much cleaner now
if self.ability.name == 'Fibonacci' and is_rank(context.other_card, {2, 3, 5, 8, 14}) then
vs
context.other_card:get_id() == 2 or
context.other_card:get_id() == 3 or
context.other_card:get_id() == 5 or
context.other_card:get_id() == 8 or
context.other_card:get_id() == 14) then
The list of jokers I need to edit directly is actually much smaller than this, because I can patch Card:is_face() to fix all of the ones that only depend on that
Is there a way to inspect what exactly is inside the shader name's variable? E.g.
what's inside extern PRECISION vec2 ionized;?
cc @wintry solar
stupid question, how do we do that thing where you can split your .lua into multiple files and load them all individually, like what cryptid does for its /Items folder? (forget EXACTLY what that was called but we're still in the "waking up" phase of our day ^^;)
it's thankfully pretty easy to do, just add this to your main script
the string is the file path to the script you want to load
thats very cool
Oh, so I can paste into the debugplus console, that helps a lot
thank you :D
Yeah it fixed all of these: Scary Face, Ride the Bus, Smiley Face, Photograph, Faceless Joker, Midas Mask, Business Card, Reserved Parking, Canio
how do you stop cards that don't exist anymore from appearing in your deck after destroying them in context.individual?
hey dumb question but: boosterpacks all have a weight of .96. if i want a booster pack to show up less (or more) do i want that number bigger or smaller? which way does which lol
smaller means shows up less
less = rarer
ye
my brain is lowkey shutting down half-way because of how much time i spent on one single feature 😭
huh that's funny
SMODS.Rarity {
key = "cursed",
badge_colour = HEX("474931"),
default_weight = 0.0005,
pools = { ["Joker"] = true },
get_weight = function(self, weight, object_type)
return 0.0005
end
}
It’s this
You don’t destroy them there
ionized.r, ionized.y, ionized.x - what are those? Is there more stuff inside the <shader name> object?
ionised.x/r is the first item in that table, .y/g is the second
nevermind, i called loc_vars instead of loc_vars.vars
It’s just how you refer to the parts of the vector in the shader language
💔
So the first value is to do with the rotation and tilt of the card, and the second is just a timer
No one's fault but it seems that some of shader stuff is unnecessarily cryptic
okay so i'm trying to get the id of the mod that jokers added to deck are from, but i think i'm doing something idiotic instead
when a modded joker is added to deck it says no mod found
so that's not how you access the mod that a card is part of
problem is how
Should this be happening? cuz i don't think cryptid does anything different...
what's context.l6_joker_added
is it the joker card?
try context.l6_joker_added.config.center.mod.id
tysm!! it works
i'm not very good at navigating the structure of a card and where to find values yet lul
i just printed the card
yay
Okay this is way better than the gigantic wall of text
fr lol
does SMODS.create_card not apply stickers on jokers by default? if so how should i do it manually?
i'm testing some booster packs and unless i'm getting crazy rng no stickers are being applied
also whoops
is there a way to force a perishable sticker onto a non-compatible joker
cos like no fucking way im gonna let this be how this joker works thats way too broken 😭
how would i check if a certain card is discarded in the first dicard of round
G.GAME.current_round.discards_used let's you know the discards used
@red flower sorry for pinging, but how do i reduce this gap?
thats useful
reduce the padding value
probably in the column node
how do then i check if a certain card is discarded
hsr compat would be funny
this one?
probably?
y never know
true
try the root padding
oh sweet it works, thank
i dont get it still
the cards you discarded are G.hand.highlighted
its a table, you can use a for loop to go through it
and see if the card you are looking for is there
the card is context.other_card, you don't need a loop
the way to read it is
condtion to check to see if you're inside that context if context.discard then
This is true for that context:
context = {
cardarea = G.jokers, -- G.hand, (G.deck and G.discard optionally enabled)
full_hand = G.hand.highlighted,
discard = true
other_card = G.hand.highlighted[i]
}
Whatstthe entire text config
i will add hsr mod compat for some reason
im new to this ui stuff so theres definitely some bad decisions in there
i actually tried my best to make the code as easy to modify and read as possible lol
my abomination of a card is now compatible with every single one of these jokers
Look at what desc from rows is doing
I think this feature is done now, at least to the degree I want it to be
like this one, which works like literal lego since you can tell it what it should buff, and it will do just that without any other changes
Is it possible to manipulate loc text colours using something like {C:#1#}?
oh, i think someone actually did that here
aight, lemme check rq
I was actually wondering this too
{V:1}texr{}
you need to return a colours table in loc_vars and use {V:1}
And in loc vars return a colours array inside vars
hmmmm
You could attach them as the extra text for the elements above them
i require assistance
That would probably look cleaner
can someone help me with deckskins?
card.ability.perishable = true and card.ability.perishable_tally = 5 or smt
Look at how the set perishable function works in card.lua
The atlas in the palettes need your mod prefix
i mean i was told this was the right way of adding perishable but i guess it respects compatibility
Yeah just manually do what set perishable does
mhm, i will try that, thanks
It worked, thanks!
sweet thanks!
The formatting of my return is slightly off, but I'm not sure quite how
return {vars = {{G.C.SUITS['Hearts']}, center.base.suit}}
vars = { colours = { ... } }
thanks 🙏
is "G.GAME.current_round.discards_left" a thing?
You can use the functions smods provides to add stickers
Does that respect should apply
it is
cool!
oh shit
oh that's convenient
I love undocumented functions 🥳
All functions are documented if you just simply read the entire codebase of Lua, Love2D, Balatro, Lovely and Steamodded
hi all
I have a question about the sound files
So I am trying to edit the abientFire sounds
I changed the first one to a short song. But it still plays the other fire sounds. Any idea how they work/play? In order? Randomly? or based on ur score?
this is still giving me attempt to index field 'colours' (a nil value)
return {vars = {colours = {G.C.SUITS['Hearts']}, center.base.suit}}
for sure!
is there some kinda poll function for stickers?
cause my custom joker booster packs aint generating no stickers on gold stake
This looks fine to me, what does your loc look like
name="Omnirank Card",
text = {
"Can be used",
"as any rank",
"for {V:1}#2#{} suit"
}
},```
center.base.suit should go outside the colours i think
it is inside
I thought it was outside
brackets are hard
I think it is outside? I might literally be blind though
it looks outside to me tbh
of the brackets to the right of it, one bracket is to close the return, the other one closes vars
????
yeah i read it wrong
oh yeah you're right, that's how it works in The Idol's loc
I mean I could always forego the color and just change the text, but it would be nice to make it look pretty
im gonna try this again except im just posting the entire lua file cuz idk what i could possibly be doing wrong
im trying to make a blueprint-like card that copies the ability of one of the jokers in your deck randomly at the start of a blind, works fine for cards that have a calculate_joker function but for a card like say wrathful joker it doesn't do anything, and idk what to refer to if not calculate_joker ive went through the entire balatro source code looking for anything brainstorm/blueprint related to see if i was missing something and im missing literally nothing, tried with the blueprint code straight from balatro, tried with the old blueprint code from cryptid, it's not doing anything for jokers without a calculate_joker function
putting the formatting issue to the side for now, time to work on the Jokers for my custom enhancements
With SMODS, do jokers not receive their update function calls while in the collection?
just tried it, they do
yeah, I have a joker who changes its sprite when you have a banana, and the joker does change in the collection
how are jokers with animations done? can you do that vanilla or should i try and use a separate mod/library?
I know it's in the default structure in game.lua, but does smods support enhancement_gate for custom jokers?
Yes
they do afaik
perfect
Huh, I'm not sure why I've consistently had problems with this, then
I'll have to debug, weh
It might just be that the default rendering code for card children doesn't run in the collection
Okay yeah, it receives updates, but dt is considered to be 0 because the game is paused and dt is gamespeed dependent
does G.real_dt work?
yw I remembered that a some places in my code use dt or G.real_dt or 0
what contexts do i use for a joker like hiker?
hiker uses context.cardarea = G.play and context.individual
I just implemented a joker just like that!
bump
i dont need anyting else?
I don't believe so, no
unless you mean referencing the playing card being scored itself, which is context.other_card
can someone show me an example of using take_ownership in a joker?
How do you check which cards in hand
when
like, say, to modify the behavior of a consumable?
you could just try looking for a mod that has this sort of thing and check how its done via the source code
IIRC you don't do take_ownership in a joker, but you can do it on a joker
Hi guys, I've been working on a mod for a while and have some placeholder art (Warning! I made the art with AI). I'm interested to see if anyone would like to do some art for these joker / tarot cards I've added. If I'm in the wrong place, my apologies 🙂
Also, I suggest you look at how Incantation (https://discord.com/channels/1116389027176787968/1262697083438235729) takes control of Periko
Can you use the blueprint_compat = true, field
dummy dum here
I forgot how to localize the return
like, I want to make the "repetitions = 1"
Then it returns "Again!" bellow the card
I thought card = card would work
smods will handle auto messaging for you
elaborate?
You know, I looked at the code for blueprint and I am not sure how blueprint itself only attaches to cards with blueprint_compat, I thought it might be simple to pick a different card if one isn't compatible
So, @fathom thunder , looks like it isn't as easy as I thought, my bad
blueprint_compat is merely a visual indicator
how funny would it be if flushes and straights could be played with one less card for every copy of four fingers you have
Each card defines their blueprint behaviour by checking not context.blueprint
and on the other side of this, if the skippable gap in straights increased by one for every copy of shortcut
I need to stop having ideas like this
the thing is, theres no reason it shouldnt work right? this is what it returns when i refer to the calculate joker function for the one that doesnt work yet it doesnt do anything
every card has a calculate joker function
yea thats the thing i thought it wouldnt work because some didnt have one when i checked the code but it does and it should work yet it doesnt
Also when using debugplus to eval you can skip the print
i see
What's your code? Ideally a screenshot
i sent the entire lua file here
I'm on phone
you're only copying inside the joker_main context
So you're only coyping the joker_main effect of other jokers
ah
And you seem to have removed the setting context.blueprint and blueprint_card to nil after calling calculate
yea
If you want blueprint behavior you should literally copy the blueprint code in the base game as is
And the only difference would be what joker it decides to copy
also I wouldn't recommend saving an entire joker within your card's ability
that might cause issues when saving and loading a run
might = will
yeah i already ran into that so thats a thing im gonna have to fix now
it either crashes on save or doesn't load properly
how do you guys version releases of mods? for a release adding 5 jokers to an existing 5, would that be a v2 type thing or a v1.1?
look up semantic versioning
I do [major breaking changes or refactoring].[content additions].[bug fixes].[hotfixes]
that's pretty much it yeah
makes sense, thank you!
how am i gonna save what joker it copies in this case then cuz saving and loading works fine but once i restart the game it doesnt save the joker
i tried getting the joker again via checking if copying isnt none and other_joker is nil to get the copied joker again but that didn't do anything
because all copying does is just store the name of the copied joker
or wait maybe i could store the index of the copied joker?
does anyone know how to make it so a texture pack only uses a certain joker(s) instead of the entire sprite sheet?
I would store the index
How do you handle the joker being moved tho
why is this not patching
hooks 🙂
I'm making a new card back, how would I remove specific cards from the deck entirely? stuff like abandoned deck seems to be hard coded with a built-in no_faces setting, but I'm not sure how i'd remove specific suits from the deck
I think you can mark the copying joker with a prefixed flag in its ability
like other_joker.ability.modprefix_copied = true
and just ensure the flag is removed
you might still want to patch into copy_card in that case tho
and make sure that flag is never copied
how would you differentiate between different copies of the blueprint joker
or do they all copy the same thing? I didn't read what the ability was
i guess you could go down the path of they all copy the same one
is malverk able to replace playing card textures, or do I still have to do that the old way?
or you could add something like, always copies the leftmost joker with this flag
what about always copying the joker to the right or the leftmost joker
that would be really easy
multiple of this joker dont copy the same thing (they have a chance to tho)
yeah that would be easy
let's go with that
i guess you could assign a unique id to every copy of your joker at birth and then mark the copied joker with that id
If you don't care about the specific joker you can always store the key
stupid question but we couldn't find this anywhere in the source, is there a v:is_suit equivalent for specific ranks? we did find context.other_card:get_id() == 2 but that's not quite the same.
(for context, we're trying to make a card that, at the start of calculations, sums up the ranks of all the cards you played in-hand, a-la a blackjack.)
are you summing up the chip value of the rank
not chip value, the actual rank. otherwise, hiker could influence it, and that would be no bueno.
hiker's chip value is separate from the rank's chip value in the code
if you want to get a card's rank's chip value do card.base.nominal i believe
what would i have to hook into to get a joker's updated index after being dragged around
oh i think literally just update
Card:release probably
out of curiosity, would this even be something worth making a for loop for, or is there a far easier way to sum up the results of card.base.nominal from the scored cards?
i don't know how you'd make that easier but
it's not worth thinking about
at least not until it's a finished joker
premature optimization and all that
Idk if it counts as modding but is tjere any code difference between balatro on windows vs android
i know android doesn't have the buy buttons on the cards and stuff
there seems to be very little documentation on card backs in general, does anyone know how i'd do this?
and you need to drag them to a certain area
yeah, there's differences. discussion of modding on mobile isn't allowed here though, so anything further you might want to move somewhere else
backs have an apply function that is run at the start of the run I think
you can remove the cards you want manually
anyone know how i can add perm xmult
just make sure to properly remove them so that you don't generate ghost cards
what do y'all use for testing shaders
im trying to replace it but i want to know in what order it plays
what's this pool_opts.allow_duplicates in smods? it doesn't seem to be actually used anywhere other than in this lovely patch in smods
that is something you can return as the second value on your in_pool function
it will dictate if multiple copies of it can exist at the same time
it makes the card act as though showman were always present
i.e. multiple copies of it can exist at the same time naturally
we're 100% checking for rank & incrementing our sum variable wrong, played 3 5s and it returned 0 when it should be 15. (as of right now, it's not checking other cards, but that's on purpose until we can get it properly incrementing.) what're we doing wrong here?
you don't have a context.other_card there
I see... The thing is I've made a pokermon submod, that adds a deck that allows duplicates; but from testing, it seems that it's enabling duplicates in ANY deck. Ideas?
version = "1.0.0"
dump_lua = true
priority = 10
#Letting the hordedeck give repeated pokemon; smods also changes this line
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = 'elseif not (G.GAME.used_jokers[v.key] and not pool_opts.allow_duplicates and not next(find_joker("Showman"))) and'
position = "at"
payload = '''
elseif not (G.GAME.used_jokers[v.key] and not pool_opts.allow_duplicates and not next(find_joker("Showman")) and not G.GAME.selected_back.name == "hordedeck") and
'''
match_indent = true
a few testers believe they've seen repeated pokémon in any deck when using my mod. I'm not sure how... but it's a somewhat confusing code, what with the double negations
...gonna need a clarification, because there is one on line 396--is there meant to be another one elsewhere? :o
no it doesn't exist
no but actually tho i'd love like a tool to test a card shader
you can use debug plus watch commands
if context.other_card:get_id() == 5 then sum = sum + 5 end --shamelessly copied from Hack (doesn't seem to work?) ?????
context.other_card is not a thing in joker_main
oh. that makes substantially more sense.
yep, in debugplus watch shader Mods/MyMod/Assets/Shaders/myshader.fs(unless the location is very different for your mod)
wait where do i run this
just in the console?
please please please familiarize yourself with this document
yep
the shader stuff yeah you just throw it in the dbp console
oh ok sweet
no yea i meant the calculate stuff
how do i apply the shader to a card btw by default
you have to patch Card:draw
well actually that depends on if it's just one card or not
you can give it a draw function in your definition
draw = function(self, card, layer)
card.children.center:draw_shader('voucher',nil, card.ARGS.send_to_shader)
end
like this
if my shader was called tmtrainer would i have to import it somewhere as well i'm assuming?
replace voucher with your shader key
do i import it at a high level
like main script
sorry if this is a stupid question
you use SMODS.Shader
ah
I think the docs for it are on the edition page
okay. since other_card isn't an option in joker_main, what is an option for tallying the card.base.nominal values of the cards played in the hand? tried scoring_hand and it didn't do anything, which. we assume that's tied to the type of hand played, so, that makes sense.
scoring_hand is a list of scored cards
wait, that would be like, the thing to check then, wouldn't it?
calculate it in context.cardarea == G.play and context.individual, and store it in card.ability.extra to be retrieved in context.joker_main
yeah I got that same thing when I did watch shader, but it was after I clicked a button
no idea what it's about
What's your shader definition and draw function
don't do this
nah i think i got it
uh
nope
this shit is flying directly over mty head into the twin towers
!!
ohhh... 9/11... /ref
you need your mod prefix
the draw
the draw isn't the problem- i already did that
oh
i mean i could try again
the path needs the file extension
wait, why not?
because you can do it all in joker_main, there's absolutely no need to use the individual context, you aren't affecting cards individually
that line should probably be rewritten, it means that the name of your shader within the shader file should be the same as the name of your file without the extension
yeah
if you did it like that, your joker would sum each time a card was scored
wait, isn't that the entire goal? since the plan is to sum together every scored card in the hand according to blackjack scoring. (obviously, once the hand is done, the sum is then reset to 0, as otherwise that'd be. confusing.)
if you want to consider repetitions sure
like, including retriggers?
yes
honestly making it so retriggers count for this would be so astronomically stupid that it kinda overflows back into being hilarious. smuggling a score of 20 by playing a 5OAK of red seal 2s.
and that's exactly why you don't want to use context.individual
just count it in joker_main by looping through scoring_hand like you initially thought
Why is this not working i dont understand
wait, use scoring_hand if we do want retriggers to count, or if we don't? because honestly when we put it like that we think retriggers counting might be entirely in the spirit of things
If you want retriggers to count use context.individual
got the card removal working, but hmm
shouldn't this give a random suit from smods.suits?
I'm trying to randomize the suits of all remaining cards, but not the ranks
im sure theres somewhere else i can find this information but is anything actually random in this game? like if i played the same way on the same seed with everything unlocked on both devices would it always turn out the same way or are there some fully random things
does this crash, do nothing or smt else?
doesn't crash, console spits out this
Ah
suits are weird, and I'm not sure what's up with the ranks because it should be one of each rank
i finally got my mod to work and have been working hard on it. but now im a little stuck
the issue here is you're getting a table with information about the suit
is there a way to see what the next card in the deck will be?
you need to access the key of the suit
the key?
I was replying to Wheat, idk how to do what you're asking
oh, darn
I heard someone mention a mod that does that already
im probably going to have to look through the source code then
perfect
{string = 'rand()', colour = G.C.JOKER_GREY},{string = "#@"..(G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11)..(G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.suit:sub(1,1) or 'D'), colour = G.C.RED},
heres what misprint uses
i would love to see how they did it
Oh nvm it was misprint yeah
oh yeah I was just about to say, look into what misprint does
im such an idiot, i can use misprint lol
That's easier than I thought
fr
i wonder if i can see if it has any modifiers on it or not.
ill figure it out
ill just put the value into a variable and use that
G.deck.cards[#G.deck.cards].ability.effect?
okay yeah this worked, adding .key to the end of the pseudorandom gives me what I'm looking for, thanks
currently trying to replicate Midas Mask's "played face cards become gold" except make the cards wild. referencing Midas Mask's function, i see v:set_ability(G.P_CENTERS.m_gold) . there is no version of G.P_CENTERS.m_ that accounts for wild cards. will i have to create a G.P_CENTERS myself within the function, or is there a simpler way to make a card change its enhancement when played?
m_wild?
is there a way to run a test with the joker im working on?
DebugPlus
Open a new game, find the Joker in your collection, press 3
is that a mod
yes
Yep
pog ill look for it
oh dude i'm going to overdose on painkillers before i get a single shader done
i'm gonna take a break from this for a bit lmao
there is no m_wild unfortunately :( ateast not when ctrl + f 'ing for it in the game's source code.
there definitely is
i ctrl+fed through the source and found it there
well ctrl+shift+f
through the full source
check lovely/dump instead of the raw balatro source code
smods makes a few changes to it
LMFAO rly?? no way, lemme try again
okay, that's confusing. for whatever reason, when multiple different ranks are being calculated, like a full house or a straight, the math sometimes just does not math correctly. for instance, a full house of 2 9s and 3 7s, which should be 39, totalled to 35. what the heck are we doing wrong here?
aside from. y'know. The Obvious Optimization Issue, but we're trying to get it functioning first.
oh there's a lovely dump? is that on the smods github?
Mods -> lovely -> dump
remove the for loop, context.individual is already called once for every scored card
yup, found it. does it matter that there is no "G.P_CENTERS.m_wild" in base game?
but there is...
it is in the base game
ah, must be misunderstanding what G.P_CENTERS does then. ok, ty!
def gotta move to the dump, that'd make this way easier LOL
please replace your if elses with this
if you want an explanation of what is going on, context.individual is being called once for every scoring card (retriggers included) for each card you're setting the sum to 0, then for every card in the play area (scoring or not) you're adding its value to sum, then assigning that sum to your card
So essentially, your sum will be the last scoring card's value multiplied by the amount of played cards
this doesn't take into account modded, do context.other_card.base.nominal
having removed the for loop, now it only seems to care about the very last card scored?
yes read the explanation above
i was mainly just aiming to get rid of all the if statements LMAO
also how does base.nominal work?
that'd be the chip value of the rank
yeah, ideally you also check if it actually has a rank
we mean, it's still doing that even after removing the "sum = 0" line altogether, unless it's doing that because of the declaration of the local variable "sum"? (also sorry we haven't inserted the one elseif replacement, we're trying to figure out this first)
ace has the ID of 14 not 1
once again, context.individual is called once for every scoring card (retriggers included)
i don't want to just give you the answer, just try to understand what's going on
Hey all! So I'm making a mod and just winging stuff by reverse enginerring the balala code. Are there SMOD docs and is there a way to lint using the SMOD classes n stuff for type hints?
Cuz I'm boutta 'splode
there is a wiki in the github repo for SMODS, as for type hints... you won't get any unfortunately
😭
there is a pull request for lsp_def though
Thank you though love docs ❤️
ofc the SMODS version isn't up to date, but I just downloaded the lsp_defs folder and put it into my version
(although workspace.disable should be diagnostics.disable)
whoops
we mean, the answer is obvious, remove the local sum = 0 step and put it elsewhere, since putting it in if context.individual and context.cardarea == G.play then means it's constantly setting sum = 0, right? but then, where exactly do we put it?
we tried removing the sum local variable and just using card.ability.extra.sum, which does MOSTLY work... but now, it doesn't actually properly reset the value at all, so it just increments forever; even with a card.ability.extra.sum = 0 call at the very end of scoring. what's up with that??
okay it looks like you basically got it
wait is that meant to go out of the return
before returning, save what the sum is in another local variable
(the card.ability.extra.sum = 0 i mean)
then set the card's one to 0
so im looking through the code, and sorry im new to this. what does cost_mult do?
What do you have so far?
kinda basic but im teaching my self as i go
key = 'Clint', --atlas key
path = 'clint_joker.png', --atlas' path in (yourMod)/assets/1x or (yourMod)/assets/2x
px = 69, --width of one card
py = 93 -- height of one card
}
SMODS.Joker{
key = 'Clint',
loc_txt = {
name = 'Clint Eastwood',
text = {
'Gain {C:red}Mult{} equal to the {C:blue}value{}',
"of the next {C:attention}card{} in the deck.",
"{s:0.7}''The future is coming on,",
"{s:0.7}It's coming on, it's coming on''"
}
},
atlas = 'Clint',
pos = {x = 0, y = 0},
effect = "Mult",
cost_mult = 1.0,
config = { extra =
{
mult = (G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11),
}
},
loc_vars = function(self,info_queue,center)
return {vars = center.ability.extra.mult}
end,
calculate = function(self,card,context)
if context.joker_main then
return {
card = card,
mult_mod = card.ability.extra.mult,
message = '+' .. card.ability.extra.mult,
color = G.C.MULT
}
end
end
}
i got it to do Xmult
but i realized i wanted to do just normal mult
all you have to do to give mult, xmult, chips, xchips, or money is
return { mult = x } where x is whatever you want