#💻・modding-dev
1 messages · Page 585 of 1
Have you tried looking how Ortalab does it?
bump
It's called SMODS iirc
But depending what you want to test you may not need a custom deck
how can i check when a joker gets moved
guys help
im trying to make it so if there's 3 of any kind of face card individually, it gives 3.14 mult
but my code is the uh
'not workl
could you reformat please? it looks awful on my screen
Use code from get_X_same
Use code from the function called get_X_same in functions/misc_functions.lua
i have never decompiled balatro
No, it just checks if there is a number of a kind.
oh
No, in the lovely dump.
hey yall just a quick question, how many py and px are seals?
71x95, the same as jokers, consumables, vouchers, boosters, decks and enhancements.
this patch works, except for the blind select page, where the blinds display their normal values
why doesn't that specifically work?
You need to patch create_UIBox_HUD_blind I think.
ahhh i see
No, you need to patch create_UIBox_blind_choice
Because it uses the dollars from the object from G.P_BLINDS
calculate = function(self, card, context)
if context.pre_discard and G.GAME.current_round.hands_played == 0 then
G.E_MANAGER:add_event(Event({
trigger = 'immediate',
func = function()
local discard_count = #G.discard.cards
G.FUNCS.draw_from_deck_to_hand(discard_count+1)
card:juice_up()
return true
end
}))
end
I want to design a Joker card with the effect: "When discarding, you can draw one extra card." But my G.discard.cards seems to be empty during the first discard? (The first time, I discarded 5 cards, so I should have drawn 6 cards, but G.discard.cards was nil; the second time, I only discarded one card, and then G.discard.cards stored the cards from my previous discard, resulting in drawing 6 cards.)
Can I ban specific jokers from being spawned by SMODS.create_card
Yes, put it in G.GAME.banned_keys then remove it.
I was gonna do that but thought it would affect the seed's pool, I assume that isn't the case?
if context.pre_discard and G.GAME.current_round.hands_played == 0 then
G.E_MANAGER:add_event(Event({
func = function()
G.FUNCS.draw_from_deck_to_hand(1)
card:juice_up()
return true
end
}))
end
What do you mean?
Sorry, what I meant is would this somehow affect the seed pool in any way? For example if blueprint gets banned then unbanned again would that allow it to be spawned naturally? I thought banned keys permanently alters the joker pool
No, because it's not banned anymore.
I know I can just flick it from true to false and slot in SMODS.create_card in between
alright
thank you
hmmmm I tried this, but it still seems to draw the same number of cards that were discarded, without the extra card being drawn.
Try putting the event in an event.
hai :3 so uhm, im tryinna move a thing that currently works on math.random and math.randomseed into pseudoseed so it changes every time u go into a run, but im getting confused on how i should structure it
here is the original code:
math.randomseed(n)
return allowed[math.random(1, #allowed)]
and heres how i tried doing it (sorry if its stupid xwx):
return pseudorandom_element(allowed, pseudoseed(n))
any help would be useful <3
btw idk if its important but, allowed is a table
holy crap that works but how😭
this is so fucked up
indeed psuedorandom element
Because it will happen after the cards are drawn after the discard.
what is the use of event manager add event
yea, i tried copying it from cryptid mod ://crash consumable cuz it had a similar functionality of same-seed same-action
oh nvm it get wrong again
but its crashing :C
It adds an event to the event queue.
i mean most things should use that
though cryptid is usually not the best reference
true
send tje log
uhm
game isnt loaded for some fucking reason??
when does the crash happen
nvm 88 mods
Code? Also your version of Seals On Everything is outdated.
i swear, you will not believe me, but the 88 mods is NOT the problem here
how do people even play with 88 mods
okay but still maybe not a great idea to test with 88 mods 😭
in general it is best to dev your mod individually
i actually know its an issue with the code specifically cuz whenever i revert it it works fine
show code
I guess the extra card draw isn't displayed correctly
yea
but it's actually working
is there any way to fix this
after discarding twice, It's now drawing two cards that I don't recognize lol
those two blank spaces are (probably?) the card it drew
No, it's SMODS.Enhancement not SMODS.Joker but elsewise if you want all gold cards to nothing always then yes.
its SMODS.Enhancement right
not Joker
hey yall just curios, how do you make a tarot card show up in the collection/tarot tab
i made my first tarot card and im kinda confused on how to make it show up in the collection (if it even exists lol)
what is the use of this
It should be by default.
then im probably doing something wrong lol
Making things happen at the correct time in scoring and not before scoring.
ok thx for clarifying
for context this is in a seperate consumeables.lua in a item folder
Are you loading the file?
what do you mean loading the file?
Loading the file using SMODS.load_file to run the contents of the file.
i just recently organized everything is there something i should know about that
previously everything was in a main.lua
Yes, anything not in the main file will not be loaded unless you load it yourself.
how does loading work exactly
assert(SMODS.load_file('path/from/root/of/the/mod/folder'))()
how can i get a rank's id
SMODS.Ranks[rank].id
ty
are the suits in SMODS.Suits just their names
and if they arent, how can i get them
like with how card.base.suit stores them
No, it's their keys.
Yes.
okty
quick question, anyone know if there's an equivalent next(SMODS.get_enhancements(k)) for seals or editions?
oh damn, I literally looked in that document but missed it
if card:get_seal() and if card.edition
ty lol
there isnt a function like that because quantum seals and editions dont exist
why does this cause an overflow
how to increase booster shop and voucher shop slots?
look at how vanillaremade does it
??
search for overstock
vanillaremade doesnt do that
yeah I was confused
SMODS.change_booster/voucher_limit
iirc
Why are you using copy_table?
to create a temporary table for the suits
Why?
because im trying to make a deck that deletes 2 random suits for each rank
is the issue copytable?
Yes.
what do i do instead then?
okay so ive been looking around a little,
is it a good idea to make one "main" file in my mods folder
that runs everything
so for example in meta deta i call main.lua as my main folder and then in that main cast all load files
Yes, a main file is required and you can only have one.
im a little confused on how to setup the SMODS.load_file, is there a tutorial or something for this online?
i have a feeling without more details im gonna be asking at least 5 more questions about this entire process lol
so this would SMODS.load_file('Balatro/Mods?Mymod'))()?
No, it's from the folder containing your files.
so just mods?
No, the mod folder.
hello??
SMODS.shallow_copy
ahh ok
man im trying to look at other mods i have installed to try and draw inspiration and with every single line i read i get more and more confused
wait what
if its that simple why does every mod ive looked at so far do it in a way more complicated way?
a lot of mods do recursive loaders because they have a lot of things split into individual files
i don't do recursive loaders
but also chaaaaat i need help with SMODS.gradient
I tried using it with custom colours and it's just coming out as black
why does my deck delete every single card
from a glance, is this supposed to be a not?
what
hold on so you're destroying every card except
the 7 of hearts or something
?
oh for each rank
yeah
if i like
choose hearts and spades
for example
jacks
it will only keep jacks of hearts and spades
and the suit will be randomized for the other ones
why don't you just destroy 2 cards from each rank in the deck
doesn't that have the same effect
wait ur right
yeah i was wondering why you didn't do that
smthing like this?
forgot the pairs, dont mind that
and it still destroys everything
🙏
No, the return goes in the if
like istg what am i doing wrong
Also are you editing directly on GitHub?
are you referring to @stoic void or me
im guessing me but idk
yaeh
No, you should use a code editor.
Im not trusted to be a normal person apparently, so I have parental controls so I cant download much
Vscode is free and by Microsoft
im reading from vanllia remade on how to add tarots but im a little confused by something
use vscodium instead
-- The config field already handles the functionality so it doesn't need to be implement,
it says this under all of the tarots
Vscode is 100% safe
ok thx
where and what is the config field exactly
the config = { ... } in the card
Config is where you usually store your variables/values
why is the amount of cards i lose incosistent
You can check the tarot remade code for reference
ik ik but im just a little confused on why they say it handles "functionality"
to jokers atleast theres alot more to it no?
is tarot functionally just built into it?
but with consumables max_highlighted, mod_conv and suit_conv is handled automatically
I dont know how to use vs code
Hey, I realied when you add a card to your hand from your deck, it comes facedown. I tried just adding :flip() after drawing it but it didnt work lol, anyone know how to fix that? (I'm drawing it using emplace like dna in vanilla remade)
It’s simple . Works like any text editor
is calc_dollar_bonus a thing
so if i want to create my own tarot card how exactly do i have to implement it
ig for more specification
i want to make a tarot that adds one seal to a card
so i was thinking of looking at justice and then change the glass value to a seal value
SMODS.ObjectType
I believe
no???
but now bcs of this whole config field im a little confused
I know how to use it now
My bad i forgot
i was thinking about a whole seperate thing (like tarots, planets, spectrals, mything) but i have a feeling thats way to difficult (WAS as in not anymore just gonna stick to tarots for now)
God forbid you forget function
for suit and enhancement conversion theres the automatic functionality, otherwise just define a use function
Yes.
also copy from vanillaremade seal spectrals
oh yeah right that exists
i completely forgot about those
wanted to remention this since I think theres a lil less going on now
Hop off league
G.E_MANAGER:add_event(Event({
func = function()
magnet_card = pseudorandom_element(most_changed, pseudoseed('magnet'))
G.hand:emplace(magnet_card)
magnet_card:flip()
magnet_card:juice_up(0.5, 0.5)
return true
end
}))
emerald isnt gonna hit itself 🙏
Fair
currently just afk tho
i ussually have a game open to play when i eventually have had enough headaches from trying to understand this XD
most_changed is a table with some playing cards in it, in case that's important, though that part seems to work
G.FUNCS.draw_from_deck_to_hand(1)
SMODS.draw_card(card_to_draw)?
doesn't seem like that's the way to do it
No, it's just draw_card
sorry I'm unfamiliar with this one so just draw_card doesn't get me there
draw_card(card_to_draw)?
i need to draw a specific card
No, draw_card(from, to, percent, dir, sort, card, delay, mute, stay_flipped, vol, discarded_only)
ok cool
Where would I be able to find that information? I feel like I can never find functions like this in the github stuff I've seen
And I hate always asking you guys but idk where else to find this stuff
theres like a couple here but not a lot https://github.com/Steamodded/smods/wiki/Utility
vanilla functions like draw_card should have a bit of documentation in the lsp_def/vanilla.lua file in smods, but it's not super human readable because it's meant to be used by the LSP system
got it
someone should make a more accessible way to find this stuff lol
I say that as if that wouldn't be a ton of effort but like
it would be nice
yea it's definitely a lot of work to write good documentation
but well worth the effort
ye
that would mean that going to #🎨・fan-art or #⚙・modding-general would be better, idc much but its a heads up
yeah sorry, are you asking how to implement your joker? or what
hey sorry to bother you again, it's working but I didn't know what percent, dir, and sort were exactly. I put em as nil for now and it works but the card ends up like too far to the side, as in it's like an extra card space too far to the right after being drawn, do you happen to know whats doing that?
The smooth chaotic movements were actually pretty difficult to make properly
Why aren't you using card:explode()?
that's weird
it won't let me select the face-down card
I should record this
Yes, because it thinks it's still in the deck.
Nah the other guy right, i might try to learn to code, i just showin i like msking jokers. Mb
got it, all good
ohhhhh
how can I solve this?
and sometimes it still shows up as blank lol
probably a refresh issue or something similar, but I don't really know how to fix that
I completely forgot that
Exists
Fuck
what
It's the function used when opening a booster pack.
Yes.
do you know why it would always be coming out black
Code?
local tsunlc = loc_colour
function loc_colour(_c, _default)
if not G.ARGS.LOC_COLOURS then
tsunlc()
end
G.ARGS.LOC_COLOURS.tsun_gold1 = HEX("FFD700")
G.ARGS.LOC_COLOURS.tsun_gold2 = HEX("f6e3c3")
G.ARGS.LOC_COLOURS.tsun_gold3 = HEX("edd5a9")
G.ARGS.LOC_COLOURS.tsun_gold4 = HEX("dcbe78")
G.ARGS.LOC_COLOURS.tsun_gold5 = HEX("d8b162")
G.ARGS.LOC_COLOURS.tsun_pale = HEX("E1ECF2")
return tsunlc(_c, _default)
end
SMODS.Gradient {
key = "tsun_gradient_gold",
colours = {
G.C.tsun_gold1,
G.C.tsun_gold2,
G.C.tsun_gold3,
G.C.tsun_gold4,
G.C.tsun_gold5,
},
cycle = 1
}
i made the code for all the other colours aages ago and i'm trying to convert them into a gradient now
the individual colours work properly
but the gradient is just always black
G.ARGS.LOC_COLOURS is not the same as G.C
Loc_colours are used in text
but when I do {C:tsun_gold1} in a joker the colours still work?
oh
well I guess that explains
that
it should work if I just put in the hex codes then right
Yes.
right okay
Hey, I'm having an issue where I add a card to hand at the start of a round, but if the played leaves and rejoins the run the card isn't there. I tried throwing a save_run() after adding the card to hand since I saw that somepleace but it didn't seem to work, anyone know how I might go about fixing that?
i completely forgot that everyone else can save runs and I can't
how can I put my gradient into G.C so I can use it for a rarity badge
No, it's SMODS.Gradients.modprefix_key
Code?
the gradient works in text but here it just comes out white
SMODS.Rarity {
key = "tsun_gold_legendary",
default_weight = 0,
badge_colour = SMODS.Gradients.tsun_tsun_gradient_gold,
pools = { ["Joker"] = false },
get_weight = function(self, weight, object_type)
return weight
end,
}
and yes i tried it with only one tsun_ and it still just came out white
Did you define the gradient before this?
I'm not sure
this code is at the top of a file loaded with load_file
and the file is loaded before the gradient is defined
but I thought loaded files ran after the current file was finished loading?
oh I can just put it in end_of_code
No, they load when they're loaded.
i had this issue with something else and I made a lua file specifically for the end of the code
that didn't work either
¯_(ツ)_/¯
is it possible to set other blinds (ex. small and big blind) to another blind?
yeah
how so
From what I recall it needs a lot of patches
What's the best way to alter the chip amount per blind as long as a thing is held
Like if I wanted a voucher that doubled the score requirement
possible, however any blind thats a boss blind in those spots WILL cause issues
so you need fancy patches
if thats what you want to do
yeah
is it possible to get the blind from the current choices
like
get the small and big blind
and modify their propreties
oh like
yeah theres like G.GAME.round_resets.blind_choices i think?
but thats just 3 keys, you cant modify anything else about the blind before starting it besides what blind it is
can i atleast get its position
like
is it in the place of the big blind or not
or
get their index
in the rounds
is there a hook i can add to check when a blind is selected
you can hook any context as a function
how
how?
not without seeing any code probably?
Oh?
hello??
they recommend beta-0711a but idk if thatd cause crashes
hook SMODS.calculate_context & check context.setting_blind
ok thanks
is there something that allows me to get the boss blind's position? something like i just did on the image?
Hey I’m having an issue where stakes wont unlock for me (example playing purple stake to unlock orange and playing white stake to unlock black) does anyone have any tips or ideas to which file would handle this issue?
G.GAME.round_resets.blind_choices?
ye
check for modify_ante and ante_end and then return table with modify set to 0? (this is from smods/src/overrides.lua btw)
so i should copy the code and add my check?
no
if context.modify_ante and context.ante_end then
local halt_ante = true -- set this to your condition for stopping the ante increase
if halt_ante then return { modify = 0 } end
end
??
code i found was a little bit outdated so im adjusting the solution, one moment
set modify to -1
instead of 0
im not sure, went looking thru both balatro source & smods for a bit but cant seem to find an easy way to do so, still looking tho
bringing this back since it's been a while and nobody had an answer at the time
SMODS.PokerHandPart{ -- Handful of Rocks base
key = 'handful',
func = function(hand)
local cards = {}
local count = 0
for _, card in ipairs(hand) do
local enh = card.config.center.key
if MINTY.rocks[enh] then
table.insert(cards, card)
count = count+1
end
end
if count >= 5 then
return cards --IT'S ALREADY A TABLE, YOU DON'T NEED TO PUT IT IN A TABLE
else
return {}
end
end
}
SMODS.PokerHand{ -- Handful of Rocks
key = 'Handful',
visible = false,
chips = 55,
mult = 6,
l_chips = 25,
l_mult = 2,
example = {
{ 'S_2', true, enhancement = "m_minty_microcline" },
{ 'D_7', true, enhancement = "m_minty_microcline" },
{ 'C_3', true, enhancement = "m_minty_marble" },
{ 'C_5', true, enhancement = "m_stone" },
{ 'H_K', true, enhancement = "m_minty_crystal" },
},
evaluate = function(parts)
return parts.minty_handful
end
}
any ideas why some of the rocks in a handful wouldn't score, despite being part of the poker hand?
maybe compare with the Cryptid Bulwark hand code
local stones = {}
for i, card in ipairs(hand) do
if card.config.center_key == "m_stone" or (card.config.center.no_rank and card.config.center.no_suit) then
stones[#stones + 1] = card
end
end
return #stones >= 5 and { stones } or {}
end,```
hmm
not all of these rock enhancements have always_score
i feel like that's related
cryptid doesn't need to handle anything for the bulwark, since vanilla stones do have that trait
hey gang, I've got something that adds a card to hand after the first hand is drawn, but it doesnt save or happen again if I leave and come back, anyone know why?
ah
try save_run()
then idk
are you calling it before making the card or after creating it?
show code
BTW while that's happening does anyone know how to reduce the reward money from blinds with a custom stake?
ik this doesnt rlly contribute to the solution but cant you just check #cards >= 5 instead of having a manual counter variable?
I want to add a new higher stake that reduces all blind rewards by $1
something like this
its from some of my code
func = function()
magnet_card = pseudorandom_element(most_changed, pseudoseed('magnet'))
draw_card(G.deck, G.hand, 100, nil, nil, magnet_card)
G.hand:sort()
save_run()
return true
end
}))
you can just do a math.max(0, blind.dollars - 1)
put the save run outside the event
try that
wont that run before the event though
i mean I can try it i suppose
didnt work unfortunately
I'm mostly just wondering where to put that code to execute it like what to take ownership off or insert somewhere with lovely etc.
mostly i just keep forgetting that feature exists
try doing a hook with calculate context
and check for the current stake
and if its the stake that you want
do the code snippet
is there maybe a context for reentering a run from the menu lol
since it doensn't redraw the cards my thing doesn't retrigger
and for some reason I cant save
I'm guessing using a G.GAME.modifier would also work but I'll check
I checked the list I usually look at and its not there but someone sent me one that isnt on that list once so idk
use a variable in G.GAME
self is the prototype object thats in G.P_CENTERS, changes to that are permanent
Reference to card (should be "back") instead of self
breaking news: this user made a slight grammatical error using brackets
Eventually. The rat explodes
add this sound to it it'll make it 1e308 times better
I was planning to do a balloon pop sound but sure
I'm so confused, I'm playing spot the difference between my code and vanilla remade code bc mine doesn't save the card it adds
My code:
G.E_MANAGER:add_event(Event({
func = function()
magnet_card = pseudorandom_element(most_changed, pseudoseed('magnet'))
draw_card(G.deck, G.hand, 100, nil, nil, magnet_card)
magnet_card:juice_up(1, 1)
G.hand:sort()
SMODS.calculate_context({ playing_card_added = true, cards = {magnet_card} })
save_run()
return true
end
}))
From vanilla remade:
G.E_MANAGER:add_event(Event({
func = function()
G.hand:emplace(_card)
_card:start_materialize()
G.GAME.blind:debuff_card(_card)
G.hand:sort()
if context.blueprint_card then
context.blueprint_card:juice_up()
else
card:juice_up()
end
SMODS.calculate_context({ playing_card_added = true, cards = { _card } })
save_run()
return true
end
}))```
I don't even want to do the calclulate context in mine bc im not even adding a card to my deck I just thought maybe that was the problem
maybe adding a card to your deck makes it save but drawing one doesn't?
yea dont add that lol u didnt add a new card
ik lol, i didn't have it until I was banging my head agaisnt the wall tryna figure out what was different
it didnt do anything so its gonna die but i left it in in case someone else thought that
i dont think this would cause u not to save, theres gotta be something else in ur code that youre not showing
Pretty much sounds like what I went through when making this.
calculate = function(self, card, context)
if context.first_hand_drawn then
--Find a list of most changed cards
local most_changed = {}
local max_change_count = -1
local change_count = 0
local in_hand = false
for i, playing_card in pairs(G.playing_cards) do
in_hand = false
for _, card_in_hand in ipairs(G.hand.cards) do
if playing_card == card_in_hand then
in_hand = true
end
end
if not in_hand then
change_count = 0
if next(SMODS.get_enhancements(playing_card)) then change_count = change_count + 1 end
if playing_card.edition then change_count = change_count + 1 end
if playing_card.seal then change_count = change_count + 1 end
if change_count > max_change_count then
max_change_count = change_count
most_changed = {playing_card}
elseif change_count == max_change_count then
table.insert(most_changed, playing_card)
end
end
end
--Draw card to hand
G.E_MANAGER:add_event(Event({
func = function()
magnet_card = pseudorandom_element(most_changed, pseudoseed('magnet'))
draw_card(G.deck, G.hand, 100, nil, nil, magnet_card)
magnet_card:juice_up(1, 1)
G.hand:sort()
SMODS.calculate_context({ playing_card_added = true, cards = {magnet_card} })
save_run()
return true
end
}))
end
end,
actually it is pretty bad
i plan on having a joker force 2 aces into hand that's gonna be a pain to make
save_run() should be its' own event afterwards.
can you add lua highlighting to ur code block
```lua
code
```
i tried that too 😭
oh, so like back.effect.config. for calculate and G.GAME.selected_back.effect.config for loc vars
local magnet_card
oh shit
should fix the saving
ty ill let you know if it works
i have bad news... :(
ty for finding that tho it was probably not good
wompwomp
im not the greatest w/ debuggin stuff but i tried
all in a days work for eddy rob
why are the cards so incosistent?
heyyyy @slim ferry im evil and am pinging you bc i see you're online...
if u dont feel like debugging ur all good lol
hello
but you tend to be quite helpful
try saving the run in a seperate event after that drawing cards one maybe?
Any1 know of a way to edit an enhancement/edition’s weight?
i did try that but maybe i did it wrong ig? someone else suggested that too
like an existing one?
i have no clue then
Yes
Like in the code
take ownership of it, and then set weight to a value (default is 5), or also add a get_weight function if you want it to be dynamic instead of a static weight
Ahh, okay, thanks!
are there any modded jokers that inherit the ability of a random joker? I can't figure out how to do it at all considering i'm also targeting a specific group of jokers
i suppose its a hook that changes the joker's calculate function everytime?
can look into pinkprint ortalab
by picking it out from G.P_CENTERS
anyone?
Hol on
card.base.value I think?
ill try
I think It would be card_key, and you access it like a normal key
oki
ty
card key is like the key for the base combination iirc, not for the individual rank or suit (so like ace of hearts would be H_A i think)
Yea but he could probably pull it from there, like take the A out of H_A
But it was the best I could find, still kinda new
hello, i'm trying to make a mod that changes the sprites for constellation and hologram using malverk, i tried to do it myself but i honestly can't wrap my head around how to start with that, could anyone here help me with that?
dont?
theres a reason malverk exists
and its so you dont have to take ownership of stuff
so what should i do if you wouldn't mind? i tried looking it up and didn't really get anything back
which is why i came here to ask
have you asked in the malverk thread? idk many people here that use malverk much
didn't know that was a thing if im being honest
Okay my weight stuff is still tweaking out, I’m trying to make my modded enhancement and edition scale on how many of them you have
And I’m having trouble altering the weights
where would i find it if you wouldn't mind me asking
😔
i'll just wait and hope someone else has the answer i suppose
anyone know how i would go abt adding another tab to the collection's "other" section? i want to add a section under stickers for my custom card type
i guess?
trying to make my joker have custom dimensions like square joker by hooking some functions, but i keep getting this crash. any help? here's the code:
-- Custom dimensions for Jokers
local set_sprites_ref = Card.set_sprites
function Card:set_sprites(_center, _front)
local ret = set_sprites_ref(self, _center, _front)
if _center then
if _center.set then
if _center.key == "j_chak_steal_this_joker" and (_center.discovered or self.bypass_discovery_center) then
self.children.center.scale.y = self.children.center.scale.x
end
end
end
return ret
end
local set_ability_ref = Card.set_ability
function Card:set_ability(center, initial, delay_sprites)
local ret = set_ability_ref(self, center, initial, delay_sprites)
if center.key == "j_chak_steal_this_joker" and (_center.discovered or self.bypass_discovery_center) then
H = W
self.T.h = H
end
return ret
end
local load_ref = Card.load
function Card:load(cardTable, other_card)
local ret = load_ref(self, cardTable, other_card)
if self.config.center.key == "j_chak_steal_this_joker" then
H = W
self.T.h = H*scale
self.T.w = W*scale
end
return ret
end
tbf the base game uses _center.name but when i did that it just didn't work
that maybe fixed it but i got a new crash
it might be from a different mod this time though'
that looks like you did something wrong while modifying .T.h
i pretty much 1:1 copied it from the source code so idk
blame the thunk
no i blame you
read the code properly
also i just realized
why are you trying to change the size in a hook
there are smods apis for that
i looked and couldn't find anything on that
🤷♀️
also vanillaremade
vanillaremade is nice
how can i move a card i created with add_card into the deck
because add_to_deck doesnt work for me
do you want to create it directly in the deck
yes
add area = G.deck
kty
add_to_deck doesnt add cards to the deck, it just runs functions when a card should be added to the players slots
add_card does that automatically
am still struggling with this, it looks fine in the collection but not during a run, its probably something simple but i do be stupid
how does it look during a run
oh its because it says xmult =
remove that
how do I make a joker with a sticker play a sound when it appears in the shop?
for context it's going to be a pre-owned sticker which will be used in a custom stake. Pre-Owned jokers will be cheaper, but slightly worse than their new counterparts (as in all of their values are multiplied by 0.75)
it just says xNil
btw this is the sound that I plan on using lol for when it appears
ill change the thingy and see if it works
are color codes in localization case sensitive?
yes
gotcha, thank you
tried changing it, didn't work and the mult isn't applying either
ill post the whole thing just need a seperate message because character limit
local solo_tally = 0
if G.playing_cards then
local ranks = {}
for k, v in pairs(G.playing_cards) do
ranks[v:get_id()] = ( ranks[v:get_id()] or 0) + 1
end
for k, v in pairs(G.playing_cards) do
if ranks[v:get_id()] == 1 then
solo_tally = solo_tally +1
end
end
return {
Return_mult = 1 + card.ability.extra.xmult * solo_tally,
}
end
return { vars = { card.ability.extra.xmult, 1 + card.ability.extra.xmult * solo_tally } }
end,
calculate = function(self, card, context)
if context.joker_main then
local solo_tally = 0
local ranks = {}
for k, v in pairs(G.playing_cards) do
ranks[v:get_id()] = (ranks[v:get_id()] or 0) + 1
end
for k, v in pairs(G.playing_cards) do
if ranks[v:get_id()] == 1 then
solo_tally = solo_tally +1
end
end
return {
Return_mult = 1 + card.ability.extra.xmult * solo_tally,
}
end
end,
wasn't sure which return to change so i did both
remove just the Return_mult =
got it
and you need to add vars too actually
return { vars = {1 + card.ability.extra.xmult * solo_tally}}
this
return { vars = { card.ability.extra.xmult, 1 + card.ability.extra.xmult * solo_tally } } ?
i already have that line two rows down from the edited return, do i need it else where?
oh wait yeah this is diffrent
the bottom one is if G.playing_cards doesnt exist
ah ok, so i change the return to that?
the first one, yes
it works now, thanks 👍
how do I make a custom stake be in-between the red and green stake
how would i get a joker's loc vars to change if it detects that you have another joker?
chat is this any good
#G.jokers.cards > 1 i guess 
check using next(SMODS.find_card('j_prefix_jokerkey'))
i think they meant a specific other joker, not any other joker
yep
context: there's a UI inconsistency with vanilla in smods where there's pages on the hands page when there shouldn't be with the vanilla 12 hands or less
now a page size of 12 doesn't really work because of space
a little impractical and maybe too slow if you're reloading a lot of sprites, but sure
oh aure's done the poker hand list thing I was suppsoed to do 🤣
okay so im kinda stumped, i recently got a normal file structure bcs i wanted to add a tarot card
so i made a main.lua that runs everything etc
now
there's nothing to be done differently there, right? I don't love the page size being inconsistent but I can't fit 12 and a page selector
how?
when i run my consumables.lua with only this that is straight from vanilla remade
would be alot more convienient for my situation specifically that i will not elaborate about
how detailed of an answer do you need?
uh
maybe have a look what dependencies the things you're copying have
Enough to use it??
this depends on a custom consumable type 'vremade_Tarot' that you haven't defined in your mod
I think this is the best solution, yeah
take ownership of green stake and make it unlock when your stake is beat
kk sending it
unless we remake the page selector
where am i supposed to define that?
you're not, unless you actually want to have a full consumable type of your own
i dont
vremade does it so its redefined tarots don't mix with the vanilla ones
i just want this to be a tarot
how do i make a custom consumable card set
you can just change the set to 'Tarot'
i was thinking about that but that's probably beyond my current scope lol
on a scale of 'hint me to some resources that will help me accomplish this' to 'give me all of the code for it'
give me all the code to it
i don't have time for that, as i said it's a tad impractical. maybe someone else will
where can i find the code for it then??
reference https://github.com/Steamodded/smods/wiki/SMODS.ObjectType#api-documentation-smodsconsumabletype
and vanilla remade i guess
code isn't found, it's written
if this was ready written somewhere and I knew about it, I would have just told you that
"I'm so happy" from Cardsauce but it's impractical
-# I tried to do that once
okay now im genuinely curious how bad it can be
changing an individual joker's sprite within the same atlas can be done by calling set_sprite_pos on that joker's center sprite
yo, how do i change the badge color of a custom objecttype ?
Random question... how hard is it to make a Balatro mod with near 0 coding knowledge. To learn from scrap and also is there any good ressources
I keep getting idea for jokers sometime when I sleep or shower and would love to give a shot at just making them lmao
the issue with that is that it resets if you reload the save
yeah see that's why I don't really want to give an answer
it's annoying to deal with
have you tried joker forge
it's worse if you're changing atlases on top of that
I just discoevered the site 10 seconds before you said that lmao
been hacking at it for a while and i cant find how to change it
tried primary_colour and secondary_colour & also badge_colour and idk man
what the fuck
jokerforge if you just want to quickly get some easy ideas in the game. you'll find its capabilities are limited. if you do want to dig deeper, there's a good bit of resources available and you can always ask here
tried making it so that the red stake unlocks the pre-owned stake
SMODS.Stake:take_ownership("red", {
unlocked_stake = "comedy_pre_owned",
})
what dod I do wrong???
speaking of which,
-- Pre-Owned Stake
SMODS.Stake {
name = "Pre-Owned Stake",
key = "pre_owned",
atlas = "comedy_stakes",
pos = { x = 0, y = 0 },
sticker_atlas = "comedy_stickers",
sticker_pos = { x = 1, y = 0 },
colour = HEX("fd5f55"),
unlocked_stake = "green",
applied_stakes = { "red" },
modifiers = function()
G.GAME.modifiers.comedy_enable_preowned_in_shop = true
end,
}
it doesn't seem to apply the red stake either
finally got it ^^
is there a good base to make a deck skin?
might have figured out my problem
so what about a base for the cards themselves
question, do you guys prefer steam modded or balamodded?
answer, balamod is dead and nobody uses it
yea i just realized that
lovely+smods is the standard and all content mods use smods
now for the bigger issue at hand: why isn't the sticker appearing
-- in the code for the stake
modifiers = function()
G.GAME.modifiers.comedy_enable_preowned_in_shop = true
end,
-- in the code for the sticker
rate = 0.3,
should_apply = function(self, card, center, area, bypass_roll)
return G.GAME.modifiers.comedy_enable_preowned_in_shop
end,
redefining should_apply like that breaks a few bits and pieces
not entirely your fault, the API is just really janky
there's a default enable flag though that you should be using
btw how do I make it so that the sticker makes the joker cheaper in shops?
how do i add use buttons to non-consumables
wait why is it not showing up
how do i check if a card is a consumable, again?
Is there a mod that put us in like a creative mode that allow us to just cheat in joker to test stuff?
DebugPlus
card.ability.consumeable
thanks ^u^
like, the affects of the sticker are working, but the sticker sprite and the sticker popup text aren't showing
how can i apply stickers to consumables?
Card:add_sticker ?
well i tried set_eternal but that hasn't worked
DebugPlus also seems to be unable to do that
and how do you spawn in jokers?
hold tab for the debugplus cheat sheet
oh thanks
ok so i figured out the culprit
apply = function(self, card, val)
if card.ability and card.ability.extra then
card.cost = math.floor(card.cost * 0.75)
if type(card.ability.extra) == "table" then
for k, v in pairs(card.ability.extra) do
if type(v) == "number" then
card.ability.extra[k] = v * 0.75
end
end
end
end
end
this single function is what's causing the sticker to collapse in on itself. the modifiers do work, but now for some reason it does this
fixed it
i actually hate how perfect the sound is for it
okay so i have a weird question i just want to know if a feature i want to add is even possible, so i have a joker pool called coffee jokers which i have a consumable to give a random one but i specifically let it surpass the joker limit, once the joker limit has been met i want the consumable to give something called "spilled coffee" and they will be negative as to not disrupt the other jokers if you want to change synergy later but it will gain +1 mult for every extra of said card obtained, the others will not grant the mult so im thinking it will have to be 2 seperate jokers but i dont really know where to start with that, thats not what im here for though i will figure it out i just want to know if its even possible
well in simple terms is there a way to say if joker count is at 100% do this instead and if its over 100% then give this instead
well no i plan on making it negative so maybe an if joker is present in hand then give this
actually that sounds possible but i have no idea the code for it, ima go figure it out guess i helped myself
btw here's a comparison as to how worse a pre-owned joker is compared to its fresher counterpart
idk how I did it but somehow I got it to apply to a consumable
as for why, I think what happened is how my should_apply function works:
should_apply = function(self, card, center, area, bypass_roll)
-- only applies if the card has values that can be made worse
return G.GAME.modifiers.enable_comedy_preowned and (card.ability ~= nil) and card.ability.extra
end,
is there a way to check if joker slots are full ?
so i basically want this Joker to have a 25% chance of giving a meteor tag when blind is skipped, and a 75% chance of a Meteor Tag instead. As is, its only giving Orbital. Does anyone know how i'd fix that within the confines of JokerForge?
why can't i properly set the rate of my custom sticker? i have rate = 0.3 but the sticker gets applied to all compatible jokers. also, i took ownership of the perishable and eternal stickers to change their should_apply function, and for some reason the same rate issue occurs???
is it a problem with bypass_reroll?
how do i get a consumable to do something depending on different variables in the game
like if a joker limit has been reached then do this instead ?
because at the moment its doing both
i think the rate setting only does anything if you don't define/modify the should_apply function, you need to account for that if you're (re)writing one yourself
this is a basic programming concept
https://www.lua.org/pil/4.3.1.html
how would i start it here ? i tried using #G.jokers.cards < G.jokers.config.card_limit to stop the first set still being granted but it just crashed the game which didnt really make sense to me since it was not full when i tested it so it fit the peramiters
what's your goal
like what do i want it to do ?
yes
i want it to give me a random joker from a pool i st which is what this does until i reach the limit i want it to give me one spilled coffee joker then when it detects that i want it to instead give me overflow but right now its giving me spilled coffee + the first set and never giving me the overflow
what you have right now is: always create a coffee1 joker. then, if your jokers are over the limit, create a spilled_coffee joker. then, if your jokers are over the limit and you have the card mm_joker36 (which will never be true, assuming that's supposed to be a joker key), create an overflow joker
if all that logic makes sense otherwise, you probably just need to change the joker key to j_mm_joker36
ah thanks, what do i do to stop getting a coffee1 joker
as an if #G.jokers.cards < G.jokers.config.card_limit then before thr first part crashes the game
if #G.jokers.cards <= G.jokers.config.card_limit then
-- add a coffee1 joker
else
-- add a spilled coffee joker and maybe an overflow joker
end
if that still crashes, show the crash log
also use SMODS.add_card, it does the whole card = create_card(); card:add_to_deck(); G.jokers:emplace(card) thing for you
okay i will try this
that worked for stopping the creation of coffee 1 after the limit has been reached but i still am not getting overflow after i have a spilled coffee in hand
Hey gang, I've been trying off and on to fix this bug since this morning, my game doesn't actually save the drawn card. Anyone know why this might be happening? It's stuctured just about identical to certificate from vanilla remade
G.E_MANAGER:add_event(Event({
func = function()
local magnet_card = pseudorandom_element(most_changed, pseudoseed('magnet'))
draw_card(G.deck, G.hand, 100, nil, nil, magnet_card)
G.hand:sort()
save_run()
return true
end
}))
ok well the condition you currently have is looking for a specific joker, not any spilled coffee
joker 36 is spilled coffee it has its own pool so it worked, i dont exactly know why but once i defined the joker having its own pool the code worked fine
so would i be able to replace j_mm_joker36 with spilled_coffee so it checks the pool instead ?
how do i fix this?
SMODS.Back {
name = "Family Deck",
key = "familydeck",
atlas = "oliverteaganmod",
pos = { x=4,y=0 },
config = {},
loc_txt = {
name = "Family Deck",
text = {
"Start with the",
"Oliver Teagan Mod",
"Jokers"
}
},
apply = function ()
G.E_MANAGER:add_event(Event({
func = function ()
SMODS.add_card("j_otm_teagan")
SMODS.add_card("j_otm_oliver")
SMODS.add_card("j_otm_andre")
SMODS.add_card("j_otm_august")
end
}))
end
}
it's crashing when i start a run with the deck
whats the error message?
no, it only checks for a name
so what would i need to do
what do i need to do
ive taken a break from coding for the last like month so im a bit clueless on half thre things i used to know
im warming back up but im not there yet
I thiiiink it should be
SMODS.add_card(key = "whatever_key")
do i need to have the "j_otm_"
got it
gonna re-mention this though no worries if you cant figure it out, i've stumped a few people already
Hello, anyone know how the paperback mod can retrigger jokers with the normal joker?
wait a minute
your using event manager right
i already fixed it
ah
this joker retrigger all common joker, but because i'm a begginer i dont know how to do it
And i want do it with a pool, no with a rarity
anyone know of any mods that do stuff in first_hand_drawn context?
first of all do
SMODS.current_mod.optional_features = { retrigger_joker = true }
to include vanilla jokers aswell as custom ones it would be easier to do so with rarity wouldnt it
in main?
any file works, this is to enable joker retriggers
(if you're using a different file make sure to assert it)
just turn on all optional features tbf easier to do it now than forget later that its optional, thats what i did
already
dunno why you want it to be only common jokers in a pool but
https://github.com/nh6574/VanillaRemade/wiki#retrigger_joker
yeah thats what i was thinking it is easier to just do it as the rarity
no, i want do work only in a pool of green jokers, but the original joker only works with commons jokers
How do you make an animated joker? I've been racking my brain for hours now
works, thank you
you need to use card.children.center:set_sprite_pos({x = num, y = num}) in update or draw or a drawstep to switch between the sprites on a timing
if you're patient there's an SMODS PR that would allow jokers to use animated sprites
oh
You need to know what youre doing to do this
I eas really hoping I was just naimg things wrong :(
how does quantum ranks work again
it doesn't yet
(unless you specifically downloaded the PR, in which case you should read through the PR for the details)
dang
I just copied from another mod and it works great
So happyyyy
<@&1133519078540185692>
how do i hide mod badge
no_mod_badge = true
Ive been asking everyone this bc I can't seem to figure it out, anyone willing to give it a look?
what's the goal
Why is there just crypto
mods are asleep
mods are asleep so they can’t murder the crypto scam
unfortunately.
Ah
to draw the magnet_card to hand at the start of the round. rn it draws but if you leave and rejoin its not there anymore
weird. save_run should be saving it
ikr
can i see the full thing
i also tried putting it in its own event
ye
calculate = function(self, card, context)
if context.first_hand_drawn then
--Find a list of most changed cards
local most_changed = {}
local max_change_count = -1
local change_count = 0
for i, playing_card in pairs(G.deck.cards) do
change_count = 0
if next(SMODS.get_enhancements(playing_card)) then change_count = change_count + 1 end
if playing_card.edition then change_count = change_count + 1 end
if playing_card.seal then change_count = change_count + 1 end
if change_count > max_change_count then
max_change_count = change_count
most_changed = {playing_card}
elseif change_count == max_change_count then
table.insert(most_changed, playing_card)
end
end
--Draw card to hand
G.E_MANAGER:add_event(Event({
func = function()
local magnet_card = pseudorandom_element(most_changed, pseudoseed('magnet'))
draw_card(G.deck, G.hand, 100, nil, nil, magnet_card)
G.hand:sort()
save_run()
return true
end
}))
end
end,```
theres prolly some goofy stuff in there but it does draw the card just doesn't save
Already stumped a couple other people unfortunately
😭 the cards that are not in hand are in G.deck.cards
ope
i don't think thats the issue but it's very convoluted code
how did you do the event thing for save_run
how do i add_card a specific joker
lemme go put it back to that rq
calculate = function(self, card, context)
if context.first_hand_drawn then
--Find a list of most changed cards
local most_changed = {}
local max_change_count = -1
local change_count = 0
for i, playing_card in pairs(G.deck.cards) do
change_count = 0
if next(SMODS.get_enhancements(playing_card)) then change_count = change_count + 1 end
if playing_card.edition then change_count = change_count + 1 end
if playing_card.seal then change_count = change_count + 1 end
if change_count > max_change_count then
max_change_count = change_count
most_changed = {playing_card}
elseif change_count == max_change_count then
table.insert(most_changed, playing_card)
end
end
--Draw card to hand
G.E_MANAGER:add_event(Event({
func = function()
local magnet_card = pseudorandom_element(most_changed, pseudoseed('magnet'))
draw_card(G.deck, G.hand, 100, nil, nil, magnet_card)
G.hand:sort()
return true
end
}))
G.E_MANAGER:add_event(Event({
func = function()
save_run()
return true
end
}))
end
end,
ill double check it doenst work
ok instead of that put the event in the place save_run was originally
oh like nest them?
yes
ill try that
you want that event to be after the event draw_card does
because vanillaremade doesn't use draw_card there
draw_card specifically uses an event
omigosh ty it worked
huh, I did try using emplace and it didnt work either
idk lol it works now tysm
purpose: retriggers face cards in played hand by how many cards are played.
if context.repetition and context.cardarea == G.play and context.other_card:is_face() then
return {
repetitions = #context.scoring_hand
}```
this is how i do it?
No, the number of cards played would be #context.full_hand
for making custom cards for playing cards, do I need to make a full suit or can I just edit the face cards? My other question of how do I properly palettes cause I am so confused and getting it telling me to do it right or use the old formatting
gains xmult if a face card is retriggered but what context
There is no context for that.
oh i didnt read retriggered
hey uh is there a pseudorandom that gives a random number in a range
wait, so that's a custom context altogether?
pseudorandom('seed', min, max)
do any peeps know rather or not that I would need to do a full suit for custom cards or can I just edit the face cards?
What do you mean custom cards?
like how the friend of jimbo stuff works
how would i make it so if you discard cards it has a chance to give that card an effect
is there a way to detect if a gold card existed in player's hand
this one just crashes
pretty sure just add a context.individual
Is the mod loading?
yeah
,?
re-booting balatro
return is not closed properly in calculate
if context.joker_main then return { xmult = ... } end
In one line?
Can be, yes.
If the file has syntax errors and the game is opening without crashing that means the file isn't loading.
how do I see syntax errors?
Install the Lua extension.
...assuming VSCode is used.
:|
I am
because apparently github isnt ggod enough
Im guessing this one?
Colours
Set up the lsp
lsp?
So you get auto completion
local result = {}
for k, v in pairs(houseofcommons) do
print(inspectDepth(result))
result = SMODS.merge_effects(result, { x_mult = card.ability.extra.x_mult })
end
return result
...am I not using SMODS.merge_effects right?
Yes, put {} around everything in SMODS.merge_effects.
It's just 1 not +1
SMODS.merge_effects({{result}, { x_mult = card.ability.extra.x_mult, card = G.consumeables.cards[v] }})?
No, remove the {} around result.
what does that do?
You shouldn't have the + in the change shop size
someone already told me
SMODS is underlined in yellow
im guessing that isnt good
It doesn't matter unless it's red
are you loading the file the joker is in?
how do I do that just so i know if I have
can you send a screenshot of your main file
I dont think I have
Copy the code from the joker file and paste it under this
under the main.lua ? ok
OH SHIT THX
idk why I dont have audio on this
Cooked obs
Ive done clips with sound on other games tho, idk
'Ello!
I'm new to Balatro modding. I'm doin' a small mod for me and my friends, and I'm wondering if there's like a wiki or something to check functions I can use to do some events in the game (Like turning a joker into its negative version, or stuff like that)
smods wiki and vanilla remade wiki
https://github.com/Steamodded/smods/wiki
https://github.com/nh6574/VanillaRemade/wiki
card:set_edition('e_negative')
-# How do I add a cardarea to UI?
how a custom game over dialogue that activates when a certain joker is in your hand
search jimboquip
https://github.com/Steamodded/smods/discussions/919
I'm working on a Joker that "eats" a card if it's the first hand of the round and there's only one card, then gives all eaten card back when destroyed or sold. Logically I don't see why this wouldn't work, but in practice it seems broken, and a weird draggable card stays on the screen instead of disappearing when playing a 1 card hand
you can't save cards to a card's ability table anyway
it will not reload properly
i would recommend storing these cards in a hidden cardarea
Is there some sort of a modded or non-modded Joker that does something similar, so I can have a reference? Never worked with hidden cardareas
entropy butterfly deck stores cards in a hidden cardarea, you could try looking at that
Thank you!
If you want you can put the cardarea above the Joker's card area so when you "eat" the card you move it towards the Joker who ate it and then it goes offscreen
this is my lovely patch for the cardarea if you want to take a look
# Add off-screen Stack area
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = '''G.SPLASH_BACK = Sprite(-30, -6, G.ROOM.T.w+60, G.ROOM.T.h+12, G.ASSET_ATLAS["ui_1"], {x = 2, y = 0})'''
position = "before"
payload = '''
self.cs_stack_W = 4.9*G.CARD_W
self.cs_stack_H = 0.95*G.CARD_H
self.cs_stack = CardArea(
G.jokers.T.x,
G.jokers.T.y - (G.jokers.T.h*2),
self.cs_stack_W,
self.cs_stack_H,
{card_limit = 5, type = 'cs_stack', highlight_limit = 0}
)
'''
match_indent = true```
Thank you so much, that's really helpful! And it would be great visually to have it that way, that's a really nice touch!
how to make localization file to make my quip?
I made my localization file a lua file and put this inside of it
return {
misc = {
quips = {
xmpl_evil_quip = {
"example quip"
}
}
}
}
is there any other steps I should be aware of?
That should be it...
ok then why isn't it appearing?
Is your modprefix matching? Is the localization file named right?
Oh and also
local original_draw_card = draw_card
function draw_card(from, to, percent, dir, sort, card, delay, mute, stay_flipped, vol, discarded_only)
if card and card.cs_stolen then
return original_draw_card(from, G.cs_stack, percent, dir, sort, card, delay, mute, stay_flipped, vol, discarded_only)
end
return original_draw_card(from, to, percent, dir, sort, card, delay, mute, stay_flipped, vol, discarded_only)
end
This is the hook that precedes draw_card. If you don't know what a hook is, it lets you run something either before or after the original function call
If the card is eaten (for me, I am using stolen because I'm stealing it but it's the same behaviour) then instead of going to the right it's placed into the hidden cardarea
You can set a similar flag in your Joker's calculations for your card (is_eaten) and check for that instead
quip_filter = function(quip, type)
if (quip.key == 'toga_srb2kartwin' or quip.key == 'toga_srb2kartlose') then return true else return false end
end
I myself am crashing because of this on the SMODS.Back object.
-# Ping me if responding to this, I'll catch it later-
it worked thx
Aside from the smod and vanilaremade wiki, where else can I find information on the smod API? Some things, like the G object, don't seem to be well-documented
or should I just look at other mods for comparison
i mean almost everything is stored in G
i dont think theres documentation on everything in it
a lot of it isnt really useful anyway
it would look like table: <some memory address>
it doesnt actually print the contents
Sick
