#💻・modding-dev
1 messages · Page 558 of 1
ok all it's doing is putting a red seal on the joker
how to unlock one challenge if another specific challenge was unlocked?
well, it works now but why the dirt card sprite is still applied after the cards are flipped?
do I have to manually set the other enhancement sprite?
I don't even know how to code lol, I hope I'll get it
No, you're telling Card:set_ability to delay the sprites.
in that case how can I fix that?
Remove all inputs after the first.
alright, thx!
whats the fix of mods not showing up in mod menu again
make your json well?
can someone help with this error? i just installed this mod and now im having the error https://github.com/Fantom-Balatro/Fantoms-Preview/releases/tag/v2.3.1
for issues not related to dev it's better to seek help in #⚙・modding-general
can you make a boss_colour a gradient?
So I follow the instructions but the open workspace settings doesn't show up in vscode
you can also just create/open a settings.json file in the .vscode folder of your mod
I want to make my own mod but I don't even understand you rmessage :<
in the .vscode folder of your mod
this part in fact
you can make it if it doesnt exist yet, vscode automatically creates it for workspaces to store workspace-specific settings
the .vscode folder
just a folder named .vscode ?
yeah
Alright thank you
Does anyone know why my custom poker hand doesn't work? I wanted to make a hand that consits of 5 custom suits, just like a flush, but the game sees it as a generic flush
where does it appear on the hands list?
Above flush
Huh, is the slow mode still here as a precaution?
a mod pinged everyone, that's what happened
the classic
not sure why it spilled to modding chats
idk why the slowmode would even be needed outside the channel with the ping since thats where the people will be
I think it's just that in general we've Alerted The Horde so now there's a hundred thousand people all of a sudden with eyes on a server likely to message at once, many of whom may have forgotten they were even in here at all
Upside is that every time an everyone ping happens in a bit server, like hundreds of people who hadn't been active in months realize they're still here and leave the server
fair point
my blinds don't show up in the collection
Do they have localization entries in a localization file?
yup
Also if you're declaring "boss", you need to also redeclare the min and max ante
Since they optional ones are entirely cleared if you replace the default
....I think
min and max are optional for showdowns
Oh then yeah ignore me
showdown blinds are a little funny and just ignore min for some reason
no wait
i forgot that i haven't asserted the file with these
Oop! That's it then
How can I make the joker create a booster pack at the end of the round?
(right after the game gives you money and before entering the shop.
hrm
blinds need an animation atlas
i see
I tried to put the scripts of creating a booster pack inside the caluclate function and if condition but... when it happens it all mixes up
like... it creates the booster pack and shows the results at the same time making it a mess
For someone who doesn't know any code, how hard do you peeps think it would be to code a mod to keep things such as special cards and jokers from oen run to the other
Is there a way to detect what sprite pos the card uses right now?
card.children.center.pos iirc
And how would I use that in an if statement? if card.children.center.pos == ? then
what's the .center property?
as in, card.config.center or?
card.center i think
i've seen it a lot in the wiki, but not good references of what is it
as far as i know card.center isnt a thing
Wait, card.children.center.pos is nil...
card.config.center contains all the information related to the center in G.P_CENTERS such as rarity, key, and like probably a bunch of other stuff that i dont know because i never needed them
or this: card.children.center.pos
card.children is related to like rendering and stuff afaik
Oh i see
That's why i'm confused lmao
card.children.center.sprite_pos
How would I use it in an if statement?
What is the goal?
I want to change the sprite of my joker when it's effect is starting and stop when it's back on the x = 0, y = 0 of the spritesheet. Normally I'd use math.floor(G.TIMERS.REAL * 10) % 7 but that doesn't stop
if card.children.center.sprite_pos.x == 0 and card.children.center.sprite_pos.y == 0
That works, thank you :3
How do you make an object appear more often in pool?
I just created a boss blind with all the requirements and the game crashes for some reason:
how can I fix this?
Rewrite the pool function for now
Alternatively wait for official support
Ill do that for now, thanks
whats the command to add a floaty thingy like the legendaries or hologram to a card
i forgort....
I just figured it out: I needed to add the boss_colour
soul_pos
ty
as per #1406740128231194644, i'd like to be able to create a single Sprite object that i can re-adjust its atlas.image property during a DrawStep (if i create the sprite within the DrawStep, the game shits itself and fps drops a ton). however, creating a sprite object just in a file that's loaded at boot crashes the game on startup, because the dummy atlas i'm passing to it doesn't actually exist (fully?) yet. how can i. do this
whats the context for defeating a boss blind? would it be end_of_round and whatever the boss blind context is or something else?
if context.end_of_round and G.GAME.blind.boss then
it's not a context, G.GAME.blind.boss is just true during a boss blind
No, it is a context, context.beat_boss
ah thanks
i sure do wish it was documented
no its an smods one
oh lol
fuck
anyway bump
How do I make a joker have an effect right before scoring? what is the context for it?
context.before perhaps?
you can see most of the context in the wiki
thx
what causes this usually (i took out talisman and this still happened)
pls post whole log
something is passing a string instead of a table for a joker description
what are the parameters of the copy_card function?
oh yep
my code fucky as always
other, new_card, card_scale, playing_card, strip_edition
im trying to make a card that creates 2 negative copies of a card and so im looking at the code for ankh. the way it does this is by selecting a card from the joker area as the variable 'chosen_joker' then doing local card = copy_card(params) and card:add_to_deck().
is this how i go about doing that :?
No, because it is removing negative.
well but id just replace that with nil and add card:set_edition({negative = true}, true) before card:add_to_deck()
im mainly asking if this is the current up to date way to do this since i know smods does streamline some methods
tis the problem with referencing code from the base game
whats the code for a joker? like, if i wanted to exclude a specific joker from a for k, v in pairs function what would that be?
card.key = 'j_joker'?
card.config.center_key
ty
if i wanted to use a joker to retrigger other jokers (not copy) how would i do that
like if a joker from the list activates, retrigger it
first, you need to enable the optional feature to allow for retriggering jokers. then you can retrigger a joker by returning repetitions = [number of retriggers] during context.retrigger_joker_check
first you want to enable the joker retrigger optional feature (https://github.com/nh6574/VanillaRemade/wiki#what-are-optional-features), then its the same as retriggering cards but in the retrigger_joker_check context
why does my mod cause this error when the base game doesnt? (second image is the code for ankh i referenced, third is my code)
What is the best way to create an exact copy of a card?
copy_card
local card = copy_card(-thing youre copying-, nil)
card:start_materialize()
card:add_to_deck()
G.jokers:emplace(card)```
It's a playing card that needs to go into the deck actually
youre missing a = in the condition
actually the condition is wrong
copy_card(-thing youre copying-, nil) will give a error
card.config.center.key ~= "j_kj_kaito"
It was supposed to be a filler for the actual thing you're copying, idk what you're using it for :v
center_key also works im just used to the .
What is a "center" in Balatro? Been meaning to ask
different name for game objects
Should've probably already read through that in its entirety
to give a more precise answer, prototypes for properties of cards - defining the properties of jokers, consumables, enhancements, editions etc. It's not quite consistent what is or isn't a center, some prototypes (like for blinds) are defined in the same way but are not considered centers by the game
would this check if a selected card is debuffed?
Don't worry, this channel is for those who did read to tell you stuff you'd know by reading 
being the main ability is the closest consistent answer you can get, but it's not quite correct either
.debuff
I haven't read a thing, just got other people to do stuff for me!
enhancements and editions are centers, while seals aren't

also editions are a bit wierd
because they can actually be applied to cards without replacing the existing center, unlike enhancements
If you think of the terms literally it kinda makes sense
Editions and enhancements change the card at the core while seals add things on top
what about backs
editions also just add something on top
there's no deeper reasoning behind that, all there is to that is that there was only one seal in the beginning - so thunk didn't need to prototype them to start
Is it possible to make it, so that I don't always have to make this 'window' when I do this but rather switch the person depending on the card it is shown next to?
name = "Idea:",
text = {
"{C:purple}Person"
},
},
No no editions on cards irl quite literally affect the printing, it's not like a sleeve or wtv
put a variable in it, and add a specific_vars field when putting into the loc_vars
as in #1#, etc
What?
that's not how it's applied to Balatro cards though, it's a shader that overlays the sprite
editions are shaders applied directly to both card.children.center and card.children.front
as opposed to a seal, which is its own layer
So seals are?...
seals
i mean regardless theres no deeper meaning behind whats a center and isnt
Could you maybe give me a little example or explain it a bit more, please?
Kind of their own thing, Balatro source code isn't that organized
garbshit for example does (left image) in the localization, and enters the variables for the description in the loc_vars (right image)
Being a center is defined by being stored in a table called G.P_CENTERS
seals have their own table G.P_SEALS
huh i sure wonder why my code isnt working
"guys why isnt my code working"
looks inside
like 10x10 pixel screenshot at most
calcute :3
I hate when that happens
lua language servers when you give number|scrimblo to parameter expecting number: 😭 😭 😭 😭 🤬 🤬
lua language servers when misspell parameter by 1 letter: 😊 😊 😊
lua language servers when there is no possible way a given value is nil: need check nil 😡
ok so i did that and now when i get to the context this crash happens :?
if context.beat_boss and context.game_over == false then
local dupeable_jokers = {}
for k, v in pairs(G.jokers.cards) do
if card.config.center.key ~= "j_kj_kaito" then dupeable_jokers[#dupeable_jokers + 1] = v end
end
local card = copy_card(pseudorandom_element(dupeable_jokers, pseudoseed('kaito_choice')), nil)
card:set_edition({negative = true}, true)
card:start_materialize()
card:add_to_deck()
G.jokers:emplace(card)
card:add_to_deck()
G.jokers:emplace(card)
end```
its better if you post the logs in full
why are you doing emplace and add_to_deck twice
cuz theres 2 cards :V
oh
youre only copying one
no it doesnt
?
thats what we're saying
you need to create two cards
ohhh
you cant just do emplace and add_to_deck twice on one card
also dont call it card, since that already exists in the function's arguments
could do wierd shit
does anyone here know if you have to submit your mod somewhere to add it to bmm?
it should be v.config.center.key ~= "j_kj_kaito"
i thought thats what im supposed to do, im just mainly copying code from the ankh card
yes, to the balatro mod index, it should be in the bmm thread
i mean
i dont think ankh uses the regular card parameter anywhere
though generally overriding function arguments isnt needed anyway
Is this is a good way to select two random cards from the scoring hand? It seems like the destruction table always is nil
you should use a local variable to store the cards to destroy, game does not like storing objects in card ability tables
also use context.destroy_cards if you want to destroy played cards
also dont shuffle the scoring hand or you might mess up other effects
try pseudorandom_element to pick a random card
Sweet, g2k
Nice, thanks
pretty new to this
if self.ability.name == 'Ankh' then
--Need to check for edgecases - if there are max Jokers and all are eternal OR there is a max of 1 joker this isn't possible already
--If there are max Jokers and exactly 1 is not eternal, that joker cannot be the one selected
--otherwise, the selected joker can be totally random and all other non-eternal jokers can be removed
local deletable_jokers = {}
for k, v in pairs(G.jokers.cards) do
if not v.ability.eternal then deletable_jokers[#deletable_jokers + 1] = v end
end
local chosen_joker = pseudorandom_element(G.jokers.cards, pseudoseed('ankh_choice'))
local _first_dissolve = nil
G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.75, func = function()
for k, v in pairs(deletable_jokers) do
if v ~= chosen_joker then
v:start_dissolve(nil, _first_dissolve)
_first_dissolve = true
end
end
return true end }))
G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.4, func = function()
local card = copy_card(chosen_joker, nil, nil, nil, chosen_joker.edition and chosen_joker.edition.negative)
card:start_materialize()
card:add_to_deck()
if card.edition and card.edition.negative then
card:set_edition(nil, true)
end
G.jokers:emplace(card)
return true end }))
end```
oh this is vanilla code
you should generally always use vanillaremade for reference over vanilla code since vanilla code is a little funky sometimesx
where would i aquire such vanillaremade code
VanillaRemade also more accurately reflects how things would be implemented in mods
thats me
thanks N for making vanillaremade
❤️
N is so goated
the spectrals are astra tho
alr coolio ill just rewrite it using vanillaremade as a base
<@&1133519078540185692>
are the cards in you played hand considered "highlighted"?
i wanna create a boss blind that destroys the cards left in hand when you play a hand
the played cards are in an entirely different area
that but in context.press_play, which is where you should probably do this, they are in G.hand.highlighted
alr
so
if i pass an additional check that determines if the card is part of the hand then that should work?
depends on what the check looks like lol
okay
so
my idea is to check the card against the highlighted hand
if the card is found in the highlighted hand, it shouldn't get cut
i return with another puzzle
card.ability.extra.repetitions is set to 2, yet by the end of a single round that function is called as if it is equal to 0, when it should actually be set to 1
why is this?
add a context.main_eval check to the end of round check
how would i add a special variable to a copied card so that i can keep track of it for something else?
yeah
-# omg maxx hiiiii
would .highlighted check for this?
isnt that what appending does
the negatives im copying are supposed to be temporary, so my thought process is to create them with a specific variable, then when the timers up i check for the variable and delete all cards with that variable
haiiii where do i know you from? im a little slow :b
ijiraq
why dont you just make them perishable
you can set perishable rounds to any value
oh what
hm. can i make something perishable without having the perishable sticker? i kinda dont like the visual itd have
i dont think you could
beh
you could make like an invisible sticker with a similar effect
the answer is yes.
also stickers can have configs now so that makes it even easier
that could work but seems like over-making a solution. couldnt i just like give the card a variable and then do a check in a context and destroy the cards with the variable
you could definitely do that
i literally do that (granted it's not for destruction but i have to do it in cases)
yea
though you should check for that in a global mod calculate so it still works if the associated card doesnt exist
SMODS.current_mod.calculate = function(self, context)
and then its just the same as any other calculate
card.ability.custom_variable
gotcha
Pretty sure the copied_card should be replaced with corresponding cardn
With the set_edition
ik i was just in the process of doing it when i took the screenshot
Just making sure
off topic: I've started "modding" a couple of days ago by tweaking the game.lua file. assuming I make a mod I want to share, what's SOP for modding? I'm guessing directly modifying game.lua isn't the way
cool thanks!
how do you destroy a card?
theres quite a few ways:
returning remove = true in context.discard/destroy_cards (playing card only)
SMODS.destroy_cards (generally cant go wrong with this one)
Card:start_dissolve (generic dissolve anim)
and theres Card:remove ig but that is just no animations it just vanishes
how does one change handsize 🗿
I feel like I've asked this before, but I forgot and can't access my other jokers at the moment...
What was the context for the end of a round?
was it just context.end_of_round
G.hand:change_size(amount)
yeah
am i just stupid or like
kk, thanks
should be ==
yeah i am lol
thx
the bottom part works to add a copy of a card to the hand before scoring
does anyone know how to make it add it to the last position instead of the front of the area?
Uhhh how can I double sprite resolution within the same dimensions?
uuh do I need to put it in something? does it not work on its own
can i see the entire code
Oh right this is what display_size is for methonks
I just put G.hand:change_size(-2) in the joker
where in the joker
just in it
yeah but
?
just show the code vro
this doesnt really help
like yeah i get that its in the joker
none of the surronding code is related to it though
just
Wdym 😭
why cant you just screenshot the whole joker man
this is like absolute peak of shitty screenshots in modding-dev
hall of indexing nil values
okay actually the one thing i can make out from this is the comma after tha function
which like idk what that implies but i dont think its good
also why didnt you like
look at vanillaremade stuntman or smth before any of this
idk what that is
Oh so I do have to put it in something got it
Also I don't get why that matters when none of it was related
well i could BARELY tell
I literally just put that line in the joker by itself 
only the comma let me see the issue

because that tells me you just... put it as a parameter in the joker
You should add it to add_to_deck
Placing it randomly in the code does nothing and will ultimately crash your game because it’s not a know parameter
shouldnt it be remove_from_deck since I want to lower hand size?
Sorry I didnt realize it was something that needed a thing i thought it was just a line that lowered hand size by itself
Yes to cancel the effect
No
You want it to be add_to_deck
To lower handsize
And add handsize back in remove
Just like how stuntman works
Also now that I know this exists I should be able to figure out a lot of things by myself from now on so thats cool 😄
The best kind of feeling Is when you figure something out without asking in modding dev 🔥
i just asked something and then figured it out immediately does it count
wrong chat
My body is a machine that turns sprite art into shader effect (I already did this joke sorry)
Winter i need this
my body, or.......?
Which one
Ye
Can't really give it to you, not because I can't show the code to you, but because it's fairly specific so I doubt it would be an easily portable solution to use elsewhere
These are the textures used for it
Oh i see
you can import textures into shaders?
What about the love.graphics implementation?
Are you hooking this to the hover ?
2
worst thing about ui code in balatro is maintenance
Basically, I have this whole DrawStep that handles the auras, which are "queued" to play for a certain amount of time. In the collection, there's a centralized hover value that queues an aura on an item that's given 0 duration, which means it doesn't cancel itself until it's manually removed
---------------------------
--------------------------- For stand auras in the collection
---------------------------
local ref_card_hover = Card.hover
function Card:hover(...)
if ArrowAPI.col_stand_hover and ArrowAPI.col_stand_hover ~= self then
ArrowAPI.col_stand_hover.ability.aura_flare_queued = nil
ArrowAPI.col_stand_hover.ability.stand_activated = nil
ArrowAPI.col_stand_hover = nil
end
if self.ability.aura_hover or (self.area and (self.area.config.collection or self.area == G.pack_cards) and self.ability.set == 'Stand') then
ArrowAPI.col_stand_hover = self
self.ability.aura_flare_queued = true
end
local ret = ref_card_hover(self, ...)
if self.facing == 'back' and self.area and self.area == G.deck and (not self.states.drag.is or G.CONTROLLER.HID.touch)
and not self.no_ui and not G.debug_tooltip_toggle and G.GAME.selected_back.effect.center.artist then
self.config.h_popup = G.UIDEF.deck_artist_popup(G.GAME.selected_back.effect.center)
self.config.h_popup_config = {align = 'cl', offset = {x=-0.1, y=0}, parent = self}
Node.hover(self)
end
return ret
end
local ref_card_stop_hover = Card.stop_hover
function Card:stop_hover()
if self.ability.aura_hover or (self.area and (self.area.config.collection or self.area == G.pack_cards) and self.ability.set == 'Stand') then
self.ability.aura_flare_queued = nil
self.ability.stand_activated = nil
end
return ref_card_stop_hover(self)
end
function love.focus(f)
if not f then return end
if ArrowAPI.col_stand_hover then
ArrowAPI.col_stand_hover.ability.aura_flare_queued = nil
ArrowAPI.col_stand_hover.ability.stand_activated = nil
ArrowAPI.col_stand_hover = nil
end
end
Sorry for big code block
Like yeah the code's all here, it's not a trade secret or anything, I would just struggle in your position to modify it........ especially since I didn't comment it much
Dw about it
winter is a shader wizard
this looks like 2am code
this is SCARY
I love doing minigames in a game like it’s a game engine
i have 3 atm 👀
no ideas are ever original.........
I think this is the implementation I built mine off, it's based on a really old technique that can be done in older graphics hardware. Basically, it goes like this:
- using the texture coords, look up the r value on the noise texture (amount of black, essentially)
- you "scroll" the noise texture vertically by adding a time value to tex_coords.y
- aftewrwards, determine an alpha values for the edges of the flame effect by subtracting the alpha of neighboring pixels
- "step" along the gradient's r values using the random noise value. This is what creates your flame effect
- you can step multiple times to give multiple distinct sections of flame color (like yellow -> orange -> red), though I only use two colors for mine
There was some other resource I used for the "spread" thing that kind of pulls it into a ball but I can't find it
when was this recorded
few days ago
yay i was first
recorded and implemented are 2 different things
ive also got battleship
yo this is dope
hi dilly!
This one: https://godotshaders.com/shader/2d-fire/
How does create_card() work? Is the second to last argument expecting a key? or a name? Or does it like, ignore that if you give it a set
I've used a lot of Godot shader references
did you program the ai or borrow it from somewhere
i did the ai
i was initially going to try and use this fuckin lua battleship thing i found but i couldnt really figure out their shit so i did my own
nice
it also places its own ships depending on strategy it chooses and hunts for ships based on size
so itll only make shots if for instance the cruiser can be there (meaning 4 squares)
and then goes down depending on whats left
I am guessing it takes it's shots somewhat randomly until it finds a ship rahter than on a sequential pattern?
how can I check if a hand has any unscoring cards?
#context.full_hand > #context.scoring_hand
yea, itll shoot in random spots that fulfill the 4 square guideline until it gets a hit, once it gets a hit on any ship that becomes a point of interest which it focuses on until a ship is sunk, then it resumes its search
as the grid is filled it aims for areas that can only fit the ships its looking for
can i do something similar in Blind:debuff_hand?
that's cool
you can use calculate functions for blinds now, I don't remember what gets passed to the actual debuff hand function off the top of my head
gotcha :D thanks
I feel dumb
how do you get the key of context.consumeable in context.using_consumeable?
like, context.consumeable.key is nil and also context.consumeable.ability.key is also nil?
how does yours work opponent wise
context.consumeable.config.center_key
you mean the apple?
tf
idk what opponent would be in snake
yeah lol that was snake
oh wait that was snake you were showing huh, i thought it was your own battleship
do you like it
i mean it kinda looked like battleships (with the boxes)
yea thats what i thought you had lmfao
but nah your snake prob looks better than mine admittedly
i think my battleship looks great though
I mean, i'd suck at it, but it's interesting, to say the least.
(and very cool)
I think you could dress it up a little
You could have the balatro crt effects over it, and the bloom
dont worry im ass at it myself
i didnt want any of the filters and stuff because i felt it messed with readability
I can feel that raw love.graphics
make it kinda look like a text-mode game for cp/m computers of the '80s
thats why i settled for a black background witht he grid over it
I mean, thats why balatro has those settings, lol
im working on a menu where you can choose a joker but i dont know how to make the jokers clickeble and how would i put it in my joker slots?
function joker_menu()
return {
n = G.UIT.ROOT,
config = {r = 0.1, minw = 8, minh = 6, align = "tm", padding = 0.2, colour = G.C.BLACK},
nodes = {
{n = G.UIT.C, config = {minw=4, minh=1, colour = G.C.MONEY, padding = 0.15}, nodes = {
{n = G.UIT.R, config = {minw=4, minh=4, colour = G.C.MONEY, padding = 0.15}, nodes = {
{n = G.UIT.T, config={text = "Choose a joker", colour = G.C.UI.TEXT_LIGHT, scale = 0.7}},
}},
{n = G.UIT.R, config = {minw=4, minh=4, colour = G.C.MONEY, padding = 0.15}, nodes = {
-- card
{n = G.UIT.O, config = {object = create_card("Joker", G.jokers, nil, 1, nil, nil)}},
-- card
{n = G.UIT.O, config = {object = create_card("Joker", G.jokers, nil, 1, nil, nil)}},
-- card
{n = G.UIT.O, config = {object = create_card("Joker", G.jokers, nil, 1, nil, nil)}},
}},
{n = G.UIT.R, config={button="my_button_click", padding=0.05}, nodes={
{n = G.UIT.T, config={text="Click Me!", colour=G.C.UI.TEXT_LIGHT, scale=0.5}},
}},
}},
}
}
end
You probably want to hook Card.click
I think that's the function name.
or something similar
And give a special property to the cards you create in that menu.
so my Boss is mostly working, but when selecting a hand, it always says it won't score, even if it does
code
i assume i need to determine if the hand will contain an unscoring card before playing it, but how?
hands containing unscoring cards don't score :3
mmm
i know there's a boss in Ortalab that does the same thing, but i didn't intend for that :3 tis parallel thinking
Maybe the issue is it checking even before you play the hand, idk
Maybe more context conditionals can do the trick..?
I don't really know.
wouldnt you use debuff_hand rather than calculate ?
like, the function
i feel like that'd fix the whole visual side of things, personally i woulda only went for calculate when debuffing a hand using a joker or the like
calculate is fine it just won't have the scoring hand stuff available iirc
just look at the ortalab one and rip the condition out
the condition wasnt the issue
thats why im saying it might be better to use debuff_hand
the condition is absolutely the issue
no it isn't, the debuff functions, it's the visual side of it that theyre trying to fix
the calculate does the same thing
am i missing something here? like ive reread their message several times
unless theres a misunderstanding there
the condition is wrong
the condition is practically the exact same as the ortalab one though
they do the same thing
checks scoring cards count vs total cards count
Does somebody know how can i add a "Take" Button below the use?
idk but u could probably look at the cryptid "pull" button in code packs
I tried, i havent found anything yet
ill help look then
its a parameter attached to booster packs normally
if you want use and take you'll have to patch in your own button
select_card = "consumeables" would pull them consumables i think
Well, let me see, thanks
while not perfect, does this look better to you?
Hey read the pinned message
Very cool though btw
the issue isn't when the hand is played, it's before it's played
i am doing neither of these things
is that not what ive been saying😭
Oh I thought you were cuz it said "play battleship against (prohibited word)"
context.scoring_hand is nil before the hand is played iirc
well you dont use a context with debuff_hand function anyways
nor does the ortalab solution
but @exotic hedge can i get some clarification if this context is okay?
the context is the battleship gamemode i have implemented for a blind has its own 'ai' which plays against you
it does not train through balatro mods or balatro itself, it just is a form of intelligence that is facing you
i'd do what ortalab does, with the debuff_hand function and all, but i don't trust it, with the always-scoring check and all that
i'd rather directly check the hand itself
which i suppose it does too but whatev
sub cards for G.play.cards ?
wouldnt be surprised if the rule applied specifically to gen ai or ai that uses models to train in general, where a basic battleship ai with heuristics doesnt really apply
i can't find where the G.FUNCS function is defined
That's not (prohibited word) unless It's something like the (prohibited word) chess thingy that beat world-class players which learned by playing game I think
- that's a table
- probably vanilla
thats what i took it as, but im asking to just know for sure instead of us guessing
True I think they should edit the message for it to be more specific and no mistakes to be made
You aren't going to get obliterated if you say the word, I believe.
blidns are just calculate = function(self, context) iirc
oh :D! will try
Issues arise only when the context starts going into that direction.
dilly you are fine dont worry
it's in state_events.lua (and i would hope that smods overrides it to account for modded hands)
ah okie
I can't risk it cuz the message says to not talk about it so I think It's better to not do that
i didn't look in that file
referencing this with my message btw
i definitely thought so but i figured better safe than sorry
whatever, up to you
smh you didnt tell me if that looked better to you mr jogla
i can fix dw
wait maybe I am wrong
(self, blind, context) probably correct then if this only happened after the fact
I am sleepy T_T
Oh, I thought I did
It looks nicer.
A lot nicer.
awesome
That blind is hell
right
Idk how to play battleship
my friend has been beating my ass in battleship online recently, theres this site you can play it on
so it inspired my to make this
and shocker, i lose alot here too lmao
You would probably beat me lol
make a upvalue for Card.click function
local l_click = Card.click
function Card:click()
local ret = l_click(self)
if _G.mod_prefix_choosing_joker and self.config.center.set == "Joker" then
local t_card = copy_card(self)
t_card:add_to_deck()
G.jokers:emplace(t_card)
end
return ret
end
the blind works, except before the hand is played
it evaluates every hand as not-going-to-score
even though they sometimes do score
id say it wouldnt hurt to try this in your blind, substitute calculate for this and see if it works as intended
debuff_hand = function(self, cards, hand, handname, check)
local _, _, _, scoring_hand, _ = G.FUNCS.get_poker_hand_info(cards)
local always_scores_count = 0;
for _, card in pairs(cards) do
if card.config.center.always_scores then always_scores_count = always_scores_count + 1 end
end
if #scoring_hand + always_scores_count ~= #cards then return true end
end
yea
Balancing question, for common joker that gains chips after you beat a boss blind, how many chips would make it a useful joker without straying into uncommon joker levels of strong?
I was thinking +50 chips per boss beaten
tbh i think that my main criticism is that it's too small. Like, 14x14? I feel like 10x10 is much more common a board size, and making the board smaller means you can increase the scale of the board. This would improve the readability a lot, and so you might be able to add better "graphics" (I still think a "text mode" esque graphical simulation would look great, and would go great with balatro's sort of "video poker" styling well)
hmmm
there is an issue here in that the scoring hand isn't being passed through
I'll try to come up with something
im not quite sure yet what's going on with straights
is there a way to get the full scoring hand (accounting for splash) without a context?
you meant It's too big?(Cuz It's bigger than 10x10)
dunno, it looks just fine to me
and I also have some API design complaints
but it's quite the thing
well its 15x15, 0 counts
10 x 10 would be smaller than the current 15x15 which wouldnt solve that
meaning I haven't taken the time to try to understand what exactly they did with straights
No I mean like
the scale of the board is too small. It's too complex and zoomed out
can we say quantum anything is cursed and delete quantum enhancements too? 🤞
window wise it doesnt feel small either imo
yeah thank you i was almost there just didnt know about copy_card lmao
one cell here fits like 10 or so of your cursors
np
oh I see the issue 😭
modern smods is too bloated, revert to 0.7.2
I mean, you have to look at it not in fullscreen. Oh, and consider the GUI scale of the rest of balatro. there's good reason why it's so large
Yes please
the hell even
i have no idea what any of this means
i love breaking changes
well this isnt suppose to be like the rest of balatro, battleship is not IN balatro
its suppose to be battleship, just accessible here
im not sure though, cause i play in windowed mode where it looks like this which looks even better than full screen
assuming that's at like, the standard size of windowed balatro
do you have like, a 1440p monitor? Scale seems way off
your calc function will be fixed in the next smods release 👍
Dude, that's crazy :O
i do yea, but my testers play on laptops and on a normal 1080 and ive asked them what youve said and they said they dont understand where you are coming from either
so im unsure, cause theyve liked how its scaled thus far
thank you :D
Why are y'all implementing Games in Balatro, a Game xD
because they're fun
and i wanted to do something unique-ish
Looks good
I mean, I think a lot of people who are willing to test unfinished things are also people to use gui scale 1 in minecraft
its just too small for a lot of people
I should really play your mod some time
games inside games have become boring, we need games inside games inside games
Can someone do balatro in balatro
dont worry once it releases youll know lmfao
Also, you tend to sit way closer to a laptop than to a computer monitor, so it's kinda not ideal
Thats boring we need operating systems inside balatro
me when os lib
but thats why im saying how for me and one of my other testers they say its fine, if people arent struggling to read the text or click the boxes it feels like there is a non issue at play
one person of 4 on a laptop where 3 others are desktop see it as scaled fine doesnt math up to being poor scaling i feel
it being an unfinished mod doesnt apply to testers being okay with it when i ask 'does the scaling feel fine for a release' and the answer being yes
Quick question since I've seen it multiple times by now: What is next(Something) for and what does it do?
it gives you the next key value pair in a table, usually used to see if the table has something
Well you said that the CRT effect and bloom makes it harder to read, which is why it's a good idea to make it way more readable than it reasonably has to be. To make it accessible to those who need to have the CRT effect off in normal balatro. Most people could have it on, and it be fine. But if having it on for your situation makes it unreadable, then you should consider improving it.
So I would use that to see if a joker is in the joker area?
i didnt say it did, i just said i felt putting effects over text does by default impact readability
so leaving something by default without it wont end anyones run or ruin their moods
its more about checking if a table is empty, at least for a lot of usecases
all settings effects apply for the normal balatro, this is just a black box OVER the normal blind thing
So I would use it without next instead?
I'm assuming you're talking about next(SMODS.find_card("jokerkey")), that's because SMODS.find_card("jokerkey") gives you a table of jokers
Yes. So which one would I use to detect a joker?
the first one
So then what does it look like with the CRT effects on?
I would recommend brushing up on some lua tho
it would look exactly the same as with it off
dilly said it's drawn over the top of everything else
yes
im not overlayting the crt effect onto the grid because i think that would impact readability to some margin
and having it this way does not impact anyones runs, moods, or otherwise
drawing everything on top just makes the most sense
Well that's what I'm saying! You said that it would affect readability, so you just completely disabled it. But then also, normal balatro is perfectly fine with the CRT but you can turn it off to make it more accessible!
Which means there is a problem
but its not disabled techncially, the effect exists underneath the drawing of the black box
its just not rendered onto the grid
thats
thats not
please read the words i am saying
Drawing something on top instead of beneath effects is disabling it
Yeah, should probably do that
There's no difference between "ignoring an effect" and "disabling it"
How do I get the chips from one of my jokers?
okay ive got a mega cursed joker idea where do i begin with this one
want a joker that on being sold, will “insert” another ante between this ante and the next one
say you sell it on ante 6
it’d make it so after beating the ante, you then go to ante -1 instead of 7, and then after beating ante -1 you actually go to ante 7
how the hell do i store the “next ante” for this?
the joker would already be gone as its been sold
you can store in a global and use the new mod object calculate for this
and maybe the new ante contexts
the global would be like G.GAME.modprefix_extra_antes = 1 or something
interesting
definitely gonna look into the new ante contexts
they're a bit dodgy if mods are hooking ease ante for now
bump
No, how many it currently is holding. I want a different joker be able to use that for something
if you know that it's going to be that specific joker, you can literally just do [whatever card it is].ability.extra.[whatever the name of the chips parameter is]
Couldn't you just do
joker.ability.extra.val
You have to get the joker tho
For example using SMODS.find_card
What does that do? I never used that before
you can access the variables in the ability table from anywhere, just like you do from within the joker itself
card.ability.extra but on other jokers?
Oh, okay
this isn't java, there's no private/public to deal with. everything is public
I don't know any java, I'm used to C# xD
same deal i think (i've never touched C#, java is just the language i go to when i want to make fun of programming)
iirc C# is just microsoft flavored java
Hi MaxBoi o/
hello easternmorning :clueless:
:clueless:
Yeah... Heard that before

Nitro perms
hi dilly
Smh
hi N
nitro user detected
im making my new mod
peasants the lot of u
is it called deckdisplay
no 💔
people out here have released multiple mods and i havent released one yet
hate to see it
i just add jokers
N slop....
one has a musical number
anyhow anybody here familiar with how smods edits card:open? and its related things
im currently making a dumb silly function to open anything like its a booster pack
everything is working fine
except the shop doesnt rise back up after skipping/using a card 💀
you should get that checked
surely its alright
these ones have short descriptions
i need to multibox at some point
multibox is nice
-# @daring fern when you get a chance, can you help me out with your safe_set_ability? the one you set me up with cant reach things like burglar's hand extra or chaos' reroll thing. basically theres stuff i still gotta reimplement myself and i wanna make sure thats intentional and not something being missed by the code?
multiline name is cool too :3
i gotta get around to doing that
you shoudl get around to eating some soup
like what the fuck 😭
i have 14 bags of chips if you want one
family size
please
isnt this just loyalty card popcorn 😭
interesting combination i will say but like 🤯
yes :3
its cool tho
it also switches sprites when the mult is 0
insane deal
he punching
i had never seen it before, asked a friend near me and she said they always do that sorta stuff on holidays
so i need to use it much more often
function Card:pseudo_open()
self.config.center = SMODS.Centers['p_arcana_normal_1']
draw_card(self.area, G.play, 1, 'up', true, self, nil, true)
self.config.pseudo_open = true
self.ability.extra = 4
self.config.center.config = {
choose = 1
}
self:open()
G.CONTROLLER.locks.use = false
G.TAROT_INTERRUPT = nil
end
like what am i missing 😭
(this will severaly be revamped right now i just need it to work)
Is there something in the wiki for joker.ability.extra.val?
no thats custom for each card
diabolical
Do you have an example on how to use it?
can someone tell me what the default G.shop.alignment.offset.y is :clueless: (as in visible on screen)
im gonna do more jank
you know how your jokers have a config? and you do card.ability to access it? well all jokers hve that nd their values hve different names
i wish my keyboard worked
maybe i need to clen it
clen
clean
nvm got it
i have an idea :clueless:
And how would I grab a specific value like, lets say from my variable 'chips'?
If your joker has config = { extra = { chips = 10 } } then it would be in card.ability.extra.chips
That much I know, I just don't know how to use joker.ability.extra.val to get that. Do I type joker.ability.extra.val(card.ability.extra.chips) for it?
ok, joker.ability.extra.val is not a thing per se
you replace val for the key you want
and joker for the variable that stores the joker
in this case joker is card and val is chips
I love when people take a random example as something super specific and needed to be copied word for word
Maybe I should stop giving random examples
Sorry, I said I never used it before TwT
or just preface with
THIS IS AN EXAMPLE AND NOT SPECIFIC
:clueless:
Clueless overuse !
But then I don't get it from the different joker, do I? Since that results in card.ability.extra.chips and would just try to get it out of it's own config or am I dumb?
you cant make me not use :clueless:
Well, yes but in the case you want it from a different joker you would need to use whatever variable you used to get that other joker
whatever you named it, it could be joker or x or my_cool_value
Oh, okay. I think I get it now
dude i am literally killking myself over making a sticker
it feels like it's supposed to be so simple
Been there

oh dont worry stickers are slightly evil
but then checking if something is a joker with card.ability.set == "Joker" works perfectly fine
i'm going crazy
Why does this just crash my game without an error?
local _, shnack = next(SMODS.find_card("j_cstorm_shnack"))
print(shnack.ability.extra.chips)
SMODS.destroy_cards(shnack)
card.ability.extra.activated = true
end```
infinite loop probably
You could look at the log
i believe next(...) only returns 1 value?
unless im crazy
Mods/lovely/logs
how do I make an ehancement apply ^mult after exporting it without ^mult in jokerforge
i should return two im pretty sure
cause I want ^mult but I'm making my mod in jokerforge
Pretty sure you return emult
You need to have talisman tho
I should update this to add cryptlib
okay so like
I export the files with no ^mult
then I edit n the ^mult
right?
Should work like that
how do I prevent jf from overwriting my modified file
Doesn't say anything about that
Anything at all?
i have located the source of the problem
If I remove the _, it says that ability is undefined
Not there
huh
Calculate
so replace all mention of xmult here with emult?
new problem:
im fucking :clueless:
The last things are literally
INFO - [G] 2025-09-04 00:57:44 :: INFO :: TIMER :: [0021] Injected Draw Step in 0.265 ms
INFO - [G] 2025-09-04 00:57:44 :: INFO :: TIMER :: [0000] Injected [INTERNAL] in 1.613 ms
INFO - [G] [DebugPlus] Press [-] to toggle console and press [shift] + [-] to toggle new log previews
chat
"I fucking beg"
Just x_mult = with emult
alr
i name my debug prints however the hell i want
like this?
well yes, but now you should also go back to the initial spot you were at and replace x_mult to emult too
card.ability.extra.[something] refers to the variables you set in the config table
wait
thx for pointing dat out :33
card.ability.extra.[something]refers to the variables you set in the config table
🤦♂️
so this is better?
my genior strikes again
yes :) intelligence is not the same as those AI chatbots 😡 thank you for asking though
sorry for the late response
as long as your battleship ai is not powered by a LLM it is aok
????????
Hello. Is there a way to tell SMODS to open this UI through whatever button/function?
or stable diffusion, somehow
update smods
Or any tab from a given mod.
Why does this not work but if I add a context it does work:
if next(SMODS.find_card("j_cstorm_shnack")) and card.ability.extra.activated == false then
local _, shnack = next(SMODS.find_card("j_cstorm_shnack"))
print(shnack.ability.extra.chips)
SMODS.destroy_cards(shnack)
card.ability.extra.activated = true
end
end```
Why TwT
it says theres no update available tho
mod manager is kinda bad at this
Get it from the github repository.
bump, mayb?
alr!!
depends on the page, i have this to open my collection
:DDDDD
bump
Do you happen to know which function is the one in charge of creating the settings menu?
Or where it is defined?
does anyone know the keys for seltzer and showman? they're not j_showman/j_seltzer apparently
Nickpick and shit, but usually exponentia mult is purple and fuck I know exponentia chips. Also separate the text and the number.
praise
thats a page?
they putting in crazy work over at jokerforge
all of them????
I tried separating them
god bless
For some reason when seltzer self-destroys itself, it's "getting sliced"
Found anythin', N'?
im on it
bump2
G.SETTINGS.paused = true
_, G.ACTIVE_MOD_UI = next(SMODS.find_mod("modid"))
SMODS.LAST_SELECTED_MOD_TAB = "config"
G.FUNCS.overlay_menu({
definition = create_UIBox_mods(e)
})
oh!
is there a way to set a challenge to gold stake?
oh you can remoe that
my jank... worked?
thats not supposed to happen
i can now pretend that anything is a booster pack 🔥
yum
Wait did that redrew the same cards or different?
bump3
Would it return the cards to deck from the discard pile?
different
they are in my discard pile i believe
actually wait imm stuipid
one moment
ignore what i said for now
they are not in my discard pile no
im trying to make a joker that gives 2x multi on every card but decreases game speed by 0.05, but it crashes whenever it activates, can anyone help
this is the first time ive seen someone actually use freeform screenshot (if its windows)
freeform on top
Interesting shape for a screenshot I must say
well do you have any ideas on what im doing wrong
anyone got any ideas on how to only remove jokers from the shop but still allow them to be made by judgement/riff-raff/ etc. ? this would be for a challenge
no because the error talks about juice up for some reason
but lemme check whats at that smods line
found it myself sorry for the basic ah question
wait let me see if its something else other than the game speed changing
it probably is because its trying to juice up a card but the card its told to juice is nil?
bump4
Probably an infinite loop somewhere
If you remove the context and add a print statement I wouldn't be surprised if the log was spammed
Gonna test that
It is spammed by the print... But why is it an infinite loop?
Doesnt end of round trigger multiple times without main_eval
But there is a check so idk
Im probably wrong/
They said it closes without an error if they ommit the context.end_of_round
So that suggests infinite loop
Of some sorts
i think i made my delay too long :clueless:
Maybe a little
But why is it infinite? I mean, I'm checking if card.ability.extra.activated == false and set it to true in that if statement, as you can see
local _, shnack = next(SMODS.find_card("j_cstorm_shnack"))
print("Spam?")
card.ability.extra.mult = shnack.ability.extra.chips * card.ability.extra.multiplier
SMODS.destroy_cards(shnack)
card.ability.extra.activated = true
end```
Need to? no. preferred? Probably (idk never used it)
Maybe find_card calls a context which calls this function again?
ok after rerunnning it at 0.5 i can confirm that delay incorporates gamespeed
Did they hook delay 🥺
idk i just mod here
Same 💖
I'm trying to put a bunch of joker atlases to a separate file from my main file, then use require, but lovely can't find the file?
how do i put this color inside the description of a joker
ive tried different things but cant get it to work
are you using smods?
yes
"Uncolored text {C:inactive}Grey text {}Uncolored text"
Why the fuck does it run through this 17 times when I use context.end_of round before stopping?!
yeah my modded joker that checks if a joker is destroying itself (a.k.a not getting sliced)
how do i make a joker not appear in the shop at all
i would send an issue to smods
ty
how can i read/display what the "value" is that Oil Lamp is modifying?
how do i make it so that you can only hold one of a certain joker at a time, even with showman
or like how do i add custom flags
obscure error from left field: 💥
oh wait no i forgot to pass on loc vars :clueless:
i think thats the problem?
no i need this thing to have a name 🤯
ok wow another stupid obscure bug
Can I show you the effects of my jokers and you tell me if it's balanced?
post it
What does rate do? (SMODS.Rarity)
["Joker"] = true,
["Joker"] = { rate = 0.7 },
},```
its rate in the pool
anybody know what in the game would cause everything to work fine except block you from playing hands and selling jokers?
like a jokers rarity but for the custom rarity in a specific pool
The higher the number the higher the probability to show up?
yea
the only thing stopping my silly pseudo open from being peam rn (alongside minor cosmetic bug)
im trying to make my deck make negatives not cost more money
but its crashing
crash log
i tried a few things for this
here's the code
local card_set_cost_ref = Card:set_cost()
SMODS.Card:take_ownership('card', {
set_cost = function()
card_set_cost_ref()
if self.edition then
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
self.extra_cost = self.extra_cost - cost_sub
self.cost = self.cost - cost_sub
end
end
})
i may be doing this horribly wrong
SMODS.Card:take_ownership('card' is not a thing
i thought so
the last thing didnt work either though
so i thought it was worth a shot
local card_set_cost_ref = Card:set_cost()
function Card:set_cost()
card_set_cost_ref()
if self.edition then
local cost_sub = self.edition.negative and G.GAME.modifiers.rad_extra_cost_negative or 0
self.extra_cost = self.extra_cost - cost_sub
self.cost = self.cost - cost_sub
end
end
here was the other thing
gimme a sec
and not passing the self parameter to it
oh shit yeah you right
that should work, how are you testing it
sorry im terrible at lua
it crashes on boot
Everyone makes mistakes
do i need to?
you get better with time though
of course
recommended
bc even if it returns nil
but thats rust so
maybe theres a mod that hooks it to return something else
and needs that specific stuff
I started with roblox studio
I was not very good
- arrogant
and too confident

