#💻・modding-dev

1 messages · Page 108 of 1

merry raven
#

Man I'm not experienced enough to tap into patches yet 💀

wicked leaf
#

its one file, cant be that bad

teal estuary
#

i jsut delete the existing lovely and steammodded files, and then redownload the new versions?

shell tangle
#

Yeah.

wicked leaf
#

basically

teal estuary
#

cool

#

ty

merry raven
#

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

teal estuary
#

isnt cryptid heavily dependent on talisman/lovely? thats what i've heard, but i've never chanced myself to look at its code

merry raven
#

No idea

wicked leaf
teal estuary
#

true, true

shell tangle
#

Yeah.

teal estuary
#

hrm

shell tangle
#

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.

teal estuary
#

OOOH

#

that helps a lot

#

-# wonder why its still erroring though...

shell tangle
#

Two things, are you testing on a new run, and is it still the same issue with something about seal and nil?

teal estuary
#

one moment

#

let me defintely not start testing on a new save
-# but yes, same error

#

new save, same error

wintry solar
#

well what's at that line in state_events

teal estuary
#

lemme

#

-# wait where is state_events

wintry solar
#

Mods/lovely/dumps/functions

teal estuary
#

ah, ty

#

im going to presume its related to the fact im using repetition_only? since IIRC that context is related to red seals?

merry raven
#

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
teal estuary
#

i like the latter idea more, but both are super cool

wintry solar
#

do effect.seals.repetitions = card.ability.extra.repetitions

teal estuary
#

testing it

#

(just to be sure, here)

wintry solar
#

uhhh, put a ```lua
else
effect.seals = {}
end

#

enhancement calculation is a little scuffed

teal estuary
#

makes sense 😭

#

just to be sure, like this?

wintry solar
#

can you show the whole block

teal estuary
#

oh sure, mb

wintry solar
#

move it above the end above it

teal estuary
#

thought so, sure

wintry solar
#

need to change the effect.repetitions line again too

teal estuary
#

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 😭

wintry solar
#

uhhh actually this isn't a good way of doing this

#

hold on lemme have a think

teal estuary
#

sure, take your time mwah~1
i do want to thank you for helping me with this

wintry solar
#

let me write you a quick lovely patch

merry raven
#

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

teal estuary
#

wooo, my first lovely patch!

merry raven
#

niiiiiiiice

teal estuary
#

obviously you can replace the x and Hearts with whatever you need

merry raven
#

Is there a way to make it more modular

teal estuary
#

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

merry raven
#

Let's see it

teal estuary
#
      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
wintry solar
#

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

teal estuary
#

sure

merry raven
teal estuary
#

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

wicked leaf
merry raven
#

Tangle cards are Enhancements so they don't have rarities
Do they?

wicked leaf
#

So a tarot card equivalent

wintry solar
#

enhancments never get other_card in contexts

wicked leaf
#

Would work well I think

wintry solar
#

you'll have to manually look at context.scoring_hand

merry raven
#

Guh

teal estuary
#

im still curious about how it worked fine for you, but my bucket of bolts and botches went "nuh, no work"

merry raven
#
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

teal estuary
#

-# im gonna be banging my head agaisnt this for a while

teal estuary
merry raven
#

Highest card thing

#

"When played between two cards, all three cards will be scored as the highest level and its suit."

teal estuary
#

hrm

wintry solar
#

@teal estuary I think I'm actually just going to unscuff enhancement calc if you don't mind waiting till later

teal estuary
#

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

merry raven
#
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

teal estuary
#

it looks right, no idea if it should work though 😭

merry raven
#

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

teal estuary
#

yeah itrs essenitally just free cryptid/DNA 😭

merry raven
#

💀

wicked leaf
#

brainstorming

#

(copper shortsword)

merry raven
# teal estuary 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?

teal estuary
#

that sounds good, yeah

merry raven
#

Which contexts or variables do I use for granting chips again

teal estuary
#

for enhancements? im not sure, theres chip_bonus and bonus that are natively supported

merry raven
#

Natively supported?

teal estuary
merry raven
#

Oh that

teal estuary
wooden nexus
nocturne garnet
teal estuary
#

i realise that now

#

never knew it did it

nocturne garnet
wooden nexus
#

Antimatter doesn't include the negative effects

#

mine does

nocturne garnet
#

so basically

wooden nexus
#

Every effect at once

nocturne garnet
#

antimatter deck without cryptid with the bad stuff

wooden nexus
#

i guess?

#

It's just every balatro deck at once

merry raven
# merry raven A less OP way of approaching this is to check if left and right cards exist, che...
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

storm oar
#

does the key for something need to have a prefix to prevent conflicts between mods or does steamodded automatically handle stuff like that?

wooden nexus
#

I still have to get Anaglyphic and plasma deck working

frosty dock
#

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

wooden nexus
#

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

nocturne garnet
wooden nexus
#

Then I merged them all together and put it back up to 100%

#

essentially, the average of each pixel in the decks

tidal ice
nocturne garnet
wooden nexus
#

I think it's correct for the pixelation stuff

merry raven
wooden nexus
rough furnace
#

For the file picjer

brisk quartz
wooden nexus
#

I'll still use the old one (the right one)

primal robin
#

But this also can be useful, thanks

zenith plover
#

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

rough furnace
#

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

zenith plover
primal robin
#

Now I understand why love.filesystem is bad JangSchna

teal estuary
#

are retriggers just borked somehow on enhancements? i tried to just make a “this enhancement retriggers this card once”, and it just >:(

#

doesnt wanna

zenith plover
#

I hate enhancements so much lol

teal estuary
#

they do seem a little iffy

#

-# and i need to add 93 of them

zenith plover
#

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

zenith plover
teal estuary
#

every metallic element as an enhancement

#

-# maybe some as editions

zenith plover
#

I have to admit that is really cool

teal estuary
#

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)

zenith plover
#

Maybe instead of destroy you can make it decay, like it usually would

teal estuary
#

oh this is for things like lithium, francium, caesium, etc - for decaying elements it'll be different

zenith plover
#

Ah

teal estuary
#

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

zenith plover
#

Cool

teal estuary
#

(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)

zenith plover
#

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)

teal estuary
#

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

zenith plover
#

im looking at the source code for red seal and repetitions joker

#

im pretty sure that its possible

teal estuary
storm oar
#

is there a way to force a specific voucher so i can test things?

zenith plover
proper relic
teal estuary
#

hrm, ty

zenith plover
zenith plover
#

that doesnt work

teal estuary
#

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

zenith plover
#

probs doesn'tpass repition to enhancements

#

patch it into lovely

teal estuary
zenith plover
#

create a file: enhancements.toml

teal estuary
zenith plover
#

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})

wintry solar
#

I’m in the process of unscuffing enhancement calcs

zenith plover
#

yay

wintry solar
#

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

zenith plover
teal estuary
#

oh, cool
-# i wasnt sure if it'd effect me with anything else i wanted to do, sorry if i seemed impatient mwah~1

zenith plover
wintry solar
#

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

wintry solar
teal estuary
#

meh, practice on lovely patches is practice with lovely patches

zenith plover
#

i had a stroke trying to read that

teal estuary
#

-# how did i spell it wrong the same way, twice

primal robin
#

Did anyone work with Balatro music? I'm trying to stop and reload sound file but without success. How to do it properly?

zenith plover
teal estuary
#

i did

zenith plover
#

i would just look in source code and try shit for the payload man

#

idk

teal estuary
#

fair enough tbh 😭

zenith plover
#

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
'''
teal estuary
#

ty ty

zenith plover
# teal estuary 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
nocturne garnet
zenith plover
teal estuary
#

actually, wait, wanna check, does this look good to you?

zenith plover
#

🤦‍♂️ forgot then after if scoring hand[i] thing

#

my b

teal estuary
#

all good :]

zenith plover
#

indent look quite cursed but don't think that'll change anything

#

rest looks good

zenith plover
# teal estuary 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

teal estuary
#

oh yeah makes sense, im used to factorio modding which is like an entirely different language compared to this 😭

zenith plover
#

yeah my python experience doesnt help very much either

zenith plover
#

Now i'm invested

teal estuary
#

whoops, on moment

#

it did not, but i am fully expecting it to be my own error

zenith plover
#

i think i made a mistake

teal estuary
wooden nexus
#

it looks like one

teal estuary
#

it does, thats why i added the 999. and 100g markings 😭

wooden nexus
#

Then what is it?

teal estuary
#

silver card

wooden nexus
#

oh

teal estuary
#

i wasnt sure what to do with silver apart from "hehehe shiny", and somehow shiny translated into a retrigger

fallen tendon
#

does this look good?

teal estuary
#

does look pretty good, i like it

fallen tendon
#

this is how it looks ingame

wintry solar
#

I think the label looks a bit off

fallen tendon
#

what could make it better?

wintry solar
#

Might work better as a floating sprite

fallen tendon
#

oooooo

wintry solar
#

Or at least the bottom outlines too

fallen tendon
#

and for some reason it got thanos snapped off of the smods docs?

zenith plover
zealous glen
fallen tendon
#

oh its just soul_pos

zealous glen
#

yes

fallen tendon
#

i think they accidentally deleted it from the docs

fallen tendon
#

how does this look?

#

now it looks more like a label

zenith plover
#

Sick

#

I didnt even know soul was different

teal estuary
rough furnace
wintry solar
zenith plover
cinder elk
fallen tendon
#

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

zealous glen
#

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

fallen tendon
#

i'm trying to use the cryptid method of supporting stickers on playing cards and i dont know what im doing wrong

#

help please?

wintry solar
zealous glen
#

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

zealous glen
wintry solar
#

That’s exactly what it does

wooden nexus
nocturne garnet
wooden nexus
#

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

rough furnace
#

Sorry wrong thing copied edited

wooden nexus
teal estuary
#

ooooh, pretty

#

kinda look like ripoff spectrals

wooden nexus
#

Well this was during demo era

cosmic notch
#

Stars and moons?

wooden nexus
#

Yeah, made them as a 6-suited concept

#

which became the sixsuit mod w/ Aure

teal estuary
#

i love the jimbo with 5.. thingies

#

all the art is nom though

#

what is the top left one meant to be though?

zenith plover
wooden nexus
teal estuary
#

ooooooh

#

makes sense

wooden nexus
#

It's supposed to look like cards being fanned out like the printed gaff cards

wooden nexus
#

bean

rough furnace
wooden nexus
#

Has anyone done stuff with permanent effects on cards?

rough furnace
#

That shouldn't be possible

#

On 1.0.0

wooden nexus
#

Stuff like hiker?

#

how it gives a permanent +chips?

teal estuary
#

i made a mult

#

version

wooden nexus
#

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

wooden nexus
teal estuary
#

uhhhhh, shouldnt do?

#

-# what would it break

wooden nexus
#

idk

teal estuary
#

but yeah, you can essenitally give them anything

#

never tried retriggers, that might not work

wooden nexus
#

I don't plan to do retriggers

teal estuary
#

fair enough

#

but yeah, + and xmult, money

#

anything that enhancements can give cards, is something a joker can give

zenith plover
#

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!"

wintry solar
#

assert(SMODS.load_file('path')())

zenith plover
#

and that just does it?

wintry solar
#

yeah

#

the () might need to be at the end instead, I don't remember

zenith plover
#

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

wintry solar
#

yes

zenith plover
#

yup

frosty dock
zealous glen
wintry solar
#

check debug plus wiki

wicked leaf
#

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

zealous glen
#

It's easier to convert a spritesheet to 2x

#

Because you just need to upscale one file

wicked leaf
#

I guess

#

I'm just scared of jokers getting misaligned in the spritesheet if I make the spritesheet bigger

teal estuary
#

just make sure its always a multiple of 71 and 95 respectively

wicked leaf
#

aight then

analog cypress
#

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
wintry solar
#

do local usedspectral = G.GAME.consumeable_usage_total and G.GAME.consumeable_usage_total.spectral or 0

#

that should fix the problem

faint yacht
#

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
analog cypress
#

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

faint yacht
#

Still wish we could pass custom sounds through to card_eval_status_text via the effects table.

wintry solar
#

making sure usedspectral is a number will mean specbonus will always be a number though

bold osprey
wintry solar
#

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
faint yacht
#

That assumes the default base value is to be given still even if no spectral cards were used.

wintry solar
#

it won't get in the block if no spectral cards are used

#

if 0 then doesn't pass

faint yacht
#

Right.

faint yacht
wintry solar
#

yeah it would

#

just needs a extra.sound or ... at the start

faint yacht
#

Just being cautious with such things... first it's my overwrite of the SMODS.eval_this function, now this...

proper relic
#

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?

frosty dock
#

context.card.ability.set == 'Joker'

proper relic
#

Thank you!

wicked leaf
#

alright, time to get started

weak depot
#

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

teal estuary
#

we should be getting a rewrite on enhancement calcs, to make retriggers work 😭

weak depot
#

do retriggers not work on enhancements???

#

wowie

#

how would you do it normally?

teal estuary
weak depot
#

like in a deck or joker

teal estuary
#

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

autumn coral
#

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 😅

elder vapor
#

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

autumn coral
#

i was trying context.game_over and context.before

#

that one made sense to me

#

oh yk what?

#

i just thought about something

proper relic
#

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.

autumn coral
#

loc_vars

proper relic
#

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

echo summit
#

Has anyone made a 52 Pickup Joker before? I had an idea for one but it's a little fuzzy in my brain.

wicked leaf
#

right now

#

how do I add a SINGLE joker

#

I'm seeing a lotta modders make a separate Jokers folder

crisp elbow
#

that isn't needed for one joker

#

or technically at all

wicked leaf
crisp elbow
#

honestly it's just half the time for organization purposes

teal estuary
#

yeah, all my code is in one file

wicked leaf
#

I see

wintry solar
teal estuary
#

i might split it up at some point, but its fine

wicked leaf
#

My mod's name is Ludus, my file should be Ludus.lua right

teal estuary
#

it can be whatever you want IIRC, i did name mine after my mod though

nocturne garnet
wicked leaf
teal estuary
#

-# there are example jokers in the example mod file, but uhhh

wicked leaf
#

oh okay

wintry solar
#

its in SMODS.Center

teal estuary
#
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
cinder elk
teal estuary
#

oh hey, sticker star

cinder elk
#

i had the idea to put all the stickers from that game and turn them into jokers

wicked leaf
#

why not consumables

cinder elk
#

that is fair.

#

i do wanna make a mod i just have. so many ideas.

#

and i dont know how to code in lua.-

wicked leaf
#

me neither! so im getting started like right now

cinder elk
#

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.

faint yacht
#

Steamodded itself brings example mods to peek at.

cinder elk
#

oh

#

oh it does

analog cypress
#

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
}
autumn coral
#

siiiigh this is gonna suck ass

gaunt thistle
#

the most fun projects always do

autumn coral
#

this is not fun

faint yacht
autumn coral
#

this thing i'm doing is so easy

gaunt thistle
#

nevermind

autumn coral
#

i'm so sad rn

gaunt thistle
#

:-(

#

you got this

#

just keep trying

autumn coral
#

iunno if i do man, holy mantle sounded a LOT easier in my head

#

lmfao

analog cypress
#

Success! It still doesn't do the upgrade text like what I wanted but it's working and with no crashes!

teal estuary
#

-# the art looks pwetty

analog cypress
#

Thanks, I drew it myself. Balatro's art style's easy to replicate

teal estuary
proper relic
# wintry solar you need 2 entires in the localisation tables, and then you can switch between t...

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
}```
analog cypress
#

The one time you get rewarded for using Sixth Sense + DNA with my joker

faint yacht
#

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..?

analog cypress
#

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

faint yacht
#

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.

obsidian fjord
#

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.

autumn coral
#

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

wicked leaf
#

trying to make it so at the end of the round one of the numbers on the card goes down by 1

autumn coral
#

oh my god i'm so stupuid

cinder elk
#

ooh, okay

#

we're getting somewhere

#

now why does it say "nil"

#

hmmm

teal estuary
cinder elk
#

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...

elder vapor
#

yes

#

name sure to close the loc_vars function

cinder elk
#

loc_vars = function(self, info_queue, card)
return { vars = { card.ability.extra.chips } }
end,

teal estuary
#

looks good

elder vapor
#

yeah looks good

cinder elk
#

still says nil

#

hmm

obsidian fjord
#

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.

cinder elk
#

basically what i did was alter the example joker

obsidian fjord
#

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?

elder vapor
#

what does your code look like

faint yacht
cinder elk
#

is

#

is that the issue

faint yacht
#

Yeah.

obsidian fjord
#

Ohh I didn't see that, yeah the number between the # references the variable in loc_vars

faint yacht
#

#X# is the number entry for the returned value from loc_vars.

cinder elk
#

HOT DAMN

faint yacht
#

So if you return 5 values from that function, you can go up to #5#.

cinder elk
#

now with debugplus

#

how do i spawn one in my run

teal estuary
#

3

#

hover over it in collection

#

and press 3

faint yacht
#

May need to hold CTRL as well in the recent updates.

obsidian fjord
#

Nah I installed it a few days ago, you just gotta hit 3 while hovering it

cinder elk
#

hm

faint yacht
#

You're not return-ing the right stuff.

cinder elk
#

you seem important.

#

let me change it to chips

faint yacht
#

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.

cinder elk
teal estuary
#

mult_mod for mult, and Xmult_mod for xmult

cinder elk
teal estuary
#

and repetitions for.. repe

#

show your entire return table

faint yacht
#

Message may not be set up right.

teal estuary
#

might be

faint yacht
#
return {
  message = localize({ type = "variable", key = "a_chips", vars = { card.ability.extra.chips } })
  chip_mod = card.ability.extra.chips,
  colour = G.C.CHIPS
}
teal estuary
#

y'never know

cinder elk
#

oh i just noticed this

#

message = localize { type = 'variable', key = 'a_mult', vars = { card.ability.extra.mult } }

teal estuary
#

😭

cinder elk
#

listen

#

listen .

#

i might be stupid.

teal estuary
#

we all are

cinder elk
#

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

teal estuary
#

i dont know everything but i can help

cinder elk
#

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

teal estuary
#

jokers.

cinder elk
#

noted

#

i'll start with that

wicked leaf
# wicked leaf that should prolly do it

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)

sleek badge
#

I wish to try it once a release is made

cinder elk
sleek badge
#

Thank you

cinder elk
#

adds the entire pvz1 almanac roster as cards

sleek badge
#

Ooh

#

Yea don’t do pvz2

cinder elk
#

oh no yeah.

#

im not stupid.

#

not

#

entirely.

#

i wouldnt mind seeing people make expansion packs though 👀

sleek badge
#

lol i would if i could mod

#

or code

obsidian fjord
#

This shader mess is making me question whether I can code

cinder elk
fading fox
#

Shaders are evil wizard shit no matter the language used

obsidian fjord
#

Oh I know but normally I can read something and get a general sense of what's going on, nope not with this nightmare

scenic sphinx
#

okay so question yall
i want to make my joker 2 effects

  1. get +7 mult whenever you use a consumable
  2. have a 1/10 to double his mult instead how would i do that
cinder elk
#

im surprised no-one's made a mod that adds jokers based on boss blinds

scenic sphinx
#

reduces hands to 1 gives +200 chips

cinder elk
#

FUCK I THOUGHT I WAS BEING CLEVER

scenic sphinx
#

its something with 1 hand

teal estuary
scenic sphinx
teal estuary
#

i know its very abstracted, but you get the point

scenic sphinx
#

yeah

teal estuary
#

im glad to help :]

scenic sphinx
#

its like my first joker so thanks for the help

teal estuary
#

i can give you an example of card_eval_status_messages if you'd like

scenic sphinx
#

i have that i think

teal estuary
#

-# you also be better to put them inside each if statement, not as their own thing

teal estuary
scenic sphinx
#

yeah anyways time to read the steamodded wiki to find the consumable thingy

teal estuary
#

good luck

scenic sphinx
#

ill need it lol

scenic sphinx
teal estuary
#

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?)

scenic sphinx
#

wait nvm thats when a consumable removes a card

scenic sphinx
frosty dock
teal estuary
#

-# the [] are just meant to be a [insert thing here], do take the [] out :]

obsidian fjord
#

Is there a way to remove the shader from a sticker?

zealous glen
#

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.

frosty dock
teal estuary
#

-# 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"

zealous glen
#

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

teal estuary
#

☹️

scenic sphinx
#

i think this is what i need for the first part

placid frigate
faint yacht
#

...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
frosty dock
faint yacht
#

Outside, actually.

scenic sphinx
obsidian fjord
#

How does info_queue work? I'm trying to add a tooltip for a custom sticker and I can't seem to get it.

zealous glen
wooden nexus
zealous glen
#

I used the fluoride(?) shader from Steamodded as a reference, with some functions taken from vanilla

wooden nexus
#

i see

zealous glen
#

and the specific calculation is one used by Bunco, just rewritten in the shader language

scenic sphinx
#

im so confused rn

teal estuary
scenic sphinx
#

omfg im dumb

shy gorge
#

is this the channel where i can get help with mods 😭

autumn coral
#

No

#

Well making them

#

Yes

#

Mods in general? No

shy gorge
#

just like installing

#

ok thank you

autumn coral
#

Yeah modding chat

#

Np!

scenic sphinx
faint yacht
#

Why are you using self.using_consumable? Do you have a config part in your joker with { extra = { mult = 1 } }?

scenic sphinx
#

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

faint yacht
storm oar
obsidian fjord
#

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

scenic sphinx
cold peak
scenic sphinx
#

nvm didnt need it i think

obsidian fjord
#

Oh nevermind I can just take_ownership and make calculate an empty function

zealous glen
#

What's the difference between tex and uv?

violet void
faint yacht
#

Uncommon, maybe.

merry raven
#
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?
violet void
scenic sphinx
#
  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

zenith plover
proper relic
#

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 }))
faint yacht
#

create_card('Joker', G.jokers, nil, nil, nil, nil, 'insertkeyofjokerhere', 'rngseed')

merry raven
#

Which lua file in Balatro's source code can I find the list of all contexts?

storm oar
#

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

scenic sphinx
#

edens blessing?

storm oar
#

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?

carmine burrow
#

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"?)

faint yacht
#

Some things will require Lovely patching, truly.

carmine burrow
faint yacht
#

Definitely grabber-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.

carmine burrow
faint yacht
carmine burrow
#

probably

carmine burrow
#

it's really easy to accidentally get like 20,000 points in ante 3 and reset it

zealous glen
#

@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.

wintry solar
#

🤷‍♂️

zealous glen
#

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

zealous glen
#

I thought I could use the screen coordinates modulo the image size to choose the part of the atlas I want to draw

wintry solar
#

I don’t remember, I haven’t touched shaders for months

zealous glen
#

v_v

carmine burrow
wintry solar
#

^ this sounds correct

zealous glen
#

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

scenic sphinx
#

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

teal estuary
scenic sphinx
teal estuary
#

...wheres your config

scenic sphinx
#

config?
the test joker i made a bit ago didnt need one?

carmine burrow
#

what's using_consumable

zealous glen
#

Your Joker wants to remember a changing value so it needs to store that somewhere

teal estuary
#

yeah

#

you need to define a config for.. any of that

zealous glen
#

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

carmine burrow
scenic sphinx
zealous glen
#

Well, only if you actually have something to put into it

carmine burrow
zealous glen
#

If the logic is elsewhere then it doesn't need a config

carmine burrow
teal estuary
#

config = {extra = {mult = 0 },

#

-# you'll also need to replace any card.ability.mult with card.ability.extra.mult

scenic sphinx
scenic sphinx
teal estuary
#

put it anywhere next to your rarity or cost

#

heres an example, you also need loc_vars for the description

carmine burrow
#

is putting everything in extra incl. +mult generally considered good practice for modding? seems like that isn't done in the base game

teal estuary
#

i'd say so, yeah

#

base game does it differently, so

carmine burrow
#

maybe i misread the code..

scenic sphinx
teal estuary
#

looks good, but make sure your config contains the same thing as your .extra.x

scenic sphinx
#

wdym?

carmine burrow
#

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?

scenic sphinx
#

like 1/5

#

wait this i got

#

like this?

carmine burrow
#

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?

scenic sphinx
#

instead of the +7

carmine burrow
#

i.e. when using a consumable?

#

maybe move the if pseudorandom(...) inside if using_consumeable in that case

scenic sphinx
#

yes

#

like this or am i stupid

#

wait bc there is if is there also an else?

carmine burrow
# scenic sphinx like this or am i stupid

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
scenic sphinx
#

yeah imma do it in the second way

#

makes my brain remember easier bc c#

storm oar
#

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?

carmine burrow
#

afterlife ?

storm oar
#

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

carmine burrow
#

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)

storm oar
#

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

scenic sphinx
storm oar
#

the newline is breaking it i think

#

or, maybe some weird stuff with the conditions needing parentheses or something

gilded narwhal
#

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?

scenic sphinx
storm oar
#

what's the code look like currently?

scenic sphinx
storm oar
# scenic sphinx

instead of sending screenshots, should send it as code blocks, it'll help.

just use
```lua
(code here)

hardy viper
scenic sphinx
# storm oar instead of sending screenshots, should send it as code blocks, it'll help. just...
    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

hardy viper
#

yea we don't have this unfortunately

storm oar
#

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

sturdy compass
#

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?

scenic sphinx
#
    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

}```
storm oar
scenic sphinx
#

now thats the issue again

storm oar
#

which line is line 48

scenic sphinx
#

if using consumable

storm oar
faint yacht
#

if context.using_consumeable

storm oar
#

ah that i didnt know

hardy viper
#

well yeah

#

of course

edgy reef
#

...Is there not a way to declare Steamodded a source or library in VSCode or something?

scenic sphinx
storm oar
# scenic sphinx 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
scenic sphinx
#

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

faint yacht
#

...are you defining using_consumeable = true, as part of Joker?

scenic sphinx
#

i think so i have no idea what im doing

carmine burrow
proper relic
#

Is there a way to make a joker that doesn't randomly show up in shops? I wanna have it obtainable through other means.

carmine burrow
scenic sphinx
proper relic
placid frigate
proper relic
#

Especially if I just make it visually the same as Rare

carmine burrow
carmine burrow
scenic sphinx
# carmine burrow the error message looks like a syntax error but it's hard to tell where exactly ...
--- 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----------------------


carmine burrow
proper relic
scenic sphinx
merry raven
#

Weird Lua syntax

carmine burrow
# scenic sphinx yup for some reason that worked

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

scenic sphinx
carmine burrow
#

for that one i think you need to replace random_chance inside calculate w/ self.ability.extra.random_chance

elder vapor
#

^^

carmine burrow
#

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

scenic sphinx
#

yeah thats prob the reason the game crashed lmao

carmine burrow
#

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

storm oar
faint yacht
#

Yes.

carmine burrow
scenic sphinx
#

alr let see if it works

#

attempt like 35

faint yacht
#

true allows it to naturally appear. false does not.

in_pool = function()
  return #SMODS.find_card('j_joker', true) > 0
end
scenic sphinx
# carmine burrow also, i'm not quite clear on how `context.repetition` and `context.repetition_on...

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
faint yacht
#

Missing and after if pseudorandom('dyonisus') < G.GAME.probabilities.normal / self.ability.extra.random_chance.

storm oar
#

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

carmine burrow
scenic sphinx
#

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

carmine burrow
#

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

scenic sphinx
#

its like this part

#

easiest way to show it with the numbers

carmine burrow
#

oh ... maybe replace self.ability..... with card.ability....? looks like that's what the example jokers do

#

my bad

scenic sphinx
#

then thats the issue again

#

honestly imma just sleep

#

its almost 6:30 in the morning

carmine burrow
#

sounds reasonable

storm oar
#

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?

runic sinew
#

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.

storm oar
#

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

edgy reef
#

The larger problem is that lovely will not work if the mods don't exist until after the game is launched.

runic sinew
#

Right now, I find the concept of manually updating mods to be a royal pain, especially when a given download has breaking changes

true jasper
#

How would I make cards flip like tarots make cards flip when used?
when i use my consumable on it

runic sinew
#

"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

storm oar
edgy reef
#

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

storm oar
#

well, at least if thats a possible option, then at least save the files locally too as a backup incase of not having internet

runic sinew
#

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

storm oar
#

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

runic sinew
#

Well, in that case, have the download on to storage be done in the background as the game is running.

merry raven
#
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

runic sinew
#

It needs to be handled git-style, as otherwise the drive will be hit by excessive write cycles

tribal ocean
#

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

merry raven
#

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

faint yacht
#

And without the sound, it works just fine?

stray warren
storm oar
#

oh i didnt know that existed, good to know for the future

storm oar
#

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?

nocturne garnet
tribal ocean
#

Alright, here goes

#

Now time to figure out how to actually do this

crisp coral
#

steamodded 0.9.7 😭

wintry solar
#

{T:v_overstock} in your deck description text

storm oar
tribal ocean
nocturne garnet
merry raven
# faint yacht And without the sound, it works just fine?

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

wicked leaf
#

something's wrong

merry raven
wicked leaf
#

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

frosty dock
wicked leaf
frosty dock
wicked leaf
#

oh wait, I see a lil problem rq

#

nvm

wicked leaf
frosty dock
#

🤔

#

it failed to load your main file for some reason

wicked leaf
#

this is my main file

tall wharf
#

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}
wicked leaf
tall wharf
#

what did i do wrong

wicked leaf
#

no yeah same

crisp coral
#

your path shouldn't have the outer textures folder

#

and the path (in code) should just be collab_WF_1.png

wicked leaf
#

idk what im doing wrong either

crisp coral
#

er. collabs/file.png in this case

frosty dock
#

your file path here is jokers/ludusjokers.png

wicked leaf
#

oooh

tall wharf
#

ok that worked wow thanks

crisp coral
#

hatsune miku...........

tall wharf
#

true....

wicked leaf
#

okay what now

#

I changed the path

frosty dock
#

oh

#

your folders are x1 and x2

wicked leaf
#

yeah, don't I need both?

frosty dock
#

yeah but those are the wrong names

#

it's spsed to be 1x and 2x

wicked leaf
#

man.

#

ok, lets see if this works now

frosty dock
#

that's in the docs right

#

98%

wicked leaf
#

aye there we go

tall wharf
#

also just wondering how do 2x textures help with pixel smoothing

#

is it purely because bigger image scales up smoother

nocturne garnet
#

possibly favorite jokers to make

crisp coral
#

Jimbo's Pack's joker copy abilities when they see LobotomyCorp jokers

crisp coral
#

as in, i suspect it's gonna crash a lot

nocturne garnet
#

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

wicked leaf
#

almost working

#

the second guy's texture isnt working for some reason

#

it should, but its not

tall wharf
wicked leaf
#

I said ALMOST

wicked leaf
tall wharf
#

actually hold up i got an idea just from that

wicked leaf
tall wharf
#

is that copper shortsword

wicked leaf
#

x = 1, y = 1 should be the second one of the second column right

#

idk why it no worky

wicked leaf
tall wharf
#

also i think in lua index starts at 1

frosty dock
#

for atlas positions, it starts at 0

tall wharf
#

ah

wicked leaf
#

I have zero clue what the problem is

storm oar
#

its not even pulling from the atlas, it's using a default image

wicked leaf
#

the first one works,

#

the second one doesnt

storm oar
#

hm

#

wait

#

check the brackets.

wicked leaf
#

well I HAVE noticed the brackets are blue

#

it is most likely related to that

frosty dock
#

can I see the full joker def?

storm oar
#

yeah there's another layer of brackets there

#

did you accidentally put it in the text thing?

wicked leaf
storm oar
#

config isn't closed

wicked leaf
#

ah

frosty dock
#

yeah that's in your config

wicked leaf
#

ere we go

storm oar
#

yeah theres a closed bracket at the bottom where it should be after config

wicked leaf
#

new problem

#

seems like it has lost waaay more than 3

#

its also not giving the payout

frosty dock
#

context.end_of_round ahh jank

#

see how golden joker does it

#

Also probably self-destruct the joker when it goes below zero

wicked leaf
#

but that clearly isnt working so

nocturne garnet
wicked leaf
nocturne garnet
#

use calc_dollar_bonus function

#

you could just

#

remove the money in the calc dollar bonus

wicked leaf
#

good point

frosty dock
#

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

wicked leaf
#

aye, its workin now

tall wharf
#

redrawing miku 😭

#

someone take aseprite away from me

night pagoda
nocturne garnet
#

or is it just delaying the destruction

night pagoda
#

upon selling the joker the joker is technically sold (gives selling reward and loses sell value), but stays until the next round and only then gets destroyed

#

so I wonder if it will make a synergy by basically cloning the sold joker for one round