#💻・modding-dev
1 messages · Page 108 of 1
its one file, cant be that bad
i jsut delete the existing lovely and steammodded files, and then redownload the new versions?
Yeah.
basically
Oh shit Cryptid has a way to increase selection limit
But its source code is also very fucking cryptid, it's not like the documentation that I've read on Steamodded
isnt cryptid heavily dependent on talisman/lovely? thats what i've heard, but i've never chanced myself to look at its code
No idea
I mean
all mods are heavily dependent on Lovely
Yeah.
hrm
1226a means the first update on 12/26 if you haven't noticed that pattern, and lovely doesn't have updates as often, so it's pretty obvious when it's out of date.
Two things, are you testing on a new run, and is it still the same issue with something about seal and nil?
one moment
let me defintely not start testing on a new save
-# but yes, same error
new save, same error
the entire thing raisedcateyebrow~2
well what's at that line in state_events
Mods/lovely/dumps/functions
ah, ty
im going to presume its related to the fact im using repetition_only? since IIRC that context is related to red seals?
Yeah fuck it I'm just gonna scrap the idea of my Tangle card's original mechanic and turn it into something else, which do you guys think is better?
- When the tangle card is placed between two cards, it will form a bridge between those two cards' levels. For example, a Tangle card between a 7 and a 5 would make it count as a 6
- When the tangle card is placed between two cards, all three cards will count as the highest level and suit amongst them
i like the latter idea more, but both are super cool
do effect.seals.repetitions = card.ability.extra.repetitions
uhhh, put a ```lua
else
effect.seals = {}
end
enhancement calculation is a little scuffed
can you show the whole block
move it above the end above it
thought so, sure
need to change the effect.repetitions line again too
iooh, okay
testing it now
this error has haunted me for ages, i got it with another joker and had no idea what to do with it 😭
let me write you a quick lovely patch
What contexts are there for checking the suit and level of a card?
I want to make an if case to check if my Tangle card is between two cards, and checks itself and the two cards to see which has the highest level, and also checks that level's suit
wooo, my first lovely patch!
niiiiiiiice
(context.other_card:get_id() == x) and context.other_card:is_suit("Hearts")
obviously you can replace the x and Hearts with whatever you need
Is there a way to make it more modular
presumably? i do not know of it though 😭
i do have code that checks if all 4 suits are currently in a played hand, if that'd help
Let's see it
local suits = {
['Diamonds'] = 0,
['Spades'] = 0,
['Hearts'] = 0,
['Clubs'] = 0,
}
local suits_req = {
['Diamonds'] = 1,
['Spades'] = 1,
['Hearts'] = 1,
['Clubs'] = 1,
}
for i = 1, #context.scoring_hand do
if context.scoring_hand[i].ability.name ~= 'Wild Card' and not context.scoring_hand[i].config.center.any_suit then
for k, v in pairs(suits) do
if context.scoring_hand[i]:is_suit(k) then
suits[k] = suits[k] + 1
end
end
end
end
if suits['Diamonds'] >= suits_req['Diamonds']
and suits['Spades'] >= suits_req['Spades']
and suits['Hearts'] >= suits_req['Hearts']
and suits['Clubs'] >= suits_req['Clubs'] then
-- do stuff here
okay, put this in a lovely.toml in your main folder, and then go back to the effect.repetitons = ....
wait
that's missing a bit, hold on
sure
So for x, that's an integer right? Do Aces, Jacks, Queens and Kings count as ints?
If it is then it'll be a whole lot easier to check for the highest level with math.max
A = 14, K = 13, Q = 12, J =11
i have a joker in the works that makes them score their actual values, and not just 10 and 11
-# i just cannot get it to work
but yes, they are all ints
if tangle cards are common maybe itd work out
Tangle cards are Enhancements so they don't have rarities
Do they?
So a tarot card equivalent
enhancments never get other_card in contexts
Would work well I think
you'll have to manually look at context.scoring_hand
Guh
im still curious about how it worked fine for you, but my bucket of bolts and botches went "nuh, no work"
calculate = function(self, card, context, effect)
if context.cardarea == G.play then
local left_card, right_card
for i, playedCard in pairs(context.scoring_hand) do
if playedCard == card then
left_card = context.scoring_hand[i-1]
right_card = context.scoring_hand[i+1]
break
end
end
if left_card and right_card then
what the fuck do I put here
end
I'm at an impasse
-# im gonna be banging my head agaisnt this for a while
are you doing the average number thing or the highest card thing? raisedcateyebrow~2
Highest card thing
"When played between two cards, all three cards will be scored as the highest level and its suit."
hrm
@teal estuary I think I'm actually just going to unscuff enhancement calc if you don't mind waiting till later
fine by me :] thank you for this
just ping me or something when its unscuffed mwah~1
ironically, while i wait, im gonna start working on other enhancements for a different mod
if left_card and right_card then
local highest_rank = math.max(left_card:get_id(), card:get_id(), right_card:get_id())
local highest_card
if left_card:get_id() == highest_rank then
highest_card = left_card
elseif card:get_id() == highest_rank then
highest_card = card
else
highest_card = right_card
end
Guh does this look right to yall
it looks right, no idea if it should work though 😭
Yeah I need to do the calculation part
I don't really know how to approach it, any suggestions?
Or wait, maybe I could just change the suit of the three cards and let calculation happen automatically
Fuck it may be too op if the player keeps using Tangle and they'll eventually turn their whole deck into one suit and one level
yeah itrs essenitally just free cryptid/DNA 😭
💀
A less OP way of approaching this is to check if left and right cards exist, check the highest level only (no suit modifications), and then add the number of chips x times depending on the number of cards there are (3 cards worth of chips (left + tangle + right), or 2 cards worth if there is no left or right card (tangle + right or left + tangle))
Sound good?
that sounds good, yeah
Which contexts or variables do I use for granting chips again
for enhancements? im not sure, theres chip_bonus and bonus that are natively supported
Natively supported?
Oh that
its the card value displays...
antimatter deck without the cryptid
so basically
Every effect at once
antimatter deck without cryptid with the bad stuff
calculate = function(self, card, context, effect)
if context.cardarea == G.play then
local left_card, right_card
for i, playedCard in ipairs(context.scoring_hand) do
if playedCard == card then
left_card = context.scoring_hand[i-1]
right_card = context.scoring_hand[i+1]
break
end
end
local card_count = 1
local highest_rank = card:get_id()
if left_card then
card_count = card_count + 1
highest_rank = math.max(highest_rank, left_card:get_id())
end
if right_card then
card_count = card_count + 1
highest_rank = math.max(highest_rank, right_card:get_id())
end
if card_count > 1 then
chips = highest_rank * card_count
end
end
end
Tried my hand at doing this and then realized a fuckup
Unless the Tangle is the highest card, it won't proc its effects if the cards on the sides of it are higher since they get scored and not the Tangle
does the key for something need to have a prefix to prevent conflicts between mods or does steamodded automatically handle stuff like that?
I still have to get Anaglyphic and plasma deck working
steamodded automatically handles prefixes in most* cases
-# * There's some places where the prefix isn't added by default when specifying keys elsewhere, e.g., requires on vouchers
more importantly, when directly interfacing with object tables, creating cards and the like, you need to specify the full key including a class prefix and mod prefix
Ok anaglyph deck has been implemented
Now for plasma
Ok Plasma been added
Fun Fact: I divided 255 by the deck count to get this
in this case 15 to get 17 opacity in Paint.net
paint.net my beloved
Then I merged them all together and put it back up to 100%
essentially, the average of each pixel in the decks
this actually looks very pretty
I need to double check if my calculations are correct later
I think it's correct for the pixelation stuff
Need some insights here, is the logic correct for proccing the card at least correct when played AND scored? Or is there something I'm missing?
Interesting... same method, different program
Oh the message was deleted but https://love2d.org/forums/viewtopic.php?t=92916
For the file picjer
interesting
I'll still use the old one (the right one)
I found love.filedropped(file), which is enough for me, at least for now
But this also can be useful, thanks
does anyone know how i can play the start_disolve animation without destroying the card?
i lovely pathced a card with "Fire" enhancement to have a 1:2 chance to turn into a card with the "Ash" enhancement, but i want the animation to play when it changes instead of just not at all
You probably want to use events to play the aninatiin and then and then change its base
I was doing something like this before bit it was kinda messy
Or hmm seems I set some kind of arg to do ot
Idrc
Yeah, hard part is enhancements are way harder than jokers, there isn't as much you can do without patching
Now I understand why love.filesystem is bad 
are retriggers just borked somehow on enhancements? i tried to just make a “this enhancement retriggers this card once”, and it just >:(
doesnt wanna
I hate enhancements so much lol
I dont know how you've set it up but you can't use return you need to modify things directly, many contexts are not passed through the same way as jokers. Right now i'm just lovely patching the code for my enhancements that i really cant get to work
Oh gosh why do you do this to yourself
i had a mod idea and i wont stop till its primarily complete
every metallic element as an enhancement
-# maybe some as editions
I have to admit that is really cool
ty, its related to my other main mod ever
its a factorio mod, which adds every element
i have a couple ideas for balatro though, like having reactive elements have a chance to destroy themselves + the entire hand played for a big bonus
the more reactive the element, the higher the chance
currently all i have is iron (+5 mult in hand, worse steel), and currently trying to add silver (1 retrigger)
Maybe instead of destroy you can make it decay, like it usually would
oh this is for things like lithium, francium, caesium, etc - for decaying elements it'll be different
Ah
an idea im taking over from my actual balatro mod is having radiation be represented by retriggers
so maybe an enhancement can retrigger the entire hand played, and after x amounts of retriggers the card is destroyed
Cool
(or base it off how strong the radioactive element is, if its a weak/alpha emitting one it can only retrigger the one next to it, if its a gamma emitter/strong it can retrigger the entire hand)
you get the point though trianglepupper~2
Create new consumables for all type of particles lol Bèta Alpha and Gamma, base decay chance on half time and give consumables after decay, change card into more stable version (eventually deck will be purely lead)
oooh, thats neat
i was thinking about lead
an idea thats floating around is that lead cards cannot be retriggered, but can always be played and are just better in general
im not sure how i'd do that
but im sure its possible clueless
im looking at the source code for red seal and repetitions joker
im pretty sure that its possible
oh wait really? raisedcateyebrow~2
is there a way to force a specific voucher so i can test things?
yeah take a look at state_events line 664-780
Cryptid does it with echo cards so I’m sure it’s possible somehow
hrm, ty
when in shop go to collection -> vouchers and hit ctrl 3
oh, yeah sure
calculate = function(self, card, context, effect)
if context.cardarea == G.play and context.repetiton_only then
effect.repetitions = card.ability.repetitions
end
end
i've tried context.repetition and context.repetition and not context.repetition_only
it all just does.. nothing
create a file: enhancements.toml
sure raisedcateyebrow~2
patches add shit to source code this should be in your toml file
[manifest]
version = "1.0.0"
dump_lua = true
priority = 1
[[patches]]
[patches.pattern]
target = 'file where the code should be added'
pattern = '''this is where it gets added ({position} this line)'''
position = 'before'
match_indent = true
payload = '''
this get added
'''
for pattern i would do this local eval = eval_card(scoring_hand[i], {repetition_only = true,cardarea = G.play, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, repetition = true})
I’m in the process of unscuffing enhancement calcs
yay
Should be done later this evening when I’ve got more time on my pc
I’d recommend not touching them for now as this will probably be a breaking change
position should be after in this case
oh, cool
-# i wasnt sure if it'd effect me with anything else i wanted to do, sorry if i seemed impatient mwah~1
just no more working on enhancements then?
It’ll probably come with some additional contexts too, so if anyone has any requests for where they need calcs that are missing let me know
I mean you can work on them, they’ll just need changing again later
meh, practice on lovely patches is practice with lovely patches
i had a stroke trying to read that
-# how did i spell it wrong the same way, twice
Did anyone work with Balatro music? I'm trying to stop and reload sound file but without success. How to do it properly?
yeah thats what i was wondering, did you mean practice?
i did
fair enough tbh 😭
these are the only patches i made maybe you can get some help from them
[manifest]
version = "1.0.0"
dump_lua = true
priority = 1
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''local cards_destroyed = {}'''
position = 'before'
match_indent = true
payload = '''
local cards_burned = {}
'''
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''if destroyed then'''
position = 'before'
match_indent = true
payload = '''
if scoring_hand[i].config.center_key == 'm_avatar_fire' and not scoring_hand[i].debuff and pseudorandom('fire') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra.odds then
burned = true
else
burned = nil
end
if burned then
cards_burned[#cards_burned + 1] = scoring_hand[i]
end
'''
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''for i=1, #cards_destroyed do'''
position = 'before'
match_indent = true
payload = '''
for i=1, #cards_burned do
G.E_MANAGER:add_event(Event({
func = function()
cards_burned[i]:set_ability(G.P_CENTERS.m_avatar_ash, true)
cards_burned[i]:add_to_deck()
return true
end
}))
end
'''
ty ty
maybe for payload this would work
if scoring_hand[i].config.center_key == 'm_modkey_enhancekey'
for h = 1, scoring_hand[i].ability.repetitions do
reps[#reps+1] = eval
end
end```
not entirely sure tho
i shall try it, ty
tell me how it goes
actually, wait, wanna check, does this look good to you?
all good :]
i always forget the "then, do and ," started this journey few days ago and been doing python for the grater part of my life
oh yeah makes sense, im used to factorio modding which is like an entirely different language compared to this 😭
yeah my python experience doesnt help very much either
Does this work?
Now i'm invested
i think i made a mistake
that's a steel card
it looks like one
it does, thats why i added the 999. and 100g markings 😭
Then what is it?
silver card
oh
i wasnt sure what to do with silver apart from "hehehe shiny", and somehow shiny translated into a retrigger
does this look good?
does look pretty good, i like it
this is how it looks ingame
I think the label looks a bit off
what could make it better?
Might work better as a floating sprite
oooooo
Or at least the bottom outlines too
lol i forgor how to do that
and for some reason it got thanos snapped off of the smods docs?
You might need to add something to the eval_card functions in common_events
what do you want to do
make a floating sprite like in the soul
oh its just soul_pos
yes
i think they accidentally deleted it from the docs
Old DebugPlus detected
theres a new one?
Its updated fairly frewuenekty (I have actial releases now)
That looks so much better
What changed?
ROBLOX
yeah, its a roblox mod
a revival of an old and VERY buggy mod i once made
lol was testing and got a natural straight flush in the first hand
How can I test a Balatro shader?
Outside of Balatro, I mean
I remember some websites that could run shaders in the browser, but I never understood how they worked very well
i'm trying to use the cryptid method of supporting stickers on playing cards and i dont know what im doing wrong
help please?
You can also test inside balatro using debug plus’s watch command
I know I can test them in-game
But I can’t do it live while writing the code
I need to launch the game each time
Unless the watch command circumvents that?
That’s exactly what it does
so many wands
it's literally just 2 rn
They're based on the actual ones that are used in the base game's cards
as you can see here
The only thing as of right now is changing the "pentacles" to coins
Less sacrilegious imo
I WOULD do my inverted color one but everyone's been doing that
Well assuming you were on the master branch a lot. https://github.com/WilsontheWolf/DebugPlus/blob/master/docs/changelog.md#debugplus-100
Sorry wrong thing copied edited
Stars and moons?
i love the jimbo with 5.. thingies
all the art is nom though
what is the top left one meant to be though?
i was on 1.0.0 so ig not very much
a printer
It's supposed to look like cards being fanned out like the printed gaff cards
BEAN
bean
Why is an other event queue of 0 showing then?
Has anyone done stuff with permanent effects on cards?
I was about to say, is it possible to do it for +mult, xmult and money?
but considering you made a mult version, i guess it is
does it majorly break compatibility?
idk
but yeah, you can essenitally give them anything
never tried retriggers, that might not work
I don't plan to do retriggers
fair enough
but yeah, + and xmult, money
anything that enhancements can give cards, is something a joker can give
does anyone how i can split up my main.lua file so that i have multiple files like jokers.lua and decks.lua, with in the main file just some code that says "hey run these files!"
assert(SMODS.load_file('path')())
and that just does it?
are you sure its load_file, my vscode autofills loadfile\
now i dont have the game files opened in here so it might be load_file but idk
NVM figured it out
yup
yeah it should be at the end, otherwise it crashes if the file doesn't return anything and doesn't have useful error logs if it actually failed
how do I use it
check debug plus wiki
the pain of having to export all my jokers to x2
I can just put the files separately, right? I don't need a spritesheet of all of em?
Spritesheets sound painful when adding new jokers
It's easier to convert a spritesheet to 2x
Because you just need to upscale one file
I guess
I'm just scared of jokers getting misaligned in the spritesheet if I make the spritesheet bigger
they shouldnt? at all? raisedcateyebrow~2
just make sure its always a multiple of 71 and 95 respectively
aight then
Following up. I'm trying to prevent my joker from earning the default amount of chips (currently 50 chips * spectral card usage) by locking the chip bonus down to 0 but I'm getting an arithmetic on nil error
if context.joker_main then
local usedspectral = G.GAME.consumeable_usage_total.spectral
local specbonus = card.ability.extra.chips * usedspectral -- this is either 0 or actual multiplied bonus.
if usedspectral == nil then usedspectral = 0 end -- Lock the amount of used spectral cards to 0, not nil
if specbonus == nil then specbonus = 0 end -- Same thing for this, except for the bonus chips
if specbonus == 0 then return end -- Don't do anything if the bonus equals 0
else
return {
card = card,
chip_mod = card.ability.extra.chips + specbonus,
message = '+' .. card.ability.extra.chips + specbonus .. ' Chips',
colour = G.C.CHIPS
}
end
do local usedspectral = G.GAME.consumeable_usage_total and G.GAME.consumeable_usage_total.spectral or 0
that should fix the problem
That was attempted before, actually.
Was my idea, too, but it still gave out nil for some reason.
Though, the usedspectral == nil check sound come right after defining it.
local usedspectral = G.GAME.consumeable_usage_total.spectral
if usedspectral == nil then usedspectral = 0 end -- Lock the amount of used spectral cards to 0, not nil
local specbonus = card.ability.extra.chips * usedspectral -- this is either 0 or actual multiplied bonus.
if specbonus == nil then specbonus = 0 end -- Same thing for this, except for the bonus chips
That one did work to prevent that error, I'm mainly looking at specbonus
I need to pick up my cat from the vet but I can explain later
Still wish we could pass custom sounds through to card_eval_status_text via the effects table.
making sure usedspectral is a number will mean specbonus will always be a number though
I won't be modding this game anymore.
I give everyone permission to reuse, edit reupload freely any or all of my mods for balatro
They're all made for steamodded 0.9 so you would need to update it to 1.0
https://next.nexusmods.com/profile/infarctus/mods?gameId=6217
oh I see the problem, it's a logic error, your return is in the else blocked linked to if context.joker_main, it should be linked to if specbonus == 0 ...
I think you can actually simplify it to this
if context.joker_main and G.GAME.consumeable_usage_total and G.GAME.consumeable_usage_total.spectral then
return {
card = card,
chip_mod = card.ability.extra.chips * (1 + G.GAME.consumeable_usage_total.spectral),
message = '+' .. card.ability.extra.chips * (1 + G.GAME.consumeable_usage_total.spectral) .. ' Chips',
colour = G.C.CHIPS
}
end
That assumes the default base value is to be given still even if no spectral cards were used.
Right.
Hang on, this would be a somewhat simple Lovely patch to pull off on this bit in common_events.lua... no?
sound = extra.edition and 'foil2' or extra.mult_mod and 'multhit1' or extra.Xmult_mod and 'multhit2' or 'generic1'
Just being cautious with such things... first it's my overwrite of the SMODS.eval_this function, now this...
How would I determine whether a card being sold is a joker or not? Is there something similar to context.card.is_joker or something?
context.card.ability.set == 'Joker'
Thank you!
alright, time to get started
how would i make this retrigger the card that's enhanced? i'm not sure how to do retriggers 😅
code: ```lua
local enhancement = {
name = "Sewn Card",
pos = { x = 2, y = 0 },
loc_txt = {
name = "Sewn Card",
text = {
"{C:green}Retrigger{} once per",
"other {C:enhanced}Sewn Card{}",
"in {C:blue}played{} hand",
"{C:inactive,s:0.8}(Art by {}{C:dark_edition,s:0.9}@ricottakitten{}{C:inactive,s:0.8}){}"
},
},
config = {retriggers = 0}
}
enhancement.calculate = function(self, card, context, effect)
local other_cards_sewn = -1
for _, card in ipairs(G.play.cards) do
if card.ability.name == 'Sewn Card' then
other_cards_sewn = other_cards_sewn + 1
end
end
if other_cards_sewn > 0 then
enhancement.config.retriggers = other_cards_sewn
end
end
return enhancement
we should be getting a rewrite on enhancement calcs, to make retriggers work 😭
like in a deck or joker
when i tried it i needed a lovely patch
-# the lovely patch needs fixing
but just wait a little bit and the fix should be out
is there a way to change the gameover state to be false if it's true in calculate?
like prevent it and give +1 hand and +1 discard instead?
i was looking at mr bones and it doesn't exactly do what i had in mind 😅
you could check to see if (after scoring) the chips to beat the ante are lower than the current chips then give a hand + discard
i was trying context.game_over and context.before
that one made sense to me
oh yk what?
i just thought about something
Is there a way to have description text only appear if a certain ability is true or not? I want a joker to activate once a couple jokers are sold, but I don't want the description text to stick around once it's active.
loc_vars
Well yeah but like how do I make description text appear or not depending on that
I don't want it to just show a different value with #1# and stuff, I want the line to just not show up at all
Has anyone made a 52 Pickup Joker before? I had an idea for one but it's a little fuzzy in my brain.
right now
how do I add a SINGLE joker
I'm seeing a lotta modders make a separate Jokers folder
Well I mean, I'm gonna add more, I just wanna get to add the first one
honestly it's just half the time for organization purposes
SMODS.Joker {
--all joker stuff, im too lazy to write it all out
}```
yeah, all my code is in one file
I see
you need 2 entires in the localisation tables, and then you can switch between them in the loc_vars return
i might split it up at some point, but its fine
My mod's name is Ludus, my file should be Ludus.lua right
it can be whatever you want IIRC, i did name mine after my mod though
you can name your file whatever ya want
where can I find the joker guide? I can't find it in the steamodded wiki
-# there are example jokers in the example mod file, but uhhh
oh okay
its in SMODS.Center
SMODS.Joker {
key = 'name',
loc_txt = {
name = 'Ingame Name',
text = {
"A {C:attention}joker{} description",
"Gives {C:mult}+#1#{} Mult"
-- C:attention gives the text a yellow colour
-- C:mult/C:chips colours the text to the colour of mult or chips
}
},
config = {extra = {x = y}},
loc_vars = function(self, info_queue, card)
return {vars = {card.ability.extra.x}
end,
-- Sets rarity. 1 common, 2 uncommon, 3 rare, 4 legendary.
rarity = 1,
unlocked = true,
discovered = true,
atlas = 'Atlas Name',
pos = {x = 0, y = 0},
cost = 4,
calculate = function(self, card, context)
end
}```
heres a basic joker outline
oh hey, sticker star
i had the idea to put all the stickers from that game and turn them into jokers
why not consumables
that is fair.
i do wanna make a mod i just have. so many ideas.
and i dont know how to code in lua.-
me neither! so im getting started like right now
hmmmm
i do have an example mod
but
it's helpful but also not.-
and looking at the game's code is like looking at moon runes.
Steamodded itself brings example mods to peek at.
Alright so it doesn't crash anymore, but there's now a discrepancy with what chips I expect to get vs. what I get. (One spectral card yields 100 chips instead of 50)
SMODS.Joker{
key = 'profren',
loc_txt = {
name = 'Prof. Renderer',
text = {
'{C:chips}+#1#{} Chips per {C:blue}Spectral{}',
'card used this run',
'{C:grey}(Currently{} {C:chips}+#2#{}{C:grey}){}'
}
},
atlas = "Jokers",
pos = {x = 0, y = 0},
config = {
extra = {
chips = 50
}
},
rarity = 3,
cost = 8,
loc_vars = function(self,info_queue,center)
return {vars = {center.ability.extra.chips,center.ability.extra.chips * (G.GAME.consumeable_usage_total and G.GAME.consumeable_usage_total.spectral or 0)}}
end,
calculate = function(self,card,context)
if context.joker_main and G.GAME.consumeable_usage_total and G.GAME.consumeable_usage_total.spectral then
return {
card = card,
chip_mod = card.ability.extra.chips * (1 + G.GAME.consumeable_usage_total.spectral),
message = '+' .. card.ability.extra.chips * (1 + G.GAME.consumeable_usage_total.spectral) .. ' Chips',
colour = G.C.CHIPS
}
end
if context.using_consumeable and context.consumeable.config.center.set == 'Spectral' then
return {
card = card,
message = 'Upgrade!',
colour = G.C.ATTENTION
}
end
end
}
siiiigh this is gonna suck ass
the most fun projects always do
this is not fun
Remove the 1 + within 1 + G.GAME.consumeable_usage_total.spectral.
this thing i'm doing is so easy
nevermind
i'm so sad rn
Success! It still doesn't do the upgrade text like what I wanted but it's working and with no crashes!
-# the art looks pwetty
Thanks, I drew it myself. Balatro's art style's easy to replicate
oh yeah, defintely, its so easy to recreate
I think I'm starting to get it, this is what I've got so far. Two things, is there a way to make the text colored and is there a way to do this where it removes all of the lines #1# and below when active?
key = "test_joker",
loc_txt = {
name = "Test",
text = {
"+{C:mult}#2#{} Mult",
"#1#",
"{C:inactive}Requires {C:red}#4#{C:inactive} sacrifices and",
"{C:attention}#3#{C:inactive} empty spaces to activate."
}
},
config = {extra = { mult = 25, max_cost = 2, b_cost = 2, active = false }},
atlas = "Balscr",
blueprint_compat = true,
pos = { x = 12, y = 3 },
rarity = 1,
cost = 3,
loc_vars = function(self, info_queue, card)
if card.ability.extra.active then
return {vars = { "Currently {C:green}Active{}", card.ability.extra.mult, card.ability.extra.max_cost, card.ability.extra.b_cost}}
else
return { vars = { "Currently {C:red}Inactive{}", card.ability.extra.mult, card.ability.extra.max_cost, card.ability.extra.b_cost } }
end
end,
calculate = function(self, card, context)
if not card.ability.extra.active then
card.ability.extra.active, card.ability.extra.b_cost = handle_bcost(card.ability.extra.max_cost, card.ability.extra.b_cost, context)
end
if card.ability.extra.active then
if context.joker_main then
return {
mult_mod = card.ability.extra.mult,
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
}
end
end
end
}```
The one time you get rewarded for using Sixth Sense + DNA with my joker
Did you try moving if context.using_consumeable and context.consumeable.config.center.set == 'Spectral' then part above? Though weird how context.consumeable.config.center.set may not be doing it..?
I don't think I touched it since I added it in. It's been at the bottom of the calculate function for a while
Whilst using Spectral card, print(context.using_consumeable and context.consumeable and context.consumeable.config.center.set) did print Spectral... may need to play around with the condition checking.
Is there any way to modify the texture of a card that I've taken ownership of? I want to change the texture of a card when an edition is applied to it but I know nothing about writing shaders so I can't properly achieve the effect I want with them.
i made it work btw
is there a way to make your hands set to 1 and discards set to 1 on a deck?
like on the apply function or somethign?
OH
nevermind
trying to make it so at the end of the round one of the numbers on the card goes down by 1
oh my god i'm so stupuid
show your config and loc_vars raisedcateyebrow~2
config = { extra = { chips = 50 } },
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.mult } }
so if i change mult to chips
that might fix it...
loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chips } }
end,
looks good
yeah looks good
Did you create a new joker in game or use the same one from the same run? I ran into that issue a few days ago.
basically what i did was alter the example joker
Sorry I worded that badly, when you reload the game, do you continue the run or make a new run and get the joker again?
what does your code look like
#1#.
Yeah.
Ohh I didn't see that, yeah the number between the # references the variable in loc_vars
#X# is the number entry for the returned value from loc_vars.
HOT DAMN
So if you return 5 values from that function, you can go up to #5#.
May need to hold CTRL as well in the recent updates.
Nah I installed it a few days ago, you just gotta hit 3 while hovering it
You're not return-ing the right stuff.
chip_mod for adding Chips, it should be equal to the value you want to be added.
In your case, it'd be chip_mod = card.ability.extra.chips.
Also?
mult_mod for mult, and Xmult_mod for xmult
hmmm
Message may not be set up right.
might be
return {
message = localize({ type = "variable", key = "a_chips", vars = { card.ability.extra.chips } })
chip_mod = card.ability.extra.chips,
colour = G.C.CHIPS
}
y'never know
oh i just noticed this
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }
😭
we all are
maybe i should save mod dev for the. pros. i wanna make my own stuff but i dunno if someone would be willing to help
that should prolly do it
i'd be more then willing to help
i dont know everything but i can help
oh; sweet
i should probably organize my thoughts before i do anything tbf
what would be easier
an entire pack of new jokers or an entire pack of consumables
jokers.
all I gotta do now is either 1. be responsible and make it dissapear once it goes to 0, or 2. leave it as is so it can go to negative values (evil choice)
Packs vs Zomblinds!
Thank you
adds the entire pvz1 almanac roster as cards
oh no yeah.
im not stupid.
not
entirely.
i wouldnt mind seeing people make expansion packs though 👀
This shader mess is making me question whether I can code
IF ANYTHING
this is just a concept; i still wanna find a cool idea for a themed mod; i'm open to suggestions
Shaders are evil wizard shit no matter the language used
Oh I know but normally I can read something and get a general sense of what's going on, nope not with this nightmare
okay so question yall
i want to make my joker 2 effects
- get +7 mult whenever you use a consumable
- have a 1/10 to double his mult instead how would i do that
im surprised no-one's made a mod that adds jokers based on boss blinds
green needle /s
reduces hands to 1 gives +200 chips
FUCK I THOUGHT I WAS BEING CLEVER
its something with 1 hand
sounds easy enough to do? i cant give the exact code, but
if [consumable being used] then
card.ability.extra.mult = card.ability.extra.mult + 7
end
if psuedorandom('hdundndnd')[odds check] and not context.repetition and context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * 2
end
[put the card_eval_status_messages here]
[put the mult_mod return here]
thank you that helps enough
i know its very abstracted, but you get the point
yeah
im glad to help :]
its like my first joker so thanks for the help
i can give you an example of card_eval_status_messages if you'd like
i have that i think
-# you also be better to put them inside each if statement, not as their own thing
cool, cool
yeah anyways time to read the steamodded wiki to find the consumable thingy
ill need it lol
i think i got the first part?
seems good? im not sure of a way to see if a consumable has been used, i presume there is one though (maybe tarot joker is a place to look?)
wait nvm thats when a consumable removes a card
alrighty lemme look trough the game files lmao
uh that's not valid syntax haha
-# the [] are just meant to be a [insert thing here], do take the [] out :]
Is there a way to remove the shader from a sticker?
First attempt at a shader and edition. It's just meant to run and not to look good. I need to figure out a good pipeline for working on shaders and seeing what they look like still.
-# i could get behind that if it saved space
-# mimimimmim
that brings up a question, are shaders usable on enhancements? i have an idea for an enhancement but i have no idea what to make it look like but "half of card is negative"
I think you'd need to patch the function that renders the center but yes
I also want to make an Enhancement that uses a shader
☹️
i think this is what i need for the first part
What deck of cards are these
...how do I make a card wiggle like Trading Card, except for last discard? This only makes it wiggle once and right as the discard occurs.
if G.GAME.current_round.discards_left == 1 and not context.blueprint then
local eval = function() return G.GAME.current_round.discards_left == 1 and not G.RESET_JIGGLES end
juice_card_until(card, eval, true)
end
are you doing that in context.discard? you need to activate it after the discard that happens when there's 2 discards left then
Outside, actually.
i think i got it not sure
What do you use for Shaders?
How does info_queue work? I'm trying to add a tooltip for a custom sticker and I can't seem to get it.
What do you mean
what did you do to make the shader?
I wrote it
I used the fluoride(?) shader from Steamodded as a reference, with some functions taken from vanilla
i see
and the specific calculation is one used by Bunco, just rewritten in the shader language
isnt it pseudorandom raisedcateyebrow~2
omfg im dumb
is this the channel where i can get help with mods 😭
okay now tf is this issue
Why are you using self.using_consumable? Do you have a config part in your joker with { extra = { mult = 1 } }?
calculate = function(self, card, context)
if self.using_consumeable then
card.ability.extra.mult = card.ability.extra.mult + 7
end
if pseudorandom('dyonisus') and G.GAME.probabilities.normal and not context.repetition and context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * 2
end
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_chips', vars = { card.ability.extra.mult } },
colour = G.C.mult,
mult_mod = card.ability.extra.mult,
}
end
like thats what it does
tip, when posting code do this:
```lua
[code here]
```
Any way to remove the abilities of a joker when a sticker is applied to it? Sorta like debuffing but I need the sticker to stay active
i didnt put it between my config i think oops
There's the perma_debuff tag that the one challenge uses, but I'm not sure if it applies outside of that challenge
nvm didnt need it i think
Oh nevermind I can just take_ownership and make calculate an empty function
What's the difference between tex and uv?
is this too strong as a common
Uncommon, maybe.
calculate = function(self, card, context, effect)
if context.cardarea == G.play then
local left_card, right_card
for i, playedCard in ipairs(context.scoring_hand) do
if playedCard == card then
left_card = context.scoring_hand[i-1]
right_card = context.scoring_hand[i+1]
break
end
end
local card_count = 1
local highest_rank = card:get_id()
if left_card then
card_count = card_count + 1
highest_rank = math.max(highest_rank, left_card:get_id())
end
if right_card then
card_count = card_count + 1
highest_rank = math.max(highest_rank, right_card:get_id())
end
if card_count > 1 then
effect.chips = highest_rank * card_count
end
end
end
Trying my hand at making my custom enhancement called a Tangle (if there are adjacent cards to the Tangle, then the Tangle card will score the number of chips as the number of cards + itself with the highest level), unfortunately it's not triggering, so there are some things I'm missing:
- Is the played card check properly implemented?
- Is the chip calculation properly implemented?
- Is math.max the way to go for detecting the highest level of a card?
mmm I guess so, wild cards are easy to come by
key = 'Mythos',
loc_txt = {
name = 'Dyonisus',
text = {
"{C:mult}+#1#{} mult",
}
},
rarity = 1,
atlas = 'Mythos',
pos = { x = 0, y = 0 },
cost = 4,
eternal_compat = true,
blueprint_compat = true,
brainstorm_compat = true,
using_consumeable = true,
calculate = function(self, card, context)
if using_consumeable then
card.ability.mult = card.ability.mult + 7
end
if pseudorandom('dyonisus') and G.GAME.probabilities.normal and not context.repetition and context.repetition_only then
card.ability.mult = card.ability.mult * 2
end
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.mult } },
colour = G.C.mult,
consumeable = card,
mult_mod = card.ability.mult
}
end
end
}
i feel that im so close yet so far
ik the text aint right thats for later
Bit late too reply, but it was not my screenshot, was just wondering what had changed since last version since i downloaded it
How do I have a joker create a specific other joker?
I found this elsewhere in the code and it does make a joker but I can't figure out how to get it to make a specific one.
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function()
play_sound('timpani')
local card = create_card('Joker', G.jokers, nil, 0, nil, nil, nil, nil)
card:add_to_deck()
G.jokers:emplace(card)
return true end }))
create_card('Joker', G.jokers, nil, nil, nil, nil, 'insertkeyofjokerhere', 'rngseed')
Which lua file in Balatro's source code can I find the list of all contexts?
okay i was being dumb, apparently the way i was doing a while loop froze the game
so cool, i now have a voucher which gives a "reincarnation" effect that if you lose a run, you can restart with a new seed and keep some of the same cards at the start
edens blessing?
well it isnt fully random cards, it's randomly selected from the cards at the end of the previous run, and i plan to have them have an effect applied to the cards as well as a special joker granted from the voucher effect being used
question though just for some visual flair for it:
is there a way I can make the voucher appear on screen after the new run starts, dissolving, and turning into the joker that is added?
i was messing around w/ modding and managed to get this effect working, but it required changing a bunch of things about how hands are calculated & how context is handled. could something like this be achieved using steammodded?
(my guess is that it wouldn't be, but maybe i could change the effect to something like "swap played cards and cards in hand before and after scoring"?)
Some things will require Lovely patching, truly.
there was also this one (not quite sure about this effect game-design-wise lmao) which i implemented by passing an extra field in context for end-of-hand calculations
Definitely
-sy that Joker is.
And now I need opinion on this being a Legendary or Rare. Unless I can make a custom rarity that's not complicated.
what does '
-sy' mean ?
totally rare
Handsy. You'd need to use up quite a few hands to perform such consecutive levellings.
probably
i tried making a challenge where you start w/ a negative eternal copy of this joker & it destroys a random joker every time it gets reset ... don't think i ever won
it's really easy to accidentally get like 20,000 points in ante 3 and reset it
@wintry solar How could I make a regular, repeated tiling edition shader? I've been trying for hours, starting from the flipped shader in the example mods but I couldn't figure it out.
🤷♂️
I found tutorials for non-regular shaders, but they're complicated enough I'm not sure how to reverse engineer a regular shader from them
@wintry solar Do you know this at least?
I thought I could use the screen coordinates modulo the image size to choose the part of the atlas I want to draw
I don’t remember, I haven’t touched shaders for months
v_v
i don't know about the specific shader language balatro uses but i'd guess tex is the texture color at the pixel and uv is some sort of 2d coordinate (i'd guess it's (0,0) for the top left of a rect and (1,1) for the bottom right?)
^ this sounds correct
I guess I want to know what's the difference between the texture and the sprite
I thought one was the image and the other the in-game object
Because I think the tiling shader will require computing tex at new coordinates, especially since that's what the flip shader does
And it needs some component that depends on the screen position
yall ive been looking and idk why it doesnt work like why doesnt the mult get added to it like i just dont get it
show off the code raisedcateyebrow~2
config?
the test joker i made a bit ago didnt need one?
what's using_consumable
Your Joker wants to remember a changing value so it needs to store that somewhere
did the joker give chips, mult, money or retriggers? raisedcateyebrow~2
yeah
you need to define a config for.. any of that
Doing any of those individually doesn't matter, but needing to update the value does
Although it is generally good practice to use a config even if you don't need one
oh using_consumable is a field in context i guess
i think it gave a flat amount of chips
Well, only if you actually have something to put into it
looks like it's actually "using_consumeable"
If the logic is elsewhere then it doesn't need a config
in that case i think in the calculate function you'd want to replace if using_consumable then with if context.using_consumeable then
config = {extra = {mult = 0 },
-# you'll also need to replace any card.ability.mult with card.ability.extra.mult
okay so it ended up having one i was just blind lmao
how so?
put it anywhere next to your rarity or cost
heres an example, you also need loc_vars for the description
is putting everything in extra incl. +mult generally considered good practice for modding? seems like that isn't done in the base game
does the same apply for xmult? it looked like not only was just using ability.x_mult standard, xmult from ability.x_mult was applied automatically
maybe i misread the code..
so this should work?
looks good, but make sure your config contains the same thing as your .extra.x
wdym?
i think config shouldn't say extra = { Xmult = 0 } but instead extra = { mult = 0 }
also iirc it would be good to replace the magic numbers 7 and 2 for scaling w/ other fields in extra ?
as in
config = {
extra = {
mult = 0,
consumeable_mult = 7,
random_mult = 2
}
}
``` and then replace `7` and `2` w/ `self.ability.extra.consumeable_mult` and `self.ability.extra.random_mult` respectively
the random code also looks a little bit off... not quite sure though
instead of pseudorandom('dyonisus') and G.GAME.probablities.normal it should be pseudorandom('dyonisus') < G.GAME.probabilities.normal / [some number goes here]
how likely do you want the double mult to be?
almost -- i think random_chance inside calculate should be self.ability.extra.random_chance
also: since the random chance thing doesn't check for context first (aside from checking for blueprint & repetition) it seems like it'd have a chance of doubling every time literally anything happens
when do you want the random chance to trigger?
instead of the +7
i.e. when using a consumable?
maybe move the if pseudorandom(...) inside if using_consumeable in that case
more like
if using_consumeable then
if pseudorandom("dyonisus") < [...] then
card.ability.extra.mult = card.ability.extra.mult * self.ability.extra.random_mult
end
card.ability.extra.mult = card.ability.extra.mult + self.ability.extra.consumeable_mult
end
```i think
if you don't want the +7 to trigger when the x2 triggers, you can do
if using_consumable then
if [...] then
-- *2 thing
else
-- +7 thing
end
end
should i make it so that if a run isn't a seeded run it still uses the same seed on restarting with the afterlife effect or should i have it randomize the seed again?
afterlife ?
I'm making a mod that adds vouchers that upon losing a run, it gives you a second chance, restarting the run with extra effects
the one i have partially functioning now picks random cards from the deck you lost with and replaces random cards in the new deck
and, I'm planning for each to have associated joker cards only accessible within the afterlife runs
i'm not sure from a balance standpoint but i think it could be cool to have a second chance on the same seed (main problem is that it might encourage people to obsessively take notes on exactly what shows up in every shop etc. which might be tedious)
one thing that'll help balance-wise is the afterlife vouchers won't show up if you've used one so you dont get to just keep restarting
possibly i could do something where it uses a new seed for most things, but the boss blinds use the original seed, if that's somehow possible
i dont get the error sorry that im asking so many questions
the newline is breaking it i think
or, maybe some weird stuff with the conditions needing parentheses or something
Hey gang I'm not actually home rn because of vacation but for when I get back, is it hard to add an extra menu or something to Run Info?
now this is the issue
what's the code look like currently?
instead of sending screenshots, should send it as code blocks, it'll help.
just use
```lua
(code here)
Lua Language Server uses the Language Server Protocol to offer a better Lua development experience for your favourite editors.
extra = {
mult = 0,
consumeable_mult = 7,
random_mult = 2,
random_chance = 5
}
},
cost = 4,
eternal_compat = true,
blueprint_compat = true,
brainstorm_compat = true,
using_consumeable = true,
calculate = function(self, card, context)
if
( pseudorandom('dyonisus') < G.GAME.probabilities.normal / random_chance and not context.repetition and context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * self.ability.extra.random_mult)
else
(using_consumeable then
card.ability.extra.mult = card.ability.extra.mult + self.ability.extra.consumeable_mult)
end
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } },
colour = G.C.mult,
consumeable = card,
mult_mod = card.ability.extra.mult
}
end
end
yea we don't have this unfortunately
there's more to that
its just bad syntax in general
the if pseudorandom, remove the opening parentheses there, as well as the newline, and remove the closing parentheses after random_mult
for using_consumable, remove the parentheses and make it either "else if using_consumable" or add an if before the using_consumable on the new line and add another end
Heya, I’m new here and I’m interested in starting to mod the game. I have a fair bit of coding knowledge but have no clue where to actually start (getting set up, organization, what loader to use, etc.) Are there any resources that can point me in the right direction?
extra = {
mult = 0,
consumeable_mult = 7,
random_mult = 2,
random_chance = 5
}
},
cost = 4,
eternal_compat = true,
blueprint_compat = true,
brainstorm_compat = true,
using_consumeable = true,
calculate = function(self, card, context)
if
pseudorandom('dyonisus') < G.GAME.probabilities.normal / random_chance and not context.repetition and context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * self.ability.extra.random_mult
else
if (using_consumeable then
card.ability.extra.mult = card.ability.extra.mult + self.ability.extra.consumeable_mult)
end
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } },
colour = G.C.mult,
consumeable = card,
mult_mod = card.ability.extra.mult
}
end
end
}```
https://github.com/Steamopollys/Steamodded/wiki follow the install instructions here to get Steamodded and theres example mods to look at included
now thats the issue again
which line is line 48
if using consumable
Thank you!
remove the parentheses for that. also, since the if is on a new line you need to add another end to it
if context.using_consumeable
ah that i didnt know
...Is there not a way to declare Steamodded a source or library in VSCode or something?
wdym with the double if btw?
not double if, but as an example
if thing then
do_thing()
else if other_thing then
do_other_thing()
end
vs
if thing then
do_thing()
else
if other_thing then
do_other_thing()
end
end
ohhh
alright
extra = {
mult = 0,
consumeable_mult = 7,
random_mult = 2,
random_chance = 5
}
},
cost = 4,
eternal_compat = true,
blueprint_compat = true,
brainstorm_compat = true,
using_consumeable = true,
calculate = function(self, card, context)
if
pseudorandom('dyonisus') < G.GAME.probabilities.normal / random_chance and not context.repetition and context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * self.ability.extra.random_mult
else
if context.using_consumeable then
card.ability.extra.mult = card.ability.extra.mult + self.ability.extra.consumeable_mult
end
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } },
colour = G.C.mult,
consumeable = card,
mult_mod = card.ability.extra.mult
}
end
end
}```
64 is last line you can see
honestly idk whats wrong
...are you defining using_consumeable = true, as part of Joker?
i think so i have no idea what im doing
using_consumeable is a field in context, so i think you'd want to replace using_consumeable in the calculate function w/ context.using_consumeable & then remove the using_consumeable = ... part
Is there a way to make a joker that doesn't randomly show up in shops? I wanna have it obtainable through other means.
i think you'd have a few options:
- using a
no_shop_flagthat's always present or ayes_shop_flagthat doesn't exist - defining a new rarity w/ weight 0
maybe a few other things?
yeah that still isnt the issue lol but yeah changed it
Weight zero might work if I can figure out how to get rarities working, I tried yesterday and I kept crashing lol
Are there other decks like this and if so, where can I download these?
Especially if I just make it visually the same as Rare
the error message looks like a syntax error but it's hard to tell where exactly the error would be without seeing the full lua file ... is the codeblock you sent the full file?
lemme sent that rq
why do you want the joker to appear as Rare? is it supposed to show up using things like the "create a rare joker" spectral card and the tag that makes the shop have a rare joker?
--- MOD_NAME: Mythos
--- MOD_ID: Mythos
--- MOD_AUTHOR: Salems_Bane
--- MOD_DESCRIPTION: An example mod on how to create Jokers.
--- PREFIX: xmpl
----------------------------------------------
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Mythos',
path = 'dyonisus.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'Mythos',
loc_txt = {
name = 'Dyonisus',
text = {
"{C:mult}+#1#{} mult",
}
},
rarity = 1,
atlas = 'Mythos',
pos = { x = 0, y = 0 },
config = {
extra = {
mult = 0,
consumeable_mult = 7,
random_mult = 2,
random_chance = 5
}
},
cost = 4,
eternal_compat = true,
blueprint_compat = true,
brainstorm_compat = true,
calculate = function(self, card, context)
if
pseudorandom('dyonisus') < G.GAME.probabilities.normal / random_chance and not context.repetition and context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * self.ability.extra.random_mult
else
if context.using_consumeable then
card.ability.extra.mult = card.ability.extra.mult + self.ability.extra.consumeable_mult
end
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } },
colour = G.C.mult,
consumeable = card,
mult_mod = card.ability.extra.mult
}
end
end
}
----------------------------------------------
------------MOD CODE END----------------------
ah, it seems like you need to replace else if with elseif
Well I guess no reason in specific, just that the first stage is Rare so it would be ideal if the others were too. I've got something set up where a joker can turn into another one at the end of a boss blind to sort of "level up" and I want only the first stage to be available to buy
yup for some reason that worked
Weird Lua syntax
lua thinks that else if means
if a then
...
else
if b then
...
``` i.e. the things inside `else if` are inside two nested blocks, which means that you need 2 `end`s to close both nested `if` statements
on the other hand, when you use `elseif`, it's interpreted as
if a then
...
elseif b then
...
``` in which case you only need 1 end to close the block
when you used else if, there weren't enough ends to close all the nested blocks including the function, causing a bunch of errors
i love lua but it's really really weird syntactically imo
and now i get this just why
for that one i think you need to replace random_chance inside calculate w/ self.ability.extra.random_chance
^^
i'd also replace the code before if context.joker_main with this:
if context.using_consumeable then
if pseudorandom('dyonisus') < G.GAME.probabilities.normal / random_chance and not context.repetition and context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * self.ability.extra.random_mult
else
card.ability.extra.mult = card.ability.extra.mult + self.ability.extra.consumeable_mult
end
end
the current code does the following every time something happens in-game:
- if the 1 in 5 roll succeeds, multiply this joker's +mult by 2
- otherwise, if we're using a consumeable, add 7 to this joker's +mult
which means the 1 in 5 roll is going to trigger like 70 times every round... i think
yeah thats prob the reason the game crashed lmao
also, i'm not quite clear on how context.repetition and context.repetition_only work but i think you'd want to replace not context.repetition and context.repetition_only w/ not context.repetition and not context.repetition_only
does in_pool work for jokers? cause if so that would probably be the easiest way
Yes.
i've never heard of that! if that's in the api then that's definitely the way to go
true allows it to naturally appear. false does not.
in_pool = function()
return #SMODS.find_card('j_joker', true) > 0
end
welp ``` --- STEAMODDED HEADER
--- MOD_NAME: Mythos
--- MOD_ID: Mythos
--- MOD_AUTHOR: Salems_Bane
--- MOD_DESCRIPTION: An example mod on how to create Jokers.
--- PREFIX: xmpl
------------MOD CODE -------------------------
SMODS.Atlas{
key = 'Mythos',
path = 'dyonisus.png',
px = 71,
py = 95
}
SMODS.Joker{
key = 'Mythos',
loc_txt = {
name = 'Dyonisus',
text = {
"{C:mult}+#1#{} mult",
}
},
rarity = 1,
atlas = 'Mythos',
pos = { x = 0, y = 0 },
config = {
extra = {
mult = 0,
consumeable_mult = 7,
random_mult = 2,
random_chance = 5
}
},
cost = 4,
eternal_compat = true,
blueprint_compat = true,
brainstorm_compat = true,
calculate = function(self, card, context)
if context.using_consumeable then
if pseudorandom('dyonisus') < G.GAME.probabilities.normal / self.ability.extra.random_chance not context.repetition and not context.repetition_only then
card.ability.extra.mult = card.ability.extra.mult * self.ability.extra.random_mult
else
card.ability.extra.mult = card.ability.extra.mult + self.ability.extra.consumeable_mult
end
end
if context.joker_main then
return {
message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } },
colour = G.C.mult,
consumeable = card,
mult_mod = card.ability.extra.mult
}
end
end
}
------------MOD CODE END----------------------
honestly idk anymore it keeps on breaking every time and im screaming internally so much rn holy shit
Missing and after if pseudorandom('dyonisus') < G.GAME.probabilities.normal / self.ability.extra.random_chance.
also will this work how i expect or no:
joker is locked, if the joker is locked then voucher appears in shop as a generic voucher with a generic description, when the afterlife effect from the voucher is used, it unlocks and discovers the joker since it adds it in the new run, and the voucher will have the proper name, description, and sprite the next time it shows up?
like if i have a check for the joker being unlocked setting it to the proper description and name
small question why is it SMODS.find_card? i'm like just getting started w/ steamodded
im gonna cry like my code doesnt work and after this i gotta figure out the text on the card like why is this so difficult
it says that the error occurred on line 45 of Mythos.lua (line 2 of error message [SMODS Mythos "Mythos.lua"]:45). does your text editor/ide/whatever show line numbers?
if so, what's the text of line 45?
if not, line numbers can be really useful for debugging since error messages will usually tell you roughly where the error is
oh ... maybe replace self.ability..... with card.ability....? looks like that's what the example jokers do
my bad
welp
then thats the issue again
honestly imma just sleep
its almost 6:30 in the morning
sounds reasonable
how complicated would it be to make a kind of "aura" visual effect for cards that can show no matter if the card is face up or face down?
Ad idea I'd like to offer, and something that can be implemented in the external loader; instead of storing mod files, there could optionally be a list file of GitHub URL's. That way, the loader fetches the repo files and have them stored in memory before the game fully loads. The file loading is still there in case of user-made mods or tweaked mods.
no, it's best to have the files locally
cause what if no internet?
then you can't load mods that aren't stored locally
The larger problem is that lovely will not work if the mods don't exist until after the game is launched.
Right now, I find the concept of manually updating mods to be a royal pain, especially when a given download has breaking changes
How would I make cards flip like tarots make cards flip when used?
when i use my consumable on it
"Oh, a mod is out of date"
Uh... which one?
Also, having the mods start on RAM instead of disk has the potential of reducing the start-up delay a good bit
okay, well yeah have a list of github repos but, instead download the files proper and it can detect changes to the repo
Actually this whole idea might just fail because lovely wouldn't work with mods in memory instead of disk.
But I don't think this has been tested (or maybe just basic computer illiteracy from me).
Ehh if it's a problem and this is a good solution I'd imagine that Lovely can just change to work with this
xdd
well, at least if thats a possible option, then at least save the files locally too as a backup incase of not having internet
With this idea, offline should not be affected
This is not about replacing what worked
Rather, it is about adding another option for a wider use case
okay but, should people decide to use that, save the files locally as a backup option
because otherwise yes, it will affect offline play, if the files arent saved locally it won't be able to load mods from a github repo if it cant access the github repo
Well, in that case, have the download on to storage be done in the background as the game is running.
SMODS.Sound({
vol = 0.6,
pitch = 1,
key = "tangle",
path = "tangle.ogg",
})
...
SMODS.Enhancement {
key = "tangle",
loc_txt = {
name = "Tangle",
text = {
"When scored with adjacent cards,",
"adds chips equal to the sum of",
"their highest ranks"
}
},
atlas = 'Enhancements',
sound = 'tangle',
config = {
chips = 0
},
pos = {x=0, y=0},
calculate = function(self, card, context, effect)
if context.cardarea == G.play and not context.repetition then
local left_card, right_card
for i, playedCard in ipairs(context.scoring_hand) do
if playedCard == card then
if i > 1 and context.scoring_hand[i-1] then
left_card = context.scoring_hand[i-1]
end
if i < #context.scoring_hand and context.scoring_hand[i+1] then
right_card = context.scoring_hand[i+1]
end
break
end
end
local card_count = 1
local highest_rank = card:get_id()
if left_card then
card_count = card_count + 1
highest_rank = math.max(highest_rank, left_card:get_id())
end
if right_card then
card_count = card_count + 1
highest_rank = math.max(highest_rank, right_card:get_id())
end
effect.chips = highest_rank * card_count
end
end
}
I want to add a custom sound to play when this custom Enhancement card is scored, but I'm not sure where to put the audio cue
It needs to be handled git-style, as otherwise the drive will be hit by excessive write cycles
Are there any mods that modify already existing jokers? I'm doing a patch mod for the game and would like to see one of those mods so I can learn how to code joker rebalancing
I need some help here
Stack Traceback
===============
(1) Lua local 'handler' at file 'main.lua:612'
Local variables:
msg = string: "card.lua:4971: attempt to index local 'obj' (a nil value)"
Got this error after trying to add a sound file to play.
SMODS.Sound({
vol = 0.6,
pitch = 1,
key = "tangle",
path = "tangle.ogg",
})
....
-- Continued at the end of the right_card if case
if card_count > 1 then
play_sound('bfm_tangle')
end
effect.chips = highest_rank * card_count
...
Not sure where the error is pointing to at all, I need some insights here. My prefix is bfm
card.lua in the source code doesn't even go to 4971
And without the sound, it works just fine?
card.lua in the source code doesn't even go to 4971
It does if you check the dump file card.lua in your lovely folder in Mods/lovely/dump/card.lua, which is the state that file is in after Steamodded gets patched to it
oh i didnt know that existed, good to know for the future
for my mod having a way of cards carrying over to the next run, is replacing cards directly in G.playing_cards with randomly selected cards from the previous run's G.playing_cards safe to do?
or could that potentially cause issues somewhere?
steamodded 0.9.7 😭
{T:v_overstock} in your deck description text
id recommend grabbing the latest steamodded by downloading the source for the github repo
I did, I just forgot to put it in lol
Yeah, after I removed the SMODS.Sound function, the sound = 'tangle' line, and the entire if case with the play_sound, it works fine
I initially assumed that if I remove the sound = 'tangle' line (which I thought worked like the atlas) it would fix the problem, but nope, I would need to remove any and all implementation of a custom sound for it to work again
something's wrong
Did you update your steamodded
I did I did
all my other mods work so its something with the json file
something is VERY wrong with my mod
clearly I didnt set it up correctly
change the dep to Steamodded (>=1.*~)
the mod file only has an atlas and two jokers, how bad can this be
show json file and file structure
thank you
oh wait, I see a lil problem rq
nvm
😭
the failed to collect hits me again
SMODS.Atlas {key = 'collab_WF_1', path = "textures/collabs/collab_WF_1.png",atlas_table = 'ASSET_ATLAS',prefix_config = { key = false },px=71,py=95}
so same my friend
no yeah same
your path shouldn't have the outer textures folder
and the path (in code) should just be collab_WF_1.png
idk what im doing wrong either
er. collabs/file.png in this case
your file path here is jokers/ludusjokers.png
oooh
ok that worked wow thanks
hatsune miku...........
true....
yeah, don't I need both?
aye there we go
also just wondering how do 2x textures help with pixel smoothing
is it purely because bigger image scales up smoother
Jimbo's Pack's joker copy abilities when they see LobotomyCorp jokers
show....
as in, i suspect it's gonna crash a lot
i wanna try out the lobotomycorp mod
but i also dont wanna spoil myself 😭
i have lobotomycorp and i never play it but i wanna finish it one day
but the lobotomycorp mod just seems too good
almost working
the second guy's texture isnt working for some reason
it should, but its not
nice value proposition
I said ALMOST
anyway, any reasons why this guy isn't appearing properly
actually hold up i got an idea just from that
is that copper shortsword
x = 1, y = 1 should be the second one of the second column right
idk why it no worky
yeah
also i think in lua index starts at 1
for atlas positions, it starts at 0
ah
I have zero clue what the problem is
its not even pulling from the atlas, it's using a default image
can I see the full joker def?
yeah there's another layer of brackets there
did you accidentally put it in the text thing?
config isn't closed
ah
yeah that's in your config
ere we go
yeah theres a closed bracket at the bottom where it should be after config
new problem
seems like it has lost waaay more than 3
its also not giving the payout
context.end_of_round ahh jank
see how golden joker does it
Also probably self-destruct the joker when it goes below zero
tbh it would be really funny if you forgot to sell it and it took money from you
but that clearly isnt working so
dont use context.end_of_round for money stuff
use calc_dollar_bonus function
you could just
remove the money in the calc dollar bonus
good point
just remove the calculate and reduce the value in calc dollar bonus
end_of_round with no additional checks happens a bunch of times
e.g. for each card in hand
Also you're explicitly only returning the bonus if it's positive, no wonder it's not working when it's negative
yeah I noticed that part
eternal sticker ooo
aye, its workin now
I wonder how the second one would work with bunco's hindered sticker
does it also delay the triggers for selling cards
or is it just delaying the destruction