#đ»ă»modding-dev
1 messages · Page 49 of 1
YEEEEEEES
this was a good idea
wait what if i remove isaac.states.drag.can = false
aw you can't drag him
no way the balatro cursor is trans
real
how would one go about adding a new object type like editions, enhancements, and seals? (that's not a consumable)
SMODS.Edition, SMODS.Enhancement, SMODS.Seal
all three of them are present in Cryptid if you want to steal from it
isnt it about a new type of those though
i'll try that
wait let me pull specialist music
Look at contracts mod code
testing for mod compat be like
What is that?
Wrong channel whoops
If the UI is rendering every frame that solves one problem. Next one, for the joker area do you know by chance what is used to display max joker, i thought it was G.jokers.config.card_limit but modifying that doesnât seem to change the max value
Security checks in Ankh (WIP)
Basically if you have mods installed you can use it to see if they were tampered with for a replay
I think we might want to change how stickers are drawn on a card, thereâs a very limited number of positions and I think having them be positioned according to the code might be better
there's no need to display all the information on the left side, the blank space on the right side of the Joker should be utilized
It's not difficult to add new content with SMODS.Sticker now. Considering there may be an increasing number of stickers in the future, it might be a good idea to have a centralized information button floating on the edge of the card
I mean the actual images
Tooltips are fine, we can just make them display in a grid instead of a column eventually
OK
I agree this would be good, but it would require a change in sprite size for stickers
the current sticker sprites are card-sized
Yeah make them more like tag sized would be best I think. I was imagining the column down the left of the card with 4 slots and then when you have more than four they continue to be placed at the bottom but adjust to still fit on the card but overlapping
there could eventually be more then one column if we don't want them to become as indistinguishable
Yeah that sounds good
Also tag sized is probably too large, 3 tags don't fit a card's height without overlap
Whatever size standard stickers are then
How to solve the problem of having too many badges?
Itâll be 22x22 ish?
I think possibly a column solution after a certain number could be useful here too, along with a scaling down of them if in column mode
I tried a solution with scrolling before, but I wasn't able to get it to be dynamic
columns should be better
...this is hilarious
Personally I like the idea of oversized, overlapping stickers with random positions
Yes, yes I am⊠;u;
Not even issaac? đ
There's 2 as?!?
it's isaac...
Isaac and his Issac lived alone in a small Issaac on a Isac
Damn, I'm too dyslexic
wtf is happening, I have shuffling code whenever I try to inject???????
that "end" gets teleported from the other place for some reason
lovely possessed by amber acorn
??????????????????? (made the injection into one line without spaces)
something something before patches
yeah but removing only this patch completely unshuffles it
as in image â3 here
fast
I wonder if the smods patch is conflicting with it and causing some shenanigans
is there a nice way to hook into Game:start_run
Everyone say "Thanks Myst"
what do you want to do
grab then deck to detemine and setup some flags I use with the deck đ
Unless there may be a better way you reckon?
ooh hang on didnt know that existed
and how did you override that? when i try
local init_game_object_ref = Game:init_game_object
it complains or do I override differently (new to Lua sadly)
do Game.init_game_object
then pass self as the first argument
Sometimes I try to hook and I fail because I do local obj_ref = Class:obj instead
or whatever
right so we can use the Class.method but when we use the Class:method override it needs self to be passed into the ref before original args
I want to make this a shader but for now this will do. I talked about ideas with @wintry solar but I haven't done anything shader-related yet
I think Class:method calls the method with Class as the first argument, while Class.method is the reference to the method
makes sense, this is why they recommend looking into the language before modding huh xD
I didn't look into it
đź
I just looked directly at other mods lol
ah see thats where I went wrong.. apparently I like pain and hitting myself with bricks >_>
it's still a good idea to know lua first
how do i make mods for the game?
Mind Useful resources at the bottom of the page, too
If you wanna help out...
ORTALAB JOKER POLL - ROUND 1
#1217704157574860810
WIP example jokers, as well. Mostly done, but there are still a few more complex explanations missing.
Idk but you can look up what Negative Jokers do
yeah it was this, was confused because it didnt update when i changed so relaunched the game and it worked and was mega confusioned
what function did you throw it in?
it was in ease_dollars so i made a func to recalc and assign accordingly
What mod loader is used?
steamodded
that or you can do it the dirty way and extract the game files and do the jiggery pokery >_>
no don't do that
i never said it was a good idea.. just that it is in an idea.. totally not what I did for v.0.1 of my mod
Still struggling with the first part
how do you give the player the ability to choose something?
Round start, Display all legendary jokers in the center of screen and prompt player to choose one?
the way cryptid implemented something like this was having you type it in
but that also made more sense with the theme of the consumable, showing the legendaries in a collection view and clicking would be better probably
ok maybe this will work:
- Start of blind
- Trickster starts juicing up
- Pop Up appears where all legendary jokers are shown
- When you click on one, the Pop Up disappears
- Trickster takes that form and stops juicing up
I have an idea about some type of effect that prevents face cards from showing up
is there a good way to check whether a card is an actual face card?
card.base.value == 'Jack' or card.base.value == 'Queen' or card.base.value == 'King' isn't very mod-compatible
and card:is_face will always get ruined by Pareidolia and other mod "all facecards" jokers
card.rank > 10 and card.rank < 14?
that's... not bad actually
we're still assuming all mods put their face card ranks in that range
ok then card.rank > 10 and not card.rank == 14
so aces are ignored and every card higher than 10 is good
then it depends on what you want to do with the cards
just check how is_face does it while paredolia isn't owned
if id == 11 or id == 12 or id == 13 or next(find_joker("Pareidolia")) then
return true
end
similar issue as before no?
we're still assuming all mods put their non-face cards outside the 10-14 range
if you are trying to think of all the possible mods, then you won't make yours
hah ain't that the truth
just do it the most natural way and you're good
that really doesn't consider any other mods implementing custom is_face đ
this without the Pareidolia
probably best yeah
something something "best effort" guarantees
thanks :)
am I doing it right?
the idea is this
just use an object node and add a cardarea?
i don't see why you need five object nodes
because I need 5 buttons and with this solution all the buttons are aligned with the cards
You could just have a card area where you can select any one of the shown cards
i don't think you can put a cardarea inside a button
you could have a cardarea with a max select of 1, and a submit button below it?
and the submit button just finds the selected card
Everything has a colour!
Incorrect depth most likely.
what about the concept of time.
UIBox_button is inside a table when it shouldnât be probably.
i don't use UIBox_button actually lol
i looked at other people and they did this
I never used it before
so you put button in the config of a node?
where did you take this
"Columns are for nodes arranged vertically"
lobcorp's discover all button
Is there any documentation on how to make a joker from scratch?
a lot actually
btw can standalone .lua files be in the mods folder or do they all need to be in 1 folder?
if the mod is only one .lua file it can be in the 'Mods' folder
Ah got it
ok scrap this sheet
gonna be Hover + left/right arrows
they can be but it's not recommended for steamodded 1.0
you won't be able to disable any such mods individually
What was the alternative you tried there?
I got the file data with NFS.read and tried to pass it directly to newSource
Honestly I think youâve already been given the easiest solution, a card area of size 5 with a selection limit of 1, and a single button to confirm
How does the new localization work for Vouchers?
Mods that implement more legendaries:
is_face IIRC
Thatâs an error with their mod
As I said before, what about mods that add more Legendaries?
i've been really struggling with G.UIT.C
it doesn't in any way create a column
I donât know if cerlo is planning on supporting that or not
Youâre using it wrong then, can I see what the problem is?
the way I coded the calculate of the Trickster, it is impossible to add modded legendaries
also, I would need to add a sprite for every modded legendary...?
Would break even during the base game once pareidolia shows up, which is why others were suggesting to do the id check
What do you mean
IIRC there is a vanilla function to check if a card is a face card, which is how Pareidolia does it
Thatâs why Iâm saying doing it the way MathIsFun suggested is better
Search box only needs to account for one card at a time
card.base.face_nominal?
I think aces also populate that space for some unknown reason
Wrong
Oh that one might be interesting? I havent looked at smods support for ranks yet
i don't plan on adding support for modded legendaries
they already specified base
this one also checks for parei
and the actual is_face function is modified by smods
function Card:is_face(from_boss)
if self.debuff and not from_boss then return end
local id = self:get_id()
local rank = SMODS.Ranks[self.base.value]
if not id then return end
if (id > 0 and rank.face) or next(find_joker("Pareidolia")) then
return true
end
end
That's just gonna break the second the player buys pareidolia
I'd like to replace a face card with another random card
Ah I see
I mean, I could also nuke all face cards, and it probably would be funny
But I'm not sure that's very fun to play with lol
it crashes while starting the game
Put the object in its own row node
still having problems with the cardarea
maybe the one I copied wrote has only space for 1 joker
local function createCardArea()
G.Trick_CardArea = CardArea(G.ROOM.T.x + G.ROOM.T.w / 2, G.ROOM.T.h, 5.09 * G.CARD_W, 1.03 * G.CARD_H, {card_limit = 5, type = 'title', highlight_limit = 1})
local center = G.P_CENTERS['j_caino']
local card = Card(G.Trick_CardArea.T.x + G.Trick_CardArea.T.w / 2, G.Trick_CardArea.T.y, G.CARD_W, G.CARD_H, nil, center)
G.Trick_CardArea:emplace(card)
center = G.P_CENTERS['j_triboulet']
card = Card(G.Trick_CardArea.T.x + G.Trick_CardArea.T.w / 2, G.Trick_CardArea.T.y, G.CARD_W, G.CARD_H, nil, center)
G.Trick_CardArea:emplace(card)
center = G.P_CENTERS['j_yorick']
card = Card(G.Trick_CardArea.T.x + G.Trick_CardArea.T.w / 2, G.Trick_CardArea.T.y, G.CARD_W, G.CARD_H, nil, center)
G.Trick_CardArea:emplace(card)
center = G.P_CENTERS['j_chicot']
card = Card(G.Trick_CardArea.T.x + G.Trick_CardArea.T.w / 2, G.Trick_CardArea.T.y, G.CARD_W, G.CARD_H, nil, center)
G.Trick_CardArea:emplace(card)
center = G.P_CENTERS['j_perkeo']
card = Card(G.Trick_CardArea.T.x + G.Trick_CardArea.T.w / 2, G.Trick_CardArea.T.y, G.CARD_W, G.CARD_H, nil, center)
G.Trick_CardArea:emplace(card)
end
Change the 1.03*G.G_CARD_W to 5.09
No donât fix it
Just change the number in the multiplication
So it respects the card size
ohh ok
the problem still remains
is the highlight_limit 1
yeah
why's the type title?
add something like this maybe
i copied the cardarea from JokerDisplay
is that cardarea highlightable?
you can set the type to joker
the game one features the buttons "sell" and "use"?
or maybe hand
JokerDisplay didn't need highlighting
collection card areas are created on demand
type = 'joker'
probs for testing
i fucking hate ui
mood
Objectively correct opinion
you are more than welcome to solve my issue
the ui engine isnt actually that bad once you figure it out
but it has a steep learning curve, bc its a custom engine
but once you get it, you get it
that's the problem
you have to figure it out
well what's your current problem?
this one
yeah i believe i've gotten a grasp of it now
check G.UIDEF.use_and_sell_buttons function
By the way did you see temporary cards
what type is it set as?
no
joker
@crisp coral
As I said I want to make it a custom shader but for now
Doesnât each CardArea have their own highlight area?
the fuck did i do lmao
or at least highlighting a joker in a joker type cardarea does
I used Laetitia Gift for reference
oh ok
Speaking @wintry solar đ

ok it works but you can sell the legendaries
Teach me your ways, shader bachelor
Do whatever the shop does
glory to the best legendary joker
inject into it and return nil if card.area is your area đ€
have you considered simply adding an exception to the code that adds the buttons
i'm not using my brain anymore
it broke with the last G.UIT.C i wrote
whats the problem
you shouldn't be able to sell the jokers
then don't have the area config type be jokers?
local card_highlight_ref = Card.highlight
function Card:highlight(is_highlighted)
if self.area and self.area.config.type == "cerlo" then
self.highlighted = is_highlighted
else
card_highlight_ref(self, is_highlighted)
end
end
local can_highlight_ref = CardArea.can_highlight
function CardArea:can_highlight(card)
if self.config.type == 'cerlo' then
return true
end
return can_highlight_ref(self, card)
end
change your cardarea type to cerlo
I think this works
wooooo i got my own cardarea
it might not do
but I think it should
Myst, does the mod index git pages tend to link to releases or main branch?
main branch, or file in source code if it's something like betmma's
hmmm
replace the cerlo's with title
I don't know why it won't draw the cards
oh wait
yes I do
if I do type = 'joker', anotherValue = 'dontSell' and change this function to self.area.config.anotherValue
local card_area_draw_ref = CardArea.draw
function CardArea:draw()
card_area_draw_ref(self)
if self.config.type == "cerlo" then
for k, v in ipairs(self.ARGS.draw_layers) do
for i = 1, #self.cards do
if self.cards[i] ~= G.CONTROLLER.focused.target then
if not self.cards[i].highlighted then
if G.CONTROLLER.dragging.target ~= self.cards[i] then self.cards[i]:draw(v) end
end
end
end
for i = 1, #self.cards do
if self.cards[i] ~= G.CONTROLLER.focused.target then
if self.cards[i].highlighted then
if G.CONTROLLER.dragging.target ~= self.cards[i] then self.cards[i]:draw(v) end
end
end
end
end
end
end```
this should draw the cards
Perkeo sitting there
chilling
just create some columns
đ€·ââïž
G.UIT.C
use the same code that thunk uses to place the card on the main menu
and place them inside the columns with some padding
you can adjust the size, the scale, etc.
that's not the problem
maybe go back to this idea?
what is the problem you have
@wintry solar I put 'title' and erased the CardArea:draw and it works
yeah I thought it might
there'll be some other parts of card area that populates things for draw that are being skipped by using a custom type
but now it might create errors with other CardArea title?
Just to make sure, buffering was set?
yeah
I think you'll be able to highlight in the collection now iirc
And did you try passing in a decoder over the file data and using that for the source?
Anyways @crisp coral you didnât answer me ;P #1257366048382914580 message
I AM IN A MIDDLE OF SOMETHING ELSE
you don't need all the qol on one specific card, the deck view qol is there because it's used for the whole game
Itâs the other way around
The card shouldnât work in a specific way because the QOL isnât there
You donât add QOL for a specific card
You change how the specific effect works
Thunk has expressed a similar opinion
Also Marvel Snap operates on similar principles
also the entire time until you specified i thought the you were talking about the card itself, not when the blind from the card is active
whatever
As I said I didnât foresee people having that interpretation
how is this argument productive?
Since most of the time youâd use it immediately, and you wouldnât use it during another Blind or anything
the misunderstanding was already figured out
I was just curious about her opinion since she replied to my comment about hard platformers
Since itâs an expression of more general design principles
Now the problem is passing the value to The Trickster
G.FUNCS.Trick_Select = function()
if G.Trick_CardArea.highlighted[1] then
local selected = G.Trick_CardArea.highlighted[1].config.center.original_key
end
end
The game giving the player the time to plan their decisions isnât an argument for obscuring information
Well, not obscuring
and also, creating the UI every context.setting_blind
Just maintaining it hidden inside a couple of menus
and making it go away after i select
Define G.GAME.YourMod and save the value inside
ok
now this?
I don't know how to do that and was too lazy to look it up
Do you happen to have the code from your experiment? I want to try
is there a wait_until() function?
there's juice_card_until
A trick Iâve made is to create an event that either executes a function or creates a copy of itself
it prints nil
yea that's basically what juice_card_until does
I see
and it prints right after creating the UIBox
i'm testing a solution
my solution was a failure
i'm invoking your help
@fallen tendon
@wintry solar
@zealous glen
I have been summoned
did you try what victin suggested with the events?
They didnât return true
can you show me?
I mean if they want to stop other things happening until a choice has been made
Otherwise the EventManager doesnât know the event is finished
And it freezes the game
There are other ways to achieve that AFAIK
I thought if it didn't return true it just did the event again
Idk. I only see people who make it return nil by not including a return
So it freezes
does it create it outside of the event?
try doing that and return G.GAME.Trickster as the only thing in the event
will take a look
Trickster.lua, line 105 to 113
The idea is this:
- Use NFS to open a file, set its buffer to be chonky, and load to string
- Convert this string into Love2D file data
- Pass this file data in when creating a sound decoder
- Pass the decoder when creating the audio source
it should be like this?
The menu is a bit invasive but cool
multiple doesn't workl
that's because it doesn't stop the game
I should be able to make it stop the game
Actually a good tool is to use create_uibox_generic_options
Thats what i used for variable and it keeps the game running but you cant interact with it
If you want the game to stop you can turn it into an overlay
just cleaning some stuff up and getting multiple to work
do you want them to have independent selections?
yeah
swag
so am I right in thinking this is effectively all 5 legendaries in one in terms of effects and you just choose which to apply per blind with this voucher?
yep
just going to try one more thing
you have total freedom
what do you think?
it's beautiful
it should track the tooltips correctly this way
If you keep the same legendary, does the stats gained stays inbetween transformations?
Or like if you pick x, change to y and change back to x
it gains stats for all forms at all times
Oh wow so if I grind Yorick for example and switch to another legendary with XMult it keeps it?
yeah, and then when you switch back it will be as if you had never switched
Neat
can you send the code back?
yeah just adding a couple of notifications
`
hmmm
not sure on the ! for discards
it's nice to know it's having an effect though
i think it is better without notifications
because you have no way of knowing which legendary it applies
please leave it as it is @wintry solar
Oh hell yeah
there you go
the messages are still in, see how you find them but they're easily removed
I think they'd be useful
it's not intuitive that the counters continue progressing when that joker isn't chosen
I did speed up the discard one
I was trying to make some planet cards but when i hovered over them, i received this error. anyone recognize it or know how to fix it?
functions/misc_functions.lua:1918: attempt to index field 'colours' (a nil value)
Try seeing what is calling .colours
It might be an UI error since I had something similar, but I think it was colour
colour = part.control.V and args.vars.colours[tonumber(part.control.V)] or loc_colour(part.control.C or nil, args.default_col),
the line in question
what function is it in?
Yeah itâs a UI issue
localize
like the loc_txt?
yeah
SMODS.Planet {
key = 'tetra',
name = "Tetra",
loc_txt = {
name = "Tetra",
text = {
"{S:0.8}({S:0.8,V:1}lvl.#1#{S:0.8}){} Level up",
"{C:attention}#2#",
"{C:mult}+#3#{} Mult and",
"{C:chips}+#4#{} chips"
}
},
config = {hand_type = 'h_bj_natural'},
atlas = "planets",
pos = {x = 0, y = 0},
loc_vars = function(self, info_queue, card)
local hand = self.config.hand_type
return { vars = {G.GAME.hands[hand].level,localize(hand, 'poker_hands'), G.GAME.hands[hand].l_mult, G.GAME.hands[hand].l_chips} }
end,
}
define colours in your loc_vars
k
Iâm curious what itâs used for
I havenât made a Planet
colours = {(G.GAME.hands[_c.config.hand_type].level==1 and G.C.UI.TEXT_DARK or G.C.HAND_LEVELS[math.min(7, G.GAME.hands[_c.config.hand_type].level)])}
because it changes based on level right?
yah that worked, ty
I thought that was added automatically
Because I changed the level colors
But I didnât have to touch any individual Planets
planets already have this option sent to them
Here
Yeah and this is a Planet
Ah the levels arenât added automatically
you can imagine V in loc_txt as a varying colour, which you define in your loc_vars as colour = {option1, option2}etc.
Itâs in the localization
yes
whack

uhh... wait why is Steamodded loading the sounds on the main thread, and not delegating that to the sound manager thread
The baby is born #1265798766774976645 message
idk maybe because threads are fucked and smod sounds can't be loaded there normally

gah then
Tried merging in the sound changes, lag spike problem still remained. Tried hooking the sound playing and modulation functions to see if I could catch the channel being filled, I couldn't see any channel filling
Well, this was pretty annoying, but got some progress going 
like the MODULATION function in misc_functions?
Yeah
that's only used if the thread doesn't exist though
why does everyone do checkboxes on the right
The game defaults that way
I insert them right after the call to push to the sound manager channel
I see the appeal of the checkboxes on the left, but I'll have more than just checkboxes, and text fields wont look as good
Left to right reading sense
guys
please help with fixing vanilla game bug
bc i have spent the last few hrs trying to find the exact cause of it and I got nothin
hm what bug
bug that causes cards bought from shop to be burried under random amount of consumeables from the top when you have a large quantity of consumeables from perkeo
it only occurs when cards are bought, it does not occour when cards are generated from emp or pri
Hmm why is the waviness of cards not visual-only?
wdym
also @languid mirage if your working on a better deckviewer saturn already has features like that in development if u want to help with that
I mean, it's already released #1258438028800692224
I'm just working on better settings menu
tbh I have no idea about this one
is .T.x always an integer?
Also switched back to the luajit that Balatro comes with, why the f does 2.0.5 chug a lot less than 2.1
maybe it has to do with the autosorting screwing up when there's a <1 pixel gap?
sounds like you ran into the same thing thunk did lol
maybe
the problem is with align_cards()
the card gets emplaced into the correct position, but then after align_Cards() it gets placed 5-8 positions back.
For serious play I'm going with 2.0, but I'm determined to get to the bottom of 2.1 performance regressions
float
the issue is that it NEVER happens when using emp or pri
its so weird
thank you so much for mentioning this I managed to remove about a hundred lines from my code lmfao
(mb for the reply ping D:)
Just had a thought about a workaround for the issue that might also look cool: Adjust consumable spacing so that consumables at the end are spaced out more than those at the beginning
Add functionality for the spacing to shift around the mouse location if its near the consumable slots, and youd get a sort of riffling effect
@regal wolf
I don't think that will solve the bug, but I'll give it a try
If it truly is a "move consumable to position" thing, then this should mitigate it at least
to be fair, Idk why not just use #1248924034716930100
it's not 100% vanilla
but it shouldn't be too hard to adjust it
like the only difference is that incantation allows non-negative consumables to stack and take up 1 slot
Yeah everyone was like âthis could be a great QOL modâ but alas the author didnât want to make it a QOL mod
yeah, maybe.
There are ways to work around the issue, for now at least I want to try and fix the bug.
sounds like a great cartomancer feature đ
why would I steal someone else's core mod idea đ
I think making it into a QOL is different enough
You might opt to reimplement rather than copying or referencing the code
But it is a good standalone QOL feature
pretty sure jen mentioned adding an option to toggle it being qol at some point
I think it's easier if I just PR that feature
any remember how to fix the problem where you drag cards around and tey don't go back to where they should be?
Anybody got some repo's or advice how to spawn UI elements?
this is probably good enough for vanilla mode
only negative consumables can stack
HAHAHAHA
it certainly do be doing stuff
I actually had a very similar issue with my card sleeve
Lmao
pls help
it's not a bug, it's a feature 
how about a deck with all cards from all of the decks? 
yeah sorry, this was my fix for the element not snapping back (just stop the player from moving it) đ
card.states.collide.can = false
card.states.hover.can = false
card.states.drag.can = false
card.states.click.can = false
but let me know if you find an actual fix >:)
uhm why do I have random nil
apparently it appears if I open options -> settings
apparently nopeus causes it
someone didnt remove a text field correctly
I tried installing love for mod support, but it bluescreened me with this. What have I done wrong? I have Steamodded 1.0.0 installed and working
did you verify the game files through steam yet?
None of the instructions told me to
Oh, wait, I got it
No
But deleting it still crashes the game, from Steamodded side this time
So something broke inside of it
Aight, the mod was the culprit of that one
But adding lovely back without the mods crashes still
Without lovely and mods it runs
Without lovely it is just the base game, right?
Yea
Nvm
I verified files and it fixed itself
Steam has found a broken one
Weird that it ran without lovely anyway, but idk
Still works if you add the mods back too?
Nice đđ»
I think I'm doing something wrong
What am I supposed to be looking at here
boss rush
Cool
is it possible to add additional information in crash screen?
Iâd like to see the full file name for once
yeah SMODS.load_file exists, it just needs to be used
how
Does it work like NFS.load?
it uses NFS
if there's a file at <your_mod>/path/to/file.lua, all you do is SMODS.load_file('path/to/file.lua')
Does it also return error and the file as an executable function?
uh
+10x mult while the dvd logo is hitting the corner
I think it will be funny to do this if game was inactive for like 5-10 seconds
1 second
đ
also I now have to add CRT shader to it because I couldn't get a separate canvas to work
rn its either one or the other
make it play the dougdoug corner sound when it corners
đ
that might be hard (it's a shader)
I guess it's not impossible, but probably not something I want to bother with
another dougdoug watcher spotted
hey! i've been posting on modding-chat. but i might as well post here as it seems more centred on developing mods
im creating a hand, and i've been trying for about a day to get this down
i've done almost everything except implimenting the hand
im wondering if anyone could provide some help on what the coding behind this hand would be
screenshot for context
did you see example mod in steamodded?
not that useful for this tbh - it only has a composite hand
which doesn't work for this
it's technically composite, but it doesn't compose strictly out of other hand parts
because high card in game is defined as not any other poker hand
Question, is there a way to prevent a joker from being sold e.g locking it but not debuffing, alternatively how could I spawn a UI block under the joker area?
i think what i need is related to straights
whatever code checks a card
and then makes sure its one after
ive tried to find it
but i keep failing
yeah but the hand part for that is specifically the highest ranked card
so it should use atomic_part, not composite
I believe its evaluate_play and it uses the selected_hand with the text it destructs at the top
ah true
havent coded a hand before but is it something like this
does that mean i should change this
such a thing doesn't exist in vanilla, ranks are highly hardcoded. Steamodded does change this, given the value of a card, you can get all the ranks that come after it by SMODS.Ranks[card.base.value].next
yes, atomic_part = function(hand) ...
hand contains all cards in the played hand as Card objects
that has a few issues:
- it doesn't capture even vanilla ranks being non-transitive, i.e. a hand of AA2 will not activate this (Aces have an ID of 14)
- it doesn't have the wanted behavior for custom ranks, their IDs are in order of being registered and usually not useful
yeah, the first one I've noticed but I didn't want to just solve all the problems for them lol
then there's also the fact that get_X_same looks for exactly pairs, it won't tell you if there's a higher amount of same cards
I should probably add a utility function for that like get_X_or_more_same(n, hand)?
oh yeah, considering the fact i do want to make other "run" hands that's probably something i need to consider
If you want to make other types of run hands that are considered separate then I think the base get_X_same is more useful then so you can distinguish between pair + card and three of a kind + card
I think
not really
a 3+1 run still contains the 2+1 version
base game code accounts for these containing hands explicitly
which is barely extensible
atomic_part = function(hand)
local ret = {}
local _pairs = get_X_same(2, hand, true)
for _, _pair in ipairs(_pairs) do
local rank = SMODS.Ranks[_pair[1].base.value]
local run = false
for _, card in ipairs(hand) do
for _, next_rank in ipairs(rank.next) do
if card:get_id() > 0 and card.base.value == next_rank then table.insert(_pair, card); run = true end
end
end
if run then table.insert(ret, _pair) end
end
return ret
end
or maybe instead of get_X_or_more_same, I'll add an optional argument to get_X_same that will count higher pairs
so like get_X_same(2, hand, true)
perhaps that's cleaner
what does atomic_part do btw? does it add it to the result table that evaluate_poker_hand gives you?
i dont think this does actually exist
infact, i got an error about it when selecting a card
I literally just said I need to make it
no, I just wrote the code under the assumption it exists
why would you not break after run= true btw
there could be multiple next ranks
that would be two pair then
@frosty dock quick question, do you know if there any resources for spawning custom UIâs and any ordering one should be aware of as you seem quite knowledgeable about the game?
ah
I have a bit of a question about the inner workings of Balatro, if anyone can help me
How does Balatro take the string used for random Seeds and uses that?
Like
I'm making my own card rogue lite (Based on Uno instead of Poker)
And I wanna implement a similar Seed system
But for some reason Unity's Random class can only contain an Int?
So I thought, okay I'll take a 8 character string, convert it to number, and we're good to go
However, if there's too many numbers, the string exceeds the limit of Integers...
So I wanted to ask how Balatro does it
Maybe I'll get some inspiration
jee just realised how common this hand i made is
Like I know Balatro doesn't use Unity for its engine so I'm not expecting a clean 1 to 1 conversion
I think Eremel posted an in-progress UI guide somewhere here at some point? The source code as-is is pretty much useless for understanding how it works given its terrible formatting
As much as I'm hoping to hear more about the inner workings of the game and maybe get some inspiration to fix my own situation
this
I don't think thunk would be happy with using his seeds code for a different game, but if you just want to see the idea, the stripped code can be found in a C & C++ rewrites for seed searching
https://github.com/MathIsFun0/Immolate/
Oh yeah I wasn't gonna copy him one to one
I don't even know what his algorithm looks like
I'm more than happy to try and explain something in more detail, should it be needed
also you can probably ask Math in #1209513992519946250 as they're the one who made immolate
oops, there's another issue here, actually
really? working fine in my experience
base.value doesn't account for stone cards having no rank
get_X_same accounts for it, but say you had a stone card that was originally a seven and played it along a pair of sixes
is there a way i can prevent that
Awesome! Ill do a search and see if i can find something đ
yeah i just edited it in, checking for a positive return value from get_id is the least hardcoded way to go about it, I think đ
I am also around to help out with ui related queries
Thank you!
And thank you, to you too đ
anyway thank you immensely for the code that you wrote, i definetly wouldnt be able to progress with the mod without the help
:D
(to make it work currently i just used "get_X_same(2, hand, true)")
alright you'll be able to keep that, just adding in the patches to make it work
but theres one more thing i was wondering
would there be any major issues if i tried to make a "house" variant of it
eg.
55566
replacing the high card with a rank one higher with a pair
yeah no doubts it could be extended to that
thinking the or_more arg to get_X_same should also be useful for that
get_X_same(1, hand, true) basically gives you the cards grouped into lists of cards that share the same rank
that's probably good enough to generalize
just pushed the util to main
would that be to replace the other get_x_same code from the previous code
you can keep it as is, the third argument of true now just actually does something
so what exactly would i change if i wanted it to account for a "run house" as i call it
let me write up a generalization
function get_run(hand, len1, len2)
local ret = {}
local minlen = math.min(len1, len2)
local pair_list = get_X_same(minlen, hand, true)
local _pairs = {}
for _, v in ipairs(pair_list) do _pairs[v[1].base.value] = v end
for _, rank in ipairs(SMODS.Rank.obj_buffer) do
local curr = _pairs[rank]
if curr and #curr >= len1 then
local run = false
for _, next_rank in ipairs(SMODS.Ranks[rank].next) do
local other = _pairs[next_rank]
if other and #other >= len2 then
for _, v in ipairs(other) do
table.insert(curr, v)
end
run = true
end
end
if run then table.insert(ret, curr) end
end
end
return ret
end
oh what the hell
I rephrased in terms of ranks because that's more efficient
before you posted that
i think i solved it kinda
i have no idea how, and full house and other run hands work normally
i just changed it from > 0 to > 1
that should make no difference
oh it was just bias
i tested more
and it just replaced run of three
did you make it a composite hand with full house?
ah
so the nice thing about this is that it can completely disregard any cards that don't form a large enough pair (a singleton is just a pair of one card)
len1 and len2 would be the min amount of cards needed in the lower/higher rank respectively, you can pass these in as needed from your atomic_part function
i know it sounds stupid but, if i wanted to use this function; where do i put it
atomic_part = function(hand) return get_run(hand, 2, 1) end
and i assume before or after the atomic part function i also put the thing (the big code that you sent a min ago)
you'll want to put that somewhere in top scope of your mod file
i.e. not in a poker hand object
sure
after i put it there it errored
well everything is exactly how it was put in messages
maybe i need to add a { onto that end
well that gave me another error
I'll have a look if you send the file
oh you need nothing from the previous atomic part function
the end of that file should look like
atomic_part = function(hand) return get_run(hand, 3, 2) end
}
oops, there
and get rid of the excess } after the get_run function
this
i did not send that last message as i wanted it to, apparently
for the excess }, i mean the one you put after this function
maybe also read up on lua syntax a bit more and get a code editor that catches these syntax errors as you go - vscode has a lua extension
yeah notepad isnt the best code editor
lol
you need an end to close the function and a } to close the table constructor
oh my it didnt immediately crash
it might work
awww nope
what went wrong?
is somethign wrong with my atomic part for the house, its not working
could you send the file again? I'll do some testing, maybe I messed something up in generalizing the function?
oh wait you only ever sent a snippet and not the full crash so I can't tell, did you update steamodded?
yeah well
you can't expect a functionality I just added to be there if you don't update
i thought that was self explanitory
didnt know it was updated
ssry
and i think the last hand i need to add
is the flush run
a normal run
but all cards have to be of the same suit
that doesn't make too much sense for a 3-card hand
yeah your right
nevermind
run of four it is
i guess the mods done for now
ill check if it works
ohh what the fukc
i didnt even change anything
i just rebooted it and it did this
what does that error mean
its linking to a non mod file
i think that means your above_hand isn't valid
i put run of four above run house
whats wrong with that
its literally called run house in my mod
are you registering run of four after run house?
yep
i forgot about the class prefix, actually
h_rh_Run House
mb
alternatively you can save the run house object like local run_house = SMODS.PokerHand { ... and then do above_hand = run_house.key
that gets you around dealing with the prefixes
i'd rather keep it prefixed for now
it will still be prefixed
it just means you don't have to denote them explicitly
but h_rh_Run House should work
đ
its beautiful
but its not done quite yet
time for the planets
which are very easy
thank god
@regal wolf heard you're investigating a vanilla memory leak, got any leads?
not investigating it yet, but its on my list
theres a few different possibilities, and I also saw someone report a memory leak from just afking on the main menu.
so there might be multiple, lua is notorious for memory leaks
After a while of natural play, I get slowdowns, especially when I move my mouse around (not even over anything in particular)
I've hooked the nuGC function to print if it hits its memory limit, and it's reporting that it's getting those, in rapid succession, in this state
So yeah bona fide memory leak
yep
1x
if i use my 1x size, what xpos and ypos would i need to display the first planet?
Assuming everything is correctly spaced, first one would be 0,0, 1,0, 2,0 etc
can you describe exactly what is happening when the memory leaks start occouring?
if you get like a black/gray box you're outside the boundaries (which really should throw an exception, not just silently throw up nothing, but ya know)
0, 0 just displays the entire image squished
It shouldnât
I get smol lag spikes at frequent and extremely regular intervals when I move the mouse
idk why i put the right values
That's when the symptoms start that is
on the main menu? in a game?
Wherever I happen to be
it happens as soon as you load up? or after some amount of time?
Donât use 325 and 106
After a while of playing
ok
Use 71 and 95 in code
use the size of the individual images, not of the whole sprite sheet
i wonder if its data not being correctly deleted
i tried and it did this
Then your sprite sheet is wrong
what do you think went wrong here?
i dont know i made sure my sprite was positioned right
what's the first 71x95 pixels of that sheet from the top left?
yeah they're not positioned correctly
try using this one
(make sure the image is named correctly though)
see if it works
what would i have to do to make it 2x as well
I think cryptid has a nice little auto upscaler
yeah here you go: https://github.com/MathIsFun0/Cryptid/blob/main/assets/1x/resize.py
how do you use it
you need python
u sure?
pip install PIL or something
that gives an error
Hello everyone. How can I do smooth transition for changing alignment in UIBox?
here's one i use that converts all files in assets/1x when run in the mod folder
There aren't a whole lot of heap profiling tools for luajit 2.0
Might have to grit and strain through luajit 2.1 again
Genuine question, why do people use a Python program to scale their art? Don't most art programs allows that?
why do all these programs keep telling me i dont have a PIL module
i installed pillow module which is the same thign
try py -m pip install pillow and possibly (?) restart the cmd after you've installed it
one click button to upscale every image is a lot easier than going through all of them manually
is it just supposed to not do anything for ages
Oooh I see
the install shouldn't take longer than ~10 sec
i have already isntalled pillow, its just not working with anything that uses PIL
is that why
if you see this
C:\>py -m pip install pillow
Requirement already satisfied: pillow in c:\users\user\appdata\local\programs\python\python311\lib\site-packages (10.4.0)
then you already have it installed yes
well it didnt show that
it just
kept
going
and its still doing this
but when i dont use py
it works
well just to try to fix some stuff
im quickly installing a new python
ill try that when im done
alrighty
I suggest not having multiple python versions installed at the same time unless necessary btw
can get kinda messy
I use it because I donât make the art, ppl send it in various resolutions and the python program lets me drag and drop to fill out both 1x and 2x properly
I literally just make the spritesheets in Paint
I also âmadeâ resize.py (or rather, prompted an AI to make it
)
cant imagine having people willing to draw for me đ
lmfao
m7
what am I missing?
I made like two assets total for balatro modding
Vulcan in the planet example mod and Labyrinth in Cryptid
And for both of them I used tools to help me (not AI lmao)
share your wisdom on how to get people to draw for you
ref table contains all instances of the game object
you don't have it
look at other game objects
make a community project that ppl want to contribute to
"You should draw for me cuz I'm awesome and epic"
perfect
still cant get that python thing to work
pillow just doesnt want to work
the programs tell me that PIL is not installed when ran
i've checked about 20 times
and i have installed newest pillow
i feel like im bashing my skull against a wall of knifes
jgskjfsjdasjldas
?
it returns without no output?
Is this before or after you reinstalled python
it took too long so i ended up not doing it
how do i fix that
If you somehow installed pip through some mechanism outside of using python to do so, uninstall that
no
he installed python once through python.org (presumably), and once through the windows store
both come bundled with pip
