#💻・modding-dev
1 messages · Page 407 of 1
for some reason, changing G.GAME.blind.chips wont update the score requirement text
oh
do i have to like
manually reload it
Too op, make it Rare ty
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
thank u :>
a
i think i made a polterworx joker, im sorry everyone
im gonna see if i can make it fancy
Trying to figure out how to check for money spent
Try looking at Redeo from Cryptid
hook to ease_dollars, might not be consistent for effects that change G.GAME.dollars directly but its the cleanest approach
or if you want it to be absolutely consistent, then you might want to use update 🤔
It hooks ease_dollars and checks if the value has decreased
Why would something change G.GAME.dollars directly?
-# me once
unfortunately
for i = 1, 20 do
G.GAME.blind.chip_text = number_format(math.floor(oldBlind - i / 20 * difference))
delay(0.1)
end
doesn't work 😔
It's fine I can just change it normally
delay(0.1) doesnt really do anything here
it's fine to ignore mods that change G.GAME.dollars directly because that is Incorrect
true
you might just want to use an event instead
o
I do wonder if it is possible to add an event to the queue and make it not be the last event.
Wanted to drop by and ask how useful would an API be that categorizes Jokers (i.e. chip jokers, mult jokers, scalers, food, etc)
Id imagine a release would come pre built with some popular mods already sorted
For mod makers it would allow you to basically compare a key to a table and return relevant categories. If it sounds useful, what would you imagine would need a category, and how strict do you think it would be
henlo
oh thatd be super useful
very
yeah that'd be somewhat useful
i think food jokers should def be a category
You say like, tags for cards?
cavendish for example: joker, food
fool: consumeable, tarot
idk
The joker/Consumable category wouldnt be necessary since you can already check that but yes
ah
yeah, you can check their set
Good idea to tag if it interacts with a special type like tarots or planets though
this would definitely be helpful
i have a joker rn that checks for food jokers which is quite finicky and requires people to add their food jokers to the pool
So, exactly, how would it work? You pass a key and it returns a table with all associated categories?
From a mod dev end too I'd imagine you'd be able to feed your own custom tags for your mods so it plays nicely with other CatAPI sorted stuff
Aye
smods already has "pools" which do the same thing
just having a standard set of pools and a mod that applies them to vanilla would be good
Is this what the meme pool is
howthefuckdoesoneworkwithpools
meme pool is indeed a pool
Awesome
SMODS.ObjectType
water pool
for the food pool dango uses i basically convert the center pool of food jokers to a key value dictionary
because iterating fucking sucks
Is there merit in just making it a separate json file or something so it's easier to edit
unbelievable
someone help
Node moment
i cant work on ui no more 😭
Buffet - Rare
When you discard a Royal Flush, destroy this joker and create a negative copy of every Food Joker
what if legendary food joker
a global table that anyone can add to would be nice
I could try to help you if my puter did not broke down and I actually knew how to work with (your) UI structure.
nukes the whole table by just setting the value to nil
:3
anyways for pools smods already lets you define them on the joker definition
the humble metatable
the what now?
anyways building a new system for this probably isn't a good idea
since smods objecttypes/pools already exist
kms
SMODS has had something in the work for this but it hasnt shown progress in a while
I'm struggling to get the level colours on my planet card to work. I thought I got it when I found G.C.HAND_LEVELS, but it's still just the default colour
Do you have talisman?
I do
Try ```lua
colours = {
(
to_big(hand.level) == to_big(1) and G.C.UI.TEXT_DARK
or G.C.HAND_LEVELS[to_big(math.min(7, hand.level)):to_number()]
),
},
Just tried it without talisman and it doesn't work either
I'll try this though I guess
that works and I don't understand why :3
Is the handlevel == 1 and TEXT_DARK part even necessary?
Ah, I see why it is necessary now :3
Thanks for the help :3
Does lua use pass by reference or pass by value
I want to make some qol functions
depends
tables are passed by reference
there might be something else passed by reference too
but most thing slike ints and strings and bools are passed by value
if context.playing_card_added and not context.blueprint and playing_card:get_id() == 9 then
card.ability.extra.count_nine = card.ability.extra.count_nine + 1
end
end```
It's context.cards for the cards that were added.
You would need to iterate over it.
so i need to check for every card that is added right
Yes.
is there anyway to check the table of new card added to the deck
for k, v in pairs(context.cards) do if v:get_id() == 9 then card.ability.extra.count_nine = card.ability.extra.count_nine + 1 end end?
Adding an event for animation purposes in context.before that grants enhancements to scoring cards seems to not make the enhancement apply during scoring, is there a way to fix it?
No, you have to put it outside of an event.
It can't be calculated if it's in an event.
I see, so you can't really make a flip animation in that case if i'm not mistaken
it works great ty
how do I add a sticker to a given card
SMODS.Stickers["modprefix_key"]:apply(card, true)
thank u :>
I want to have a single planet card for 7 similar hands, but if I do that then they wouldn't work with Blue Seals because that only checks config.hand_type of the planet cards, which can only hold one hand. Any ideas for potential workarounds?
You patch where blue seal is calculated?
So it has to have true after ... .total_rounds?
Then I have to learn how to do patches 
That's probably the reasonable way, yeah. Is there a guide on that I can read?
Thanks
No, you have to modify those values so it can be true.
whats does collection rows mean in this example
SMODS.ConsumableType {
key = 'vremade_Spectral',
default = 'vremade_familiar',
collection_rows = { 4, 5 },
primary_colour = G.C.SET.Spectral,
secondary_colour = G.C.SECONDARY_SET.Spectral
@daring fern
When you open your consumable in Collection, it's the amount of cards that shows per row
How would I go about duplicating a card
Use copy_card
When you look at the type in Collection, the first row can have up to 4 cards and the second row can have up to 5 cards
is it not already? some mods create a "food pool"
thank u
I'd recommend 2, 1 otherwise youll have a weird empty row below
oh
what's the issue when it comes to pools that's being discussed?
what about 3, 0
what will happen?
nvm i realise now that its a manually created thing and has crossmod issues if its not added properlu
They'll be on the top row
What are the parameters for that
I wanted to do like a generic card (like it could be a joker/consumable/playing card)
There can be any number of rows, I think.
so i can just say 3 and be done with it
I tried to read back up and see what the issue was for pools, as I'm considering seeing if I can set something up for it for smods to make crossmod stuff easier without needing to incldue everything during coding. But discord's not showing any messages when I scroll up
Probably.
The context is it's to do with a sticker's functionality
The first parameter of copy_card takes the card you want to copy
so for example copy_card(G.jokers.cards[1])
is pos always 3,4?
No?
oh you can use just one parameter?
neat
I thought you had to use four
Actually I think for playing_card you need the fourth parameter too?
my first mod so pear with me ...
Here's an example w a playing card
so what defines pos??
You?
o
is it like a thing I'd have to do case-by-case for each card type so that the sticker behaves correctly
Non-playing cards don't need the fourth parameter, unless you wanna strip edition or something
What sticker effect are you doing?
How do I do that? Putting true somewhere? (Say, in the parenthesis or before then)
Pos is the x,y position of your sprite in your spritesheet
It duplicates the card when it's applied and then if the card is still there by the end of the round, both cards are destroyed
id its only one sprite, i put 0,0?
And it works for all kind of cards?
Yes
that's the idea
For the fourth parameter you can do (card and card.playing_card and G.playing_card) or nil
No, it's G.playing_card
nope
That was easier than expected, I got it (almost) first try (we don't count the attempt where I spelled the planet key wrong) :3
Nvm it is my bad
Both are used in the code
@thorn furnace There's no s in playing_cards sorry
yea no worries
can someone explain this line to me, need to understand so i can modify
info_queue[#info_queue + 1] = G.P_SEALS[card.ability.extra.seal]
info_queue is the list of extra info tooltips, #1116390750314307698_queue is the amount of things in that list
info_queue[index] gets the entry at the index; #1116390750314307698_queue + 1 would be a new index, because it comes 1 after the highest entry
and then it sets that entry to the seal set in the cards extra thingy
oh, i get it now, thx absent
It's a lua W that they do arrays like that
(card.ability.extra.invis_rounds >= card.ability.extra.total_roubds) true then ?
-# I think technically #info_queue + 1 doesn't always give a fresh entry, if the list isn't already in order, but the assumption is that no one goes out of their way to set entries at weird places for no reason
i mean I assume it just gives the memory address at that point
it does because # doesn't count if they're not in order so # + 1 will always be empty unless im being stupid
if you're talking about if some other thing sets something to nil then no
that doesnt remove the element
the corresponding key or index will still exist
I'm still getting used to lua, so I could be wrong, but the way I see it:
If the list has entries at index 3, 4, and 5, but is otherwise empty, then it has a length of 3
and #array + 1 would then be 4, which would already be set
.
indices can have nil values
it wouldn't make sense otherwise
what wouldn't make sense
Yea
It seems like it's counting just the total number of used indexes
So it'll always be new
Having entries at indexes 3, 4, and 5 still leaves 1 and 2 existing
so #list + 1 would be 6
Then is #array not the length of the table? 1 doesn't make any sense to me there
no I don't think that's true
it is if it's a proper integer-indexed array
otherwise no
the argument that indices 1 and 2 would be skipped only applies if the table is a dictionary
which is not the case
I'm pretty sure they are skipped
is this code correct for a spectral consumable that adds seal?
-# The easy way to find out is to run it and see :3
what I've gathered is that list wouldn't have the # operator defined for it
Because the length of a table t is only defined if the set of its positive numeric keys is equal to {1..n}
but {nil} is skipped
i hate this language
Hmm intteresting
tried running nothing is shown
What do you mean with nothing is shown?
if it has nil then it shouldn't count
{10, 20, nil, 40} isn't a sequence and thus the length shouldn't be defined
the lua manual lied to me
that is still a sequence
game crashed when i looked up seals
something is after nil
there was nothing in spectrals
so it would count as such
but there's a hole in the sequence
nils only don't count IF its the last element in the array
it's not equal to some {1..n}
you tell me that
int array[] = {40, 10, NULL, 20}
isnt a sequence
Well what's the crash message?
I'm quoting the manual
dont know how to copy all the text ...
A table with exactly one border is called a sequence. For instance, the table {10, 20, 30, 40, 50} is a sequence, as it has only one border (5). The table {10, 20, 30, nil, 50} has two borders (3 and 5), and therefore it is not a sequence. The table {nil, 20, 30, nil, nil, 60, nil} has three borders (0, 3, and 6), so it is not a sequence, too.
i think it makes sense when an array is always an array but not when the array is not always an array
Looks like probably some localisation isn't right or missing
blame lua for making tables both arrays and dictionaries
which version of lua is this for
ok to explain what i have
i have main code which "summons" other codes as shown
thought the problem was cause joker.lua was empty
so i tried removing that and then this happened
i hate this
when the table has multiple holes it seems to create UB with the length operator
Can we just collectively rewrite this in C
Like when _jeb and the others were making Minecraft Java and they said "hey Java sucks let's rewrite this entire thing in C++ instead"
Probably forgot to close some bracket or if statement somewhere, and that's why the file fails to load
Thinking about setting up a probability function for Smods, but I don't think everyone checks the feature requests there, so linking it here in case people have thoughts
or its cause i didnt add the new seals in the seals code
You better not know how arrays work in JS 
This crash basically always means you're not closing or ending a function or bracket somewhere.
gonna go search for that then ...
Traditional array with values nil, 1, nil, 20, nil
#: 4
pairs: 4
ipairs: 0
Dictionary with values 1: hi, 2: nil, 3: hello, 4: world, 5: nil
#: 1
pairs: 4
ipairs: 1
What you think about 3 possible values of "nothing" in JS arrays? 
dont even get me started on js
i dont think about js sorry
in general table count counting in lua is very stupid
just note that pairs skips nil values and continues and ipairs doesn't
It's straightforward: start from 1, check value by this key, if nil then stop
yeah this is basically why i thought it skipped them
you can chalk it up to lua implementation being the weirdest thing ever
The fact that string keys and number keys are different is crazy
god i wish discord on mobile displayed code properly
this is the 4th diff crash now
tbf it's barely formatted pseudocode because I wrote it on mobile too
im adding a joker that makes fun of this for no reason whatsoever
"guess the table n count joker"
let's goo
is this not the exact same crash as you posted earlier?
..... 
and here i thought i sloved it
i really had 3diff crashes after it when i modified the code
😩
can you show your code in some screenshots?
i can stream if u are up to a VC...
screenshots are a lot easier, I'm technically still working atm, haha
It's not the solution for it, but I really recommend getting a vsc extension to colour match matching brackets
that's very, very helpfulf or issues like these
but yeah, you're missing a bracket, two lines above key = 'phantom'
this one?
I can check which one I use when I'm home, but I'm not sure which one is best or if they all work for lua, sorry
Sorry to jump back
Uh
I think something went wrong
You still need to add to deck and emplace.
at this point it's probably just better to handle jokers vs consumables vs playing cards on a case by case basis
I was hoping I wouldn't have to do that :/
it worked
thx
Increasing the cost doesn't work with multiplication? Yes, if I just add a number it works, but if I try to multiply... nothing seems to happen
why...
Emplacing is general, so it's not specific to object I think
o
Oh nvm it's not emplacing that is
i mean you still have to like
G.hand:emplace(card)
hold on lemme dig SMODS utils
card.area:emplace(card)?
o i didnt kno u could do that
Yea you can use SMODS.add_card
I was thinking about that
Or that
add_card would just be one line
now i remember why i stopped coding 2 years ago ....
Oh actually SMODS.add_card allow for using the card itself as a parameter
You need to try
Goes like SMODS.add_card(card) and that's it, no emplace or anything
Wait I think I'm reading the lsp wrong
Oh no it returns a card mb
I mean honestly it's not too bad to just copy like the key and the edition and whatnot
though it does kinda mess up stacking jokers
lemme check the source code
why are you using visual studio for lua 😭
yall hate on vs too much fr
what should i use then
oh
i know its diff program
lazy to download it now
maybe later
and vs works just fine
But yea do as Something said, add this bit from SMODS.add_card directly into your code
card:add_to_deck()
local area = t.area or G.jokers
area:emplace(card)
oki
does the add_to_deck() part work for jokers and consumables too?
baller
knight
Unfortunately the cards appear to still float around
Unchained from any of the three coils destined to capture it
Show your code
apply = function(self, card, val)
local copy = copy_card(card, nil, nil, card and card.playing_card and G.playing_card or nil)
copy:add_to_deck()
card.area:emplace(card)
end
copy.area:emplace(copy)
reposting things from the smods server
i know a lot of you are not comfortable making issues on github so if there's anything you think should be easier to do with smods let me know and I'll see if I can figure out something
I'm not fixing the docs tho
I'm bad at writing
Can a joker be not found in shop or duplicated from other effects when its already owned? Im trying to make an unduplicatable joker
got it
Add a PR to SMODS so I can make Jimbo say a swear word 😈
i recommend the lua extension by sumneko
i need to figure out how to make code that can only be run by a specific individual but sure
already have it
You would need to probably patch where the game looks for showman to get rid of copies in the shop (or wait for this to be merged and hook it https://github.com/Steamodded/smods/pull/717)
For copying in general, hooking copy_card and create_card to avoid generating more when already own might work
also I hope you played my mod and tried out subterrors lol
ok now i got vsc, that doesnt fix the problem tho ...
this
Ahaha i do play subterror yea, and will do
it's a bit of a journey but there appears to be one more issue with the sticker
It doesn't actually get applied to either the card or its clone
It just clones the card and vanishes
i mean tried out subterrors in the mod haha
Show your whole seal code
me?
No
SMODS.Sticker {
key = "kiss",
badge_colour = HEX('c261bd'),
apply = function(self, card, val)
if card.area then
local copy = copy_card(card, nil, nil, card and card.playing_card and G.playing_card or nil)
copy:add_to_deck()
card.area:emplace(copy)
end
end,
calculate = function(self, card, context)
if context.end_of_round and not context.repetition then
SMODS.destroy_cards(card)
end
end
}
What is up with the formatting getting ruined when I paste these things
Discord window too small
i mean like it replaces each tab with like three tabs
I haven't paid attention to your issue up til now, but that sneaky little and at the end there might be causing problems for you
oh
that was a typo it's not in the code
can i see your localization file
honestly some weeks at work i use vscode more for regex stuff than coding haha
oh yeah that's your problem
wow .Lua
you're missing a loc_txt or localization file
Can you add a print(context) above SMODS.destroy_cards to see which context goes trought that'd cause this
oki
tho the cards don't actually get destroyed at the end of the round so it might not trigger
and here i knew that i was missing something but was ignoring it
Didn't you say the card gets destroyed?
where did the b go
It's Like lua But Every Word Begins With A Capital Letter
the b got returned to canichatandobserve
The sticker just doesn't appear on the card
It clones the card and then the sticker vanishes
she doesn't have infinite bs
From the og card or copied card?
both
so i just make a folder named localization and thats it or does it need something inside?
it doesn't appear on either of them
But the card gets cloned so obviously it does something
well it needs a localization file inside with all the text
will figure it out
You didn't set a pos
There's no sprite loading
I think
I mean it's not like the game's crashing due to failing to load an image
Well yea cuz you're loading none
everything else seems to have a default image
im looking at it rn
Try setting a pos but without the atlas
i have it installed
See if vanilla seal sprite work and don't dissapear
and it shows up in Collections
oki
it does
I don't understand how is a seal sprite is showing up when none is specified
it's a sticker
Oops mb
Also I forgot SMODS.Sticker might have default values in it's constructor
Ok yea it does, so that's weird
yea
I see the constructor has this in it's apply fucntion try adding the line too in your apply func
At the beginning
thank u :3
Once I am done this mod it will be peak
not Cryptid levels of broken but definitely easier
(not because I want it to be broken but because I'm bad at balancing things while maintaining thematic relevance)
did you draw this
yes

It was going to be cryptid levels of broken before I started balancing it
now it's just like
Moderately good
yep, cant figure out localization ...
On the note of the consumable in this pic uhh
Is there a proper way to create a consumable that adds a sticker to any selected object
In my code I just have it like this and it barely works (and doesn't work for consumables)
use = function(self, card, area, copier)
if #G.consumeables.highlighted == 1 then
SMODS.Stickers["jojo_kiss"]:apply(G.consumeables.highlighted[1], true)
elseif #G.hand.highlighted == 1 then
SMODS.Stickers["jojo_kiss"]:apply(G.hand.highlighted[1], true)
else
SMODS.Stickers["jojo_kiss"]:apply(G.jokers.highlighted[1], true)
end
end,
can_use = function(self, card)
return (G.consumeables and #G.consumeables.highlighted == 1)
or (G.jokers and #G.jokers.highlighted == 1)
or (G.hand and #G.hand.highlighted == 1)
end
i mean it's not going to work for consumables unless you make the highlight limit bigger
and check for the other card highlighted
How would one go about that in this case
Hypothetically
Asking for a friend
G.consumeables.config.highlighted_limit iirc
but it's kinda complicated if you dont want to change the limit all the time
Not exactly the same case but I have consumables that let you highlight 8 cards and the logic is kinda dumb
I'm guessing there's like a while_holding function or something I put that in
they have an add_to_deck and remove_from_deck functions
oh
I thought that would've stayed active even with other items
Ah, lol okay
im gonna kidnap someone from here and make him do the code 
it stays active as long as you have the card, if you want anything more complicated you might need to hook card:highlight or something
but honestly, I would make it either random or always target the first card lol
I wanted to know if there is any version of Balatro where the code is open, just so I can take as an example what localthunk did and help with my mod
You can extract the .exe and get all the code or look inside the lovely/dump folder in your mods folder
here are a lot of the objects implemented in smods which might help too
https://github.com/nh6574/VanillaRemade
How do I do this?
...why all of this on one line...
for _, area in ipairs(SMODS.get_card_areas('jokers')) do for _, _card in ipairs(area.cards) do
nested fors are icky so if theyre in one line it's like they're not there :3
Not helpful if I want to intercept the "for" loop creation and adjust it in the same way I did with SMODS.calculate_main_scoring...
-# Guess I need an another shot at the SMODS.get_card_areas hook.
you can always use a regex patch
...if I knew how to use it for such, I'd do it.
what are you trying to add?
how can i make so the joker has a description on the side with the description of the joker it is copying?
by description i mean these things
info_queue[#info_queue+1] = G.P_CENTERS[key_of_the_copied_joker]
Something like this... or I could probably try to stuff it all in one line instead?
you can with ;
What I want to do is make a custom deck that makes my modded jokers appear more frequently, but it doesn't seem to have any effect
Or maybe I'm blind or it's confirmation bias
Write what by hand?
the joker descriptions
No, it does it for you.
where are you using that
loc vars
does it display an empty box? does it crash?
can i see more code
key = "soulwheel",
loc_txt = {
name = 'Soul Wheel',
text = {
'Every round, will change its',
'soul copy.',
'#1#',
}
},
atlas = 'soulwheel',
cost = 4,
pos = {x = 0, y = 0},
config = { extra = {
text = "{C:red}Determination: +2{} mult"
},
},
blueprint_compat = true,
loc_vars = function(self, info_queue, card)
info_queue[#info_queue+1] = G.P_CENTERS['j_ub_determination']
return { vars = {card.ability.extra.text} }
end,
set_badges = function(self,card,badges)
end,
calculate = function(self,card,context)
if context.repetition and next(SMODS.get_enhancements(context.other_card)) then
return { repetitions = 1 }
end
end
}```
how can i check the edition of a card?
uhh no idea, are you sure the key is correct?
card.edition
uhh yeah
wait
no
it was det
😭
how would i do something whenver the player spends money?
so it'd be like this?lua if card.edition == "editionkey" then
Hook ease_dollars
dont know what that means
No, it would be if card.edition and card.edition.key == "e_modprefix_key"
so something
ok thanks!
which part, hook or ease_dollars?
Here's what I did!
both
The code on the bottom is a hook, that lets the joker's code know when the money value changes, and by how much
ease_dollars is the function used when altering money.
hooks: https://forums.kleientertainment.com/forums/topic/129557-tutorial-function-hooking-and-you/
ease_dollars is just the function that adds to the dollars counter and does the little update animation
Hooks are freaky
instead of the loop i recommend SMODS.calculate_context{MLP_ease_dollars = to_big(mod)}
I plucked the hook code from ExtraCredit "Hoarder"
Now it is this, way more elegante
what are mod and x
x is instant and mod is how much to change the dollar amount.
what do you mean x is instant
x is replacing instant
dont know what instant is
It doesn't use an event.
So it goes instantly.
And by setting the hook's variable to mod, it lets me use that value in a Joker's effect, right?
Yes.
how do i check if the money change was caused by spending?
if to_big(mod) < to_big(0)
Okay, thank you helping my understanding
wouldnt that one playing a card loses you $2 boss blind also activate that?
Yes.
can i stop it from activating that?
if context.MLP_ease_dollars and to_big(context.MLP_ease_dollars) < to_big(0) and not context.blueprint then
It's checking if the ease_dollars value is negative, which means that money is lost
You would probably patch where it calls it and set a global variable and check for that in the hook.
Hello. I'm using SampleJimbos as a reference for coding a joker but I find it a bit annoying due to it having more than one joker, and the structure of what's needed within my own lua file is not easily recognisable from the different original files.
Is there any other reference I can check out there?
so i have no idea how i would even go about that
Am I able to separate jokers into separate lua files instead of having all of them in one big file and if so how would I be able to
yea
good opportunity to learn!
just load the files
i do need somewhere to learn how to do them from tho
the lovely github
and check the patches in other mods
Speaking of lovely patches...
how can i get a list of all Tarot cards in the game?
many thanks
G.P_CENTER_POOLS.Tarot
yes?
card.config.center.key
One line... and I make Consumeables do their thing before Jokers. 🧠
this is a good start but the jokers are still in a big lua file, do you think its ok maybe like ```lua
local jokers_to_load = {
"my_joker"
}
for k, v in ipairs(jokers_to_load)
assert(SMODS.load_file("content/jokers" .. v .. ".lua"))
end```
yes
okie dokie, ty
this is how i do it in my mod https://github.com/nh6574/JoyousSpring/blob/ba699ffdde89a3bcd438e1111ecff78c1bdd2924/JoyousSpring.lua#L29
I want to make a custom deck that makes the jokers from my own mod appear more frequently, similar to this one from SDM_0's stuff
But when I try it in game, it doesn't seem to have an effect on the Joker's rates
Maybe it's confirmation bias, or I'm blind and missed something in my code
oh yeah i saw that
but i dont have the code for the game with me rn
to see if the patch makes sense
Anyone know how to fix this? I'm trying to add 10 playing cards with lucky enhancement on them at the end of a ante boss but the card just stays there
People yearn for the per-card rarity system
Here is the patch for the deck's effect, and the deck itself
I have been following a tutorial and this code is not working and I can't figure out why
I know the effect is not gonna work but
I just want it to appear
try removing the meow at the beginning
Your header is wrong.
mm, i've extended looking at all Tarots to all Resource cards, and this is crashing:
local resource = pseudorandom_element(G.P_CENTER_POOLS.phanta_Resource, pseudoseed('monopolychosenresource')).config.center.key
(haven't tested this on the Tarots, this is what i wanted to do)
do i need to add next()? instinct is telling me that'd do something
It would be just .key
ah ^^" cheers
It needs to be ```lua
------------MOD CODE -------------------------
``` instead of just Code
I think.
wait its that strict??
Yes.
yay! that worked :D
It's still not working ;-;
oh hey ghost
heyoooo!!
It needs to end with ```lua
------------MOD CODE END----------------------
yeah I added that
What does the current code look like?
hey yall, any ideas on how to stop this from destroying all card played if there is a heart and have it only destroy the hearts.
for _, card in ipairs(context.scoring_hand) do
if card:is_suit("Hearts") then
return {
message = "Upgraded",
remove = true
}
end
end
end```
Try removing the space at the end.
Try adding a space between --- PREFIX and ----------------------------------------------
if context.destroy_card and context.cardarea == G.play and context.destroy_card:is_suit("Hearts") then
that also did not work
I think the problem is in another place than the code
Try removing the header entirely and just using a JSON
?
Do I replace this part with that?
@red flower going back to the unduplicatable joker thing, i decided to just make my joker self destruct if theres another copy
makes sense
you delete that and have another .json file with what the wiki says
Btw thanks for the help
I was about to suggest that as opposed to egging on the header usage
Lol
hi astra
Hello N
I added this and its working now thank youuuu!!!!
I fixed it
is there documentation for quantam enhancements
thinking of ways to implement this and i feel like id have to use wild card quantam enhancements, right?
ok i found this but it just. says what quantam enhancements are without giving what function to use lmao
i have a quantum enhancement
i can show u
that would be appreciated
if cardarea == G.jokers and context.before then
if (context.first_hand) then
for k, v in ipairs(context.scoring_hand) do
v.SMODS.has_enhancement(v, wild) true```
something like that
A much easier way to do that is to set card.any_suit to true before scoring and remove it afterwards (assuming it doesn’t have an enhancement that does that already)
Or smthn like that
^ obviously not the correct syntax for the func but
you would need if context.check_enhancement and context.scoring_hand then
and on the return a return { m_wild = true}
oh there's an any_suit variable?
just setting it to true should work
also you have to enable quantum enhancements
It’s not a function, it’s an attribute
return {
quantum_enhancements = true
}
end```
this is for quantum enhancements to enable
what i meant yea
But yes it is
i always assumed i would need it to be specifically a wild card because stuff like flower pot specifically checks for the wild card enhancement in vanilla code
unless steamodded changes that to check for any_suit?
I think it might actually
i see i see
How I get the chips amount from a card in calculate func?
card.ability.chips, or card.ability.extra.chips if you have it on config extra
If I define a
Config{
extra{
chips= x
}}
This chips amount will replace the original amount of chips from a marked card?
getting an 'unexpected symbol near "," ' error, but I've no idea where to start looking for that error, no line is provided
send code
For example, a card marked with a seal
i think that should do it
this is in my code (chip_gain not necessary)
Usually the error is above of error line
json, sorry lol
remove last ','
Ty, I gonna try
np
np too
You can "comment"
https://www.freecodecamp.org/news/comments-in-json/
im not into json so yeah i didnt search it
Can anyone point me to where in the code it creates the bar where the Jokers go? (Or the Consumables bar. I suppose either would work.) Attempting something stupid so I don't want to drag anyone else in farther than I have to.
i simply tried to do it with -- but it doesnt work
what bar?
You mean the card area?
Yes, the card area.
o
The UI section on SMOD API would help
https://github.com/Steamodded/smods/wiki
tbh they should pin this
(the docs)
Fantastic, thank you. I've read the smods UI article several times today but was getting nowhere.
yeah those are not UI elements in the same sense, they're objects like cards
That explains the disconnect I was having between what I was reading and what I was trying to accomplish.
Thanks.
I want my Joker to give +3 hand size at the beginning of the round and then take the hand size away when the second hand is played.
Using context.first_hand_drawn kills the player after selecting the blind (because for whatever reason the -3 hand size happens several times)
Using G.GAME.current_round.hands_played == 1 makes the +3 hand size work at first hand but then does the -3 hand size several times at second hand, bringing the hand size down to 0.
How do I make the -3 hand size work only once?
if context.hand_drawn and G.GAME.current_round.hands_played == 1 then
see if that works
Yeah, it works now. Thanks!
was that for me?
the only thing I'm kind of using that's oudated is maybe samplejimbos, but I'm moving away from it to moddedvanilla examples.
other code I'm using is that from the game luas themselves
the joker is functionally similar to invis joker so I just checked what the og files had on it, but they are confusing
yeah there's a lot of stuff there that was for smods 0.9.8 that it's done differently now
vanillaremade has invisible joker if you are interested
checking it out rn
Im trying to make to make the joker give 33 chips but it keeps doing something else than that :< Is there a big mistake in this code?
Just do return { chips = card.ability.extra.chip }.
uhhh where do I need to add the end?
After the return.
Also move the end inside the table.
oh yea
i might be stupid
Quick question over vanilla remade's invis.
is this the section that checks for other jokers in hand or is it this one?
How do I make an object appear under "Other" in the collection?
Theres apparently an unexpected symbol near line 35 which I can't see
The one that copies is the bottom one, the one that adds the Remove negative from copy is the top one.
You're still missing an end
Every function and if and for and while needs an end
current money is G.GAME.dollars right
Yes.
oh wow this worked perfectly thank you
thanks
The current blind score is G.GAME.chips and yes.
and i’m assuming current mult is G.GAME.mult?
No, it's just mult
i want current chips and current mult, i’m trying to see if the score is gonna set on fire
so current chips is just chips then
mhm
alright
No, it's hand_chips
math.floor()
math.ceil()
Yeah the built in lua math library is math
Annoying because I think the one for Javascript was Math so coming over from JS from my last project I keep screwing it up
i'm making a consumable that converts 3 cards into random enhancements — what's the best way of doing this?
Use SMODS.poll_enhancement?
what does that do, again? ^u^"
It gets the string of a random enhancement and it respects weights.
is it possible to modify a spawn rate of a joker
awesome :D thanks!
wait one more thing, does it take any arguments?
ah :D tyty
for example i want a certain joker to spawn more often in the shop
if a joker is present
alright so smallll issue with something I'm trying to do. I'm trying to add a card to the deck directly, and for some reason it only adds to the "temp limit" and not the actual limit (ie can't see it in the deck preview)
FaeLib.Builtin.Events.BlindCompleted:register(function (blind)
if (FaeLib.Tags.BossBlinds:contains(FaeLib.Builtin.GetCurrentBlindKey())) then
for _, value in ipairs(G.jokers.cards) do
if FaeLib.ForagerCards[value.config.center.key] then
G.E_MANAGER:add_event(Event({
trigger = "immediate",
func = function()
SMODS.calculate_context({ playing_card_added = true, cards = {FaeLib.ForagerCards[value.config.center.key]:create()} })
return true
end})
)
end
end
end
end
)
ForagerCard.create = function (self)
local card = SMODS.add_card({area = G.deck, key = self.card_to_create.key or self.card_to_create.config.center.key})
return card
end
In this case, card_to_create is a SMODS.Enhancement
It properly creates the card but doesn't add it fully
is there a way for me to get whatever i've done added into my hand?
whatever i've done is a pretty good descriptive heh
add the joker I coded into the joker bar without finding it in-game
thx
Use create_playing_card
is there a calculate_dollar_bonus func for jokers or does that one need hooked
Yes, it's calc_dollar_bonus
What repository is this screenshot from?
Using create_playing_card({area = G.deck, center = "m_hime_fruit_enhancement"})?
No.

self, card, context ?
🙏
What does your loc_vars look like?
it's empty apart from the function(self, info_queue, card)
that may be it actually
but I'm unsure what should go there then
<- oopid
no, i had to make an individually weighted system for that
you can add a fake rarity to it maybe if it's just one joker
return {vars = {card.ability.extra.accountant_rounds, card.ability.extra.total_rounds}}?
later in the code they are referenced as card.ability.extra.accountant_rounds/total_rounds
and the main function of the code is after a calculate = function rather than the loc_vars
yeah, fixed by adding the extra stuff yeye
I have a question, is there like a wiki that has a full in depth explaination on what every thing means and has for variables, etc.? Like for example in the C# microsoft wiki?
thx
due to my mod but outside of my mental grasp
Heyo people, wanted to try and test out modding this game, am both very unexperienced with doing so and coding in general, are there any rescources I could follow to get some guidance? I cant find anything on google about actually writing mods for the game, just how to install stuff
damn, thanks
where’s this mythical steamodded visual studio code extension i hear of
I want to debuff a card halfing they chips, What I can do?
calculate = function(self, card, context)
if context.pre_joker or (context.main_scoring and context.cardarea == G.play) then
return {
chips = -(card.ability.chips / 2) --card.ability.extra.divisor) --card.ability.value_multiplier * self.base.nomimal
}
end
end
}
I tried this and don't work
Is this an edition?
No, is a seal
context.pre_joker doesn't happen on seals on playing cards?
it's a machination of your dreams, there's no such thing afaik
you can add the steamodded folder to your project to get lsp definitions tho
what are the primary and secondary colours of a consumable type used for, again?
is there a method for getting the suit of a card?
I want to get the suit of a card and save it into a variable, so I can check something later
card.base.suit
thanks!
One is used for the collection and one is for the badge I think.
I mean, the seal and context are fine but appaers a error code because card.ability.chips is nil
is is_suit = function(suit, bypass_debuff, flush_calc) valid
It would be card.ability.seal.chips
darn
mm, the secondary colour seems to be used for both
how
i don’t use vsc usually
(ignore the loc error)
in an intellij enjoyer
i just open the mods folder in vscode, but you can also add it to the lua config i dont recall how exactly
that would add extra chips, I'm wrong? I want to reduce the base chips or atleast subtract
card.base.nominal = card.base.nominal - number
that would be inside the calc func?
Yes.
is there a possibilty I could have a loop, that does not crash the game?
Yes.
What would that loop look like?
for k, v in pairs({}) do end
calculate = function(self, card, context)
if context.pre_joker or (context.main_scoring and context.cardarea == G.play) then
return {
card.base.nominal = card.base.nominal / 2 --card.ability.extra.divisor) --card.ability.value_multiplier * self.base.nomimal
}
end
end
like that?
Move it outside of the return.
thanks, this also allowed me to fix several bugs in my code
if context.pre_joker or (context.main_scoring and context.cardarea == G.play) then
card.base.nominal = card.base.nominal / 2
return {
card.base.nominal --card.ability.extra.divisor) --card.ability.value_multiplier * self.base.nomimal
}
end
end```
Remove the return.
I do not understand a single thing in that line except for for do and end 💀 Could you please explain it? I also looked it up on lua.org but I do not understand it 😭
isn't it necessary?
No?
i’m nil checking way more
It loops over an empty table and does nothing.
oh, I gonna try
oooh, how would I break out of it?
break
oh okay thanks!
Dind't work unu
how might one implement
function Card:is_suit(suit, bypass_debuff, flush_calc)
if card:is_suit("Hearts")
ig my question is like
So I have this line of code local current_suit = context.other_card.base.suit that crashes my game, why doesn't that work?
in the same way as smeared joker
how can i make lists on lua?
like for example spades and hearts are functionally the same
You need to hook Card:is_suit
Code?
okay yeah thats what im doing but its not working at all
local list = {a, b, c} now list[1] is a, list[2] is b and list[3] is c
function Card:is_suit(suit, bypass_debuff, flush_calc)
if flush_calc then
if next(find_joker('Plaid Joker')) and (self.base.suit == 'Hearts' or self.base.suit == 'Spades') == (suit == 'Hearts' or suit == 'Spades') then
return true
end
if next(find_joker('Plaid Joker')) and next(find_joker('Smeared Joker')) then
return true
end
return self.base.suit == suit
else
if self.debuff and not bypass_debuff then return end
if next(find_joker('Plaid Joker')) and (self.base.suit == 'Hearts' or self.base.suit == 'Spades') == (suit == 'Hearts' or suit == 'Spades') then
return true
end
if next(find_joker('Plaid Joker')) and next(find_joker('Smeared Joker')) then
return true
end
return self.base.suit == suit
end
end
if G.GAME.current_round.hands_played == 0 then
if context.before then
local current_suit = context.other_card.base.suit
for k, v in pairs({}) do
local random_suit = SMODS.change_base(context.other_card, pseudorandom_element(SMODS.Suits, pseudoseed('suits')).key)
if current_suit ~= random_suit then
break
end
end
end
end
end```
oh so it isnt []
ok
You need to hook it not overwrite it.
wait didnt they start by 0
No.
lua is not 0 index, usually
[] is for a certain item in a table, so table[3] would give you the third result in a table
{} is for the table itself
yeah but in other languages [] is the list yk
im only familiar witu lua
how do i hook it instead of overwriting it?
generally other languages differentiate between an array and a map/object/dictionary, however you wanna call it
local oldissuit = Card.is_suit
function Card:is_suit(suit, bypass_debuff, flush_calc)
return oldissuit(self, suit)
end
thank you
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
guide to function hooking in lua
why did they have to add the and you 😭
🫵
So does anyone have a Solution for that? Here the code again
if G.GAME.current_round.hands_played == 0 then
if context.before then
local current_suit = context.other_card.base.suit
for k, v in pairs({}) do
local random_suit = SMODS.change_base(context.other_card, pseudorandom_element(SMODS.Suits, pseudoseed('suits')).key)
if current_suit ~= random_suit then
break
end
end
end
end
end```
context.other_card doesn't exist in context.before
oooh okay that makes sense
how are jokers named in things like this? (like j_key_key or any other way)
huh?
i mean
the first key would be your mod's prefix, then the second key would be the joker's key
that's not it
I removed the if, but the game still crashes :/
i meant
imma send the whole code idk how to explain it
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then
other_joker = card.ability.extra.soul
end
end
if other_joker and other_joker ~= self then
context.blueprint = (context.blueprint and (context.blueprint + 1)) or 1
context.blueprint_card = context.blueprint_card or card
if context.blueprint > #G.jokers.cards + 1 then
return
end
local other_joker_ret, trig = other_joker:calculate_joker(context)
if other_joker_ret or trig then
if not other_joker_ret then
other_joker_ret = {}
end
other_joker_ret.card = context.blueprint_card or card
other_joker_ret.colour = G.C.bluepring
other_joker_ret.no_callback = true
return other_joker_ret
end
end```
If you remove the if, contexts that don't have context.other_card are being called.
it works like a blueprint
but with an specific card
that you dont necessarily have to have it
Use SMODS.blueprint_effect
where?
So how can I check before scoring, and save the suit of a card into a variable then?
Instead of everything after the for loop.
What card are you trying to check?
I am trying to check every scoring card
so its looking for copies of itself?
could you put the effect in plain text please
You would iterate over context.scoring_hand
if you dont need to have it then that's more complicated
wait later ive to dinner
:P
I have a joker that does that.
I am trying to randomize every single card a random Suit, which works but the problem is that sometimes a card gets randomized to the same suit, and I want to reroll that again for every card that lands on the same suit
and the 2nd part of the thing I'm trying is not working
So you want every played and scored card to be changed into the same suit?
no
Like for example a pair
the one card gets turned into spades
and the other to hearts
but the issue is when randomizing lets say a spades card, it can be turned into a spades card
how are you randomizing the suit right now
.
local random_suit = SMODS.change_base(context.other_card, pseudorandom_element(SMODS.Suits, pseudoseed('suits')).key)
I would make a new table with all the suits except the card's and do a pseudorandom_element on that
my problem right now is that it is crashing at local current_suit = context.other_card.base.suit
yea but if I remove if context.before then it still crashes
so this would work right?
if G.GAME.current_round.hands_played == 0 then
for _, playing_card in ipairs(context.scoring_hand) do
local random_suit = SMODS.change_base(context.other_card, pseudorandom_element(SMODS.Suits, pseudoseed('suits')).key)
if playing_card.base.suit ~= random_suit then
break
end
end
end
end```
so it works, but not in the intended way, I just tryed it hahahha
It should only randomize the played/scoring card not the entire hand 😭
you still need context.before
but idk what you're trying to do exactly, can you explain it again?
lets say you are playing a pair with a spade and a heart card
the spade card gets turned into diamonds (it could also get turned into anyother suit except spades)
and the heart gets also turned into diamonds for example (it could also get turned into anyother suit except heart)
if context.before and G.GAME.current_round.hands_played == 0 then
for _, playing_card in ipairs(context.scoring_hand) do
local valid_suits = {}
for key, _ in pairs(SMODS.Suits) then
if key ~= playing_card.base.suit then valid_suits[#valid_suits+1] = key end
end
SMODS.change_base(playing_card, pseudorandom_element(valid_suits, pseudoseed('suits')))
end
end
like this?
maybe I'll try it really quickly, but I don't have an idea what the valid_suits[#valid_suits+1] excatly means :/
it appends to the end of the array
ok so does it add the suit to the end of the array?
it adds all suit keys in SMODS.Suits to a new array except the one the card has
ooooh ok I get it now
so the code does nothing now
like nothing happens when I play a first hand
uhh maybe the keys are wrong
you probably have to append value.key instead of the key
if they're different at all
i dont think so
if context.before and G.GAME.current_round.hands_played == 0 then
for _, playing_card in ipairs(context.scoring_hand) do
local valid_suits = {}
for _, v in pairs(SMODS.Suits) do
if v.key ~= playing_card.base.suit then valid_suits[#valid_suits+1] = v.key end
end
SMODS.change_base(playing_card, pseudorandom_element(valid_suits, pseudoseed('suits')))
end
end
might as well try it
btw the second for needs a do, if not it will crash
oh yeah yeah
still does nothing :/
Should we try again with randomizing it until it is not the same suit?
cause I'm confident that that randomizing works, since it worked before
that code looks fine to me
can you share what yours looks like
after pasting that in
if context.before and G.GAME.current_round.hands_played == 0 then
for _, playing_card in ipairs(context.scoring_hand) do
local valid_suits = {}
for _, v in pairs(SMODS.Suits) do
if v.key ~= playing_card.base.suit then valid_suits[#valid_suits+1] = v.key end
end
SMODS.change_base(playing_card, pseudorandom_element(valid_suits, pseudoseed('suits')))
end
end
end```
me neither, make sure you saved the file, restarted your game and started a new round
yeah I did that
do you have debugplus
the only thing was that it crashed at other_card.base.suit
wdym?
the mod #1228149931257237664
nope will get it now tho
i was going to ask you to print(valid_suits)
you can do it without that but debugplus makes it nicer
Now I have it
add print(valid_suits) after change_base
and wrap the change_base call with assert()
wha
assert(SMODS.change_base etc etc)
it sayed tryed to call something
Did the game crash
no
can you press / and screenshot the message
i think your pc is cursed
yea it might be
/ should open the console
there should be a key that opens the console
alt or shift / if your settings are set up that way, no?
so / I am doing with shift 7
yes
😭
do local suit = pseudorandom_element blah blah before the change_base call
and just pass suit to the change_base function
it should give you the first value regardless
yeah but 1 is not a valid rank
oh yeah
so it's complaining
you need to do , nil

