#💻・modding-dev
1 messages · Page 490 of 1
why does calling this function like this during context.final_scoring_step cause a crash for "init_chips" being a nil value?
Is there a game event for when a card gets flipped?
How are you calling it
there isn't one, but you can define one by hooking Card:flip
idk what you mean
In LUA, it is a very important concept to understand that everything is a variable and all variables may be edited in runtime. This includes functions. With modding other peoples' LUA files, like Klei's basegame code, you may find yourself wanting to run your code before or after the original fun...
how do i check what seal a card has?
card.seal
I went to look for this and accidentally sent it in #⚙・modding-general
🥴
strangely this activates after scoring despite using final_scoring_step
probably because of the event
asking for help with this again, cannot for the life of me figure it out on my own
if context.remove_playing_cards then
for k, v in pairs(context.removed) do
if v == card then
-- do things
end
end
end
```?
the game crashes for the x mult part
that seemed to do the trick, thank you!
win_game is not a function to check if the game is won, it just wins the game.
oh
top 1 people who weren't at their computer #1
me
ty ty, I'm in bed now but I had a static sprite on top of the sprite I applied a shader to if that makes sense so hopefully this will fix it
:3
yeah also about declaring the thing it's declared in that draw func
hiii somecom
ok modding question how would i check the sellvalue of a card
hi dilly

cant you not just just check sell_cost
(i didnt know that was a thing)
oh
(that's why i asked)
what's your question
card.sell_cost for how much it sells for, card.cost for how much it costs to buy
why the hell does my consumable not work if its found in a booster pack here
it works if its already in consumables and i dont have a can_use, do i really need one when i just have a use?
highlighted card or not is irrelevant btw
Yes.
cause the card just pulls from your profile settings
why the heck it work without can_use sometimes then
is that specific to packs or if ytou have set conditions?
behold my
of pure evil, now with a random sellvalue limit per run
maybe if you have max_highlighted or min_highlighted set
i once again ask: how do you make tooltips on rarities?
-# (The documentation makes no sense to me and neither does any examples i look at so i need someone to dumb it down slightly)
You mean info_queues?
i think so...?
-# The things that pop up when you hover over a joker with eternal on it, for example
I don't think there's an api for doing that on rarities
ughh
what is nativefs
could i use a UI element or smth?
native file system, a lua library i think
you can patch into the generate_UI function and add your own info_queues to any card that has that rarity
ill try that but i won't be happy abt it
[manifest]
version = "1.0.0"
dump_lua = true
priority = 0
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = "local cfg = (card and card.ability) or _c['config']"
position = "after"
match_indent = true
payload = '''
if _c and _c.rarity == 2 then
-- append stuff to info_queue if it's uncommon
end
'''
something like this i think
oh that's how you patch things-
for a custom rarity i would just put the rarity's key in place of "2", right?
@limber blaze the talisman code doesnt work
Yeah, should be
hold
nxkoo_dies = {
show_mustard = false,
mustard_timer = 0,
show_image = false,
image_timer = 0,
show_flashbang = false,
flashbang_timer = 0,
current_flashbang = nil,
default_flashbang = love.graphics.newImage("Mods/Tangents/assets/customimages/jumpscare_2.png"),
path = SMODS.current_mod.path,
flashbangs = {
shop = "shop_flashbang.png",
blind = "blind_flashbang.png",
hand_played = "hand_flashbang.png",
discard = "discard_flashbang.png",
round_start = "round_flashbang.png",
joker_trigger = "joker_flashbang.png"
}
}
well yeah you didnt change the path
the talisman code just gives you the path to use
i see
how
though
What's the code to detect certain played hands and level up those hands
something with eval
but anyway
itd be something like
tangents_path .. "/assets/customimages/jumpscare_2.png"
thanks
:(
although you might not even need the talisman code if smods.current_mod.path works i think talisman is weird because it doesnt need smods 💀
oh you want your condition to be if _c and _c.rarity == 2 and first_pass otherwise it will add it like 50 times I think
okay its trolling now
that file path is definitely corrrect?
okii
also sorry to be a bother but how do i append stuff to info_queue? everything i try to put there crashes
im not sure
info_queue[#info_queue + 1] = { set = 'Other', key = 'some key' }
try SMODS.current_mod.path .. "/assets/customimages/jumpscare_2.png"
sure
hm?
relative means?
relative to the love directory aka the folder where Mods is in
can you load an image from file data instead of a file path
im trying to figure this out
how do you check if an enhancement overrides the base rank?
if SMODS.has_no_rank(card)
i should make a deck that makes everything have no rank and then make no hands exist and then
my mod will be G = nil
also someone help them
something, did you figure out how to patch debugplus
No.
local nativefs = require("nativefs")
local data = nativefs.newFileData(nativefs.read(tangents_path.."/assets/..."), '???', 'base64')
local imagedata = love.image.newImageData(data)
local image = love.graphics.newImage(imagedata)
does thiswork?
ill try this
this is why i haven't touched patches before today, it works but no text displays
if context.scoring_name = "handname" then
return {level_up = true}
end
```?
that means you appended the wrong thing
well no it wouldnt be base64 here
what should the default line will be?
damn smt beat me to it
i was gonna give him bad info on my second part, is there a reason we return level up as opposed to using the smart level stuff
i mean the box displays fine, but no text appears
what did you append
ruby
what should the default path line be
Because it automatically levels up the last played hand, also it happens in a return, so it happens at the correct time.
idk
gotcha okay, thankies from mcspankies
-# im sorry this is really new to me 😭
srock we are gonna be besties in exactly 4 years i think
i think that's in that set
i look forwards to it
is it forwards or forward
forward i think
but its because you wont trust someone you randomly met ont he internet so i gotta get real super close to you and itll take 4 years and then i will be at your wedding
i think you got the wrong person
no because that would not fit the narrative i made up
Actually was wondering how you would give 3 plus leveling
More than just one level up
Change true to 3
That makes sense
How would one do multiple
Play a hand to level two playing hands
Like it levels up a pair and two pair
buh
if context.scoring_name = "handname" then
return {
level_up = true,
level_up_hand = "handname",
extra = {
level_up = true,
level_up_hand = "handname"
}
}
end
using my power of deduction i will say tangents_path is nil
thank you brock
@lament agate string.sub(tangents_path, string.find(tangents_path, "Mods")).."/assets/custom_images/jumpscare_2.png" is probably your best bet
but this would break with a fucked up path
that has more than 1 Mods in it
If I wanted to do more than 3, I assume I add the this one to the extra as well or
Curiosity yk
It now displays the blue seal tooltip, so it's progress!
inside extra, you put another identical extra
what do you mean
Well goddamn
Extra sandwich
delicious
wait where do i put this
insideof the increment?
like C:\users\me\appdata\roaming\Balatro_with_Mods\Mods
Thank you my goats
inside of where your image path was previously
so love.graphics.newImage
-# now i need to figure out how to make a custom one-
yeah that should work
its just a weird string hack to make the native path a relative path
you need a localization file
same issue, concatenate
try SMODS.current_mod.path instead
where are you defining tangents_path
if you deleted the unneeded talisman code tangents_path is gonna be nil
i tried avoiding that for as long as possible but fine
string.sub(SMODS.current_mod.path, string.find(SMODS.current_mod.path, "Mods")).."/assets/customimages/jumpscare_2.png"
```?
yes
your journey ends here then
oh
i was trying stuff that didnt work
I think SMODS loads nativefs info a global NFS already btw
replace the path with this
it worked lmao
what i do
being here
maybe this is a stupid idea, but is it possible to make a joker that allows legendary jokers to appear in shop? so something like showman, but instead of overriding it so duplicate jokers can appear, it just overrides legendaries to appear
yeah sure it is
Yes.
just set legendary’s joker pool rate to something non-zero i think
how do i do that, i've never messed around with modifying vanilla stuff before
hey guys im tryna start messing around with making mods and the quick-restart binds are kinda js not working
closing the game and it dont restart
No, it's hard coded.
why the frig
how would i check if a card has a specific modded enhancement?
What buttons are you pressing?
do you have steamodded and lovely
also make sure its alt f5 and not alt f4
uhhh yes i think
yea i tried the m and the alt f5
lemme try one more time
how then?
Try to look for other mods that do it.
Visdev for custom suits
Tysm!
so i definitely have the right things installed and i know im pressing alt+f5
I'm adding new suits, how would I make it so Erratic still starts with 52 cards but it selects from the new suits?
it js kinda closes the balatro window and leaves the console open
im on linux so i fear its a little fucky
may be a bug?
I'm on linux and holding M works, but alt f5 doesn't
Requiem arrow and stone mask
one last thing that should be much easier: how can i make a joker double all blind requirements?
hmmm lemme try again
yea nah it js closed the balatro window and kept the console open
if context.setting_blind then
G.GAME.blind.chips = G.GAME.blind.chips * 2
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
ty!
Is that a mother fucking Jojo reference 😱😱😱
np, i also add play_sound("cancel")and card:juice_up() for extra juice
Also I know I keep extending this, but how to detect the ranking with the playing hand itself
optional but i like using it
Yeah I'm trying to figure out what level of detail I want because the traditional suit sigils are pretty sparse
i like the right one if it helps at all for the arrow
waitwaitwait, i should have specified: i want this to affect all blinds in the future even if the joker is sold
Mmmmm. Yeah the arrow has these little green trim details, and the mask has various cracks and wear that I can either keep or withhold
Unsure
Like the pair is 2
youre perfect and awesome and epic
Jgdgjfsskfkfskg
did u alsos ee my dms bestie westie
Yep!!! I didn't respond at the time because I was too busy gay making out with my partner hold on
wheres the patreon
So I did read that correctly
Amen
Also nvm Something I don't need it
Wanted to have only playing Pairs of 2 to level up
But idk how it would work with Two Pairs of 2s so
Bump
someone mentioned being gay so i am here now
Amen to that
as opposed to making out straightly
I can't make out with anyone straightly, I'm sorry
can someone help me debug this ts fr pmo :3
real
If I wasn't depressed and struggling with motivation I'd def be making NSFW content for money by now yea
in my experience quick restarting can just lead to a lot of issues for no reason :P
Instead my programming is quite pornographic. Don't look kids, it's optimized to the point of eroticism
(I don't actually write optimal code. I'm a designer, not an engineer)
but its so slowwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
??????????????
im dying
that is a sentencee i didnt think i'd hear today
you can wait the ONE MINUTE it takes
i GUESS i can continue watching my queer show while i wait for it to restart
in theory this should be working, but it isn't doing anything...
name of this show, please and ty
Damn, how do I temporarily switch teams
question: how do i give a card more than one rarity just because?
bluey
ive only seen kids and the queers watch it
queer show
look inside
FUCKING BLUEY AGAIN
that's the neat part: you dont
But that would not fit the storyline im trying to pursue
how does this relate to modding dev?
Im trying to do the winter route
We are all devs of mods, glad i could help 👍
doubt
were discussing the demographic of people who mod belatro to better fit our audience
i'd assume something with patching but you may need to wait for someone with experience in this area to get a helpful answer
You can't.
is it possible to CHANGE the rarity mid-round?
Yes.
in calculate?
Yes.
how do i do it then?
card.config.center.rarity = newrarity
If it matters I'm bisexual lol. I'm not exclusively attracted to women, and my nonbinary partner who looks like a gay bear can attest
How does a bear look gay
I love bears they're such cool fellas even though they could murder me
how does one change the spawn rate of a booster through a joker?
do you not know what-
like let's say I want a joker to prevent a specific booster pack to spawn
i wouldn't know the exact path but you'd alter the pack's weight variable, at least from what i see in the docs
yeah i've tried but it didn't seem to work
may we see the code?
wouldn't be sure how to format it
i formated it similarly to uh. consumeable's rates
why do you have an underscore before weight?
cause tht's how it works with rate lol
it still shows up regardless
did some research, figured it out
changed center
to
G.P_CENTERS.p_rw_selectfoodpack.weight = 0
G.P_CENTERS.p_rw_regularfoodpack.weight = 0
works as far as i know :3
yayy :3
boop how can i make every blind after getting this joker have double the requirement, if this doesn't work
I cant imagine it would
Blind requirements are in G.GAME.blind.chips so you'd have to change that
local delta_extra_slots = function(self)
local slots = 0
if self.config.center_key == "j_delta_cooledwater" then
slots = slots + 1
end
return slots
end
local delta_empty_slots = function(self)
if G.jokers ~= nil then
return (G.jokers.config.card_limit - #G.jokers.cards + delta_extra_slots(self)) > 0
else
return false
end
end
-- Hooking buyspace checks
local delta_buyspace_check_old = G.FUNCS.check_for_buy_space
G.FUNCS.check_for_buy_space = function(card)
return delta_empty_slots(card) or delta_buyspace_check_old(card)
end
local delta_cardselect_check_old = G.FUNCS.can_select_card
G.FUNCS.can_select_card = function(e)
local card = e.config.ref_table
if delta_empty_slots(card) then
e.config.colour = G.C.GREEN
e.config.button = 'use_card'
else
delta_cardselect_check_old(e)
end
end
replace j_delta_cooledwater with your joker
@wooden nexus
and i just put this in the joker?
right?
no you put this in main.lua
it runs outside the joker and does its thing
replace j_delta_cooledwater with your own joker name
gotcha
*key
How do I make the cards jiggle like DNA does
nope
juice_up()?
is ObjectTypes a real table or did i make a typo
Sorry I meant how do I make the joker keep jiggling like how Dna does until you do a certain action
check vanillaremade(?)
all i can help: https://github.com/Steamodded/smods/wiki/SMODS.ObjectType
Yeah imma do that
Been doing it actually but yk
how do you detect if a player bought something from the shop
i think i've done that
yeah buying_card
i know ✨
i dont think this includes booster packs tho
(it does not)
yeah
maybe you could use both open_booster and buying_card?
ITS NOT WORKINGGGG
that would include boosters from skips tho...
Imma kms brb
you could do
this but open_booster but you check if the player is currently in the shop
if context.buying_card or context.open_booster and G.shop
hmmmm
or rather more like the other way around since you can only buy cards in the shop
or just put parantheses around it
brb
yeah that's what i mean flip ur parentheses
what if you buy a card while not in the shop 😲
what if the card costs 0 because of a tag
Then don't put > 0
I only did that is because the joker steals a card
In the shop for free
And it's kinda useless if the free item gets used
On a free item
is there a way to detect if card is in an ObjectType if card is a part of P_CENTERS and not a string
sorry if it's stupid
I had an idea for a pair of jokers that I'm not sure how to implement.
Free Cell: Lets you move base cards between empty joker slots and your hand.
Ambidextrous: Same as above, but also lets you store jokers in your hand. ( But the jokers return to the joker space at the end of the round which can put you over the joker limit if you use Judgement, similar to what happens if Invis Joker copies a Negative. This is intended, you have to sell down below the limit to acquire more jokers. )
Also, why not throw in a third:
Sleight of Hand: Lets you store hand cards in empty consumables.
No Jokers in consumable space because Perkeo, but this would be a way to acquire negative copies of a good hand card.
here's my idea tho
hold ON
NO
I was thinking that Free Cell would be a Common, Sleight of Hand is an Uncommon, and Ambidextrous is a Rare. But what would I need to do to the game to put things in slots they're not originally intended for?
Lock in
Didn't you already do that but with spamton
new endless joker just dropped
Hm
you orick
Well damn
Good question
the opportunity
im not sure what u mean by that lol
I remember someone did a joker where if you didn't buy anything in shop you get X3 mulg
I forgot who
can i steal your hook
im just blabbering shit
dont worry
Be my guest
I stole this off of someone so
I mean
Borrowed
-# can you put it here
Oh yea
nic = {} -- Vouchers/Boosters
function nic_ctx(context)
if context.nic_buying_voucher then return 'buy a voucher' end
if context.nic_buying_booster then return 'buy a booster pack' end
end
nic.hooks = {}
nic.hooks.Card_open = Card.open
function Card:open()
if self.ability.set == "Booster" then
SMODS.calculate_context({nic_buying_booster = true, card = self})
end
return nic.hooks.Card_open(self)
end
nic.hooks.Card_redeem = Card.redeem
function Card:redeem()
if self.ability.set == "Voucher" then
SMODS.calculate_context({nic_buying_voucher = true, card = self})
end
return nic.hooks.Card_redeem(self)
end
nic = {} ?
Uncommon
Wow this is way simple
Should probably use this instead of my hook-
Thank you notmario
Mine just accounts for the cost of the item so it can either be free or double price while the one mf use just depends on if an item is purchasrd
Sooooo
lmao
i suppose
I suppose 😒
huh
using your code as a reference for my joker
oh alright
yeah
Yipee
You're going great
I'm currently trying to add a consumable type however it crashes when I enter the shop.
SMODS.ConsumableType {
key = 'reversetarot',
primary_colour = G.C.SET.Tarot,
secondary_colour = G.C.SECONDARY_SET.Tarot,
loc_txt = {
name = 'Reverse Tarots',
collection = 'Reverse Tarots',
},
}
shop_rate?
it's listed as optional but it still happens no matter what it is set to
i wouldn't know then
SOMEONE HELP VIOLAET
GET THAT PERSON SOME HELP
A SHIELD
They wanna know how to double the blind requirements
Have you tried updating lovely and SMODS?
try looking at Cryptid
I think it's when you have a score that's x2 it sets you to ante 8
cryptid is the one place i wont look at for reference
Unless it's somewhere else
Have you tried: ```lua
for k, v in pairs(G.P_BLINDS) do
v.mult = v.mult*2
end
didnt work
Gulp
Yes, because you're using ipairs.
Oh my
lmao
-# i fucking swear if that was it-
fucking hell that was it
I did try on newest smods, I will try updating lovely
I assume a joker is doubling the score or
I wasn't paying attention
this is a joker, yes
how can i increase the selection limit in booster packs?
how do you detect other jokers retriggering
context.post_trigger but you have to enable it.
in?
Optional features.
?
Yes.
mm i see
but the quantum enhancement doesnt work somehow
Code?
oh it was when i code soldier about high card being every single enhancement
before i changed it to something else
because it doesnt work
how doyou even use it anyways
Yes, because that would cause extreme lag.
oh well that explains it
You return {m_modprefix_key = true} in context.check_enhancement
i see
didn't even need to patch anything, ty!
Pro
nope, i tried smth stupid and it somehow worked flawlessly
If it worked it's not stupid
but everything i do is stupid :3
This joker I'm making is able to retrigger all other jokers except for TV. I believe it has to do with the fact that TV is a retrigger joker as well and I was wondering if there was anyway to get it to do the retrigger for tv as well?
No.
alr thanks for letting me know
Jokers that retrigger jokers cannot retrigger jokers that retrigger jokers.
also you shouldn't check the localized name, but the key
which, joker59 is a first for me
definitely works with multiple copies of it, too!
how are keys typically organized?
how does can_use work? for some reason it wont let me use this.
SMODS.Consumable {
set = 'reversetarot',
loc_txt = {
name = 'The Fool?',
text = {
'The Fool??',
},
},
atlas = 'reversetarots',
pos = { x = 0, y = 0 },
unlocked = true,
discovered = true,
use = function(self, card, area, copier)
SMODS.add_card({set = 'Joker'})
end,
can_use = function(self, card)
return true
end,
}
numbering them just seemed easier to me and it functions fine so its what I've been doing
for your tv joker I would've made it just key = 'tv'
but if numbers work for you I guess that's fine
when are you trying to use it
The name of the joker lowercase with no spaces.
ah guess I never thought of doing it that way
just in a regular game
Your code looks correct to my 4 am eyes, did you save it?
uhh actually nvm you're missing a key
i think your game would crash without a key so it's still likely you didn't save it
holy fuck, I'm an Idiot, I realise I forgot to save the file right before I saw your message, thanks for the help anyway
Hook Card:set_cost()
I noticed that when starting a new run after acquiring a joker with this code, the doubled blind requirements stay even if you go to the main menu. I would just use remove_from_deck, but i want the effect to stay throughout the run, and solely using remove_from_deck would work when the card is sold. How could i go about fixing this?
G.GAME.starting_params.ante_scaling = (G.GAME.starting_params.ante_scaling or 1)*2?
where would i put that?
You would replace the loop with that.
how to make rerolls free
how many rerolls
Every reroll or a certain number of rerolls?
every
Then you would hook calculate_reroll_cost
G.GAME.current_round.free_rerolls = G.GAME.current_round.free_rerolls + 1
is this a thing?
and alos this?
yes but if you want every reroll free then do what something said
also why would eremel lie
Why is this happening?:
how do I add a custom Consumable Types to boster packs? this is currently what I've got which kinda works, just the problem is it can try to add the custom consumable type more times than there are implemented.
SMODS.Booster:take_ownership_by_kind('Arcana', {
create_card = function(self, card, i)
local _card
if (pseudorandom('reversetarot') > 0.8) then
_card = SMODS.create_card({
set = 'reversetarot',
area = G.pack_cards,
skip_materialize = true,
soulable = false,
})
else
_card = SMODS.create_card({
set = 'Tarot',
area = G.pack_cards,
skip_materialize = true,
soulable = false,
})
end
return _card
end,
},
true
)
The way the card creation system works in balatro it doesn't really care about if there are any cards of the type left, if it chooses to make a type of object and there's no other one available it will make the default
You'll need to do it manually. I think rare tag does something like that?
is there a context after hand scoring but before it's checked to be above blind
i need to compare hand chips to blind size but using contexts directly related to hand scoring does not work
i need it to then compare current chips to chips needed to beat the blind
so if the current chips is higher, it adds mult
but using context.after did not trigger it
context.final_scoring_step then
will try that
How can i make mechanics? i made this but it's enh
can a hook be wrapped in to_big?
no, but the return can
ah
you'll have to give us more information
i got a talisman crash over here
like what?
just wrap the amount and the 0 in to_big
what's the problem? what are you trying to do? what do you mean by mechanics?
problem is i don't want to make them enh/im trying to make something like seal,enh,edition,etc./new type of thing i gave for example
you'll have to extend SMODS.Center then
ok thanks
is there a context like end of hand, like after the hand has scored and it has been added to game chips but before the round ends
context.after
you'll have to be more clear as to exactly you want to do, you might have a problem with the logic not the context
like this?
no, you'll need to extend the class like in the link I sent
It's a bit advanced
after the context, an if statement compares g.game.chips to g.game.blind.chips, and if chips are larger than blind chips mult is added
the problem is that the chips from scoring aren't added to g.game.chips at context.after so it'll be 0
and what was the problem with final_scoring_step?
use context.final_scoring_step and use hand_chips * mult as your current score value
ohh omg that works
thank u all so much :)
one last question
is there a way to check that before adding the mult from the card to scoring
wdym
joker has 2x mult
and the final scoring step would reset the mult to 1x
but the 2x would be added to mult before it reset
if that makes sense
like this?
-- pseudocode
local old_xmult = card.ability.extra.xmult
if chips > blind chips then
card.ability.extra.xmult = 1
end
return { xmult = old_xmult }
SMODS.Back {
key = "gangsta",
loc_txt = {
name = "Gangsta Deck",
text = {
"Start with {C:money}$50{}",
"and a {C:dark_edition}Negative{} {C:red}Eternal{} {C:attention,f:tngt_DETERMINATION}DealMaker{}",
"{C:money}$2{} per remaining {C:red}discards{} and {C:blue}hands{}"
}
},
unlocked = true,
discovered = true,
atlas = "dicks",
pos = { x = 3, y = 1 },
config = { dollars = 50, extra_hand_bonus = 2, extra_discard_bonus = 2 },
loc_vars = function(self, info_queue, back)
return { vars = { self.config.extra_hand_bonus, self.config.extra_discard_bonus } }
end,
apply = function(self)
G.E_MANAGER:add_event(Event({
trigger = 'immediate',
delay = 0.1,
func = function()
SMODS.add_card({
key = "j_tngt_dealmaker",
edition = "e_negative",
stickers = { "eternal" },
area = G.jokers,
discovered = true
})
return true
end
}))
end
}
deck not showing up
what happened
what not working
if i understand it right then yeah
it only uses the reset xmult for future calculations
not showing up in deck selection
looks fine to me
weird
check if the file is loading, you saved properly, etc
is it on a different file to the main one
well yeah
i did smods load file
i mean all decks shows up fine
modded one
except this one
dunno, looks fine to me
this game keeps fucking with me
oh my god
fxed
ifx
ed
fixed
local original_calculate_reroll_cost = calculate_reroll_cost
function calculate_reroll_cost(...)
local cost = original_calculate_reroll_cost(...)
if next(SMODS.find_card("j_tngt_dealmaker")) then
cost = pseudorandom('dealmaker_reroll', 1, cost + 100)
end
return cost
end
aritmethic crash
any idea?
what's the crash log
oh it doesnt seem to return a value
but i already set return cost
i have a hook that sets all rerolls free but im not on that PC rn haha
i think you just set reroll_cost to 0 in that hook
or whatever value you want obviously
well i mean
i wanted to like
randomize its value
just how i randomize
the items in the shop
thought i could do the same
with rerolls
you can write the entire sentence in one go
it doesnt look good
it's less annoying
yeah you can just randomize G.GAME.current_round.reroll_cost in that hook
so i hook that instead?
no, in that same hook replace all the cost stuff for that
local original_calculate_reroll_cost = calculate_reroll_cost
function calculate_reroll_cost(...)
local cost = original_calculate_reroll_cost(...)
if next(SMODS.find_card("j_tngt_dealmaker")) then
G.GAME.current_round.reroll_cost = pseudorandom('dealmaker_reroll', 1, G.GAME.current_round.reroll_cost + 100)
end
return cost
end
i was just typing it out
thanks
can i do this in real time?
no idea
local cost_dt = 0
local oldgameupdate = Game.update
function Game:update(dt)
local g = oldgameupdate(self, dt)
if G.shop and G.jokers and next(SMODS.find_card("j_tngt_dealmaker")) then
cost_dt = cost_dt + dt
if cost_dt > 0.2 then
cost_dt = cost_dt - 0.2
for i, v in ipairs({G.shop_jokers, G.shop_vouchers, G.shop_booster}) do
for ii, vv in ipairs(v.cards) do
vv:set_cost()
end
end
end
end
return g
end
i have this for the joker itself
looked at the code, yes you can
sure
should i put this code to the deck too
that code is only in the joker data rn
i mean i dont know how your code is structured or what you want to do
anyone who understands why Thunk wrote it like this? (it's how the Ox determines the most played hand)
if G.GAME.blind:get_type() == 'Boss' then
local _handname, _played, _order = 'High Card', -1, 100
for k, v in pairs(G.GAME.hands) do
if v.played > _played or (v.played == _played and _order > v.order) then
_played = v.played
_handname = k
end
end
G.GAME.current_round.most_played_poker_hand = _handname
end
you mean the order part?
yea
If you got hands with equal plays I think it takes the highest one?
he probably wanted to give you the hand with the lowest order if tied but he either forgot or removed it
wait isn't the ordering from pairs undefined btw
yes
oh so in case of a tie it's just... random
Isn't order called to prevent that?
no _order never gets redefined
yeah and also seems device dependent
oh
the order would solve that
Yeah, okay. Funny

using hand_chips * mult means for blinds that cap score like the tax, it triggers as true every hand because the chips and mult are above the blind but is then capped later
is there a way to work around that
lemme see
local cost_dt = 0
local oldgameupdate = Game.update
function Game:update(dt)
local g = oldgameupdate(self, dt)
if G.shop and G.GAME.current_round.reroll_cost and next(SMODS.find_card("j_tngt_dealmaker")) then
cost_dt = cost_dt + dt
if cost_dt > 0.2 then
cost_dt = cost_dt - 0.2
for i, v in ipairs({G.GAME.current_round.reroll_cost}) do
for ii, vv in ipairs(v.cards) do
vv:set_cost()
end
end
end
end
return g
end
that doesnt make sense
reroll only
ok i’ve made my new suit give mult instead of chips, how do i change the ability box to display “+X mult” instead of “+X chips”?
local cost_dt = 0
local oldgameupdate = Game.update
function Game:update(dt)
local g = oldgameupdate(self, dt)
if G.shop and next(SMODS.find_card("j_tngt_dealmaker")) then
cost_dt = cost_dt + dt
if cost_dt > 0.2 then
cost_dt = 0
G.GAME.current_round.reroll_cost = pseudorandom('dealmaker_reroll', 1, G.GAME.current_round.reroll_cost + 100)
end
end
return g
end
call G.GAME.blind:cry_cap_score(hand_chips * mult)
does find_card check every card area
this sounds more nice
thanks
every joker-type area
so consumables and vouchers too i think
how do i look for a particular consumable
ah alright
so can i SMODS.find_card('c_temperance') and get away with it
i think so
ill just test
but its a try and find out moment
idk how check for unlock works but doesnt it only check when it's called
i think it checks quite often
Pro coding tip if you got a bool check that goes if .. return true else return false you can just shorten it to one line, going return next(SMODS.find_card...
ooh fair
Anybody know how to make custom rarities for Jokers? Specifically for the shop.
Thanks!
probably fairly obvious and simple answer to this question: how do i make a joker using a probability based event like business card? when i look at the code it uses pseudorandom with the name of the joker, but how can i define my own probability like this (if i need to)?
pseudorandom takes any string seed you want the only important thing is that it's unique so it doesn't conflict with other pseudorandom calls
BUT there's a new way to do probabilities that is simpler and more compatible with other mods, example here:
https://github.com/nh6574/VanillaRemade/blob/a214d81d3816eb239d3c9e4d2aa6386807d83503/src/jokers.lua#L1057
(also I recommend vanillaremade to look at vanilla code)
k thanks ill look into that
rough full ver edward robinson balatro theme is this any good
when was this created?
i may change my random calls to this
last smods release
ah
also people are working on a bunch of cool stuff with this so you defo should
or it wont be compatible
okay cool ill migrate it in my next commit
let me finish this joker and ill comb through and change stuffs
there's documentation in the last release notes
okay cool
right now im scratching my head at something
i need to see all of the unscored cards in my hand
in a played hand
i mean
i was thinking of iterating over played hand AND scored hand to see if they match up then putting them in a different table?
yeah, theres a helper for that SMODS.in_scoring(card, context.scoring_hand)
oh shit
that makes it way easier
i was gonna do some nested for loop shenanegans
hi
still less mess in my code
🍪
alright
I've done a little bit of snooping around the files and I noticed the music files are all sped up, has anyone talked about this?
yes, the game slows them down. to save space i think?
the games song was originally composed as the faster version but localthunk slowed it down in game to fit the game more i think
@manic rune i need your help
hi
this code somehow leaks
i want it to be activated when theres that joker
but it just leaks into a jokerless run
ITS JUST TEXT THO
5 kb of UI code
hey atleast it worked
SO I'm trying to make a Tag that makes a mega pack of my custom boosters, but when I use it the game crashes and gives me this
functions/common_events.lua:2301: attempt to index local 'center' (a nil value)
key = "occ_tag",
loc_txt = {
name="Rite Tag",
text={
"Gives a free",
"{C:attention}Mega Occult Pack",
},
},
atlas = "occ_tag",
pos = {
x = 0,
y = 0
},
apply = function(self, tag, context)
if context.type == 'new_blind_choice' then
local lock = tag.ID
G.CONTROLLER.locks[lock] = true
tag:yep('+', G.C.PURPLE, function()
local booster = SMODS.create_card { key = 'p_tg_occocc_m_booster_1', area = G.play }
booster.T.x = G.play.T.x + G.play.T.w / 2 - G.CARD_W * 1.27 / 2
booster.T.y = G.play.T.y + G.play.T.h / 2 - G.CARD_H * 1.27 / 2
booster.T.w = G.CARD_W * 1.27
booster.T.h = G.CARD_H * 1.27
booster.cost = 0
booster.from_tag = true
G.FUNCS.use_card({ config = { ref_table = booster } })
booster:start_materialize()
G.CONTROLLER.locks[lock] = nil
return true
end)
tag.triggered = true
return true
end
end
}```
The code's built from the Vanilla Rebuild charm tag since the boosters work like arcana packs
THANK GOD
try using if G.jokers and next(SMODS.find_card("j_tngt_autocorrect")) then
if im not wrong, SMODS.find_card returns a table? 🤔
@red flower is SMODS.destroy_cards a new thing?
yes somewhat
holy shit theres alot of new functions
i need to like
learn these
all of these
does it work on jokers?
if it works on jokers this is huge
yes, it checks eternal too
can i see the booster code
and context.joker_type_destroyed??
oMGGGG
opirtjnmgoignjowerhwouigfwr
THIS FIXES A CARD I HAVE
name = "Occult Pack",
key = "occ_m_booster_1",
kind = "occult",
atlas = "occ_pack",
pos = {
x = 2,
y = 1
},
config = { extra = 7, choose = 2},
cost = 8,
weight = 1,
draw_hand = true,
unlocked = true,
discovered = true,
set = "Booster",
group_key = "occult_pack",
loc_txt = {
name="Mega Occult Pack",
text={
"Choose {C:attention}#1#{} of up to",
"{C:attention}#2#{C:spectral} Occult{} cards to",
"be used immediately",
},
},
loc_vars = function(self, info_queue, card)
return { vars = { card.config.center.config.choose, card.ability.extra } }
end,
ease_background_colour = function(self)
return ease_background_colour_blind(G.STATES.SPECTRAL_PACK)
end,
create_card = function(self, card, i)
return {
set = "occult",
area = G.pack_cards,
skip_materialize = true,
soulable = false
}
end
}```
error saying context is equal to nil on line 34?
and your prefix is tg?
can i see the full crash log?
wait what is this for
this is literally the first joker im making so bear with my incompetence
prefix is tg_occ
function calculate_individual_effect(card, context)
local ret = original_calculate_individual_effect(card, context)
if ret and G.jokers and next(SMODS.find_card("j_tngt_autocorrect")) then
if ret.mult then
ret.xmult = (ret.xmult or 1) * (1 + (ret.mult or 0)/100)
ret.mult = nil
if not ret.message then
ret.message = localize{type = 'variable', key = 'a_xmult', vars = {ret.xmult}}
ret.colour = G.C.MULT
end
end
end
return ret
end
this somehow doesnt do anything
did i fuck something up
it should be card.getting_sliced, not self.getting_sliced
checks if a non playing card is destroyed, it can prevent destruction too
yes
consumables are a joker-type
-# damn you only had to send a file 😭
but i dont like the name either
yknow thats smarter than chopping it up
i forget it shows the content of txts
bumpy
calculate seems to be getting the arguments in the wrong order
can you send the whole file?
yes
its SMODS.calculate_individual_effect
then it should be p_tg_occ_occ_m_booster_1
OH it adds the _ at the end of the prefix automatically this explains so much
thank you
i cant tell if this is a card sleeves problem or a me problem
i call SMODS.destroy_cards to wipe unscored cards but when i check my full deck card sleeves crashes
how would i use that in this scenario
im checking for a condition in one context
? like this
first off, dont use that ancient header, please use a metadata file instead
set a temporary flag like card.modprefix_destroyed = true and then check for that in the other context
oh okay
so just mark it for death pretty much
:3 did you forget how to hook in approximately 10 minutes
its 11 AM
you're using really old syntax, please use a newer example mod as a base
figured it out
yeah there is a lot of old syntax here
yeah thats mb i copied bbbalatro as a base since its the first one i found
local ref = SMODS.calculate_individual_effect
function SMODS:calculate_individual_effect(card, context)
local ret = ref(self, card, context)
--code in here...!!!
return ret
end
this works too
thank youu!!!!!
this is a tiny bit outdated but a better start point https://github.com/Steamodded/examples/blob/master/Mods/ExampleJokersMod/ModdedVanilla.lua
Steamodded example mods. Contribute to Steamodded/examples development by creating an account on GitHub.
@near heart
if context.destroy_card then
for k,v in ipairs(context.full_hand) do
if context.full_hand[k].marked_for_death then
SMODS.destroy_cards(context.full_hand[k])
end
end
end
end
like this?
that seems wrong
i can see that
-# i meant that to basil
hmm
if context.destroy_card and context.destroy_card.marked_for_death then
return { remove = true }
end
ohh okay
what context.destroy_card does is going through each and every individual card in your hand, played hand and such
and returning remove = true will mark them to be destroyed
i see
this is in the docs :3
sorry
etooo bleh
-# hi basil
it still does
are you sure
the same thing
you got all the arguments right??
..pretty sure
i feel like this is a card sleeves issue
threw a trash bag
let me see if card sleeves has an update
YOU DIDNT TYPE THIS OUT
WHEN
😭
[podqwgbjnpokuhqc
i thought YOU got it correct already...
IM LEANING
modding dev is the second funniest channel on this server i swear
leaning
okay now all of them are unused,,
shush
reminded me to disable it actually thanks
buddy
friend
pal
look at your local ret = ..., carefully
wtf are you doing
yes
five nights are freddy
what do i do
fuck freddy bro make like movie mike and go to sleep
ill FIX this first
wuh
local ret = ref(self, effect, scored_card, key, amount, from_edition)
thats all
i thought you knew how to hook already nxkoo 😭
yeah
😭
can i say the line
what line

ARE YOU SURE
local ret = ref(self, effect, scored_card, key, amount, from_edition)
fuck
wuh
sob
oh i know that pain
oh but also
i did it here before and i just didnt say shit
im pretty sure what you are doing for your code rn doesnt work
the hook works, but the code isnt correct
br
SMODS.calculate_individual_effect() always returns a bool value
so just need to fix it?
mhm
dfghjkoploiou9o8y7t6r57edrycghjlknml'lo0i98768t5e46we5sre3w4q23waesdfghjjklm.,/,l;opiou8y7tufydrxfzhuyt675r64e3w4q2awrextfcghvhjbjnj bnvbcxdfrtyuhbm bvghfdtesrdxcvbn.8y78tyufc sxs465t87y98upok;lm,
fortynitey
my forehead is imprinted with keyboard
how are you speaking in encryption
encryption.....inscr.... 
yes boss
nxkoo DIES in approximately 12 minutes, 30 seconds and 113 ms later.
what about the other 25 letters
WHAT
how many nanoseconds vro...
3
1
light sway on the horse's back
does this mean somethign
i would hate to be employed
can confirm as someone employed
