#💻・modding-dev
1 messages · Page 684 of 1
local uno_data = {
values = {
'2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace'
},
colours = {
Red = 'Hearts',
Blue = 'Spades',
Green = 'Clubs',
Yellow = 'Diamonds'
}
}
uh no, its just a local
behind it is a planet card
however this also seems bad since it creates more conflicts with other crossmod
at the same time this exists
-# also local!!!
I think you just patch in your modifications after the table here
first time patching so uhhhh
[manifest]
version = "1.0.0"
priority = 0
[[patches]]
[patches.pattern]
target = '=[SMODS jen "jen.lua"]'
pattern = '''
local uno_data = {
'''
position = 'at'
payload = '''
uno_data = {
'''
match_indent = true
```the patch so far
wait i'm confused
don't patches happen before smods can load any mods
no wait nvm i see the issue with just making it global
@queen crescent i think your best bet is to copy the uno card loading code into your own mod and just run it with only the custom uno cards you want to make
and then hook relevant functions and whatever
.
patches happen when the file being patched is loaded
In this case that's jen.lua so patching happens right before pwx is loaded
is there info_queue stuff for blinds?
bump
bumping
it's loc_txt, not loc_text
Thx
at which point during the draw?
first hand drawn, and during pack openings that draw cards?
During any draw from the deck
ehh scratch that i found a workaround
I have an example patch here to do exactly tha- I wasted half an hour of my life then
most jank crossmod ever made
-# up-to-date image
oh im sorry
my game carshes for some reason I dont why, Its started carshing when I added a boss blind but I dont really know.
your blind object declaration is wrong
it should be SMODS.Blind{...}, not SMODS.Blind = {...}
the latter overrides SMODS.Blind, causing crash when smods tries to take ownership of The Wheel
21
hey so I cant figure out how to add my logo to the title screen
So this code is from maximus but like it doesnt work
https://github.com/Steamodded/smods/wiki/The-Mod-Object#modmenu_cards---table you dont need to hook, you can use this now
yeah but its not a card
np
you can do other main menu stuff in that function
Oh I'll look in that
-# just run the code in there
Is there any way to display in the joker description how many retriggers it's been given from the joker retriggers option? The way I'm currently handling retriggers is setting a value to a card (in this case card.ability.uma_retriggers) to basically give that card parmanent retriggers. What's the best way to show how many retriggers a card would have?
probably do something similar to SMODS.localize_perma_bonuses probably, thats used for playing cards so youll just need to patch in adding the retrigger count somewhere in Card:generate_ui i think?
Quick question: using the "create_card" function, how do you specifically create self made jokers. i can manage to create base game jokers but somehow i cant find the proper ID for my self made ones
j_modprefix_key?
sorry, but what is the modprefix?
the prefix defined in your mod's metadata file
when selecting a hand to play, in G.hand.highlighted outside of calculate, how do i see which cards will score
thank you found it ❤️
use G.FUNCS.get_poker_hand_info, one of the return values is the scoring hand
select(4, G.FUNCS.get_poker_hand_info(G.hand.highlighted)), but that doesn't check for things like Splash
...what the fuck is this function 😭
excellent
i was thinking of doing next(SMODS.find_card('j_splash')) to cover that, but i'm wondering if there's a util func or smth that will cover anything that changes stuff that changes hands. i'm wondering if i should iterate over the cards to check for things like SMODS.always_scores() and SMODS.never_scores()
that doesn't really cover individual instances of add_to_hand or remove_from_hand passed from context.modify_hand from other jokers though
You would copy the code from G.FUNCS.evaluate_play that does that.
I can't find a generate_ui function anywhere in the base code or inside SMODS anywhere
👍
how do i update a mod that i have on blalatro mod manager
It has an update button for mods that have an available update
Also #⚙・modding-support
-# yeah wrong channel, mod devs don't use mod managers
did you not configure auto update?
how do i make a specific boss blind play a specific track. for example, if i have a custom boss blind called b_hatch_evilplant and a music track called music_evilplant.ogg, how would i define that
key = "evilplant",
path = "music_evilplant.ogg",
select_music_track = function()
end
}
im aware i need to have smth like this ^ but how would i go about it
i dont know, i created a new release on my repo but there doesnt appear to be an update in the modmanager
- the key needs to contain
music return G.GAME.blind.config.blind.key == 'bl_modprefix_key' and 100 or nilwhere 100 is whatever priority value you want
yeah ik its meant to contain music
ok thanks
what is your mod
Is the mod manager even like. Good
it has claude code iirc
Its called Carpet rocketfuel
Interesting...
I once thought of making a mod manager inside of Balatro, or at least one that checks for updates.
oh you released 20 minutes ago..
the version checker doesn't constantly look for updates, give it a few hours and it'll be on there
ingame mod manager is probably of interest to you
no i uploaded it 2 weeks ago
Oh, is it already a thing?
I just always forget to update my mods. LOL.
??????
SMODS.Sound {
key = "evilplant",
path = "music_evilplant.ogg",
select_music_track = function()
return G.GAME.blind.config.blind.key == 'bl_hatch_evilplant' and 100 or nil
end
}```
the key needs to contain
music
specifically at the start iirc
o
the new version..
thunking it
ill keep checking, thanks for the help
Interesting. Where does it get its information?
And does it deal with updates?
same mod index that bmm uses
the last index update happens to be ~40 minutes ago, you did just miss it. it'll be on soon though, dw about it
now i get an index null value error
on line 23
this is line 23
return G.GAME.blind.config.blind.key == 'bl_hatch_evilplant' and 100 or nil
yeah i omitted some nil checks
finish the drawing
i was too lazy to include them
return G.GAME.blind and G.GAME.blind.config.blind.key == 'bl_hatch_evilplant' and 100 or nil this should do
thanks
just checked and it runs every hour
okay so i'm just messing around with modding stuff and i'm trying to make one joker that combines every single joker (or as many as i can get), is there any way to make it so stuff like the mults from jimbo and jolly joker trigger seperately instead of how i currently have it where its just adding everything together?
if context.cardarea == G.jokers and context.joker_main then
local result = {mult = 0, chips = 0}
-- Jimbo
result.mult = result.mult + 4
-- Jolly
if next(context.poker_hands["Pair"]) then
result.mult = result.mult + 8
result.chips = result.chips + 50
end
-- Zany
if next(context.poker_hands["Three of a Kind"]) then
result.mult = result.mult + 12
result.chips = result.chips + 100
end
-- Mad
if next(context.poker_hands["Two Pair"]) then
result.mult = result.mult + 10
result.chips = result.chips + 80
end
-- Droll
if next(context.poker_hands["Flush"]) then
result.mult = result.mult + 10
result.chips = result.chips + 80
end
-- Crazy
if next(context.poker_hands["Straight"]) then
result.mult = result.mult + 12
result.chips = result.chips + 100
end
-- Half
if to_big(#context.full_hand) <= to_big(3) then
result.mult = result.mult + 20
end
if
return result
end ```
#💻・modding-dev message something like this
that message and the one below should be what you need
you can just do SMODS.merge_effects() and just stack up your return table like that
how do I get a # to properly show up in a localization string? (doing \# says it's an invalid escape sequence)
you can't get a literal # through the loc parser
you have to pass it as a variable
i.e. #1# and vars[1] = '#'
thanks
Holy fuck I finally got the localization to work with the values LET'S FUCKING GO
btw what color do I use for the background of ^Mult?
there's no standard
if you have spectrallib it defines its own gradient, otherwise it's up to you
Most purple use dark_edition
is you're using spectral lib use emult
How would one get this to work with mime retrigger? I have this
if context.repetition and context.cardarea ~= G.hand and context.end_of_round and (next(context.card_effects[1]) or #context.card_effects > 1) then
effects[#effects + 1] = {
repetitions = 1,
}
end```
Based on the logic from joker forge, but it doesn't retrigger the cards
This is meant to have a 1/4 chance to give $100 when sold during a Boss Blind, but it doesn't work for some reason.
It should be context.cardarea == G.hand
And remove the context.end_of_round
context.beat_boss is only true for a very short time at the end of the round, during a timing window when you aren't allowed to sell anything
With just if its in repititon and the hand thing it still doesn't retrigger
i love when the smods wiki lies to me
Replace context.beat_boss with G.GAME.blind.boss
No, it says that's only for context.end_of_round
okay cool it works now, thanks
Code?
effects[#effects + 1] = {
repetitions = 1,
}
end
return SMODS.merge_effects(effects)
end ```
I also tried it with the context.repitition thing part there and it didnt work either
idk why the formatting just like
died
Trying to get this to work properly, but the actual scaling is incorrect for some reason
How does generate_card_ui in common_events.lua work with these lines that just seem to run the localize function, but doesn't set any variables to the function output?
how do you get the current boss blind as an object? I want it to modify its chip_text before entering the blind
You can't, the blind only exists when the blind is selected.
mm is there any way i can grab the text ui for the score required at least then
i just want to modify the text, i can properly set the score with set_blind
Is there like documentation anywhere for how all the vanilla jokers are made because i can’t find anything and the code in the jokerforge stuff doesn’t seem to work for anything that isnt like a basic mult or chip hoker
Wait I cannot use different atlases for center and soul sprite? What a hell
this sucks
try this instead
Idk how to code but I took a quick 5 minutes look into the documentation
If It works I can explain but Idk If It'll work
sanity check: SMODS.calculate_effect({ ... }, G.GAME.selected_back)?
How to I access the extra ability section of a joker inside the generate_card_ui function? the table passed through _c is card.config.center, so I can't read card.abililty.extra from there. I need to be able to toggle on a description element for any card if they have a certain extra value set.
No, it would be G.deck.cards[1] or G.deck instead of G.GAME.selected_back
generate_card_ui does have a card argument: generate_card_ui(_c, full_UI_table, specific_vars, card_type, badges, hide_desc, main_start, main_end, card) are you not able to just do card.ability?
no card for me here
what version of steamodded are you on
beta 1503a, but the bit i just posted was from base game files
try latest release
ill give that a try
Yes, you should be looking in the lovely dump.
yeah that makes a lot of sense now
i forget that patches change stuff
if you forced look into generate_card_ui then you're in trouble, good luck
how do increase the weight of another joker within a joker?
if context.modify_weights then
return {key = 'j_modprefix_key', weight = number}
end
```?
ty
latest smods has a new optional feature object_weights, which allows weight modifications up to single objects
do this first
SMODS.current_mod.optional_features = {
object_weights = true,
}
does anyone know how to get the current list of blinds in pool available for the current ante
its been seven hours. i think its pretty safe to say i didnt configure th auto update ;-;
how would i do that?
I figured it out in a weird way, literally just removing it in set_badges (typically badges[2])
looks like it's because you set fixed-release-tag-updates but didn't upload an asset like you did last time. you should remove that flag and instead point it to the default source code asset (e.g. https://github.com/carpetrocketfuel/Balatro-1AHITM-Mod/archive/refs/tags/v1.2.zip)
how do i change the github meta files
on the index? make another pull request
Sorry, i really dont know my way around github. what do i need to do
Really wish there was an easier way to edit mods on the mod manager
I get why it is the way it is but it's such a hassle
I'm still trying to figure it out having to manually edit the download link every release
what create_card do?
i can do it for you if you want
that shouldn't be necessary, the index has the option of automatic updates
It doesn't for me for some reason
I probably have it set-up wrong
But whenever I try to change something the bot gives a merging error
I can have a look for you as well, what's your mod?
Twitch Integration Mod
looks like it works fine
then you shouldn't have fixed-release-tag-updates set
I tried removing it but the bot wouldn't let me merge
looks like you still had fixed-release-tag-updates set though, which doesn't work with the link you provided
is there a way to make my enhancements display on top of the card? i have a symbol on it and want it to be on top
https://github.com/Steamodded/smods/wiki/SMODS.Back this should help
in your joker's loc_txt, text should be a table, not a string, so text = { 'I want this to add 30 chips' }
also for the atlas you don't need to include your mod prefix
how would one go about adding joker display compat?
bump
but how do i use this?
look at v remade
iirc incantation, familiar, and grim use it
or certificate
SMODS.Joker {
key = "jimbo",
atlas = "atlas",
config = { extra = { chips = 30 } },
discovered = true,
loc_txt = {
name = 'Test Jimbo',
text = { '{C:chips}+#1#{} Chips' },
},
calculate = function(self, card, context)
if context.joker_main then
return { chips = card.ability.extra.chips }
end
end
why does it say nil
Bump
SMODS.Joker {
key = "jimbo",
atlas = "atlas",
config = { extra = { chips = 30 } },
discovered = true,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chips } }
end,
loc_txt = {
name = 'Test Jimbo',
text = { '{C:chips}+#1#{} Chips' },
},
calculate = function(self, card, context)
if context.joker_main then
return { chips = card.ability.extra.chips }
end
end
}
```?
Yes.
easiest way is to use SMODS.create_card, which lets you pass a table of arguments instead of a linear list of mostly nils
but it's just a wrapper for create_card
-# it's not just a wrapper, it does add features vanilla create_card doesn't have
I'm having some real trouble getting my mod icon to load, must the textures be in {Mod root}/assets, or can that folder be called something else? I have dedicated ones to many assets, like /blinds/, /basics/, /cards/ etc., this is in Eris-dev/basics/1x/modicon.png and the 2x counterpart too.
ohh okay
This erises me
from this btw (og eris card)
does anyone know how to get the current list of blinds in pool available for the current ante
My mod now doesn't load, expects a string for a line that literally is just " ], // no conflicts yet"
How do I give a temporary discard
ease_discard(1) will add 1 discard for the current/upcoming round only
ok I though it was a G
i mean it probably is, but the ease function handles the animation too
oh yeah
json doesn't have comments
ohhh
is there a ease_hand
ease_hands_played
i wanna make a deck that makes all jokers negative, but i dont now how to do that at all or where to start
ok
I though that was modifying the number of hand played this round
thunk naming conventions
Is custom Perma bonuses possible? I wanted to give an Xmoney perma bonus but I looked on the smods wiki there isnt an option for that 
anything is possible. but as of yet there's no API for it (in other words you'd have to patch it in)
There's been a couple of people encountering an issue with my mod, where the longest animations (125+ frames) are only appearing as a red/white sprite
I'm still uncertain what's causing it
I can't really reduce the size of the files/animations themselves without removing frames
iirc that's a known issue when your atlas is too wide
Uh oh
Is there any way to fix it? As far as I know, I can't, like, stitch two animations or columns together for a card based on how SMODS implements it
hopefully they add an API for it eventually 
gonna add it to the list of things to do 🫡
smods currently doesn't modify animated sprites beyond supporting atlas.fps, but other than that you're right
poland jonkler
welp if i'm gonna touch animated sprites, do we think something like this is worth the hassle?
specifically my comment
This is a good idea, but it's fairly specific to blind chips. A more versatile addition would be a multiplier to the duration of each frame. Let me know if you want to have a go at this, else I could do it too.
Oh, interesting!
Reminds me, I wrote a system for one of my mods that basically streamlines adding custom card bonuses since even tho I only had to account for 6 bonuses (2 scoring params, 3 operators), it resulted in having to potentially deal with 24 keys
I know there are a few mods that might greatly benefit from this
For those mods it would greatly reduce the complexity of atlases caused by duplicate frames
I have very little reference point for how difficult that would be considering I'm still relatively new to lua and balatro modding, but it sounds awesome, if nothing else
hmkay i'll do it
i do have to figure out how to make it efficient since we need to check for what frame we're on every update
https://github.com/Steamodded/smods/pull/1316 I'm actually looking forward to this one more
man, I couldn't imagine the performance if I had still been using my old 14yo Mac
probably not terrible if i just preprocess the data correctly
I also refrained from using quantum enhancements (made a new enhancement combining 8 vanilla ones instead) because of performance issues too
atp we need a solution for quantum enhancement lag or to scrap them
Is there anything specific about their implementation that is causing the lag?
ruby's looked into it, a big part is that it calls card:set_ability() a lot but there's still some unexplained lag that was happening even when she disabled all those calls and all the QE contexts
bump
why do we use set_ability for quantum enhancements btw
scoring purposes i think? idk ruby knows more
that's the part I'm concerned about
it gets called way too often
I more care about "why", not "how often'
reminds me of Chiseled cards in Ortalab jumping around when dragged
I haven't looked at ts in a WHILE but have we looked at fake changing the ability table
again, please talk to ruby if y'all are planning on doing stuff with QE, she has a WIP rework of it already underway iirc
why not just implement Card:quantum_set_ability idk
I'm planning on nothing tbh
I'd probably rather review quantum ranks than rework quantum enhancements
I'm assuming there's already a pr draft for this?
it's kind of a mess anyway, I'm not even confident enough to make any says here
I want to look into ruby's approach
no
I should also have a look at it tho
I think we can start working from scratch
also have we ever established what an actually good api for quantum anything should look like
Is there a possibility that we can afford breaking changes at some point?
if we can burn anything to the ground and start from scratch, it's quantum enhancements
if you're using it despite the lag, you're a maniac and deserve your mod breaking
imo i think scrapping the contexts entirely might be a good idea
"quantum suits" are handled just by hooking Card:is_suit, i see no issue with hooking SMODS.get_enhancements or a similar function moved to exist in Card
Highly depends on for what quantum enhancements are used for
if it's only check is enhancement present then yes this works
If it checks ability then it's more complicated
"quantum suits" don't exist in my books and they may get a more sophisticated API after quantum ranks
I don't think the context is currently the culprit though
smeared jonkler is basically quantum suits jonkler
yea my "scrap the contexts" opinion is unrelated to the lag tbh
the contexts provide more utility than what's gained from scrapping them imo
Also up for discussion is how the context should even function
fair
I definitely think we're looking for modifying a map throughout the context calc. doing it directly on the table is fine, but we can look at making proper return keys for it that are more useful
Question. Does current quantum enhancements support functionality of { m_steel = false }?
So if steel, discard it
Another question: does it supports effects available only during some contexts like All Steel cards at end of round count as Gold?
I wonder if it would be beneficial/feasible to just develop a baseline "quantum mechanics", something that can be built from, given there are three distinct attributes that are being considered for quantumization
this is a yes, because it's just a context like any other context and it's called many many times, including whenever a card is about to be scored (e.g. end of round held in hand)
so yea that's a point in favor of contexts that i hadn't considered
looks like no
question is can I apply qwuantum effect ONLY at end of round?
considering common interactions being
- attribute is considered something
- calculating each considered somethings of an attribute
- attributes require quick reference with minimal unnecessary checks
i dont know how to like parse these thoughts into words but
yes because a context stack exists
Okay, good
I see what you mean but we should have something that works properly before we abstract it
I think that all we need to do is just create Card:quantum_set_ability
Because Card:set_ability doing a lot of unnecessary work, which includes: sizing, sprites changing, debuffing...
I supposed to do my job and not balala 😭
lmao

Do you have any tests for quantum enhancements shit? I'll try to do quick attempt for optimizing them
that looks like a thunkism, did we not patch that out? 
no, copied directly from dump
shucks, should probably do that
I don't
So I have this code here G.E_MANAGER:add_event(Event({ func = function () local card = create_card("Joker",G.jokers,true,4,nil,nil,nil,"") card:set_edition({ negative = true }) card:add_to_deck() card:start_materialize() G.jokers:emplace(card) return true end }))
and I want make that insted spawning a legendary joker it spawns joker from a pool how could I make that?
should this be called on quantum enhancements?
@gilded blaze test this https://github.com/SleepyG11/smods/tree/quantum_set_ability
SMODS.add_card({set = 'poolkey', edition = 'e_negative'})
whats the cardarea and/or card set for the cards in the Editions section of the collection
the card set is just Edition as far as i know
the cardarea idk but i assume its the same as other collection menus?
i'd assume so too but i still dont know what that area is tbf
Why do you need it?
We tested it, it takes 3.5 seconds to calculate 100 quantumed steel cards in hand instead of 5.5
It's an area in G.your_collection
Also game lags much less while selecting a hand just hovering a cards
There's this card that clones cards of a certain edition, and it's freaking out when you open the collection lol
You can check if a card is in the collection by checking card.area.config.collection
Although I wonder how your checking when to clone that it causes issues with the collection
Jimbo has 2 hearts confirmed.
I actually have no idea, it's not my mod
I just added a check for if the set is Edition
also the bottom heart lines up perfectly with the rest of him
my vscode keeps lagging, I have my whole mod folder open and it's 100+ folders, how do i make vscode stop scanning the folders for coding errors?
dont open your whole mod folder
and just add mods you need for library purposes as a library in vscode workspace settings
Currently I have a sticker that's supposed to have all jokers with it be sold or destroyed at once, meaning if one is sold all are sold and the same thing with being destroyed
However my coder made it to where when one is sold the rest are destroyed and you're simply given the sell value, how can it be changed to have them actually be sold as to not trigger destruction effects when sold
There's something up with that guy I swear
how do I get my joker to display colored text like the "spade" text here
I'm having trouble making a planet, this is my code but it never works. I gave up on localisation.
-- Asteroid Belt
SMODS.Consumable {
key = "asteroid_belt",
atlas = "atlas_p1",
set = "Planet",
cost = 3,
pos = { x = 0, y = 0 },
config = { hand_type = 'ers_Mixed Bag' },
loc_vars = function(self, info_queue, card)
return {
vars = {
G.GAME.hands[card.ability.hand_type].level,
loc_txt = {
name = "Asteroid Belt",
text = {
"Level up Mixed Bag",
"{C:red,s:1.1}+1{} Mult & {C:blue,s:1.1}+12.5{} Chips"
},
},
G.GAME.hands[card.ability.hand_type].l_mult,
G.GAME.hands[card.ability.hand_type].l_chips,
colours = { (G.GAME.hands[card.ability.hand_type].level == 1 and G.C.UI.TEXT_DARK or G.C.HAND_LEVELS[math.min(7, G.GAME.hands[card.ability.hand_type].level)]) }
}
}
end
}
```lua
-- code
```
please
anyway loc_txt goes in the consumable table, not inside loc_vars
My coder keeps misunderstanding what my teal seal supposed to do so I'm asking for help here as I feel it's just simpler to do than try to explain it over multiple testing logs
When played it doesn't score and it never directly triggers jokers, when held in hand it does -10% score requirement
They kept misunderstanding it as it still doing the -10% score requirement when it scores, when in reality it's never supposed to score
Am I able to get at least a skeleton of that to present to them
it works now, dumb me forgot I had commented out the assert in my main file for planets ://
and what's keeping you from saying "only give the -10% if it's held in hand"?
The misunderstanding lies in the 'does not score and does not trigger jokers' part
is there like a language barrier or something?
also why is your coder still not in this server
no, you would use context.modify_scoring_hand
context.modify_scoring_hand works for unscoring the card
They are, I'm just more social
if you want to be explicit about it not triggering any jokers, even if they target unscored cards, you'd have to do that
but i doubt that's actually what you mean
Also yes there is a language barrier, albeit slight but it's enough to have misunderstandings such as this
yea i gathered the effect was just supposed to be "the card doesn't count as part of the scored hand"
please inform them that it's quite frankly infuriating to have to use you as a proxy, and we'd much rather talk to the coder directly if they need help with anything in the future
(just in general it's frustrating to have to go through a third party)
I'm doing this to be nice and help them, I frankly believe they value their free time which is why they don't bother outside of sending me the builds
2 optimization prs by me in 2 days
if they want the help then they should ask for help, i don't see any reason why that would cut into their free time
The only message they ever sent here was the one offering to code for me, I don't think they're a talker
If it's frustrating to you that I'm the one looking for help just don't help me
my point is just I think it's their loss if they're not willing to use the resources provided to them, including the community
but yea that's fine
Yes it is their loss, but it is also my loss if several builds in the same problems persist and they don't seem the social type so I bring it upon myself
So using this it can be set to always be unscored?
yes but i forgot you can just set never_scores = true on the seal
Oh
What about the part where it doesn't trigger jokers, is that currently possible
Like if it's a 2 rank it won't trigger even steven
Pretty sure a card not being scored already covers that
If it's a 9 rank but still scales cloud 9 that's plausible for me
Played, held in hand, discarded, etc.
Being unscoring just doesn't trigger jokers that require it to score
Hook eval_card and return {}, {} if card.ability.set == 'Joker' and context.other_card and context.other_card:get_seal() == 'modprefix_sealkey'
Seeing as you seem unsure maybe it'd be good to run a rudimentary test on that before I relay it
that will not stop it from triggering cloud 9
If it still scales stuff that's fine, it just can't cause the trigger
how can I tell if a card is generated in the shop in its set_ability function?
how can i use # in a localized string without it trying to become a variable? i tried escaping it with \ and it didn't like that
pass it as a variable, so #1# and then in loc_vars return { vars = { '#' } }
You would return '#' as a variable in loc_vars
lol, okay
I realized I forgot to ask, do you have to list every joker individually or is 'joker' the entity type
Also why the hell does it take up the whole line when I do a code box
'Joker' is the set, also it's because you would only use one backtick instead of three.
o
how would one make an enhhancement that either has the card not count towards played handd size or not count towards hand size
for hand size, you can either make it increase card.ability.card_limit by 1 (like how negative works, increasing hand size to 9 while it's present), or decrease card.ability.extra_slots_used by 1 (leaving hand size at 8)
try looking at All In Jest's implementation of Ice Cards
yea all in jest ice cards can bypass the played card limit
when I have struggled I have turned to other mods to see how they did it lul
how do i somehow always accidentally have hte same ideas as things
no such thing as an original idea, just roll with it
surely that's a small change
play limit -> overall limit
no yea i meant that as in "it does what your first request does"
as opposed to held card limit
anyway aij ice cards also can't contribute to poker hands at all, so if your idea does allow them to make poker hands then that's something unique you've got going
ah cool atleast i got that goig for me
yeah so if they temp change play limit it could just be changed to temp change card limit
like how I can change Jimbo from being useless +4 mult to be an even more useless +4 chips with a small change
went and looked at the ice cards and i think the code is spread elsewhhehre nbecause nothing happens when i use wahhts in the lua
ah
whats the least buggy way to change the y pos of a card and soul sprite in the case of an animated sprite
ok i managed to get it to take up no handspace
couldnt figure out the selection size stuff
how close is thihs code to being right?
idk why it says 3 i set it to 1 but yeah
Not very
bump
what is you're trying to do 
set a specific ability of a card if its created in shop, instead of riff-raff or judgement
can't say much its for jame
i see. does it have to be via a set_ability hook, or are you able to start from context.create_shop_card instead? that would be easier if you could
even if this isn't a specific joker or deck effect, you could still accomplish that via SMODS.current_mod.calculate
although you could alternatively do this in a create_card hook
oh that should work
forgot that context existed
i have a deck that guarantees the apperance of a pareidolia in a future shop if you have midas mask and vampire and i do that via a create_card hook
i implemented a somewhat more generic system to do so, so that i could make potential use of it with other effects and such
honestly, i might actually PR it
...oh, shop_create_flags exists 
local oldhighlight = Card.highlight
function Card:highlight(is_higlighted)
local g = oldhighlight(self, is_higlighted)
if SMODS.has_enhancement(self, 'm_modprefix_key') and not is_higlighted and self.area == G.hand and self.config.modprefix_key_enabled then
self.config.modprefix_key_enabled = false
SMODS.change_play_limit(-1)
end
return g
end
local oldaddhighlighted = CardArea.add_to_highlighted
function CardArea:add_to_highlighted(card, silent)
if SMODS.has_enhancement(card, 'm_modprefix_key') and self == G.hand and not card.config.modprefix_key_enabled then
card.config.modprefix_key_enabled = true
SMODS.change_play_limit(1)
end
return oldaddhighlighted(self, card, silent)
end
local oldcardarearemovecard = CardArea.remove_card
function CardArea:remove_card(card, discarded_only)
if Card.is(card, Card) and card.config.modprefix_key_enabled then
card.config.modprefix_key_enabled = false
SMODS.change_play_limit(-1)
end
return oldcardarearemovecard(self, card, discarded_only)
end
sanity check: card.edition.key?
i guess i'll do some cursed shit like lua 'e_'..card.edition.type
for now until someone affirms
where do i specify edition in Card:set_seal 🥴
how do i detect when a specfic consumable is used?
if context.using_consumeable and context.consumeable.config.center.key == 'c_modprefix_key'
thank you!!!
Yes.
hey do yall know how to make deck sleeves?
i was trying to make my own for my 7 custom decks in this mod im making
6*
Right, but do you have a specific question, or do you just need general info? If so, you can find the API for it at https://github.com/larswijn/CardSleeves/wiki/API-Documentation
CardSleeves Balatro Mod. Contribute to larswijn/CardSleeves development by creating an account on GitHub.
general info, ive never made a deck sleeve before
i hate the colours field
what the hell am i doing wrong i followed the example why is it always index into nil
What's the exact error you're getting, and what's your code?
loc_vars = function(self, info_queue, card)
local aoran = 'a'
local rank = 3
local suit = 'Clubs'
if card.ability and #card.ability.extra.full_stack > 1 then
rank = localize(card.ability.extra.full_stack[card.ability.extra.index][1], 'ranks') or 3
suit = card.ability.extra.full_stack[card.ability.extra.index][2] or 'Clubs'
end
if card.ability and card.ability.extra.full_stack[card.ability.extra.index][1] == 8 or card.ability.extra.full_stack[card.ability.extra.index][1] == 14 then aoran = 'an' end
return { vars = { rank, suit, card.ability.extra.increment, card.ability.extra.xmult, aoran },
colours = { G.C.SUITS[suit] }
}
end,
The colours table needs to go inside the vars table that you return in your loc_vars
i get that im stupid but my hate for the colour field is justified
why tf are you there
The hate is justified, it's a very strange format
bump
Sooo, I been wanting to do a certain UI effect for my mod that I just have no idea how to start doing, was curious if anyone could point me in the right direction
So.. my mod is making a remixed version of each joker, but currently it does this just by adding 150 jokers and disabling the vanilla ones.
Theres still a chance the vanilla jokers are relevant (like, if I have an effect that turns a joker into its vanilla card), so I thought it'd be cool if instead of having 10 more pages of jokers to sift through, that it shows my remixed versions first, and that there would be a button I could press on the collection page that would switch between that and the non-remixed cards.
Can anyone help point me in the right direction on how to do something like that?
I think all I need to know how to do is:
- override what shows up on the collection screen
- add a button to the collection screen
- (optional) be able to get/set what page of the collection screen I am on
you can change the sprite's animation.y and it should use that from the next frame change
animated sprites are a bit weird
potential idea, you can toggle the center's no_collection flag
and then find out what pressing the < > buttons does and call that function
---@field no_collection?: boolean|fun(): boolean
Ohhh okay interesting, not a bad idea! I could try that out
what magic is this?
this is part of a lua Language Server Protocol definition, which translates to: the field no_collection can either be a boolean or a function that returns a boolean
the function part is useful to you because you can use a toggle's state
no_collection can be dynamically changed in-game, too.
Oh thats beautiful! I been learning more lua tricks I can use, havent heard of this before. Gonna have to look more into how that works
I really liked Attributes in C#, and if this is a way I can do something like that, I'll be so happy
So, I suppose, all I need to know then is how to add a button onto the collections page? Is there an easy way of doing that?
I suppose alternatively I could also add a hotkey that just switches between the two views
Sagatro has a hook to it, you can take a look
thank you so much, thats very helpful
I was trying to make a joker that if some joker was in the pool it would destory it and gain xmult but it crashes can someone help me with that?
Heres code:
if context.setting_blind and not context.retrigger_joker then
local destroyed
for _, joker in ipairs(G.jokers.cards) do
if joker.config.center.pools.food then
joker.getting_sliced = true
destroyed = joker
break
end
end
if destroyed then
SMODS.scale_card(card, {
ref_table = card.ability.extra,
ref_value = "basexmult",
scalar_value = "gainxmult"
})
end
end
if context.joker_main then
return {Xmult_mod = card.ability.extra.basexmult}
end
end```
I might be wrong, but it looks like joker.config.center.pools is not defined (nil),
so you probably have to change
if joker.config.center.pools.food then
to
if joker.config.center.pools and joker.config.center.pools.food then
basically, turning the "if" statement to also check if pools exists at all before it checks if pools.food exists
now Its not carshing but dosent work im gonna try do something with it
try Food instead, thats what most mods use
also with the current smods the attribute system exists
calculate = function(self, card, context)
if context.setting_blind then
local destroyed_cards = {}
for k, v in pairs(G.jokers.cards) do
if v:has_attribute('food') then
table.insert(destroyed_cards, v)
end
end
if next(destroyed_cards) then
SMODS.destroy_cards(destroyed_cards)
SMODS.scale_card(card, {
ref_table = card.ability.extra,
ref_value = 'basexmult',
scalar_value = 'gainxmult',
no_message = true
})
return {message = localize({type = 'variable', key = 'a_xmult', vars = {card.ability.extra.basexmult}}), colour = G.C.MULT}
end
end
if context.joker_main then
return {xmult = card.ability.extra.basexmult}
end
end
i want to make something but i dont have any ideas
the function part is also not actually in smods
would be useful, though, someone should add that
it's a very simple change to SMODS.collection_pool really
then do it 🫵

how do i change the textures of joekrs?
does it persist in loads
oh I got baited
yeah that's an easy change
can't check rn
but also i have some additional features planned for animated sprites
set_sprite_pos
but how
put in the new position in the atlas
i mean like texture the vanilla joekrs
i wanna make a texture pack
oh, i was just wondering if there was another way cause i already know malverk exists
what mod is this
No this is development of a mod?
k
well yeah but
then show it off in #⚙・modding-general no?
because this is the dev help channel
modding support is the playing help channel
But that's also true
Checked yeah
More in https://discord.com/channels/1116389027176787968/1209506360987877408 than here ig :3
I didn't even know modding support existed
for some reason never showed up on my list
how does one make a targeted joker invisible?
also how do you get a joker to sick to a specific position on the screen, i've gotten it to move where i want it to move when i click on it, but it always gets snapped back every game update
what is the id of a speed tag? It's not tag_speed?
I figured out my previous questions, but now I have another. How can I fix align_cards() to act as though there are less jokers than there actually are in the card area based on a specific count. Say I do a for loop over the jokers checking for a specific attribute, how can I then make align_cards() treat the rest of the jokers as if those counted jokers do not exist. They will be invisible so their position and alignment is irrelevant.
why make the jokers invisible instead of making a new off-screen card area and store those jokers there
i want them to trigger normally
i couldn't figure out how to make that work without leaving them in the joker area
how can i fix the ante?
why trigger normally when invisible
because thats what i am trying to do
huh
the effect is to still allow invisible jokers to work while not allowing the player to align them?
i just want the joker card area to skip over the invisible cards when doing alignment
they will always have a specific attribute with this, so its easy to distinguish them
im just not sure how to correctly update align_cards() to get it to completely ignore them for everything
patch this line
What do the invisible jokers do?
wait nvm
they do what they do...
you just can't see or interact with them
yea, that's not great in terms of joker order from left to right
how do they realign when invisible and you're aligning visible ones then
its basically a workaround for fusing any 2 jokers together without trying to patch every possible trigger condition from one joker into another
thats my whole problem
hence why im trying to get align_cards() to ignore them
what I meant is that
e.g. you have an invisible joker this way, and suppose it's at slot 3 (4 other jokers are visible)
what you're able to see are the 4 visible jokers
That sounds like an awful workaround
when you realign visible ones, how would the invisible one react
the invisible one is permanently locked to the position of another joker
that's awful to implement
takes immense effort for a wacky effect that doesn't make sense to a lot of people
You’d be better off dynamically creating invisible card areas and calling to calculate that area within the calc function, similarly to how blueprint works
like i said before, i don't know how to do that
Also how would that actually work, because blueprint is a joker in your joker card area that has its calculate function called by the game. This requires any joker regardless of trigger condition or blueprint compatibility to trigger its effect whenever it should normally. The first thing I did was remove it from the card area, but I immediately ran into the issue of not having a way to trigger any joker regardless of its condition when it is not in the main joker area.
Well you should have some sort of base card that represents the fusion, no?
i do
i got it to work anyway
@gilded blaze can you test quantum enhancements in some extreme cases with this pr?
just to make sure they're not broken https://github.com/Steamodded/smods/pull/1322
I seen you mentioned that you was implementing a thing like "card count as all enhancements" or smth
i just checked and nothing in sprites persists in loads
where would i put this?
it ended up as a separate enhancement and I didn't plan on moving it to quantum 😭
since the effect is slightly different from combining 8 vanilla enhancements
premium enhancement it is:
8 vanilla enhancement in 1, with a few differences:
- lucky aspect is guaranteed
- 1 in 15 chance to destroy card, rather than 1 in 4
In your main file but outside of everything.
ah hok
thanks
ok so it works but theres a biig issue of if you try clicking on one when your hand is full it permanantly removes play size
any idea on how id fix that?
ok so actually its worse selecting multiple cards will decrease the selection limit
Code?
local oldhighlight = Card.highlight
function Card:highlight(is_higlighted)
local g = oldhighlight(self, is_higlighted)
if SMODS.has_enhancement(self, 'm_baggutro_ghostcard') and not is_higlighted and self.area == G.hand and self.config.baggutro_ghostcard_enabled then
self.config.m_baggutro_ghostcard_enabled = false
SMODS.change_play_limit(-1)
end
return g
end
local oldaddhighlighted = CardArea.add_to_highlighted
function CardArea:add_to_highlighted(card, silent)
if SMODS.has_enhancement(card, 'm_baggutro_ghostcard') and self == G.hand and not card.config.baggutro_ghostcard_enabled then
card.config.baggutro_ghostcard_enabled = true
SMODS.change_play_limit(1)
end
return oldaddhighlighted(self, card, silent)
end
local oldcardarearemovecard = CardArea.remove_card
function CardArea:remove_card(card, discarded_only)
if Card.is(card, Card) and card.config.baggutro_ghostcard_enabled then
card.config.baggutro_ghostcard_enabled = false
SMODS.change_play_limit(-1)
end
return oldcardarearemovecard(self, card, discarded_only)
end
SMODS.Enhancement {
key = 'ghostcard',
pos = { x = 1, y = 0 },
loc_txt = {
name = 'Ghost Card',
text = {
[1] = 'Played card {C:attention}Always{} scores'
}
},
atlas = 'CustomEnhancements',
any_suit = false,
replace_base_card = false,
no_rank = false,
no_suit = false,
always_scores = true,
unlocked = true,
discovered = true,
no_collection = false,
weight = 5,
calculate = function(self,card,context)
if context.cardarea == G.hand then
card.ability.extra_slots_used = -1
end
end
}
Remove the calculate function.
alrighty
You should instead put extra_slots_used = -1 in config
it still decreases my play size when selecting them on a full hand
Hi people
I'm trying to develop a mod, in this case I'm first trying to add a joker which adds chips if a full house is played
However, it always adds chips no matter which hand I play, which I find weird cause I'm specifying the poker hand context to only be Full House
https://github.com/Renzo-MGRR/Planetarian/blob/main/src/jokers/BaseJoker.lua
Any ideas how can I fix that?
the hand tables in context.poker_hands are always at least an empty table, you should check next(context.poker_hands["Full House"]) instead
Oh, alright
Thank you!
how would I make a joker with exponential mult
the easiest way is to depend on amulet, which provides such scoring keys
As long as you depend on Amulet, you can return e_mult the same way you'd return x_mult in calculate functions. For coloring the ^mult text, you'd use {X:dark_edition,C:white}
bleh you beat me to that, i'll just scrap what i was writing
so I've just gotta install amulet and make my mod dependent onn it and it'll just work?
Yeah
I don't know whether or not you need to list a version, but I think it's for the best since you wouldn't want, for example, players seeing issues that can only be caused because they happen to have some outdated version of Amulet compared to what you're running.
ok
when I try to put the version in with amulet in my dependencies my mod no longer shows up in the mod menu
My probability joker is crashing to desktop when I hover over it with Oops, what am I doing wrong? I can hover over it in the collection just fine (without Oops anyway) and get no nils. (I think) Relevant code is:
loc_vars = function(self,info_queue,center)
local multnum, multdenom = SMODS.get_probability_vars(self, 1, center.ability.extra.multodds, "goldenmult")
local moneynum, moneydenom = SMODS.get_probability_vars(self, 1, center.ability.extra.moneyodds, "goldenmoney")
return {vars = {multnum, multdenom, moneynum, moneydenom, center.ability.extra.multgive, center.ability.extra.moneygive}}
end,```
Replace self with center in the get_probability_vars calls
Still happens
local oldhighlight = Card.highlight
function Card:highlight(is_higlighted)
local g = oldhighlight(self, is_higlighted)
if SMODS.has_enhancement(self, 'm_baggutro_ghostcard') and not is_higlighted and self.area == G.hand and self.config.baggutro_ghostcard_enabled then
self.config.m_baggutro_ghostcard_enabled = false
SMODS.change_play_limit(-1)
end
return g
end
local oldaddhighlighted = CardArea.add_to_highlighted
function CardArea:add_to_highlighted(card, silent)
if SMODS.has_enhancement(card, 'm_baggutro_ghostcard') and self == G.hand and not card.config.baggutro_ghostcard_enabled then
card.config.baggutro_ghostcard_enabled = true
SMODS.change_play_limit(1)
end
return oldaddhighlighted(self, card, silent)
end
local oldcardarearemovecard = CardArea.remove_card
function CardArea:remove_card(card, discarded_only)
if Card.is(card, Card) and card.config.baggutro_ghostcard_enabled then
card.config.baggutro_ghostcard_enabled = false
SMODS.change_play_limit(-1)
end
return oldcardarearemovecard(self, card, discarded_only)
end
how would i fix this to prevent my hand size being made smaller when trying ot select with a full hand
If you start the code block with ```lua you'll get text coloring
Anyways, what exactly is your enhancement trying to do? If you just want the card with it to not count against the hand size, putting extra_slots_used = -1 in the enhancement's config will cover that, no hooks needed at all.
nono its meant to be able to be selected beyond your play size
it works but its very buggy atm
like if i select all normal cards and try select one it will decrease my play size instead
how do i check if a card is flipped? 
How does the key part of prefix_config work when creating a Consumable type?
I know that
prefix_config{
key = {mod = false}},
is a thing, but how do I actually define the prefix for the item type itself?
if card.facing == "back" then
it just means that consumabletypes don't automatically get the mod's prefix attached to the start of the key. if you create a new consumabletype with key "Something", it'll just be "Something" in-game, not "modprefix_Something"
this is mostly relevant for e.g. localization or creating the card of that consumable type, where you'd normally add that mod prefix
wait so then where do I actually put this
you don't need to have a prefix_config in your specific definition
is this channel only really used for technical questions or can balance ones be asked here
yea this is for technical stuff, balance questions usually go in #⚙・modding-general
this isn't returning true when i put seals or editions on anything
that's not how it works
you need to do a second loop, right now you're just checking if G.jokers.cards.seal etc
ipairs cannot have multiple tables as input
ipairs is taking a table, that part's fine
but yea your existing loop should have cards instead of card_obj, and then inside it you should do for _, card_obj in ipairs(cards) do
ohhh
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.m_zwp_whimsical
local whimsy_tally = 0
if G.playing_cards then
for _, playing_card in ipairs(G.playing_cards) do
if SMODS.has_enhancement(playing_card, 'm_zwp_whimsical') then whimsy = whimsy_tally + 1 end
end
end
return { vars = { card.ability.extra.emult, 1 + card.ability.extra.emult * whimsy_tally } }
end,
for some reason the total emult isnt displaying correctly in game
j_zwp_exwhimsy ={
name = "Compounding Whimsy",
text = {
"Gives {X:dark_edition,C:white}^#1#{} for",
"each {C:attention}Whimsical Card{}",
"in your deck",
"{C:inactive}(Currently {X:dark_edition,C:white} ^#2# {C:inactive} Mult)"
}
}
thats the localization
Hello Zarcheus.
That is an interesting problem you have there Zarcheus.
Too bad no one will help you.
How can I make effect "<vanilla poker hand> counts as <another vanilla poker hand>"?
whats wrong with my sleeves
ok so i'm working on a spectral card that should shuffle seals and editions accross cards and jokers, but for some reaosn, some are getting removed outright instead of being moved somewhere else
here's the entire use function, what am i doing wrong
You need:
- collect all seals and editions you can transfer and store them in a list
- cleanup all editions/seals on all cards
- for each filtered seal
- collect all cards available to target
- roll a card to apply
- apply upgrade
- exclude this card from available cards
- if all cards was used, discard leftover seals
- repeat until all seals distributed
- repeat for editions
that's pretty much what i wrote. it goes through everything, grabs all the seals and editions, cleans them up, goes through each grabbed seal, picks a random applicable card from the pool, applies, removes that card from the pool, repeats until all seals are assigned, then repeats for editions
but as i show, it's deleting some seals and editions for whatever reason
erm this doesnt work yk
for removing them from the pool?
this things do nothing essentially
hhhhhhhh
so how do i properly remove the items from the pool
First, you need to make sure that pool is separate object and not belongs to smth like cardarea
fullObjPool is fine because it's result of merging multiple arrays which returns new array
but onlyJokerPool is reference to G.joker.cards which is live object belongs to cardarea
you don't need to have a prefix_config in your specific definition
you don't need prefix_config anywhere, i promise. defining a new consumabletype handles it automatically
So first step will be local onlyJokerPool = SMODS.shallow_copy(G.joker.cards or {})
won't it not take if i do shallow copy?
Yeah that's what mannpower.lua's there for, it's the file with the ConsumableType
again, you don't need to have it anywhere at all. delete line 5 entirely
i was gonna say if i do copy_table, it'll crash because recursive. but shallow_copy i thought would make it no longer reference the original items, which i need to be able to actually assign the seals/editions
no, copy_table will cause stack overflow
SMODS.shallow_copy takes array of items and make it's copy, that's it
items stay the same, but array containing them is new
so :set_seal on a objects in a shallow copy will still apply a seal to the original object?
you're not copying cards, only array containing cards
Okay at least there's something now
ahhh
it's 1-layer copy, not deep
ok so how do i properly remove the items from my pools once i've assigned a seal or edition to them
pseudorandom_element returns 2 things: rolled item, and key rolled
table[key] = nil?
now where do I put the actual thing name in the localization
So, ```lua
local onlyJokerPool = SMODS.shallow_copy(G.joker.cards or {})
for _, seal in ipairs(seals) do
local target_card, target_key = pseudorandom_element(onlyJokerPool, "cirno_rng_key")
if target_card then
onlyJokerPool[target_key] = nil
-- apply seal
end
end
not the consumable, the category
then you need find index of target card by looping and remove it aswel
kinda sucks but you have no choice
I feel like you're not quire understand what is "reference" in programming yet
bump
bump x2
most checks for hands do next(context.poker_hands[hand]) so maybe try setting a metatable to context.poker_hands when it's created so that when indexing hand you return smt different

i'm assuming local declarations only last for the remainder of the condition
Always was
local t_obj, t_key
if red_seal then
t_obj, t_key = pseudorandom_element()
else
t_obj, t_key = pseudorandom_element()
end
and, you're looping a bit wrong
for k, v, in pairs(pool) do
if v == t_obj then
pool[k] = nil
break
end
end
pairs and ipairs difference is inportant
you want pairs, not ipairs
it's a keyed table?
number is also a key
what's your atlas definition? either there's something wrong with your asset or your atlas definition
heres the one for the sleeve and the one in main.lua
sleeves are not 365 by 190 😭
oh, i copied the x1 from cardsleeves lol
do they all need to be individual sleeve pngs then
ok
the px and py tell the game how many pixels go in each sprite
it already knows how big the image is
Ah, of course.
I want to leave the suit intact
what does this even mean?
then just make the suit nil
yea they only want to change the rank of the card
anyway the rank also has to be the key of the rank, not the id
so it should be "King", not "13"
i'm in like 8 teto servers
It at least doesn't crash now.
(It letting me select up to 2 cards is just from me copying most of Strength's code as a base and adding/changing shit from there, in the future it will only select 1)
but uh
yeahhh
okay I think that should be it fixed
damn you, ouija
trying to destroy consumables and im failing miserably
if context.end_of_round and context.main_eval then
return {func = function()
SMODS.destroy_cards(G.consumeables.cards[1])
end}
end
ya returning remove only works in one or two specific contexts, SMODS.destroy_cards is what you'll want to use most of the time
how do I apply a perma.bonus to a card from using a consumable?
card.ability.perma_bonus = (card.ability.perma_bonus or 0) + number
my "casual" voucher isnt showing up on my custom sleeve
it's cus you're fully overriding the apply function, at the start of it add CardSleeves.Sleeve.apply(self, back)
before apply = function(self, back)?
after that line
apply = function(self, back) CardSleeves.Sleeve.apply(self, back)
?
apply = function(self, back)
CardSleeves.Sleeve.apply(self, back)
-- rest of your code
end
works now, thx :)
Why there are no colors~~ and no values~~ at all? nvm about values im just dum
en-us.lua
Weapon = {
c_liroxfunstuff_weapon_stick = {
name = "Stick",
text = {
"Next played hand have {C.chips}+#1#{} Chips",
"Has {C.green}3 in 4{} chance to appear in first 3 shops",
"Has {C.green}#2# in #3#{} chance to become Metal Pipe",
"Pretty much useless"
},
},
weapons.lua
newWeapon(
"weapon_stick",
0,
{extra = {baseChips = 50, chips = nil, event = "before_card", interations = 1}},
function(self, info_queue, card)
return {
card.ability.extra.chips,
3, 4
-- todo: add propabilities
}
end,
function(self, card, area)
card.ability.extra.chips = card.ability.extra.baseChips * G.GAME.blind.ante
end,
function(self, card, area)
apply_weapon(card.ability.extra)
end
)
globals.lua
function newWeapon(key, cost, config, loc_vars, update_values, use, pos, can_use, replicatable, has_soul)
pos = pos or {x = 0, y = 0}
can_use = can_use or function(self, card, area) return true end
if replicatable == nil then replicatable = true end
if has_soul == nil then has_soul = false end
SMODS.Consumable({
object_type = "Consumable",
atlas = "weapons",
key = key,
set = has_soul and "SoulCard" or "Weapon",
config = config,
loc_vars = loc_vars,
pos = pos,
soul_pos = has_soul and {x = pos.x, y = pos.y + 1} or nil,
cost = cost,
unlocked = true,
discovered = false,
use = use,
can_use = can_use,
update_values = update_values
})
if replicatable then -- todo: add in BookOfLifeDrop pool
end
end
i was doing some rigorous testing, and it seems that sometimes pseudorandom_element will return two nil results.
It should be C: not C.
so its c: for consumables or loacales?
like, because its a consumable or because its in locale file
in en-us.lua, c: is the correct colour format, not C.
so for locales its c: instead, noted
now next question: how to make some cards have different type names? for example there are planets and dwarf planets in the same category
Use the set_card_type_badge function.
uhh example?
like, set_card_type_badge("c_liroxfunstuff_weapon_sword", "some_translation_key")?
set_card_type_badge = function(self, card, badges)
table.insert(badges, create_badge(text, card_type_colour, card_type_text_colour, 1.2))
end
ohh that
is text here a translation key?
No, text is the text as a string.
its not working for me apparently? is usage of HEX("colors") here ok or i need to use smth else?
I tried everything but it just wont work
Code?
function newWeapon(key, badge, cost, config, loc_vars, update_values, use, pos, can_use, replicatable, has_soul)
pos = pos or {x = 0, y = 0}
-- badge = badge or function(self, card, badges) badges[1] = create_badge(localize(badge), get_type_colour(self or card.config, card), nil, 1.2) end
badge = badge or function(self, card, badges) table.insert(badges, create_badge(text, get_type_colour(self or card.config, card), nil, 1.2)) end
can_use = can_use or function(self, card, area) return true end
use = use or function(self, card, area) apply_weapon(card.ability.extra) end
if replicatable == nil then replicataable = true end
if has_soul == nil then has_soul = false end
SMODS.Consumable({
object_type = "Consumable",
atlas = "weapons",
key = key,
set = "Weapon",
config = config,
loc_vars = loc_vars,
pos = pos,
soul_pos = has_soul and {x = pos.x, y = pos.y + 1} or nil,
cost = cost,
unlocked = true,
discovered = false,
use = use,
can_use = can_use,
update_values = update_values,
set_card_type_badge = badge
})
if replicatable then -- todo: add in BookOfLifeDrop pool
end
end
newWeapon(
"weapon_dagger",
"test",
2,
{extra = {baseChips = 50, chips = nil, event = "before_card", interations = 1}},
function(self, info_queue, card)
return {
card.ability.extra.baseChips,
card.ability.extra.chips
}
end,
function(self, card, area)
card.ability.extra.chips = card.ability.extra.baseChips * G.GAME.blind.ante
end,
nil,
{ x = 1, y = 0 }
)
Your inputting badge as "test" instead of a function.
isnt it redefined? badge = badge or function() {} end?
how do I check each card in context.full_hand to see if one has an enhancement
It's only redefined if it doesn't exist.
x = x or y means "Keep x as it is, unless it isn't set to anything at all. If it doesn't exist, set it to y"
ohh, ok
whats the translation key of consumable type? For example Tarot Cards, Planet (badge),
foreach in it?
b_<type>_cards for "Type Cards", such as when looking at the list of consumable types in the collection
k_<type> for "Type", which is the text used in the badge itself.
uhh this goes into misc.dictionary?
Yes
thanks
How would I add a Joker Display line for any potential joker (vanilla or modded) that has a certain config item that my mod sets? Would it be a similar method to patching generate_card_ui and simply checking for the value?
foreach in it and do SMODS.has_enhancement(iteration_card, 'm_steel')
replace m_steel with your needed enchantment
if context.individual and context.cardarea == G.hand and not context.end_of_round and context.other_card:get_id() == 14 and context.other_card:is_suit(card.ability.extra.suit) then
hasstonecardinscore = false
for card in context.scoring_hand do
if SMODS.has_enhancement(context.other_card, "m_stone") then
hasstonecardinscore = true
end
end
if context.other_card.debuff and hasstonecardinscore == true then
return {
message = localize('k_debuffed'),
colour = G.C.RED
}
else
return {
x_mult = card.ability.extra.xmult
}
end
end
end```
this code crashes game
how fix
may you provide the crash log?
I gotta say you're making your life harder by downgrading to SMODS 0.9.8 style of declaring a new object
Use this instead:
for _, playing_card in ipairs(context.scoring_hand) do
if SMODS.has_enhancement(playing_card, "m_stone") then
hasstonecardinscore = true
break
end
end
What is the goal?
is there a better way?
this is lowkey better
define each object as a table
put them all into a larger one
then run a loop
may i see how you define joker_table?
You could also just extend SMODS.Consumable
interesting, thanks for the idea
it's better than your previous one, sure
but it's still not ideal
it's best you put each object in a separate file
and make a folder containing all those files
then in main.lua (your main file), load all items in that folder
otherwise you end up with an ever-inflating single file
😭
i already have separate files like jokers.lua, weapons.lua, decks.lua, etc all in items folder
if you don't plan to have 100+ weapons, fine then
i already made all of them
18k lines....
the only 2 things left are texture atlas and weapon execution system
and still going up since this is my local branch and I'm adding more stuff as we speak
I'm scared
hello scared, I'm Lirox
hi Lirox I'm sleepy
Is there a standard way to create your own "events" for jokers to calculate?
Like, my mod adds the ability to click tags to use a charge of that tag to do some action, and I'd like for jokers to be able to react to it
You would call a context where you are triggering the tags.
so do I just loop through all the jokers, call the calculate function and pass in my own "context" table that just sets some value like {tag_charge_used = true, tag = "tag_whatevertagkey"}
No, SMODS.calculate_context({modprefix_tag_clicked = true, tag = tag})
Ooooh okay ty ty thats helpful
whats the function for checking edition?
im using if context.other_card.edition == "e_prefix_edition" then but its not working :(
if context.other_card.edition and context.other_card.edition.modprefix_key
ok ty
card.edition is a table if the card has an edition
check card.edition and card.edition.type
or what something said, that also works
quick question sorry
would setting context.before and context.after to true for before/after the effect be appropriate here? Or is that not how those are intended to be used?
No, that would trigger jokers that trigger on those contexts.
Ah okay I think I might've misunderstood what the purpose of those contexts were
ty!
just don't do SMODS.calculate_context({before = true, after = true}) directly
objects that rely on those contexts expect more fields, which will certainly crash the game
Hello everyone, i got a question regarding a joker idea i have. Is it possible to make a joker that makes face cards function like wild cards? I want to try and make one but i don't know whether that is even possible or not.
SMODS.current_mod.optional_features = {
quantum_enhancements = true,
}
SMODS.Joker{
key = "example",
calculate = function(self, card, context)
if context.check_enhancement and context.other_card:is_face() then
return {
m_wild = true,
}
end
end,
}
oh
huh
is_face takes Pareidolia into account
ah, context loop
😭
I need to figure out how to set my project up so that I have context menus so I can actually navigate these contexts
Ah, Ty for the help!
wait, don't use it yet
replace context.other_card:is_face() with SMODS.Ranks[context.other_card.base.value].face
Okay
What sort of menu do you mean?
for my IDE
I just been opening files with the default IDE, which is Visual Studio for me, (probably since I usually work in Unity) but theres no context menus of any kind showing when I press G. for example, it won't show me what options are available from it, I been having to memorize, reference documentation (which is hard to navigate sometimes to find what I need exactly) or print values to see what is in them, or, just ask questions here
(Incomplete) LSP for Balatro. Contribute to frostice482/balatro-lsp development by creating an account on GitHub.
Oh hell yeah, thank youuuuu that looks like a lifesaver
No, smods detects context loops.
How can I mimmick the ability of a joker by joker key? (if possible)
this will break on smods#1322
This PR targeted to optimize quantum enhancements by providing Card.quantum_set_ability function, which works mostly the same as Card.set_ability but without any kind of resizing or sprite manipula...
If that gets merged then they would use that function instead.
true, just wanted it to be known that this will no longer work
or maybe it makes sense to actually redirect that to the new function? probably
i want to make something but i dont have any ideas for what to make
lovely patches Card:open to not set G.STATE = G.STATES.TAROT_PACK etc.
how would i go about checking what type of pack is open?
SMODS.OPENED_BOOSTER.config.center.kind
Does the global calculate happend before every other calculate in the same context ?
No, afterwards
speaking of it. Can ve consider a new release? So far there was no big changes merged, so merging 2 optimization prs and making new release for sake of performance makes sense?
We can figure out how make quantum enhancements properly later, right?
Just curious, has anyone took advantage of lua metatables for balatro modding?
Been learning more lua, and it looked super powerful, so I was curious if there was any applicable examples of it, cause I thought it'd be fun to see
Oooo I would love to hear of cool uses of it though, any stand out?
but also basically every object in balatro uses metatables in order to make object oriented-like programming with them
this is one i have tho
very very simple
Ooooo okay okay I heard about metatables being useful for that
i did this so i could do results[x] = results[x] + y without having to check if results[x] was there already
I'm more used to object oriented programming (came from working in C# for Unity), so lua has been.. interesting to learn
Ahhh I see, thats super cool actually
metatables is a way to define getters/setters by using middleware basically
Yeah yeah, that makes sense, was looking at what you posted, I suppose you're just making an update system of some kind that uses __index as a getter
thats pretty cool
Yes, I use metatables for my blueprint enhancement: https://github.com/Somethingcom515/SealsOnJokers/blob/dev/main.lua#L2999
A mod that puts seals on everything. Contribute to Somethingcom515/SealsOnJokers development by creating an account on GitHub.
So
I'm making a mod that remixes all the cards in vanilla balatro (called "Disheveled")
and, so far I was just adding new jokers/consumeables/etc that suppress the originals from showing up in the pool
But I came to the realization after making an effect that reacts to you gaining a "juggle tag" specifically
And I realized that, if someone else made a key check for that in a different mod, I would like the keys to inherently also apply to the disheveled versions. So gaining a "disheveled juggle tag" I want to also trigger "juggle tag" effects for example
One idea I had on achieving that was changing the metatables of any "key" values to override the __eq when comparing it
But, I realized that was probably... awful, and probably annoying to set up anyways
(The other option I'm concidering after Somethingcom515 showed me the mimic joker effect, was to just override the base jokers with all values of the Disheveled variants instead of having entirely new copies of each thing. But, that also is probably really messy too so, I probably just wont worry about it)
That wouldn't work because __eq is only triggered if the other value also has the same __eq function on Lua 5.1 which is the version of Lua that Balatro uses.
Oh wow thats actually an incredible use of metatables actually
I cant say I completely understand whats going on because of my lacking understanding of everything in balatro modding, but I think I see the general idea of what you're doing, super cool! thanks for sharing
Ahhhh okay interesting! Good to know
Yeah it sounded messy anyways, but was a thought I had
what are the licenses and what do they mean
(number 5 #📜・modding-rules message)
They are just text explaining what you can and can't do with the software
which one should i use
How can I figure out if the game is in the "select blind" screen? (Or any screen that is viable for calling G.FUNCS.reroll_boss(), to be specific)
Depends on what you want people to be able to do with your mod
what do the different licenses mean
there are way too many...
i mean the common ones'
would heavily recommend GPL3 as it's the standard for balatro modding and basically allows people to do whatever with your creation including making their own versions or using your code so long as they also use gpl3
i believe i got that correct
if G.STATE == G.STATES.BLIND_SELECT
also in file explorer there is an option to show hidden items liek AppData or .git and such is there a way to do that in vscode
Is there a function I can hook to make a playing card score even when debuffed (like for jokers we can hook can_calculate)
modding people, I remember there being a place where I can see the game code after lovely injects applied, where is that?
Mods/lovely/dump
ty
No, you would have to patch SMODS.calculate_main_scoring
Thank you
Is there any way to check for key presses?
Might help me debug a little
Thats perfect thank you
looking to replicate the "only get legendaries you dont have gold sticker on yet" mechanic for my own stake, where in the code is that located?
why does my mod not show up
desciption
oh
desciption
how do i make it multipel lines long
i just realized i messed up the icon pos
4 Aces, 12 Face Cards, 36 Number Cards
13 Number Cards, 13 Red Stakes
13 Face Cards, 13 Aces
I see nothing wrong here 
also how do i change the icons for ace face and number and not just suit cause deckskin only lets you change the icon for suits i think
i want to make it
4 Diamonds, 12 Clubs, 36 Spades
13 Number Cards, 13 Red Stakes
13 Face Cards, 13 Aces
someone?
you can just override the atlas that contains those
what do you mean
This is how I am creating a tag
G.E_MANAGER:add_event(Event({
func = function()
local tag = Tag("tag_dishevel_juggle")
tag:set_ability()
add_tag(tag)
play_sound('holo1', 1.2 + math.random() * 0.1, 0.4)
return true
end
}))
Is there a way to make this immediately call apply on the tags upon it being created?
seems reasonable. one thing that comes to mind is that we should probably allow backwards compat with delay_sprites="quantum" by means of redirecting to the new function. A feature overhaul can wait I guess. In that case I do want to include another change I discussed with Wilson the other day
@frosty dock
Easy to do, I'll do it
make atlases with the exact key the vanilla atlases for the icons use (using prefix_config or raw_key), I think that's ui_1 and ui_2 for the low and high contrast versions respectively. this is unconditional though, so if that's not good enough you'll have to patch the code responsible for creating the corresponding sprites
mm, is there a way to have it still activate for individual context as well
i am still confused, is there an example?
SMODS.Atlas {
key = "ui_1", -- low contrast icons
prefix_config = { key = false },
px = 18,
py = 18,
path = "icons_lc.png",
}
does anyone happen to know how to force the visuals of a playing card to update?
im using debuff card in the before context but its not working
is there a way to change the path of an atlas at runtime and it will change its texture?
https://github.com/Steamodded/smods/wiki/SMODS.Keybind
what do i put for action(self)
couldn't tell you how but yes there's a way
look into the pixel smoothing code
Is there a way to get tags to call apply?
\n
Can someone please help me? Im trying to make a joker that makes all face cards function like wild cards but i can't get it to work.
quantum enhancements 😭
send your code
already got some help with the code but i can't get it to exactly work
just use context.other_card:is_face()
like this?
okay, lemme see if it works.
okay so something went wrong. there is a mistake but i can't figure out how to fix it, i have been trying the last couple of minutes but nothing works
delete the yellow bracket at the end
if it says it expected something that means you got a syntax error
i got unclosed brackets now
hi
long story short; i'm working on a mod and i'm looking for people who can actually make sprites /nf
if you can make sprites and wish to help me out, contact me via DM.
i need to know how
what does pixel art smoothing even do
maybe im missunderstanding you but just use Debugplus and press ctrl + m to reload atlases?
the problem is how do i change the atlas not how to reload the change
what use is it to reload it if i cant change it
ah right, mb
switch the file path from 1x to 2x and vice versa
I forgot to say that I did the thing
look into the code of it and figure it out
trial and error along with examining code is one of the best ways to learn
i'm working on a mod and i'm looking for people who can actually make sprites /nf
if you are willing to help me out, please contact me via DM.
Does anyone know how to ontact the poeple behind BMM
so i can fix a missing thumbnail
oh wait i fucked up and made it not a jpg
LOL
Is there a way to attach an info-queue to a button in UI?
Can someone please help me? Right now im trying to make 2 jokers that have special functions when put together. The last 2 cards are supposed to work together, one gives chips and the other mult. Now i want to make so when both of these jokers are put together in the joker slot, they both give xchips and xmult alongside their original bonuses.
put in their calcualte function a check for the other joker
if its there, do extra
How would that exactly make that work? im still learning to code so i don't know exactly what you mean.
use next(SMODS.find_joker("j_modprefix_jokerkeyn")) to see if the other joker exists



