#💻・modding-dev
1 messages · Page 278 of 1
you probably should use SMODS.create_card, I just don't
thanks yeah i saw that code in card.lua for other jokers but something is trying to index center and it was crashing because of nil
guess i should just find the source of the crash instead of using SMODS.create_card
what does your current code look like for creating the card?
one second ill share it
totally written by me and nobody else btw
if #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.0,
func = (function()
local card = create_card('Tarot', G.consumeables, nil, nil, nil, nil, key, 'double')
card:add_to_deck()
G.consumeables:emplace(card)
G.GAME.consumeable_buffer = 0
return true
end
)}))
key is not nil
wait i think i might see it, bout to test it
yeah key is the card you're trying to force to be created
yeah im setting that up manually
Guess whaaaattt
found the problem
what did you get now
i needed this line before the call to G.E_MANAGER:add_event:
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
Is the key correct?
Ya
and for the mod ID, I use the prefix right?
that's what someone told me earlier
When does it happen?
As soon as I play the 20th High card hand
yeah so it should be c_prefix_cardkey
Show the code.
SMODS.Joker {
key = 'stellar_collapse',
loc_txt = {
name = 'Stellar Collapse',
text = {
"After {C:attention}#2# High Card{} hands,",
"collapses into {C:legendary}Singularity{}.",
"{C:inactive}(Currently {C:attention}#1#{C:inactive} hands played)",
}
},
config = { extra = { high_card_count = 0, high_card_limit = 20 } },
rarity = 2,
atlas = 'collapseatlas',
pos = { x = 0, y = 0 },
cost = 6,
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.high_card_count, card.ability.extra.high_card_limit } }
end,
calculate = function(self, card, context)
if context.before and context.scoring_name == "High Card" and not context.blueprint then
-- Increment count
card.ability.extra.high_card_count = card.ability.extra.high_card_count + 1
-- Check if it should transform
if card.ability.extra.high_card_count >= card.ability.extra.high_card_limit then
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
card:set_ability("j_LSingle_singular")
play_sound("CollapseBoom")
card:juice_up(0.3, 0.3)
return true
end,
}))
end
-- Normal progress message
return {
message = "Collapsing...",
colour = G.C.ATTENTION,
card = card
}
end
end
}
what is card:set_ability("j_LSingle_singular")
^^^
I was told to use that to make a joker transform into another (kinda like Ghost)
Hmm... SO what Would I do for turning it into another joker (i.e. destroying itself and spawning 'singuler')
Bruh my keyboard is on the fritz
What I said does work.
I wasn't saying it didn't work, I just wasn't aware the function did that
should this
-- Normal progress message return { message = "Collapsing...", colour = G.C.ATTENTION, card = card
be nested in an else? (I should really learn lua better IK)
Every time you play high card it's going to say Collapsing...
Well thats fine, since once it transforms it'll be a different joker
what is line 262 of your card.lua?
and also, did you start a new run before testing this
Your prefix is LSingle right?
idk
there's also the chance that trying to change a joker within itself causes some weird pointer issues
but I couldn't tell you
nope, I put it in one of my own jokers and it worked
although I didn't do it as part of the event manager
Could I see that?
works in the event manager too
this is all I have in the calculate function
if context.end_of_round then
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
card:set_ability("j_reverse_rekoj")
card:juice_up(0.3, 0.3)
return true
end,
}))
return {message = "test", colour = G.C.ATTENTION, card = card}
end
end```
did you perhaps
did you forget to start a new run the last time you tested it before the sound error?
question
so for a while I've had a system where I put all my special mod variables into their own table, so that I don't accidentally create a "unique_jokers" table that overlaps another mod
is this a good practice or would I be better off just changing it to be more like on the right
That... may have been the case
programmer art is insane
tonight's mod was brought to you by the letter 'B'
neater looking version of the second one
is there even any performance difference at all?
wait
WAIT
NO
IT CAN'T BE
Is it because the card it's trying to turn into was undiscovered
I assume the difference between individual prefixed variables and storing them in a table is just a single pointer operation every time you want to access it, unless you're indexing it with ['key']
i'm just referring to it like this
nvm it crashed even with the card discovered
shouldn't be? at least I don't think.
Emperor can create undiscovered tarots
I don't think you need to worry about performance issues unless you're deeply nesting loops, or making recursive functions
as a rule of thumb
okay
working again
just sound I needc help with
how do I specify the file location
I'm looking at the SMODS sound page
And I'm goofy
nvm
Okay... IDK what I've done wrong
I've specified the key and the path for my sounds
But it keeps crashing with the same error as before
screenshot the path and the audio
In the files?
yes
is it .ogg or is it .wav
.ogg
Show the code where you’re trying to use it
calculate = function(self, card, context)
if context.before and context.scoring_name == "High Card" and not context.blueprint then
-- Increment count
card.ability.extra.high_card_count = card.ability.extra.high_card_count + 1
play_sound('Stellar_Upgrade', 1, 0.7)
-- Check if it should transform
if card.ability.extra.high_card_count >= card.ability.extra.high_card_limit then
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
card:set_ability("j_LSingle_singular")
play_sound('Stellar_Transform', 1, 0.7)
card:juice_up(0.3, 0.3)
return true
end,
}))
end
-- Normal progress message
return {
message = "Collapsing...",
colour = G.C.ATTENTION,
card = card
}
end
end
}
I intially had the upgrade sound in the return, but I just tried moving it out to see if that'd change it
You need your mod prefix on the sound key
Is there a scoring_hand cardarea to check for scoring cards? I can't remember
G.play
That's all the cards though, right? I just want the ones that actually score
Ah, I was using G.hand.highlighted. Forgot to change it 🤦♂️
Ok actually, that brings me to my next question. How do I check for the scoring cards when they are played in a blind? This code doesn't seem to be working. It's supposed to add the scored ranks to a table, but I don't think the cards are actually in G.play at the point that press_play runs:
press_play = function(self)
for k, v in pairs(G.play.cards) do
if not SMODS.has_no_rank(v) then
G.GAME.blind.config.blind.ranks_played[v:get_id()] = true
end
end
end,
-- Debuff ranks registered in ranks_played when a hand is drawn
drawn_to_hand = function(self)
for k, v in pairs(G.playing_cards) do
if not SMODS.has_no_rank(v) then
if G.GAME.blind.config.blind.ranks_played[v:get_id()] then
v:set_debuff(true)
end
end
end
end,
-- Set the ranks_played table to an empty table for if the boss shows back up
defeat = function(self)
G.GAME.blind.config.blind.ranks_played = {}
end,
}
I believe you can use the new blind calculate functions to do this
Oh that's a thing? I didn't see it on the Wiki. That sounds like what I need
tbf I was only looking in the Blind section
Uh, is the calculate function just calculate for a blind with the same parameters and contexts as other objects?
Made multiple Shortcuts stack
Ah, I think I found it on the repo.
there really should be a mod that just makes all duplicate jokers stack some way
Hey guys, last thing. My joker plays a sound when a high card is played, and also has a sound for when it transforms into another joker. Problem is, when the 20th High card hand is played, both sounds play, and I only want the transform sound. any tips?
here is the code
calculate = function(self, card, context)
if context.before and context.scoring_name == "High Card" and not context.blueprint then
-- Increment count
card.ability.extra.high_card_count = card.ability.extra.high_card_count + 1
-- Check if it should transform
if card.ability.extra.high_card_count >= card.ability.extra.high_card_limit then
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
sound ='LSingle_StellarTransform',
func = function()
card:set_ability("j_LSingle_singular")
card:juice_up(0.3, 0.3)
return true
end,
}))
end
-- Normal progress message
return {
message = "Collapsing...",
sound = 'LSingle_StellarUpgrade',
colour = G.C.ATTENTION,
card = card
}
end
end
}
You should put an if around the 2nd one checking that high_card_count is less than high_card_limit
Okay, the upgrade sound doens't play anymore, but the upgrade sound doesn't play either. Not sure why.
NVM, fixxed
Bells & Whistles
can i change the ingame currency ($) with an image?
Good luck
Are there any mods that have a functionality added that allow multiple different enhancements on a single card? If it's a lot of custom I might just keep the idea on the backburner
I'm pretty sure Steamodded has quantum enhancements built in.
Oh shit, sweet. For editions or enhancements too?
what's your specific idea, btw?
Just a joker that allows "quantum enhancements" as you called it for Aces
Or not you
But Somethingcom
quantum enhancements allow for jokers to have effects like 'all stone cards count as copper cards'. It also works for ranks and suits, but you have to be prepared to deal with some jank, as you can't check for rank or suit the normal way in the check enhancement context for quantum enhancements
Is there a mod that makes this mess of jokers easier to sort through?
there is no mod that makes the gameplay of cryptid reasonable, no
Yeah this makes sense, having a stone wild card is a paradox lol
Jank is to be expected
stone wild cards are just wild cards with 50 chips makes sense to me
i dunno about that
-# try baliatro today
But like what I was think is like, stacking enhancements and stuff like that. So like if you use a devil on a glass card, it becomes a gold card and a glass card, rather than converting
damn, they're learning. they're shilling their mod now 😛
And you could stack another
Thanks
You'd have to implement a custom system for that, I reckon. It's an interesting idea, but I suspect it'd be quite some refactoring code
Hmm. Well maybe once I know a little more I'll throw my hat at it. Thanks for the help guys
Wait a minute that would be a nightmare visually, enhancements are a custom png not a layer thing
Yeah maybe this is too much of a pipe dream
is it blueprint compatible too?
Wait a min I'm just talkin out my ass, ah well whatever I need sleep
is there a way to make a seal that prevents flipping by boss blinds?
Im trying to make it so my joker copies to the left and not the right, but it still says its compat with the one on the right.
heres the jokers code
hook Blind:stay_flipped to check for your seal on the card being evaluated
👍
i honestly dont know what to do
if G.jokers.cards[i] == self then self is a center
if G.jokers.cards[i] == card then
similarly other_joker ~= card
good morning everyone
card.ability.name = "Blueprint"
return {
vars = {card.ability.name == "Blueprint"},
main_end = main_end
}
end,```
this is probably every kind of wrong
Hi :3
that works like normal blueprint
hi 🥕
first of all
you set your card's ability name to blueprint
that will trigger all the vanilla code
to consider your card a blueprint
no fucking clue
also you set your card ability name to blueprint and then set vars to a comparison for the same value
which is literally just true
the main_end btw
there is no case in which vars = {card.ability.name == "Blueprint"}, isn't equivalent to vars = {true}
which makes me think there's a lot of copy pasting going on here that you don't understand the purpose of
I'm pretty sure this is what you are looking for ```lua
loc_vars = function(self,info_queue,card)
card.ability.blueprint_compat_ui = card.ability.blueprint_compat_ui or ''; card.ability.blueprint_compat_check = nil
return {
main_end = (card.area and card.area == G.jokers) and {
{n=G.UIT.C, config={align = "bm", minh = 0.4}, nodes={
{n=G.UIT.C, config={ref_table = card, align = "m", colour = G.C.JOKER_GREY, r = 0.05, padding = 0.06, func = 'blueprint_compat'}, nodes={
{n=G.UIT.T, config={ref_table = card.ability, ref_value = 'blueprint_compat_ui',colour = G.C.UI.TEXT_LIGHT, scale = 0.32*0.8}},
}}
}}
} or nil
}
end,
yup, main_start is the other side of that same coin
then where is main_middle
interesting, i might abuse this
How do I make it so that only a certain suit can have a certain rank? Is that even possible?
(I wanna make musical ranks but only have them be able to have Bells and Whistles as their suit)
you don't
your code is very far from correct
you're still checking for self in update instead of card
second, there are two incompatibles in your box which makes me think that you're still somehow tripping vanilla code
ive been making blinds, and i wonder if theres an equivalent to card.ability to store data that can be used and isn't reset whenever you re-enter the run?
G.GAME.blind
Update should be like this. ```lua
update = function(self, card, context)
local other_joker = nil
if G.STAGE == G.STAGES.RUN then
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] == card then other_joker = G.jokers.cards[i-1] end
end
if other_joker and other_joker ~= self and other_joker.config.center.blueprint_compat then
card.ability.blueprint_compat = 'compatible'
else
card.ability.blueprint_compat = 'incompatible'
end
end
end
i could've swore i used that but it still resets, thanks
It works for me.
nope! ❤️
...actually?
but it's still checking a card against a center
Actually. No vanilla blind stores information. I'm doing it by setting current.round variables for kino, atm
-# fuck
that's incorrect though Ice
G.GAME.blind is your intended "card" for the current blind
look at stuff like fish, which store their state vars in self (which in vanilla is G.GAME.blind)
there still is two for some reason, even i dont see me calling for any of blueprints needs
i tried storing into self.config before
of course it kinda starts breaking apart if you want multiple blinds active at the same time
I think I've misinterpreted Aiko, then. They're using the debuff table to store information, and that it didn't save/load properly
never EVER EVER EVER EVER EVER modify ANYTHING on self in an SMODS.GameObject
I think i should edit
card.ability.blueprint_compat = 'compatible'
else
card.ability.blueprint_compat = 'incompatible'
end
im sorry 💔
but idk what to edit but it gives me the vibe sometghings wrong
I assume it's possible with a bunch of workarounds, and presumably hooks or patches, but I'm not sure which one I should do
(As in, whether I should do hooks or patches or none at all(
sudden idea: blueprint update() could be eliminated if joker reordering evaluated a context (event driven rather than looping the array of jokers for every blueprint you own)
Hmm, fish doesn't have any variables it needs to store right?
it does
when a hand is drawn you can't differentiate in a vanilla blind between cards drawn as a result of a discard and cards drawn as a result of a hand played
so fish stores a prepped flag every time you play a hand to signal that cards drawn until the next discard are supposed to be drawn face down
yes, but that's unflagged the moment the cards are drawn, no?
And no saves can happen during that state, so it never needs to save it's state
saved into G.GAME.blind
and it needs to save/load the joker that is being debuffed to function correctly
yes, being debuffed is an attribute of the joker but crimson heart needs to understand which joker is being debuffed as it cannot pick the same one twice in arow
Crimson Heart doesn't store the debuffed card, no? I though it flagged a card as debuffed on the card object, and then checks if there is currently a card being debuffed by it
it does
it absolutely stores it
listen i had to reimplement every vanilla blind as an SMODS.Blind in baliatro, i know exactly how much state is being stored
haha, I believe you, no worries, I'm just not sure how it saves it then? Is it just because the data that you tie directly to the object gets saved?
everything under G.GAME is being saved
simple as that really
saving a run saves the G.GAME table and every cardarea under G
wait, actually?? 😭
is it for ur uhh deal with the devil or smt
I've been operating under a very wrong understanding of the save system then! God, that's good to have someone correct me on
im glad i learned something from asking a dumb question :3
it is for the deal with the devil
save system is wack
i also had to hook every blind hook
dear god
I thought it reset instances of each object based on their configs, and only saved specific data, but I guess it makes sense that it can save then. Do you know if the save system interacts strangely with tables, then? Because for my custom blinds, I stored information in the debuff table, which didn't seem to save
i need to put my mod's name in my nickname again
i managed to do this (i cant figure out how to get blinds to reset from the second boss and not the first)
there we go
i have no idea what the debuff table is if i'm being honest
fused all the four names together
the most I've done is putting L Corp. Myst as my nickname once
that helps a lot
I'll mess around a bit more with it with this knowledge in mind
every single project moon agent in existence when they hear a game got a pm-related mod:
Ante always increases after beating a Boss Blind, regardless of where it is on the blind deck
how do you edit the logo appearing on the main menu
onto what
Blind:save() is very conservatively implemented
so, would there be a way to reset from the fourth blind, unless I made the third blind draw from a set of non-boss blinds?
okay i take back everything @hushed field i'm stupid lol
but also this does raise an interesting question
i might contribute some blind state saving to SMODS to sort it
i actually think there might be vanilla blind bugs hidden here if i looked deeper
what question!!!!
blud said that and never specified the question 💔
seems like most of the blind data actually ends up being saved in card abilities
but also
Hahaha, good to know. I have no clue how the save system works so if you tell me something does save, I'll assume I've just implemented things wrong 😋
does that mean theres no consistent way to save stuff for a blind rn?
unless through G.GAME, but that probably requires everything to be reset whenever you face the blind again
so here's the thing right
mhm
-# god damn it
Easiest solve is just add the base info onto the blind, and have it create a table for it in G.GAME.current_round that it'll alter and check
save to G.GAME.blind instead and hook to save funcs
the best thing you can do is you can do like G.GAME[G.GAME.blind.config.blind.key] = {my_state_var1 = 'foo'}
store it in a keyed table under G.GAME
i have no clue where the save funcs in question would be :3
it is guaranteed to save
Blind:save and Blind:load
just make sure you hook set_blind to reset that table
-# oh fuck that exists?
much simpler than overriding Blind:save and Blind:load imo
girl
man
Oh, that brings up a question on my end, what's the logic between what is stored in G.GAME[x] vs G.GAME.current_round[x]?
wouldnt G.GAME.current_round be more convenient in this case?
technically yes
since theres no need to reset stuff afterwards in set_blind
boy
i'll absolutely hate you when i have to patch around it for deals with the devil but you can do it
;3
well however you save your blinds you can't really save specific cards
i guess i will do your approach then, i will try my best to avoid conflicting other mods
you still need flags on the cards instead
just set stuff in card.ability
card.ability is saved as-is
it's saved so as-is that if a function ends up in card.ability the game crashes on save
Wait, really? That'd imply I should have some bugs that I don't seem to be having. Or I've just fully missed them so far
so there is kind of a caveat
it might only be resetting specific keys
i already did that, but i thought flags r a different concept
as most things in balatro, it's not cleanly reset
it's literally resetting each key one by one 🙂
Ofc hahaha
swag
balatro is a if it works it works game
so you'd still need reset logic bepis
i wonder why "core" is dark
cry_ dansgame
:3
truly a
moment indeed
this should do the work righte
yes
nice
nice
nice
patching into blind:get_type doesnt increase the ante, but it still resets to small blind
Im suffering the consequences of making a detailed joker again
All the vanilla blind stuff is very hard coded iirc
I might do a blind update for smods to allow for a lot more options
SAAAAAAAAANS??????
How do you add a custom drawstep?
baliatro already adds a bunch of extra triggers for blinds so you can do more
i wanted to contribute that to SMODS too
but i'm waiting for aure to knock out blind contexts and so i can understand what he's refactoring there
are blinds receiving even more contexts than the last update gave 'm?
so far blind calculate has been very friendly to beginners like me
i think blinds don't have any new contexts
yeah I meant calc support generally
oh yeah, baliame, how does context.modify_scoring_hand work?
its not documented so idk how to get it workin
i assume whatever calcs we have right now correspond with the blind functionality (recalc_debuff, set_blind, press_play, etc.)
so we're probably not getting more calcs unless we get more blind hooks
i do intend to add more blind hooks
no idea
man, i sure love undocumented features
go on, im listening
it runs on each G.play card, and you can return {add_to_hand = true/false, remove_from_hand = true/false} to make that card storing/not scoring
but it seems like it only runs on cards in play so you can't do fun stuff like i did with splatter
-# try baliatro on the next day ending with 'y'
mmmm
quite possibly one of the strongest jokers in my set
it is
scoring 10 cards at most is insane lol
and i imagine those scored cards in hand also function as cards in hand?
like, steel cards would still work
yes, those cards are both scored and held in hand
jesus
not as big of an advantage as it sounds
gold ticket would go crazy
it's an upgraded joker, it's quite hard to force specific upgraded jokers
it's a postcard effect
upgrades a compatible joker
inspired by bazaar, tbh
only common jokers have upgrade paths though
Yeah I think it only runs on cards you play
It’s easy to add cards in hand to scoring though
some of them are just strong
how would u do this 🤔
some of them can really go off the rails
oh, so like, joker evolution?
Was testing a new Joker, and... guessed the 1 in a 1000 chance first try...
(The min and max update dynamically based on your guesses)
cavendish broke
surely when you get a 1 in 1000 first try you have to assume your code is wrong
baliame, i thought my gacha code broke too
like, i got the 0.3% twice in a row
but turned out its just the seed i got is cracked as hell
I've had a 1/4 chance trigger 16 times in a row during testing, and spent too much time bugfixing something that wasn't broken
💔
you always have insane luck when you are playtesting your mod
# Polydactyly
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'before'
pattern = '''
-- TARGET: adding to hand effects
'''
payload = '''
local ortalab_poly_jokers = SMODS.find_card('j_ortalab_polydactyly')
if next(ortalab_poly_jokers) and (next(poker_hands['Straight']) or next(poker_hands['Flush'])) then
for i=1, ortalab_poly_jokers[1].ability.extra.cards do
table.insert(final_scoring_hand, G.hand.cards[i])
end
SMODS.calculate_effect({message = localize('ortalab_polydactyly')}, ortalab_poly_jokers[1])
end
'''
This is the patch I have that does it in ortalab
awww, we need a patch for that? 💔
Does anyone know a mod that can choose jokers before starting a game? I want to use it for testing several jokers at once
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '-- TARGET: adding to hand effects'
position = 'after'
payload = '''
local extra_cards = 0
for i, joker in ipairs(G.jokers.cards) do
if not joker.debuff and joker.config.center.additional_scoring_cards and type(joker.config.center.additional_scoring_cards) == 'function' then
extra_cards = extra_cards + joker.config.center:additional_scoring_cards(joker)
end
end
extra_cards = math.min(extra_cards, #G.hand.cards)
for i = 1, extra_cards do
table.insert(final_scoring_hand, G.hand.cards[i])
end
'''
match_indent = true```
generic additional_scoring_cards center implementation
also lmao i remember i marked this experimental and then it just worked perfectly first try
i felt like the game might have something to say about G.hand cards scoring, nope, it's all okay
Ah, yeah code was bugged
called it
How does one make it so something only triggers once no matter how many copys of the joker there are?
Yeah, cards that are “scored” dont actually care where they are
It means making hand cards score is remarkably easy
which one
6
6
1
specific table
make a global variable in like G.GAME
like G.GAME.your_joker_triggered and then like ```lua
if not G.GAME.your_joker_triggered and other_conditions then
G.GAME.your_joker_triggered = true
-- do the stuff
end
one full page yall
B B B B B bb b
B indeed...
alas there are actually 17 jokers but two of them are on Commented for the Forseeable Future because they're blueprints and dont work with retriggers
I need to figure out how I want the synergy messages to work 🤔 the current system is super annoying.
As I'm typing this I'm realizing I can just limit it to one message per joker and just have it display an xN thing behind it
Oh ugh I also still need to do the config UI change because I have too many config options at this point
Or put your mod in the wiki
I think oinite just added a localization parses, so it really is dead easy to add your stuff to the wiki now
Oh? How does that work
i need a sanity check does anyone know how to change the rank of a card
SMODS.change_base
assert(SMODS.change_base(card2, nil, "9"))
this crashes
is that supposed to crash
What's the crash?
I haven't used it yet, myself, so not entirely sure. They've posted about it in the wiki discord though!
I'm not sure why that'd fail tbh
Unless card2 isn't a playing card
card2 should be a playing card
for index, card2 in ipairs(context.full_hand) do
tis defined here
It looks like change_base returns the card, and in your case the card is somehow nil
But not before it tries to change the rank
So I'm not sure what's going on
That's odd
I just referenced the strength code to make a utility function that does it for me (argument is a number from 2-14) ```lua
function Card:set_rank(new_rank)
local suit_prefix = string.sub(self.base.suit, 1, 1)..'_'
local rank_suffix = new_rank
if rank_suffix < 10 then rank_suffix = tostring(rank_suffix)
elseif rank_suffix == 10 then rank_suffix = 'T'
elseif rank_suffix == 11 then rank_suffix = 'J'
elseif rank_suffix == 12 then rank_suffix = 'Q'
elseif rank_suffix == 13 then rank_suffix = 'K'
elseif rank_suffix == 14 then rank_suffix = 'A'
end
self:set_base(G.P_CARDS[suit_prefix..rank_suffix])
end
ik
oh but also, whats "T"?
i just noticed that
I think for some reason the ten has like a letter
that was just in the strength code
💔


Has anyone here added a custom context with automatic calculation
D_9
D_10
D_J
D_Q
D_K
D_A
i mean, i guess its to make it consistent
oh cuz it'd be one letter longer than the others
the horror
i bet with 100% certainty that either localthunk wanted a nice list or it actually matters in some horrid spaghetti code
ig also explain why ace is id 14
its to make it higher than kings
i think 1 is stone cards?
¯_(ツ)_/¯
if you just do SMODS.calculate_context({ insert table here }) it will do it all for you
nop
I don’t think it handles animations automatically
it just doesn't get used
ig there's straight up no id 1
vampire:
wdym
I don’t think that’s true
Stone Cards are negative
@rain slate This (although that version shouldn’t have any animations anyways)
I tried to fix it and add an animation (when I tied it to a Joker) but I got nothing
It is possible for Stone Cards to form a Straight
Although I’m not sure if that’s a vanilla bug or a SMODS bug
I could only find reports of it in modded versions of the game
Tested what
i just converted a straight into stones with tower
But if those IDs are sequential they could be Straights I think
Interesting
it doesnt go below zero
how is this not a rare 💔
it's effectively just +4 hands/discards with a tossup on whether you actually get hands or discards
i mean technically burglar turns 3 discards into 3 hands and it's a common
thats an uncommon
this is somewhat more flexible but at the end of the day it's an economy joker on par with golden joker
not a common 😭
right, uncommon, w/e
and thats exactly my point
this seems better than burglar by a long (?) i forgot the idiom
ig i can just knock it down to +2/+1
here's my counter argument
having +1 hand is one of the weakest stats in the entire game
i will assume that playing 1 hand -> +1 discard, using 1 discard -> +1 hand
can you imagine how broken that would be if this hits High Card
not many jokers scale well off of hands played, the value of a leftover hand is $1
lmao mail-in rebate already effectively breaks the game without any other joker
no
to-do list hitting high card is a 1 in 10 and otherwise it's wasting a joker slot for the most part
play 1 card, +$4
discard 1 card to get another +1 hand
repeat until you go through your entire deck, then win the round
play 1 hand -> +1 discard -1 hand
and even if you high-roll it, to-do list converts $1 into $4 which is on par with a gold seal
i'm sorry bepis but you're way off on the balance of this card, it's actually really weak for an uncommon
i could also argue that it goes really well with hanging chad + lucky cards/cards with gold seal too
theres nothing keeping you from just playing your entire deck
there is a lot that keeps you from playing your entire deck
or hanging chad + gold ticket
with this joker playing 1 hand costs you 2 hands
i thought it meant playing a hand gives you a discard, and vice versa
even when i have 9 hands here in reality i really have 5 if i dont discard further
if its playing a hand -> reduces 1 hand, increases 1 discard then yeah, ig its fine
i am on blue deck
that is a bad image
imagine 8 hands instead and 4 hands in reality if i dont discard further
my current use for this joker is uhhh ... fishing for royal flush and failing once in every 15 blinds
To Do L
i won gold stake with that before, helped me a lot with econ surprisingly
I’m just making a joke at the image
to do list more like to il etpaper
unironically i cant believe that the joker named "Balancing Act" is the only joker that ive posted here that has a balance discussion spawn from it
Bepis won’t let me disrespect pis
i honestly find it funny that we'd ever bring up a joker as bad as to do list in a conversation about balance when mail-in rebate exists
-# that was a joke, please dontt ake it seriously eofam
him? off*
Actually no that’s not how I wrote it
him i guess off*
yeah but LIKE
the synergy with that rolling on High Card + a high number of hands is insane, think about it ❤️
potential joker
ing
:( i will protect this joker even when im killed for it
my potential boy WILL get a W
you say this but ive failed my last three todolist + balancingact test runs due to my greed
on white stake too. im a good player trus t me
death by 100 dollars and 50% of the required blind score
1 in 10 (12?) to hit a "good" hand, and you gain $3 per extra hand played effectively, to do list is actual garbage and someone is doing cryptid levels of broken shit for it to have a measurable effect on balance
Oh I thought it was 3
i''ve already accounted for losing $1 because you played a hand
It's not terrible IF you actually hit a good hand
i hit rebate more often when i throw it in haphazardly as a negative and accidentally play the right hand without looking at it
More money is always a good thing
the only good hand is high card, maybe an argument can be made for pair
at best it's a 1 in 6
i have an idea: i want my jokers to have effects that are outside scoring purposes too, but at the same time, i dont want to abuse the page mechanic too much:
do you think its a good idea to convert this description to something else when you are not in a blind, and converts it back when you are? but at the same time, it will make it so you dont actually know its scoring effects outside blinds, so maybe its not a solution
in that round you earn, let's say you have burglar, $21 extra. mail-in rebate with 4 discards is effortlessly $10 per round played
i've unironically forgotten about the discard and hand tags
...eh, i will just add another description page for that one
not much
Fixed the code validating function for this joker
skipping a blind is literally never a good play (except maybe a select few tags in ante 1)
you never need to worry about discard/hand tag balance
the thing is, you can't really choose which one you get during a run
and you do have more hands than discards to start with without any other jokers
so maybe theres something to optimize it?
sure but it's not relevant, this is about whether it's even worth discussing the balance and we are talking about two jokers of equal rarity
oh i was wondering why i didnt get any discards for my hand, i literally am out of juice and need to discard
impressive
they're both heavily affected by rng so I think they're pretty similar
i feel like how balanced a joker is should be based on whether if you find it in a shop, do you want to buy it or not
i personally usually buy to-do list when it appears for e-con, not sure about others' opinion on that though
i would buy a lot more things over to do list
mail-in rebate is arguably lighter affected by RNG because it naturally weighs towards giving more money (idol card selection logic)
unironically i would buy golden over to do list
fair, its more consistent
golden joker is far more reliable
but UNSEEDED balatro runs dont give you the option to just freely choose what joker you will pick, i still think to-do list is a solid option for e-con
to-do list risks being money negative
it may be the correct play to not even buy it
to do list is awful for its cost imo
usually i try to get a lot of interest before even buying anything
i'd buy golden joker before ante 3 but not to do list
doubt it, dont you get to see the hand to-do list is choosing before buying it?
if the hand is what you are looking for, you can buy it, play that hand, and sell it, isnt that a profit in which case
most of the time it really doesnt do that
and okay to do list is like 4 dollars
no shenanigans i have 4 hands 3 discards
Good schmorning chat
to do list basically gives 3 dollars profit due to hands
yeah but if it hits a good hand (high card, pairs)
in the next blind, you can get a considerable amount of money
you've gotta sacrifice hands for a chance of hitting the card you want to then discard it, if you have your deck fixed then yeah, it's way better late game
i have to be missing something incredibly fucking obvious. This joker checks how many pairs you have in hand, then gives 50 chips for each. Except #_ranks is always empty.
if you have 3 discards, you will statistically gain at least $5 per round with $0 invested, even a "whiff" is not as brutal as to do list hitting straight flush
for those who wonder if stickers can go on other cards, yes
i'm sorry, you can't close the gap with whatever RNG arguments you have
(I know that there's a neater way to write the check if the item exists, but I thought I'd gotten the syntax wrong, so resorted to this, to find it that wasn't the issue)
to do list on average does nothing for several rounds while mail in rebate generates money for investing resources that otherwise don't generate money
there's a vanilla function for checking what hands are in a certain list of cards
evaluate_poker_hand i believe
or smt like that
nop
-3 = -$3 at payout
3 high cards/pairs = $12, if you havent reached the max limit of uhhhhh forgot the term ($5 = +1$), its $14
=> $10
and nothing's preventing u from just not buying it when it hits a bad hand anyways, so u can just ignore it when it hits a bad hand in shop, and buy it when it hits a good one
That wouldn't return a potential 3 number of pairs, right? As this checks for cards held in hand. Or does it return information for every potential pair in a table?
you lose all 4 hands from playing the three high cards
right, so its $10
that functions counts only unique pairs
so if you have 4 2s it'd only be one pair
you get an extra $13 is the one round highroll you might get on an average 4 hands deck. this is the only case where it has an immediate positive RoI (it appears in the shop with high card). it's so bad.
and it definitely works with cards held in hand
my code, I think, should to. But if you have a 2,2,3,3,5,5,K you'd be holding in hand, would it return the fact that there are 3 separate pairs in hand present?
u didnt account for interest
Yeah it does
You can look at pocket pair in paperback as a reference
aint it 1 dollars interest
2
still, baffled by why that array doesn't store anything. I feel like I was going crazy, checking that. I must be missing some super simple lua syntax, somewhere
you lose the $4 by buying it
Thanks, srockw! I'll solve it that way
you also gain $2 from selling it though 🤔
ah pain
you lose $4 from buying it, you lose $4 from hand money, you gain $12 if its highcard, gain $1 interest, gain $2 sell
the problem was you were using ipairs to loop thru it
you should've used pairs
Good morning schdilly
that's $7 profit
again - its $2 interest
so you sell it during the blind
you are gaining $12 from doing the high card
that is already after losing money from buying
You can just reuse the function that computes Poker hands
oh, true
it's $12 not $16
its still hitting the $2 interest mark if you are selling it after using the 3 hands though
can we please say out loud that to-do list is a terrible joker that has one super meh highroll which is so bad you'd still be better off economically finding a hermit and it's literally not worth discussing it from a balance perspective
.......................
i
I'd say to-do list is not as bad as you make it sound
was testing a blind
it's always the mod testing runs
Sure there are better options, but that doesn't mean it's worthless
Me testing a Blind and drawing 4OAK
ah yeah ofc. I got distracted by #_ranks always printing 0, haha
also to do list sucks for the nontrivial reason that if you play a secret hand it gets added to the pool iirc
which does lower the chances if you have those kinds of builds
yeah okay it does do that
why .
what do you mean
why would you use to-do list when you reached a point when you unlocked a secret hand though, thats the question
true
I don't like to-do list that much but I think it's acceptable
but think about the HIGHROLLS
with the MATADOR
when you land it right before a suit debuffing blind omg
To all of you who helped me. Thank you. I can sleep now that this silly mod is done.
lets go gambling with the J 10 9 8 7
its already as inconsistent as it is, 1 in 10 for just $10 💔
you could argue that oops all 6s increases the chances of which, but lucky cards exist
think. of the oops potentia
1 in 2*X mayhaps?
aww youve already thought of the oops potential
should you?
idk i think i've done decentish with balancing
it's basically business card
it's $1 per card played for 4 not that good ranks
vs business card being $1 per card played for 3 good ranks
just that i end up picking this and get like 15 dollars in one hand in some round and go "waoh..."
it is much better on abandoned
yeah but you expect larger dry spells than with business card so shrug
do we like the idea of unique small/big blinds chat
not below gold stake lol
thanks ben for obelisk 2
obelisk is a very good joker though
mostly asking because i need to find a place to add those birbs in :3
its a very fragile enemy in hsr, but i think it would be fun to encounter fodder enemies every once in a while for small blinds
bepis, develop my biome system for me so that you can have persistent effects in the blind that work as the fodder enemies
biome what
honestly, i feel like most obvious design gaps are filled by the vanilla jokers, so if you try to not go too out there with your designs, you'll definitely run into that quite often
dude
idk if it's the quality of your images but the small text feels too small
I wanna set up a biome system that adds modifiers to antes, as a separate mod from kino, though
might be the CRT effect
you can just make flavor text inactive so that it wont look off even when its big
once I actually start on that mod I'll definitely check your pact code, baliame, haha
...oh
they're more readable in full
im kinda
if you pull this off i will add compatibility with the Scoundrel mod i plan on making that will. replace every single system the game has
planning on doing smt similiar to that
but i havent thought about modifiers to antes themselves though
it's literally just a complete hooking of all vanilla blind stuff, i should package it as a library mod or something
so maybe our ideas are not the same :3
theres no way 1x game speed is actually this slow wtf
what function does it run when a new run is started
haha, damn, did nothing break with the latest smods version??
definitely not :start_run(), since that runs when you re-enter an already existing run too
definitely start_run
just add a check for not saveTable if you're patching
start_run, not saveTable, yeah
ok so it seems that when using G.GAME.dollars in calculate, it uses whatever value the money was at when scoring began. Is there any way to pull the current value of G.GAME.dollars?
using an event
no other way?
nada
there's a dollar buffer somewhere
don't remember where
that ease_dollars writes
i think
ideally i need this calculate to return a mult thats calculated using the current dollars value
Wrong
hmm
dan g...
Use the buffer
if you can't make it work with the dollar buffer baliame mentioned you might have to SMODS.calculate_effect
ok now time to find the buffer ig
common_events.lua probably
Also the buffer doesn’t get updated automatically
ease_dollars sounds like a common event to me
So if a mod adds effects that change the amount of money during scoring
It doesn’t necessarily update the buffer
this should work then, right?
The modder needs to buffer it
it should run only once when a new run is started
saveTable is not defined there
crap, what am i supposed to check
this what game does
SMODS provides an utility to set variables at the start of a run
Also each Ante
I'd personally set it up not as blind hooks, but as new objects that probably use similar logic, but I reckon that'd be very similar in use.
that's called kinda in the middle of the start_run function tho
if you want smt to happen after everything you'll still want to hook
Oh if you want to change the background color
Hi dudes, I cannot figure out this context window
If played hand is Flush, give +3 mult for each card
Check out how Bunco or my mod do it
not the background color, just uhh
something i want to set to G.GAME when a new run starts
Whatever Hiker does
counterpoint: writing them as out of pool blinds gives you easy access to both acting on game events and letting other things act on biome events without significant effort
ok no ease_dollars just does G.GAME.dollars = G.GAME.dollars + mod so idk
then yeah definitely use the utility function for mods
waut nvm
As I said
It doesn’t automatically update the buffer
it adds that to the event queue
The buffer needs to be updated manually
shiiiiiit
basically this
hmm, that's a good point. I'm taking this down in the brainstorm doc for it, and give it some actual thought once that mod seems like something I'll start working on
you'd just check if run_start then
there's Kino and Jokersets still in my event queue first, haha
hmmmmmmmmmmmmmm
Then check the Castle example
it doesnt look like there is a buffer for money it just adds the change to the event queue. thats. funn
ahhh icic, gotcha
There is a buffer
:3 in my defense, i completely forgot castle used smt like that
Check out cards that add money during scoring or that use the value of money during scoring
I meant the SMODS Castle example
yeah thats what i meant
i mean okay technically you can implement it as cards instead, it all depends on the types of effects you want to do, not that easy to get a card to debuff a hand (Not allowed!)
anybody know what cardarea the collection pages use?
They use collection cardareas
that would make sense
Invisible Joker in the sky that calculates all the rules
is itttt this or SMODS.current_mod.reset_game_globals = function()..?
or are they the same
:3
it looks like vagabond just checks G.GAME.dollars
i think thats just a lack of lua knowledge on my side, honestly
i mean that's the same thing I sent
good ol control cubes
just it has castle logic inside
I think blinds can do whatever jokers can, but not the other way around, currently, so blinds would definitely be the way to go. My current idea, which I haven't thought through much, was to set it up as a new object type that is channeled by the blind objects, similar to the set up I'm using for Spellcasting in Kino. Probably wouldn't be that simple to convert that, though, as these effects would be passive, and spellcasting is active
i don't think blinds get contexts, or is that what aure did in blind calcs?
what can't Jokers do
yup
They do
debuff a hand
they can do it, I assume, but not as easily
by default jokers don't act on debuff_hand and recalc_debuff
they could but both require patching
thx
I might start to mess around with it sooner rather than later, just because I'm considering making the showdown blinds for Kino ones that also do things during the small and big blind
I think now you can just hook into Card.can_calculate
Notably it's not the only buffer in the game
that doesn't do what i'm saying though
that figures out if a card should be considered debuffed, but that's a bad pattern here
since the game during recalc_debuff asks the blind if it thinks a card should be debuffed, so the pattern would be to also ask the jokers
not have the card report it's debuffed based on what jokers you have
or i guess can_calculate() could call back to jokers which would be incredibly expensive since you're trading an O(1) cache (card.debuff) for an O(n) live check
I considered passing the context to can_calculate
it works :3
So that it itself could calculate on the card
oh, the way I made a joker debuff cards is to hook into the blind function you mentioned
how would I check if the collection is currently open?
is it possible to add a button to this area
maybe check if G.your_collection exists
but that might only be the case if there are cards visible
i'm not entirely sure
actually, i think i figured how to
the question here is: where's the ui of boss blind?
i can probably attach a button to that
maybe create_UIBox_blind_choice in ui_definitions.lua
Attempt to use a nil value at self.extra.odds
I will never remember that this is nil in calc for smods. I should just remap self = card
Every time I think I'm ready to push the new updates, I discover something I still need to do
as far as I can tell this always exists
different approach, is there a way to tell what cardarea a card is currently in?
from the card itself
card.area
that will probably work
hi guys, I feel like this is just too weak or slow. How would you improve this card?
I think if Trousers gains +2 mult per pair, then this should gain +5 mult
i agree
really cute art btw
i love chocobos
also it should be red and +2 mult
i think
TY, my wife went crazy making tons of cards, now I am trying to think of how to use them
here is like half of the jokers, just to share
heres the description following Spare Trousers as an example if you want
"This Joker gains {C:mult}+#1#{} Mult",
"if played hand contains",
"a {C:attention}Straight{}",
"{C:inactive}(Currently{} {C:mult}+#2#{} {C:inactive}Mult){}"
those all look great!
im so slow i just realized that "atlas" isnt a madeup word for codding used in balatro its an actual word
its just a resolution variable basically
So guys, I have a little problem. It's not really important, it does what I want, but not the way I want it.
This piece of code for a joker retriggers a lucky card until it gets lucky (Gives either the mult or the money). And, it works! But the strange thing is:
- It first does the card eval status text as many times as it will retrigger BEFORE the card gets even scored
- The retriggers are ... inverted? The first score of the card is lucky, while all the following scores are not
This makes it all look very very strange, so... does somebody have an idea of what I am doing wrong? Or how to optimize it? Like it's ok, but just very strange. Especially the first problem is pretty uncomfortable. Maybe I should put the card_eval_status_text somewhere else?
the card eval message should be in an event, in this case!
Ooooooh makes sense, thanks! Do I have to put SMODS.score_card in the Event as well to have the scoring not inverted?
what we think of this effect? disintegration would be a status or something that destroys the card in the alotted time, 3 hands might be too quick but idk
-# (also art is WIP)
How do I call the "Foo" pool table if I hypothetically followed this part of smods wiki?
My guess is G.P_CENTER_POOLS.Foo but I want to make sure before proceed.
where in the balatro archives are the tarot cards?
My suspicion is that putting the score card in there will create some major issues
I'll try, let's see XD
i love jerma
I love it! But kind of weak for a rare joker I guess... maybe make it create 2 Spectral cards or lower the rarity to uncommon or increase disintegration to 5 hands?
what if instead of figuring out why the sprite is wrong before the card has been discovered, I just make it discovered by default to bypass the issue
havent touched the rarity yet but ill keep that in mind when deciding, ty
Also does the disintegration have an effect on eternal Jokers? :D
depends how i end up getting it to function but im thinking of just applying a perishable sticker instead
I see
which would work on eternal jokers
when making an edition, where do i say what it does?
Check SMODS.Edition in the wiki
tyty
editions is either the joker ones or the card enhancements or is there a different thing for enhancements that im not seeing?
editions
enhancements
no yeah ik, just wondering if in the code there is a difference because i didnt find a "SMODS.enhancement" part in the example part
ohh mb
np ^^
There exists a SMODS.Enhancement
