#đ»ă»modding-dev
1 messages · Page 555 of 1
your a life saver, thank you so much for the help! ^^
Always refer to this when you have issues https://github.com/nh6574/VanillaRemade
Check cryptid code
which exactly? I never played cryptid so i'm not sure what card does something like this
p sure its the run card
alrighty
ye i found it just now no worries, thank you regardless c:
although this is pretty complex mm
did you ever figure this out? i came up with a really similar deck concept that im doing
Thereâs
A joker in yahimod
That increases negative spawn rate
But i think it does it in a different way
do you have any idea how i would implement that for a deck
im pretty new to modding balatro but not to programming so im not sure exactly where to do that
It has a percentage chance to add negative to a card appears in shop if itâs a joker
Thatâs it
how would i make that different for specifically the deck
i feel like just adding an if statement is not a good way to do it
I think decks have a calculate function
the run card is killing me
i mean the way negative normally works is that theres a base 4% that an edition rolls at all, and then from there its another 7.5% chance (i think) for it to be negative
so either you mess with the edition spawns or just inflate the rate of negatives so its more likely than other editions or do the yahimod way
Thereâs a context for rerolling and a table for cards in shop you just go through the table with a for loop and do pseudorandom to either add negative to said card or no
you can also take ownership of negative
elaborate
ah cool
how do i make so a joker is giving extra joker slots
make it negative :3
you can change the amount of joker slots in add_to_deck and remove_from_deck
You either do this or manipulate negative rate
also, if i wanted to increase negative spawn rate to something like 1%, should i have it run separate logic for making negatives, or just make cards with editions appear with negative more often?
i also want to make consumable cards spawn with negatives at the same rate
what i linked is to modify the rate of negatives
Consumeables canât spawn with an edition in vanilla
im aware
thats the point of the change
for that you would probably need to patch create_card
well taking ownership wont change what cards can spawn with the edition, vanilla behaviour is only on playing cards and jokers and smods doesnt change that
consumables are vanilla
wdym
it just doesnt spawn
This
ah
yeah I just don't know how to do this on my own at all, can someone help by any chance? I tried looking at Cryptid's run card and it's starting to make my head hurt.
You can also give it the card_limit property added recently
i didnt recommend it because i found it to not work properly, have you had experience with it?
also hii winter
It is made in yahimod the cat named koda
how do i set the texture of my custom deck
i cant find anything documenting how to do this
Like you do with the jokers i guess
atlas=âatlaskeyâ, pos={x=0,y=0},
yea i figured it out
cuz im the goat đȘ
and by the goat lets just say

mentally deficient
but also like
bro lua feels so easy
cuz im used to writing everything i do in rust
ayy would you look at that
âJust take the win broâ deck
3 joker slots is mean though
but yeah probably
If youâre confident i highly recommend read the src of steamodded
cant wait for somebody to get streamer luck and find 5 negative blueprints by ante 7
im semi-confident
not in lua but in general programming
but lua is pretty simple so its not awful
bro 0% confidence is all i need to gamble
thats why im built different (poorly constructed)
lowk starting to lose it, I don't understand why this doesnt work but works when it's parsed through debugplus' eval command
Good luck
lovely is written in rust
I tried to make one lovely patch and paralyzed my game
Okay so this might be potentially stupid question part 2 (electric boogaloo) but where the hell am I supposed to put this damn '}' at? I thought everything was closed off properly :'<
Crab language
Comma after name
In loc_text
Also use vscode
Itâs much better
can't believe i missed that lol tysm!
And even without lua extension it highlights your syntax perfectly
I mean what he's using is still better than regular notepad
yeah regular notepad absolutely sucks. I didn't know about VScode tho so i went with the next best thing
That one guy who used notepad for his entire mod deserves a clap and a half
Trust me vscode is better
You can open your whole project folder and it supports mostly all languages also has some good themes so you donât get stuck with light theme and burn your eyes
Spreading vscode propaganda like theres no tomorrow
funnily enough I started working on my mod in notepad and kept doing that for a week straight until i realized i could just use VSC
If you do end up installing vscode I recommend you check out this https://github.com/nh6574/VanillaRemade/wiki#3-set-up-the-lua-lsp
I'll def look into it! Is it a free program like notepad++ and regular notepad?
Yeah
Yes itsâs 100% free
As it should
awesome i'll def be getting it then
What the fuck vscode
AI
Anyway here's the link https://code.visualstudio.com/
Like literally everything is now ai powered bro itâs ridiculous
The count doesn't increment with every debuffed card, is there a way to make it to where it does?
Pay me 30$ a month and get a review on your code and suggestions!!
This wonât work
Use a for loop instead
I think joker_main had access to context.scoring_hand
Calculate the mult amount with context.before and add it when context.joker_main
Also I recommend saving the value in your config and resetting it before the for loop
gotcha
assuming it should look like this but is there a function to check if a card is debuffed?
Yes this should work
I think the check for debuff is wrong tho
I thinking itâs ability.debuff
ok
I might be wrong
I said I might be wrong lol
thanks microsoft
ive had to uninstall copilot on my windows 10 pc twice now
because it LOVES to just show up again
I think Ai kills research and brain functionality
yup
Depends on how you use it tho
Yes.
No, you would do it in context.joker_main
gonna test to see if this works
No, remove the second if
Also it's scored_card.debuff
ok gotcha
but if i remove the if then how will it check if the scored card is debuffed?
OH WAIT
you meant the context if
my fault
should be good now then
gonna edit it to be scored_card.debuff
This can return 0
im trying to make a consumable that Disables Boss Blind and 1 selected Joker for 1 Hand, is there going to be hiccups with the 1 hand part since the consumable is technically gone already and if so, is there a better way to rectify that that isnt just keeping the consumable around until it resolves?
latest smods added a way for the whole mod to be a calculatable object, so you can just make the consumable set a global flag to "true" and then make the mod itself set that flag back to "false" after you play a hand
to do so, in your mod outside of any definitions (e.g. SMODS.Joker or whatever), add SMODS.current_mod.calculate = function(self, context) and then you can write a function under that like it was a joker calculating
How do I make a condition to ignore itself in the loop
I'm learning how patches work here: https://github.com/nh6574/VanillaRemade/wiki#whats-a-patch, but what would the name of the file with the code A basic Lovely patch looks like this:?
Since I am replacing create_UIBox_HUD, I assume I would place the entire function's content within pattern. I plan to put this code on github, but i don't want to break the sharing source code rule. Am I thinking about this wrong, or would I need to ignore the file?
like do that can work:
if not card = card then
Posting some part of the code is not really a problem although it would be better if you load a file instead of patching the whole function
a patch might fail
is current_mod just a placeholder term here or should that be exactly that?
exactly that
@red flower may I ask some questions about the new probability functionality
go ahead
I referenced JoyousSpring but I don't see you passing an identifier to SMODS.pseudorandom_probability
it takes the seed by default
I expect that, as long as I don't want to have an effect that interacts with my own probabilities, I should just make the identifier distinct from everything else, right?
yeah
cryptid mod wormhole deck has this in it, and defines cry_negative_rate to be 20, does that boost the negative spawn rate?
init = function(self)
SMODS.Edition:take_ownership("negative", {
get_weight = function(self)
return self.weight * (G.GAME.modifiers.cry_negative_rate or 1)
end,
}, true)
end,
negative spawn rate of the cards with editions i mean
yeah
what should my numerators be
the x of "X in Y"
it does, though the actual functionality of the modifier is defined elsewhere by cryptid
ah wait I misread the release notes
gotcha
I know what a numerator is, I meant if I should pass G.probabilities.normal too or not
so how should i go about doing this for my own deck
but upon reread it seems like I don't
i know you know, what i meant it that it has to be the number
for testing purposes i kinda want negative spawn rate to be 5%
haha
just to easily see if it works
I mean, G.probabilities.normal is a number :P
the number might change, but it's always some number
not if i set it to a boolean
anyways, reading this it implies it handles G.probabilities.normal internally, so I just pass numerator (usually 1)
yeah
I mean, then you're just breaking vanilla :P
good
but some languages parse Boolean as numbers
Like some people who use 1 and 0 in C
yup
yes
it doesn't have to be the same though
demonic input
though it would make sense
Doofenshmirtz's new inator
and you only need the identifier if you're going to have effects that affect specific probabilities
any idea where? these are the only places it shows up
well it is the first result
yeah thats my point
i did the same thing cryptid does but it just causes a crash because there's no functionality there
the functionality is in the take ownership you posted tho?
i mean i thought so
it is
but clearly balala doesnt like it
and the code
null pointer error WOOT
SMODS.Back{
name = "Overflow Deck",
key = "rad_overflow",
pos = {x = 0, y = 0},
config = {
rad_negative_rate = 20,
joker_slot = -2,
},
atlas = 'Radium',
loc_txt = {
name = "Overflow Deck",
text ={
"{C:attention}-2{} Joker slots",
"{C:attention}X3 {C:dark_edition}Negative{} chance",
"{C:tarot}Tarot{}, {C:planet}Planet{}, and {C:spectral}Spectral{}",
"cards may be {C:dark_edition}Negative",
"Start with an Eternal",
"{C:dark_edition}Negative{} {C:green}Showman",
},
},
apply = function()
G.GAME.modifiers.rad_negative_rate = self.config.rad_negative_rate
G.E_MANAGER:add_event(Event({
func = function()
if G.jokers then
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, 'j_ring_master', "deck")
card:set_eternal({true})
card:set_edition({negative = true}, true)
card:add_to_deck()
G.jokers:emplace(card)
return true
end
end
}))
end,
init = function(self)
SMODS.Edition:take_ownership("negative", {
get_weight = function(self)
return self.weight * (G.GAME.modifiers.rad_negative_rate or 1)
end,
}, true)
end,
}
And this is how the loc_vars should look?
dont take ownership in the deck vro
i poorly copy pasted code my fault gang
thats what cryptid does
buh
init doesnt exist outside of cryptid
unless you copied the load system
ohhh
can you tell that i have no idea what im doing đ
this is why we don't recommend looking at cryptid code to learn
i mean its what was recommended to me đ
i had a fucking seizure there good lord
i cannot type
When this says "respecting Joker order", it means inside this specific context, since O!A6s applies to all Jokers regardless of order, right?
pretty much yea
basically it means that it's more optimal to have a +numerator joker before a xnumerator joker than the other way around
so how do yall recommend i do this
your not the only one lmao â ïž
just take ownership of negative outside of the deck instead
Also this probably doesn't matter to me but what is this for
get yourself a vscode...
oh wait i see what i mean
notepad++ jumpscare
this is true if it's during play and not when hovering a description
weakling that you are, relying on the computer to provide the documentation for you
-# (/j of course, write your code however you're comfortable)
it also did not enjoy this
yea im grabbing it
did you add self to apply
i just put this in the main lua file
SMODS.Edition:take_ownership("negative", {
get_weight = function(self)
return self.weight * (G.GAME.modifiers.rad_negative_rate or 1)
end,
}, true)
that was the other crash
oh yknow what
i forgot to do that
i said i would and i did not
đ
this is what happens when your pharmacy fucks up and cant get you your adhd meds bro
Mickey and Donald meme why
How would one bring discarded cards back from G.discard, to be discarded again?
You could draw them
"drawing" means moving a card from one CardArea to another
The main difficulty is timing
Aikoyori has a joker like this
negative rate certainly seems to be boosted
I have a Joker that draws from G.discard to G.play IIRC
Although it does more than that
so if i wanted to boost the number of negatives while keeping the number of foil, holo, and poly cards the same i should take ownership of the edition chance as well correct?
do some math to make the numbers work out
No, that puts discarded cards back in the deck.
Do you want them to return to hand ?
Yes.
As I said above, the logic of moving cards is always the same
You just need to watch for the timing
You can clone discarded cards and add them back yo hand temporarily
Yes, but there is already a function for that, so it doesn't help.
guys I don't understand why it doesnt work like I just want to ignore if its the card of the seal
I may be misunderstanding how to format the UI but how do I get it so these strings Hello world and the seed are vertically aligned in get_item_availability? I've tried changing return {n=G.UIT.C to return {n=G.UIT.R, and also putting an alternative child in there, but still get the same results.
local orig_hud = create_UIBox_HUD
function create_UIBox_HUD()
local contents = orig_hud()
local jokerFoundInfo = {n=G.UIT.R, config={id = "dv_joker_found_info", align = "cm", padding = 0.1}, nodes={}}
table.insert(jokerFoundInfo.nodes, get_item_availability())
table.insert(contents.nodes[1].nodes[1].nodes[4].nodes[1].nodes, jokerFoundInfo)
return contents
end
-- Checks to see if the parametrized item is found within the filters
function get_item_availability()
return {n=G.UIT.C, config={align = "cm"}, nodes={
{n=G.UIT.T, config={text = tostring(G.GAME.pseudorandom.seed), colour = G.C.UI.TEXT_LIGHT, scale = 0.5}},
{n=G.UIT.T, config={text = "Hello world", colour = G.C.UI.TEXT_LIGHT, scale = 0.5}}
}}
end
What do you mean
G.FUNCS.draw_from_discard_to_deck()
There's another function you're missing
Which G.FUNCS.draw_from_discard_to_deck calls
not c == card parses as (not c) == card iirc, do c ~= card instead
If I want to move something in a cardarea where it doesn't belong instead of the right one, how would I do that? Let's say a Joker. You buy a Joker but instead of moving to the cardarea for jokers, it moves into the deck of cards.
omg I think im dumb
@slim ferry how can i take ownership of the chance to find an edition
rather than the weight of a particular edition
Is this done using love graphics ?
Yes, I know I have to use draw_card
Forgot to ping
because i want negatives to be more common than they are with the weight cranked up but i don't want to mess with the rates of the other editions
draw_card calls another function
you would have to do like some hook or patch shenanigans for that since the edition rate isnt tied to any object
rip
do you know where the behavior for that is located
i mean im fairly sure cryptid wormhole deck also just doesnt bother
đž
yeah but i would like to bother
thats negatives weight, not the chance of an edition appearing
...right, oops.
No, that draws a random card, I need to draw back the discarded cards.
i have no clue where the roll happens, i would look into the create_card function though (or poll_edition)
bump
here's a thought
would it be easier to, rather than calculate the weights and edition spawn chance such that non-negative edition rates aren't impacted, just set negative weight to 0 and then have a separate dice roll to make it negative
You can specify where to draw the card from
As is written
that way i could make negative a separate chance entirely, thus unaffected
i mean i think the latter would be easier
agreed
Patch G.FUNCS.buy_from_shop
So just specify that you draw from G.discard
No, I mean the discarded cards used in the last discard.
depends on when and where youre moving it from
eris do you know which file create_card is in
i think functions/common_events.lua
im guessing card.lua maybe
true
In that case you just use draw_card
also just use vscode search
i should yeah
im like really lazy though i just have the games source code open in 7z
đ
you can press the unpack all or whatever button and dump it into some folder
its here
oh im aware
awesome
Okay, and what if I want to make a deck that has jokers in the hand and deck and cards in the joker area?
Like switch their places
bro i am not a fan of john thunk inventor of localthunk's arithmetic formatting here
function poll_edition(_key, _mod, _no_neg, _guaranteed)
_mod = _mod or 1
local edition_poll = pseudorandom(pseudoseed(_key or 'edition_generic'))
if _guaranteed then
if edition_poll > 1 - 0.003*25 and not _no_neg then
return {negative = true}
elseif edition_poll > 1 - 0.006*25 then
return {polychrome = true}
elseif edition_poll > 1 - 0.02*25 then
return {holo = true}
elseif edition_poll > 1 - 0.04*25 then
return {foil = true}
end
else
if edition_poll > 1 - 0.003*_mod and not _no_neg then
return {negative = true}
elseif edition_poll > 1 - 0.006*G.GAME.edition_rate*_mod then
return {polychrome = true}
elseif edition_poll > 1 - 0.02*G.GAME.edition_rate*_mod then
return {holo = true}
elseif edition_poll > 1 - 0.04*G.GAME.edition_rate*_mod then
return {foil = true}
end
end
return nil
end
misinput
put spaces between your variables and your * please đ
put the two text nodes each inside a row node
It would work, but you would need to do a lot of things to make them activate.
like with a \n between?
to expand upon what N' said, rows stack vertically and columns stack horizontally
How much, if you had to take a guess?
No, I've done it before.
Text is usually organized in horizontal lines on top of each other, so text nodes go inside row nodes inside a column node
And doesn't patching overwrite it for everything, not just that deck?
like
C = {
R = {
T
},
R = {
T
}
}
Text of different colors or effects are different text nodes
Yes, but you would check if the deck is that deck.
So a row can contain multiple text nodes
A common effect is a background color, which is actually a column node, so you could have a column with a row with text and (column with text)
Okay, so I need to patch the area the cards and jokers are in and moved to, that the jokers activate in that area instead and what else?
When you read a Joker's description, try to mentally break it down in terms of nodes and you should be able to visualize what the nodes are doing
how would i go about patching this function?
poll_edition is actually overriden by SMODS entirely.
oh okay
i was thinking that because there is some stuff that i used with smods that is missing from there
@red flower I had a Joker whose intended effect was to add +1 to the numerator. So instead of whatever was happening on the left, I can now just have whatever is going on the right?
See src/overrides.lua for it.
is there a global avariable i can set inside my deck to control the overall chance of finding an edition?
Your deck can set a variable to the run itself in apply.
Nothing, perhaps.
well yeah but what variable
G.GAME.negativefartchance or w/e.
- Is there some sort of data structure for jokers within the source code? And do jokers have some sort of
idso you can check for a certain one, like "blueprint" - How can I check which jokers are going to show up in the shop. Whether on first entrance, or on reroll?
I found these lines within state_events.lua end_round(), but I can't seem to get a reference to jokers
G.jokers.cards[i]:calculate_rental()
G.jokers.cards[i]:calculate_perishable()
Okay, how do I do that check you mentioned earlier? Like, check if the deck is my deck and only then use the patch?
no i mean the chance for an edition to spawn
i already have the negative weight change
SMODS.Edition:take_ownership("negative", {
get_weight = function(self)
return self.weight * (G.GAME.modifiers.rad_negative_rate or 1)
end,
}, true)
SMODS.Back{
name = "Overflow Deck",
key = "rad_overflow",
pos = {x = 0, y = 0},
config = {
rad_negative_rate = 20,
joker_slot = -2,
},
atlas = 'Radium',
loc_txt = {
name = "Overflow Deck",
text ={
"{C:attention}-2{} Joker slots",
"{C:attention}X3 {C:dark_edition}Negative{} chance",
"{C:tarot}Tarot{}, {C:planet}Planet{}, and {C:spectral}Spectral{}",
"cards may be {C:dark_edition}Negative",
"Start with an Eternal",
"{C:dark_edition}Negative{} {C:green}Showman",
},
},
apply = function(self)
G.GAME.modifiers.rad_negative_rate = self.config.rad_negative_rate
G.E_MANAGER:add_event(Event({
func = function()
if G.jokers then
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, 'j_ring_master', "deck")
card:set_eternal({true})
card:set_edition({negative = true}, true)
card:add_to_deck()
G.jokers:emplace(card)
return true
end
end
}))
end
}
heres my code
im aware of the soul https://spectralpack.github.io/TheSoul, but wanted to see if it was possible within the game itself
if G.GAME and G.GAME.selected_back and G.GAME.selected_back.effect.center.key == "b_modprefix_key"
You can perform your own probability roll and then set _guaranteed to be true in the hook.
yes
Where does that go?
so uh, this is an infinite loop and i dont really understand why
SMODS.current_mod.calculate = function(self, context)
if G.GAME.blind and G.GAME.blind.boss and not G.GAME.blind.disabled and Cosmic_Zapped then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 50,
func = function()
G.GAME.blind:disable()
return true
end
}))
end
end```
should i set another flag/check to make sure it doesnt disable the boss blind 40 bajillion times in 2 seconds?
how though
In the patch when telling purchased cards to go elsewhere.
Do you mean vanilla or SMODS?
Jokers and most objects have keys.
There are ways to predict random rolls without affecting them
Right, okay. Thank you
As in jokers that are not modded. I pretty much am remaking the soul https://spectralpack.github.io/TheSoul, but within the game, and adding more qol features
set Cosmic_Zapped to false outside of the event but still in the if block, yes
Vanilla has Card
local polleditionref = poll_edition
function poll_edition(_key, _mod, _no_neg, _guaranteed, _options)
-- do chance roll here - if it succeeds, _guaranteed = true
return polleditionref(_key, _mod, _no_neg, _guaranteed, _options) -- call original function
end
how can I round down a number ?
https://github.com/nh6574/VanillaRemade/wiki#how-do-i-get-the-set-pool-or-key-of-a-specific-cardobject
https://jokerforge.jaydchw.com/keys
for the second one there are some mods that have that as an effect but idk how it is done
math.floor(number)
math.floor(number)
or math.ceil(x)
No
if you want to round up
Well yeah
how does this replace the existing poll_edition though
thats what im unclear on
It doesnt replace it
like how does this actually do the thing
It modifies it
chat i cant read lol
98%
By executing code before the original function runs
local polleditionref = poll_edition sets a local variable to be equal to the original function, then we override the function with our own, but with calling the original function at the end.
so wait if i just stick this in my lua file will it modify all the existing calls to poll_edition?
oh thats fucking sick
sorry if i am overthinking this
i am used to game engine stuff in rust where everything is so much more complicated
Hooks are awesome they allow you to do like cool shit
much more powerful but much more complex
N' has reached the point where they reply to questions with photos of N' pointing to the answer
no kidding
I mean why basically copy paste from the wiki if you can just link the wiki
@red flower for April's Fools you should replace "What's a hook?" with a photo of Captain Hook and "How do I debug my code?" with a bug spray
i will just make the page redirect to jokerforge
I just think it's funny that rather than answering N' just links to the last time they answered
Without 'em, wouldn't be able to do shenanigans with scoring stuff.
is there a way with this i could make it such that when the chance roll hits, it is always negative?
and also which pseudorandom function do i use for the roll? ive seen several in the source code but i want to make sure i use the right one
cuz yknow seed stuff
_guaranteed = true & _options = { 'e_negative' }
I thought I'd help make it clearer
cool thanks
what about this
probably just regular old pseudorandom
this might be a stupid question but what is the convention for random rolls in balatro modding
again im not very experienced with lua so im not super sure what the correct way to do it is
You should generally always use pseudorandom functions for stuff that happens in runs
There's been an update for randomness
Probability, more of.
To streamline how mods interact with it
oh cool
Randomness, Probability, Stochasticity
đȘ
evil
Thats for specifically probability rolls and modifying them though (e.g. oops), rather than general randomness
I didn't finish talking
-# Also rolling for stuff with weights is still rolling
What kind of roll
lets just say for example i want a 5% chance for the guaranteed negative
If you don't want it to be affected for anything else
Didnt the guy literally put a comment for where the roll should go
he did yes i just dont know how to implement the roll in lua
Where, but not what exactly.
Fair
again i have like zero experience with lua
i've written a script brush for axiom but thats like all my recent experience LMFAO
First I'll explain the math to you
pseudorandom samples an uniform random variable according to a given seed
for the 5% chance i would do a weighted roll with guaranteed being a weight of 1 and not negative being a weight of 19
makes sense
Oops, no _probability
That's the new one
upvalues functions
cuz you don't use debug.gethook
you use debug.getupvalue
đ
hook sounds gay
upvalue sounds cool
"upvalue" who let this guy cook get him off the grill
this sounds like a tax fraud thing
so maybe you make a good point
i do like tax fraud
so how do i actually use it
this is what i have
local polleditionref = poll_edition
function poll_edition(_key, _mod, _no_neg, _guaranteed, _options)
-- do chance roll here - if it succeeds, _guaranteed = true
return polleditionref(_key, _mod, _no_neg, _guaranteed, _options) -- call original function
end
what do i actually put in there
how would you do it mathematically?
Okay, quick question: What are the different cardareas called again or where can I find what they're called in the documentation?
get a random number from 0 to the sum of all weights then check the value against each weight
but like how to do that in lua ergonomically
G.jokers, G.play, G.hand, G.deck, G.consumeables, G.discard, G.vouchers, G.shop_jokers, G.shop_vouchers, G.shop_booster, G.your_collection, G.pack_cards, G.title_top
G.vouchers also exists
you don't need all the weights unless you want to be super accurate
also some shop CardAreas
and the collection CardAreas
bro i understand how random rolls work i just don't know the best way to do it in lua specifically đ
look at this for example
I'm just saying it's easier for binary events
you just do the weighted random element algorithm normally
And suggesting you think of one to start with
but you use pseudorandom instead in Balatro to keep the same results across the same seed
Because it's easier
I would recommend looking at the code for SMODS.poll_enhancement
for an example
dont really have any clue about modding but how hard would it be to make a mod to remove the negative color inversion filter?
for i = 1, played_count do
G.E_MANAGER:add_event(Event({
func = function()
G.play.cards[i]:juice_up()
return true
end,
}))
crashes when a glass card breaks, any ideas?
0/10
like 0/10 braindead easy
whats the error
trying to index nil value, pointing at "G.play.cards[i]:juice_up()"
best guide you think to show something like that? Im seeing guides for how to make jokers but that info doesnt feel super applicable to what i want to do
try to do
if G.play.cards[i] then
G.play.cards[i]:juice_up
end
ight
there is a lot going on there
read the game code and see where the stuff is implemented
how would i just do a weighted boolean roll
like i would expect that to have a util function right?
I mean I can explain a binary one
nah
could you like write it out
its a lot easier for me to figure out how it works if i can just read it than if it is explained to me
like i knew the math
ive said like 4 times now that i understand how it works just not how i SHOULD do it in lua
if pseudorandom('your_seed') < p then
âŠ
else
âŠ
end
errrrrrrrr
is p the probability of the event happening?
i got softlocked
if i want a 1/20 chance of the roll hitting, where do i specify that 20
cause you're not returning true on the event probably
Yes, also, seeds should follow specific guidelines
yes i am?
what the code looks like
what is the probability of the event happening
wait so is p 1/20
Yes but
OHHH wait i see
yeah might be over my head I dont have experience with coding but ill go do some tinkering and see what i can come up with
I'll reiterate what I said before
This is technically wrong
im very tired lol
but it should be close enough
pseudorandom gives you a float correct?
yeah you're not returning true
Is this what defines that jokers move into the joker cardarea?
local joker_tally = 0
for i = 1, #G.jokers.cards do
if G.jokers.cards[i].ability.set == 'Joker' then joker_tally = joker_tally + 1 end
end
if joker_tally > G.GAME.max_jokers then G.GAME.max_jokers = joker_tally end
check_for_unlock({type = 'modify_jokers'})
end```
You'll end up with a greater than 20% chance of getting Negative
you're only returning true If G.play.cards[i] exists
ah
you need to keep return true outside the if statement
well yeah what i really want is 19.7%
ight, thank you
np
If the original chance of getting Negative is q, and you do it as I suggested, the chance that you get Negative will end up as (1/20) + (19/20)q
because of the existing 0.3% of getting a negative
pseudorandom("key") <0.197
although other mods and effects could modify it
so YMMV if you want to care about that
yeah it works now tysm
ymmv?
and 19.7% ~ 20%
your mileage may vary
@pastel osprey also
i was about to ask about the seed thing
Seeds should be unique if you want to avoid random effects influencing each other
bump
Though if you want them to influence each other, they should be the same
I think here you'd rather not
So just prepend your mod's infix to the seed, and that should be unique enough
so how would i get the seed in that case
I mean, the seed can be whatever you want
apologies if im overthinking this lol
or i mean like
No, because that is not in G.FUNCS.buy_from_shop
if i start two runs with the same seed, will that chance hit the same each time?
Yes, but I'm not talking about that seed
If you use pseudorandom yes
okay cool thanks
I'm talking about the internal seed for this pseudorandom call
i wasnt sure if that was bundled into the pseudorandom function or not
Actually there's a caveat, just to clarify
But I don't want it to only be when a joker is bought from the shop but rather always, all the time
this is based on number of calls to pseudorandom with this seed
again sorry if im overthinking it ive been using a game engine in rust for a while now so im used to the whole thing of global variables dont exist n shit
If you don't make a call, it doesn't advance the seed
cuz rust is not a fan of those
Wait, nvm
I'm stupid
so wait what did you say i should pass in to pseudorandom as the seed
it was my mod's id thing then what after that
whatever you want
is there a function for predicting what will happen with a certain seed?
Is it G.jokers:emplace(c1)?
Yes.
20% negative rate is so fair and so balanced
And I would change that to G.deck:emplace(c1) to move them in deck and G.hand:emplace(c1) to move them into the hand?
Yes, if the deck is your deck.
how would i go about making planet, spectral, and tarot cards spawn as negatives?
maybe not spectrals because this isnt ghost deck
but yknow
i set the negative chance back to 5%
this is based
this deck might be fucked balance wise but that remains to be seen
im trying a run rn
the 3 joker slots thing is kinda crippling ngl
getting a run off the ground may be tough
do you recall any of these mods off the top of your head?
im currently struggling getting the effects of the boss blinds back to work properly, any advice on how to fix it? (ive been using the candy sticks joker from cryptid as a reference)
Cosmic_Zapped = false
SMODS.current_mod.calculate = function(self, context)
if context.setting_blind then
Boss_Ability = G.GAME.blind:save()
end
if G.GAME.blind and G.GAME.blind.boss and not G.GAME.blind.disabled and Cosmic_Zapped then
Cosmic_Zapped = false
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
G.GAME.blind:disable()
return true
end
}))
end
if context.after and G.GAME.blind.boss and G.GAME.blind.disabled then
G.E_MANAGER:add_event(Event({
trigger = 'after',
delay = 0.2,
func = function()
G.GAME.blind:load(Boss_Ability)
return true
end
}))
end
end```
yeah this deck seems really strong on paper but only having 3 joker slots is a big kick in the balls
how do i have a consumable detect when a joker is selected? wanna make a consumable that simply makes a selected joker negative
G.jokers.highlighted is the selected jokers
bro you NEED to name that consumable Turboplasm
Why does this change nothing? It doesn't even do the print
version = "0.1.0"
priority = 0
#Change areas for jokers
[[patches]]
[patches.pattern]
target = 'button_callbacks.lua'
pattern = '''
G.jokers:emplace(c1)
'''
position = "at"
payload = '''
if G.GAME and G.GAME.selected_back and G.GAME.selected_back.effect.center.key == "b_cstorm_law_of_chaos"
G.deck:emplace(c1)
print("Works")
end
'''
match_indent = true```
Should I be looking to edit the negative.fs shader or somethin in game.lua you think? To remove the negative color inversion. I still want negative edition in the game just without the inversion. Keeping the shine is fine
If that's what you want then yes
but shaders are different
shaders are hard ngl
yeah thats what ive been currently experiencing lol
anytime i try fuckin with em game crashes on seein a negative
nothin in game.lua even references the shader to my knowledge so ima try and look and see where it does call it out
Card:draw probably
if (self.edition and self.edition.negative) or (self.ability.name == 'Antimatter' and (self.config.center.discovered or self.bypass_discovery_center)) then
self.children.center:draw_shader('negative', nil, self.ARGS.send_to_shader)
if self.children.front and self.ability.effect ~= 'Stone Card' then
self.children.front:draw_shader('negative', nil, self.ARGS.send_to_shader)
end```
this maybe?
in card.lua
If you just want to remove the negative shader you can just take ownership of negative right?
Plus the shader is already split into the shine and the colour inversion
yeah I saw that, im fine with the shine existing i just want the inversion gone
trying to work out how to dump that. What do you mean by take ownership of negative?
SMODS:take_ownership I think
functions/button_callbacks.lua
damn yeah, I just dont know enough about lua or balatro modding/smods to make use of that information
nope sorry
Yeah, now it works and it looks funny, thank you xD
bump
Do I need to replace/patch the whole code for function G.UIDEF.deck_preview(args) to show the jokers instead of the cards?
No, you just need to put them in G.playing_cards
bump 2: electric boogaloo
So like this? table.insert(G.playing_cards, self)
Yes, if self is the card.
Wait, what is the card? I didn't define it...
Is the joker in the table G.jokers?
How does this work btw? Do i take ownership of the shader itself?
The card object should be c1 but doing table.insert(G.playing_cards, c1) still doesn't show it in deck
how do we think this is balance wise
like i said earlier, the -2 joker slots is a massive kick in the nads
Not balanced at all
For reference painted deck -1 joker slot +2 handsize
What if you canât afford it tho
that is a fair point actually
i might make the deck have negatives not expensive
and remove the showman
Actually idk if itâs balanced youâll have to playtest
ah rip
it seems to be kind of similar to plasma deck progression wise
the earlygame is not bad
midgame is hard
but once you can get it off the ground with some econ, the extra negative jokers can make the run go crazy
Not every negative is useful to your build
What can ancient joker do if youâre running a baron build
Lol
hello there
i mean negatives are still luck yeah
but it goes from 0.3% ro 5%
thats huge
ah fuck right 3 joker slots
yeah ouch
Watch it hit showman
ikr
im gonna hang on to invis until i see something good
i still need to make the code that allows consumables to be negative
lowkey part of me thinks
maybe this deck could start you with an ecto rather than the goofy ass showman
the showman's purpose is simply to be funny tbh
i can work with this
fair point
wdym free negative
Not 100% free but increased chance
yea
I mean iâm taking a negative if i see it
i might change -2 joker slots to -1
a free negative often doesn't hurt
-2 is such a lead pipe to the skull
Rental free negative
evil
boys i dont know wtf im doin rn help
if im tryna prevent negative edition from having the color inversion and using negative.fs is this the right direction even somewhat??
{
disable_base_shader = true,
shader = "negative",
}
) ```
You canât change shaders to my knowledge
trying to piece some bullshit together with no lua knowledge from
https://github.com/Steamodded/smods/wiki/API-Documentation
and
https://github.com/Steamodded/examples/blob/master/Mods/EditionExamples/EditionExamples.lua
cant just disable them being used?
If it works then you can make the shader do nothing
Editions donât work without shaders to my knowledge
real talk tho like why do you want to disable the negative shader
how can you tell its negative at that point
baby steps lol
i just wanna see if i can do this
ima try doin that but just temporarily set it to like holo
chat do i sac the scoring for the bag
Good luck
lua
Just add shader=âholographicâ
im so helpful i know
Idk if the rest stays the same i never done take ownership
Api docs says to edit parameters
you have GOT TO BE KIDDING ME
right after i pick up golden ticket
showman shows his man
when showman show man he show you golden ticket
Holy stonks
Hi, Can anyone help me with this?
when you take ownership do you need to include the assets in your mod that youre replacing with
like do i need to include the holo.fs
if im trying to change it to holo temporarily
when is debuff_card called
Alright friends i need some help
i have two jokers that apply red and purple seals to wild and steel cards respectively
and when the hand starts scoring it just applies all the seals instantly
but i want it to apply the seals one at a time and only after the card is scored
how would i do this
you need to move context.other_card:set_seal to a different spot
more specifically you'd need to return a function that creates an event which sets the seal
it's kind of a lengthy process to explain so do you want me to give you the proper calculate function or do you want me to guide you into inserting the event properly?
i'll save you the trouble of explaining, just the calculate function pls
for koraidon it'd be
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if SMODS.get_enhancements(context.other_card)["m_wild"] == true then
return {
func = function()
G.E_MANAGER:add_event(Event({
func = function()
local temp_card = context.other_card
temp_card:set_seal("Red", true)
return true
end
}))
end
}
end
end
end
I'm trying to make a (what I imagine is) basic card texture replacement pack but I'm struggling with lua, is this the correct channel to get support for that?
so far I've changed the enhancements texture and trying to get the game to load but it crashes on load and I've looked at the steamodded documentation but it didn't really explain how to get the atlas key to work (I'm also very new to lua and this is my first mod I've created so sorry if there's something I missed)
also I'm on linux and using r2modman
and i presume i can just replace "m_wild" with "steel" and "red" with "purple"
bump to the scond question. If anyone knows any mods that observe the rng without modifying, that could help as well
for miraidon
yep correct
question, does the code shown below add every instance of the selected joker or just sums them all up to one?
if G.jokers and G.jokers.cards then
for i, joker in ipairs(G.jokers.cards) do
if joker.config.center.key == 'j_rose_hydrangea' then
duplicate_count = duplicate_count + 1
end
end
end
oh
hmm i thought it worked like that
this counts the number of jokers with the key "j_rose_hydrangea"
okay, so with the code as it is if i had x amount of j_rose_hydrangea, i would have duplicate_count = x + 1, gotcha
Does anyone know how to change the background color of the menu?
i'll get back to ya in a bit, need to check some stuff
sure thang
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if SMODS.get_enhancements(context.other_card)["m_wild"] == true then
local temp_card = context.other_card
return {
func = function()
G.E_MANAGER:add_event(Event({
func = function()
temp_card:set_seal("Red", true)
return true
end
}))
end
}
end
end
end
there we go
cool i'll let you know how it goes
it works well
although there is a little tweak i'd like to make if you're down to help me
sure
alright cool
I'd like the seal to apply like it does when you use a consumable like talisman or deja vu
like it does a little wiggle and a thunk sound plays
a local thunk if you will
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if SMODS.get_enhancements(context.other_card)["m_wild"] == true then
local temp_card = context.other_card
return {
func = function()
G.E_MANAGER:add_event(Event({
func = function()
temp_card:set_seal("Red", true)
temp_card:juice_up(0.3, 0.5)
play_sound("tarot1")
return true
end
}))
end
}
end
end
end
juice_up does the wiggle and play_sound does the sfx
oh that's what "juice up" means
yep
i saw that in joker forge and i was like "wtf does that mean"
it's a weird name for a function but it is what it is
alright i'll see how it goes
right spot
i think looking into malverk for texture packs will be helpful
can you add a custom color to G.C?
i think so probably
but what do u need a custom color for?
also btw you should remove the steamodded header in ur lua file and convert it to a metadata json file as detailed here https://github.com/Steamodded/smods/wiki/Mod-Metadata
I was gonna say tag return color but i'm having trouble loading the tag XD
tag return color? so like a custom color for the message after your card makes a tag?
the little + icon when they're redeemed
oh
ok thunderedge it is almost perfect, i just need it to pause before it gets to the next card, i dont want every event to happen at the same time
so you just want a delay between when the cards score?
try this
calculate = function(self, card, context)
if context.individual and context.cardarea == G.play then
if SMODS.get_enhancements(context.other_card)["m_wild"] == true then
local temp_card = context.other_card
return {
func = function()
delay(0.9)
G.E_MANAGER:add_event(Event({
func = function()
temp_card:set_seal("Red", true)
temp_card:juice_up(0.3, 0.5)
play_sound("tarot1")
return true
end
}))
delay(0.9)
end
}
end
end
end
increase the 0.9 if the pause is too short
ty! ^v^
lemme know if it still doesnt do what you want it to do
oh
i'm not looking for a satic delay
just like the normal delay between scoring cards that is based around your game speed
i do believe the delay function is affected by gamespeed
in vanilla its inconsistent but i think .8 is closer to the average delay for scoring
alright cool
i'll see how it feels
ok its almost there
and this last adjustment i could probably do myself
i just want the joker to get "juiced up" at the same time the seal appears
if it's not too much trouble to ask, how come I don't see the option for the malverk ui? I check the options and I don't see the texture options it says to look for.
also thank you for helping me sorry for not responding earlier.
clarify
do you mean the menu ui options (like selecting texture packs) or the options to toggle when making ur texture
in on the main menu in the options screen in the game I presume is where I find the "textures" button of which there is none
have you defined a TexturePack in ur code?
also strange the menu should be there
how do you open a booster pack from a tag?
i tried copying code from paperback and bunco (they were the same code in the end) but it didn't work
with this crash:
i think the crash is because the key is not correct tho
Are the create_card and SMODS.ObjectType needed in this case, or can I do with just create_card?
@rocky plaza do you know how to make this last adjustment? i'm gonna need to go to bed soon but i dont wanna rush you either
really quick is the seal being set and then it shakes with a pause in between?
the code i sent should not have an issue with that unless juice_up has an internal delay
the joker shakes, pauses, then it applies the seal and the card shakes
oooohhhhh
not at my pc rn but try removing the first delay and see what happens
idk if itll work (prob not) but give it a shot
yeah they're both the same here
So can I remove the ObjectType and be fine?
yeah you're literally not using it lol
but objectypes are nicer
also create_card needs the area iirc
The retrigger isn't happening, anyone got a clue on how to fix?
context.repetition
Thanks
I think the issue was how I installed it because now it's working.
I cloned the repo directly into the mod folder instead of downloading a zip and installing it through r2modman
anyone know why my tag isn't working? i just want it to create a free booster pack when you enter the shop
SMODS.Tag {
key = "ghostly_shopper",
atlas = "Tags",
pos = { x = 2, y = 0 },
loc_txt = { -- local text
name = 'Ghostly Shopper Tag',
text = {
'The next shop will have',
'an additional {C:attention}free',
'{C:chak_sticker_ethereal}Ethereal Buffoon Pack{}'
}
},
loc_vars = function(self, info_queue, tag)
info_queue[#info_queue + 1] = G.P_CENTERS.p_chak_buffoon_ethereal
end,
apply = function(self, tag, context)
if context.starting_shop then
tag:yep('+', G.C.GREEN, function()
local booster = SMODS.add_booster_to_shop('p_chak_buffoon_ethereal')
booster.ability.couponed = true
booster:set_cost()
return true
end)
tag.triggered = true
return true
end
end
}
it doesn't even get used up atm
what does this mean
either your localisation files are inputted incorrectly or your loc_text was inputted incorrectly
it looks like this
this image is so confusing ngl
how so?
windows vista notepad đŹ
Is the name and text of the texture pack supposed to be in loc_text?
I mean it's just malverk
this is kwrite, I'm on linux.
Why is the windows notepad icon there đ
aerothemeplasma
wym?
there are themes for plasma that make things look like vista
or macos
or fuckin, idk, windows 3
Let's be honest
There are themes for everything in Linux
anyway I'm not sure why it's error-ing out and not applying
because its. it seems to be a linux text editor but it has the windows theme and our brain just errors out on that one
I am currently doing some bugfixing for my mod and I can't get this Joker to work. It's effect is to draw hands to card before scoring, which works, but the drawn cards do not trigger held-in-hand effects (steel, Baron, etc.). Any ideas on how to fix?
Did you even change anything
Well that's good at least
am i blind
I don't see anything
do u know what red is :3
is there a way to hard set a specific value for the booster/voucher/shop size? I know SMODS.change_booster_size and things like that exist but as I said I wanna know if I can just hard set the value that it is changing instead.
I know you can but I can't remember the exact syntax for it right now
I use a very similar method for one of my jokers
no worries
For booster packs you can set the config for the number of picks and choices
SMODS.change_booster_limit((-(G.GAME.modifiers.extra_boosters or 0)-2)+number)?
And I'm not really familiar with change booster size but could you not do like, change booster size * 0 + number
That's what I was thinking
high five
would change_shop_size work similarly, asking just to make sure
Sorry im about to go to sleep I'd check my code otherwise. If you still need help with stuff tomorrow feel free to message me
gotcha, thank you regardless c:
Yes, but it would be change_shop_size((-G.GAME.shop.joker_max)+number)
alrighty
(also good night)
sorry for asking again but what would be the correct syntax for vouchers?
SMODS.change_voucher_limit((-(G.GAME.modifiers.extra_vouchers or 0)-1)+number)
they always seem to stay whenever the shop is refreshed, I realized that's intended behavior. Is there a way to remove them?
What seems to stay?
vouchers
i think i can just remove them instead of setting their limit but idk how to remove them really
You want the voucher limit to be reset?
more precisely i want the voucher field to empty itself whenever you leave and re-enter the shop. I figured out the leaving and re-entering part but idk how to remove vouchers
I've tried working with this snippet and yeah, it unfortunately doesnt affect the vouchers that already exist
G.shop:recalculate()?
Managed to get things mostly working, however i do need help with this text box thing. Is this a syntax error or am I missing something?
It's loc_txt
â ïž ofc i would miss that lmao thxs for the help
Also unrelated question: is it possible to change the white background of the cards in your deck to another color? (Doing a Luigi Poker mod and I wanna get it as close to the OG game as possible)
didn't seem to do anything
What do you mean?
they still stack on top of each other
so lets say I wanted to change the white background of these cards to the light blue color that the Luigi Poker cards have, is that possible to do or am I stuck with the white color?
That would probably require a texture pack.
gotcha, i'll look into setting that up. It's not really that important but I think it would just be better if it was as 1:1 as possible lol
okay everything is mostly working, my last hurdle is just the Xmult calculation not working (and the fact theres the extra tag under where the joker rarity shows up, dunno if that can be removed or hidden). I'm following this tutorial to a T but it's still giving me issues đ sorry for all the probably super dumb questions I really shouldn't be doing this with like 4 hrs of sleep â ïž
bump
You mean the mod badge?
yeah how do u hide/remove it? the mod id and the name of the joker are basically the same so it's redundant having it show up twice
no_mod_badges = true on the joker definition.
I plan to make a joker called Golden Freddy which gives a random rare consumable at the end of the round. How do you make specifically a random rare consumable spawn?
You would iterate over G.P_CENTER_POOLS.Consumeables and put all the ones with hidden in a table, then get a random key from that table, then use SMODS.add_card
oh nvm its hidden
does seem like either would work though unless there are consumables with soul_set thats not rare somehow đ€
So SMODS.add_card{ set = G.P_CENTER_POOLS.Consumeables, hidden = true }?
no
How do you do it
Oh ty for the mod badge fix! I hate to bug ya again but I also need help with the Xmult calc. The x7 mult for every ace card played is not being triggered and when i'm looking at the code some of the values say unknown. I'm having a hard time figuring out if its another syntax error or if maybe vscode isn't able to get the smod/game values it needs to đ„Č
local pool = {}
for _,v in ipairs(G.P_CENTER_POOLS.Consumeables) do
if v.hidden then pool[#pool+1] = v.key end
end
local random_key = pseudorandom_element(pool, "random_rare_consumeable")
if random_key then SMODS.add_card{key = random_key} end
probably smt like that
No, i would be a number.
No, if it was a syntax error, your game would crash on start up.
Also you're returning dollars instead of xmult
This would look for ALL rare consumables?
yes
So I put that inside the
if context.end_of_round then
â
No, it would be context.end_of_round and context.main_eval
here's the code that i have so far. the tutorial i was following had the Xmult calc set up like this. the money thing is intentional thats the 2nd part of my jokers ability
Right
Wait, whatâs the difference between not having context.main_eval and having context.main_eval?
Then you would put xmult = card.ability.extra.Xmult in the return with dollars
And remove the first if
context.end_of_round triggers multiple times
not having context.main_eval will catch all of the triggers
oh my god it finally works as intended!! Thank you so much i rlly appreciate the help ^^
also your tutorial seems to be outdated, you can just replace this whole part with xmult = card.ability.extra.Xmult lol
(keep the return {} and put the thing i said inside the table, went too broad there)
Would be useful for jokers that gain something for every single playing card in deck.
Idk what for though
it doesnt go through every card, just specific cardareas that are enabled in your mod iirc
it's for mime
oh that makes sense
Oh right, the same happens when I use context.individual without cardarea G.play
what if there was a start of round enhancement
tbh i was thinking that it might be outdated when it didnt work after triple checking everything several times, but because this is my first ever time modding in a joker I just thought the problem was me being a skill issue lol
I should make those exotic cards Jen has.
â
how would one modify an already existing joker's info_queue without interfering with their loc_vars?
like say i wanted to add another info_queue to the Lusty Joker, how would i do that?
Trying to make a joker that creates negative âperishableâ jokers, but it doesnât seem to be making PERISHABLE JOKERS


