#💻・modding-dev
1 messages · Page 29 of 1
[manifest]
version = "1.0.0"
dump_lua = true
priority = 0
# Wee Fibonacci rendering
[[patches]]
[patches.pattern]
target = "card.lua"
pattern = 'if center.name == "Wee Joker" and (center.discovered or self.bypass_discovery_center) then'
position = "before"
payload = '''
if center.name == "cry-Wee Fibonacci" and (center.discovered or self.bypass_discovery_center) then
H = H*0.7
W = W*0.7
self.T.h = H
self.T.w = W
end
'''
match_indent = true
[[patches]]
[patches.pattern]
target = "card.lua"
pattern = 'elseif self.config.center.name == "Wee Joker" then'
position = "before"
payload = '''
elseif self.config.center.name == "cry-Wee Fibonacci" then
self.T.h = H*scale*0.7*scale
self.T.w = W*scale*0.7*scale
'''
match_indent = true
This is how I do it for wee fibonacci in Cryptid, although using soul_pos might make things trickier
there's also this scale factor that goes into the shader
# Draw midground layer
[[patches]]
[patches.pattern]
target = "card.lua"
pattern = "if self.config.center.soul_pos and (self.config.center.discovered or self.bypass_discovery_center) then"
position = "after"
payload = '''
if self.config.center.soul_pos and self.config.center.soul_pos.extra and (self.config.center.discovered or self.bypass_discovery_center) then
local scale_mod = 0.07
local rotate_mod = 0
self.children.floating_sprite2:draw_shader('dissolve',0, nil, nil, self.children.center,scale_mod, rotate_mod,nil, 0.1,nil, 0.6)
self.children.floating_sprite2:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)
end
'''
match_indent = true
This is how I draw one of the layers for Cryptid's Exotic jokers, and it doesn't move or rotate here but it's a little bigger
you might be able to get away with this and just change scale_mod to like -0.4 or something (along with the whole equation)
this is getting super frustrating, im trying to make the amount of uses on a consumable refresh when you beat the boss blind, but for some reason it isnt triggering inside the calculate function. i dont know where else to put it, and i dont really know any other context that could work
yeah calculate only works for context.joker_main on consumables, unfortunately
you'd probably have to add those calculate calls yourself
how would i do that?
yo, how do I check for what card is currently being scored, because other_card is nil ignore the spamton stuff its because the card has a section that looks like his sprite
probably with lovely
you need to check context.individual, other_card doesn't exist in other calculate calls
sorry we're closed
I was about to head to bed
I don't
now gn
that is far too complicated for me
im still taking a very large amount of my code from the base game
maybe i could just change my idea and have the gears not refresh their uses
What
You could maybe use a hook
whats the ID for aces? 0, 1, 11, or A?

Anyone know why context.poker_hands["Pair"] only contains the 3oak in a full house?
Presumably because the 3OAK contains a Pair. Maybe it’s not an exhaustive search?
or maybe because aure changed how it’s calculated, IIRC?
it finds both in a two pair though
is there a way to get the cards in the hand and score them AND the cards played?
Isn’t that Splash
What I was thinking was if you play a royal flush, the cards played score twice, and your hand (the cards at the bottom of the screen you can play from) get scored before they all get destroyed
I’d probably check for a royal flush then add a variable that triggers a repetition while also setting an internal variable that makes cards in hand score, and then destroy them, and reset the internal variable afterwards
Maybe a hook/lovely patch to score cards makes more sense than doing it inside calculate
Final Qs before I end the project work for the day.
-
How do I display two messages if the card gives both chips AND mult, since this code (attached) doesnt show two message prompts
-
What do I call to check if certain jokers are in the joker slot?
So in return, call eval_this(self, mult, chips)?
my mod keeps crashing and I don't know why... I took bits and pieces from another mod and the games code :P
the steamodded wiki was confusing to me so I might have skipped over something important on accident
So, my joker seemingly runs the upgrade under every card, and sometimes multiple times per card (it should only run once on it being scored, and the only triggering cards should be a 3,2, and an Ace.
if context.individual then
if context.other_card:get_id() == 2 and not context.blueprint then
self.ability.extra.chips = self.ability.extra.chips + 2
self.ability.extra.mult = self.ability.extra.mult + 2
print("upgraded by 2")
print(self.ability.extra.chips)
return {
extra = {focus = self, message = localize('k_upgrade_ex')},
card = self,
colour = G.C.CHIPS ,
extra = {focus = self, message = localize('k_upgrade_ex')},
card = self,
colour = G.C.MULT
}
elseif context.other_card:get_id() == 3 and not context.blueprint then
self.ability.extra.chips = self.ability.extra.chips + 3
self.ability.extra.mult = self.ability.extra.mult + 3
print("upgraded by 3")
print(self.ability.extra.chips)
return {
extra = {focus = self, message = localize('k_upgrade_ex')},
card = self,
colour = G.C.CHIPS,
}
elseif context.other_card:get_id() == 14 and not context.blueprint then
self.ability.extra.chips = self.ability.extra.chips + 1
self.ability.extra.mult = self.ability.extra.mult + 1
print("upgraded by 1")
print(self.ability.extra.chips)
return {
extra = {focus = self, message = localize('k_upgrade_ex')},
card = self,
colour = G.C.CHIPS,
}
end
end
if self.ability.name == 'Destruction' and context.joker_main then
salesman = math.random(1997)
return {
message = localize{type='variable', key='a_chips', vars={self.ability.extra.chips}},
chip_mod = self.ability.extra.chips,
mult_mod = self.ability.extra.mult,
card = self,
colour = G.C.CHIPS,
}
end
end
sorry about the wall of text
any clue where I effed up in order to have it run multiple times and not even check for the card numbers?
context.individual and not context.repetition for the former point
anyone know why this doesn't work, im trying to retrigger cards. (0.9.8) ```SMODS.Jokers.j_jackpot.calculate = function(self, context)
if not self.debuff and context.individual and (context.cardarea == G.play) then
if true then
return {
message = localize('k_again_ex'),
repetitions = self.ability.extra.times,
card = self
}
end
end
end```
you should be checking context.repetition
How do I make the text inside the red border white? This makes it black
no space within {}
Oh, like after the comma?
Understood, thanks
ty
does steamodded support custom sfx
forgot crash log
nvm im dumb
that happens a lot
How do I make it so my joker will never appear in the shop? Like Cavendish pre-Gros Michel extinction
I can't find anything about it under the Card class in the Source Code
What’s the condition you want it to satisfy for it to appear?
Or do you just want it to never appear
I think it’s hidden = true or something, but you should check the create_card() function
Yeah, I want it to never appear. I have a function that makes it appear upon selling "Egg"
I'll do that
does steamodded 1.0.0 have custom sfx compatibility?
there's sound API I believe, haven't messed with it though
the "2" card is card id "2", presumably, right?
I’d recommend going down the yes/no_pool_flag route and changing the value of it when you sell egg
better to do syntax like this though (at least in Steamodded 1.0)
oh im still on steamodded 0.9.8 💀
idk what the equivalent is but there's probably something like that
i was doing
whith that inside a if context.indivdual and not context.repetition satement
but any card seems to run that code
Is this saying that it's unsupported right now?
That's under SMODS.injectJokers()
And actually, when I change the yes_pool_flag, will that then make it possible to show up in the shop? Because that's not what I want to happen
updated steamodded to 1.0, but now my mod doesnt load saying its for 0.9.8, how do i make it 1.0 compatible?
oh you want it never in the shop?
yeah
G.GAME.pool_flags.sphero_extinct = false
G.P_CENTERS['j_lea']['yes_pool_flag'] = 'sphero_extinct'
``` something similar to this should stop it from appearing in the shop
ok so the card does work and show up in collection but now it crashes when i start the deck with it as a starter item?
its the game code but swapped clubs spades and black suit for diamonds hearts and red suit
do you know what I should do for 0.9.8?
no
Anyone else not able to run the game with 1.0? When I use the 0.9.8 tag the game launches fine, but when I switch to main branch I get this error
I'll check that out when I get home. I'll probably have some more questions lol
hmm. What seems to be happening is other_card in the way I set up checks the WHOLE HAND, not just played cards
heres my current code if that helps
what's it supposed to do?
If a two is scored, increment the jokers chips and mult by two. If a three is scored, increment the jokers chips and mult by three. If ace, increment by one
but what happens is it checks the whole hand
e.g, the played cards and the cards in your hand (at the bottom of the screen)
honestly now that im thinking about that, the skill seems more "rare" or "legendary" than uncommon
what do you mean, it checks the whole hand?
heres a really weird recording of how it acts
trying to override Card.use_consumable but nothing is changing
do you want it to look over the hand?
it works fine when I use a lovely patch actually, nvm; still weird though
no, just the played/scored cards
can you send me the calculate code in DM real quick?
how could I make my joker do what blackboard does but for hearts and diamonds instead?
search for blackboard in card.lua
i did do that but when its in my code edited to the other suits it just crashes as soon as i start a run
gotta love it when i follow the sound api drections and like the most basic elementary function to make it all work fails
i dont know what doing register_sound_global() is not causing this function to happen
edited game code
i think that there is no red_suits local in game
could you try with black_suits?
sure, one sec
i never messed with blackboard's code so idk how to mess with it
oh
now i noticed
there is no context for the joker
try putting if context.cardarea == G.jokers then before the first if
here?
yeah
ok so that helped, it went until i played the first hand then crashed again.
oh shoot no, thanks for asking that lol
that's probably why
lmao
sometimes we can forget a thing that is so simple
and, idk if the extra gonna get rid of the crash message
it didnt but im gonna do some looking around in the game code for the black_suit local and make a red one to see if that does anything. tysm for the help 😊
no problem, i tried doing my best, i'm still learning
I know theres {C:attention}, but is there a thing to make it small? and is there a way to change the joker artwork while the joker is in the joker slots?
You can do like {C:attention,s:0.8}
and you'd need to change the pos values to dynamically change the joker artowrk
so if I were to put in in a spritesheet, with one right next to the other (transparent boarder intact), how would I change the POS
you could probably just manually modify self.pos.x or self.pos.y to match what you want in the spritesheet
not 100% sure if this would work since I haven't done something like this but it would make sense
Honestly seems like a lot of work to implement a silly joke because of the way I drew a pattern looked like spamton
if you change the center's pos itll change it for every instance of that card
you'll need to change card.children.center
card.children.center:set_sprite_pos({x=#, y=#}) i think
card.children contains all the sprites for that card, wherein center is the one you'll be concerned with for pretty much everything except playing cards
floating_sprite is the soul_pos, and front has the playing card suit/rank sprite
back is what's shown when the card is facedown, typically drawn from your deck back but you can manipulate it if you want
so it would be
card.children.center:set_sprite_pos({x=#, y=#)
end
```?
kewl, its just a silly easteregg anyway
fair
i might have the arguments wrong idk, id doublecheck how basegame uses :set_sprite_pos
(alas i am afk for ~10 hours)
I just didnt think that the base game had texture changing jokers when conditions were met
it doesnt, but the :set_sprite_pos function is used for setting up cards
you're basically just using a function that normally only gets called once per card
i forget if there has to be other stuff than just the pos, been a bit since i set up anything using that function
alright, new thing. card not defined. heres the temp code to set it every time before I implement the condition
oh yeah it should be self in that case
im used to 1.0 lol
(1.0 funcs get self and card, where self is the center object itself and card is the actual card)
excuse me x=71????
i sincerely doubt you have 71 cards in a horizontal line in your spritesheet, did you mean x=1? sprite pos's already account for the per-card size
then probably x=1
do i need to set the 71 to 142 in order to have it work?
answer is no, it works on playing a card
Is there a way to loop through each registered Joker and embed a message in their description? So if I wanted to display their current sell value in the description, and have it update when the sell value changes, which function should I start at?
Well, not loop through. But just somehow embed the sell value in the description on calculate
sounds like something for generate_card_ui perhaps
or the UIBox function that calls it, which i forget the name of
the description window is dynamically generated on hovering over the card, the text isnt stored with the card
Oh ok, that's one thing I was wondering about
So could I do something within the hover function? Is the hover function stored in the Card class?
I'm not at my computer right now or I would check
You can hook generate_card_ui or generate_UIBox_ability_table
I myself did the latter to display Hiker-like extra Chips and Mult on Jokers
Is a hook the thing where you get the reference and then overwrite the function?
yes
Could you show me the code that you did inside your function? Just so I have a reference?
AtumunMood924
I wonder who that is
It was also my first time messing with the tooltip so I learned how to do it from your code
Also arachneii's a bit
But I'm changing the tooltip after it's created which I find easier
Well, after the table has been created
ne wimage alert?
local generate_UIBox_ability_table_ref = Card.generate_UIBox_ability_table
function Card:generate_UIBox_ability_table()
local generate_UIBox_ability_table_val = generate_UIBox_ability_table_ref(self)
local key = self.config.center.key
if self.ability and self.ability.set and self.ability.set == 'Joker' and G.STATES ~= G.STATES.MENU and G.STATES.TUTORIAL and not misc.is_in_your_collection(self) then
end
main_end = {
{n=G.UIT.T, config={text = "$", colour = G.C.GOLD, scale = 0.32}},
{n=G.UIT.t, config={text = self.sell_cost, colour = G.C.GOLD, scale = 0.32}}
}
end
so
this one?
profile
o
This is what I've got right now. If I wanted the main_end text in this code to show up, and just be after the card's normal description, how do I do that?
I was able to do it by calling generate_card inside, but the loc_vars was erroring out
And I'm really not sure how to access loc_vars inside that function
Me neither but you can access variables as I do
As you can see I access the Joker's base Chips and Mult
that I added to all Jokers
i suggest inspecting the anatomy of the original function's return value
dissecting jimbo like a frog
you can print(inspect(...)) to see whats in a table
huh and I had my own stolen dump function
yeah i think smods comes with an inspect implementation? or maybe its just debug stuff left over from thunk
its not recursive tho
three actually lol
chat are these readable and good, will thac be eternally hated if i ship the mod with these textures, etc
I think they’re fine and you can always change them later if you change your mind
I think thac will be eternally beloved if you release it
But it doesn't appear to be showing up in-game
I think the face cards of coins lack definition but I don’t know how to resolve that
What's the context for being in the booster pack screen to choose a card?
fuck it im gonna make coins purple
how about silver?
Where are the descriptions for the vanilla jokers stored?
localization/en-us.lua
ok i know how id do this in the base game, but in the interest of mod compatibility id ideally want to make it check if the hand started out flagged hidden. anyone know how i can do that
Anyone know why this happens?
This is the code for the afflicted area
calculate = function(self,context)
if self.added_to_deck then
return { --line 125
G.hand:change_size(-1),
G.GAME.round_resets.discards = G.GAME.round_resets.discards - 1,
}
end,
if not self.added_to_deck then
return {
G.hand:change_size(1),
G.GAME.round_resets.discards = G.GAME.round_resets.discards + 1,
}
end,
if context.joker_main then
return {
message = localize{type='variable',key='a_mult',vars={50}},
mult_mod = 50,
}
end
end,
It says the { is never closed, but it is
maybe delete the commas at the end of the } ? just spitballing im not sure
Will try
Because I don't know how Lua works
Removed the commas after end, but no cigar
I copied it from stuntman and merry andy basically
I might've gotten it wrong though
Actually no, I adapted troubadour's -1 hand to -1 discard
I looked at stuntman for the hand size
It works perfectly if I remove this bit
if self.added_to_deck then
return { --line 125
G.hand:change_size(-1),
G.GAME.round_resets.discards = G.GAME.round_resets.discards - 1,
}
end,
if not self.added_to_deck then
return {
G.hand:change_size(1),
G.GAME.round_resets.discards = G.GAME.round_resets.discards + 1,
}
end
But then it doesn't have the full intended effect
Again, that was something that Stuntman and Troubadour do. They seem to "permanently" modify your stats when they are bought, and then permanently modify them again when they're sold
Well, that's how it looks like
It’s not redundant?
If it wasn’t there you wouldn’t get the discards back
Oh yeah I get what you mean
I'm still having the issue of missing bracket but there is a bracket
I wonder if removing it means it always triggers though, I’m not sure how the added to deck parts trigger
You have a comma after end
I removed the return {} function, so its just this now
Still not a fan, but a different error
You have commas at the end of your lines
You don’t need them unless it’s inside a table
context.joker_main works when the rest is removed
That’s what the error says
That was when they were inside a return, and I forgot to remove them
Ok, that code above "works" without those commas now
However
It immediately sets me to 0 discards and 0 hand size
After I play a hand
It probably triggers for every joker calculate call because you have no contexts
All of it obviously
3.199 mil
Either you win big, or its a rags to riches play
Whats the context trigger for when bought or sold?
Check the context stack in card.lua
What does that mean?
Read through calculate_joker and figure it out
That’s where all the contexts are
It’ll serve you better in the long run to understand the contexts rather than just ask
The only one that’s not there is G.joker_main but that’s just the final else at the end
Right, there's about 500 "calculate_joker" bits, I don't know which to read, or what I'm looking for
And follow the tree backwards to find the contexts
The joker should add +50 mult, -1 discard, -1 hand size, similar to stuntman or troubadour
But neither of those jokers have their -hand size in a calculate function I can find
And if they do, I copied it word for word already
No you need the context
Not the actual calculate code
Go to where you found that card and examine the if-else tree it’s in
Yeah, I found that
What does the ease do?
I've seen it used for ease_money() or ease_hands_played() or ease_discards()
Are you using 1.0 or 0.9.8
0.9.8
So I think you’ll need another function like calculate called add_to_deck
1.0 has add_to_deck, idr if 0.9.8 has any such thing
Yeah worst case is it doesn’t work
Can you show your whole code?
also the latter half of that should be a remove_from_deck call i think
You also don’t need the if
also im still pretty sure it doesnt exist in 0.9.8
and if you're in 0.9.8 then you dont have self on most functions
The syntax looks like 1.0 though 🤔
I don't know where to find 1.0.0
Its "not released, but available" according to Steamo
yes mod in 1.0.0 join me
The most fun is modding in both
there's a green code button at top of the page
I don't use git
click that and download the zip file
oh no aure is gonna tell us not to use 1.0.0 because theres more breaking changes coming
but it's easier to update with git
nah, I want ppl using it so I don't have to do all the testing
aure the goat
kden, do better
"tags/1.x.x" is not a commit
I copied it letter for letter
This
I downloaded the zip
Steamodded-main
What do I do now?
This is brand new
Same isue
Already cleared 0.9.8
The code hasn't changed
Where is SMODS.INIT?
Yeah, something called Deck Creator
Ah bugger
I'm using it to test my jokers
How do I move SMODS.INIT to top level scope?
Ah sick
Where do I put _RELEASE_MODE = false?
In my mod?
Same issue again
I have my mod
Steamodded
And lovely
It doesn't
My main.lua has 388 lines
steamodded injects an extra few thousand lines into main.lua if you're still confused
Right, so steamodded 1.0 is broken then?
Some specific commits might be broken
Will reinstalling keep my progress?
verify game files on steam and see if the issue persists
it might be two conflicting installs
you're not looking at the lovely dump then
I had this issue with 1.0 last night and reinstalling balatro fixed it
My mod keeps crashing as soon as I play a hand with the joker. Using base game code but edited for the ability.
ok so after some testing, it can detect the hand and if it has a spades or clubs but once it has only diamonds and or hearts it crashes.
Found your culprit i think, when it returns the key it uses is key = ‘a_xmult’
Steamodded doesn’t need to check for the Joker name
It should just be a_mult or x_mult
I’m not sure what you’re doing with loc_vars but it probably doesn’t have to be there
And I think there’s an easier way to do that effect if I understood it correctly
Well, maybe not easier, but slightly faster on average?
Also the indentation is really weird
And i think you could just try to find if theres any black cards and then have it fail instead of trying to see if the amount of red cards matches the total amount of cards then have ot succeed
Still great that you are learning though
It’s slightly different due to Custom Suits
ty for the help, its still crashing but i think its starting to work out :) I was testing somethings so i couldnt respond earlier.
Tried that, tried reinstalling, same issue
💀 my keyboard had a stroke
there's no such thing as an inject function in 0.9.8
best to hook into injectSprites probably
local inject_ref = SMODS.injectSprites
function SMODS.injectSprites()
inject_ref()
-- your code
end
I finally got it to not crash, Can't do anything else atm though since im leaving for a roadtrip but just wanted to say i fixed it (kinda) :D
how exactly does one create a random member of a custom consumable type?
and not like injecting it into the tarot or planet pools
like creating a new consumable pool
Aight, it's progress
don't click links folks
<@&1133519078540185692>
ty mods
Ty 👍
Now that I'm here, I have a question lol
I have a working joker but need some help! My code currently is written to give $7 when Three of a Kind of 7s is played, but ideally I'd like it to give $7 when a played hand contains exactly three 7s, would anyone be able to take a look at this and give me pointers on how to replays the #context.full_hand == 3 line to accomodate that?
-- Jackpot
if config.j_jackpot then
local jackpot = {
loc = {
name = "Jackpot",
text = {
"Earn {C:attention}$7{} if hand contains",
"three scoring {C:attention}7s{}"
}
},
ability_name = "Jackpot",
slug = "jackpot",
ability = {
extra = {
dollars = 7,
poker_hand = "Three of a Kind",
},
},
rarity = 2,
cost = 7,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = true
}
-- Initialize Joker
init_joker(jackpot)
-- Set local variables
function SMODS.Jokers.j_jackpot.loc_def(card)
return { card.ability.extra.poker_hand }
end
-- Calculate
SMODS.Jokers.j_jackpot.calculate = function(self, context)
if context.joker_main and context.cardarea == G.jokers then
for k, v in ipairs(context.scoring_hand) do
if #context.full_hand == 3 then
if next(context.poker_hands[self.ability.extra.poker_hand]) then
if v:get_id() == 7 then
ease_dollars(self.ability.extra.dollars)
end
end
end
end
end
end
end
Yeah misclicked my b
Dope! ty
Ahhhh that's a smart approach, I'll look into setting that up
And, still learning, I put # before something to get an output in numerical form I can check, right?
you should also be able to llook in context.poker_hands['Three of a Kind'] and check if the first card in it is a 7
like, context.poker_hands['Three of a Kind'][1][1] will give you the first card in the three of a kind
yeah it counts that too
I think the only thing that is missing from poker_hands is when you play a full house, pair only returns the set of three
Yo thank you! I'll give this a test, very grateful to you (and everyone else) for the pointers as someone who started learning 2 days ago lol
note that this will also trigger on 4oak/5oak
Trueeeee, I bet I can set up an if / if not somehow
But first I want to get that working, even if it triggers sometimes I don't want it to this is a good iterative learning process
if next(context.poker_hands['Three of a Kind']) and not next(context.poker_hands['Four of a Kind']) then should do for that
I'm just stoked my joker is loading in game, with art, and not crashing everything hahaha
Okay, so all hands like 'Three of a Kind' and 'Four of a Kind' are inclusive of other scoring hand types that may include those cards?
very good to know, probably have to be quite careful with pairs then haha
🔫
Okay one more question that isn't apparent to me after a google, when should I include "next" and when do I not need it (e.g., "if next(context..." vs "if context...")
Legit made a joker like this yesterday
Oh no way! Wanna use my art if you like it or anything? I'm all for not having redundant mods
I’m fine with my design, what’s the joker do btw?
Cool just offering! The idea is that it pays $7 for each hand played that contains exactly 3 scoring 7s (like hitting a jackpot on a slot machine)
l o l
Well I drew it on wednesday sheesh
Haha that's hilarious tho, something something great minds something
Lol
So this raises an interesting question, are there config files that can easily be edited by mod users? It would be cool to be able to toggle jokers on and off if there are redundant packs you have installed
You can put one in your mod but I don’t know if that is convention
I used to make stardew mods (really REALLY easy because I just basically made pixel art and then used a content patcher framework that made life so simple) and it was awesome to have config options to change the colors of different kitchen appliances, wallpapers, etc.
Would be really cool if easy toggles became the norm imo
end user friendly for ultimate customization
anyone know how to add a pool for a custom gear type such that it functions with create_card()?
that would be a really good feature in steamodded
like a mod settings button
Yeah if you could reference an external config.txt file or something with slugs and 1 for on and 2 for off
Okay I've officially broken it by attempting to simplify. this does nothing now, what did I need that I no longer have?
-- Jackpot
if config.j_jackpot then
local jackpot = {
loc = {
name = "Jackpot",
text = {
"Earn {C:attention}$7{} if hand contains",
"exactly three scoring {C:attention}7s{}"
}
},
ability_name = "Jackpot",
slug = "jackpot",
ability = {
extra = {
dollars = 7,
},
},
rarity = 2,
cost = 7,
unlocked = true,
discovered = true,
blueprint_compat = true,
eternal_compat = true
}
-- Initialize Joker
init_joker(jackpot)
-- Set local variables
-- Calculate
SMODS.Jokers.j_jackpot.calculate = function(self, context)
if context.joker_main and context.cardarea == G.jokers then
if context.poker_hands['Three of a Kind'][1][1] == 7 then
if next(context.poker_hands['Three of a Kind']) and not next(context.poker_hands['Four of a Kind']) then
ease_dollars(self.ability.extra.dollars)
end
end
end
end
end
context.poker_hands['Three of a Kind'][1][1] == 7 this doesn't work
the context gives you the card
you'll need to do something with that before checking it equals 7
oh so I need an id or something
what exactly does context.poker_hands['Three of a Kind'][1][1] spit out if not the number 7?
(thank you for the help btw, sorry if these questions seem dense and no rush in answering or obligation to answer at all of course)
it gives the card object
you can run this to see what it contains
for k,v in pairs(context.poker_hands['Three of a Kind'][1][1]) do
sendDebugMessage(k..": "..tostring(v))
end
@frosty dock can't get this working properly, any tips? it's in game_object.lua right now
SMODS.process_loc_text(G.localization.descriptions.Edition, "e_negative_playing_card", {
name = "Negative",
text = {
"{C:dark_edition}+#1#{} hand size"
}
})
I'm back what did I miss
Something went wrong… but it also went right?
It's probably some domain error I'm too tired to see
local anim_timer = (G.TIMERS.REAL % 2)
anime_timer = anim_timer > 1 and 1 - anim_timer or anim_timer
local ease_num = (anim_timer < 0.5 and 4*anim_timer^3) or (1 - ((-2 * anim_timer + 2)^3) / 2)
local red_hand_scale_mod = -0.04 + 0.16*ease_num --0.04 + 0.08*math.sin(1.8*G.TIMERS.REAL)*math.abs(math.sin(1.8*G.TIMERS.REAL))
self.children.floating_sprite:draw_shader('dissolve',0, nil, nil, self.children.center, red_hand_scale_mod, rotate_mod, nil, 0.1 + 0.03*math.sin(1.8*G.TIMERS.REAL), nil, 0.6)
self.children.floating_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, red_hand_scale_mod, rotate_mod)
or a typo lol
"anime_timer"
But that makes it shrink instead of grow :<
I want it to pulse
should it not be anim_timer > 1 and 2 - anim_timer or anim_timer?
I haven't read the rest but that'll go from 0 to 1 then from 0 to -1
I already fixed it but I did want it to go from 0 to 1 to 0 to 1
@tawny perch What do you think? I wonder if it's too distracting
also @wintry solar what do you think of a HologramAPI for these kinds of shader effects? Do you think it needs anything besides an injection to Card:draw to add a check for custom shaders to apply?
does that have a shader on?
Not a custom one, but I change the scale
as you can see here
but Hologram's code right before does call a custom shader I think
It does. I inject after self.hover_tilt = self.hover_tilt/1.5
hence if you wanted to use a custom shader, this would be the spot
for a shader on the floating sprite, sure
I mean, it could be on the original sprite too, though Invisible Joker does it earlier
I think if you have a list of injection points, it could be adapted into an API
its a little much, just tone it down a little bit
also if its possible, make the tentacles seperate and not move as much as the hand
its pretty cool tho
What do you want me to tone down?
I do think parallax on the tentacles would be good, but I don't want to figure out how to make multiple soul sprite layers work right now
the growing in and out part
You mean the speed or the size?
speed
I wanted the size to change quickly but hold at the extremes for a little bit
I like the hold, I think the change is a little quick
yeah, it'd have to be built into joker declaration I think, but I think it should be very simple to inject a check there and draw a shader if needed
I mean, it could be optional
well yeah it'd have to be optional
@wintry solar
yeah that looks better imo
nice
collared mention
No functionality quite yet, but here's my WIP
where in my spaghetti code did i go wrong to cause this consumable which is supposed to convert 2 random cards in hand to the most common suit in your deck to do absolutely nothing
I realized, in order to continue making dumb stuff I need to learn how to mod balatro for real. I really want to make a change to card stacking. With the hope that I could categorize jokers by what they mainly do (eg: mult X vs mult flat), and have those cards stack into a drop down, or sub menu.
That would be really cool
essentially making it easier to view your joker cards when you have more than normal, i.e 30 or whatever
I’ve had multiple requests for a feature like that along with Cryptid (where you can get hundreds of jokers easily on some builds)
But it’d be very complex so I’ve been pushing it off
does that include Death tarot
Yes
btw, although i have no idea how to code for lua if I ever learned I'd prolly be happy to be a helper to this idea.
since I started making joker decks of over 100 during the demo and was always annoyed by the stacking system in place rn
Anyone know why my Joker just isn't triggering? Been cross-referencing with a few other mods and have no idea what I'm doing wrong
Here's my calculate function:
...
calculate = function(self, context)
if context.cardarea == G.jokers and context.joker_main then
return {
Xmult_mod = self.ability.extra.current,
message = localize {
type = 'variable',
key = 'a_xmult',
vars = {self.ability.extra.current}
},
}
end
end,
...
Bump, still haven't found a solution
All I've really been able to gather is that with the above function definition, context.cardarea == G.jokers always returns false and context.joker_main always returns nil
I have no idea if this is from context being gotten incorrectly or a wrong calling of fields of context or what
I am very lost right now
are you in 1.0.0
Yes
calculate = functions(self, card, context) in 1.0.0
where self is the center object
rn you're essentially checking the card as if it was a context
im pretty sure this is consistent among all center/blind functions now
and maybe tags but i dont remember
Changing the function header to that does allow that to trigger, but now I'm getting a crash of attempt to index field 'ability' (a nil values)
Ah
self is the center object (as in, the thing you define with SMODS.Joker{...})
card is the actual card game object
not sure why its giving me this error here
im guessing the problem might be that the joker keeps changing them back and forth but
nvm i think i got it
hears
Balatro comes with a count_of_suits(area, suit) function
I have SMODS._loc_txt for this purpose
load-time processing of loc text never works because it doesn't persist reloads of G.localization. One such reload is forced at start of injection
though I might actually change this to support loc files
Did that change in 1.0?
Ended up wrapping it in the process_loc_text of where we take ownership of negative
It needs things such as a weight, and also to keep the code clean by avoiding hard coded checks for base editions first
What does it need a weight for? I guess it could be useful if people wanted to make it nonzero, but do you need to take ownership to set a weight?
Mods might want to take ownership of it themselves
I mean it needs a weight so that poll_edition can actually function with custom editions
edition.weight or 0
Yeah good job never spawning any base editions 👍
How does steamodded handle multiple take ownership calls?
But also, I don’t know how you expect editions to work without converting the base ones into the api format
I thought it only took the first one
I can test it out in a bit
I mean, inject the code you need or hook it without taking ownership
Or just add a variable to a table at runtime
I implemented Negative Playing cards without taking ownership
Well yeah, you don’t need ownership for that, you’re just applying an already existing edition to the card
The weights are just numbers. AFAIK there’s no Edition object that can hold anything, so the weights would be stored elsewhere anyways
No but there is an edition object now
You can use it without taking ownership
multiple take ownerships work
I think they still need to change different things tho
yeah
Anyone's using mods with the alpha of Steamodded on Mac ?
but if smods itself takes ownership of something it always happens first
so its not unpredictable behavior
That was my understanding
smods already takes ownership of Strength, Ouija, and Sigil i think
It takes ownership of stakes too iirc
that makes sense, i havent checked stake api out
But it makes send right, if you’re building functionality into an api, you have to allow the base game things to have that functionality
Huh what for
suit/rank apis
I guess I just don’t understand why it needs to take ownership to do that
mostly for good practice
since ppl might look in smods code to see how to do stuff
better to do it the unhacky way if possible
Hmmm
stakes are fully re-implemented, so it just creates the objects for those
they aren't something that already exists
there aure's here ask him why he took ownership of strength/ouija/sigil not me im not a mind reader
Aure why did you took ownership of those consumables
my crops are dying my land is salted aure
because it's cleaner than doing it through lovely
their effects need changing due to suit/rank APIs
my crops rise from the dead my land is cured and can be stored for later consumption
i take back my previous statement, i am in fact a mind reader
same for grim/familiar/incantation
What number am I thinking of
413
floating point precision be like
Oops
413.000000000000000000000000000001
Oops! No Cards
ill float your point
I’ll point at a float
👉🎈
I thought you were a cat not a ballon
I'll
Santa Claus moment
cats can't float though
Hence dispelling the magic
cats float in mercury
You’re going to space aure
wrong mercury
Autumn going to mercury would be an.... oddity
Mercury in Autumn is a good vacation
The sulfur clouds just hit different during that time of the year
@zealous glen just tested taking ownership in another mod, works fine
Can the mod change the weights or does the API have methods for it
negative playing cards negative playing cards oooooo you wanna release negative playing cards right now oooooo
(i am exceedingly impatient lmao)
I can send you the development version of edition api if you want to test it out
look at this lovely "polychrome" boy
unchrome
Monochrome
Glad I got this working (not sure if the colors on "duplicated" is too much)
chromeless behavior
true
man i wish i could shader
I also need a good negative, thought of -1 hand per ante (down to a minimum to 1) or a high ante scaling, dunno
that is a BALLER deck back sprite
Thanks!
Ngl I just slapped one my legendary's head art onto the default back deck and I just color em differently
Just put coins in cups with wands and swords on the side 😎 🧠
What are their effects again?
I think it’s already a bit negative. Maybe something to discourage small hands
Generally I prefer encouraging big hands
a flush of:
swords - X2 mult
cups - +1 Hand
coins - +$5
wands - +10 chips to each played card permanently
So if I score 5 cups I get +5 hands? 🤔
It’s per Flush
it is independent from the cards scoring
happens between played cards and hand cards
wands may change before release to be +chips to all pcards played and in hand
Are they enhanced cards or you can slap one on em?
they are suits
Played hand of glass swords to be epic
for the jack?
Yes
also note the special colors on wild :3
i thought it was a neat touch :3
Oh yea the motif is leaking too, didn't notice that, that's cool
what were the watermark ones for again?
I got VV'd and lost 😔
watermark is currently on the homestuck aspect suits, which there are 12 of.
they'll be enabled as compat features for balatrostuck in thac
THE DREAM IS REAL AUTUMN
Nvm it doesn't work somehow 😔
Copies don't seem to count as additions?
you have to have the joker calls
creation/destruction effects both need to manually call for joker effects
i forget the function but there is one to just do that
Darn I didn't know that, I have a bunch of stuff to modify then
Found the function
can't you call calculate_joker() with the right context?
i also have permission to enable nebula deck watermark on stars and moons on sixsuits, i just gotta figure out how to do that nicely
yea but theres a handy function for each case i think
that seems very unlike thunk
id just check dna/cryptid's code and hanged man's code but i am afk for a bit
it's probly more to do with the fact that it is a usecase that comes up often so making a function is just simpler
idk why yall feel the need to psychoanalyze the man based on his code
I’m not
Getting closer and closer to a release^^
me, hoping this leads to unique playing card api
The ____ background actually would look really good as a center
@random sleet 👀
I could make the artwork when I’m home
Working on it !
Oh yeah !
oh that would be baller
i could try to make a watermark version maybe
and see how that looks
Chips pill or Mult pill
Amazing ❤️
one makes you larger
Thank @grand violet
What does the other do
the other one is estrogen
Balatrans
bala is candy which I guess a pill is similar to, so it works as a multilingual pun
CAN I BEAT BALATRO WHILE ONLY TAKING ESTROGEN?????
ye just play queens
Trans mod when /hj
i wanna make an easy dynamic texture replacement mod but idk how to support animated atlases lol
i guess i could just Not
Autumn on its way to make the most baller Balatro mods ⛹️
also i just realized itd be annoying to support soul_pos and anything extra based on position will fail to work correctly
ugh actually i might avoid that headache
got enough garbage to make anyhow
I did it
Wait do you want to render more/less texture or do you want to change the size
I wanna make it smaller
I’m not sure you can do it without the shader, but you can do it with the shader
I think you can do without actually
Because I did it by accident
I need to apply the hologram shader anyways, thats not working rn either
so
Will have to tackle the Shaders sooner or later
I think if you change the width of the sprite without changing the scale it will shrink
I think
Otherwise I did implement a custom soul sprite yesterday
changing the T.w and T.h didnt do anything for me
I put the code here
it was by accident so I don’t remember exactly what combination achieved that
where? :3
This was me trying to debug it @fast badge
I used an injection
The relevant part is the scale mod
You can probably do 0.5*scale_mod
-0.5
I recommend injecting after this line
-0.5 was the only way it worked for me when I tried it with the other approach
This was the end result after I fixed it
Ah right I forgot that I think the dimension of scale isn’t linear*
At least it’s not like scale*visual_area
My suspicion was that it’s exponential but Idk I didn’t test it much
Maybe it’s (scale+scale_mod)*visual_area
me when im fat
Lusty?
Lusty is the soul sprite 🥴
Try throwing the calculations Victin did on it
Which dya mean
I mean, not those specific ones because they don’t quite work
I think if you do sin(1.8*G.TIMERS.REAL) it will look better
Well, you can see the result. It runs but it looks weird
I'm not seeing any change anyways so that doesn't matter really
I replaced anim_timer with a triangle wave
What does your patch look like?
Where did you have that code btw
I sent you
In what function, I mean
I also sent you
eh?
It’s inside Card:draw IIRC
I don't use any lovely patches
Then do it
It worked without
There’s no reason not to use lovely patches though
The patch is also quite easy
Besides not knowing how to do it, I feel like it's bad practice if there's another way
I think it’s bad practice not to do it 🤔
How are you currently doing it then?
elseif self.ability.name == “MyJoker”
--code
good practice: non-overwriting lovely patch
bad practice: overwriting lovely patch
what the fuck are you doing: the other thing
That’s what my patch does
Why is overwriting bad?
I do want to make my Plasma functionality into an API via overwriting the existing check
not saying there arent cases
Currently I overwrite but it’s not an API
just saying it shouldnt be used with abandon
Still, scaling down this bozo has to work with simply adjusting the values
I agree
Again playing with width and children.scale.x should help
I just don’t remember the correct combination
Adjusting scale.x and scale.y just crops the image, and T.h and T.w dont have any influence at all
do not use self.ability.name 🙂
Maybe you’re changing the wrong h and w
“Wee Joker” uses width IIRC
What is the object you’re trying to scale though? Does it have those values?
I see
Unless you mean they’re accessing the wrong sprite
Although if the crop changes it suggests it’s the correct sprite
If changing the scale.x works I think I am accessing it correctly
I think the scale would only change the region of the atlas it’s drawing but I’m not sure
Can you show your code?
No use a crystal ball to divine if 🔮 /j
(aka how some people ask for help in either of the modding chats)
there's nothing to be seen really, I'm just digging through the source code to find any hints
just saving some arbitrary values there
putting any hardcoded values there doesn't work either with the h and w
Have you done card.children.floating_sprite.T.h = card.children.floating_sprite.T.h * 0.5?
yep
is reset()... resetting the sprite :)
ability.extra is where extra is stored
what the fuck is the point of the first line
Or the second line
It sets up the atlas AFAIK
You can change it to whatever atlas you want
It just uses what it already has to set them again
fax no printer
What is the point of the function
What’s the issue
I mean
The atlas the key retrieves can be different
There’s two folders of assets after all
1x and 2x
Both have .pngs with the same name
But they’re different
did everyone get got by Madness
The function has broken us
It just finds the atlas with the same name as the one it already has, no?
btw, removing the reset it still works
The function doesn’t do anything
At all
@zealous glen do you know what the dissolve shader does?
No but it’s the default shader
lurks
Does it just draw the card?
I’ve not looked at the actual file, but I know it’s everywhere
If it does, that’ll need the scale modifier to make the sprite smaller I think
also lurks
lorks
I imagine with certain parameters it draws the card and otherwise it applies the dissolve effect
that is exactly what it does
That’s because you’re changing the part of the atlas it looks at to draw with the x and y IIRC
^ scale.x and scale.y
I think this is going to need a lovely patch
why cant I just run a shader over it tho
Wrong step
The shader applies every frame
Yeah I need that anyways
Also I suspect maybe the floating sprite size can’t change by itself because it might be tied to the major but I didn’t test that
I remember accidentally making the major wide but not the soul
self.children.floating_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, 0.5)
you could try that
I mean I already have the patch code that helps
try drawing the shader in your code block instead of the reset_sprite thingy
I think it's unlikely to work but worth a go
I tried
yeah I guess the one in the Card:draw stack draws on top of it
Probably
[patches.pattern]
target = "card.lua"
pattern = "self.hover_tilt = self.hover_tilt/1.5"
position = "after"
payload = '''
CALCULATE SCALE AND DRAW SHADER HERE
'''
match_indent = true```
with an elseif self.ability.name="Blank Joker" at the start of the payload
Where do I put that
hold on
[patches.pattern]
target = "card.lua"
pattern = "self.hover_tilt = self.hover_tilt/1.5"
position = "after"
payload = '''
else if self.ability.name == "Blank Joker" then
scale_mod = scale_mod * 0.5
'''
match_indent = true```
the lovely tutorial
put that in a lovely.toml in your mod folder
unskippable cutscene
aight thx
I think that will work
needs header
self.children.floating_sprite:draw_shader('dissolve', nil, nil, nil, self.children.center, scale_mod, rotate_mod)``` put those in too
oh yeah I forgot the header
version = "1.0.0"
dump_lua = true
priority = 0```
thank
aren't elseif and else if functionally the same?
oh no they'd need an extra end
nvm
me when it still doesnt work
*0.5 should half the scale
huh
oh wait yeah of course
because the scale_mod the game defines just pulses slightly
I still don't think it needs to be negative though
looks like it's an addivite modifier
mhmm
did you want the hologram shader on top of it too?
that didnt work half a minute ago, lets see
update, it still doesnt
neither with the code from the hologram shader itself
show code?
code pic
self.children.floating_sprite:draw_shader('hologram', nil, self.ARGS.send_to_shader, nil, self.children.center, 2*scale_mod, 2*rotate_mod) doesnt work either
is it the ordering? or does one of them need to be replaced
try just putting the self.ARGS.send_to_shader in palce of the second nil in the screenshot you sent

it just draws the plain joker?
you could replace the second dissolve shader
currently you draw the shader > draw the card > draw the hologram effect
uh huh
uh huh
huh
me when I dont draw the card:
code?
no the hologram shader should draw the card
well well well
it might have to do with hologram shader expecting to be drawing the translucent joker sprite and doing it on other things doesnt quite work
but also you are being rather rude to people you're basically asking to code this for you so idk im probably gonna peace outta here for a while lol
hmmm
Isn’t that the shadow?
mb its jokes i guess i need to use tone indicators
Yeahh
Yeah
the hologram shader just omits anything where the alpha is 1
are you in 1.0?
Indeed I am
then there's 2 options
option 1 - change the shader yourself and create a new shader here
option 2 - wait for editionAPI to be finished because we have shader objects and it'll stop compat errors
is it possible to inject the shader file using lovely patches?
I guess
although I'm not sure how it'll handle non lua files
I mean option 1 isn't hard
Yeahh
G.SHADERS["key pls"] = love.graphics.newShader(SMODS.current_mod.path.."/assets/shaders/".."something.fs")
non-lua might be fine, but I'm not sure you can actually add files
Oh you're so right
you can add lua modules, which isn't of use
this is better
it'll also be easy to switch to the api when it's released
Where would I best register that?
just in top scope of your mod
SMODS.Shader({key = 'key pls', path = "path.fs"})
yeah that should do, injection doesn't mess with it
this'll be the api version
so if you put the key in the first one with your prefix at the start
you just need to change the definition when it's ready
could even have a draw method on SMODS.Shader that takes in the sprite to draw on
I don't fancy relying on hard-coded mod prefixes
but sprites already have a draw_shader method