#💻・modding-dev
1 messages · Page 10 of 1
are you saying you want me to send my whole mod file
if you used obs, you can 'remux recordings' to change it to mp4
what the flip is overwatch
outplayed
oh
I can't do that much from a glance other than suggest trying a different loop for checking suits.
i.e. make it happen before the draws and stuff
what do you mean by a different loop
like for example, is there a way for me to clear added events queue before adding more?
feels like i could have just make all the accumulated event happen like once
i think context.setting_blind happens before first hand drawn
( imight be misinterpreting the question)
currently what i did is basically wrapped G.FUNCS.play_cards_from_highlighted before G.FUNCS.draw_from_play_to_discard
but that somehow makes the draw at the same time as play cards i think
instead of sequentially
let me try to be a little more specific
this is what it is doing
you just want to remove from the list, right?
basically, before G.FUNCS.draw_from_play_to_discard, I check if this joker is there, if so, put all the highlighted cards back to hand, highlight them, and play them
(I'm doing this because the events I added happens AFTER your cards are tossed)
and what do you want it to do?
after you play your hand, play it again
but not like retrigger, it should count as two hands
I think that was the tricky parts
the problem with this currently is that the game would fill your hand before the second play is done
i believe sixsuits is interfering with this somehow
I can't figure out a way to actually make the event happen in the right time/sequence
because it says i have a spectrum when i only have 2 suits
even though i think it tried all i could
ok yeah it's definitely sixsuits
huh
for some reason spectrum overrides flush
this wouldn't be a problem if it didn't i think
oh it's because they hook into the end of eval poker hand
i have no idea what to do about this
i think get_spectrum is also the reason why is_suit is called SO many times
yes.
this is really annoying
i know exactly why it thinks everything is a spectrum with smeared too
chat i have a quandry
in context.using_consumable how would i get the name/slug of the consumable in question
I have a script that loads the entirty of steamodded into the settings file. As such, a stock version of balatro then loads steamodded. However, this only works on one load (as baaltro overwrites the file like immediatly)
context.consumeable has the consumable information
any fool proof way of checking like a slug or something compared to name?
i think i might just get rid of the smeared changes i don't have the energy to troubleshoot this in the slightest
even with the smeared bullshit off the table i still have the problem where blackboard only shows 1 color tooltip
what am i doing wrong
are you not allowed to run loops in tooltip or something
Wouldn't adding #info_queue+k result in skipping positions in info_queue?
doesn't k just increase by 1 every loop or do i have it wrong
#info_queue already increases once per loop because it's always increasing it's own size
You should be able to just do #info_queue+1
Score at least 0
Is that two blinds at the same time?
How would you even pull that off
Wait
Does destroying_card only work for scoring cards?
bruh
if context.using_consumeable then
for i, v in ipairs(self.ability.extra.tapestry_list) do
if v == context.consumable.name then
return nil
end
end
self.ability.extra.mult = self.ability.extra.mult + 4
G.E_MANAGER:add_event(Event({
func = function() card_eval_status_text(self, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')}); return true
end}))
return
table.insert(self.ability.extra.tapestry_list, context.consumable.name)
end```
am i stupid?
(im trying to check for duplicate consumable usage)
You're not stupid. Did you see how Mutated Joker does it in Codex?
yeah i have it pulled up right now
i see it references G.GAME.consumeable_usage
(though i havent updated my version yet 
yeah im
stumped
gonna sleep for tonight, too frustrated to code
can someone tell me about before, immediate and after for events? They are all performing in the same way for me...
I don't think anyone has ever looked into how G.E_MANAGER works
hmmm
and it makes me want to die 
um, its increasing.
constantly
Well, it exists now.
ohthat's neat
Gonna also do in hand as well
wait you made unscored card destroyable??
With the power of Lovely yea
that's lovely 
I'm thinking of making a joker context extension API
Only thing stopping it is that there's not that much we can add
As almost everything already has a specific context
Only other thing I can think of is on draw
For stuff like "If you draw a King, gain .5X Mult"
on the end of discard
if you discard more than one
so post_discard
right now i use a hack to do it
oh yeah i can use lovely to send the chips score through context now
You can already do that through checking if the card being discarded is last
Just like how Faceless Joker does
yeah that's what i did
well not really
i counted highlighted card and see if the discard happens for that amount of times
is it safe for order swapping?
well this felt somewhat shady tbh
Then it is hooked up into a G.E_MANAGER event so it's technically not immediate (I think)
how do i make a joker gain x1 mult if the played hand has a specific card
right now in my tiny brain before, immediate and after are not so different
idk about before events
immediate events make it so that everything won't run on the same frame
after events add a delay
but they still happen in the order of which is accumulated right?
That's done too
Quick question about syntax, which one would be prefered? Making a new one with a different name or using the already existing context and specifying if the card is scoring or in hand?
Former is easier to implement exclusions for already existing modded jokers using this context, but the other one is more in-line with how the game handles context.
fuck, just discovered that for some reason every events added in play_cards_from_highlighted is after events added in draw_from_deck_to_hand?? why the hell
i think former? just so that it is not too confusing
i probably won't touch it personally unless it's live on steamodded one day
yeah it should act like a queue
having the same problem
i need to figure out how to exclude dark fountain from appearing literally anywhere except the collection and knight spawning
tag it
tag
never call it anywhere, problem solved
is this a common solution or personal?
I also want to do this
i think its common, you can call it to make it start appearing when something happens. but i don't call it so it only appears when set to be added by something else in the code(in my case its a deck)
only place it appears
yea thats what it does
pool flags already exclude them from shops
It's what controls Gros Michel and Cavendish
oh so for a joker to not appear in shop, we just do SMODS.Jokers.j_joker_name.yes_pool_flag = 'whatever' and that's it?
yep
just make sure to not call the whatever in the code otherwise it'll start appearing
i think thats what they do
aaaaaaawesome
just uncallable tags
gonna make all xplaying jokers exclusive then
Don't think so, they're just natively not factored in when generating jokers in the shop
right now it basically corrupts legendary pools which is kind of annoying
oh i meant whether having this tag would also prevent soul to spawn certain legendaries
i'd have to check
i think it does prevent soul spawn
It would go through the pool flag checks yea
lmao i was hacking this before
so basically i made my mod's default joker to manually remove every jokers from my mod from the pool
guess i was the caveman
time to fix that
oh btw do you just do it when you set sprite for your joker?
I just kind of stick it in between sprite and loc_def.
lovely
It does prevent soul spawn.
(if it didn't i would have a dawn deck card on top of these ones)
moved rarity to 4 to check
i don't understand the question
oh i understand now
its the deck's sprite on a joker designed for the deck
a flipped joker?
then when deck is played i just add a negative eternal version of the joker
no, its the sprite of the joker
you have no idea how tempted i am to keep this placeholder art
it would look like the deck sprite when flipped but it can only be found in the deck and negative
so no art problems
just make on eye blue and keep it
blind with sans music
i might make jokers for undyne and undyne the undying that are like gros michel and cavendish
oh my god
what if the undyne the undying one
whenever it got destroyed it came back stronger
that could be so interesting but also scary
does anyone know if you can add a card with steammodded without adding it to the pools/collection?
snow just talked about it a bit ago
here
thanks, but it still appears in the collection
it may be harder removing it from collection.
guess i'll go with not using smods api then
In 1.0, you will
<@&1133519078540185692> GET THEM
<@&1133519078540185692>
smods
what did I miss here lmao
Bot account pulled up
its better to have missed
oooh
ahh
ankh gaming
hex gaming, ghost deck gaming
madness gaming
i'll maybe make it a chance to come back instead of guaranteed
doesnt work since i'm hooking into start_dissolve
i couldn't find any other way to tell when a card is destroyed
just add at the end not context.selling _self
i did and it was nil
context.selling_self is clearly just not set during that event
i did the exact same thing for one of my jokers, just have self.ability.extra.being_sold = false, change it to true when sold, and then in card.start_dissolve make sure it's false
i see
that's clever
ok yah im definitely giving her a chance to die permanently shes way too strong LMAO
it fits anyway
why does it say "attempt to index field "atlas" [a nil value]" when i go into my collection and try to see my joker
Animation is a little scuffed but I'm not sure exactly what I can do about that, either way, new context just dropped
for some reason when undying is first created she has X1 mult even though i put x_mult = 2 in the config
crap im dumb as heck
you aren't registering your sprite
i think with the nerf, starting at 2x and coming back with twice the mult is balanced
Probably because the game uses self.ability.x_mult for stuff which might be screwing with it
Swap it to self.ability.extra.x_mult and it probably wouldn't be an issue
can you make it gain the xMult regardless of if the probability hits so if it returns through another method its still buffed?
i dont think so because it creates the new card while it's being destroyed and sets its x_mult based on its own
Delete the sell button on the joker 
how do i give myself a joker easily, i need to test it
alr
she's died on the second destruction twice in a row for me 😭
...i need to have her use G.GAME.probabilities.normal
oh god
this is so scary
its not consistent because oops all 6s could just get destroyed but still wow
cough cough ceremonial dagger cough cough
so how do i get the scored cards? is it just G.play.cards?
i really dislike the chance decreasing though
why
hey guys sorry to pop by but i notice this is where people active rn, does the update fuck with mods?
at anything below a 1 in 2 chance it's just stupid to try destroy it again
yeah true ig
then again
you could literally make her immortal with oops all 6s if she was just a 1 in 2
unless it was 1 in 2 chance to die but thatd feel dumb
yeah, i had that issue with a joker i'm working on
my solution to it was kind of... non-standard
i think i'll stick to the chance decrease for now
ok, but maybe start at 3 in 5 and increase the denominator by one each time
yeah i guess 3 in 5 is more fair
remember that still means in 40% of runs the joker will do nothing
i could also do something like 3 in 3 to give her 1 guaranteed revival
...oh god imagine her with lucky break from balatrostuck
true
what's that?
3 in 3 with all 6s would be... 4 guaranteed revivals
joker that makes all chances succeed in the final hand
you can't destroy jokers during scoring though
i'm not sure if it's during scoring or when you have 1 left hand in general that's probably a question for akai
one piece of advice about joker balancing is to not be too worried about powerful synergies between two specific jokers. there are so many jokers in the pool that the player deserves to have a little fun if they luck into the perfect combo
yeah fair
just think about photograph chad, vampire midas, etc.
how do i check if the scored hand contains a certain rank of card
i'd suggest referencing the original code for stuff like this
it'll usually have the answer to your question
im trying to use context.other_card:get_id() but its not working
attempt to index field "other_card" (a nil value)
Like how 8 ball does it?
I'm trying to think of other Jokers that care about a certain rank to look at
why do i need to have these in reverse order of nominals basically everywhere? i only just realized this makes sorting by suit vs. view deck UI hella inconsistent
do i just loop in reverse, adding new suits at the top of view deck instead of at the bottom?
well i got my code not to crash
which is progress
i need it to count cards that arent scored
its only wanting to count the cards that are scored i think
use or rather than and?
i want it to only activate if played hand contains all those A, 9, 8, and 4
yeah, but it's going through each card and checking "is this an ace, a 9, an 8 and a 4" and unsurprisingly saying no each time
this is new 8 ball, which has a different effect to what i think you need
Also would you need to specify if this is context.before or context.after?
Or neither if I’m understanding this code right
i want it to activate after all the cards are scored but only if played hand contains aforementioned ranks
oh ok, then you need context.joker_main
then you can loop through context.full_hand
yeah, often times there's already code right there for what you want to do
I had a similar idea but for a Joker that only revives once. Interesting
now it works but it immediately crashes after
bad argument #1 to 'ipairs' (table expected, got nil)
What did you put in the ipairs? And under what context is it?
the weird thing is it works and detects all of them and does the if statement below that, and then gives the error
Maybe that context is called somewhere else where there's no context.full_hand
Also fun tip if you want to check if a boolean is true you can simply write if ace and nine and eight and four then
woah
Try adding and context.full_hand to the first if line
if context.cardarea == G.joker_main and context.full_hand then?
Yup
I have messed with them and they performed differently for me
it works tysm 🙏
I think there's a lot of context which can be done with hooks, but which could help. is_suit, selling other cards, buying self, etc.
wait why does the card trigger for each joker
Check Cavendish
Because of the context you used
sorry i'm late but i'm pretty sure i understand what they mean
so the event manager keeps a queue of all of the events that are ready to take place
it also keeps a series of delays in this queue
for example:
- delay(0.5)
- eval_status_text gros michel
- delay(0.2)
- destroy gros michel
Should I use G.jokers instead?
if you add an event with immediate, it will add it directly to the front of the queue, but behind any delay that's already in progress
Try it.
if you add an event with before and pass in a delay of x, it will add your action to the back of the queue and then put a delay(x) behind it
it.. kinda works? like it looks like it activates twice but it only does anything the second time, but it makes a little red particle both times
whereas if you use after, it will still your event at the back of the queue, but even after the delay
i'm not completely certain of this, this is just what's worked for me so far
@queen scroll Do you know why some events speed up when there are a lot of them?
no i don't
i assume it's something hardcoded into the event manager, but idk exactly how it works
I was told that but it doesn't seem to work in some circunstances like drawing multiple cards individually or creating events while in the shop
just use if context.joker_main
i would guess that's just a parameter
you'll have to look into it yourself
But which parameter? I've looked through all of them already
thx for the explanation
it's lame that lua doesn't allow that
When someone figures that out please tell me ;_;
you will probably have to figure it out yourself
I've pretty much given up already
sometimes you just have to move on and think of another way
works perfectly 👍
The other way is to ship it as is until someone else figures it out
i'm cracked at this 😎
Also how do localization works
Or maybe the issue is when trying to add the tooltip badge for something else
depends on whether you're dealing with ui descriptions/tooltips or not
if you're not, then it just looks up a code in a lookup table
if you are, then it looks up the code, then does some funky stuff to turn it into ui objects
yknow, like these ones
the god awful annoying ones
I’m trying to add a new entry to the localization table then edit another part of the code to add the tooltip to a card
But it gives me an error when I use a custom one
if you're using steamodded i think they have an api for that
Not for Editions, I think
Besides I don't want a new edition, I just want a new tooltip
i think you could probably hack it out by making a print_table function (or stealing the one i put in enhanceAPI, idm)
that's how i've dipped my toe into
nodes
I've already hacked tables
But the code for editions already exists and works. I can change it to another existing tooltip. But my new one doesn't work and I don't understand why
how the heck do i make it so it adds x1 mult to the joker each time i do a specific thing
cause i know that if you do #1# in the loc_txt it will access the loc_def or something but i have no idea where to start with that
why do you check if they are true ? do "if ace and nice and..." (mb it was already recommended)
I would also put them in local.
look at the joker api example on the steamodded github
I would also put an else for debugging pruposes
Good work! It's getting there.
I would also do "if contect and context.cardarea == G.joker_main and context.full_hand" at the beginning
If it still bugs after all that
attempt to perform arithmetic on field x (a nil value)
also, just do ace = name:get_id() == 14 and so on
nope, because it would put them to false at the end
ace = ace or name:get_id() == 14 (would maybe work)
is this valid or am i doing something wrong
yeah, nevermind. didn't look at it completely
Check when you do a specific thing then add to an extra variable in the Joker when not context.blueprint
Funny flavor, but I think your arguments are in the wrong order
You want xmult to be in ability. Also, there’s a native name for this which works with existing code do you might want to check that
I did it’s Xmult
Actually nevermind
where is ability
I added it to extra
local joker = {
slug = "the_one",
name = "The One",--name used by the joker
config = {extra={Xmult = 6, type = 'High Card', rank = 'Ace', suit = 'Spades'}}, --variables used for abilities and effects.
pos = { x = 0, y = 0 }, --pos in spirtesheet 0,0 for single sprites or the first sprite in the spritesheet
rarity = 3, --rarity 1=common, 2=uncommon, 3=rare, 4=legendary
cost = 8, --cost to buy the joker in shops
blueprint_compat=true, --does joker work with blueprint
eternal_compat=true, --can joker be eternal
unlocked=true, --joker is unlocked by default
discovered=true, --joker is discovered by default
effect=nil, --you can specify an effect here eg. 'Mult'
atlas=nil, --defines the atlas that you want to use for the sprite sheet. atlas=nil if you want to use single sprites
soul_pos=nil, --pos of a soul sprite.
}
joker.calculate = function(self, context)
if context.cardarea == G.jokers and (not (context.before or context.after)) and self.ability.name == 'The One' and context.scoring_name and context.scoring_name == self.ability.extra.type and context.poker_hands and next(context.poker_hands[self.ability.extra.type]) then
local the_one = false
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 14 and context.scoring_hand[i]:is_suit('Spades') then the_one = true end
end
if the_one then
return {
message = localize{type='variable',key='a_xmult',vars={self.ability.extra.Xmult}},
colour = G.C.RED,
Xmult_mod = self.ability.extra.Xmult
}
end
end
end
joker.loc_def = function(self)
return {self.ability.extra.Xmult, localize(self.ability.extra.type, 'poker_hands'), localize(self.ability.extra.rank, 'ranks'), localize(self.ability.extra.suit, 'suits_plural')}
end
return joker
did you do the modification we told you ?
And did you try returning { mult_mod = 1} ? if false
This Joker gives xmult when played hand is High Card with a scoring Ace of Spades
I could add a break to make it slightly faster
shame on you for not doing it ! (jk XD )
Anyways, if you want to increase Xmult, just have an Xmult_mod (or hardcode the increase) and increment Xmult when it's not context.blueprint
Even my sound API I have 2 loops that do almost the same thing but I just didn't bother to combine the 2 of them
Actually better than break I think I can just return out of the loop
so true lmao
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 14 and context.scoring_hand[i]:is_suit('Spades') then return {
message = localize{type='variable',key='a_xmult',vars={self.ability.extra.Xmult}},
colour = G.C.RED,
Xmult_mod = self.ability.extra.Xmult
} end
end
ok now help me localize and event manage
is that not what break does in lua?
and generate ui
AFAIK break exits the loop, return exits the function
return exits everything inside the function
But it's different
Oh, I mean, I'm looping only to set a boolean to true and if true do something
Instead I can return immediately when I find it
I don't even need the boolean

oh, now i get what you mean
for i = 1, #context.scoring_hand do
if context.scoring_hand[i]:get_id() == 14 and context.scoring_hand[i]:is_suit('Spades') then
return {
message = localize{type='variable',key='a_xmult',vars={self.ability.extra.Xmult}},
colour = G.C.RED,
Xmult_mod = self.ability.extra.Xmult
}
end
end
like this?
I did it (I think) and it says ']' expected [to close '[' at line 12] near '='
does not output the same thing if you have something after your loop and when your loop ends
yeah, I know. Just misunderstood what you wanted to do
oh okay x)
don't have the name =, slug =, etc
we thought you were generalizing XD but in our case yes it would have done the same thing
local j_george = SMODS.Joker:new(
"George Orwell",
"george",
etc.
k
I think you must be missing something before line 12 maybe
attempt to index global 'self' (a nil value)
You have a self where you shouldn’t
card should work
when i did that they activated but just did nothing
Excuse me Discord?
Tbf thunk is inconsistent
See
Try SublimeText too
should it be rare or legendary
I think either works
I’d nerf it and make it rare
x0.5 instead of X1?
I’d consider a different effect for flavor but I have no idea what so this works
Ya
Then x1 is fine, maybe even weak
True
It could work as a legendary but they’re hard to get and being hyper specific means they’d get ignored
true
I think the reward could be different but Idk what
im so bad at pixel art
Well you can't get worse so that's always a plus.
morning chat
balatrostuck is nearly done cooking in terms of jokers
soon we will move onto things like
Aspects

this would actually be almost correct in steamodded 1.0 haha
(would just need to replace (...) with {...})
the slug on it is george, why isnt it going for george.png when loadin
it's j_george
?
its loading jimbo pic instead of the custom thing i made
Whats your sprite loading line looks like?
idk how to make that
Check the steamodded github wiki section
how do i find the slugs of vanilla objects?
theyre all defined in game.lua
ew mixels
sus
no u
Guess what happened here
mixel joker
+X mult to the next multiple of 10
guess what's left for me to deal with >_<
oh shit challenges
it's just view deck stuff
but gosh, it's ugly UI code
i first need to figure out what the things I changed even are, and maybe then I can make it use lovely and get rid of redundant code
Hey all, I'm completely new to modding and LUA, just trying to make some simple jokers to get my bearings and I'm kinda having trouble knowing where to start lol, I'm following the steammodded wiki page but unsure of how the atlases and sprites work. I think that's causing me to get this error
My code (copy + pasted from the wiki basically)
the atlas 'Jokers' doesn't exist - you should just leave the atlas field blank if you want the default spritesheet for jokers to be used^^
i believe its name is 'Joker', but the game knows better haha
Ok I removed that text but now instead of opening and crashing on Collection screen it's simply crashing on load. Error message seems to be suggesting an unclosed bracket but I can't see one?
remove the comma after 'Mult'
Exact same error message
Ah, I see they got caught when trying to beautify the code. Thanks!
Finally, my first Joker idea (though not in the way I wanted to implement it, but in an easier way)
Time for paredolia and Canio to go to the moon
Interesting combo
Lemme test it
Sorry to keep spamming this chat with noob errors but I've managed to get past where it would crash before, it now shows up in collection but as soon as that page is loaded it now gives me this error and I cannot for the life of me figure out what nil value I have created
can you send me your file ?
Lua or save?
LUA
to compare declaration
oh I know
SMODS.Joker:new is outside of your SMODS.INIT
Nope
James had same error with his BadApple Joker,
Check this PR :
https://github.com/jamesthejellyfish/JellyMod/commit/1707c289d53fa4c02c8a4ed7383ed067dde023e1?diff=unified&w=0
you will understand what I mean by outside of SMODS.INIT 😉
The joys of only having Python coding experience I suppose lol, not used to all of this declaration
Python has __main__ though
True, but I mostly write scripts to do quick and dirty data analysis rather than anything too serious haha
Check existing working mods, adapt xD
That's the idea lol
Tell me if new INIT works 😉
Now it works
Does indeed, thank you! Now to figure why it's saying it add ERROR mult lol
I'm following this at the moment but thank you!
you'll need a loc_def function, putting variables in your description doesn't work out of the box
The only remaining issue is that if the card is added while the Goad is active it’s not debuffed. But otherwise my code is identical to Grim, which does has its Aces debuffed, so I don’t know what’s the difference here
are you not calling Blind:debuff_card anywhere?
from #1221916334372290620
function CodexArcanum.Alchemicals.c_alchemy_oil.use(card, area, copier)
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.1,func = function()
for k, v in ipairs(G.hand.cards) do
delay(0.05)
v:juice_up(1, 0.5)
v:set_debuff(false)
v.ability.extra = v.ability.extra or {}
v.ability.extra.oil = true
if v.facing == 'back' then
v:flip()
end
end
return true end }))
end```
If it can help
No, but neither does Grim
it actually does get called when grim is used
create_playing_card calls the Card constructor, which in turn calls Card:set_base(), which calls G.GAME.blind:debuff_card()
Me too
It's the same timing as Certificate too. Let me test how that Joker works
Certificate works fine
certificate manually calls G.GAME.blind:debuff_card(_card)
Where
Oh!
I'm using the old version as reference
That should fix it
- Fixed bug where the card generated by 'Certificate' was not being debuffed by the boss
it's in the patch notes
Getting an error even though it's literally copy + pasted from the wiki? Error seems to be on the line info_queue[#info_queue+1] = { set = 'Other', key = 'my_key', vars = {card.ability.mult} } -- Custom tooltips
that part is a bit confusing, I know
but there isn't actually a Card being passed to the tooltip function, just a proto center object
card.config.mult should do
What does everyone think?
It was first idea I ever had for a Balatro Joker. It's not exactly what I first envisioned because that's hard to implement, but the result is the same. Also this has neat synergies
Looking at other mods in the value section of the SMODS.Joker they have {extra = {}} instead of just values, is this something seperate?
The extra dictionary serves to hold just about any information the Joker needs.
So it's custom made for Jokers
Other entries in the dictionary that contains extra are more widespread
Also a similar concept which I find less interesting, but it's amusing because Homestuck reference
i never asked do you guys think this is good for a legendary
The condition is a bit plain but otherwise yes
eh i thought it was nice and straightforward
what does dark fountain do?
See tooltip
oh I missed that
This is a minor thing but it may sound better "Create a negative Dark Fountain when boss blind is defeated"
seems strong, I like it
Too straightforward IMO. I do think that makes the Legendary more competitive, but on the other hand that makes it less interesting to me
I disagree
I prefer trigger condition -> effect
so basically 2^x
maybe if it added a condition like "without using discards" for example
Even something minor would make it more interesting
i could have it trigger when it's defeated with no light suits or smth
How about it debuffs itself when you play a red suit?
maybe idk
What does this error mean: Could not decode PNG image (custom zlib or inflate decompression failed)
ok, it just... started working
nvm its still not showing the correct sprite for my joker
it means you probably need to free some memory
how?
by closing whatever programs you have running and don't need to be
oh
i still dont get why its not showing the sprite though
it just shows jimbo
oops, i was just being DUMB
Sorry if this isn't the best place to ask, but does anyone know how I could get just a blank white card with the foil/holo/poly shader on? I just need a clean image of each edition to work with. But I'm clueless on how to work with shaders like this.
What exactly are you trying to accomplish?
Just get a nice clean image of the foil/holo/poly patterns to use in photoshop for various things
Without help from anybody else - probably the easiest way would be the Deck Creator to create a specific deck and then to "erase" the printed text/suits from the texture for the playing cards.
*"\resources\textures\1x\8BitDeck.png" *
*"\resources\textures\2x\8BitDeck.png" *
yeah, it's either that, or commandeering the editions ui box
and telling it to draw the "centers" atlas at {x=1, y=0} instead of the "jokers" atlas, at jimbo's sprite position
I'd go for something like creating a tarot that changes a card to the blank card (set_base(nil) or something should do), then cycling through editions by pressing q with debug mode enabled
or yeah, using the collections page and changing the sprite
ok thanks for the advice! 👍
why does this cause issues
what issues does it cause?
something about expecting a }
wait how would i make a card give an effect already in the game, like steel or wild
I have a mod that’s supposed to add a blank card, but maybe an easy solution to do yourself would be to just make the playing card face textures transparent
They’re stored separately from the base so I imagine if you replaced the texture atlas with a transparent one temporarily you can get a blank card
i wonder if it's possible to make a consumable buff your next hand
Codex Arcanum?
does codex do that?
Idk
sorta? cobalt upgrades your current held hand
'then' expected near '='
on line 36
my idea for a weird hacky way to do it is have the consumable create a joker that just destroys itself after one hand
= is assignment
oops forgot == instead of =
you are also missing commas
alternatively i could maybe do something like thac joker tarot where it stays in your consumable slot?
Two comments: apparently the context main_joker does that for you already; and personally I think you could have a global config variable that’s checked when you start a hand
yeah i guess i could just hook into calculate_joker and use a variable
It’s not clear to me how main_joker works exactly, but that Voucher that ensures you always get your most played hand planet uses it, and AFAIK it’s the only thing that does
i do want it to be visual in some way though
I meant hooking it into evaluate_play, probably
now it says <eof> expected near end on line 72
oh yeah true cause you could just not have any jokers
which is the end of the program
You can hook the function that computes base hand score and use the global config variable
Just curious, I want to make 2 jokers with effects very similar to currently existing jokers - What's the best way of replicating the behaviours (The jokers in question are Invisible and Ride the Bus)
Reading the code
Of the game
Or mods that work similarly
Is it decompiled somewhere?
open the exe as an archive with 7zip
Cool cool
wide candace
Is there a wise Candace?
there are some jokers (like the ones that give mult when you play a specific suit/hand) that are coded differently to most other jokers, but depending on the effect it shouldn't be too hard to get what you're looking for
That's me when you ask me questions about stuff that I actually know about (LUA is not one of those things)
What do you know about?
I'm pretty good at maths
Why so many math people are Balatro players
try adding commas in the objects that you return, that's probaly not eh problem but it might help later
Number make brain go brrrr
It’s like thunk is trying to get math people into statistics gambling
Maths people are already into gambling
Just nobody wants to play with them
Not really
i think thats how i won a game of five crowns with 24 points
Balatro isn't really about math or statistics and statistics don't really factor in all that much
except it is
The closest Balatro gets to conventional math is through mental arithmetics the game makes you perform every time you hit play
I think there’s a lot of math in it
Wait what’s conventional math to you
Because then I might agree lol
Technically you can optimise your discards and throwaway hands through doing hypergeometric calcs
People think math is arithmetic
Dweeb shit
TRUE
Maybe trigonometry
I’ve thought about writing an algorithm to optimize discards because I’m curious about it
But it seems too large for classical dynamic programming
Most math in like, a mathematician sense is closely related to calculus, statistics are more of a data analyst field
Sure, they require arithmetics and graphing, but that's more like tools
Rather than the actual devices
Calculus is much more related to data science than pure mathematics (source: I am a pure mathematician)
Algebraists and logicians:
That too
they teach you statistics in math class, therefore, statistics are math
What do you study?
I have a masters in mathematics, my specialism and dissertation were in advanced group theory and topology
So algebraic topology?
I did some crossover but I meant more as two disticnt subjects (My dissertation was on Topological groups though)
I did a lot of topology and my best subject was Galois theory
I’m an applied mathematician so I look at algebraists like normal humans look at mathematicians
Some of my best friends are algebraists—
At least you're not an engineer 
;P
lmao
I went to university and then realized that it's a scam that does nothing to progress my development and that a focus on academia is detrimental to my growth as an artist and as a programmer so I dropped out 
Or even worse, an econ student
I’m currently in an engineering school tho @_@
That's fair, compsci at uni is largely theoretical and not super useful at a programmer level
I knew a person doing both economy and applied math simultaneously (in two different universities) but they dropped out of economy for math
“Economy math was too simple.”
Paraphrasing
Didn't do compsci, did a gamedev course (hate pure compsci with a passion)
I took design classes in high school, including game design, but ultimately I decided I’d better follow a stem path
That might be because you're not specifying the right context
What's the correct context?
afaik you put the calculate function on the joker before you register it
Just saying that the cardarea should be G.jokers means nothing to the large if else tower of doom of Balatro
Idk read the conditional tower to find out
haha that has nothing to do with it
The easiest hack to get thing to work and then shoot yourself in the foot later down the line is
if context.cardarea == G.jokers and context.joker_main
Look for the calculate_joker function to find a relevant Joker and see when it triggers
joker_main is a very weird context
how so?
It only shows up one time in the source code
For Observatory voucher
Which isn't even a Joker
what
by the way, mult and mult_gain should be in ability.extra not in ability
this is because ability is a reserved table in Balatro that exists because it automates the execution of a lot of jokers
ability.extra is not reserved
Yeah I had them in one, I removed it to see if that was what caused it to not add mult
It works!
so you have to wrap your ability/config table in an extra{} table
but you want that to be the case
you want it wrapped in an extra
right now you have two issues
a) wrong context spec
b) wrong config spec
Fantastic art and creative effect
Are you controlling the speed manually?
no it just got faster and faster
I wish I knew how v_v thanks anyway 🙏
as if it's one hand played
i think it's how vanilla game deal with longer and longer executions
Only during scoring I believe
Because it doesn’t work in the shop
but what kind of execution happens in shop?
Also it doesn’t work when you draw individual cards
A Joker that buffs each one of your Jokers
oh i see what you mean
probably a state event
check if anything in STATES.HAND_PLAYED would differ from, say STATES.SHOP
ACC is conventional for storage
Storage?
yes
In a computer's central processing unit (CPU), the accumulator is a register in which intermediate arithmetic logic unit results are stored.
Without a register like an accumulator, it would be necessary to write the result of each calculation (addition, multiplication, shift, etc.) to cache or main memory, perhaps only to be read right back aga...
It's short for an Accumulator
Ah, accumulator
could've said that ^^
But it shows up in ```lua
G.ACC = math.min((G.ACC or 0) + dt0.2self.SETTINGS.GAMESPEED, 16)
then that might be acceleration
this is why you should never abbreviate
abbreviation is the work of the devil
i use acc for accumulator in my code LOL
ok wh. T. abb.
i would have used spd for speed personally LOL
chat when I get home I have a coding quandry
Is that a pantry with four sides
Mostly because I can't parse what fields are returned in context consumable
that sounds interesting, im in
It's nothing too complicater
I just want to record when a consumable is used and check it against a list to see if it's been used before
So I've put it back in the extra table, and I've looked at a relevant joker (just the normal +4 mult joker) and the context appears the same but this is what's happening in game https://outplayed.tv/media/wXYGMZ
To capture and share your gaming highlights, download the Outplayed app on Overwolf
oh you can probably look at Cruxite Dowel code then
Doesn’t the game keep a list already?
that's because you haven't changed the localization target
the var here has to be card.ability.extra.mult
I'm pretty sure it does but I'm not sure what field is recorded
also Lyman I'm gonna send you the Cruxite Dowel
Or rather what I would check context.consumable.blah
SMODS.Jokers.j_cruxitedowel.calculate = function(self, context)
if context.using_consumeable then
if #self.ability.extra.consumables_orders < 3 and not context.blueprint then
table.insert(self.ability.extra.consumables_orders, context.consumeable.ability.order)
end
if #self.ability.extra.consumables_orders == 3 then
local table = self.ability.extra.consumables_orders
local alch_idx = ((bitoper(bitoper(table[1], table[2], AND), table[3], OR) - 1)) % #G.P_CENTER_POOLS["Alchemical"] + 1
local alch_name = G.P_CENTER_POOLS["Alchemical"][alch_idx].key
if #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function()
play_sound('timpani')
local card = create_card('Alchemical', G.consumables, nil, nil, nil, nil, alch_name, 'crux')
card:add_to_deck()
if G.GAME.used_vouchers.v_cauldron and pseudorandom('cauldron') > 0.5 then
card:set_edition({negative = true}, true)
end
G.consumeables:emplace(card)
G.GAME.consumeable_buffer = 0
return true end }))
end
if not context.blueprint then
self.ability.extra.consumables_orders = {}
end
end
end
end
this is how Cruxite Dowel gets consumable IDs
its context.using_consumeable for the clause itself
and context.consumeable for getting the exact details of it
Amazing, thank you
if you want to just know the unique detail of each I'd just like
make a table and each table would contain Order + Set
Oh bless up I'll have to look at that when I'm not on mobile
I just need the name is all
yeah I told you
context.using_consumeable for the clause itself
context.consumeable for getting the exact details
Yeee
So you'd have sth like
if context.using_consumeable then
if table doesnt have this thing specifically then
local result = {
id = context.consumeable.ability.order
set = context.consumeable.ability.set
}
table.insert(self.ability.extra.consumeables, result)
end
end
because if you want to check if a consumable of any kind has been used then you just need 2 values
the order and the set
because order duplicates between sets
because the order refers to the position in the center pools
This was basically my code that I had earlier
The order and set explanation makes sense though
I wasn't doing either
yee
I'm assuming something in these context calls are wrong (I want it to gain +1 whenever a non-straight hand is played and reset when one is played)
this is wacky and i wonder if manually replaying a hand twice could be used for some other fringe cases
Names of upcoming jokers for my mods
I remember suggesting Damocles to someone
Was it you?
Curious about Damocles
Oh shit has it been done before?
I don't think so
What's the proposed effect
I had suggested it to Lyman #⚙・modding-general message
If you play TBOI it's something similar to an item of the same name
Oh, wonder what he made then (if he did)
i dont know how alchemical cards work programming wise but i just realized
if borax affects the actual deck then it'll be really good with integrity
any glsl shader whizz kids here?
oh this is easy
I have figured it out!
good
is lovely behaving a ok? haven't been keeping track of things
Ew wait I just realised Lua starts idexing at 1
it bit my finger so i gave it some hard candy
Ikr?
Again, apologies for asking so many questions but what should my end context be in this code so it doesn't do the strange trigger on every card? It's not adding to the mult on any of those triggers either so I just find it strange https://outplayed.tv/media/44zVzJ
To capture and share your gaming highlights, download the Outplayed app on Overwolf
Actually I think I fixed it, it's to do with the elseif being linked to the context.cardarea if and not the context.before if
Okay one last question (for now) How do I make the text of the card update after an upgrade?
use loc_def
example
just put any variable(s) in the table and in the card's description add #1# #2# etc for each one
Great, cheers!
I'm trying to make a patch but it doesn't seem to work. However an older patch still works.
eg. it works on an older version but not a newer one?
it has been on my end
No, a different patch which I wrote previously ^^
I've had some stupid errors or things not getting parsed, but that more my incompetence to write regex than lovely
(i keep needing to remind myself to escape every bracket)
but no issues specific to 1.0.1e or 1.0.1f
version = "1.0.0"
dump_lua = true
priority = 0
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "if (G.STATE == G.STATES.HAND_PLAYED) or (G.STATE == G.STATES.NEW_ROUND) then "
position = "at"
payload = '''if (G.STATE == G.STATES.HAND_PLAYED) or (G.STATE == G.STATES.NEW_ROUND) or true then'''
match_indent = true
overwrite = true
This is what I tried (in an attempt to debug) but had no effect
are you sure the space at the end of your pattern exists?
these are extremely inconsistent and I feel bad for relying on something having or not having a space because it may well be changed at any moment
One shows up here but I guess I can try without it
removing the space made it work
hmm
i guess the pattern patch trims trailing whitespace?
leading, I was aware of
trailing, I've only really used in regex patches to find a unique anchor that would have otherwise required more text
dunno about pattern, but i guess that's how that works
I can't remember if I'm calling trim or trim_start on the line
yeah, trim, so it removes leading and trailing whitespace
hm yeah idk how i feel about that
Alright, does anyone have any suggestions on how I can manipulate this? I can set it to always increase acceleration, but my attempts so far to have a variable control it haven’t worked
This might be because I change the variable inside an event, but I’m not sure
Sans is not okay
whenever he talks the text doesn't show up and i'm not really sure why
i basically copied the card_character code
Maybe there's a state issue?
is there a way to make it so the game only has modded jokers?
I made the same thing and had the same issue (and I fixed it)
how do you attach the text?
g.localization.misc.quips
yeah how do you insert the text into it
local additional_quips = { table_with = your quips }
for k, v in pairs(additional_quips) do
G.localization.misc.quips[k] = v
G.localization.quips_parsed[k] = {multi_line = true}
for kk, vv in ipairs(v) do
G.localization.quips_parsed[k][kk] = loc_parse_string(vv)
end
end
I have this loop to add text to the localiziation
(me when I was making talking card and then someone else makes the same thing 🥲)
ohh they need to be parsed?
im so confused
how would i make a joker that makes all of one rank act as every suit
I think maybe Autumn or someone else had a Joker talk
What if I removed naneinf?
Probably hook into is_suit to check if you have both a Joker and a card of the appropriate rank
hook Card:is_suit() to always return true if the card is that rank and the joker is present
I know how to accelerate, but I don't know how to brake
This is... somewhere
wait noooo
I forgot to have OBS mute my youtube playlist
bruh
I think you need to hook it properly otherwise the game won’t know how to compare suits normally
oh
yep you still need to call the original
so like this then?
uh not quite
local card_is_suit_ref = Card.is_suit
function Card:is_suit(suit, bypass_debuff, flush_calc)
-- your code here
return card_is_suit_ref(self, suit, bypass_debuff, flush_calc)
end
In your case, this is “your code here”
A better comparison of the speeds. If anyone else has dabbled in this any information would be helpful ^^
still doesnt work
im trying to play a flush with 4 of one suit and a joker of another suit
jack* not joker
I think it's pretty much a x1.5 final score, but with all the cards able to trigger some accumulative jokers twice as well as having it count as playing this poker hand twice
changed it to be "Jack of All Trades" instead of "joat" and now it works
lmao

is there a mod reload button?
no
darn
would inf >= inf not also be false?
oh mb i forgot it's not that weird

Dance, Jimbo, dance!
wait until there's some other mod that has an edge case that relies on this not being inf
Well I mean my mod is litteraly just adding inf to this so if it does, it just straight conflicts with my mod
Fixed the glitched fire
Now I’d like to see mod interaction when you have both this and Balatrostuck
oh god there's like 3 talking jokers in progress
Talking Joker Yaoi when
first the regular named joker yaoi scene has gotta grow
how do i define loc_def for #1# and #2#
Return an object with two elements in loc_def
oh ig that makes sense
guys is this joker good
Joker gaming
society
can you do (card).ability.whatever, or can you only do (card).ability.extra
ok so I'll explain this once here
card.ability is used by Balatro vanilla Jokers - it contains predetermined variables that are used to automate generic scoring abilities
card.ability.extra is whatever it needs to be - it can also be a table, and that's what we use in mods because it allows us to create our own extra variables that we have full control over
so i could do card.ability.extra.whatever
its giving me error: attempt to concatenate a table value
ok
i just
ok
theres just not really any way to fix it if i have no idea whats wrong
oh my god
oh i never even changed my table insert
ok it works now but now im confused
ok am i dumb
local result = {
order = context.consumeable.ability.order,
set = context.consumeable.ability.set,
}
for _, item in ipairs(tapestry_list) do
if item.id == result.id and item.set == result.set then
return nil
end
end```
its working on checking for sets but not the specific card
you're storing order and set
good
new speedrun timer UI looks really clean
oh yeah wasn't that mod obuscated?
if so, isn't that against #📜・modding-rules #6
or was it changed?



