#💻・modding-dev
1 messages · Page 576 of 1
I see that
Better than nothing :3
By the way, is it a trend that so many people only have a letter as a name? I swear it's getting more and more
:clueless:
Hey, trying to make a patch - I feel like the logic for this is pretty simple, so Idk why it's not doing anything.
The injected function is "Card:get_end_of_round_effect" at line 1040 in "card.lua". It's supposed to create a tag when a blue seal is triggered.
Wait, isn't SMODS.calculate_effect only for scored cards and not jokers?
No idea but I see no reason why that would be the case
its for literally everything
Where are lovely logs again?
Does anybody know why the other DebugPlus files don't appear for patching with Lovely when launching Balatro with --dump-all? It doesn't let me patch core.lua from DebugPlus specifically (I need to change the behaviour for using ctr + c on a unhandled type of card)
because they're not loaded via smods
its not anywhere in the lovely dumps
it's loaded as a lovely module called debugplus.core
you should be able to target that buffer name
they're my admirers
How do I get this value that's in scored_card in SMODS.calculate_effect?
Did not work sadly
so... lovely modules just straight up can't be patched? I'd say they must have some other buffer name, but if they don't get dumped, they clearly don't
@gaunt thistle care to explain?
The error message said '823: bad argument #1 to next', what is it that I am fixing?
The next(...) part of the condition is used by Seance though, why does it work there?
what is card.ability.extra.poker_hand here?
I put in 'Royal Flush'
okay then that would be because royal flush isnt actually its own hand
its just straight flush but it displays a different name
So I have to do an extra check for it?
yea, just check straight flush and then if all the cards are rank 10 or higher
Alright, thanks!
it's because lovely directly calls the original Lua loadbufferx fn, bypassing its hook. https://github.com/ethangreen-dev/lovely-injector/blob/master/crates%2Flovely-core%2Fsrc%2Fsys.rs#L93
I'll need to look into it tomorrow to determine how hard a fix will be
@rough furnace
Hmm I don't think its working even then
For reference, the code is still broken at the same part
did you restart the run before testing?
How do I use SMODS.calculate_effect()?
for what
I'm trying to hook it to see if I can get the chips a joker gives and then double that using a consumable
SMODS.calculate_effect({ chips = 10 }, card) is how you usually call it but I couldn't tell you how to hook it to do what you want
Yeah, right now I have this but it doesn't feel like it's getting me somewhere
function SMODS.calculate_effect(effect, scored_card, from_edition, pre_jokers)
-- Code before
local ret = calculate_effect_ref(effect, scored_card, from_edition, pre_jokers)
-- Code after
local chips_value
local best_match = nil
if scored_card and scored_card.ability and scored_card.ability.extra then
for k, v in pairs(scored_card.ability.extra) do
print(k)
if string.find(k:lower(), "chips") then
-- Priority: exact match
if k == "chips" then
best_match = v
break
end
-- else the closest
best_match = best_match or v
end
end
scored_card.ability.extra.best_match = best_match
print(scored_card.ability.extra.best_match)
end
return ret
end```
i believe modifying joker values is an affront to God so i can't really help with this kinda stuff sorry
i would use a library like cryptlib maybe, no need to reinvent the wheel
How would cryprlib help?
What are you even trying to do actually
Increasing joker chips via a consumable can mean a lot of things
giving it foil would be the funniest answer
Peak
I'm trying to make a consumable that can be used on Jokers and doubles their chips values. So the Joker would usually give +20 and after the consumable it would give +40. After another consumable it would give +80 and so on, permanently
Probably possible but not while actually keeping the description accurate for the joker
You got a link for me?
You'd have to do some post_trigger shenanigans to change the chips amounts based on some hidden counter in the joker that increments when the consumable is used i imagine
Sounds kinda complex
idk if it allows filtering by value types, probably not
Okay, how would I use that in my mod and code? I never used a library mod before
yea like i mentioned earlier, value manipulation is particularly tricky if you're trying to edit a specific value, because there's no way to control what the variable name is
make your mod have Cryptlib as a dependency and then just use the functions that cryptlib adds (e.g. Cryptid.manipulate(card, args))
"dependencies": [ "Steamodded (>=1.0.0~BETA-0827c), Cryptlib (>=1.0.0)" ] in the json file, right?
close. each mod has to be in its own set of quotes, not all in one
I keep getting this crash on start-up, even though I changed it
...you also need to install the mod
I did
then you didn't do it right, because it's not in the mods list in the crash log
As you can see, I put it into the mods folder though
🤷♀️ maybe you need to set your mod's priority to be after cryptlib's? (higher number loads later)
Found the problem
For WHATEVER reason there was a .lovelyignore in the folder. It's even in the screenshot
Anyways, where do I find all the functions that cryptlib has?
in the cryptlib files
you just have to read the code
but the stuff in manipulate.lua is probably what you're looking for, since that's all the value manipulation stuff
I'm currently readin through that and I don't really understand what I put for args
yea the documentation isn't the greatest. args should be a table, see what the function grabs out of it
asking in the cryptid server seems like a good idea too
I tried fixing it and couldn't figure it out. There's a weird chain of dependencies that you need to call the original. You can probably solve it pretty easy because you know how to modify the architecture much easier than I can and idk how rust works
...sounds familiar...
Okay I'm getting closer to solving the issue
I NEED TO SEE THAT CODE
Can you send me the link to the mod, please?
Thank you
probably a silly question someones asked before, but is it possible/how do i replace a vanilla joker/edit it? can that be done?
research taking ownership
oh thank you lmao
Would that work as a consumable too?
SMODS.find_card looks for Jokers, really.
SMODS.find_card can look for anything
its the old find_joker that doesnt
if _type == 'jokers' then
local t = {G.jokers, G.consumeables, G.vouchers}
-- TARGET: add your own CardAreas for joker evaluation
return t
end
Oops, yeah.
Okay, I have this now. How do I make it work?
SMODS.calculate_individual_effect = function(effect, scored_card, key, amount, from_edition)
local pulsar = SMODS.find_card('c_cstorm_pulsar')
if next(pulsar) and amount then
for i = 1, #pulsar do
amount = amount * pulsar[i].config.halfDouble
end
end
local ret = calcindiveffectref(effect, scored_card, key, amount, from_edition)
if ret then return ret end
end
SMODS.Consumable {
key = "pulsar",
set = "Spectral",
config = { max_highlighted = 1, halfDouble = 1.5 },
atlas = "jokers_SPACEHOLDER",
discovered = false,
unlocked = true,
pos = { x = 0, y = 0 },
calculate = function(self, card, context)
end,
can_use = function(self, card)
if G.jokers.highlighted and (#G.jokers.highlighted == 1) and G.jokers.highlighted[1] then
return true
end
end,
use = function(self, card, area, copier)
end
}```
Though, for actually applying the value modifier to a specific Joker by a consumable, you'd probably want to set a special variable on said Joker and then check for it in the SMODS.calculate_effect hook itself, then check for the chips or chip_mod in the effect table that's passed to it, then alter the amount and remove the special variable set by the consumable.
-# Just my tired thoughts.
create_card('Joker', G.jokers, nil, 1, nil, nil, nil, 'uncommon')
is the 1 supposed to be the rarity?
Okay, which one do I hook now? SMODS.calculate_individual_effect or SMODS.calculate_effect?
...actually, as scored_card is usually the actual "source", I guess only the SMODS.calculate_individual_effect could work? You'd just need to check the key for the chips or chip_mod.
Under vanilla conditions, values up to 0.7 indicate Common rarity, values above 0.7 and up to 0.95 indicate Uncommon rarity, and values above 0.95 indicate Rare rarity.
How would I do that?
if key == 'chips' and scored_card.ability.extra.pulsaractive then
amount = amount * scored_card.ability.extra.pulsaractive
end
how would i check how many cards in the deck have a certain enhancement
check vanillaremade code for one of the vanilla jokers that do exactly that
...forgot which one that was.
So like this?
SMODS.calculate_individual_effect = function(effect, scored_card, key, amount, from_edition)
local pulsar = SMODS.find_card('c_cstorm_pulsar')
if next(pulsar) and amount then
for i = 1, #pulsar do
amount = amount * pulsar[i].config.halfDouble
end
end
if key == 'chips' and scored_card.ability.extra.pulsaractive then
amount = amount * scored_card.ability.extra.pulsaractive
end
local ret = calcindiveffectref(effect, scored_card, key, amount, from_edition)
if ret then return ret end
end```
i havent played vanilla in a WHILE
i did too lol. might be stone joker?
i know it's not lucky cat, glass joker, or golden ticket
cloud 9 is also helpful, although it doesn't demonstrate checking the enhancement, only the looping through the deck part
Remove the SMODS.find_card portion entirely and, instead, in the use function of consumable, make it set the .ability.extra.pulsaractive on it.
-# Not sure how to remove it though, oop.
Steel Joker.
right, steel
Okay, so overall like this?
SMODS.calculate_individual_effect = function(effect, scored_card, key, amount, from_edition)
if key == 'chips' and scored_card.ability.extra.pulsaractive then
amount = amount * scored_card.ability.extra.pulsaractive
end
local ret = calcindiveffectref(effect, scored_card, key, amount, from_edition)
if ret then return ret end
end
SMODS.Consumable {
key = "pulsar",
set = "Spectral",
config = { max_highlighted = 1, halfDouble = 1.5 },
atlas = "jokers_SPACEHOLDER",
discovered = false,
unlocked = true,
pos = { x = 0, y = 0 },
calculate = function(self, card, context)
end,
can_use = function(self, card)
if G.jokers.highlighted and (#G.jokers.highlighted == 1) and G.jokers.highlighted[1] then
return true
end
end,
use = function(self, card, area, copier)
card.ability.extra.pulsaractive = true
end
}```
And then card.ability.extra.pulsaractive = false somewhere
if G.jokers.highlighted and (#G.jokers.highlighted == 1) and G.jokers.highlighted[1] then
G.jokers.highlighted[1].ability.extra.pulsaractive = true
end
You could do the removal of that special variable right after the amount is changed...
if key == 'chips' and scored_card.ability.extra.pulsaractive then
amount = amount * scored_card.ability.extra.pulsaractive
scored_card.ability.extra.pulsaractive = nil
end
Okay, I'm gonna try that out now
Or move it outside of that if block... mess around.
I got this error
Then just .ability.pulsaractive instead.
Wait, why amount = amount * scored_card.ability.pulsaractive? Doesn't this just crash because scored_card.ability.pulsaractive is a bool?
You can set scored_card.ability.pulsaractive to be the desired multiplier instead.
Okay, for some jokers it does change the value but it doesn't stay. Like after it gave that bigger amount of chips it goes back to the earlier amount
Thank you so much, I really thought I wasn't going to do that
If you want the value change to persist, depending on for how long, you may need extra work much like Cryptid's own value influencing.
I just put scored_card.ability.extra.chips = amount in there and it works
If the change is permanent, you can directly just set the .chips variable on the Joker itself... although, keep in mind that some may not store their chips result like that.
I know but at this point I don't care anymore, too tired of this stuff
-# Mood.
By the way, why does that not work on vanilly jokers? They use chips, don't they?
Some store it differently, be it .extra.t_chips or directly as .extra.
But still in key.ability?
Yeah.
Adding them did not make a difference...
amount = amount * 1.5
scored_card.ability.pulsaractive = nil
scored_card.ability.extra.chips = amount
scored_card.ability.extra.t_chips = amount
scored_card.ability.extra = amount
end```
If you want the change to persist, modify the values in the use of consumable... then there'd be no need for the hook.
attempting to make a joker that posseses an ability to do something along these lines
anyone got any clue on how i could progress with this idea ?
it would be a good idea to actually write it down, rather than using pictochat to send it here
is it too complex to make it so that this blind will only give 1 dollar,
no matter what joker you have or what deck you're on?
only allows every other card in played hand to score, retriggers all previous scoring cards in said hand upon advancing to next scoring card
if im making myself clear enough here
Uuuuhhhhh i think so? The order in which you are doing it is quite strange and would require some extra work if its possible, compared to doing regular retriggers.
if context.modify_scoring_hand then
local my_pos
for i, v in ipairs(context.full_hand) do
if context.other_card == v then
my_pos = i
end
end
if my_pos % 2 == 0 then
return {remove_from_hand = true}
end
end
well then
got the card skipping to work ! thank you !!
gonna have to figure out the retriggering business eventually, though,, but this is some great progress regardless
Yes, I don't understand what you mean with the retriggering.
Is there a suit gate in the same fashion as an enhancement gate?
No, you would have to use in_pool
I forget, can i use in_pool through lovely?
attempt at explaining through edited video ???? if it helps maybe ???
it really just goes 1; 3, 1; 5, 1, 3
there's definitely a better way of putting it but this is the best i can currently do
So each card would be retriggered for each scoring card in front of it?
yeah, i believe so
if context.repetition and context.cardarea == G.play then
local my_pos
for i, v in ipairs(context.scoring_hand) do
if context.other_card == v then
my_pos = i
break
end
end
if #context.scoring_hand-my_pos > 0 then
return {repetitions = #context.scoring_hand-my_pos}
end
end
```?
I assume that's a no?
No, I don't understand what you mean.
wdym you don't understand?
I'm trying to code mostly with lovely
I don't wanna have to make a joker all the way at the end just so i can have in_pool
Hello! I'm still relatively new to modding, but I've spent the last few days trying to understand the documentation on how config menus work, and I just can't seem to understand it. I was wondering if someone could help me with my menu where it has a toggle that says "Weston Mode" which is default to off and then when toggled, switches the sprite of a joker. Is this easy to implement?
You're not using SMODS?
i'm trying to avoid for the most part
But yes, I'm not using SMODS to create the joker
Then no, you can't use in_pool without SMODS
Okay then... is there a way with smods to CHECK the suit of the card?
Because I found the code for enhancement gate with smods
add = nil
for kk, vv in pairs(G.playing_cards) do
if SMODS.has_enhancement(vv, v.enhancement_gate) then
add = true
end
end```
I can then make one for suit and then do that
card:is_suit()?
If I wanted to create a negative consumable at the beginning of a round, how would i do that?
it works quite well. not as precisely as in the effect demonstrated in the example (by going back to the first card and progressing upon scoring and whatnot) but it does get the job done 👍
No, it would be SMODS.add_card({edition = 'e_negative'})
add = nil
for kk, vv in pairs(G.playing_cards) do
if vv:is_suit(v.suit_gate) then
add = true
end
end```
What's wrong here?
god it working
cool!
what's the joker's name and such
okay, as a final request regarding the joker im trying to implement, would it be fine to ask for a way to get this effect going as intended ?
well what's the code
not sure if joker and or card is needed text wise
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''elseif v.enhancement_gate then
add = nil
for kk, vv in pairs(G.playing_cards) do
if SMODS.has_enhancement(vv, v.enhancement_gate) then
add = true
end
end
'''
position = "after"
payload = '''elseif v.suit_gate then
add = nil
for kk, vv in pairs(G.playing_cards) do
if vv:is_suit(v.suit_gate) then
add = true
end
end'''
match_indent = true
cavandish
You mean the cards score like the order in the video?
honestly the settings would be like
- one for spawning one of each of the stuff so if you only want lets say the planned editions, boss blinds, or stickers you can do that
- one for balancing
- one for item-specific joker support
- one for miscellaneous (like the title screen and if i do add soul-like or animated jokers, have an option to have it static
if context.individual and context.cardarea == G.play then
local cards = {}
for i, v in ipairs(context.scoring_hand) do
if context.other_card == v then break end
table.insert(cards, v)
end
if next(cards) then
return {func = function()
for i, v in ipairs(cards) do
SMODS.score_card(v, {cardarea = G.play})
end
end}
end
end
```?
can't tell if this is an issue with the way i appended the code or if it's something else
You need an in between i, v and ipairs
Also, install the Lua extension.
upon scoring
Which line is that?
how would i get the key of the opened booster pack when the player opens a booster pack
context.open_booster and context.card.config.center.key
thank you
typist, debugplus and sticky fingers (+ steamodded and my own, of course)
Can you put print(context) after if context.individual and context.cardarea == G.play then?
not sure what the word for the last one
maybe visibility?
will do and report results when possible tomorrow as im now off of my pc
anyone have any idea why the game is crashing when i open a booster from a func called within my joker? this joker is supposed to open another booster of the same type when you skip a booster a certain amount of times per round, yet i'm getting this crash. the crash doesn't happen when the new booster materializes, it happens when it opens
here's the joker's code:
calculate = function(self,card,context)
if context.open_booster and not context.blueprint then
card.ability.extra.booster = context.card.config.center.key
end
if context.skipping_booster and card.ability.extra.time > 0 and not context.blueprint then
card.ability.extra.time = card.ability.extra.time - 1
CHAK_UTIL.open_booster_pack(card.ability.extra.booster)
return {
message = "Again!",
colour = G.C.FILTER
}
end
if context.end_of_round and not context.blueprint then
card.ability.extra.time = card.ability.extra.times
return {
message = "Refreshed!",
colour = G.C.FILTER
}
end
end
and here's the func for opening a new back
--- Creates and opens the specified booster pack
--- @param pack_key string
function CHAK_UTIL.open_booster_pack(pack_key)
local booster = SMODS.create_card { key = pack_key, area = G.play }
booster.T.x = G.play.T.x + G.play.T.w / 2 - G.CARD_W * 1.27 / 2
booster.T.y = G.play.T.y + G.play.T.h / 2 - G.CARD_H * 1.27 / 2
booster.T.w = G.CARD_W * 1.27
booster.T.h = G.CARD_H * 1.27
booster.cost = 0
booster.from_tag = false
G.FUNCS.use_card { config = { ref_table = booster } }
booster:start_materialize()
end
this booster pack func has worked before btw, so idk why it's acting up now
it does materialize a new booster of the same type btw
uh is there a way to make this compact
two columns
orange or blue?
no like
you see how you have all your G.UIT.R nodes inside a single G.UIT.C node
after the first G.UIT.C node, make a second G.UIT.C node and move half of the G.UIT.R nodes to the second G.UIT.C node
(R stands for Row and C stands for Column)
would you prefer either alphabetical or having them in sets like the consumables on one row
and i do plan on adding other stuff like suits
for consumables i think for minor tarot either just put that in arcana packs or just make it where if you enable minor tarot it enables the boosters
how would i guarantee a jimboquip?
weight = math.huge?
hey anyone familiar with ui stuff, i've added a button to my joker, but for some reason it gets rid of the sell button. what's causing this?
is it possible to take ownership of every Joker
probably
thanks lexi
you're welcome 🤑
definitely possible, but there's potentially a better way to implement whatever you're trying to do
me when I take ownership of all Joker so I can super mog my balatro
Cryptid does something basically like that, maybe look how Cryptid does it
What is the goal?
Cryptid.lua iirc
im trying to override every Joker's name into one name
ill check
you'll probably want to hook a localization function instead, that way it a. even accounts for other modded jokers, and b. doesn't require taking ownership of 150 jokers
it's late so i dunno the finer details, but i can look into it for you tomorrow if you're interested
yeah sure, hook me up tomorrow
if you remember of course
i read this as 'if you remember me of course' and i was about to say how sad that was
first of all
fuck you too
die sexy
@robust marsh So sorry this took so long, I was moving into a new house
You just set score_invisible = true on any blind definition object you want to hide the score for. The result is what you see in the video
DW ABOUT IT
THANK YOU FOR DOING THIS STILL
It does properly reset after the blind is beaten, though it may still require some finessing? Since it shows the flash of the pure chip scores when it recreates them as expected (to fit regular blind behavior) + the entry on the round eval
The latter easy to fix if you gimme a sec, but the former requires a design decision
I don't mind since you win the game as soon as you beat the blind that i needed this for, but if you do want to you can fix it
i'll add this in a bit, also i'll credit you accordingly for it
shrug idrc about a credit
would you want to replace "score at least [requirement]" with smth like "KILL BOSS"
Otherwise the round eval row would look a little empty
that would be lovely actually
is there a possibility of removing the Reward: $$$$$ box
Sure. Does it not reward you?
nope, the boss is basically the "true final boss" in a sense
Ah. Then Ic ould probably just center the blind chip icon and then make it larger with the extra space from the removed round score section
would it be a hassle? I do think it would look good
Only issue is, again, the UI reset once the boss itself is cleared
but so far this is awesome
Since it'd be a more obvious "snap" back to the default UI
you don't have to bother with that actually, unless you wish to use this yourself
Im already using my own version so no
oki, then it's not needed
hmmmmmm ok gimme a sec to test this
alrighty !
is there a way to change the effects of the main 150 jokers?
take ownership
how to take ownership?
feels very nice
how do you make it so that the joker doesnt occupy a slot without using negative
extra_slots_used = -1 (i think)
🤞🏽
@robust marsh try this
I'm in bed now so I can't do much til tomorrow for changes
What still needs work?
all blinds now inherit the reward message removal, but like at the end of the round which is strange. But besides that everything is completely fine
I think i fixed it
the defeat boss text doesnt appear, but that is okay
how to add references in your joker description eg. putting the word Joker and it shows the description of Joker(Jimbo) too in a smaller description window
With an info queue
I'll get a link rq
append the center to info queue, if you just want a center description
literally just
info_queue[#info_queue+1] = G.P_CENTERS.j_joker
would work as described
of course if you're trying to info queue a different thing other than a center, it becomes more complicated than that
something like that
yes thats what was just described
Yeah, put what minty said in the loc vars function
In your card
is THIS your card?
oh ok I am new to modding so I will be asking some dumb questions
nah just an example of what I mean
yeah ik
inside of the Joker?
yeah
nah doesnt work
did anyone know how to make enhancement can be override with another enhancement so the card can have multiple enhancement?
so I want to make joker description work like misprint but the problem is I don't know how to create a ref table with a ref value so I want to know:
1- wth is a ref table and a ref value
2- how to make them
3- how to make the random numbers in a certain range
misprint doesnt need ref table/value to work
generally you dont need that unless youre doing something very complex
also have a look at the vremade misprint https://github.com/nh6574/VanillaRemade/blob/34442a850d9ecbbac5d48b27507de99590908e27/src/jokers.lua#L647
Quantum enhancements
more like quantum enlagcements..... am i right chat...
You would have to hook Card:set_ability
Did you put it in config?
is there a way to check when another joker's calculate is triggered? Or when their effects are triggered. Either of the two
context.post_trigger?
ye that's it thank you
ok did a few tweaks but how do I make it so it works with this
text = {
"{X:mult,C:white}X#1#{} Mult"
}
currently it is giving me nil
return { vars = { ... } } in loc_vars
do I just return{vars = {main_start = main_start}}?
main_start is a seperate thing
Also if youre doing something like misprint you dont need a description, the entire thing is the main_start for vanilla misprint
is #G.jokers.cards the number of jokers in the joker area, just for clarification
Yes.
no I want to do a joker that gives between 0 to 10x and I want the description to keep switching while keeping that Xmult background
ty
so is it like this return {main_start = main_start, vars = {main_start}}?
Without the vars
anything works with me but I find it easier with the vars
putting a main_start in vars doesnt do anything
so I can't do it with vars?
No, main_start is just a ui element that gets put at the start of the description
I would just copy the vanillaremade misprint thing and tweak the values for what youre doing
but I don't know how to give it that Xmult UI
Just change the one from misprint to use X instead of + and then give it a different background and text colour
Misprint doesnt actually have a description at all, its just the main start
yeah how do I the background that is the problem that I have with the mainstart
Go to the smods ui guide and scroll down to see if you can find some text background colour in the parameters
If its not there then youll probably have to make another uibox that the text is inside if for the colour
where do ig et cryptid
Anyone able to figure out what's making it crash?
caino
also same with message card, you accidentally spelled consumable correctly there too
Colour
i meann
colour isnt wrong
I’m not falling for the British propaganda
heirophant
color is just as wrong as colour
Thanks for helping, it's fully working now
Remember to not type correctly next time
modding momento
remember lads balatro is canadian
Why’s it not in French by default then
because they speak multiple languages in canada..?
canadian english is a whole nother language
They speak multiple languages in all countries of the world
also english is usually the default language for games
This isn't correctly setting reroll cost to $1, anyone know what's wrong?
G.GAME.reroll_cost doesn't exist.
I was trying some random things to make it work. Do you know what does exist?
G.GAME.current_round.reroll_cost
It only sets it to $1 for one reroll, I need it to persist.
if context.after and not context.blueprint then
local wild = {}
for _, scored_card in ipairs(context.scoring_hand) do
if SMODS.has_enhancement(context.other_card, "m_wild") and not scored_card.debuff and not scored_card.daniyared then
wild[#wild + 1] = scored_card
scored_card.daniyared = true
end
end
SMODS.destroy_cards(wild)
end
trying to make a joker which destroyes all wild cards scored
how do I do that? (please tell me I don't need a hook / patch)
In a calculate????
-# yeah, that makes sense...
in a cargo box?
Well, it's getting the job done, but it doesn't apply immediately. Can that be fixed?
hey guys new here, does there exist documentation of game object G, seen it used like "G.jokers.cards" or "G.play"
just wondering what other fields it has
There was this
So I change the value (which assuming is G.GAME.current_round.reroll_cost = card.ability.extra.final_cost) in redeem, then somehow set it again in the calculate function?
Thanks mate
Firstly, you should be using context.destroy_card
With this code, what exactly do I need to add or change to get this working?
ignore that comma at 125, i removed it
oh
how to get all the jokers of a mod?
local jokers = {}
for k, v in pairs(G.P_CENTER_POOLS.Joker) do
if v.mod and v.mod.id == "modid" then
table.insert(jokers, v.key)
end
end
kty
still doesnt work somehow
is there a python fstring equivalent in lua?
config = { extra_slots_used = -1 } ? I don't see why it wouldn't work, one of my jokers uses it and it works just fine
What is your SMODS version?
i think you should just concatenate while using a multiline string ([[string]])
0827
Yes, string.format("%s, %s, %s, %s, %s", 1, 2, 3, 4, 5)
No, it's not.
Yes, cards and card areas are not the same.
There is no type for playing cards.
i see
do i need to update it
what does G.C.Background and its insides C D L do?
its the colors of the background
yeah but what does C D L mean? and what is the background for?
it's the background when you play a game, idk what C D and L mean specifically but they're the different colors used
{ n = G.UIT.O, config = { object = DynaText({ string = r_chips, colour = G.C.CHIPS, pop_in_rate = 9999999, silent = true, random_element = true, pop_delay = 0.5, scale = 0.32, min_cycle_time = 0 }) } },
why is the color still RED
dynatext doesnt take a single colour, i takes a colours table
how to tell the game that all suits are equal something like the smeared joker effect
this but instead of returning smeared_check you return true
https://github.com/nh6574/VanillaRemade/blob/34442a850d9ecbbac5d48b27507de99590908e27/src/jokers.lua#L3330
how can i make a joker i just created negative
i mean
like
manually spawned with SMODS.add_card
SMODS.add_card { ... , edition = "e_negative" }
local card_is_suit_ref = Card.is_suit
function Card:is_suit(suit, bypass_debuff, flush_calc)
local ret = card_is_suit_ref(self, suit, bypass_debuff, flush_calc)
if not ret and not SMODS.has_no_suit(self) and next(SMODS.find_card("joker_key")) then
return true
end
return ret
end
it is not working why?
yeah
no idea then that looks correct
hey is there a way to have a deck give jokers additional effects? i'm trying to do something more specific but for example would there be a way to have a deck give jokers x1.5 mult in addition to their effects (like them being polychrome, but this would stack with polychrome)
i don't think i can really override context.individual for jokers here, as that would replace the already existing xmult they have. i did try something with context.other_joker that seemed to work but the issue is it overrides normal other_joker effects so it breaks baseball card.
is there a way to add my own context to calculate jokers after scoring and give that 1.5x?
is it because my key has spaces?
it shouldnt be, but try to see if removing them fixes it
it shouldnt override baseball card, how were you doing it?
You can give decks calculate effects if that helps
ah lol there was a huge oversight on my part and i didn't figure out i can use context.other_joker in the deck's calculate effect for what i am trying to do many thanks
Np 👍
how can i get a joker's edition
Card.edition
yes
alright
ok so I hovered over the :is_suit and it told that :is-suit is a duplicate field -> boolean|nil
yes because youre hooking it, thats normal
ok bc now it crashes at Card.lua bc it tried to index a nil value so situation got worse
ok nevermind no more crash
but it still doesn't work
How do I make a spectral appear more in spectral packs and in the shop when playing ghost deck, if the player has a specific joker?
whats the reason behind this appearing
there's no easy way to modify individual rates for cards
ok a side effect is that they become debuffed with any of those boss blinds how do I make not do that
you are returning a table without repetitions in context.repetitions (your context checks are probably not strict enough)
What would you suggest I do?
my suggestion would be not to do that effect but maybe someone else has a solution
Okay
none of my jokers use it tho
ohh
can't you make cards in pools more or less likely to appear
theoretically you could recreate the entire spectral pool and replace it with your own which has some cards at a changed rate
no unless you add rarities or you do something hacky
i mean i know there are some things you can do with in_pool to simulate this but idk how it would be and it sounds very jank
smthing like this?
show the entire thing
context.end_of_round and context.main_eval
oh
Also it would be {message = "Reset!"}
That is normal.
Shouldn't this if be true when I use the consumable on the joker?
if G.jokers.highlighted and (#G.jokers.highlighted == 1) and G.jokers.highlighted[1] then
if G.jokers.highlighted[1].key == "j_cstorm_ethereal_joker" then
G.jokers.highlighted[1].ability.extra.chips = G.jokers.highlighted[1].ability.extra.chips * self.config.fullDouble
else
G.jokers.highlighted[1].ability.extra.chips = G.jokers.highlighted[1].ability.extra.chips * self.config.halfDouble
end
end
end,```
Or does G.jokers.highlighted[1].key not exist?
Yes, it's G.jokers.highlighted[1].config.center.key
Thank you
is there a context for determining when cards (specifically jokers) are destroyed? there's selling_card that works for when they're sold but i'm looking for one for destroyed cards (for example by ceremonial dagger)
context.joker_type_destroyed and context.card.ability.set == "Joker"
And why do I get the crash "attempt to index field 'extra' (a nil value)" here?
if G.jokers.highlighted[1].config.center.key == "j_cstorm_ethereal_joker" and SMODS.get_probability_vars(card, 1, card.ability.extra.odds, 'cstorm_plusar_ethereal') then
return true
end
return false
end```
card is the consumable, not the joker.
Forgot to change that, my bad
Can I just use G.jokers.highlighted[1]?
Yes.
thanks! though it seems that this doesn't trigger for ankh/hex (it only calculates the context when the getting_sliced param is true for the card), but i'll figure out a workaround
Okay, either I am extremely lucky or my SMODS.get_probability_vars(G.jokers.highlighted[1], 1, self.config.odds, 'cstorm_plusar_ethereal') doesn't work properly
No, outside of config.
Like this
ah okay
Code?
this has been fixed in smods, idk if it is in the latest release
key = "pulsar",
set = "Spectral",
config = { max_highlighted = 1, halfDouble = 1.5, fullDouble = 2, odds = 10000 },
atlas = "jokers_SPACEHOLDER",
discovered = false,
unlocked = true,
pos = { x = 0, y = 0 },
can_use = function(self, card)
if G.jokers.highlighted and (#G.jokers.highlighted == 1) and G.jokers.highlighted[1] and G.jokers.highlighted[1].ability.extra.chips ~= nil then
return true
end
end,
use = function(self, card, area, copier)
if G.jokers.highlighted and (#G.jokers.highlighted == 1) and G.jokers.highlighted[1] then
if G.jokers.highlighted[1].config.center.key == "j_cstorm_ethereal_joker" then
G.jokers.highlighted[1].ability.extra.chips = G.jokers.highlighted[1].ability.extra.chips * self.config.fullDouble
else
G.jokers.highlighted[1].ability.extra.chips = G.jokers.highlighted[1].ability.extra.chips * self.config.halfDouble
end
end
if G.jokers.highlighted[1].config.center.key == "j_cstorm_ethereal_joker" and SMODS.get_probability_vars(G.jokers.highlighted[1], 1, self.config.odds, 'cstorm_plusar_ethereal') then
SMODS.add_card { key = "c_cstorm_pulsar", area = G.consumeables}
end
end,
}```
i think it should be?
youre using the wrong function
it's SMODS.pseudorandom_probability when you want to do an effect
SMODS.get_probability_vars is for loc_vars
SMODS.calculate_context({joker_type_destroyed = true, card = self}) still seems to be called only when getting_sliced is set to true in the latest version, but i'll update steamodded and test it in a sec
ah there are updates that assign it to destruction events yes, neat
Any clue where I would get started on making basic modification to the game? Like changing joker sprites and values?
changing sprites: https://github.com/Eremel/Malverk/tree/main
changing values: https://github.com/Steamodded/smods/wiki/API-Documentation#taking-ownership
thanks!
Now I get this error
youre passing a string
i think you got the arguments wrong because that function adds the seed
Denominator is the max chance. If it's 1 in 4, 1 is the numerator and 4 is the denominator
Yeah, I currently have SMODS.pseudorandom_probability(G.jokers.highlighted[1], 1, self.config.odds, 'cstorm_plusar_ethereal')
yeah you're missing the seed
bump
What should the identifier be? The key?
*if you don't specify it yourself
well duh
I mean it's quite obvious but yk
local card_is_suit_ref = Card.is_suit
function Card:is_suit(suit, bypass_debuff, flush_calc)
bypass_debuff = true
local ret = card_is_suit_ref(self, suit, bypass_debuff, flush_calc)
if not ret and not SMODS.has_no_suit(self) and next(SMODS.find_card("j_xmpl_simple joker")) then
return true
end
return ret
end
ok why does not bypass the debuff or does it do something else?
why is my config tab doing this
function SMODS.current_mod.config_tab()
local config_nodes = {n=G.UIT.ROOT, config = {align = "cm", colour = G.C.L_BLACK, minw = 4, minh = 4}, nodes = {
{n = G.UIT.C, config = {align = "cm"}, nodes = {}}
}}
config_nodes.nodes[1].nodes[1] = create_toggle{
label = "Does Don Quixote do the funny?",
ref_table = lcb_config,
ref_value = "don_is_funny"
}
config_nodes.nodes[1].nodes[2] = create_option_cycle{
label = "Limbus Pack Music",
w = 6.3,
scale = 0.9,
options = {
"Extraction Theme",
"Abnormality Extraction Theme",
"Oh Crab, So Crab",
"La Mancha Carnival",
"A Midspring Night's Dream 2",
unsuspicious_text,
},
opt_callback = "lcb_switch_pack_music",
current_option = lcb_config.limbus_pack_music
}
config_nodes.nodes[1].nodes[3] =
{n = G.UIT.C, config = {align = "cm", padding = 0.1}, nodes = {
{n=G.UIT.C, config={align = "cm", padding = 0.1, r = 0.1, hover = true, colour = G.C.UI.TEXT_INACTIVE, button = 'lcb_go_to_github', shadow = true, w = 1, h = 1}, nodes={
{n=G.UIT.T, config={scale = 0.3, text = "This Mod's Github", align = "cm"}},
}},
{n=G.UIT.C, config={align = "cm", padding = 0.1, r = 0.1, hover = true, colour = G.C.GREEN, button = 'lcb_go_to_download', shadow = true, w = 1, h = 1}, nodes={
{n=G.UIT.T, config={scale = 0.3, text = "Scrollable Descriptions Download", align = "cm"}}
}}
}}
return config_nodes
end
(i mean the big space on the right side btw)
bypass debuff is so a card is considered a suit regardless of debuff, it doesnt prevent blind debuffs
context.debuff_card allows you to return prevent_debuff = true to prevent the card from being debuffed
it works thanks
because it only debuffs cards in the hand
and debuffs are only calculated at the start of the round, when the cards are in your deck
mm how would i make it so a joker gets dissolved as soon as it's put into the joker area? I'm asking specifically for that because I also want it to do something else but I wanna figure out how to pull this off first
destroy it in add_to_deck
is that not the same as debuffing them regardless of their location
destroy it in an add_to_deck hook
because theyre still going to be debuffed once drawn
or in the context for added cards
thank you
right
but still, the point is that it doesnt work
change the cardarea to G.deck
it worked, ty
No, because if the debuffs are recalculated, it will undebuff the cards in hand.
done
@frosty rampart yo
how to disable retriggering in jokers?
i think you can add and not context.retrigger_joker or something along those lines to a check to make it not be retriggered
yo
I'll look into it later this afternoon, I'm busy for the next few hours but I haven't forgotten
sure
how do I add the description of a specific owned joker to info_queue? like, not that joker's description in general, but the one that's actually owned
adding lucky cat's description to info_queue always shows it currently at x1, but i want it to reflect the currently value of an owned joker
for example i have a lucky cat that's at x4, and another joker copying it and i want to add the x4 lucky cat description to its info_queue, but it always displays in the info_queue at x1
info_queue[#info_queue+1] = { set = "Joker", key = <card>.config.center.key, config = <card>.ability }
wtf? you can do that?
yeah, if you do the center it does the base config but if you do this you can just put anything as the config
such as that of an existing card
the only difference is that it wont have recursive tooltips (so the lucky cat tooltip wont have the lucky card tooltip added on as well)
i'm definitely doing something wrong
uhhhhhhhhhhhhhhhh
works like a charm, I never checked this but I assume I can use key_append to check if a joker is created by a specific source and prevent it from being destroyed
whats the info_queue code
why are so many people a letter and then an apostrophe
M'
checking it might be my fault
funy
maybe i should go ahead and claim mine
K'
N' homage, gone too soon 😢
info queue is
forgery_c is
local forgery_c = G.GAME.current_round.forgery_joker.card or nil
You can't store cards in G.GAME
i mean evidently you can
it wont save
oh okay
MANIFOLD.funcs.reset_forgery_joker = function()
G.GAME.current_round.forgery_joker.card = nil
local valid_forgery_jokers = {}
if #G.jokers.cards > 0 then
for k, v in ipairs(G.jokers.cards) do
if v.config.center.blueprint_compat and v.config.center.key ~= 'j_manifold_forgery' then
valid_forgery_jokers[#valid_forgery_jokers+1] = v
end
end
end
if valid_forgery_jokers[1] then
local forgery_joker = pseudorandom_element(valid_forgery_jokers, pseudoseed('manifold_forgery'..G.GAME.round_resets.ante))
G.GAME.current_round.forgery_joker.card = forgery_joker
end
end
this actually sets the target
i can only imagine the config is lost somewhere
yes
oki
can UI boxes display images
i guess i could make a separate var to save the current target's config and get that?
assuming nothing else stupid is wrong
i mean just putting the ability in there should work i imagine
unless some variable names change or smth
oh is it bc i'm setting only forgery_joker.card
that's probably it
so it's pulling the config from nil which was the initialized value
or
wait no that should work still right
forgery_joker.card is the card though so the ability should still exist
yeah
are we sure it should be config = <card>.ability? and not <card>.config or ability = something
ability: Table:
extra: 0.25
h_chips: 0
hands_played_at_create: 0
mult: 0
h_x_chips: 1
perma_mult: 0
order: 91
+29 more values.
yeah
is there documentation for info_queue?
no other than the fact it exists
the trend is that most of vanilla is undocumented
you put centers in it and the game magically converts them to info boxes
too many joker loadouts
wtf is Loadouts
ohhh that
yeah
Is it possible to mod changes into the source code in a way? Like making your own unofficial "patch"/update to the game
local old_add_to_deck = Card.add_to_deck
function Card:add_to_deck(from_debuff)
old_add_to_deck(self, from_debuff)
if G.GAME.selected_back.effect.center.key == "b_tdec_tainted_zodiac" then
if self.ability.set == "Joker" then
self:start_dissolve()
end
end
end
How would i check key_append here? I tried snooping around for it and couldn't find the exact thing i'm looking for
does anything in vanilla pass through info_queue config/abilities?
Like, say I wanted to change how a base game joker functions. Is that possible?
you can use hooks or patches
neat
hooks are a bit more limited but more likely to be compatible with other mods
you might also use take_ownership for that
patches can do like anything
wish i had that instead of fully teaching myself how patches work

still never used a hook and only ownership in very jank ways
i never used patches in like my first 8 months of coding
didn't lovely patches always have documentation
yeah
probably, i'm just dumb and illiterate
apparently vanilla passes config in some cases through to info_queue with vars = ...
i, think
yes
ive seen that before idk what the idea of it is
for things with set Other it works at least
it does, sometimes

key_append is only before the card is created
^
convo started there
yeah no idea
i mean, I did give it a key_append
but i don't know how to check for it
add_to_deck is too late
ah
you have it as an argument in get_current_pool and create_card
you can just add a flag to the card tho
setting config = forgery_c.ability gives this issue but setting vars or ability = forgery_c.ability crashes and says ability is nil so it might still be a me issue
alright
even tho ability is def not nil
yeah someone was trying to do something similar but had the same problem
idk what the solution is
helpful
it doesnt help that vanilla is very hardcoded
and the names for the fields used in loc_vars are sometimes different for no reason
show code
G.E_MANAGER:add_event(Event({
trigger = "after",
func = function()
local crafted_card = SMODS.add_card {
set = "Joker",
rarity = totalvalue_rarity,
key_append = "crafted_by_bag"
}
crafted_card.is_crafted = true
return true
end
}))
local old_add_to_deck = Card.add_to_deck
function Card:add_to_deck(from_debuff)
old_add_to_deck(self, from_debuff)
if G.GAME.selected_back.effect.center.key == "b_tdec_tainted_zodiac" then
if self.ability.set == "Joker" and not self.is_crafted then
self:start_dissolve()
end
end
end
Both r in separate files, i put them together for this
alright
Hi, does anyone know how I would set a hotkey for a mod up so that it can work off of a controller's button press?
i hook Controller:button_press_update for one of my mods
G.E_MANAGER:add_event(Event({
trigger = "after",
func = function()
local crafted_card = SMODS.create_card {
set = "Joker",
rarity = totalvalue_rarity,
key_append = "crafted_by_bag",
}
crafted_card.is_crafted = true
G.jokers:emplace(crafted_card)
return true
end
}))
This worked, thank you N :)
youre not adding it to deck
huh
crafted_card:add_to_deck()
Ohhhhh I SEE.,.... How would I check for a specific button press, like Select?
now i have to add crafting recipes lol this will be so fun
tysm.,..!!
new UI code crash
any UI peoples in chat
I pretty much copied my code from the working UI to make a new one, changed the layout and it stopped working
forgot to send code whoops
G.FUNCS.overlay_menu({
definition = create_UIBox_generic_options({
no_back = true,
contents = {
{
n = G.UIT.C,
config = { minw = 10, minh = 10, padding = 0.15, align = "cm", colour = G.C.GREEN },
nodes = {
{
n = G.UIT.R,
config = { minw = 1, minh = 0.2, padding = 0.15, align = "cm" },
nodes = {
{ n = G.UIT.T, config = { text = localize("k_jkbx_QH_title"), colour = HEX("FFFFFF"), scale = 0.8, shadow = true, align = "cm" } }
}
},
{
n = G.UIT.R,
config = { minw = 1, minh = 0.3, padding = 0.05, align = 'cm' },
nodes = {
Jokebox.create_uibox_button('QH_shutdown', localize("k_jkbx_shutdown"), 3, 1,
G.C.GREEN),
n = G.UIT.R,
config = { minw = 1, minh = 0.2, padding = 0.15, align = "cm" },
nodes = {
{ n = G.UIT.T, config = { text = localize("k_jkbx_shutdown_desc"), colour = G.C.GREEN, scale = 0.8, shadow = true, align = "cm" } }
}
}
}
}
}
}
})
})
G.OVERLAY_MENU:recalculate()
it still looks awful in discord because of text wrapping
does anyone happen to know what is the reason behind this crash?
the whole thing right?
yeah
also when did the crash happen
i dont have a good idea when
well what were you doing when the crash happened
testing and debugging
at first i thought it was the Uno joker since each time it crashed, Uno was in my joker slots
before i was just playing around with the jokers
test sake and all
also you dont use math.min anywhere so i dont think its your mod thats crashing
unless its some game function that uses it
yea, im not sure why but it decides to crash now and not earlier
How does one make a joker convert cards to an enhancement (kinda like how midas mask does)
have you looked at midas mask in vanillaremade
but yea it might be internally, and im not really certain how i can fix this since it happens even if i sold my modded jokers and kept vanilla ones
if it happens without any of your mods content it might be related to some hook youre using ig
if you have any hooks
does this count? ```lua -- Hook the new parameter, why is this not documented bruh
local Sr_Ref = Game.start_run
function Game.start_run(self, args)
local Ret = Sr_Ref(self, args)
SMODS.set_scoring_calculation("GG_powerCalc")
return Ret
end
welp there goes formatting
yea it hooks the SMODS.Scoring_Calculation and seems to be the only hook here
also what is that comment lol
no but like why that comment
oh wait you meant that
what isnt documented
i mean youre hooking Game.start_run here
also SMODS.Scoring_Calculation is relatively new so no docs yet
yea
but in term, yea i have no idea why this bug occurs
since it works fine for the first few antes
and it just dies on around the 3rd ante
also you dont need to hook start_run for this, you could instead just do
SMODS.current_mod.reset_game_globals = function(run_start)
if run_start then
SMODS.set_scoring_calculation("GG_powerCalc")
end
end
i will test that rq
generally should have the same effect as a start_run hook except itll be more clear if it caused the crash or not
yea it connects the scoring calc, but the bug still occurs
even discarding seems to crash it 😔
should i try disabling my mod and see if it has the same effect?
probably yea
I feel dumb for asking but what is ipairs
it loops over the integer-indexed values of a table
in order
pairs is the same but it goes over everything in no particular order
also, ipairs stops when it encounters any nil value
Ah, so does that mean that full_hand is a table?
yeah
ipairs can be used on like, any cardarea to loop through it
makes sense
luckily It's not my first language or anything, I know C# and Python to an extent
also because lua tablea are funny, for example, if you play one card, context.full_hand[1] will be the exact same thing as G.play[1]. i assume you already coded as if this was the case but you probably didnt really think about it i imagine
What does your scoring calc code look like?
Hold on
basically tables are completely anonymous and the variables associated with them just point to the table, so setting a variable to another one which is also a table will just make them both point to the same table
its used for passing variables and other information into the joker description
it can also pass colours allowing for dynamic colours
pretty sure the scoring calc code was the same as before
Get rid of the type check
main_end and main_start are a thing which can be useful at times
and the info_queue is for adding tooltips to a card
I am 95% sure that is the problem
alr
Eremel my friend
Good to see you
is it also a table?
it has the same look as one
yeah, its a table of centers and tables with localization arguments
thats also why just changing the info_queue argument actually affects the info_queue outside of the function without returning, because lua tables are just awesome like that
centers?
all of these things
ah
what the FUCK is userdata
theyre basically, well, the main part of the card. theres also a front, which is the sprite for a cards rank and suit, and a back which is the back sprite of a card
theres like a vanillaremade thing on this
Do you still need any changes on this? The one thing I was missing was just to add the score_invisible check to the round eval
I got rid of the type and tested it, it worked for the original crash but now it crashes when I would play or discard a flipped down card, and the type seemed to fix it
I'm pretty sure it worked for the first crash
Hi dilly, how have you been?
Its been rough out here
But im trying my best
Life has taken a horrendous turn currently so ive been a bit less active
Share the crash
Alr lemme fetch it rq
Btw it references the code block that had the type condition
Yea for a split sec I see that the Scoring_Calc parameter shows "?" And doesn't want to reveal
i hope everything goes better soon
Much love N
That’s sad to hear, hope things turn around quickly!
theres the crash btw
im sorry to hear that, hope it goes better too
Hmmmm
I might know why it happens tho
You know how Chips and Mult show "?" upon selecting a face down card?
Moving
The power scoring calc doesn't seem to exit "?" on scoring when the card is revealed, so it attempts to do Chips × Mult ^ "?" (String)
I have been busy setting up stuff for move so haven't done much modding recently myself. I now live with these two weirdos
ok i might be dumb how do i use SMODS.merge_effects() in conjunction with two SMODS.blueprint_effect()?
Yeah that’s the issue, I’m not sure why that’s happening though, I can’t browse the code very well on mobile
im doing some chicanery again but i can assure you if i return return1 or return2 instead of a merge that works just fine
Yea I get you, also if I can't rely on using a type() to determine whether it is not a number, do you have any suggestions?
local ret1 = SMODS.blueprint_effect(...) or {}
local ret2 = ...
return SMODS.merge_effects{ret1, ret2}
thats crazy thats literally my screenshot
no
no?
you're missing {}
Well the issue is that your type check means the function doesn’t return anything when the string is present which is why it crashed
both work
I see, so should I consider only using Chips and Mult if Power is not valid
Instead of just stopping a return, I could have two returns inside an if else?
Just do something like return mult * chips below the check
trying to figure out how to make certain cards count as an enhancement. My first instinct was to look at pareidolia, but I can't understand what the code for it is doing 😭
Alr I'll give that a shot
what specifically are you looking to do? this sounds like quantum enhancements
I want to make played 7s count as lucky cards when you have the joker (I think this already exists in a mod but I want to figure out how to make it work myself)
the pareidolia hook below is just checking for if pareidolia is present, and if so, always returning true on is_face
read the quantum enhancement one https://github.com/nh6574/VanillaRemade/wiki#what-are-optional-features
quantum enlagcements.... 😨
oh that's cool
true
😨
Quantum Enhancements are cool but they're jank and finicky by design
And I admittedly am looking forward to Quantum Ranks too 👉 👈
quantum suits when
what is this, some kind of Smeared Joker?
where am I putting this codewise
anywhere
anywhere that gets loaded
dont put the entire thing just the features you want
Do I put it in the joker file?
.
Yea the power calc is "?" during scoring
I started modding and I don't know what to put into the folder of my mod. I watched a tutorial and the files they linked have been changed a lot so what should I do?
There's a good wiki for it
You need at least
1 lua file
1 json file
is that it?
check the basic mod part if you dont care about the set up
yeah, though having more lua files is usually better for organization purposes imo
okay blueprinting two common suit cards together doesnt work
however two jimbos work
ok
tomato and tomato soup..
Stack code in one file
😨
Oh boy
cardinal sin
hmm, He's in my blood
Canned tomato soup
or is my blood?
hm this is more jank than i thought
Converging pathways 😭
😭 😭 😭 😭
oh neat i got the game to freeze
certified chicanery
I'm having a hard time believing this is not coincidental
So uh, wheres tin can
Or aluminium
Two people had the same pfp in the past 2 days
Coincidentally
Both ended up changing
Crazy
is there a way to make a card undebuff itself? im trying to make a joker's effect that debuffs itself for 1 hand
what's different with the id and Name in the .json file?
hey y'all one very simple and probably very stupid question.
iam making a balatro mod for me and friends right now and currently it doesnt show up in the mods tab in balatro itself. Iam following a tutorial and feel asthough i havent missed any steps,
Does it contain valid metadata in a json file?
What does your mod folder look like
probably not lol
Mod id
Mod name
id is the thing that gets put in your objects, like j_tomato_jonkler, whereas name is the display name
what is that supposed to look like if i may ask?
1 s
i have no experience in lua nor am i very experienced programmer
ok nthanks
It's mainly data that the modloader uses to describe your mod
this is my metadata file if you need an example{
"id": "Gooodsoups_Garbage",
"name": "Gooodsoups' Garbage",
"author": ["Gooodsoups"],
"description": "Adds random jokers and jinkies to make your balatro experience horrendous!",
"prefix": "GG",
"main_file": "main.lua",
"badge_colour": "8201B4",
"dependencies": [
"Talisman (>=2.5)"
]
}
This is a mod example that adds jokers , it should help
ah the tutorial iam following is just outdated then
yea it might
i think you confused the id and prefix
id is just an internal identifier for the mod
smods now uses one json and a minimum of one lua file
also another quick question what is the prefix used for?
i have this ``` {
"id": "UnbalancedJokers",
"name": "Unbalanced Jokers",
"author": ["Tomato"],
"description": "This is a mod that makes every joker unbalanced in your favor",
"prefix": "",
"main_file": "UnbalancedJokers.lua",
"version": "1.0.0"
}
its added to all your object keys
you need to include a prefix im pretty sure
use UJ if you want
oops you're right
i forgot they were separate entries lol
Does it matter what it is?
no
not really
ok
no, but it should be related to your mod cuz you're gonna be typing it often
since smods just uses prefixes to separate mods and avoid clashes
as far as i know
its just a thing that gets added to your object keys between the base key and class prefix
ok
also bump
also is badge_colour required?
Just put a random color
nope, it defaults to hex #666665
do a hook
trvth nvke
noo my only weakness
everyones weakness 😔
evaluate_play_final_scoring?
oh context
nvm
I now only have 2 files a .json and .lua
is it enough
the json contains your metadata right
yes
yea it should show up i think
ok thanks
wait are you supposed to have a seperate file containing metadata?
currently its just in my main 😭
you shouldnt be defining you mod in a lua file anymore
its in a json now
thats old stuff, put it in a json
back in the olden days we used to use --- STEAMMODDED HEADER

