#đ»ă»modding-dev
1 messages · Page 35 of 1
yup, you had to hook in 0.9.8
In fact, a lot of my jokers right now still use that old trick and I need to switch them over to the new method
key = 'blue_joker',
loc_txt = {
name = 'Blue Joker',
text = {'{C:blue}+2{} hands but {C:red}-1{} discard'}
},
rarity = 2,
pos = {
x = 0,
y = 0
},
cost = 5,
discovered = true,
add_to_deck = function(self, card, from_debuff)
G.GAME.round_resets.hands = G.GAME.round_resets.hands + 2
G.GAME.round_resets.discards = G.GAME.round_resets.discards - 1
ease_hands_played(2)
ease_discards_played(-1)
end,
remove_from_deck = function(self, card, from_debuff)
G.GAME.round_resets.hands = G.GAME.round_resets.hands - 2
G.GAME.round_resets.discards = G.GAME.round_resets.discards + 1
ease_hands_played(-2)
ease_discards_played(1)
end
} ```
@solemn coral would this work?
It's ease_discard, not ease_discards_played, but other than that it should, yes
ok
You should really look into getting that source code available.
It's got all those functions inside there so you can look yourself if you have any questions
by the way, isn't Blue Joker a base game Joker already?
it's going to cause conflicts with that one without a doubt
Don't mods automatically prefix their IDs so there isn't any conflicts?
i thinks Myst refers to reset_hands
no?
well
Blue Joker is the one that gives chips per card in deck right
key = 'scalper',
loc_txt = {
name = 'Scalper',
text = {'Adds {C:blue}+5 sell value of all other owned Jokers to Chips'}
},
rarity = 1,
pos = {
x = 0,
y = 0
},
cost = 5,
discovered = true,
calculate = function(self, card, context)
if G.STAGE == G.STAGES.RUN then
if self.ability.name == 'Scalper' then
local sell_cost = 0
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] ~= self and (G.jokers.cards[i].area and G.jokers.cards[i].area == G.jokers) then
sell_cost = sell_cost + G.jokers.cards[i].sell_cost
end
end
self.ability.mult = sell_cost
end
end
end
}```
solution: copy a blank character into the new Jokers name
Eremel said that i'd have to change a part if the function as well
but i don't know what to change calculate into
update
oh
so card.update
key = 'scalper',
loc_txt = {
name = 'Scalper',
text = {'Adds {C:blue}+5 sell value of all other owned Jokers to Chips'}
},
rarity = 1,
pos = {
x = 0,
y = 0
},
cost = 5,
discovered = true,
local card_update_ref = Card.update
card.update = function(self, card, context)
if G.STAGE == G.STAGES.RUN then
if self.ability.name == 'Scalper' then
local sell_cost = 0
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] ~= self and (G.jokers.cards[i].area and G.jokers.cards[i].area == G.jokers) then
sell_cost = sell_cost + G.jokers.cards[i].sell_cost
end
end
self.ability.mult = sell_cost
end
end
end
}```
Now i gotta release it
Alright, ping me wherever you release it. đ
Do you have a new mod channel for this one?
How would I make something have an effect that would trigger once per blind when any hand containing a pair is played?
any advice on how to get into modding? especially for jokers?
No, just update
wuh what happen
It still doesn't work :<
This crashes the game
if context.joker_main then
if card.ability.extra.chips > 0 then SMODS.eval_this(card, {chip_mod = card.ability.extra.chips, message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}}}) end
if card.ability.extra.mult > 0 then SMODS.eval_this(card, {mult_mod = card.ability.extra.mult, message = localize{type = 'variable', key = 'a_mult', vars = {card.ability.extra.mult}}}) end
end
?? did they change something to eval_this
Donât tell me itâs that specific âengine/uiâ crash relating to âcoloursâ being nil
Still a bit new to the calculate section of jokers, if I want to add something like cavendish, but it needs 2 flags from other jokers, I'd use add_to_pool under calculate, right? And, if so, what context do I use to check for it?
For me it was engine/text IIRC
but I'm 200 commits behind apparently
It depends on which calculate you're talking about. But I don't think you'd use add_to_pool either way
I'm not sure because I think Steamodded recently added a helper function for that
I thought add_to_pool was that helper function,
I can speak of what happens in the background in vanilla. Basically you just need to set a flag to true or false as appropriate yes_pool_flag or no_pool_flag. Since you want it to depend on two Jokers, you need 2 or 3 flags, but only the last one is associated with the Not!Cavendish.
Each individual Joker should check the first or first two flags, and depending on their values they should set the third.
The context they check should be the context associated with whatever action you want to affect Not!Cavendish's availability
Where do I find the code for yes/no_pool_flag? I only know of it being set in game.lua when it's set as a variable, haven't gotten a good idea of how it works yet.
I'd search the vanilla code for it
I mean, that's where I'm looking, just haven't found it anywhere else yet.
It's used in get_current_pool
Just found it in common events, thanks.
guys I added 7/41 Jokers and the mod file is already 691 lines long, do I split the code in multiple files?
0.9.8 bunco is 4395 lines long i think you're fine
i donât think thatâs necessary unless you really want to
true!
ok then
OMG I MISCLICKED
never thought this would be me
Is that supposed to be a lot???
how do I use the load function? I need to use a specific syntax inside the helper file?
for the amount of content it adds not at all lmao
Yes
i don't know how to use the load function
i tried looking at the lua manual but brainError
Itâs like it wraps the file in function() ⊠end then calls it
You can register the Joker inside or return it and build it with the return
suppose i have
mainfolder:
main.lua
jokers:
my_joker1.lua
my_joker2.lua
and inside my_joker1.lua I have the SMODS.Joker = {}
i do loadfile('jokers/my_joker1.lua') in main file?
apparently no because it is considered a nil value and the game crashes
Oh Idk whatâs loadfile
But the two ways that I know of loading files in Lua would require the entire path of the mod
In whatever PC itâs in
load(SMODS.current_mod.path.."jokers/08_RobinHood.lua") in main file
Jokers aren't loaded into the game
nothing changes
Context for those who started reading this now:
This is my mod's folder
mymod/
- main.lua
- jokers/
- joker.lua
The joker.lua contains multiple SMODS.Joker initializations.
How do I load the Jokers from joker.lua into the main mod file?
load(NFS.read('jokers/joker.lua'))(), basically
NFS.read gets the file content as a string, load turns it into a function which you can then call
why not just nfs.load....
How do i announce my mod to some people
well you need to use your mod path still
SMODS.current_mod.path .. 'jokers/whatever.lua'
TL;DR:
I use require(path)
we had some issues with lua_reload and using require, for some reason
I was using require but it didnât work with 1.0
The / were turned into \
So I changed to NFS.load
I copied directly from Paperback and it didnât work
the newer version of 1.0 gives problems with require
this is how I do it
SMODS.Joker(NFS.load(SMODS.current_mod.path .. "modules/jokers/" .. "filename.lua")())
the file itself just returns the table you'd pass as input. it can also NFS.load other files inside
moment of truth...
đ
it runs perfectly
Does 1.0 steamodded have deck functions in it yet?
ah yes, I see these in the wiki now, was looking at the wrong place
does anyone know how to refrence the card that are played in a hand but not scored?
context.full_hand includes unscored cards
you'll still need to isolate the scoring ones though
for anyone that is trying to pull the non scoring cards in a played hand this worked for me
function non_scoring_cards(full_hand, scoring_hand)
local nonscore = {}
for k, v in ipairs(full_hand) do
nonscore[#nonscore + 1] = v
end
for k, v in ipairs(scoring_hand) do
for i = #nonscore, 1, -1 do
if nonscore[i] == v then
table.remove(nonscore, i)
break
end
end
end
return nonscore
end```
for some reason ease_dollars is activating every frame and idk how to stop it
return {vars = {card.ability.extra.dollars, card.ability.extra.mult}}
end,
update = function(card, card)
card.ability.extra.dollars = -(G.GAME.dollars - 20)
end,
calculate = function(self, card, context)
if context.end_of_round and not context.blueprint then
if G.GAME.dollars ~= nil then
ease_dollars(card.ability.extra.dollars)
end
end
if context.joker_main then
card.ability.extra.mult = math.abs(card.ability.extra.dollars)
return {
mult_mod = card.ability.extra.mult,
card = card,
message = localize {
type = 'variable',
key = 'a_mult',
vars = {card.ability.extra.mult}
}
}
end
end,```
it should set the money you have to 20 and add a mult from how much you lost/gained
but it keeps adding the money and it should only do it one time
Iâm gonna guess itâs that update function
is it possible to stop it from updating in the update function while the calc function is called
What are you trying to accomplish with this joker?
it sets the money you have to 20 and adds to itself a mult based on how much money you lost/gained after each round
in that case, just set money to 20 if context.end_of_round
(ok, I know that's not the whole story)
there's this thing called dollar_buffer. your actual money isn't G.GAME.dollars, it's that + dollar_buffer
try looking at base game jokers that contain dollar_buffer
i got it working thanks
is there a reason why my vars are not showing up in the desc?
pos = {x = 7, y = 0},
cost = 9,
unlocked = true,
discovered = true,
blueprint_compat = false,
eternal_compat = true,
perishable_compat = true,
loc_txt = {
name = "Revolutionary Joker",
text = {
"At end of round set {C:money}Money{} to {C:money}$#3#{} and add","a {C:mult}Mult{} depending on how much money was","{C:attention}lost/gained divided by 2{}","{C:attention} self-destructs{} if amount of money ever exceeds {C:money}#4#{}","{C:inactive}(Currently a difference of {C:money}#1#{} {C:inactive}dollars with a mult of {C:mult}#2#{}{C:inactive})"
}
},```
are you passing all the vars? looks like 3 and 4 aren't being found
they're used in the code
How do i make card packs
loc_vars only has two
is there a way to get more?
just add your other variables to the table in it
'innit
oh i see now
is there any way to change the weights of booster packs? if so, how?
Theyâre just numbers in the code
I forgot where but thatâs how I got the rates for Immolate
I'm trying to learn how to mod, and I've looked into the wiki thing as well as (tried to) look at the base game joker code
I can't really tell how things are done yet though, primary thing I've been trying to figure out is exactly where the information about joker abilities and stuff are
I'm not really sure how to translate anything into a mod file either
I found an joker mod with a single joker in it in the modding page that I've been looking at and trying to experiment with to try and figure out how things work and how to do things but I'm still pretty lost
so far, I've figured out how to change the joker's name in game, change it's art, and, I think, change it's description, but I've yet to try that one yet, but I do think I've found where it's done
any tips on learning how to make a joker?
yo, is it possible to have a floating component over a normal card (like legendaries) but the floating component is larger than 71x95?
this is the card in question
idk if this is asked a lot, but does anyone know why this isn't working? the Mods button isn't even showing up on the main screen
not related but damn thats some good art
wait whats up with the border?
seems off
i wonder if a potential workaround would be making the head "floating", like what's done for hologram/legendaries
but idk about making it bigger without that
Probably possible if you mess with the spritesheet logic for it
I have an idea, but am unsure if it would work as I haven't made a mod before
You could do something similar to photograph to make the sprite a different size and then just use that to draw the sprite of the joker
you might be able to have the base sprite be sideways then turn it afterwards
it looks like the head sprite might be able to fit in a 95x71
border was requested by drspectred
ah
well the threetwo things i need are:
- Fitting the full bull over the BG
- Have that replace the bull
- ||Replace the bull with the below image when you have $0 or less||
||the full intention being that drspectred discovers this ingame, so I guess it also needs to be not visible in the collection||
Yes, iirc I have made something that did and all I needed to do was make the sprite's atlas px and py set to the sprite size I wanted instead of 71x95.
i should get @regal wolf here too
The only issue you'd face is that soul_pos doesn't take a custom atlas, at least for base game.
what does it mean for something to have a custom atlas?
sprites exist inside of an "asset_atlas"
ahhh
Joker sprites are by default 71x95.
which points to the sprite sheet, posx and posy etc
And the size for this is larger than that
i have hardly used custom atlas' tho
should it be possible to just disable bull
and then replace it with a modified version?
or would that break things
it is possible yes
you can just overwrite the atlas entry
I just dont really know how to do that yet
so ill need to read up about it
unless someone wants to help xd
i wonder if we can overwrite the discovered bool for the bull joker
would be interested to see the code for this since i plan on having a similar card
does anyone know if playing modded balatro has a chance of breaking a save file? is it recommended to make a new profile? or is there something to account for that e.g. no cloud saving is done when launching with mods?
how would i check if the deck is a certain type? like in an if statement
also, how would i check if the player owns a certain voucher
G.GAME.used_vouchers?
you might have to adjust it a bit for consumables and what you are going for exactly, but this is the code.
ty
Anyone have any idea which file I should search for to find the code that loads the draggable card on the main menu?
if you want to modify its contents, you can look at code from Talisman or Brainstorm which do this
Donât remember where the code I modified was
Appreciated, hopefully I'll have better luck searching through them.
# Show a Gold Seal to confirm Talisman is Active
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "replace_card.states.visible = false"
position = "before"
payload = "replace_card:set_seal('Gold', true, true)"
match_indent = true
overwrite = false
@shell tangle
Perfect, found what I wanted, thanks.
yw
hello "developers"
hi
Hi
hello
hi
Maybe you should make a mod that adds a joker
Maybe 2
Maybe more
Or turn balatro into minesweeper im not one to judge
I have some things I want to add to debug plus
anyone know offhand where the code for determining if something contains a specific hand is stored
think i got it, misc functions
@scarlet merlin yes you can make it like this
what do i have to put into get_flush()/get_straight()? i thought it was context.scoring_hand but nope
Basically read other mods. The game itself works differently from mods in that it uses a single calculate_joker function defined in the Card class for all Jokers
those functions return a list of flushes/straights
usually there's only one so you can do get_straight(context.scoring_hand)[1] iirc???
if you're just doing contains then do next(get_flush(...))
Ooh yeah forgot bout that
Basically the base has extra transparent space to both sides
Maybe you could do without but this was straightforward to make
ok i have no idea where to even begin tbh
actually maybe ill try a different way of going about it
but the mult/chips being set to 0 doesnt seem to be working either so
hm
you don't need to recalculate if there's a flush
context.poker_hands exists
is that used for a hand containing a pokerhand or the scared hand being a poker hand
either way the calculating if there is a flush seems to be working i just need to figure out how im going to not allow a hand to be played
containing
I think you need to do it via Blind:debuff_hand, otherwise you can't stop calculation
so i gotta hook that yea
yeah, hook that instead of using a calculate function and check if your joker is present there
is that just if context.poker_hands == flush ?
i am guessing thats the issue with this btw but it might be something else
narrowed the issue down to next(find_joker not working hmmmmmm
ok fixed that
FINISHED.
now onto probably the two hardest cards that are by themselves
i already put that in superposition, you want my code?
which one?
im guessing the straights by the name
but sure, if youre fine with it (ill give credit)
yeah, figured the context would make it obvious
bet
you know what, actually
i could probably make this code like more effecient for both of us, gimme a sec
gotcha
okay nevermind. what
i do not have that joker why isnt it allowing that hand
yeah i figured out i was missing the next
thhank u tho
which context is right after a hand is scored?
just gotta find out where to update the ability of this joker then it should be done
Theyâre all listed here
oh thanks
with the forums would show the posts even if they havent been talked in in a while :/
okay so im seeing there isnt really a context for right after a card is scored, what do you think i should do to update my joker with G.GAME.current_round.hands_played so that it looks correct
will try it
oh yeah cause of rule 5
i think i asked you if i could use the code from one of your jokers and you said yes? but just in case i didnt is that ok
my memory is so bad lol
i dont mind
cool
also context.after isnt rly what im looking for since im just trying to get the "currently x mult" to update right after a hand is played
TIL the chip color in the code doesn't match chip color in the sprites
009cfd vs 009dff
unplayable
0/10
@spice scroll this is what you want it to do, right? (also works with JQKA2 and KA234)
your custom joker, i mean
yup! and of course that working with straight flush too if applicable
straight flush is basically detected by going
"is this hand a straight and a flush at the same time? okay go"
function get_straight(hand)
local base = get_straight_ref(hand)
local results = {}
local vals = {}
local verified = {}
local can_loop = next(find_joker('Superposition'))
local target = next(find_joker('Four Fingers')) and 4 or 5
local skip_var = next(find_joker('Shortcut'))
local skipped = false
if not(can_loop) or #hand < target then
return base
else
table.sort(hand, function(a,b) return a:get_id() < b:get_id() end)
local _next = nil
for val=0, #hand*2-1 do
local i = val%#hand + 1
sendDebugMessage("Card "..i.." is "..hand[i].base.value)
if #verified > 0 then
if SMODS.Ranks[verified[#verified].base.value].next[1] == hand[i].base.value then
sendDebugMessage(hand[i].base.value.." comes after "..hand[(val-1)%#hand + 1].base.value..".")
table.insert(verified,hand[i])
skipped = false
else
if skip_var and not skipped then
sendDebugMessage("Skipping because Shortcut.")
skipped = true
else
sendDebugMessage(hand[i].base.value.." does not come after "..hand[(val-1)%#hand + 1].base.value..".")
verified = {}
val = val - 1
skipped = false
end
end
end
if #verified == 0 then
sendDebugMessage("Starting new straight.")
table.insert(verified,hand[i])
skipped = false
end
if #verified == target then
break
end
end
if #verified < target then return {} end
return {verified}
end
end```
yes i use a 0-base loop; makes working with modulus much less annoying.
so this is just going in main yeah?
hm
wait which version are you on is this a 1.0.0 thing
Not sure what point you mean for right after a hand is scored? Could you try explaining a bit more?
ok so the joker gains xmult for every hand previously played that round. i want to put the update of the amount of mult it has right after a hand is finished scoring so that when you hover over the joker, it tells you accurately how much mult the next hand is going to give
Does it not work with just updating the number played when you calculate the xmult?
That should dynamically update your tooltip
it does but the problem is when it updates when the xmult is calculated, the hands_played variable hasnt incremented yet
Canât you just increment it there?
i suppose so
When does the built in one update?
Yeah if you want it to update before that then youâll have to keep an internal counter
gotcha
actually wait then it wouldnt work with judgement generating it mid round
and i run into "when do i update the counter"
oh, yeah
that's coding for alpha
Extraordinarily annoying limitation of the base game - there's code to let cards held in hand give Mult, there's code to let them give xMult, but there's no code to let them give Chips.
Does anyone know how I could get a card to give Chips in the same way that Shoot the Moon gives Mult?
im on 0.9.8 sadly, is it possible to adapt to the older framework?
Guys I have this Joker that changes ability when its rank goes up.
- Rank 1: nothing,
- Rank 3: +1 joker slot,
- Rank 7: +2 joker slot,
- Rank 10: +3 joker slot
How do I code that?
I already coded the PT_rankUp function and it works, I just want your ideas on how to implement each ability
I think the easiest way should be running G.jokers.config.card_limit = G.jokers.config.card_limit + 1 once when the joker passes each threshold
And then use remove_from_deck(self, card, from_debuff) to remove the right number of slots when you sell/destroy the card
So... this?
Looks good, yeah
Still trying to figure out this problem - I've tried a few different things, but nothing I've done so far has worked.
Is there any existing mods that have cards give Chips when in hand that I could look at? If not, I think the only thing left I could try would be Lovely patching, which I am not looking forwards to trying to learn
Try looking at this #1247703015222149120 message
check for context.cardarea == G.hand
Already looked at that a bunch unfortunately
I even found the exact area of the code where that context gets actually used:
if effects[ii].dollars then
ease_dollars(effects[ii].dollars)
card_eval_status_text(G.hand.cards[i], 'dollars', effects[ii].dollars, percent)
end
if effects[ii].h_mult then
mod_percent = true
mult = mod_mult(mult + effects[ii].h_mult)
update_hand_text({delay = 0}, {mult = mult})
card_eval_status_text(G.hand.cards[i], 'h_mult', effects[ii].h_mult, percent)
end
if effects[ii].x_mult then
mod_percent = true
mult = mod_mult(mult*effects[ii].x_mult)
update_hand_text({delay = 0}, {mult = mult})
card_eval_status_text(G.hand.cards[i], 'x_mult', effects[ii].x_mult, percent)
end
if effects[ii].message then
mod_percent = true
update_hand_text({delay = 0}, {mult = mult})
card_eval_status_text(G.hand.cards[i], 'extra', nil, percent, nil, effects[ii])
end
It's got the code blocks for Mult and xMult, but nothing for chips, since the only in-hand cards are Shoot the Moon, Baron, Reserved Parking, and Raised Fist.
So, if I do a Lovely patch here to add a block for chips, it should work.
The big issue is that I have to do a Lovely patch.
How so? What would I do to get it to work?
Just have the Joker return chips in the context that iterates over the hand
Look at the code I posted - returning chips does nothing, since it literally doesn't check for chips in this context
It only checks for mult, xmult, and dollars since that's all the base game does
(This is in state_events.lua if you want to have a look yourself)
I canât look at it right now
Is this context.individual and context.cardarea == G.hand?
Thereâs another similar context for the Jokers that apply while youâre at the hand
The difference being whether the card or the Joker applies the bonus
That happens before hand calculation, right?
Already tried that, and it doesn't seem to do anything
I think it specifically needs the local variables inside the function
function mod_chips(_chips)
if G.GAME.modifiers.chips_dollar_cap then
_chips = math.min(_chips, math.max(G.GAME.dollars, 0))
end
return _chips
end
function mod_mult(_mult)
return _mult
end
The local variables mult and chips are the things actually updating the score and the score display, calling mod_chips does nothing
I'm just making the Lovely patch. It probably isn't too complicated.
Patching should work, the evaluate play loop has very few effects not in base game
Just replicate the h_mult one
Okay this isn't working
[manifest]
version = "1.0.0"
dump_lua = true
priority = 0
[[patches]]
[patches.pattern]
target = "state_events.lua"
pattern = '''
if effects[ii].h_mult then
mod_percent = true
mult = mod_mult(mult + effects[ii].h_mult)
update_hand_text({delay = 0}, {mult = mult})
card_eval_status_text(G.hand.cards[i], 'h_mult', effects[ii].h_mult, percent)
end
'''
position = "after"
payload = '''
if effects[ii].h_chips then
mod_percent = true
chips = mod_chips(chips + effects[ii].h_chips)
update_hand_text({delay = 0}, {chips = chips})
card_eval_status_text(G.hand.cards[i], 'h_chips', effects[ii].h_chips, percent)
end
print("If you can read this, the patch worked")
'''
match_indent = false
I can't see anything wrong with this but it's not adding the chips and it's not printing the debug message
It's also not throwing any errors in console that I can see
you cannot search for multiline with patches.pattern
Ah
you need to use regex for multiple lines
alternatively do a position = "before" patch with if effects[ii].h_mult then as the pattern
Still not doing anything that I can see
It's doing something!
It's not quite working yet, but it's at least patching the game!
Thank you!
IT WORKS!!
Jeez that was two hours spent on a single Joker I thought I could finish up in like 20 minutes max
Thank you Victin and Myst for helping me through this!
what does that joker do?
ah
Literally one of the simplest effects in this mod
hello
hi
you can't escape me
I think I'm going insane
I reckon that patch should be provided by Steamodded @frosty dock
Agreed. As I see it, if another mod wants to have a similar effect and they create another patch like this, the effect will trigger off of both mod's patches and apply the chips bonus twice.
What do you return in the file 11_Twins
nothing, like all other files
I want to add some functionality similar to Hiker to Steamodded. Someone else had done part of the implementation for Cards, I had some for Jokers, but the other person isnât around. I would like to (re)implement all of it at some point
I agree, I'm not sure if better_calc solves it already though
no clue what better_calc is supposed to do
but i'm not going to bother looking into it
like. how does it "just work"
do tags have add_to_pool?
for Blueprint/Brainstorm, what does the context.blueprint line actually do
to prevent infinite copying like leftmost brainstorm đ€
(its a counter)
yeah
(as you can see, if context.blueprint > amount of jokers +1 -> return)
. Oh
the naming of alot of variables in this source code are.... unfortunately chosen, to word it kindly
better_calc?
can someone help? The game doesn't start
.
it says that SMODS.current_mod.path .. 'jokers/11_Twins.lua' is nil
-- JOKERS
load(NFS.read(SMODS.current_mod.path .. 'jokers/03_Milady.lua'))()
load(NFS.read(SMODS.current_mod.path .. 'jokers/08_RobinHood.lua'))()
load(NFS.read(SMODS.current_mod.path .. 'jokers/11_Twins.lua'))()
load(NFS.read(SMODS.current_mod.path .. 'jokers/13_BackAlleyDoctor.lua'))()
only the Twins gives problems, the other ones load perfectly
Maybe report the bug to whoever made the mod
i made the mod
I reported the bug to myself and myself said "i don't know how to fix it"
Either the namefile isnt 1:1 or SMODS.current_mod.path changes too quickly
Might want to put it in a var
you have this in 11_Twins.lua
which uh
LMAO not lua moment
that's not lua syntax
are custom editions available? can't get them to work
in the 1.0 I mean
every time I try to create a blank edition I end up with this
maybe I'm missing some argument?...
do you have a shader file?
the file_name argument should point to that shader the same way as atlases do
how do you even do modding things i've looked at some stuff and i don't know how to even, like, start
Yeah you need a shader
The shader should be declared as its own object too iirc
I can send you my code later this evening if you havenât figured it out
But this error appears
is the file in assets\shaders\...
The example might be old
yea
its the same way atlases work
^
I will have both resources and assets now
Why do you have resources?
it's always assets\some folder for steamodded stuff
I have shaders there
that I use to replace vanilla some shaders
I guess I'll move everything
you can take_ownership vanilla shaders probably
I am unsure if you can take ownership of them
probably
I didnât foresee anyone needing to change vanilla shaders
What do you change about them out of interest?
I have these since 0.9.8
Change the quality of rendering
Specifically for background, intro and flame shaders
Are they on the bunco GitHub?
iirc it needs your mod prefix
bunc_glitter?
Yeah
didn't work for file
trying both
didn't work for both
still the same error
I avoided that error before by registering the shader manually
Letâs see the code?
like the way I replace shaders
here
Itâs file_name not path
but then it crashed in the collection
trying
now works!
ty
uh oh
shader works on the locked/undiscovered edition
Got a screenshot? I can investigate later on
Are there any tools for making custom pools?
so, I currently have a +mult joker that I'm beginning with, how would I change it into a xmult joker?
I tried to change something which I thought would do this, but it ended up having no effect in game
(in the return statement) instead of doing mult_mod you can do Xmult_mod
ooooh, ok, I didn't even see that part initially lol
Yooo, secret rares
hmm yes
Reverse Cryptid
i had made it give +mult equal to the value of the card and the value of stone cards is apparently massively negative
it is if you use get_id to determine the "value"
yeah
maybe the nominal chip value is better suited
i fixed it to be that
oh god I've screwed up my git tree
how so?
by the way: the seed i was using to test this was gabeyk9
I think it's to do with the new structure of api_hooks maybe?
and then I was trying to work on a branch but then make a change to my main branch instead and screwed it all up
I think I've got it all back though now
I actually have no idea what happened
when I reapplied what I'd stashed it did half of it?
Did it fail to reapply something?
it says on github your fork is synced with main
but the AltTexture branch is still there and last pushed half an hour ago
yeah I think I've managed to get back to how it was
right
how is best to get the new file structure in this working branch
overrides is basically just what api_hooks was without the palettes part and some changed comments
so just base functionality overrides, and then everything else thrown in utils?
overrides for any non-lovely hooks on base game functions
yeah
utils for whatever else i guess
there's also core which is where I used to throw stuff like that, now it's just mod UI and probably needs renaming
now, I'm struggling to get my AltTexture branch to update to the newest version
should I just rebranch and copy stuff over manually?
seems like about the same amount of effort as manually merging
we're working again đ
oh do I have write access to the main branch @frosty dock ?
I don't think so, but that's out of my control
seems like you do
I have 51 card suggestions for my mod
one per playing card other than 2 of diamonds?
everyone knows the jack of spades isn't a real playing card.
look at this chaos
https://docs.google.com/spreadsheets/d/1hqeq9gArictq63JySjWV8s3Nd2T1Wl29d1IAgngN0vo/edit?gid=0#gid=0
Sheet1
Card type,Name (You),Name (Card),Rarity,Effect(s),Ye or Ne,Art (if Ye),Description,Cards required,Unlock conditions,Name (you),Name (feature)
Joker,AlexZGreat,Arson,Rare,Destroy Joker to the left and to the right when full house is played, gain 0.25x mult per destroyed joker,Meh
Joker,Al...
Do you like my idea for âStop postingâ?
I mean I think itâs fine considering you can never open a shop again and the random things you get will probably be trash
otay
how would i make it so consumables have a chance to be negative when appearing in shop? or, where is the code that determines the random edition for shop jokers?
create_card_for_shop()
thanks
me when i make localization a nightmare because... i dont remember because i made this 3 months ago
where is that
card.lua:1133
is it possible to make it start with set jokers i'm having a lot of trouble finding them to test
Debug Mode/DebugPlus lets you spawn jokers in.
Debug Mode basically jsut enables LocalThunk's debug mode for Balatro and DebugPlus adds more (although requires Lovely).
i feel like im missing something obvious with these jokers repeating their effects over and over
Surely this works, right? (clueless)
guys me (and some other people) has to add 94 new stuff to stupidity
now whose code are we stealing today
You caught me LMAO
LMAO
flush_type doesnt seem to be getting the suit correctly
okay no the debug is showing that its getting the flush type correctly wtf
why is it just giving me the world
flush_type being local means it only works inside the if block
it's nil when you start checking it
(you can't play it)
how do i fix this
key = 'scalper',
loc_txt = {
name = 'Scalper',
text = {'Adds {C:blue}+5 sell value of all other owned Jokers to Chips'}
},
rarity = 1,
pos = {
x = 0,
y = 0
},
cost = 5,
discovered = true,
local card_update_ref = card.update
card.update = function(self, card, context)
if G.STAGE == G.STAGES.RUN then
if self.ability.name == 'Scalper' then
local sell_cost = 0
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] ~= self and (G.jokers.cards[i].area and G.jokers.cards[i].area == G.jokers) then
sell_cost = sell_cost + G.jokers.cards[i].sell_cost
end
end
self.ability.mult = sell_cost
end
end
end
}```
"good artists borrow, great artists steal" -me
SO TRUE
I did cook a fully custom obj_pool API to make booster easier to make so
It's not 100% stolen
đ„
oh yeah btw
23/38 done
2/38 done without art
5/38 with minor bugs
4/38 being worked on
4/38 not started (shop joker, redrawing card joker, transformation jokers)
Don't know why it's all squished together but hey, it works.
Check the card area's max thing
the real question is where do i go from here
Thanks, apparently it was being set to half the size of the pack.
for @spice scroll or anyone else on 0.9.8 in need of a "looping straights" detector
just replace "Superposition" with your joker name of choice.
it should be compatible with custom ranks, assuming they get added to G.P_CARDS, but let me know if it's not.
Spelling mistake detected
It was originally in the game as âCaino â
When he fixed the typo he never changed the slug I guess
or the ability name
i managed to get the default love2d error handler screen
me when I make a syntax error with lovely
yeah I think 2 three of a kinds is just a three of a kind too and not a full house iirc
yeah
I was wondering if there was a pool API
I wanted to make a custom pool with different types of cards
I'm not sure if it's applicable for that unless it would use get_current_pool
Cause it's basically letting you make custom versions of that.
This is what it looks like right now.
Still have to make some changes to base (like adding rarity)
(this is also totally not stolen from LobCorp xdd)
Along with making sure preset works.
(It's supposed to let you skip the starting pool and rarity parts as some object groups only need to reduce the starting pool or factor in other rarities and let SMODS.Obj_Pool handle the culling part but I haven't tested it set so it likely doesn't
).
Using it is just setting the _type used in create_card or get_current_pool to the obj_pool key
Like this
card = create_card("d6_jokers", G.pack_cards, nil, nil, true, true, nil, 'dsix_buf')
why the file name is omittedđ
It might be something to do with loading the file from the mod differing from how Steamodded loads it.
But idk
ohh đ€ makes sense
How would you word an effect that does Blue Seal with Acrobat's timing?
They both use "final hand" differently
Acrobat should be able to tell if it will be the last hand if the round /j
blue seal uses "final played poker hand" and acrobat uses "final hand of round"
there is difference
Unrelated: in principle the final hand of round needs not be the final hand, but I think that's good enough
hmmm
I decided to go with:
When you play your
final hand each round,
create its Planet card
Is the effect only triggered if itâs your last possible hand?
yeah those two lines should just read update = function(self, card, context)
does editions api have calculate function argument for scoring effects or it's not ready yet?
it's in todo
yeah ejwu has been looking at rewriting calculation stuff
you can do chips, mult and xmult, and a combination of them, and I'm not sure if the version in main branch has p_dollars or not
looking for my own effects for now
will inject then
(don't know where to inject tho yet)
now what
what is the effect?
1.2X Chips
ewwww Xchips
yup, but it's not going to appear normally in the pools
what is the edition called
glitter
you'll need to inject for playing cards and jokers
it's quite an easy injection actually
I don't know where exactly this calculation is located, that's why I'm confused
maybe here?..
no there's specific edition ones
yup, there's if edition_effects.jokers then afterwards
there's another one further up the stack for playing cards
aha, I see it too
Do I need to pass anything to the cards themselves so these condition will work?
I don't believe so
I think you should just need the actual calculation
so just modify the xMult ones
curly brackets
hmmm, anyone had any experience taking ownership of seals?
can you screenshot this part of your IDE with line numbers?
your editor
so the code?
it says } supposed to close the thing at line 22
wait
key = 'scalper',
loc_txt = {
name = 'Scalper',
text = {'Adds {C:blue}+5 sell value of all other owned Jokers to Chips'}
},
rarity = 1,
pos = {
x = 0,
y = 0
},
cost = 5,
discovered = true,
card_update_ref = card.update
card.update = function(self, card, context)
if G.STAGE == G.STAGES.RUN then
if self.ability.name == 'Scalper' then
local sell_cost = 0
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] ~= self and (G.jokers.cards[i].area and G.jokers.cards[i].area == G.jokers) then
sell_cost = sell_cost + G.jokers.cards[i].sell_cost
end
end
self.ability.mult = sell_cost
end
end
end
}```
dude i sent the area that the errors at and the error itself
I'm not scanning your code for you, give me the lines numbers
22 to 49
just go like this then I don't have to count, or solve it yourself
I mean I'm pretty sure I've told you multiple times how to solve this problem everytime you've posted it here, but now I'm asking for a little more context you're simply refusing to do a very simple task
pretend im dumb (if you weren't already)
do you know how to take a screenshot?
yes
take one of the code and paste it here
that's it?
change every self in the update function to card
The issue might be before line 90 to be fair
Like some missing bracket or comma which makes something out of scope
thats not supposed to be there
An extra thing can also be at fault
you put your update function like it's a literal hook to Card:update(), which it isn't
you can't just put random code inside a table constructor
please just learn lua properly, and not only will you be able to stop wasting your own time, but also ours
clearly you don't
^^
I can't imagine this is intended behaviour
i can
yeah having pages is probably for the better
what do you call this then?
that's a file you sent in discord
i can't tell you where that's saved on your computer
you can tell him where it's not saved though!
okay that was easy
folder names are case sensitive
your file is in Stupidity/Assets/2x, not Stupidity/assets/2x
also consider stopping being behind 3 weeks worth of commits on steamodded
please use snipping tool
xdd
oh god
tbf, I also thought they were case sensitive but did a quick test on my end
I now have an ASSETS folder
64 different assets folders with different capitalization
I used a shortcut
in other news, I can't take ownership of default seals. I think it's because they don't have a prefix in base game because for some reason they're stored in a different table, any ways around this?
it's not standardized behavior though
it's case sensitive on linux (which is probably what I was thinking of)
and it's possible to make directories case insensitive in windows (used for WSL)
i use window
huh, seems like the current take_ownership implementation won't allow you to get around the prefix getting prepended if the exact prefix isn't already there (self.omit_prefix is used, so it checks on the class itself)
...
yeah I tried throwing a omit_prefix = true into the table and that didn't go to plan
hm
too bandaidy
also not great for cross-mod ownership taking
I'll just allow omit_prefix on the object, might fix more thoroughly later
HOW THE HECK DOES local card_update_ref = card.update have an unknown symbol
darn it
please learn lua
I get this with omit_prefix on the object
wtf
hang on maybe this is my atlas mistake
is the card colors button getting moved pls
where do you want it myst
i remebered
not at the bottom
just pushed something to allow omit_prefix on the object
preferably
for _,v in pairs(G.P_CENTER_POOLS.Seal) do
SMODS.Seal:take_ownership(v.key, {})
end```
running just this gives me these lovely card backs
you can't put random code in an object constructor and expect it to work
this is getting annoying
shaders use F# đ€ another language
I shall not have my time be wasted further
Hey eremel
you're literally not providing the information needed to help you
hmm?
https://docs.google.com/spreadsheets/d/1hqeq9gArictq63JySjWV8s3Nd2T1Wl29d1IAgngN0vo/edit?gid=0#gid=0 add some ideas
Sheet1
Card type,Name (You),Name (Card),Rarity,Effect(s),Ye or Ne,Art (if Ye),Description,Cards required,Unlock conditions,Name (you),Name (feature)
Joker,AlexZGreat,Arson,Rare,Destroy Joker to the left and to the right when full house is played, gain 0.25x mult per destroyed joker,Meh
Joker,Al...
no
đ
do you want to add a card suggestion
don't question why theres so many cause i don't know either
guh i'll need to learn how to make a shader eventually
absolutely not looking forward to this
can't understand why negative edition needs so many lines
I thought it would be simple as R = 255-R, G=255-G, B=255-B
scroll down to the effect part
so this if (negative.g > 0.0 || negative.g < 0.0) { SAT.b = (1.-SAT.b); }
vec4 SAT = HSL(tex);
if (negative.g > 0.0 || negative.g < 0.0) {
SAT.b = (1.-SAT.b);
}
SAT.r = -SAT.r+0.2;
tex = RGB(SAT) + 0.8*vec4(79./255., 99./255.,103./255.,0.);
if (tex[3] < 0.7)
tex[3] = tex[3]/3.;```
this
ok
everything is 0-1
is the top better?
I don't think she meant this
it was about that it's below collection menu I think?
I also accidentially enter this menu sometimes
oh yes I am moving that
I vote to keep it where it is 
like this
it's not F# actually, it's a variation of OpenGL
fs just stands for fragment shader
it's GLSL but an old version because love
vscode is wrong

it's old but it's also modified and nonstandard
yes
These effects are written in a language based on GLSL (OpenGL Shading Language) with a few things simplified for easier coding.
what does this mean
simplification > standardization
I think itâs Love2Dâs fault not their fault
you can use SMODS.Shader({name = "test", path = "test.fs"}) on newest version
line 109 is love.graphics.setShader( G.SHADERS[_shader or 'dissolve'], G.SHADERS[_shader or 'dissolve'])
thanks

but the 0.9.8 compatibility would gone 
i copied negative shader and changed a number
you'll need to change every occurance of negative to test in it too
compat_0_9_8.lua casually missing features 
nah isn't this a case of it not working for people running 0.9.8?
the compat is backwards
not forwards
i just change Card:draw function to always draw test shader
is it possible to set default pitch in the sound api?
ok thanks
yeah
but unrelatedly, it's missing suits and ranks
either way I'm again starting to tend more towards thinking of supporting 0.9.8-related things as being a footgun
Yo imagine a pirate with a footgun for a pegleg
where do I set custom edition's sound?
(assuming I already registered the sound itself)
sound = { sound = "foil1", per = 1.2, vol = 0.4 },
per is pitch, vol is volume
I wonder where per comes from
percent?
Calculated with regard to 1 being the base pitch. Each reduction by 50 percent equals a pitch shift of -12 semitones (one octave reduction). Each doubling equals a pitch shift of 12 semitones (one octave increase). Zero is not a legal value.
Are they transparent or black spots?
transparent
Interesting
you've replaced the base shader though right?
no i made a test shader
but you aren't drawing the game's base shaders
you've overwritten the draw function for testing
yeah
i should inject here right
eh, you're still calling the original
in this image im not

in what circumstances are you using this shader?
dunno, i'm just learning shader
fair enough
namsilaT
Is there anyway I can check if a card held in hand has an edition?
Maybe itâs trying to play Bad Apple
Yes
how to make it transparent đ€ changing alpha seems only affect slight light reflection on card
are you still using your test function or have you patched now?
i'm patching
can I see the patch?
ah right yes
so your shader is transparent
the problem is that the game has already drawn the shadow and card underneath
check if card.edition exists
so what to do
hmmm
you could change your pattern to this one if not self.no_shadow and G.SETTINGS.GRAPHICS.shadows == 'On' and((layer == 'shadow' or layer == 'both') and (self.ability.effect ~= 'Glass Card' and not self.greyed) and ((self.area and self.area ~= G.discard and self.area.config.type ~= 'deck') or not self.area or self.states.drag.is)) then and return to break the loop
but then it won't draw anything else
let me check what invisible joker does
or stneicl
oh no, they're just transparent sprites
Thanks
M
m
jesus christ
that's not what I thought what happen
The big joker who makes all the rules
yeah, the call is before it does the hover/tilt stuff though
big jimbo that swirls around and changes facial expression as final boss blind
there is no shadow in the images i think
yeah, you've injected before it
assuming you've copied the hover.tilt into your lovely patch?
yeah
so doing this you don't draw the shadow
it won't draw floating sprites though this way
which part enables hovering ui
patching adds the difficulty to find the key part, i'm directly overriding Card:draw to learn 
Double checking, for the no_pool_flag, I just need it in the config to work - As soon as I throw the flag into the flag pool, I don't have to make any checks beyond that to remove it from the pool, right?
are fusion jokers compatible with 1.0.0
yup
how to add small description thingies?
want to add edition's description to edition's tag
info_queue[#info_queue+1] = G.P_CENTERS.e_greyscale
return {}
end```
they should do
I want to do some kind of sanity check regarding if there's loc_vars for tags
but not sure how
will just send message
put some variables in it
sanity check passed
will try variables
got it
I was supposed to type e_bunc_glitter, not just bunc_glitter
thanks!
ah that makes sense
is working fine without e_ for other things so I assumed this is something from old versions
I think it's to do with looking directly in the G.P_CENTERS table
does it work on legendary jokers?
wish i could use calculate for editions, maybe soon? 
maybe soon
That does not play nice with cryptidâs 3 layered exotics
Can anyone identify the issue with this? Trying to increase Xmult for each Hearts card held in hand at the end of the round. Currently goes through each one and shows "error" a single time, no matter how many hearts, and doesn't change the value at all. I assume it's something to do with the for loop, unsure what steps to take.
if context.cardarea == G.hand then
for k, v in ipairs(context.other_card) do
if v:is_suit('Hearts') then
self.ability.extra.Xmult = self.ability.extra.Xmult + self.ability.extra.Xmult_add
return {
message = "Upgraded!",
colour = C.G.MULT
} end
end
end
end```